diff --git a/.gn b/.gn
index 5cb7ef49..5f02752 100644
--- a/.gn
+++ b/.gn
@@ -93,17 +93,10 @@
   "//extensions/browser/api/file_system:*",  # 1 error
   "//extensions/browser/api/hid:*",  # 12 errors
   "//extensions/browser/api/idle:*",  # 4 errors
-  "//extensions/browser/api/system_cpu:*",  # 1 error
-  "//extensions/browser/api/system_display:*",  # 3 errors
-  "//extensions/browser/api/system_info:*",  # 8 errors
-  "//extensions/browser/api/system_memory:*",  # 1 error
-  "//extensions/browser/api/system_network:*",  # 2 errors
-  "//extensions/browser/api/system_storage:*",  # 6 errors
   "//extensions/browser/api/test:*",  # 1 error
   "//extensions/browser/api/usb:*",  # 12 errors
   "//extensions/browser/api/web_request:*",  # 37 errors
   "//extensions/browser/api:*",  # 7 errors
-  "//extensions/browser/updater:*",  # 31 errors
   "//extensions/browser:*",  # 20 errors
   "//extensions:*",  # 75 errors
   "//headless:*",  # 167 errors
@@ -139,7 +132,6 @@
   "//remoting/ios/session:*",  # 7 errors
   "//remoting/ios:*",  # 2 errors
   "//remoting/protocol:*",  # 142 errors
-  "//remoting/signaling:*",  # 30 errors
   "//remoting/test:*",  # 20 errors
   "//remoting:*",  # 27 errors
   "//sandbox/win:*",  # 7 errors
diff --git a/DEPS b/DEPS
index 3839771f..8b654e3 100644
--- a/DEPS
+++ b/DEPS
@@ -199,11 +199,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': 'a43d58393a66f7d764f536a34463e7d19d5be32f',
+  'skia_revision': '863497b7fea493d66adb5559a4e24d2a7168b837',
   # 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': 'b19b2448ed8ecdc8965621750ac648a2331c0c18',
+  'v8_revision': 'c369eee9f5827733bc6784843744c4ac8a9bea0b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -211,15 +211,15 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '281c65523a0a57d27caaabe4d1c7209026e12862',
+  'angle_revision': '41a1920e352051b7134d1087ac08b4125d5a5dc2',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '9d35d544ce966098fdcb36107835d57a4dc1f32d',
+  'swiftshader_revision': 'aba242b50921817e2575589bc95206e2c3f4bd33',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '0bbf126296ca0d50a103c0c42ae9007a4eeb4452',
+  'pdfium_revision': '031723f7a72c33fd107a1d51d6f6bce88a4ee77d',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -250,7 +250,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
-  'freetype_revision': '947e47528345ab821b4d0fc7d3f0472fa236045e',
+  'freetype_revision': '2c40559609c102a934c1f0c5ee7ccb790fc887dc',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -270,7 +270,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': 'cf4c59a33297965657c182af10711b72da36a9e6',
+  'catapult_revision': 'cabcb01f6f2e197d68e2692182e877871ff6993d',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -278,7 +278,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': 'f8ffa12f6120f09e42195bd60dd72741636f6e4f',
+  'devtools_frontend_revision': '1c0c108e0e8150bb0c4b4b404f6eeb78f391d18e',
   # 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.
@@ -314,7 +314,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.
-  'shaderc_revision': 'ac375b4b8f699f26c697fab54348494a9911a7e6',
+  'shaderc_revision': '8d081127ee28ff5df8123c994c00bc66a57e9e9c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -374,7 +374,7 @@
   # libc++ svn_revision in //buildtools/deps_revisions.gni.
   # TODO(crbug.com/1166332) rename to clang_format_revision.
   'clang_fmt_revision':    '99803d74e35962f63a775f29477882afd4d57d94',
-  'libcxx_revision':       'd9040c75cfea5928c804ab7c235fed06a63f743a',
+  'libcxx_revision':       '69897abe2d4eae76816211fb408a07ba9b9e801f',
   'libcxxabi_revision':    '196ba1aaa8ac285d94f4ea8d9836390a45360533',
   'libunwind_revision':    'd999d54f4bca789543a2eb6c995af2d9b5a1f3ed',
 
@@ -678,7 +678,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'W-1EHWPYZ8HdH_e2dRy2kb3kD-vOHJ1996OkW7qs9LIC',
+          'version': '1WBn0YPU9rlqli8Ctebdf9E3s-CIFp7jei5nojlCemAC',
       },
     ],
     'condition': 'checkout_android',
@@ -885,7 +885,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'fec25b2b8da85c69278382aaf9d2bde8a20395ce',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '007dbe82964048b9bfc54e50fcf4cf58982d194b',
       'condition': 'checkout_chromeos',
   },
 
@@ -905,7 +905,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '79f916afab2f75a985b3fe637e1ce911c845e714',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '6b6e48934806244f023e90939bcde2163a6b0c6c',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1270,7 +1270,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'b05d9d92a00eb13527779d8f4fb3324ee1a2a2ee',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '6a605833d9b393d20d9fee45830dd3997599c2be',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1479,7 +1479,7 @@
   'src/third_party/usrsctp/usrsctplib':
     Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + 'a6647318b57c0a05d590c8c21fc22aba87f08749',
 
-  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@f640b7005a0cb2d0cc38946418d930fd6d22bb04',
+  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@760f29e0ac1fe62c0f94b9a77cf32c8a8390d395',
 
   'src/third_party/vulkan_memory_allocator':
     Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'b1d65a2b3373fe12c622eaab65e5cf21b906d178',
@@ -1578,7 +1578,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@93340f5c67859df2e2d415ff1c41b11555c8ca19',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c215bbd55fd0fc26a9534a174efd9cf086bc70fa',
     'condition': 'checkout_src_internal',
   },
 
@@ -1597,7 +1597,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'E9Wkv5jU9s6E0UztqoaJUXdV6wT9MLxrA4E1zqR9sg4C',
+        'version': 'u6aZyrYs0El59xG0hNXvIVvx9SBcVwaKhQUt_Uy0Gh0C',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 0503b89aa..6d41a817 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -2489,6 +2489,7 @@
     "//services/media_session/public/mojom",
     "//services/metrics/public/cpp:ukm_builders",
     "//services/network:test_support",
+    "//services/viz/privileged/mojom/compositing",
     "//skia",
     "//testing/gmock",
     "//testing/gtest",
diff --git a/ash/capture_mode/DEPS b/ash/capture_mode/DEPS
new file mode 100644
index 0000000..514f0d0
--- /dev/null
+++ b/ash/capture_mode/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+services/viz/privileged/mojom/compositing",
+]
diff --git a/ash/capture_mode/capture_mode_controller.cc b/ash/capture_mode/capture_mode_controller.cc
index dc0c1ff4..a284b956 100644
--- a/ash/capture_mode/capture_mode_controller.cc
+++ b/ash/capture_mode/capture_mode_controller.cc
@@ -678,7 +678,9 @@
 }
 
 void CaptureModeController::LaunchRecordingServiceAndStartRecording(
-    const CaptureParams& capture_params) {
+    const CaptureParams& capture_params,
+    mojo::PendingReceiver<viz::mojom::FrameSinkVideoCaptureOverlay>
+        cursor_overlay) {
   DCHECK(!recording_service_remote_.is_bound())
       << "Should not launch a new recording service while one is already "
          "running.";
@@ -695,11 +697,16 @@
   // audio stream factory.
   mojo::PendingRemote<recording::mojom::RecordingServiceClient> client =
       recording_service_client_receiver_.BindNewPipeAndPassRemote();
-  mojo::PendingRemote<viz::mojom::FrameSinkVideoCapturer> video_capturer;
+  mojo::Remote<viz::mojom::FrameSinkVideoCapturer> video_capturer_remote;
   aura::Env::GetInstance()
       ->context_factory()
       ->GetHostFrameSinkManager()
-      ->CreateVideoCapturer(video_capturer.InitWithNewPipeAndPassReceiver());
+      ->CreateVideoCapturer(video_capturer_remote.BindNewPipeAndPassReceiver());
+
+  // The overlay is to be rendered on top of the video frames.
+  constexpr int kStackingIndex = 1;
+  video_capturer_remote->CreateOverlay(kStackingIndex,
+                                       std::move(cursor_overlay));
 
   // We bind the audio stream factory only if audio recording is enabled. This
   // is ok since the |audio_stream_factory| parameter in the recording service
@@ -717,7 +724,7 @@
   switch (source_) {
     case CaptureModeSource::kFullscreen:
       recording_service_remote_->RecordFullscreen(
-          std::move(client), std::move(video_capturer),
+          std::move(client), video_capturer_remote.Unbind(),
           std::move(audio_stream_factory), frame_sink_id, bounds.size());
       break;
 
@@ -731,7 +738,7 @@
       DCHECK(capture_params.window->subtree_capture_id().is_valid());
 
       recording_service_remote_->RecordWindow(
-          std::move(client), std::move(video_capturer),
+          std::move(client), video_capturer_remote.Unbind(),
           std::move(audio_stream_factory), frame_sink_id,
           capture_params.window->subtree_capture_id(), bounds.size(),
           capture_params.window->GetRootWindow()
@@ -741,7 +748,7 @@
 
     case CaptureModeSource::kRegion:
       recording_service_remote_->RecordRegion(
-          std::move(client), std::move(video_capturer),
+          std::move(client), video_capturer_remote.Unbind(),
           std::move(audio_stream_factory), frame_sink_id,
           capture_params.window->GetRootWindow()
               ->GetBoundsInRootWindow()
@@ -781,7 +788,6 @@
     return;
 
   is_recording_in_progress_ = false;
-  Shell::Get()->UpdateCursorCompositingEnabled();
   capture_mode_util::SetStopRecordingButtonVisibility(
       video_recording_watcher_->window_being_recorded()->GetRootWindow(),
       false);
@@ -1069,12 +1075,13 @@
     return;
   }
 
-  // We enable the software-composited cursor, in order for the video capturer
-  // to be able to record it.
   is_recording_in_progress_ = true;
-  Shell::Get()->UpdateCursorCompositingEnabled();
-  video_recording_watcher_ =
-      std::make_unique<VideoRecordingWatcher>(this, capture_params->window);
+  mojo::PendingRemote<viz::mojom::FrameSinkVideoCaptureOverlay>
+      cursor_capture_overlay;
+  auto cursor_overlay_receiver =
+      cursor_capture_overlay.InitWithNewPipeAndPassReceiver();
+  video_recording_watcher_ = std::make_unique<VideoRecordingWatcher>(
+      this, capture_params->window, std::move(cursor_capture_overlay));
 
   // We only paint the recorded area highlight for window and region captures.
   if (source_ != CaptureModeSource::kFullscreen)
@@ -1105,7 +1112,8 @@
   video_file_handler_.AsyncCall(&VideoFileHandler::Initialize)
       .Then(on_video_file_status_);
 
-  LaunchRecordingServiceAndStartRecording(*capture_params);
+  LaunchRecordingServiceAndStartRecording(*capture_params,
+                                          std::move(cursor_overlay_receiver));
 
   delegate_->StartObservingRestrictedContent(
       capture_params->window, capture_params->bounds,
diff --git a/ash/capture_mode/capture_mode_controller.h b/ash/capture_mode/capture_mode_controller.h
index 2642caa..1d520a93 100644
--- a/ash/capture_mode/capture_mode_controller.h
+++ b/ash/capture_mode/capture_mode_controller.h
@@ -23,7 +23,9 @@
 #include "base/threading/sequence_bound.h"
 #include "base/timer/timer.h"
 #include "chromeos/dbus/power/power_manager_client.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
+#include "services/viz/privileged/mojom/compositing/frame_sink_video_capture.mojom-forward.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/image/image.h"
 
@@ -177,9 +179,14 @@
   base::Optional<CaptureParams> GetCaptureParams() const;
 
   // Launches the mojo service that handles audio and video recording, and
-  // begins recording according to the given |capture_params|.
+  // begins recording according to the given |capture_params|. It creates an
+  // overlay on the video capturer so that can be used to record the mouse
+  // cursor. It gives the pending receiver end to that overlay on Viz, and the
+  // other end should be owned by the |video_recording_watcher_|.
   void LaunchRecordingServiceAndStartRecording(
-      const CaptureParams& capture_params);
+      const CaptureParams& capture_params,
+      mojo::PendingReceiver<viz::mojom::FrameSinkVideoCaptureOverlay>
+          cursor_overlay);
 
   // Called back when the mojo pipe to the recording service gets disconnected.
   void OnRecordingServiceDisconnected();
diff --git a/ash/capture_mode/capture_mode_unittests.cc b/ash/capture_mode/capture_mode_unittests.cc
index 3138c6e..78853db 100644
--- a/ash/capture_mode/capture_mode_unittests.cc
+++ b/ash/capture_mode/capture_mode_unittests.cc
@@ -25,6 +25,7 @@
 #include "ash/display/screen_orientation_controller_test_api.h"
 #include "ash/display/window_tree_host_manager.h"
 #include "ash/home_screen/home_screen_controller.h"
+#include "ash/magnifier/docked_magnifier_controller_impl.h"
 #include "ash/magnifier/magnifier_glass.h"
 #include "ash/public/cpp/ash_features.h"
 #include "ash/public/cpp/capture_mode_test_api.h"
@@ -48,6 +49,10 @@
 #include "chromeos/dbus/power/fake_power_manager_client.h"
 #include "chromeos/dbus/power_manager/suspend.pb.h"
 #include "components/account_id/account_id.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "services/viz/privileged/mojom/compositing/frame_sink_video_capture.mojom.h"
 #include "ui/aura/client/capture_client.h"
 #include "ui/aura/client/capture_client_observer.h"
 #include "ui/aura/window_tracker.h"
@@ -80,7 +85,7 @@
   return Shell::Get()
       ->window_tree_host_manager()
       ->cursor_window_controller()
-      ->ShouldEnableCursorCompositing();
+      ->is_cursor_compositing_enabled();
 }
 
 void ClickOnView(const views::View* view,
@@ -224,7 +229,7 @@
 class CaptureModeTest : public AshTestBase {
  public:
   CaptureModeTest() = default;
-  CaptureModeTest(base::test::TaskEnvironment::TimeSource time)
+  explicit CaptureModeTest(base::test::TaskEnvironment::TimeSource time)
       : AshTestBase(time) {}
   CaptureModeTest(const CaptureModeTest&) = delete;
   CaptureModeTest& operator=(const CaptureModeTest&) = delete;
@@ -574,16 +579,16 @@
   EXPECT_FALSE(controller->IsActive());
   EXPECT_TRUE(controller->is_recording_in_progress());
 
-  // The composited cursor should be enabled, and the stop-recording button
-  // should show up in the status area widget.
-  EXPECT_TRUE(IsCursorCompositingEnabled());
+  // The composited cursor should remain disabled now that we're using the
+  // cursor overlay on the capturer. The stop-recording button should show up in
+  // the status area widget.
+  EXPECT_FALSE(IsCursorCompositingEnabled());
   auto* stop_recording_button = Shell::GetPrimaryRootWindowController()
                                     ->GetStatusAreaWidget()
                                     ->stop_recording_button_tray();
   EXPECT_TRUE(stop_recording_button->visible_preferred());
 
-  // End recording via the stop-recording button. Expect that it's now hidden,
-  // and the cursor compositing is now disabled.
+  // End recording via the stop-recording button. Expect that it's now hidden.
   base::HistogramTester histogram_tester;
   ClickOnView(stop_recording_button, event_generator);
   EXPECT_FALSE(stop_recording_button->visible_preferred());
@@ -2942,4 +2947,194 @@
   EXPECT_TRUE(controller->enable_audio_recording());
 }
 
+namespace {
+
+// -----------------------------------------------------------------------------
+// TestVideoCaptureOverlay:
+
+// Defines a fake video capture overlay to be used in testing the behavior of
+// the cursor overlay. The VideoRecordingWatcher will control this overlay via
+// mojo.
+using Overlay = viz::mojom::FrameSinkVideoCaptureOverlay;
+class TestVideoCaptureOverlay : public Overlay {
+ public:
+  explicit TestVideoCaptureOverlay(mojo::PendingReceiver<Overlay> receiver)
+      : receiver_(this, std::move(receiver)) {}
+  ~TestVideoCaptureOverlay() override = default;
+
+  const gfx::RectF& last_bounds() const { return last_bounds_; }
+
+  bool IsHidden() const { return last_bounds_ == gfx::RectF(); }
+
+  // viz::mojom::FrameSinkVideoCaptureOverlay:
+  void SetImageAndBounds(const SkBitmap& image,
+                         const gfx::RectF& bounds) override {
+    last_bounds_ = bounds;
+  }
+  void SetBounds(const gfx::RectF& bounds) override { last_bounds_ = bounds; }
+
+ private:
+  mojo::Receiver<viz::mojom::FrameSinkVideoCaptureOverlay> receiver_;
+  gfx::RectF last_bounds_;
+};
+
+// -----------------------------------------------------------------------------
+//  CaptureModeCursorOverlayTest:
+
+// Defines a test fixure to test the behavior of the cursor overlay.
+class CaptureModeCursorOverlayTest : public CaptureModeTest {
+ public:
+  CaptureModeCursorOverlayTest() = default;
+  ~CaptureModeCursorOverlayTest() override = default;
+
+  aura::Window* window() const { return window_.get(); }
+  TestVideoCaptureOverlay* fake_overlay() const { return fake_overlay_.get(); }
+
+  // CaptureModeTest:
+  void SetUp() override {
+    CaptureModeTest::SetUp();
+    window_ = CreateTestWindow(gfx::Rect(200, 200));
+  }
+
+  void TearDown() override {
+    window_.reset();
+    CaptureModeTest::TearDown();
+  }
+
+  CaptureModeController* StartRecordingAndSetupFakeOverlay(
+      CaptureModeSource source) {
+    auto* controller = StartCaptureSession(source, CaptureModeType::kVideo);
+    auto* event_generator = GetEventGenerator();
+    if (source == CaptureModeSource::kWindow)
+      event_generator->MoveMouseToCenterOf(window_.get());
+    controller->StartVideoRecordingImmediatelyForTesting();
+    EXPECT_TRUE(controller->is_recording_in_progress());
+    auto* recording_watcher = controller->video_recording_watcher_for_testing();
+    mojo::PendingRemote<Overlay> overlay_pending_remote;
+    fake_overlay_ = std::make_unique<TestVideoCaptureOverlay>(
+        overlay_pending_remote.InitWithNewPipeAndPassReceiver());
+    recording_watcher->BindCursorOverlayForTesting(
+        std::move(overlay_pending_remote));
+
+    // The overlay should be initially hidden until a mourse event is received.
+    FlushOverlay();
+    EXPECT_TRUE(fake_overlay()->IsHidden());
+
+    // Generating some mouse events may or may not show the overlay, depending
+    // on the conditions of the test. Each test will verify its expectation
+    // after this returns.
+    event_generator->MoveMouseBy(10, 10);
+    FlushOverlay();
+
+    return controller;
+  }
+
+  void FlushOverlay() {
+    auto* controller = CaptureModeController::Get();
+    DCHECK(controller->is_recording_in_progress());
+    controller->video_recording_watcher_for_testing()
+        ->FlushCursorOverlayForTesting();
+  }
+
+  // The docked magnifier is one of the features that force the software-
+  // composited cursor to be used when enabled. We use it to test the behavior
+  // of the cursor overlay in that case.
+  void SetDockedMagnifierEnabled(bool enabled) {
+    Shell::Get()->docked_magnifier_controller()->SetEnabled(enabled);
+  }
+
+ private:
+  std::unique_ptr<aura::Window> window_;
+  std::unique_ptr<TestVideoCaptureOverlay> fake_overlay_;
+};
+
+}  // namespace
+
+TEST_F(CaptureModeCursorOverlayTest, TabletModeHidesCursorOverlay) {
+  StartRecordingAndSetupFakeOverlay(CaptureModeSource::kFullscreen);
+  EXPECT_FALSE(fake_overlay()->IsHidden());
+
+  // Entering tablet mode should hide the cursor overlay.
+  TabletModeControllerTestApi tablet_mode_controller_test_api;
+  tablet_mode_controller_test_api.DetachAllMice();
+  tablet_mode_controller_test_api.EnterTabletMode();
+  FlushOverlay();
+  EXPECT_TRUE(fake_overlay()->IsHidden());
+
+  // Exiting tablet mode should reshow the overlay.
+  tablet_mode_controller_test_api.LeaveTabletMode();
+  FlushOverlay();
+  EXPECT_FALSE(fake_overlay()->IsHidden());
+}
+
+TEST_F(CaptureModeCursorOverlayTest, SoftwareCursorInFullscreenRecording) {
+  StartRecordingAndSetupFakeOverlay(CaptureModeSource::kFullscreen);
+  EXPECT_FALSE(fake_overlay()->IsHidden());
+
+  // When the software-composited cursor is enabled, the overlay is hidden to
+  // avoid having two overlapping cursors in the video.
+  SetDockedMagnifierEnabled(true);
+  EXPECT_TRUE(IsCursorCompositingEnabled());
+  FlushOverlay();
+  EXPECT_TRUE(fake_overlay()->IsHidden());
+
+  SetDockedMagnifierEnabled(false);
+  EXPECT_FALSE(IsCursorCompositingEnabled());
+  FlushOverlay();
+  EXPECT_FALSE(fake_overlay()->IsHidden());
+}
+
+TEST_F(CaptureModeCursorOverlayTest, SoftwareCursorInitiallyEnabled) {
+  // The software cursor is enabled before recording starts.
+  SetDockedMagnifierEnabled(true);
+  EXPECT_TRUE(IsCursorCompositingEnabled());
+
+  // Hence the overlay will be hidden initially.
+  StartRecordingAndSetupFakeOverlay(CaptureModeSource::kFullscreen);
+  EXPECT_TRUE(fake_overlay()->IsHidden());
+}
+
+TEST_F(CaptureModeCursorOverlayTest, SoftwareCursorInPartialRegion) {
+  CaptureModeController::Get()->SetUserCaptureRegion(gfx::Rect(20, 20),
+                                                     /*by_user=*/true);
+  StartRecordingAndSetupFakeOverlay(CaptureModeSource::kRegion);
+  EXPECT_FALSE(fake_overlay()->IsHidden());
+
+  // The behavior in this case is exactly the same as in fullscreen recording.
+  SetDockedMagnifierEnabled(true);
+  EXPECT_TRUE(IsCursorCompositingEnabled());
+  FlushOverlay();
+  EXPECT_TRUE(fake_overlay()->IsHidden());
+}
+
+TEST_F(CaptureModeCursorOverlayTest, SoftwareCursorInWindowRecording) {
+  StartRecordingAndSetupFakeOverlay(CaptureModeSource::kWindow);
+  EXPECT_FALSE(fake_overlay()->IsHidden());
+
+  // When recording a window, the software cursor has no effect of the cursor
+  // overlay, since the cursor widget is not in the recorded window subtree, so
+  // it cannot be captured by the frame sink capturer. We have to provide cursor
+  // capturing through the overlay.
+  SetDockedMagnifierEnabled(true);
+  EXPECT_TRUE(IsCursorCompositingEnabled());
+  FlushOverlay();
+  EXPECT_FALSE(fake_overlay()->IsHidden());
+}
+
+TEST_F(CaptureModeCursorOverlayTest, OverlayHidesWhenOutOfBounds) {
+  StartRecordingAndSetupFakeOverlay(CaptureModeSource::kWindow);
+  EXPECT_FALSE(fake_overlay()->IsHidden());
+
+  const gfx::Point bottom_right =
+      window()->GetBoundsInRootWindow().bottom_right();
+  auto* generator = GetEventGenerator();
+  // Generate a click event to overcome throttling.
+  generator->MoveMouseTo(bottom_right);
+  generator->ClickLeftButton();
+  FlushOverlay();
+  EXPECT_TRUE(fake_overlay()->IsHidden());
+}
+
+// TODO(afakhry): Add more cursor overlay tests.
+
 }  // namespace ash
diff --git a/ash/capture_mode/video_recording_watcher.cc b/ash/capture_mode/video_recording_watcher.cc
index 650fb4b..a8c70cd 100644
--- a/ash/capture_mode/video_recording_watcher.cc
+++ b/ash/capture_mode/video_recording_watcher.cc
@@ -13,21 +13,37 @@
 #include "ash/style/ash_color_provider.h"
 #include "ash/wm/desks/desks_util.h"
 #include "ash/wm/mru_window_tracker.h"
+#include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "base/check.h"
 #include "base/check_op.h"
 #include "base/notreached.h"
+#include "base/time/time.h"
+#include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
+#include "ui/base/cursor/cursor_lookup.h"
 #include "ui/compositor/paint_recorder.h"
 #include "ui/display/screen.h"
 #include "ui/gfx/canvas.h"
+#include "ui/gfx/geometry/point_f.h"
+#include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/geometry/size_f.h"
+#include "ui/gfx/native_widget_types.h"
 #include "ui/gfx/scoped_canvas.h"
+#include "ui/wm/core/coordinate_conversion.h"
 #include "ui/wm/public/activation_client.h"
 
 namespace ash {
 
 namespace {
 
+// Recording is performed at a rate of 30 FPS. Any non-pressed/-released mouse
+// events that are too frequent will be throttled. We use the frame duration as
+// the minimum delay between any two successive such events that we use to
+// update the cursor overlay.
+constexpr base::TimeDelta kCursorEventsThrottleDelay =
+    base::TimeDelta::FromHz(30);
+
 // Returns true if |window_1| and |window_2| are both windows that belong to
 // the same Desk. Note that it will return false for windows that don't belong
 // to any desk (such as always-on-top windows or PIPs).
@@ -37,6 +53,69 @@
   return container_1 && container_2 && container_1 == container_2;
 }
 
+// Gets the mouse cursor location in the coordinates of the given |window|. Use
+// this if a mouse event is not available.
+gfx::PointF GetCursorLocationInWindow(aura::Window* window) {
+  gfx::PointF cursor_point(
+      display::Screen::GetScreen()->GetCursorScreenPoint());
+  wm::ConvertPointFromScreen(window, &cursor_point);
+  return cursor_point;
+}
+
+// Gets the location of the given mouse |event| in the coordinates of the given
+// |window|.
+gfx::PointF GetEventLocationInWindow(aura::Window* window,
+                                     const ui::MouseEvent& event) {
+  aura::Window* target = static_cast<aura::Window*>(event.target());
+  gfx::PointF location = event.location_f();
+  if (target != window)
+    aura::Window::ConvertPointToTarget(target, window, &location);
+  return location;
+}
+
+// Returns the hotspot location of the given |cursor|.
+gfx::PointF GetCursorHotspot(const ui::Cursor& cursor,
+                             float cursor_scale_factor) {
+  DCHECK_GE(cursor_scale_factor, 1.f);
+
+  // ui::GetCursorHotspot() returns a scale-factor-200 hotspot for a
+  // scale-factor-100 bitmap when the scale factor is not 1.f, causing the
+  // hotspot to be out of bounds of the bitmap dimensions. See
+  // https://crbug.com/436993.
+  gfx::PointF hotspot(ui::GetCursorHotspot(cursor));
+  if (cursor_scale_factor > 1.f &&
+      cursor.type() != ui::mojom::CursorType::kCustom) {
+    hotspot.Scale(1.f / cursor_scale_factor);
+  }
+  return hotspot;
+}
+
+// Returns the cursor overlay bounds as defined by the documentation of the
+// FrameSinkVideoCaptureOverlay. The bounds should be relative within the bounds
+// of the recorded frame sink (i.e. in the range [0.f, 1.f) for both cursor
+// origin and size).
+gfx::RectF GetCursorOverlayBounds(
+    const aura::Window* recorded_window,
+    const gfx::PointF& location_in_recorded_window,
+    const gfx::PointF& cursor_hotspot,
+    const SkBitmap& cursor_bitmap) {
+  DCHECK(recorded_window);
+
+  // Even when recording a non-root window, we use the bounds of the root
+  // window, since it corresponds to the bounds of the source frame sink we are
+  // recording.
+  const auto window_size = recorded_window->GetRootWindow()->bounds().size();
+  if (window_size.IsEmpty())
+    return gfx::RectF();
+
+  gfx::RectF cursor_relative_bounds(
+      location_in_recorded_window - cursor_hotspot.OffsetFromOrigin(),
+      gfx::SizeF(cursor_bitmap.width(), cursor_bitmap.height()));
+  cursor_relative_bounds.Scale(1.f / window_size.width(),
+                               1.f / window_size.height());
+  return cursor_relative_bounds;
+}
+
 }  // namespace
 
 // -----------------------------------------------------------------------------
@@ -84,11 +163,15 @@
 
 VideoRecordingWatcher::VideoRecordingWatcher(
     CaptureModeController* controller,
-    aura::Window* window_being_recorded)
+    aura::Window* window_being_recorded,
+    mojo::PendingRemote<viz::mojom::FrameSinkVideoCaptureOverlay>
+        cursor_capture_overlay)
     : controller_(controller),
+      cursor_manager_(Shell::Get()->cursor_manager()),
       window_being_recorded_(window_being_recorded),
       current_root_(window_being_recorded->GetRootWindow()),
-      recording_source_(controller_->source()) {
+      recording_source_(controller_->source()),
+      cursor_capture_overlay_remote_(std::move(cursor_capture_overlay)) {
   DCHECK(controller_);
   DCHECK(window_being_recorded_);
   DCHECK(current_root_);
@@ -101,6 +184,22 @@
     root_observer_ =
         std::make_unique<RecordedWindowRootObserver>(current_root_, this);
     Shell::Get()->activation_client()->AddObserver(this);
+  } else {
+    // We only need to observe the changes in the state of the software-
+    // composited cursor when recording a root window (i.e. fullscreen or
+    // partial region capture), since the software cursor is in the layer
+    // subtree of the root window, and will be captured by the frame sink video
+    // capturer automatically without the need for the cursor overlay. In this
+    // case we need to avoid producing a video with two overlapping cursors.
+    // When recording a window however, the software cursor is not in its layer
+    // subtree, and has to always be captured using the cursor overlay.
+    auto* cursor_window_controller =
+        Shell::Get()->window_tree_host_manager()->cursor_window_controller();
+    // Note that the software cursor might have already been enabled prior to
+    // the recording starting.
+    force_cursor_overlay_hidden_ =
+        cursor_window_controller->is_cursor_compositing_enabled();
+    cursor_window_controller->AddObserver(this);
   }
 
   if (recording_source_ == CaptureModeSource::kRegion)
@@ -108,13 +207,34 @@
 
   display::Screen::GetScreen()->AddObserver(this);
   window_being_recorded_->AddObserver(this);
+  TabletModeController::Get()->AddObserver(this);
+
+  // Note the following:
+  // 1- We add |this| as a pre-target handler of the |window_being_recorded_| as
+  //    opposed to |Shell|. This ensures that we only get mouse events when the
+  //    window being recorded is the target. This is more efficient since we
+  //    won't get any event when the curosr is in a different display, or
+  //    targeting a different window.
+  // 2- We use the |kSystem| priority to ensure that we get these events before
+  //    other pre-target handlers can consume them (e.g. when opening a capture
+  //    mode session to take a screenshot while recording a video).
+  window_being_recorded_->AddPreTargetHandler(
+      this, ui::EventTarget::Priority::kSystem);
 }
 
 VideoRecordingWatcher::~VideoRecordingWatcher() {
   DCHECK(window_being_recorded_);
 
-  if (recording_source_ == CaptureModeSource::kWindow)
+  window_being_recorded_->RemovePreTargetHandler(this);
+  TabletModeController::Get()->RemoveObserver(this);
+  if (recording_source_ == CaptureModeSource::kWindow) {
     Shell::Get()->activation_client()->RemoveObserver(this);
+  } else {
+    Shell::Get()
+        ->window_tree_host_manager()
+        ->cursor_window_controller()
+        ->RemoveObserver(this);
+  }
   display::Screen::GetScreen()->RemoveObserver(this);
   window_being_recorded_->RemoveObserver(this);
 }
@@ -266,11 +386,57 @@
   }
 }
 
+void VideoRecordingWatcher::OnMouseEvent(ui::MouseEvent* event) {
+  switch (event->type()) {
+    case ui::ET_MOUSEWHEEL:
+    case ui::ET_MOUSE_CAPTURE_CHANGED:
+      return;
+
+    case ui::ET_MOUSE_PRESSED:
+    case ui::ET_MOUSE_RELEASED:
+      // Pressed/released events are important, so we handle them immediately.
+      UpdateCursorOverlayNow(
+          GetEventLocationInWindow(window_being_recorded_, *event));
+      return;
+
+    default:
+      UpdateOrThrottleCursorOverlay(
+          GetEventLocationInWindow(window_being_recorded_, *event));
+  }
+}
+
+void VideoRecordingWatcher::OnTabletModeStarted() {
+  UpdateCursorOverlayNow(gfx::PointF());
+}
+
+void VideoRecordingWatcher::OnTabletModeEnded() {
+  UpdateCursorOverlayNow(GetCursorLocationInWindow(window_being_recorded_));
+}
+
+void VideoRecordingWatcher::OnCursorCompositingStateChanged(bool enabled) {
+  DCHECK_NE(recording_source_, CaptureModeSource::kWindow);
+  force_cursor_overlay_hidden_ = enabled;
+  UpdateCursorOverlayNow(
+      force_cursor_overlay_hidden_
+          ? gfx::PointF()
+          : GetCursorLocationInWindow(window_being_recorded_));
+}
+
 bool VideoRecordingWatcher::IsWindowDimmedForTesting(
     aura::Window* window) const {
   return dimmers_.contains(window);
 }
 
+void VideoRecordingWatcher::BindCursorOverlayForTesting(
+    mojo::PendingRemote<viz::mojom::FrameSinkVideoCaptureOverlay> overlay) {
+  cursor_capture_overlay_remote_.reset();
+  cursor_capture_overlay_remote_.Bind(std::move(overlay));
+}
+
+void VideoRecordingWatcher::FlushCursorOverlayForTesting() {
+  cursor_capture_overlay_remote_.FlushForTesting();
+}
+
 void VideoRecordingWatcher::SetLayer(std::unique_ptr<ui::Layer> layer) {
   if (layer) {
     layer->set_delegate(this);
@@ -413,4 +579,94 @@
   }
 }
 
+gfx::NativeCursor VideoRecordingWatcher::GetCurrentCursor() const {
+  const auto cursor = cursor_manager_->GetCursor();
+  // See the documentation in cursor_type.mojom. |kNull| is treated exactly as
+  // |kPointer|.
+  return (cursor.type() == ui::mojom::CursorType::kNull)
+             ? gfx::NativeCursor(ui::mojom::CursorType::kPointer)
+             : cursor;
+}
+
+void VideoRecordingWatcher::UpdateOrThrottleCursorOverlay(
+    const gfx::PointF& location) {
+  if (cursor_events_throttle_timer_.IsRunning()) {
+    throttled_cursor_location_ = location;
+    return;
+  }
+
+  UpdateCursorOverlayNow(location);
+  cursor_events_throttle_timer_.Start(
+      FROM_HERE, kCursorEventsThrottleDelay, this,
+      &VideoRecordingWatcher::OnThrottleTimerFiring);
+}
+
+void VideoRecordingWatcher::UpdateCursorOverlayNow(
+    const gfx::PointF& location) {
+  // Cancel any pending throttled event.
+  cursor_events_throttle_timer_.Stop();
+  throttled_cursor_location_.reset();
+
+  if (!cursor_capture_overlay_remote_)
+    return;
+
+  if (force_cursor_overlay_hidden_ ||
+      TabletModeController::Get()->InTabletMode()) {
+    HideCursorOverlay();
+    return;
+  }
+
+  const gfx::RectF window_local_bounds(
+      gfx::SizeF(window_being_recorded_->bounds().size()));
+  if (!window_local_bounds.Contains(location)) {
+    HideCursorOverlay();
+    return;
+  }
+
+  const gfx::NativeCursor cursor = GetCurrentCursor();
+  DCHECK_NE(cursor.type(), ui::mojom::CursorType::kNull);
+
+  const float cursor_scale_factor = std::max(1.f, cursor.image_scale_factor());
+  const SkBitmap cursor_image = ui::GetCursorBitmap(cursor);
+  const gfx::RectF cursor_overlay_bounds = GetCursorOverlayBounds(
+      window_being_recorded_, location,
+      GetCursorHotspot(cursor, cursor_scale_factor), cursor_image);
+
+  if (cursor != last_cursor_) {
+    if (cursor_image.drawsNothing()) {
+      last_cursor_ = gfx::NativeCursor();
+      HideCursorOverlay();
+      return;
+    }
+
+    last_cursor_ = cursor;
+    last_cursor_overlay_bounds_ = cursor_overlay_bounds;
+    cursor_capture_overlay_remote_->SetImageAndBounds(
+        cursor_image, last_cursor_overlay_bounds_);
+    return;
+  }
+
+  if (last_cursor_overlay_bounds_ == cursor_overlay_bounds)
+    return;
+
+  last_cursor_overlay_bounds_ = cursor_overlay_bounds;
+  cursor_capture_overlay_remote_->SetBounds(last_cursor_overlay_bounds_);
+}
+
+void VideoRecordingWatcher::HideCursorOverlay() {
+  DCHECK(cursor_capture_overlay_remote_);
+
+  // No need to rehide if already hidden.
+  if (last_cursor_overlay_bounds_ == gfx::RectF())
+    return;
+
+  last_cursor_overlay_bounds_ = gfx::RectF();
+  cursor_capture_overlay_remote_->SetBounds(last_cursor_overlay_bounds_);
+}
+
+void VideoRecordingWatcher::OnThrottleTimerFiring() {
+  if (throttled_cursor_location_)
+    UpdateCursorOverlayNow(*throttled_cursor_location_);
+}
+
 }  // namespace ash
diff --git a/ash/capture_mode/video_recording_watcher.h b/ash/capture_mode/video_recording_watcher.h
index ac27367..1eb990f3 100644
--- a/ash/capture_mode/video_recording_watcher.h
+++ b/ash/capture_mode/video_recording_watcher.h
@@ -7,14 +7,29 @@
 
 #include "ash/ash_export.h"
 #include "ash/capture_mode/capture_mode_types.h"
+#include "ash/display/cursor_window_controller.h"
+#include "ash/public/cpp/tablet_mode_observer.h"
 #include "ash/wm/window_dimmer.h"
+#include "base/optional.h"
+#include "base/timer/timer.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "services/viz/privileged/mojom/compositing/frame_sink_video_capture.mojom.h"
 #include "ui/aura/scoped_window_capture_request.h"
 #include "ui/aura/window_observer.h"
+#include "ui/base/cursor/cursor.h"
 #include "ui/compositor/layer_delegate.h"
 #include "ui/compositor/layer_owner.h"
 #include "ui/display/display_observer.h"
+#include "ui/events/event_handler.h"
+#include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/native_widget_types.h"
 #include "ui/wm/public/activation_change_observer.h"
 
+namespace wm {
+class CursorManager;
+}  // namespace wm
+
 namespace ash {
 
 class CaptureModeController;
@@ -29,15 +44,24 @@
 // Note that this object doesn't create a new layer, rather the controller makes
 // it acquire and reuse the layer of the |CaptureModeSession| prior to the
 // session ending.
-class ASH_EXPORT VideoRecordingWatcher : public aura::WindowObserver,
-                                         public ui::LayerOwner,
-                                         public ui::LayerDelegate,
-                                         public wm::ActivationChangeObserver,
-                                         public display::DisplayObserver,
-                                         public WindowDimmer::Delegate {
+// It also controls the overlay created on the video capturer to efficiently
+// record the mouse cursor on top of the video frames.
+class ASH_EXPORT VideoRecordingWatcher
+    : public aura::WindowObserver,
+      public ui::LayerOwner,
+      public ui::LayerDelegate,
+      public wm::ActivationChangeObserver,
+      public display::DisplayObserver,
+      public WindowDimmer::Delegate,
+      public ui::EventHandler,
+      public TabletModeObserver,
+      public CursorWindowController::Observer {
  public:
-  VideoRecordingWatcher(CaptureModeController* controller,
-                        aura::Window* window_being_recorded);
+  VideoRecordingWatcher(
+      CaptureModeController* controller,
+      aura::Window* window_being_recorded,
+      mojo::PendingRemote<viz::mojom::FrameSinkVideoCaptureOverlay>
+          cursor_capture_overlay);
   ~VideoRecordingWatcher() override;
 
   aura::Window* window_being_recorded() const { return window_being_recorded_; }
@@ -73,8 +97,23 @@
   void OnDimmedWindowDestroying(aura::Window* window) override;
   void OnDimmedWindowParentChanged(aura::Window* dimmed_window) override;
 
+  // ui::EventHandler:
+  void OnMouseEvent(ui::MouseEvent* event) override;
+
+  // TabletModeObserver:
+  void OnTabletModeStarted() override;
+  void OnTabletModeEnded() override;
+
+  // CursorWindowController::Observer:
+  void OnCursorCompositingStateChanged(bool enabled) override;
+
   bool IsWindowDimmedForTesting(aura::Window* window) const;
 
+  void BindCursorOverlayForTesting(
+      mojo::PendingRemote<viz::mojom::FrameSinkVideoCaptureOverlay> overlay);
+
+  void FlushCursorOverlayForTesting();
+
  protected:
   // ui::LayerOwner:
   void SetLayer(std::unique_ptr<ui::Layer> layer) override;
@@ -100,16 +139,82 @@
   // are above the shield layer in z-order.
   void UpdateLayerStackingAndDimmers();
 
+  // Returns the current native cursor from |cursor_manager_|.
+  gfx::NativeCursor GetCurrentCursor() const;
+
+  // Updates the cursor overlay using the given |location| in the coordinates of
+  // the |window_being_recorded_|. This is used for non-pressed/-released mouse
+  // events which can be too frequent. Recording is performed at a rate of 30
+  // FPS, so we don't need to send every mouse event to the capturer overlay on
+  // Viz via mojo. Such events can be throttled using the
+  // |cursor_events_throttle_timer_|.
+  void UpdateOrThrottleCursorOverlay(const gfx::PointF& location);
+
+  // As opposed to the above UpdateOrThrottleCursorOverlay(), this updates the
+  // cursor capturer overlay immediately without throttling, if such an update
+  // is needed (e.g. the cursor bitmap changed, or the location changed, or
+  // both). This also cancels any pending throttled update, since this immediate
+  // one is more recent.
+  void UpdateCursorOverlayNow(const gfx::PointF& location);
+
+  // Hides the cursor overlay in the video capturer. Note that this doesn't
+  // necessarily mean that the video won't contain a cursor, since the software-
+  // composited cursor might be enabled. See |force_cursor_overlay_hidden_|.
+  void HideCursorOverlay();
+
+  // Invoked when the |cursor_events_throttle_timer_| fires, in order to update
+  // the cursor overlay with the pending most recently throttled mouse event
+  // location in |throttled_cursor_location_| if any.
+  void OnThrottleTimerFiring();
+
   CaptureModeController* const controller_;
+  wm::CursorManager* const cursor_manager_;
   aura::Window* const window_being_recorded_;
   aura::Window* current_root_;
   const CaptureModeSource recording_source_;
 
+  // The end point of the overlay owned by the video capturer on Viz, which is
+  // used to blit the mouse cursor onto the recorded video frames.
+  mojo::Remote<viz::mojom::FrameSinkVideoCaptureOverlay>
+      cursor_capture_overlay_remote_;
+
   // Observes the hierarchy changes of the root window of the recorded window.
   // Only constructed when performing a window recording (i.e.
   // |recording_source_| is |kWindow|).
   std::unique_ptr<RecordedWindowRootObserver> root_observer_;
 
+  // The last cursor we used to update the cursor overlay. This is used to
+  // determine whether we need to update the cursor bitmap.
+  gfx::NativeCursor last_cursor_;
+
+  // The last bounds we used to update the cursor overlay. This is used to skip
+  // the update if the bounds didn't change.
+  // Note that these bounds are relative within the bounds of the recorded frame
+  // sink, i.e. in the range [0.f, 1.f) for both origin() and size().
+  // See documentation of FrameSinkVideoCaptureOverlay for more details.
+  gfx::RectF last_cursor_overlay_bounds_;
+
+  // Since recording happens at a rate of 30 FPS, there's no need to send every
+  // mouse move event (or equivalent events such as enter, exit, dragged, ...
+  // etc.) to the cursor overlay. This timer is used to throttle such events
+  // received while this timer is running, and their location will overwrite the
+  // value of |throttled_cursor_location_|. Once the timer fires,
+  // OnThrottleTimerFiring() will be called to update the overlay with the most
+  // recent received throttled event.
+  base::OneShotTimer cursor_events_throttle_timer_;
+
+  // Stores the location of the most recent throttled mouse event (i.e. received
+  // while the |cursor_events_throttle_timer_| was running). The location is in
+  // the |window_being_recorded_| coordinates.
+  base::Optional<gfx::PointF> throttled_cursor_location_;
+
+  // True if we force hiding the cursor overlay. This happens when we record a
+  // fullscreen, or a partial screen region, and the software-composited cursor
+  // gets enabled. The software-composited cursor is already part of the root
+  // window's frame sink which we record, so we don't need to show the cursor
+  // overlay. Otherwise, the video will end up with two overlapping cursors.
+  bool force_cursor_overlay_hidden_ = false;
+
   // Whether or not to paint the layer content in OnPaintLayer(). The value of
   // this field is calculated and updated in UpdateShouldPaintLayer().
   bool should_paint_layer_ = false;
diff --git a/ash/display/cursor_window_controller.cc b/ash/display/cursor_window_controller.cc
index 838d4538..fb61bef4 100644
--- a/ash/display/cursor_window_controller.cc
+++ b/ash/display/cursor_window_controller.cc
@@ -110,6 +110,14 @@
   SetContainer(NULL);
 }
 
+void CursorWindowController::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void CursorWindowController::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
 void CursorWindowController::SetLargeCursorSizeInDip(
     int large_cursor_size_in_dip) {
   large_cursor_size_in_dip =
@@ -139,13 +147,7 @@
     return true;
 
   if (features::IsCaptureModeEnabled()) {
-    auto* controller = CaptureModeController::Get();
-    if (controller->is_recording_in_progress()) {
-      // To let the video capturer record the cursor.
-      return true;
-    }
-
-    auto* session = controller->capture_mode_session();
+    auto* session = CaptureModeController::Get()->capture_mode_session();
     if (session && session->is_drag_in_progress()) {
       // To ensure the cursor is aligned with the dragged region.
       return true;
@@ -197,12 +199,15 @@
 }
 
 void CursorWindowController::SetCursorCompositingEnabled(bool enabled) {
-  if (is_cursor_compositing_enabled_ != enabled) {
-    is_cursor_compositing_enabled_ = enabled;
-    if (display_.is_valid())
-      UpdateCursorImage();
-    UpdateContainer();
-  }
+  if (is_cursor_compositing_enabled_ == enabled)
+    return;
+
+  is_cursor_compositing_enabled_ = enabled;
+  if (display_.is_valid())
+    UpdateCursorImage();
+  UpdateContainer();
+  for (auto& obs : observers_)
+    obs.OnCursorCompositingStateChanged(is_cursor_compositing_enabled_);
 }
 
 void CursorWindowController::UpdateContainer() {
diff --git a/ash/display/cursor_window_controller.h b/ash/display/cursor_window_controller.h
index c62cfed8..2cce7b9 100644
--- a/ash/display/cursor_window_controller.h
+++ b/ash/display/cursor_window_controller.h
@@ -10,6 +10,8 @@
 #include "ash/ash_export.h"
 #include "ash/public/cpp/ash_constants.h"
 #include "base/macros.h"
+#include "base/observer_list.h"
+#include "base/observer_list_types.h"
 #include "ui/aura/window.h"
 #include "ui/base/cursor/cursor.h"
 #include "ui/base/cursor/cursor_size.h"
@@ -28,6 +30,14 @@
 // When cursor compositing is enabled, just draw the cursor as-is.
 class ASH_EXPORT CursorWindowController {
  public:
+  class Observer : public base::CheckedObserver {
+   public:
+    virtual void OnCursorCompositingStateChanged(bool enabled) = 0;
+
+   protected:
+    ~Observer() override = default;
+  };
+
   CursorWindowController();
   ~CursorWindowController();
 
@@ -35,6 +45,9 @@
     return is_cursor_compositing_enabled_;
   }
 
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
   void SetLargeCursorSizeInDip(int large_cursor_size_in_dip);
   void SetCursorColor(SkColor cursor_color);
 
@@ -85,6 +98,8 @@
 
   const gfx::ImageSkia& GetCursorImageForTest() const;
 
+  base::ObserverList<Observer> observers_;
+
   aura::Window* container_ = nullptr;
 
   // The current cursor-compositing state.
diff --git a/ash/metrics/login_unlock_throughput_recorder.cc b/ash/metrics/login_unlock_throughput_recorder.cc
index 1436c68e..0218b0b 100644
--- a/ash/metrics/login_unlock_throughput_recorder.cc
+++ b/ash/metrics/login_unlock_throughput_recorder.cc
@@ -7,6 +7,7 @@
 #include "ash/public/cpp/metrics_util.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
+#include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "base/bind.h"
 #include "base/metrics/histogram_functions.h"
 #include "chromeos/login/login_state/login_state.h"
@@ -17,6 +18,12 @@
 namespace ash {
 namespace {
 
+std::string GetDeviceModeSuffix() {
+  return Shell::Get()->tablet_mode_controller()->InTabletMode()
+             ? "TabletMode"
+             : "ClamshellMode";
+}
+
 void ReportLogin(const cc::FrameSequenceMetrics::CustomReportData& data) {
   if (data.frames_expected) {
     int smoothness = metrics_util::CalculateSmoothness(data);
@@ -25,12 +32,14 @@
     float refresh_rate =
         Shell::GetPrimaryRootWindow()->GetHost()->compositor()->refresh_rate();
     int duration_ms = (1000.f / refresh_rate) * data.frames_expected;
-    base::UmaHistogramPercentage("Ash.LoginAnimation.Smoothness", smoothness);
-    base::UmaHistogramPercentage("Ash.LoginAnimation.Jank", jank);
+    std::string suffix = GetDeviceModeSuffix();
+    base::UmaHistogramPercentage("Ash.LoginAnimation.Smoothness." + suffix,
+                                 smoothness);
+    base::UmaHistogramPercentage("Ash.LoginAnimation.Jank." + suffix, jank);
     // TODO(crbug.com/1143898): Deprecate this metrics once the login
     // performance issue is resolved.
     base::UmaHistogramCustomTimes(
-        "Ash.LoginAnimation.Duration",
+        "Ash.LoginAnimation.Duration." + suffix,
         base::TimeDelta::FromMilliseconds(duration_ms),
         base::TimeDelta::FromMilliseconds(100), base::TimeDelta::FromSeconds(5),
         50);
@@ -43,9 +52,10 @@
   if (data.frames_expected) {
     int smoothness = metrics_util::CalculateSmoothness(data);
     int jank = metrics_util::CalculateJank(data);
-
-    base::UmaHistogramPercentage("Ash.UnlockAnimation.Smoothness", smoothness);
-    base::UmaHistogramPercentage("Ash.UnlockAnimation.Jank", jank);
+    std::string suffix = GetDeviceModeSuffix();
+    base::UmaHistogramPercentage("Ash.UnlockAnimation.Smoothness." + suffix,
+                                 smoothness);
+    base::UmaHistogramPercentage("Ash.UnlockAnimation.Jank." + suffix, jank);
   } else {
     LOG(WARNING) << "Zero frames expected in Unlock animation throughput data";
   }
diff --git a/ash/shortcut_viewer/strings/shortcut_viewer_strings_fa.xtb b/ash/shortcut_viewer/strings/shortcut_viewer_strings_fa.xtb
index 807cf65..acd9787e 100644
--- a/ash/shortcut_viewer/strings/shortcut_viewer_strings_fa.xtb
+++ b/ash/shortcut_viewer/strings/shortcut_viewer_strings_fa.xtb
@@ -149,7 +149,7 @@
 <translation id="6395172954772765143">انتخاب نوشتار تا انتهای خط</translation>
 <translation id="6425378783626925378">کلیک کردن نمادهای ۱ تا ۸ در قفسه</translation>
 <translation id="6435207348963613811">برجسته‌سازی مورد قبلی روی قفسه شما</translation>
-<translation id="6445033640292336367">برگرداندن برگه به جای اول</translation>
+<translation id="6445033640292336367">برگرداندن برگه به‌جای اول</translation>
 <translation id="6474744297082284761">دورنمایی کردن (وقتی ذره‌بین متصل یا ذره‌بین تمام‌صفحه فعال است)</translation>
 <translation id="649811797655257835">فایلی را انتخاب کنید و سپس <ph name="SPACE" /> را فشار دهید</translation>
 <translation id="6551886416582667425">نماگرفت گرفتن/ ضبط کردن جزئی</translation>
diff --git a/ash/strings/ash_strings_af.xtb b/ash/strings/ash_strings_af.xtb
index 2008a6f..e0346a5b 100644
--- a/ash/strings/ash_strings_af.xtb
+++ b/ash/strings/ash_strings_af.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Die toestel moet herbegin word om die opdatering toe te pas.</translation>
 <translation id="1175572348579024023">Rollees</translation>
 <translation id="1178581264944972037">Laat wag</translation>
+<translation id="1181037720776840403">Verwyder</translation>
 <translation id="118532027333893379">Tik op enige plek om volskerm vas te vang</translation>
 <translation id="1190609913194133056">Kennisgewingsentrum</translation>
 <translation id="1195412055398077112">oorskandeer</translation>
diff --git a/ash/strings/ash_strings_am.xtb b/ash/strings/ash_strings_am.xtb
index dbed296..d01ade3f 100644
--- a/ash/strings/ash_strings_am.xtb
+++ b/ash/strings/ash_strings_am.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">ዝማኔውን ለመተግበር የመሣሪያ ዳግም ማስጀመር ያስፈልጋል።</translation>
 <translation id="1175572348579024023">ሸብልል</translation>
 <translation id="1178581264944972037">ለአፍታ አቁም</translation>
+<translation id="1181037720776840403">አስወግድ</translation>
 <translation id="118532027333893379">ሙሉ ማያ ገጽን ለመቅረጽ በማንኛውም ቦታ ላይ መታ ያድርጉ</translation>
 <translation id="1190609913194133056">የማሳወቂያ ማዕከል</translation>
 <translation id="1195412055398077112">ትርፍ ቅኝት</translation>
diff --git a/ash/strings/ash_strings_ar.xtb b/ash/strings/ash_strings_ar.xtb
index cc81f30..d6de389 100644
--- a/ash/strings/ash_strings_ar.xtb
+++ b/ash/strings/ash_strings_ar.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">عليك إعادة تشغيل الجهاز لتطبيق التحديث.</translation>
 <translation id="1175572348579024023">التمرير</translation>
 <translation id="1178581264944972037">الإيقاف مؤقتًا</translation>
+<translation id="1181037720776840403">إزالة</translation>
 <translation id="118532027333893379">انقر في أي مكان لالتقاط صورة في وضع ملء الشاشة.</translation>
 <translation id="1190609913194133056">مركز الإشعارات</translation>
 <translation id="1195412055398077112">الخروج عن إطار الشاشة</translation>
diff --git a/ash/strings/ash_strings_as.xtb b/ash/strings/ash_strings_as.xtb
index 68d4340..79de747c 100644
--- a/ash/strings/ash_strings_as.xtb
+++ b/ash/strings/ash_strings_as.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">আপডে'টটো প্ৰয়োগ কৰিবলৈ ডিভাইচটো ৰিষ্টাৰ্ট কৰাৰ আৱশ্যক।</translation>
 <translation id="1175572348579024023">স্ক্ৰ’ল কৰক</translation>
 <translation id="1178581264944972037">পজ কৰক</translation>
+<translation id="1181037720776840403">আঁতৰাওক</translation>
 <translation id="118532027333893379">পূৰ্ণ স্ক্ৰীন কেপচাৰ কৰিবলৈ যিকোনো ঠাইতে টিপক</translation>
 <translation id="1190609913194133056">জাননী কেন্দ্ৰ</translation>
 <translation id="1195412055398077112">অ'ভাৰস্কেন</translation>
diff --git a/ash/strings/ash_strings_az.xtb b/ash/strings/ash_strings_az.xtb
index dde6e405..b0ad9d16 100644
--- a/ash/strings/ash_strings_az.xtb
+++ b/ash/strings/ash_strings_az.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Güncəlləməni tətbiq etmək üçün cihazı yenidən başlatmaq tələb olunur.</translation>
 <translation id="1175572348579024023">Sürüşdürün</translation>
 <translation id="1178581264944972037">Durdurun</translation>
+<translation id="1181037720776840403">Silin</translation>
 <translation id="118532027333893379">Tam ekranı çəkmək üçün istənilən yerə toxunun</translation>
 <translation id="1190609913194133056">Bildiriş Mərkəzi</translation>
 <translation id="1195412055398077112">overskan</translation>
diff --git a/ash/strings/ash_strings_be.xtb b/ash/strings/ash_strings_be.xtb
index cac4712..ee9f14f 100644
--- a/ash/strings/ash_strings_be.xtb
+++ b/ash/strings/ash_strings_be.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Каб прымяніць абнаўленне, трэба перазапусціць прыладу.</translation>
 <translation id="1175572348579024023">Прагартаць</translation>
 <translation id="1178581264944972037">Прыпыніць</translation>
+<translation id="1181037720776840403">Выдаліць</translation>
 <translation id="118532027333893379">Каб зняць увесь экран, націсніце ў любым яго месцы</translation>
 <translation id="1190609913194133056">Цэнтр апавяшчэнняў</translation>
 <translation id="1195412055398077112">вылет разгорткі</translation>
diff --git a/ash/strings/ash_strings_bg.xtb b/ash/strings/ash_strings_bg.xtb
index c6bfa45..c78c215 100644
--- a/ash/strings/ash_strings_bg.xtb
+++ b/ash/strings/ash_strings_bg.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Устройството трябва да се рестартира, за да се приложи актуализацията.</translation>
 <translation id="1175572348579024023">Превъртане</translation>
 <translation id="1178581264944972037">Пауза</translation>
+<translation id="1181037720776840403">Премахване</translation>
 <translation id="118532027333893379">Докоснете произволно място, за да се заснеме целият екран</translation>
 <translation id="1190609913194133056">Център за известия</translation>
 <translation id="1195412055398077112">допълнителна област</translation>
diff --git a/ash/strings/ash_strings_bn.xtb b/ash/strings/ash_strings_bn.xtb
index dcb5652..b004044 100644
--- a/ash/strings/ash_strings_bn.xtb
+++ b/ash/strings/ash_strings_bn.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">আপটেড প্রয়োগ করতে ডিভাইস রিস্টার্ট করুন।</translation>
 <translation id="1175572348579024023">স্ক্রল করুন</translation>
 <translation id="1178581264944972037">বিরতি</translation>
+<translation id="1181037720776840403">সরান</translation>
 <translation id="118532027333893379">ফুল স্ক্রিন ক্যাপচার করতে, যেখানে খুশি ট্যাপ করুন</translation>
 <translation id="1190609913194133056">বিজ্ঞপ্তি কেন্দ্র</translation>
 <translation id="1195412055398077112">ওভারস্ক্যান</translation>
diff --git a/ash/strings/ash_strings_bs.xtb b/ash/strings/ash_strings_bs.xtb
index 6a5a6e1..59bc1453 100644
--- a/ash/strings/ash_strings_bs.xtb
+++ b/ash/strings/ash_strings_bs.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Potrebno je ponovo pokrenuti uređaj kako bi se primijenilo ažuriranje.</translation>
 <translation id="1175572348579024023">Klizanje</translation>
 <translation id="1178581264944972037">Pauziraj</translation>
+<translation id="1181037720776840403">Ukloni</translation>
 <translation id="118532027333893379">Dodirnite bilo gdje da snimite cijeli ekran</translation>
 <translation id="1190609913194133056">Centar za obavijesti</translation>
 <translation id="1195412055398077112">ivično područje ekrana</translation>
diff --git a/ash/strings/ash_strings_ca.xtb b/ash/strings/ash_strings_ca.xtb
index 65e4a0a..67853e8 100644
--- a/ash/strings/ash_strings_ca.xtb
+++ b/ash/strings/ash_strings_ca.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Cal reiniciar el dispositiu per aplicar l'actualització.</translation>
 <translation id="1175572348579024023">Desplaça</translation>
 <translation id="1178581264944972037">Posa en pausa</translation>
+<translation id="1181037720776840403">Suprimeix</translation>
 <translation id="118532027333893379">Toca en qualsevol lloc per capturar la pantalla completa</translation>
 <translation id="1190609913194133056">Centre de notificacions</translation>
 <translation id="1195412055398077112">ajusta la mida</translation>
diff --git a/ash/strings/ash_strings_cs.xtb b/ash/strings/ash_strings_cs.xtb
index f6d44b7..8cb5de3 100644
--- a/ash/strings/ash_strings_cs.xtb
+++ b/ash/strings/ash_strings_cs.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">K použití aktualizace je potřeba restartovat zařízení.</translation>
 <translation id="1175572348579024023">Posunout</translation>
 <translation id="1178581264944972037">Pozastavit</translation>
+<translation id="1181037720776840403">Odebrat</translation>
 <translation id="118532027333893379">Klepnutím kamkoliv pořídíte snímek celé obrazovky</translation>
 <translation id="1190609913194133056">Centrum oznámení</translation>
 <translation id="1195412055398077112">přesah obrazu</translation>
diff --git a/ash/strings/ash_strings_da.xtb b/ash/strings/ash_strings_da.xtb
index 44e6857..53da6aa 100644
--- a/ash/strings/ash_strings_da.xtb
+++ b/ash/strings/ash_strings_da.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Enheden skal genstartes, før opdateringen anvendes.</translation>
 <translation id="1175572348579024023">Rul</translation>
 <translation id="1178581264944972037">Pause</translation>
+<translation id="1181037720776840403">Fjern</translation>
 <translation id="118532027333893379">Tryk et vilkårligt sted for at tage et billede af hele skærmen</translation>
 <translation id="1190609913194133056">Underretningcenter</translation>
 <translation id="1195412055398077112">overscan</translation>
diff --git a/ash/strings/ash_strings_de.xtb b/ash/strings/ash_strings_de.xtb
index 6c9b349e..dc0bc8f 100644
--- a/ash/strings/ash_strings_de.xtb
+++ b/ash/strings/ash_strings_de.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Das Gerät muss neu gestartet werden, um das Update zu installieren.</translation>
 <translation id="1175572348579024023">Scrollen</translation>
 <translation id="1178581264944972037">Pause</translation>
+<translation id="1181037720776840403">Entfernen</translation>
 <translation id="118532027333893379">Auf eine beliebige Stelle tippen, um den ganzen Bildschirm aufzunehmen</translation>
 <translation id="1190609913194133056">Benachrichtigungscenter</translation>
 <translation id="1195412055398077112">Overscan</translation>
diff --git a/ash/strings/ash_strings_el.xtb b/ash/strings/ash_strings_el.xtb
index f895211..fb35cd2 100644
--- a/ash/strings/ash_strings_el.xtb
+++ b/ash/strings/ash_strings_el.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Απαιτείται επανεκκίνηση της συσκευής για την εφαρμογή της ενημέρωσης.</translation>
 <translation id="1175572348579024023">Κύλιση</translation>
 <translation id="1178581264944972037">Παύση</translation>
+<translation id="1181037720776840403">Κατάργηση</translation>
 <translation id="118532027333893379">Πατήστε οπουδήποτε για καταγραφή πλήρους οθόνης</translation>
 <translation id="1190609913194133056">Κέντρο ειδοποιήσεων</translation>
 <translation id="1195412055398077112">υπερσάρωση</translation>
diff --git a/ash/strings/ash_strings_en-GB.xtb b/ash/strings/ash_strings_en-GB.xtb
index 75f9519..bad5b09 100644
--- a/ash/strings/ash_strings_en-GB.xtb
+++ b/ash/strings/ash_strings_en-GB.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Device restart is required to apply the update.</translation>
 <translation id="1175572348579024023">Scroll</translation>
 <translation id="1178581264944972037">Pause</translation>
+<translation id="1181037720776840403">Remove</translation>
 <translation id="118532027333893379">Tap anywhere to capture full screen</translation>
 <translation id="1190609913194133056">Notification Centre</translation>
 <translation id="1195412055398077112">overscan</translation>
diff --git a/ash/strings/ash_strings_es-419.xtb b/ash/strings/ash_strings_es-419.xtb
index 0bc7c3fc..acd6b4e 100644
--- a/ash/strings/ash_strings_es-419.xtb
+++ b/ash/strings/ash_strings_es-419.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Para aplicar la actualización, se debe reiniciar el dispositivo.</translation>
 <translation id="1175572348579024023">Desplazamiento</translation>
 <translation id="1178581264944972037">Detener</translation>
+<translation id="1181037720776840403">Quitar</translation>
 <translation id="118532027333893379">Presiona en cualquier lugar para capturar la pantalla completa</translation>
 <translation id="1190609913194133056">Centro de notificaciones</translation>
 <translation id="1195412055398077112">desajuste de dimensiones</translation>
diff --git a/ash/strings/ash_strings_es.xtb b/ash/strings/ash_strings_es.xtb
index 00dfcc571..6be6edc 100644
--- a/ash/strings/ash_strings_es.xtb
+++ b/ash/strings/ash_strings_es.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Se debe reiniciar el dispositivo para aplicar la actualización.</translation>
 <translation id="1175572348579024023">Desplazarse</translation>
 <translation id="1178581264944972037">Pausar</translation>
+<translation id="1181037720776840403">Quitar</translation>
 <translation id="118532027333893379">Toca en cualquier sitio para hacer una captura de la pantalla completa</translation>
 <translation id="1190609913194133056">Centro de notificaciones</translation>
 <translation id="1195412055398077112">reajustar</translation>
diff --git a/ash/strings/ash_strings_et.xtb b/ash/strings/ash_strings_et.xtb
index cab8c0c..1a87121 100644
--- a/ash/strings/ash_strings_et.xtb
+++ b/ash/strings/ash_strings_et.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Värskenduse rakendamiseks tuleb seade taaskäivitada.</translation>
 <translation id="1175572348579024023">Keri</translation>
 <translation id="1178581264944972037">Peata</translation>
+<translation id="1181037720776840403">Eemalda</translation>
 <translation id="118532027333893379">Täisekraani jäädvustamiseks puudutage ekraanikuval kus tahes</translation>
 <translation id="1190609913194133056">Märguannete keskus</translation>
 <translation id="1195412055398077112">liighälvitus</translation>
diff --git a/ash/strings/ash_strings_eu.xtb b/ash/strings/ash_strings_eu.xtb
index 59dd9cd..90ab818 100644
--- a/ash/strings/ash_strings_eu.xtb
+++ b/ash/strings/ash_strings_eu.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Gailua berrabiarazi egin behar da eguneratzea aplikatzeko.</translation>
 <translation id="1175572348579024023">Egin gora edo behera</translation>
 <translation id="1178581264944972037">Pausatu</translation>
+<translation id="1181037720776840403">Kendu</translation>
 <translation id="118532027333893379">Sakatu pantailako edozein puntu pantaila osoaren argazkia ateratzeko</translation>
 <translation id="1190609913194133056">Jakinarazpen-zentroa</translation>
 <translation id="1195412055398077112">bistaratzen ez den eremua</translation>
diff --git a/ash/strings/ash_strings_fa.xtb b/ash/strings/ash_strings_fa.xtb
index 5edbaf6..8eb44b2 100644
--- a/ash/strings/ash_strings_fa.xtb
+++ b/ash/strings/ash_strings_fa.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">دستگاه باید برای اعمال به‌روزرسانی بازراه‌اندازی شود.</translation>
 <translation id="1175572348579024023">پیمایش</translation>
 <translation id="1178581264944972037">مکث</translation>
+<translation id="1181037720776840403">حذف</translation>
 <translation id="118532027333893379">برای ضبط تمام صفحه، روی هرجایی که می‌خواهید ضربه بزنید</translation>
 <translation id="1190609913194133056">مرکز اعلان</translation>
 <translation id="1195412055398077112">بزرگ‌تر از صفحه</translation>
@@ -111,7 +112,7 @@
 <translation id="1882897271359938046">بازتاب به <ph name="DISPLAY_NAME" /></translation>
 <translation id="1885785240814121742">باز کردن قفل با اثر انگشت</translation>
 <translation id="1888656773939766144"><ph name="DISPLAY_NAME" /> از <ph name="SPECIFIED_RESOLUTION" /> (<ph name="SPECIFIED_REFRESH_RATE" /> هرتز) پشتیبانی نمی‌کند. وضوح به <ph name="FALLBACK_RESOLUTION" /> (<ph name="FALLBACK_REFRESH_RATE" />) تغییر کرده است. برای حفظ تغییرات، روی تأیید کلیک کنید. تنظیمات قبلی <ph name="TIMEOUT_SECONDS" /> دیگر بازیابی خواهد شد.</translation>
-<translation id="1919743966458266018">کلیدهای میان‌بر باز کردن مدیر فعالیت‌ها تغییر کرده است. لطفاً از <ph name="NEW_SHORTCUT" /> به جای <ph name="OLD_SHORTCUT" /> استفاده کنید.</translation>
+<translation id="1919743966458266018">کلیدهای میان‌بر باز کردن مدیر فعالیت‌ها تغییر کرده است. لطفاً از <ph name="NEW_SHORTCUT" /> به‌جای <ph name="OLD_SHORTCUT" /> استفاده کنید.</translation>
 <translation id="1923539912171292317">کلیک‌های خودکار</translation>
 <translation id="1928739107511554905">‏برای دریافت به‌روزرسانی، از صفحه لمسی برای بازراه‌اندازی Chromebook خود با صفحه‌کلید متصل استفاده کنید.</translation>
 <translation id="1951012854035635156">دستیار</translation>
diff --git a/ash/strings/ash_strings_fi.xtb b/ash/strings/ash_strings_fi.xtb
index c63a8524..04d352c 100644
--- a/ash/strings/ash_strings_fi.xtb
+++ b/ash/strings/ash_strings_fi.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Laite on käynnistettävä uudelleen, jotta päivitys voidaan ottaa käyttöön.</translation>
 <translation id="1175572348579024023">Vieritä</translation>
 <translation id="1178581264944972037">Tauko</translation>
+<translation id="1181037720776840403">Poista</translation>
 <translation id="118532027333893379">Tallenna koko näytön sisältö napauttamalla mitä tahansa kohtaa</translation>
 <translation id="1190609913194133056">Ilmoituskeskus</translation>
 <translation id="1195412055398077112">kuvasta rajataan pois osa</translation>
diff --git a/ash/strings/ash_strings_fil.xtb b/ash/strings/ash_strings_fil.xtb
index 24950d0..326973d 100644
--- a/ash/strings/ash_strings_fil.xtb
+++ b/ash/strings/ash_strings_fil.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Kailangang mag-restart ng device para mailapat ang update.</translation>
 <translation id="1175572348579024023">Mag-scroll</translation>
 <translation id="1178581264944972037">I-pause</translation>
+<translation id="1181037720776840403">Alisin</translation>
 <translation id="118532027333893379">Mag-tap kahit saan para i-capture ang full screen</translation>
 <translation id="1190609913194133056">Notification Center</translation>
 <translation id="1195412055398077112">overscan</translation>
diff --git a/ash/strings/ash_strings_fr-CA.xtb b/ash/strings/ash_strings_fr-CA.xtb
index b4e919f..1b64f20 100644
--- a/ash/strings/ash_strings_fr-CA.xtb
+++ b/ash/strings/ash_strings_fr-CA.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Vous devez redémarrer l'appareil pour appliquer la mise à jour.</translation>
 <translation id="1175572348579024023">Faire défiler</translation>
 <translation id="1178581264944972037">Interrompre</translation>
+<translation id="1181037720776840403">Supprimer</translation>
 <translation id="118532027333893379">Touchez n'importe où pour capturer la totalité de l'écran</translation>
 <translation id="1190609913194133056">Centre de notification</translation>
 <translation id="1195412055398077112">surbalayage</translation>
diff --git a/ash/strings/ash_strings_fr.xtb b/ash/strings/ash_strings_fr.xtb
index 9b3ad0cb..52a55a2 100644
--- a/ash/strings/ash_strings_fr.xtb
+++ b/ash/strings/ash_strings_fr.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Vous devez redémarrer l'appareil pour appliquer la mise à jour.</translation>
 <translation id="1175572348579024023">Faire défiler</translation>
 <translation id="1178581264944972037">Suspendre</translation>
+<translation id="1181037720776840403">Supprimer</translation>
 <translation id="118532027333893379">Appuyez n'importe où pour capturer tout l'écran</translation>
 <translation id="1190609913194133056">Centre de notification</translation>
 <translation id="1195412055398077112">Surbalayage</translation>
diff --git a/ash/strings/ash_strings_gl.xtb b/ash/strings/ash_strings_gl.xtb
index 9eb235ee1..01cb0c9 100644
--- a/ash/strings/ash_strings_gl.xtb
+++ b/ash/strings/ash_strings_gl.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">É necesario reiniciar o dispositivo para que se aplique a actualización.</translation>
 <translation id="1175572348579024023">Desprazarse</translation>
 <translation id="1178581264944972037">Pausar</translation>
+<translation id="1181037720776840403">Eliminar</translation>
 <translation id="118532027333893379">Toca calquera parte para facer unha captura da pantalla completa</translation>
 <translation id="1190609913194133056">Centro de notificacións</translation>
 <translation id="1195412055398077112">sobrevarrido</translation>
diff --git a/ash/strings/ash_strings_gu.xtb b/ash/strings/ash_strings_gu.xtb
index 4ba4200..73dfcb1a 100644
--- a/ash/strings/ash_strings_gu.xtb
+++ b/ash/strings/ash_strings_gu.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">અપડેટ લાગુ કરવા માટે ડિવાઇસને ફરી શરૂ કરવાની જરૂર છે.</translation>
 <translation id="1175572348579024023">સ્ક્રોલ કરો</translation>
 <translation id="1178581264944972037">થોભો</translation>
+<translation id="1181037720776840403">કાઢી નાખો</translation>
 <translation id="118532027333893379">પૂર્ણ સ્ક્રીન કૅપ્ચર કરવા માટે ગમે ત્યાં ટૅપ કરો</translation>
 <translation id="1190609913194133056">સૂચના કેન્દ્ર</translation>
 <translation id="1195412055398077112">ઓવરસ્કૅન</translation>
diff --git a/ash/strings/ash_strings_hi.xtb b/ash/strings/ash_strings_hi.xtb
index 76e7f53..c6687f4 100644
--- a/ash/strings/ash_strings_hi.xtb
+++ b/ash/strings/ash_strings_hi.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">अपडेट लागू करने के लिए डिवाइस को रीस्टार्ट करना होगा.</translation>
 <translation id="1175572348579024023">स्क्रोल करें</translation>
 <translation id="1178581264944972037">रोकें</translation>
+<translation id="1181037720776840403">हटाएं</translation>
 <translation id="118532027333893379">फ़ुल स्क्रीन को कैप्चर करने के लिए कहीं भी टैप करें</translation>
 <translation id="1190609913194133056">सूचना केंद्र</translation>
 <translation id="1195412055398077112">ओवरस्कैन</translation>
diff --git a/ash/strings/ash_strings_hr.xtb b/ash/strings/ash_strings_hr.xtb
index 199bafd..6bf2ad4 100644
--- a/ash/strings/ash_strings_hr.xtb
+++ b/ash/strings/ash_strings_hr.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Da bi se primijenilo ažuriranje, potrebno je ponovo pokrenuti uređaj.</translation>
 <translation id="1175572348579024023">Pomicanje</translation>
 <translation id="1178581264944972037">Pauziraj</translation>
+<translation id="1181037720776840403">Ukloni</translation>
 <translation id="118532027333893379">Dodirnite bilo gdje da biste snimili cijeli zaslon</translation>
 <translation id="1190609913194133056">Centar za obavijesti</translation>
 <translation id="1195412055398077112">rubno područje zaslona</translation>
diff --git a/ash/strings/ash_strings_hu.xtb b/ash/strings/ash_strings_hu.xtb
index 178db6e..209c2aa3 100644
--- a/ash/strings/ash_strings_hu.xtb
+++ b/ash/strings/ash_strings_hu.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Újraindításra van szükség a frissítés alkalmazásához.</translation>
 <translation id="1175572348579024023">Görgetés</translation>
 <translation id="1178581264944972037">Szünet</translation>
+<translation id="1181037720776840403">Eltávolítás</translation>
 <translation id="118532027333893379">Koppintson bárhova teljes képernyőkép készítéséhez</translation>
 <translation id="1190609913194133056">Értesítési központ</translation>
 <translation id="1195412055398077112">túlpásztázás</translation>
diff --git a/ash/strings/ash_strings_hy.xtb b/ash/strings/ash_strings_hy.xtb
index ef27752..cb3b694e 100644
--- a/ash/strings/ash_strings_hy.xtb
+++ b/ash/strings/ash_strings_hy.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Թարմացումը կիրառելու համար անհրաժեշտ է վերագործարկել սարքը։</translation>
 <translation id="1175572348579024023">Ոլորել</translation>
 <translation id="1178581264944972037">Դադար</translation>
+<translation id="1181037720776840403">Ջնջել</translation>
 <translation id="118532027333893379">Լիաէկրան ռեժիմում լուսանկարելու համար հպեք էկրանի ցանկացած կետի</translation>
 <translation id="1190609913194133056">Ծանուցումների կենտրոն</translation>
 <translation id="1195412055398077112">էկրանի եզերվածք</translation>
diff --git a/ash/strings/ash_strings_id.xtb b/ash/strings/ash_strings_id.xtb
index b96e257..b9f0798 100644
--- a/ash/strings/ash_strings_id.xtb
+++ b/ash/strings/ash_strings_id.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Perlu memulai ulang perangkat untuk menerapkan update.</translation>
 <translation id="1175572348579024023">Scroll</translation>
 <translation id="1178581264944972037">Jeda</translation>
+<translation id="1181037720776840403">Hapus</translation>
 <translation id="118532027333893379">Ketuk di mana saja untuk mengambil gambar dalam layar penuh</translation>
 <translation id="1190609913194133056">Pusat Notifikasi</translation>
 <translation id="1195412055398077112">pemindaian berlebih</translation>
diff --git a/ash/strings/ash_strings_is.xtb b/ash/strings/ash_strings_is.xtb
index 591b4790..85b0e8b 100644
--- a/ash/strings/ash_strings_is.xtb
+++ b/ash/strings/ash_strings_is.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Endurræsa þarf tækið til að nota uppfærsluna.</translation>
 <translation id="1175572348579024023">Fletta</translation>
 <translation id="1178581264944972037">Gera hlé</translation>
+<translation id="1181037720776840403">Fjarlægja</translation>
 <translation id="118532027333893379">Ýttu hvar sem er til að mynda allan skjáinn</translation>
 <translation id="1190609913194133056">Tilkynningamiðstöð</translation>
 <translation id="1195412055398077112">klipptur rammi</translation>
diff --git a/ash/strings/ash_strings_it.xtb b/ash/strings/ash_strings_it.xtb
index 5580c49d..f6b3aa1 100644
--- a/ash/strings/ash_strings_it.xtb
+++ b/ash/strings/ash_strings_it.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">È necessario riavviare il dispositivo per applicare l'aggiornamento.</translation>
 <translation id="1175572348579024023">Scorri</translation>
 <translation id="1178581264944972037">Pausa</translation>
+<translation id="1181037720776840403">Rimuovi</translation>
 <translation id="118532027333893379">Tocca un punto qualsiasi per acquisire l'intera schermata</translation>
 <translation id="1190609913194133056">Centro notifiche</translation>
 <translation id="1195412055398077112">overscan</translation>
diff --git a/ash/strings/ash_strings_iw.xtb b/ash/strings/ash_strings_iw.xtb
index 07ab2de0..c2558e3 100644
--- a/ash/strings/ash_strings_iw.xtb
+++ b/ash/strings/ash_strings_iw.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">יש להפעיל מחדש את המכשיר כדי להחיל את העדכון.</translation>
 <translation id="1175572348579024023">גלילה</translation>
 <translation id="1178581264944972037">השהיה</translation>
+<translation id="1181037720776840403">הסרה</translation>
 <translation id="118532027333893379">כדי לצלם את המסך המלא, יש להקיש במקום כלשהו</translation>
 <translation id="1190609913194133056">מרכז התראות</translation>
 <translation id="1195412055398077112">סריקת יתר</translation>
diff --git a/ash/strings/ash_strings_ja.xtb b/ash/strings/ash_strings_ja.xtb
index 5421b01e..fad15ca 100644
--- a/ash/strings/ash_strings_ja.xtb
+++ b/ash/strings/ash_strings_ja.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">アップデートを適用するにはデバイスの再起動が必要です。</translation>
 <translation id="1175572348579024023">スクロール</translation>
 <translation id="1178581264944972037">一時停止</translation>
+<translation id="1181037720776840403">削除</translation>
 <translation id="118532027333893379">全画面をキャプチャするには任意の場所をタップしてください</translation>
 <translation id="1190609913194133056">通知センター</translation>
 <translation id="1195412055398077112">オーバースキャン</translation>
diff --git a/ash/strings/ash_strings_ka.xtb b/ash/strings/ash_strings_ka.xtb
index ef8c836..9c97f7f 100644
--- a/ash/strings/ash_strings_ka.xtb
+++ b/ash/strings/ash_strings_ka.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">განახლების გასააქტიურებლად საჭიროა მოწყობილობის გადატვირთვა.</translation>
 <translation id="1175572348579024023">გადაადგილება</translation>
 <translation id="1178581264944972037">პაუზა</translation>
+<translation id="1181037720776840403">ამოშლა</translation>
 <translation id="118532027333893379">სრული ეკრანის აღსაბეჭდად შეეხეთ ნებისმიერ ადგილს</translation>
 <translation id="1190609913194133056">შეტყობინებათა ცენტრი</translation>
 <translation id="1195412055398077112">არასამუშაო არე</translation>
diff --git a/ash/strings/ash_strings_kk.xtb b/ash/strings/ash_strings_kk.xtb
index cd54adc..bd8bf30e 100644
--- a/ash/strings/ash_strings_kk.xtb
+++ b/ash/strings/ash_strings_kk.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Жаңарту күшіне енуі үшін, құрылғыны қайта іске қосу қажет.</translation>
 <translation id="1175572348579024023">Айналдыру</translation>
 <translation id="1178581264944972037">Кідірту</translation>
+<translation id="1181037720776840403">Өшіру</translation>
 <translation id="118532027333893379">Толық экранды түсіру үшін кез келген жерді басыңыз.</translation>
 <translation id="1190609913194133056">Хабарландыру орталығы</translation>
 <translation id="1195412055398077112">көрінбейтін бөлік</translation>
diff --git a/ash/strings/ash_strings_km.xtb b/ash/strings/ash_strings_km.xtb
index 080c11d..9a00d67 100644
--- a/ash/strings/ash_strings_km.xtb
+++ b/ash/strings/ash_strings_km.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">តម្រូវឱ្យ​ចាប់ផ្ដើម​ឧបករណ៍​ឡើងវិញ ដើម្បី​អនុវត្ត​កំណែថ្មី​។</translation>
 <translation id="1175572348579024023">រំកិល</translation>
 <translation id="1178581264944972037">ផ្អាក</translation>
+<translation id="1181037720776840403">ដកចេញ</translation>
 <translation id="118532027333893379">ចុចកន្លែង​ណាមួយ ដើម្បីថត​ពេញអេក្រង់</translation>
 <translation id="1190609913194133056">មជ្ឈមណ្ឌលជូនដំណឹង</translation>
 <translation id="1195412055398077112">ពង្រីកអេក្រង់ជ្រុល</translation>
diff --git a/ash/strings/ash_strings_kn.xtb b/ash/strings/ash_strings_kn.xtb
index 8ffd7b4..1a1384f 100644
--- a/ash/strings/ash_strings_kn.xtb
+++ b/ash/strings/ash_strings_kn.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">ಅಪ್‌ಡೇಟ್ ಅನ್ನು ಅನ್ವಯಿಸಲು ಸಾಧನವನ್ನು ಮರುಪ್ರಾರಂಭಿಸಬೇಕಾಗುತ್ತದೆ.</translation>
 <translation id="1175572348579024023">ಸ್ಕ್ರಾಲ್</translation>
 <translation id="1178581264944972037">ವಿರಾಮ</translation>
+<translation id="1181037720776840403">ತೆಗೆದುಹಾಕು</translation>
 <translation id="118532027333893379">ಪೂರ್ಣ-ಪರದೆಯನ್ನು ಕ್ಯಾಪ್ಚರ್ ಮಾಡಲು ಎಲ್ಲಿಯಾದರೂ ಟ್ಯಾಪ್ ಮಾಡಿ</translation>
 <translation id="1190609913194133056">ಅಧಿಸೂಚನೆಯ ಕೇಂದ್ರ</translation>
 <translation id="1195412055398077112">ಓವರ್‌ಸ್ಕ್ಯಾನ್</translation>
diff --git a/ash/strings/ash_strings_ko.xtb b/ash/strings/ash_strings_ko.xtb
index bf37b7a..d66fc219 100644
--- a/ash/strings/ash_strings_ko.xtb
+++ b/ash/strings/ash_strings_ko.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">업데이트를 적용하려면 기기를 다시 시작해야 합니다.</translation>
 <translation id="1175572348579024023">스크롤</translation>
 <translation id="1178581264944972037">일시중지</translation>
+<translation id="1181037720776840403">삭제</translation>
 <translation id="118532027333893379">전체 화면을 캡처하려면 아무 곳이나 탭하세요.</translation>
 <translation id="1190609913194133056">알림 센터</translation>
 <translation id="1195412055398077112">오버스캔</translation>
diff --git a/ash/strings/ash_strings_ky.xtb b/ash/strings/ash_strings_ky.xtb
index 5fed116..96e13e3 100644
--- a/ash/strings/ash_strings_ky.xtb
+++ b/ash/strings/ash_strings_ky.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Жаңыртууну иштетүү үчүн түзмөктү өчүрүп күйгүзүү талап кылынат.</translation>
 <translation id="1175572348579024023">Сыдыруу</translation>
 <translation id="1178581264944972037">Бир азга токтотуу</translation>
+<translation id="1181037720776840403">Алып салуу</translation>
 <translation id="118532027333893379">Толук экранды cүрөткө тартуу үчүн каалаган жерин басыңыз</translation>
 <translation id="1190609913194133056">Билдирмелер борбору</translation>
 <translation id="1195412055398077112">иштебеген аймак</translation>
@@ -287,7 +288,7 @@
 <translation id="3410336247007142655">Караңгы теманын жөндөөлөрүн көрсөтүү</translation>
 <translation id="3413817803639110246">Азырынча бир да эскертме жок</translation>
 <translation id="3428447136709161042"><ph name="NETWORK_NAME" /> тармагынан ажыратуу</translation>
-<translation id="3430396595145920809">Артка кайтуу үчүн экраныңыздын оң четинен серпип коюңуз</translation>
+<translation id="3430396595145920809">Артка кайтуу үчүн экраныңыздын оң четинен сүрүп коюңуз</translation>
 <translation id="343571671045587506">Эстеткичти түзөтүү</translation>
 <translation id="3435967511775410570">Манжа изи таанылды</translation>
 <translation id="3445288400492335833"><ph name="MINUTES" /> мүн.</translation>
@@ -903,7 +904,7 @@
 <translation id="8788027118671217603"><ph name="STATE_TEXT" />. <ph name="ENTERPRISE_TEXT" /></translation>
 <translation id="8814190375133053267">Wi-Fi</translation>
 <translation id="881757059229893486">Киргизүү ыкмаларынын жөндөөлөрү</translation>
-<translation id="8825863694328519386">Артка кайтуу үчүн, экраныңыздын сол четинен серпип коюңуз</translation>
+<translation id="8825863694328519386">Артка кайтуу үчүн, экраныңыздын сол четинен сүрүп коюңуз</translation>
 <translation id="8828714802988429505">90°</translation>
 <translation id="8841375032071747811">Артка баскычы</translation>
 <translation id="8843682306134542540">Буруу кулпусун өчүрүү/күйгүзүү. <ph name="STATE_TEXT" /></translation>
diff --git a/ash/strings/ash_strings_lo.xtb b/ash/strings/ash_strings_lo.xtb
index ed2715b..fc5e07c 100644
--- a/ash/strings/ash_strings_lo.xtb
+++ b/ash/strings/ash_strings_lo.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">ຈຳເປັນຕ້ອງຣິສະຕາດອຸປະກອນເພື່ອນຳໃຊ້ການອັບເດດ.</translation>
 <translation id="1175572348579024023">ເລື່ອນ</translation>
 <translation id="1178581264944972037">ຢຸດຊົ່ວຄາວ</translation>
+<translation id="1181037720776840403">ລຶບອອກ</translation>
 <translation id="118532027333893379">ແຕະບ່ອນໃດກໍໄດ້ເພື່ອຖ່າຍຮູບເຕັມຈໍ</translation>
 <translation id="1190609913194133056">ສູນ​ແຈ້ງ​ເຕືອນ</translation>
 <translation id="1195412055398077112">ສະແກນເກີນ</translation>
diff --git a/ash/strings/ash_strings_lt.xtb b/ash/strings/ash_strings_lt.xtb
index 4d23ee5..ccde824 100644
--- a/ash/strings/ash_strings_lt.xtb
+++ b/ash/strings/ash_strings_lt.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Norint pritaikyti naujinį, reikia paleisti įrenginį iš naujo.</translation>
 <translation id="1175572348579024023">Slinkti</translation>
 <translation id="1178581264944972037">Pristabdyti</translation>
+<translation id="1181037720776840403">Pašalinti</translation>
 <translation id="118532027333893379">Palieskite bet kur, kad būtų užfiksuotas visas ekranas</translation>
 <translation id="1190609913194133056">Pranešimų centras</translation>
 <translation id="1195412055398077112">sritis aplink vaizdo kraštus</translation>
diff --git a/ash/strings/ash_strings_lv.xtb b/ash/strings/ash_strings_lv.xtb
index c837fea..6c1c5f8e 100644
--- a/ash/strings/ash_strings_lv.xtb
+++ b/ash/strings/ash_strings_lv.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Lai lietotu atjauninājumu, ir jārestartē ierīce.</translation>
 <translation id="1175572348579024023">Ritināt</translation>
 <translation id="1178581264944972037">Pauzēt</translation>
+<translation id="1181037720776840403">Noņemt</translation>
 <translation id="118532027333893379">Pieskarieties jebkurā vietā, lai tvertu visu ekrānu</translation>
 <translation id="1190609913194133056">Paziņojumu centrs</translation>
 <translation id="1195412055398077112">attēla izvērse</translation>
diff --git a/ash/strings/ash_strings_mk.xtb b/ash/strings/ash_strings_mk.xtb
index b053389..6d8bd07 100644
--- a/ash/strings/ash_strings_mk.xtb
+++ b/ash/strings/ash_strings_mk.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Потребно е да се рестартира уредот за да се примени ажурирањето.</translation>
 <translation id="1175572348579024023">Лизгај</translation>
 <translation id="1178581264944972037">Пауза</translation>
+<translation id="1181037720776840403">Отстрани</translation>
 <translation id="118532027333893379">Допрете каде било за да го снимите целиот екран</translation>
 <translation id="1190609913194133056">Центар за известување</translation>
 <translation id="1195412055398077112">прескенирање</translation>
diff --git a/ash/strings/ash_strings_ml.xtb b/ash/strings/ash_strings_ml.xtb
index 185e956..ab01d2b 100644
--- a/ash/strings/ash_strings_ml.xtb
+++ b/ash/strings/ash_strings_ml.xtb
@@ -23,6 +23,7 @@
 <translation id="1153356358378277386">ജോടിയാക്കിയ ഉപകരണങ്ങൾ</translation>
 <translation id="1175572348579024023">സ്‌ക്രോൾ ചെയ്യുക</translation>
 <translation id="1178581264944972037">അല്പംനിര്‍ത്തൂ</translation>
+<translation id="1181037720776840403">നീക്കംചെയ്യൂ</translation>
 <translation id="118532027333893379">പൂർണ്ണ സ്ക്രീൻ ചിത്രമെടുക്കാൻ എവിടെയെങ്കിലും ടാപ്പ് ചെയ്യുക</translation>
 <translation id="1190609913194133056">അറിയിപ്പ് കേന്ദ്രം</translation>
 <translation id="1195412055398077112">ഓവർസ്‌കാൻ</translation>
diff --git a/ash/strings/ash_strings_mn.xtb b/ash/strings/ash_strings_mn.xtb
index d43ebb5..9c3806f 100644
--- a/ash/strings/ash_strings_mn.xtb
+++ b/ash/strings/ash_strings_mn.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Шинэчлэлтийг ашиглахын тулд төхөөрөмжөө дахин эхлүүлэх шаардлагатай.</translation>
 <translation id="1175572348579024023">Гүйлгэх</translation>
 <translation id="1178581264944972037">Түр зогсоох</translation>
+<translation id="1181037720776840403">Хасах</translation>
 <translation id="118532027333893379">Бүтэн дэлгэцийн зургийг авахын тулд дурын газар товшино уу</translation>
 <translation id="1190609913194133056">Мэдэгдлийн төв</translation>
 <translation id="1195412055398077112">Дэлгэцийн дүрс таарахгүй байх</translation>
diff --git a/ash/strings/ash_strings_mr.xtb b/ash/strings/ash_strings_mr.xtb
index 43dd1b8..c34480c 100644
--- a/ash/strings/ash_strings_mr.xtb
+++ b/ash/strings/ash_strings_mr.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">अपडेट लागू करण्यासाठी डिव्हाइस रीस्टार्ट करणे आवश्यक आहे.</translation>
 <translation id="1175572348579024023">स्क्रोल करा</translation>
 <translation id="1178581264944972037">विराम द्या</translation>
+<translation id="1181037720776840403">काढून टाका</translation>
 <translation id="118532027333893379">फुल स्क्रीन कॅप्चर करण्यासाठी कुठेही टॅप करा</translation>
 <translation id="1190609913194133056">सूचना केंद्र</translation>
 <translation id="1195412055398077112">ओव्हरस्कॅन</translation>
diff --git a/ash/strings/ash_strings_ms.xtb b/ash/strings/ash_strings_ms.xtb
index 24f657e..2e0f49d 100644
--- a/ash/strings/ash_strings_ms.xtb
+++ b/ash/strings/ash_strings_ms.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Peranti perlu dimulakan semula untuk memasang kemaskinian.</translation>
 <translation id="1175572348579024023">Tatal</translation>
 <translation id="1178581264944972037">Jeda</translation>
+<translation id="1181037720776840403">Alih keluar</translation>
 <translation id="118532027333893379">Ketik mana-mana bahagian untuk menangkap skrin penuh</translation>
 <translation id="1190609913194133056">Pusat Pemberitahuan</translation>
 <translation id="1195412055398077112">imbas lampau</translation>
diff --git a/ash/strings/ash_strings_my.xtb b/ash/strings/ash_strings_my.xtb
index 3ac23636..a073027 100644
--- a/ash/strings/ash_strings_my.xtb
+++ b/ash/strings/ash_strings_my.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">အပ်ဒိတ်ထည့်သွင်းရန် ကိရိယာကို ပြန်စရပါမည်။</translation>
 <translation id="1175572348579024023">လှိမ့်ရန်</translation>
 <translation id="1178581264944972037">ဆိုင်းငံ့ထားရန်</translation>
+<translation id="1181037720776840403">ဖယ်ရှားရန်</translation>
 <translation id="118532027333893379">ဖန်သားပြင်အပြည့် ရိုက်ယူရန် မည်သည့်နေရာကိုမဆို တို့ပါ</translation>
 <translation id="1190609913194133056">အသိပေးချက် စင်တာ</translation>
 <translation id="1195412055398077112">စကင်လုပ်</translation>
diff --git a/ash/strings/ash_strings_ne.xtb b/ash/strings/ash_strings_ne.xtb
index cc9f8e9..ef239f76 100644
--- a/ash/strings/ash_strings_ne.xtb
+++ b/ash/strings/ash_strings_ne.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">यो अपडेट लागू गर्न यन्त्र रिस्टार्ट गर्नु पर्ने हुन्छ।</translation>
 <translation id="1175572348579024023">स्क्रोल गर्नुहोस्</translation>
 <translation id="1178581264944972037">पज गर्नुहोस्</translation>
+<translation id="1181037720776840403">हटाउनुहोस्</translation>
 <translation id="118532027333893379">फुल स्क्रिनको फोटो खिच्न कुनै ठाउँमा ट्याप गर्नुहोस्</translation>
 <translation id="1190609913194133056">सूचना केन्द्र</translation>
 <translation id="1195412055398077112">अत्याधिकस्क्यान</translation>
diff --git a/ash/strings/ash_strings_nl.xtb b/ash/strings/ash_strings_nl.xtb
index 0be20883..1b22772 100644
--- a/ash/strings/ash_strings_nl.xtb
+++ b/ash/strings/ash_strings_nl.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Start het apparaat opnieuw op om de update toe te passen.</translation>
 <translation id="1175572348579024023">Scrollen</translation>
 <translation id="1178581264944972037">Onderbreken</translation>
+<translation id="1181037720776840403">Verwijderen</translation>
 <translation id="118532027333893379">Tik ergens om het hele scherm vast te leggen</translation>
 <translation id="1190609913194133056">Meldingscentrum</translation>
 <translation id="1195412055398077112">overscan</translation>
diff --git a/ash/strings/ash_strings_no.xtb b/ash/strings/ash_strings_no.xtb
index 266de8f9..83c651d 100644
--- a/ash/strings/ash_strings_no.xtb
+++ b/ash/strings/ash_strings_no.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Enheten må startes på nytt for at oppdateringen skal tas i bruk.</translation>
 <translation id="1175572348579024023">Rull</translation>
 <translation id="1178581264944972037">Stans midlertidig</translation>
+<translation id="1181037720776840403">Fjern</translation>
 <translation id="118532027333893379">Trykk hvor som helst for å ta bilde i fullskjerm</translation>
 <translation id="1190609913194133056">Varselsenter</translation>
 <translation id="1195412055398077112">overscan</translation>
diff --git a/ash/strings/ash_strings_or.xtb b/ash/strings/ash_strings_or.xtb
index 2d8821727..1ff41fa 100644
--- a/ash/strings/ash_strings_or.xtb
+++ b/ash/strings/ash_strings_or.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">ଅପଡେଟ୍ ଲାଗୁ କରିବା ପାଇଁ ଡିଭାଇସ୍ ରିଷ୍ଟାର୍ଟ କରିବା ଆବଶ୍ୟକ।</translation>
 <translation id="1175572348579024023">ସ୍କ୍ରୋଲ୍ କରନ୍ତୁ</translation>
 <translation id="1178581264944972037">ବିରତି</translation>
+<translation id="1181037720776840403">କାଢ଼ି ଦିଅନ୍ତୁ</translation>
 <translation id="118532027333893379">ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ୍ କ୍ୟାପଚର୍ କରିବାକୁ ସ୍କ୍ରିନର ଯେ କୌଣସି ସ୍ଥାନରେ ଟାପ୍ କରନ୍ତୁ</translation>
 <translation id="1190609913194133056">ବିଜ୍ଞପ୍ତି କେନ୍ଦ୍ର</translation>
 <translation id="1195412055398077112">ଓଭର୍‌ସ୍କାନ୍</translation>
diff --git a/ash/strings/ash_strings_pa.xtb b/ash/strings/ash_strings_pa.xtb
index 448f2b7..40fa1ad9 100644
--- a/ash/strings/ash_strings_pa.xtb
+++ b/ash/strings/ash_strings_pa.xtb
@@ -23,6 +23,7 @@
 <translation id="1153356358378277386">ਜੋੜਾਬੱਧ ਕੀਤੀਆਂ ਡੀਵਾਈਸਾਂ</translation>
 <translation id="1175572348579024023">ਸਕ੍ਰੋਲ</translation>
 <translation id="1178581264944972037">ਰੋਕੋ</translation>
+<translation id="1181037720776840403">ਹਟਾਓ</translation>
 <translation id="118532027333893379">ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਕੈਪਚਰ ਕਰਨ ਲਈ ਕਿਤੇ ਵੀ ਟੈਪ ਕਰੋ</translation>
 <translation id="1190609913194133056">ਸੂਚਨਾ ਕੇਂਦਰ</translation>
 <translation id="1195412055398077112">ਓਵਰਸਕੈਨ</translation>
diff --git a/ash/strings/ash_strings_pl.xtb b/ash/strings/ash_strings_pl.xtb
index 547b0ce5..b7909b8 100644
--- a/ash/strings/ash_strings_pl.xtb
+++ b/ash/strings/ash_strings_pl.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Aby zastosować aktualizację, musisz ponownie uruchomić urządzenie.</translation>
 <translation id="1175572348579024023">Przewijanie</translation>
 <translation id="1178581264944972037">Wstrzymaj</translation>
+<translation id="1181037720776840403">Usuń</translation>
 <translation id="118532027333893379">Aby zrobić zrzut całego ekranu, kliknij w dowolnym miejscu</translation>
 <translation id="1190609913194133056">Centrum powiadomień</translation>
 <translation id="1195412055398077112">nadmiarowość obrazu</translation>
diff --git a/ash/strings/ash_strings_pt-BR.xtb b/ash/strings/ash_strings_pt-BR.xtb
index 7db9f5b..415bfaf 100644
--- a/ash/strings/ash_strings_pt-BR.xtb
+++ b/ash/strings/ash_strings_pt-BR.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">É necessário reiniciar o dispositivo para aplicar a atualização.</translation>
 <translation id="1175572348579024023">Rolar</translation>
 <translation id="1178581264944972037">Pausar</translation>
+<translation id="1181037720776840403">Remover</translation>
 <translation id="118532027333893379">Toque em qualquer lugar para capturar a tela cheia</translation>
 <translation id="1190609913194133056">Central de Notificações</translation>
 <translation id="1195412055398077112">overscan</translation>
diff --git a/ash/strings/ash_strings_pt-PT.xtb b/ash/strings/ash_strings_pt-PT.xtb
index 3ce72b1..c68eba3ff 100644
--- a/ash/strings/ash_strings_pt-PT.xtb
+++ b/ash/strings/ash_strings_pt-PT.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">É necessário reiniciar o dispositivo para aplicar a atualização.</translation>
 <translation id="1175572348579024023">Deslocar</translation>
 <translation id="1178581264944972037">Pausa</translation>
+<translation id="1181037720776840403">Remover</translation>
 <translation id="118532027333893379">Toque em qualquer local para capturar o ecrã inteiro.</translation>
 <translation id="1190609913194133056">Centro de Notificações</translation>
 <translation id="1195412055398077112">overscan</translation>
diff --git a/ash/strings/ash_strings_ro.xtb b/ash/strings/ash_strings_ro.xtb
index 5d4da33..ec3bb56 100644
--- a/ash/strings/ash_strings_ro.xtb
+++ b/ash/strings/ash_strings_ro.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Pentru aplicarea actualizării este necesară repornirea dispozitivului.</translation>
 <translation id="1175572348579024023">Derulează</translation>
 <translation id="1178581264944972037">Întrerupe</translation>
+<translation id="1181037720776840403">Elimină</translation>
 <translation id="118532027333893379">Atinge oriunde pentru a captura ecranul complet</translation>
 <translation id="1190609913194133056">Centrul pentru notificări</translation>
 <translation id="1195412055398077112">suprascanare</translation>
diff --git a/ash/strings/ash_strings_ru.xtb b/ash/strings/ash_strings_ru.xtb
index fdc99ae2..41a22ca 100644
--- a/ash/strings/ash_strings_ru.xtb
+++ b/ash/strings/ash_strings_ru.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Чтобы применить обновление, необходимо перезапустить устройство.</translation>
 <translation id="1175572348579024023">Прокрутка</translation>
 <translation id="1178581264944972037">Пауза</translation>
+<translation id="1181037720776840403">Удалить</translation>
 <translation id="118532027333893379">Чтобы снять экран полностью, нажмите в любом его месте</translation>
 <translation id="1190609913194133056">Центр уведомлений</translation>
 <translation id="1195412055398077112">Каемка экрана</translation>
diff --git a/ash/strings/ash_strings_si.xtb b/ash/strings/ash_strings_si.xtb
index 76da5f1..bbae27f 100644
--- a/ash/strings/ash_strings_si.xtb
+++ b/ash/strings/ash_strings_si.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">යාවත්කාලීනය යෙදීම සඳහා උපාංග නැවත ආරම්භ කිරීම අවශ්‍ය වේ.</translation>
 <translation id="1175572348579024023">අනුචලන කරන්න</translation>
 <translation id="1178581264944972037">විරාමය</translation>
+<translation id="1181037720776840403">ඉවත් කරන්න</translation>
 <translation id="118532027333893379">පූර්ණ තිරය ග්‍රහණය කිරීමට ඕනෑම තැනක තට්ටු කරන්න</translation>
 <translation id="1190609913194133056">දැනුම්දීම් මධ්‍යස්ථානය</translation>
 <translation id="1195412055398077112">ඕවර්ස්කෑන්</translation>
diff --git a/ash/strings/ash_strings_sk.xtb b/ash/strings/ash_strings_sk.xtb
index d2097bf..0db34aa 100644
--- a/ash/strings/ash_strings_sk.xtb
+++ b/ash/strings/ash_strings_sk.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Uplatnenie aktualizácie vyžaduje reštartovanie zariadenia.</translation>
 <translation id="1175572348579024023">Posúvanie</translation>
 <translation id="1178581264944972037">Pozastaviť</translation>
+<translation id="1181037720776840403">Odstrániť</translation>
 <translation id="118532027333893379">Klepnutím na ľubovoľné miesto nasnímate celú obrazovku</translation>
 <translation id="1190609913194133056">Centrum upozornení</translation>
 <translation id="1195412055398077112">presah obsahu</translation>
diff --git a/ash/strings/ash_strings_sl.xtb b/ash/strings/ash_strings_sl.xtb
index af7b547..9ee301fc 100644
--- a/ash/strings/ash_strings_sl.xtb
+++ b/ash/strings/ash_strings_sl.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Če želite uveljaviti posodobitev, morate znova zagnati napravo.</translation>
 <translation id="1175572348579024023">Drseče pomikanje</translation>
 <translation id="1178581264944972037">Prekini</translation>
+<translation id="1181037720776840403">Odstrani</translation>
 <translation id="118532027333893379">Dotaknite se kjer koli za posnetek celotnega zaslona.</translation>
 <translation id="1190609913194133056">Središče za obvestila</translation>
 <translation id="1195412055398077112">upodabljanje čez rob zaslona</translation>
diff --git a/ash/strings/ash_strings_sq.xtb b/ash/strings/ash_strings_sq.xtb
index 7f8e58e..1bf0181f 100644
--- a/ash/strings/ash_strings_sq.xtb
+++ b/ash/strings/ash_strings_sq.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Kërkohet rinisja e pajisjes për të zbatuar përditësimin.</translation>
 <translation id="1175572348579024023">Lëviz</translation>
 <translation id="1178581264944972037">Pauzë</translation>
+<translation id="1181037720776840403">Hiq</translation>
 <translation id="118532027333893379">Trokit diku për të regjistruar ekranin e plotë</translation>
 <translation id="1190609913194133056">Qendra e njoftimeve</translation>
 <translation id="1195412055398077112">mbiskanim</translation>
diff --git a/ash/strings/ash_strings_sr-Latn.xtb b/ash/strings/ash_strings_sr-Latn.xtb
index 2df6ea03..da9bb480 100644
--- a/ash/strings/ash_strings_sr-Latn.xtb
+++ b/ash/strings/ash_strings_sr-Latn.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Restartujte uređaj da biste primenili ažuriranje.</translation>
 <translation id="1175572348579024023">Pomeraj</translation>
 <translation id="1178581264944972037">Pauziraj</translation>
+<translation id="1181037720776840403">Ukloni</translation>
 <translation id="118532027333893379">Dodirnite bilo gde da biste snimili ceo ekran</translation>
 <translation id="1190609913194133056">Centar za obaveštenja</translation>
 <translation id="1195412055398077112">ivično područje ekrana</translation>
diff --git a/ash/strings/ash_strings_sr.xtb b/ash/strings/ash_strings_sr.xtb
index c18ea4c..25bdf50a 100644
--- a/ash/strings/ash_strings_sr.xtb
+++ b/ash/strings/ash_strings_sr.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Рестартујте уређај да бисте применили ажурирање.</translation>
 <translation id="1175572348579024023">Померај</translation>
 <translation id="1178581264944972037">Паузирај</translation>
+<translation id="1181037720776840403">Уклони</translation>
 <translation id="118532027333893379">Додирните било где да бисте снимили цео екран</translation>
 <translation id="1190609913194133056">Центар за обавештења</translation>
 <translation id="1195412055398077112">ивично подручје екрана</translation>
diff --git a/ash/strings/ash_strings_sv.xtb b/ash/strings/ash_strings_sv.xtb
index 8ec23e7..c47a9517 100644
--- a/ash/strings/ash_strings_sv.xtb
+++ b/ash/strings/ash_strings_sv.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Enheten måste startas om för att uppdateringen ska tillämpas.</translation>
 <translation id="1175572348579024023">Rulla</translation>
 <translation id="1178581264944972037">Paus</translation>
+<translation id="1181037720776840403">Ta bort</translation>
 <translation id="118532027333893379">Tryck var som helst för att ta en bild av hela skärmen</translation>
 <translation id="1190609913194133056">Meddelandecenter</translation>
 <translation id="1195412055398077112">överskanning</translation>
diff --git a/ash/strings/ash_strings_sw.xtb b/ash/strings/ash_strings_sw.xtb
index ea3f899c..ff3993d 100644
--- a/ash/strings/ash_strings_sw.xtb
+++ b/ash/strings/ash_strings_sw.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Unahitaji kuzima kisha uwashe kifaa ili utekeleze sasisho.</translation>
 <translation id="1175572348579024023">Sogeza</translation>
 <translation id="1178581264944972037">Sitisha</translation>
+<translation id="1181037720776840403">Ondoa</translation>
 <translation id="118532027333893379">Gusa popote ili unase skrini nzima</translation>
 <translation id="1190609913194133056">Kituo cha Arifa</translation>
 <translation id="1195412055398077112">angalia kwa ujumla:</translation>
diff --git a/ash/strings/ash_strings_ta.xtb b/ash/strings/ash_strings_ta.xtb
index 93ebf5a..4a56c4e 100644
--- a/ash/strings/ash_strings_ta.xtb
+++ b/ash/strings/ash_strings_ta.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">புதுப்பிப்பை நிறுவ சாதனத்தை மீண்டும் தொடங்க வேண்டும்.</translation>
 <translation id="1175572348579024023">நகர்த்து</translation>
 <translation id="1178581264944972037">இடைநிறுத்து</translation>
+<translation id="1181037720776840403">அகற்று</translation>
 <translation id="118532027333893379">முழுத்திரையையும் படமெடுக்க எங்கேனும் தட்டவும்</translation>
 <translation id="1190609913194133056">அறிவிப்பு மையம்</translation>
 <translation id="1195412055398077112">ஓவர்ஸ்கேன்</translation>
diff --git a/ash/strings/ash_strings_te.xtb b/ash/strings/ash_strings_te.xtb
index b5fe91a0..de630e6 100644
--- a/ash/strings/ash_strings_te.xtb
+++ b/ash/strings/ash_strings_te.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">అప్‌డేట్‌ను వర్తింపజేయడానికి పరికరాన్ని రీస్టార్ట్ చేయాలి.</translation>
 <translation id="1175572348579024023">స్క్రోల్ చేస్తుంది</translation>
 <translation id="1178581264944972037">పాజ్ చేయి</translation>
+<translation id="1181037720776840403">తీసివేయి</translation>
 <translation id="118532027333893379">ఫుల్ స్క్రీన్‌ను క్యాప్చర్ చేయడానికి ఎక్కడైనా ట్యాప్ చేయండి</translation>
 <translation id="1190609913194133056">నోటిఫికేషన్ కేంద్రం</translation>
 <translation id="1195412055398077112">ఓవర్‌స్కాన్</translation>
diff --git a/ash/strings/ash_strings_th.xtb b/ash/strings/ash_strings_th.xtb
index 87c42c3..2ada905 100644
--- a/ash/strings/ash_strings_th.xtb
+++ b/ash/strings/ash_strings_th.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">ต้องรีสตาร์ทอุปกรณ์เพื่อใช้การอัปเดต</translation>
 <translation id="1175572348579024023">เลื่อน</translation>
 <translation id="1178581264944972037">หยุดชั่วคราว</translation>
+<translation id="1181037720776840403">นำออก</translation>
 <translation id="118532027333893379">แตะที่ใดก็ได้เพื่อจับภาพแบบเต็มหน้าจอ</translation>
 <translation id="1190609913194133056">ศูนย์การแจ้งเตือน</translation>
 <translation id="1195412055398077112">โอเวอร์สแกน</translation>
diff --git a/ash/strings/ash_strings_tr.xtb b/ash/strings/ash_strings_tr.xtb
index c51958e..b430108 100644
--- a/ash/strings/ash_strings_tr.xtb
+++ b/ash/strings/ash_strings_tr.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Güncellemenin uygulanması için cihazın yeniden başlatılması gerekiyor.</translation>
 <translation id="1175572348579024023">Kaydır</translation>
 <translation id="1178581264944972037">Duraklat</translation>
+<translation id="1181037720776840403">Kaldır</translation>
 <translation id="118532027333893379">Tam ekran görüntüsü almak için herhangi bir yere dokunun</translation>
 <translation id="1190609913194133056">Bildirim Merkezi</translation>
 <translation id="1195412055398077112">fazla tarama</translation>
diff --git a/ash/strings/ash_strings_uk.xtb b/ash/strings/ash_strings_uk.xtb
index 29ef2a2..1d91f18 100644
--- a/ash/strings/ash_strings_uk.xtb
+++ b/ash/strings/ash_strings_uk.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Щоб застосувати оновлення, потрібно перезапустити пристрій.</translation>
 <translation id="1175572348579024023">Прокрутити</translation>
 <translation id="1178581264944972037">Пауза</translation>
+<translation id="1181037720776840403">Видалити</translation>
 <translation id="118532027333893379">Натисніть будь-де, щоб зробити знімок усього екрана</translation>
 <translation id="1190609913194133056">Центр сповіщень</translation>
 <translation id="1195412055398077112">облямівка екрана</translation>
diff --git a/ash/strings/ash_strings_ur.xtb b/ash/strings/ash_strings_ur.xtb
index c8e82bb..c212260 100644
--- a/ash/strings/ash_strings_ur.xtb
+++ b/ash/strings/ash_strings_ur.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">اپ ڈیٹ لاگو کرنے کیلئے آلے کو ری سٹارٹ کرنا درکار ہے۔</translation>
 <translation id="1175572348579024023">اسکرول کریں</translation>
 <translation id="1178581264944972037">موقوف کریں</translation>
+<translation id="1181037720776840403">ہٹائیں</translation>
 <translation id="118532027333893379">فُل اسکرین کیپچر کرنے کیلئے کہیں پر بھی تھپتھپائیں</translation>
 <translation id="1190609913194133056">اطلاعاتی مرکز</translation>
 <translation id="1195412055398077112">اوور سکین</translation>
diff --git a/ash/strings/ash_strings_uz.xtb b/ash/strings/ash_strings_uz.xtb
index 4ff10f1f..83f59bc 100644
--- a/ash/strings/ash_strings_uz.xtb
+++ b/ash/strings/ash_strings_uz.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Yangilanishni tatbiq qilish uchun qurilmani oʻchirib yoqing.</translation>
 <translation id="1175572348579024023">Aylantirish</translation>
 <translation id="1178581264944972037">Pauza</translation>
+<translation id="1181037720776840403">Olib tashlash</translation>
 <translation id="118532027333893379">Butun ekranni rasmga olish uchun ekranning istalgan joyiga bosing</translation>
 <translation id="1190609913194133056">Bildirishnomalar markazi</translation>
 <translation id="1195412055398077112">overscan</translation>
diff --git a/ash/strings/ash_strings_vi.xtb b/ash/strings/ash_strings_vi.xtb
index 84d0c74f..0303e10 100644
--- a/ash/strings/ash_strings_vi.xtb
+++ b/ash/strings/ash_strings_vi.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Bạn cần phải khởi động lại thiết bị để áp dụng bản cập nhật.</translation>
 <translation id="1175572348579024023">Cuộn</translation>
 <translation id="1178581264944972037">Tạm dừng</translation>
+<translation id="1181037720776840403">Xóa</translation>
 <translation id="118532027333893379">Nhấn vào vị trí bất kỳ để chụp toàn màn hình</translation>
 <translation id="1190609913194133056">Trung tâm thông báo</translation>
 <translation id="1195412055398077112">quét quá mức</translation>
diff --git a/ash/strings/ash_strings_zh-CN.xtb b/ash/strings/ash_strings_zh-CN.xtb
index 073ebb4f..deca32d 100644
--- a/ash/strings/ash_strings_zh-CN.xtb
+++ b/ash/strings/ash_strings_zh-CN.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">必须重启设备,才能应用这项更新。</translation>
 <translation id="1175572348579024023">滚动</translation>
 <translation id="1178581264944972037">暂停</translation>
+<translation id="1181037720776840403">移除</translation>
 <translation id="118532027333893379">点按任意位置即可截取整个屏幕</translation>
 <translation id="1190609913194133056">通知中心</translation>
 <translation id="1195412055398077112">过扫描</translation>
diff --git a/ash/strings/ash_strings_zh-HK.xtb b/ash/strings/ash_strings_zh-HK.xtb
index 7725bc9..e50f15b 100644
--- a/ash/strings/ash_strings_zh-HK.xtb
+++ b/ash/strings/ash_strings_zh-HK.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">裝置必須重新啟動,才能套用更新。</translation>
 <translation id="1175572348579024023">捲動</translation>
 <translation id="1178581264944972037">暫停</translation>
+<translation id="1181037720776840403">移除</translation>
 <translation id="118532027333893379">輕按任何一處即可擷取全螢幕畫面</translation>
 <translation id="1190609913194133056">通知中心</translation>
 <translation id="1195412055398077112">溢出掃描描</translation>
diff --git a/ash/strings/ash_strings_zh-TW.xtb b/ash/strings/ash_strings_zh-TW.xtb
index 71f2c68..eeb9375 100644
--- a/ash/strings/ash_strings_zh-TW.xtb
+++ b/ash/strings/ash_strings_zh-TW.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">必須重新啟動裝置才能套用更新。</translation>
 <translation id="1175572348579024023">捲動</translation>
 <translation id="1178581264944972037">暫停</translation>
+<translation id="1181037720776840403">移除</translation>
 <translation id="118532027333893379">輕觸任一處即可擷取全螢幕畫面</translation>
 <translation id="1190609913194133056">通知中心</translation>
 <translation id="1195412055398077112">遮視區域</translation>
diff --git a/ash/strings/ash_strings_zu.xtb b/ash/strings/ash_strings_zu.xtb
index f9bb251b..de754fb 100644
--- a/ash/strings/ash_strings_zu.xtb
+++ b/ash/strings/ash_strings_zu.xtb
@@ -24,6 +24,7 @@
 <translation id="1165712434476988950">Ukuqala kabusha idivayisi kudingekile ukuze usebenzise isibuyekezo.</translation>
 <translation id="1175572348579024023">Skrola</translation>
 <translation id="1178581264944972037">Misa isikhashana</translation>
+<translation id="1181037720776840403">Susa</translation>
 <translation id="118532027333893379">Thepha noma kuphi ukuthatha isikrini esigcwele</translation>
 <translation id="1190609913194133056">Isikhungo Sokwazisa</translation>
 <translation id="1195412055398077112">skena ngaphezulu</translation>
diff --git a/ash/wm/desks/expanded_state_new_desk_button.h b/ash/wm/desks/expanded_state_new_desk_button.h
index a6dbf51d..1affab60 100644
--- a/ash/wm/desks/expanded_state_new_desk_button.h
+++ b/ash/wm/desks/expanded_state_new_desk_button.h
@@ -16,11 +16,6 @@
 class DeskButtonBase;
 class DesksBarView;
 
-// TODO(minch): Build the base class DeskMiniViewBase, and let both the
-// ExpandedStateNewDeskButton and DeskMiniView inherit from it. Then the
-// expanded state new desk button can be treated the same as |mini_views_| in
-// DesksBarView. It then can share the same animation and layout as other mini
-// views.
 // The new desk button view in the expanded desks bar in Bento. It includes the
 // InnerNewDeskButton and a name label below, which has the same style as a
 // DeskMiniVIew. But the name label is not changeable and not focusable.
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 53ed8ae4..42c91ab 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -2238,6 +2238,7 @@
       "trace_event/trace_log_constants.cc",
       "trace_event/traced_value.cc",
       "trace_event/traced_value.h",
+      "trace_event/traced_value_support.h",
       "trace_event/tracing_agent.cc",
       "trace_event/tracing_agent.h",
       "trace_event/typed_macros.h",
diff --git a/base/OWNERS b/base/OWNERS
index 6de5db7..9f34eac 100644
--- a/base/OWNERS
+++ b/base/OWNERS
@@ -12,6 +12,11 @@
 thestig@chromium.org
 wez@chromium.org
 
+# per-file rules:
+# These are for the common case of adding or renaming files. If you're doing
+# structural changes, please get a review from a reviewer in this file.
+per-file BUILD.gn=*
+
 # For Android-specific changes:
 per-file *android*=file://base/android/OWNERS
 per-file BUILD.gn=file://base/android/OWNERS
diff --git a/base/allocator/partition_allocator/object_bitmap.h b/base/allocator/partition_allocator/object_bitmap.h
index c1ee1d3..2fcbb24 100644
--- a/base/allocator/partition_allocator/object_bitmap.h
+++ b/base/allocator/partition_allocator/object_bitmap.h
@@ -66,6 +66,10 @@
   template <AccessType = AccessType::kAtomic, typename Callback>
   inline void Iterate(Callback) const;
 
+  // Same as above, but also clears the bitmap while iterating.
+  template <AccessType = AccessType::kAtomic, typename Callback>
+  inline void IterateAndClear(Callback);
+
   inline void Clear();
 
  private:
@@ -76,6 +80,9 @@
     return reinterpret_cast<const std::atomic<CellType>&>(bitmap_[cell_index]);
   }
 
+  template <AccessType = AccessType::kAtomic, typename Callback, bool Clear>
+  inline void IterateImpl(Callback);
+
   template <AccessType>
   ALWAYS_INLINE CellType LoadCell(size_t cell_index) const;
   ALWAYS_INLINE static constexpr std::pair<size_t, size_t> ObjectIndexAndBit(
@@ -167,9 +174,10 @@
 template <size_t PageSize, size_t PageAlignment, size_t ObjectAlignment>
 template <typename ObjectBitmap<PageSize, PageAlignment, ObjectAlignment>::
               AccessType access_type,
-          typename Callback>
-inline void ObjectBitmap<PageSize, PageAlignment, ObjectAlignment>::Iterate(
-    Callback callback) const {
+          typename Callback,
+          bool should_clear>
+inline void ObjectBitmap<PageSize, PageAlignment, ObjectAlignment>::IterateImpl(
+    Callback callback) {
   // The bitmap (|this|) is allocated inside the page with |kPageAlignment|.
   const uintptr_t base = reinterpret_cast<uintptr_t>(this) & kPageBaseMask;
   for (size_t cell_index = 0; cell_index < kBitmapSize; ++cell_index) {
@@ -184,10 +192,37 @@
       // Clear current object bit in temporary value to advance iteration.
       value &= ~(static_cast<CellType>(1) << trailing_zeroes);
     }
+    if (should_clear) {
+      if (access_type == AccessType::kNonAtomic) {
+        bitmap_[cell_index] = 0;
+      } else {
+        AsAtomicCell(cell_index).store(0, std::memory_order_relaxed);
+      }
+    }
   }
 }
 
 template <size_t PageSize, size_t PageAlignment, size_t ObjectAlignment>
+template <typename ObjectBitmap<PageSize, PageAlignment, ObjectAlignment>::
+              AccessType access_type,
+          typename Callback>
+inline void ObjectBitmap<PageSize, PageAlignment, ObjectAlignment>::Iterate(
+    Callback callback) const {
+  const_cast<ObjectBitmap&>(*this)
+      .template IterateImpl<access_type, Callback, false>(std::move(callback));
+}
+
+template <size_t PageSize, size_t PageAlignment, size_t ObjectAlignment>
+template <typename ObjectBitmap<PageSize, PageAlignment, ObjectAlignment>::
+              AccessType access_type,
+          typename Callback>
+inline void
+ObjectBitmap<PageSize, PageAlignment, ObjectAlignment>::IterateAndClear(
+    Callback callback) {
+  IterateImpl<access_type, Callback, true>(std::move(callback));
+}
+
+template <size_t PageSize, size_t PageAlignment, size_t ObjectAlignment>
 void ObjectBitmap<PageSize, PageAlignment, ObjectAlignment>::Clear() {
   std::fill(bitmap_.begin(), bitmap_.end(), '\0');
 }
diff --git a/base/allocator/partition_allocator/object_bitmap_unittest.cc b/base/allocator/partition_allocator/object_bitmap_unittest.cc
index 2892d67a..66030f8 100644
--- a/base/allocator/partition_allocator/object_bitmap_unittest.cc
+++ b/base/allocator/partition_allocator/object_bitmap_unittest.cc
@@ -165,5 +165,21 @@
   EXPECT_EQ(2u, count);
 }
 
+TYPED_TEST(ObjectBitmapTest, IterateAndClearBitmap) {
+  static constexpr AccessType kAccessType = TestFixture::kAccessType;
+
+  size_t expected_count = 0;
+  for (size_t i = 0; i < this->LastIndex(); i += 2, ++expected_count) {
+    this->SetBitForObject(i);
+  }
+
+  size_t actual_count = 0;
+  this->bitmap().template IterateAndClear<kAccessType>(
+      [&actual_count](uintptr_t current) { ++actual_count; });
+
+  EXPECT_EQ(expected_count, actual_count);
+  EXPECT_TRUE(this->IsEmpty());
+}
+
 }  // namespace internal
 }  // namespace base
diff --git a/base/allocator/partition_allocator/pcscan.cc b/base/allocator/partition_allocator/pcscan.cc
index de261e8..3a5eb3e 100644
--- a/base/allocator/partition_allocator/pcscan.cc
+++ b/base/allocator/partition_allocator/pcscan.cc
@@ -652,14 +652,13 @@
         QuarantineBitmapType::kScanner, pcscan_.quarantine_data_.epoch(),
         reinterpret_cast<char*>(super_page));
     auto* root = Root::FromSuperPage(reinterpret_cast<char*>(super_page));
-    bitmap->template Iterate<AccessType::kNonAtomic>(
+    bitmap->template IterateAndClear<AccessType::kNonAtomic>(
         [root, &swept_bytes](uintptr_t ptr) {
           auto* object = reinterpret_cast<void*>(ptr);
           auto* slot_span = SlotSpan::FromSlotInnerPtr(object);
           swept_bytes += slot_span->bucket->slot_size;
           root->FreeNoHooksImmediate(object, slot_span);
         });
-    bitmap->Clear();
   }
 
   return swept_bytes;
diff --git a/base/android/java/src/org/chromium/base/EarlyTraceEvent.java b/base/android/java/src/org/chromium/base/EarlyTraceEvent.java
index a427a3d..4fc9987 100644
--- a/base/android/java/src/org/chromium/base/EarlyTraceEvent.java
+++ b/base/android/java/src/org/chromium/base/EarlyTraceEvent.java
@@ -40,9 +40,6 @@
 @JNINamespace("base::android")
 @MainDex
 public class EarlyTraceEvent {
-    // Must be kept in sync with the native kAndroidTraceConfigFile.
-    private static final String TRACE_CONFIG_FILENAME = "/data/local/chrome-trace-config.json";
-
     /** Single trace event. */
     @VisibleForTesting
     static final class Event {
@@ -85,15 +82,37 @@
     @VisibleForTesting static final int STATE_ENABLED = 1;
     @VisibleForTesting
     static final int STATE_FINISHED = 2;
+    @VisibleForTesting
+    static volatile int sState = STATE_DISABLED;
+
+    // In child processes the CommandLine is not available immediately, so early tracing is enabled
+    // unconditionally in Chrome. This flag allows not to enable early tracing twice in this case.
+    private static volatile boolean sEnabledInChildProcessBeforeCommandLine;
 
     private static final String BACKGROUND_STARTUP_TRACING_ENABLED_KEY = "bg_startup_tracing";
     private static boolean sCachedBackgroundStartupTracingFlag;
 
-    // Locks the fields below.
+    // Early tracing can be enabled on browser start if the browser finds this file present. Must be
+    // kept in sync with the native kAndroidTraceConfigFile.
+    private static final String TRACE_CONFIG_FILENAME = "/data/local/chrome-trace-config.json";
+
+    // Early tracing can be enabled on browser start if the browser finds this command line switch.
+    // Must be kept in sync with switches::kTraceStartup.
+    private static final String TRACE_STARTUP_SWITCH = "trace-startup";
+
+    // Added to child process switches if tracing is enabled when the process is getting created.
+    // The flag is checked early in child process lifetime to have a solid guarantee that the early
+    // java tracing is not enabled forever. Native flags cannot be used for this purpose because the
+    // native library is not loaded at the moment. Cannot set --trace-startup for the child to avoid
+    // overriding the list of categories it may load from the config later. Also --trace-startup
+    // depends on other flags that early tracing should not know about. Public for use in
+    // ChildProcessLauncherHelperImpl.
+    public static final String TRACE_EARLY_JAVA_IN_CHILD_SWITCH = "trace-early-java-in-child";
+
+    // Protects the fields below.
     private static final Object sLock = new Object();
 
-    @VisibleForTesting static volatile int sState = STATE_DISABLED;
-    // Not final as these object are not likely to be used at all.
+    // Not final because in many configurations these objects are not used.
     @GuardedBy("sLock")
     @VisibleForTesting
     static List<Event> sEvents;
@@ -101,15 +120,17 @@
     @VisibleForTesting
     static List<AsyncEvent> sAsyncEvents;
 
-    /** @see TraceEvent#maybeEnableEarlyTracing() */
-    static void maybeEnable() {
+    /** @see TraceEvent#maybeEnableEarlyTracing(long, boolean) */
+    static void maybeEnableInBrowserProcess() {
         ThreadUtils.assertOnUiThread();
+        assert !sEnabledInChildProcessBeforeCommandLine
+            : "Should not have been initialized in a child process";
         if (sState != STATE_DISABLED) return;
         boolean shouldEnable = false;
         // Checking for the trace config filename touches the disk.
         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
         try {
-            if (CommandLine.getInstance().hasSwitch("trace-startup")) {
+            if (CommandLine.getInstance().hasSwitch(TRACE_STARTUP_SWITCH)) {
                 shouldEnable = true;
             } else {
                 try {
@@ -136,6 +157,36 @@
         if (shouldEnable) enable();
     }
 
+    /**
+     * Enables early tracing in child processes before CommandLine arrives there.
+     */
+    public static void earlyEnableInChildWithoutCommandLine() {
+        sEnabledInChildProcessBeforeCommandLine = true;
+        assert sState == STATE_DISABLED;
+        enable();
+    }
+
+    /**
+     * Based on a command line switch from the process launcher, enables or resets early tracing.
+     * Should be called only in child processes and as soon as possible after the CommandLine is
+     * initialized.
+     */
+    public static void onCommandLineAvailableInChildProcess() {
+        // Ignore early Java tracing in WebView and other startup configurations that did not start
+        // collecting events before the command line was available.
+        if (!sEnabledInChildProcessBeforeCommandLine) return;
+        synchronized (sLock) {
+            // Remove early trace events if the child process launcher did not ask for early
+            // tracing.
+            if (!CommandLine.getInstance().hasSwitch(TRACE_EARLY_JAVA_IN_CHILD_SWITCH)) {
+                reset();
+                return;
+            }
+            // Otherwise continue with tracing enabled.
+            if (sState == STATE_DISABLED) enable();
+        }
+    }
+
     static void enable() {
         synchronized (sLock) {
             if (sState != STATE_DISABLED) return;
@@ -169,6 +220,18 @@
         }
     }
 
+    /**
+     * Stops early tracing without flushing the buffered events.
+     */
+    @VisibleForTesting
+    static void reset() {
+        synchronized (sLock) {
+            sState = STATE_DISABLED;
+            sEvents = null;
+            sAsyncEvents = null;
+        }
+    }
+
     static boolean enabled() {
         return sState == STATE_ENABLED;
     }
@@ -237,15 +300,6 @@
         }
     }
 
-    @VisibleForTesting
-    static void resetForTesting() {
-        synchronized (sLock) {
-            sState = EarlyTraceEvent.STATE_DISABLED;
-            sEvents = null;
-            sAsyncEvents = null;
-        }
-    }
-
     private static void dumpEvents(List<Event> events) {
         long offsetNanos = getOffsetNanos();
         for (Event e : events) {
diff --git a/base/android/java/src/org/chromium/base/TraceEvent.java b/base/android/java/src/org/chromium/base/TraceEvent.java
index 3bf2f9d0..f6f296dc 100644
--- a/base/android/java/src/org/chromium/base/TraceEvent.java
+++ b/base/android/java/src/org/chromium/base/TraceEvent.java
@@ -635,7 +635,7 @@
         // done for Chrome since WebView tracing isn't controlled with command
         // line flags.
         if (readCommandLine) {
-            EarlyTraceEvent.maybeEnable();
+            EarlyTraceEvent.maybeEnableInBrowserProcess();
         }
         if (traceTag != 0) {
             sATrace = new ATrace(traceTag);
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java
index e7ba01b1..ca80306 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java
@@ -23,6 +23,7 @@
 import org.chromium.base.BaseSwitches;
 import org.chromium.base.CommandLine;
 import org.chromium.base.ContextUtils;
+import org.chromium.base.EarlyTraceEvent;
 import org.chromium.base.Log;
 import org.chromium.base.MemoryPressureLevel;
 import org.chromium.base.ThreadUtils;
@@ -245,6 +246,7 @@
                         android.os.Debug.waitForDebugger();
                     }
 
+                    EarlyTraceEvent.onCommandLineAvailableInChildProcess();
                     mDelegate.loadNativeLibrary(getApplicationContext());
 
                     synchronized (mLibraryInitializedLock) {
diff --git a/base/android/javatests/src/org/chromium/base/EarlyTraceEventTest.java b/base/android/javatests/src/org/chromium/base/EarlyTraceEventTest.java
index e08f6b4b..35a045c1 100644
--- a/base/android/javatests/src/org/chromium/base/EarlyTraceEventTest.java
+++ b/base/android/javatests/src/org/chromium/base/EarlyTraceEventTest.java
@@ -26,14 +26,13 @@
 /**
  * Tests for {@link EarlyTraceEvent}.
  *
- * TODO(lizeb): Move to roboelectric tests.
+ * TODO(lizeb): Move to robolectric tests.
  */
 @RunWith(BaseJUnit4ClassRunner.class)
 public class EarlyTraceEventTest {
     private static final String EVENT_NAME = "MyEvent";
     private static final String EVENT_NAME2 = "MyOtherEvent";
     private static final long EVENT_ID = 1;
-    private static final long EVENT_ID2 = 2;
 
     List<Event> getMatchingCompletedEvents(String eventName) {
         List<Event> matchingEvents = new ArrayList<Event>();
@@ -48,7 +47,7 @@
     @Before
     public void setUp() {
         LibraryLoader.getInstance().ensureInitialized();
-        EarlyTraceEvent.resetForTesting();
+        EarlyTraceEvent.reset();
     }
 
     @Test
@@ -77,7 +76,7 @@
         Assert.assertTrue(beforeNanos <= beginEvent.mTimeNanos);
         Assert.assertTrue(endEvent.mTimeNanos <= afterNanos);
         Assert.assertTrue(beforeThreadMillis <= beginEvent.mThreadTimeMillis);
-        Assert.assertTrue(endEvent.mThreadTimeMillis <= beforeThreadMillis);
+        Assert.assertTrue(endEvent.mThreadTimeMillis <= afterThreadMillis);
     }
 
     @Test
@@ -212,13 +211,13 @@
     @Feature({"Android-AppBase"})
     public void testEnableAtStartup() {
         ThreadUtils.setThreadAssertsDisabledForTesting(true);
-        EarlyTraceEvent.maybeEnable();
+        EarlyTraceEvent.maybeEnableInBrowserProcess();
         Assert.assertFalse(EarlyTraceEvent.enabled());
         EarlyTraceEvent.setBackgroundStartupTracingFlag(false);
         Assert.assertFalse(EarlyTraceEvent.enabled());
 
         EarlyTraceEvent.setBackgroundStartupTracingFlag(true);
-        EarlyTraceEvent.maybeEnable();
+        EarlyTraceEvent.maybeEnableInBrowserProcess();
         Assert.assertTrue(EarlyTraceEvent.getBackgroundStartupTracingFlag());
         Assert.assertTrue(EarlyTraceEvent.enabled());
         EarlyTraceEvent.disable();
@@ -233,10 +232,35 @@
         // Setting command line should disable the background tracing flag.
         CommandLine.getInstance().appendSwitch("trace-startup");
         EarlyTraceEvent.setBackgroundStartupTracingFlag(true);
-        EarlyTraceEvent.maybeEnable();
+        EarlyTraceEvent.maybeEnableInBrowserProcess();
         Assert.assertFalse(EarlyTraceEvent.getBackgroundStartupTracingFlag());
         Assert.assertTrue(EarlyTraceEvent.enabled());
         EarlyTraceEvent.disable();
         EarlyTraceEvent.setBackgroundStartupTracingFlag(false);
     }
+
+    @Test
+    @SmallTest
+    @Feature({"Android-AppBase"})
+    public void testEnableInChildProcess() {
+        ThreadUtils.setThreadAssertsDisabledForTesting(true);
+        EarlyTraceEvent.earlyEnableInChildWithoutCommandLine();
+        Assert.assertTrue(EarlyTraceEvent.enabled());
+        CommandLine.getInstance().appendSwitch("trace-early-java-in-child");
+        EarlyTraceEvent.onCommandLineAvailableInChildProcess();
+        Assert.assertTrue(EarlyTraceEvent.enabled());
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Android-AppBase"})
+    public void testEnableInChildProcessCommandLineLaterOverrides() {
+        ThreadUtils.setThreadAssertsDisabledForTesting(true);
+        EarlyTraceEvent.earlyEnableInChildWithoutCommandLine();
+        Assert.assertTrue(EarlyTraceEvent.enabled());
+        CommandLine.getInstance().removeSwitch("trace-early-java-in-child");
+        EarlyTraceEvent.onCommandLineAvailableInChildProcess();
+        Assert.assertFalse(EarlyTraceEvent.enabled());
+        Assert.assertNull(EarlyTraceEvent.sEvents);
+    }
 }
diff --git a/base/containers/checked_iterators_unittest.cc b/base/containers/checked_iterators_unittest.cc
index b4a4432..9f201beb 100644
--- a/base/containers/checked_iterators_unittest.cc
+++ b/base/containers/checked_iterators_unittest.cc
@@ -81,6 +81,9 @@
 }
 
 #if defined(_LIBCPP_VERSION)
+// TODO(crbug.com/1166360): This optimization was broken by upstream libc++
+// changes. Work around the issue and re-enable the test.
+#if 0
 namespace {
 
 // Helper template that wraps an iterator and disables its dereference and
@@ -120,6 +123,7 @@
   EXPECT_TRUE(std::equal(std::begin(arr_in), std::end(arr_in),
                          std::begin(arr_out), std::end(arr_out)));
 }
+#endif
 
 TEST(CheckedContiguousIterator, UnwrapIter) {
   static_assert(
diff --git a/base/trace_event/common/trace_event_common.h b/base/trace_event/common/trace_event_common.h
index 17947a95..9b6783b 100644
--- a/base/trace_event/common/trace_event_common.h
+++ b/base/trace_event/common/trace_event_common.h
@@ -1107,6 +1107,7 @@
 #define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6))
 #define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7))
 #define TRACE_VALUE_TYPE_CONVERTABLE (static_cast<unsigned char>(8))
+#define TRACE_VALUE_TYPE_PROTO (static_cast<unsigned char>(9))
 
 // Enum reflecting the scope of an INSTANT event. Must fit within
 // TRACE_EVENT_FLAG_SCOPE_MASK.
diff --git a/base/trace_event/trace_arguments.cc b/base/trace_event/trace_arguments.cc
index 1cb0c3db..d94c9963 100644
--- a/base/trace_event/trace_arguments.cc
+++ b/base/trace_event/trace_arguments.cc
@@ -183,6 +183,12 @@
     case TRACE_VALUE_TYPE_CONVERTABLE:
       this->as_convertable->AppendAsTraceFormat(out);
       break;
+    case TRACE_VALUE_TYPE_PROTO:
+      if (as_json)
+        EscapeJSONString(this->as_proto->SerializeAsString(), true, out);
+      else
+        *out += this->as_proto->SerializeAsString();
+      break;
     default:
       NOTREACHED() << "Don't know how to print this value";
       break;
diff --git a/base/trace_event/trace_arguments.h b/base/trace_event/trace_arguments.h
index 1191df7..30f9c42 100644
--- a/base/trace_event/trace_arguments.h
+++ b/base/trace_event/trace_arguments.h
@@ -16,6 +16,9 @@
 #include "base/base_export.h"
 #include "base/trace_event/common/trace_event_common.h"
 #include "base/tracing_buildflags.h"
+#include "third_party/perfetto/include/perfetto/protozero/scattered_heap_buffer.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
+#include "third_party/perfetto/protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
 
 // Trace macro can have one or two optional arguments, each one of them
 // identified by a name (a C string literal) and a value, which can be an
@@ -223,26 +226,7 @@
   const void* as_pointer;
   const char* as_string;
   ConvertableToTraceFormat* as_convertable;
-
-  // There is no constructor to keep this structure POD intentionally.
-  // This avoids un-needed initialization when only 0 or 1 arguments are
-  // used to construct a TraceArguments instance. Use Init() instead to
-  // perform explicit initialization from a given C++ value.
-
-  // Initialize TraceValue instance from a C++ trace value.
-  // This relies on the proper specialization of TraceValue::Helper<>
-  // described below. Usage is simply:
-  //
-  //  TraceValue v;
-  //  v.Init(<value>);
-  //
-  // NOTE: For ConvertableToTraceFormat values, see the note above and
-  // the one for TraceValue::Helper for CONVERTABLE_TYPE below.
-  template <typename T>
-  void Init(T&& value) {
-    using ValueType = typename InnerType<T>::type;
-    Helper<ValueType>::SetValue(this, std::forward<T>(value));
-  }
+  protozero::HeapBuffered<perfetto::protos::pbzero::DebugAnnotation>* as_proto;
 
   // Static method to create a new TraceValue instance from a given
   // initialization value. Note that this deduces the TRACE_VALUE_TYPE_XXX
@@ -324,24 +308,90 @@
   template <typename T, class = void>
   struct Helper {};
 
+  template <typename T>
+  struct HasHelperSupport {
+   private:
+    using Yes = char[1];
+    using No = char[2];
+
+    template <typename V>
+    static Yes& check(
+        decltype(TraceValue::Helper<typename InnerType<V>::type>::kType,
+                 int()));
+    template <typename V>
+    static No& check(...);
+
+   public:
+    static constexpr bool value = sizeof(Yes) == sizeof(check<T>(0));
+  };
+
   // TraceValue::TypeFor<T>::value returns the TRACE_VALUE_TYPE_XXX
   // corresponding to initialization values of type T.
+  template <typename T, class = void>
+  struct TypeFor;
+
   template <typename T>
-  struct TypeFor {
+  struct TypeFor<T,
+                 typename std::enable_if<HasHelperSupport<
+                     typename InnerType<T>::type>::value>::type> {
     using ValueType = typename InnerType<T>::type;
     static const unsigned char value = Helper<ValueType>::kType;
   };
+  template <typename T>
+  struct TypeFor<T,
+                 typename std::enable_if<
+                     !HasHelperSupport<typename InnerType<T>::type>::value &&
+                     perfetto::internal::has_traced_value_support<
+                         typename InnerType<T>::type>::value>::type> {
+    static const unsigned char value = TRACE_VALUE_TYPE_PROTO;
+  };
 
   // TraceValue::TypeCheck<T>::value is only defined iff T can be used to
   // initialize a TraceValue instance. This is useful to restrict template
   // instantiation to only the appropriate type (see TraceArguments
   // constructors below).
   template <typename T,
-            class = decltype(TraceValue::Helper<
-                             typename TraceValue::InnerType<T>::type>::kType)>
+            class = std::enable_if_t<
+                HasHelperSupport<typename InnerType<T>::type>::value ||
+                perfetto::internal::has_traced_value_support<
+                    typename InnerType<T>::type>::value>>
   struct TypeCheck {
     static const bool value = true;
   };
+
+  // There is no constructor to keep this structure POD intentionally.
+  // This avoids un-needed initialization when only 0 or 1 arguments are
+  // used to construct a TraceArguments instance. Use Init() instead to
+  // perform explicit initialization from a given C++ value.
+
+  // Initialize TraceValue instance from a C++ trace value.
+  // This relies on the proper specialization of TraceValue::Helper<>
+  // described below. Usage is simply:
+  //
+  //  TraceValue v;
+  //  v.Init(<value>);
+  //
+  // NOTE: For ConvertableToTraceFormat values, see the notes above.
+  template <class T>
+  typename std::enable_if<
+      HasHelperSupport<typename InnerType<T>::type>::value>::type
+  Init(T&& value) {
+    using ValueType = typename InnerType<T>::type;
+    Helper<ValueType>::SetValue(this, std::forward<T>(value));
+  }
+
+  template <class T>
+  typename std::enable_if<
+      !HasHelperSupport<typename InnerType<T>::type>::value &&
+      perfetto::internal::has_traced_value_support<
+          typename InnerType<T>::type>::value>::type
+  Init(T&& value) {
+    as_proto = new protozero::HeapBuffered<
+        perfetto::protos::pbzero::DebugAnnotation>();
+    perfetto::WriteIntoTracedValue(
+        perfetto::internal::CreateTracedValueFromProto(as_proto->get()),
+        std::forward<T>(value));
+  }
 };
 
 // TraceValue::Helper for integers and enums.
@@ -639,6 +689,8 @@
     for (size_t n = 0; n < size_; ++n) {
       if (types_[n] == TRACE_VALUE_TYPE_CONVERTABLE)
         delete values_[n].as_convertable;
+      if (types_[n] == TRACE_VALUE_TYPE_PROTO)
+        delete values_[n].as_proto;
     }
   }
 
diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h
index bfaa635..9e3f747 100644
--- a/base/trace_event/trace_event.h
+++ b/base/trace_event/trace_event.h
@@ -27,6 +27,7 @@
 #include "base/trace_event/trace_arguments.h"
 #include "base/trace_event/trace_category.h"
 #include "base/trace_event/trace_log.h"
+#include "base/trace_event/traced_value_support.h"
 #include "base/tracing_buildflags.h"
 
 #if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
diff --git a/base/trace_event/trace_event_unittest.cc b/base/trace_event/trace_event_unittest.cc
index 179e55d..7cc7893 100644
--- a/base/trace_event/trace_event_unittest.cc
+++ b/base/trace_event/trace_event_unittest.cc
@@ -3005,5 +3005,29 @@
   EXPECT_TRUE(FindNamePhase("clock_sync", "c"));
 }
 
+TEST_F(TraceEventTestFixture, ContextLambda) {
+  TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""),
+                                      TraceLog::RECORDING_MODE);
+
+  TRACE_EVENT1("cat", "Name", "arg", [&](perfetto::TracedValue ctx) {
+    std::move(ctx).WriteString("foobar");
+  });
+  EndTraceAndFlush();
+
+  DictionaryValue* dict = FindNamePhase("Name", "X");
+  ASSERT_TRUE(dict);
+
+  const DictionaryValue* args_dict = nullptr;
+  dict->GetDictionary("args", &args_dict);
+  ASSERT_TRUE(args_dict);
+
+  const Value* value = nullptr;
+  EXPECT_TRUE(args_dict->Get("arg", &value));
+  ASSERT_TRUE(value->is_string());
+  EXPECT_EQ(value->GetString(),
+            "2\x6"
+            "foobar");
+}
+
 }  // namespace trace_event
 }  // namespace base
diff --git a/base/trace_event/traced_value_support.h b/base/trace_event/traced_value_support.h
new file mode 100644
index 0000000..18480261
--- /dev/null
+++ b/base/trace_event/traced_value_support.h
@@ -0,0 +1,119 @@
+// 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 BASE_TRACE_EVENT_TRACED_VALUE_SUPPORT_H_
+#define BASE_TRACE_EVENT_TRACED_VALUE_SUPPORT_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
+#include "base/time/time.h"
+#include "base/unguessable_token.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
+
+// This file contains specialisations for trace serialisation for key
+// widely-used //base classes. As these specialisations require full definition
+// of perfetto::TracedValue and almost every source unit in Chromium requires
+// one of these //base concepts, include specialiazations here and expose them
+// to the users including trace_event.h, rather than adding a dependency from
+// scoped_refptr.h et al on traced_value.h.
+
+namespace perfetto {
+
+// If T is serialisable into a trace, scoped_refptr<T> is serialisable as well.
+template <class T>
+struct TraceFormatTraits<scoped_refptr<T>,
+                         perfetto::check_traced_value_support_t<T>> {
+  static void WriteIntoTracedValue(perfetto::TracedValue context,
+                                   const scoped_refptr<T>& value) {
+    if (!value) {
+      std::move(context).WritePointer(nullptr);
+      return;
+    }
+    perfetto::WriteIntoTracedValue(std::move(context), *value);
+  }
+};
+
+// If T is serialisable into a trace, base::WeakPtr<T> is serialisable as well.
+template <class T>
+struct TraceFormatTraits<::base::WeakPtr<T>,
+                         perfetto::check_traced_value_support_t<T>> {
+  static void WriteIntoTracedValue(perfetto::TracedValue context,
+                                   const ::base::WeakPtr<T>& value) {
+    if (!value) {
+      std::move(context).WritePointer(nullptr);
+      return;
+    }
+    perfetto::WriteIntoTracedValue(std::move(context), *value);
+  }
+};
+
+// If T is serialisable into a trace, base::Optional<T> is serialisable as well.
+// Note that we need definitions for both base::Optional<T>& and
+// const base::Optional<T>& (unlike scoped_refptr and WeakPtr above), as
+// dereferencing const scoped_refptr<T>& gives you T, while dereferencing const
+// base::Optional<T>& gives you const T&.
+template <class T>
+struct TraceFormatTraits<::base::Optional<T>,
+                         perfetto::check_traced_value_support_t<T>> {
+  static void WriteIntoTracedValue(perfetto::TracedValue context,
+                                   const ::base::Optional<T>& value) {
+    if (!value) {
+      std::move(context).WritePointer(nullptr);
+      return;
+    }
+    perfetto::WriteIntoTracedValue(std::move(context), *value);
+  }
+
+  static void WriteIntoTracedValue(perfetto::TracedValue context,
+                                   ::base::Optional<T>& value) {
+    if (!value) {
+      std::move(context).WritePointer(nullptr);
+      return;
+    }
+    perfetto::WriteIntoTracedValue(std::move(context), *value);
+  }
+};
+
+// Time-related classes.
+// TODO(altimin): Make them first-class primitives in TracedValue and Perfetto
+// UI.
+template <>
+struct TraceFormatTraits<::base::TimeDelta> {
+  static void WriteIntoTracedValue(perfetto::TracedValue context,
+                                   const ::base::TimeDelta& value) {
+    std::move(context).WriteUInt64(value.InMicroseconds());
+  }
+};
+
+template <>
+struct TraceFormatTraits<::base::TimeTicks> {
+  static void WriteIntoTracedValue(perfetto::TracedValue context,
+                                   const ::base::TimeTicks& value) {
+    perfetto::WriteIntoTracedValue(std::move(context), value.since_origin());
+  }
+};
+
+template <>
+struct TraceFormatTraits<::base::Time> {
+  static void WriteIntoTracedValue(perfetto::TracedValue context,
+                                   const ::base::Time& value) {
+    perfetto::WriteIntoTracedValue(std::move(context), value.since_origin());
+  }
+};
+
+// base::UnguessableToken.
+// TODO(altimin): Add first-class primitive, which will allow to show a
+// human-comprehensible alias for all unguessable tokens instead.
+template <>
+struct TraceFormatTraits<::base::UnguessableToken> {
+  static void WriteIntoTracedValue(perfetto::TracedValue context,
+                                   const ::base::UnguessableToken& value) {
+    return std::move(context).WriteString(value.ToString());
+  }
+};
+
+}  // namespace perfetto
+
+#endif  // BASE_TRACE_EVENT_TRACED_VALUE_SUPPORT_H_
diff --git a/build/android/PRESUBMIT.py b/build/android/PRESUBMIT.py
index 2f04723..8ac562e0 100644
--- a/build/android/PRESUBMIT.py
+++ b/build/android/PRESUBMIT.py
@@ -31,6 +31,7 @@
           files_to_skip=[
               r'.*_pb2\.py',
               r'.*list_java_targets\.py',  # crbug.com/1100664
+              r'.*fast_local_dev_server\.py',  # crbug.com/1100664
           ] + build_pys,
           extra_paths_list=[
               J(),
diff --git a/build/android/fast_local_dev_server.py b/build/android/fast_local_dev_server.py
index fbc8b607..b47d6013 100755
--- a/build/android/fast_local_dev_server.py
+++ b/build/android/fast_local_dev_server.py
@@ -5,45 +5,96 @@
 """Creates an server to offload non-critical-path GN targets."""
 
 import argparse
-# pylint: disable=wrong-import-order
-import concurrent.futures
+import dataclasses
 import json
 import logging
 import os
 import socket
 import subprocess
 import sys
+import threading
+import time
 
 sys.path.append(os.path.join(os.path.dirname(__file__), 'gyp'))
 from util import server_utils
 
+# TODO(wnwen): Add type annotations.
 
-def _run_command(name, cwd, cmd):
-  logging.info('Started %s', name)
-  logging.debug('CWD: %s', cwd)
-  logging.debug('CMD: %s', ' '.join(cmd))
+
+@dataclasses.dataclass
+class Task:
+  """Class to represent a single build task."""
+  name: str
+  stamp_path: str
+  proc: subprocess.Popen
+  terminated: bool = False
+
+  def is_running(self):
+    return self.proc.poll() is None
+
+
+def _log(msg):
+  # Subtract one from the total number of threads so we don't count the main
+  #     thread.
+  num = threading.active_count() - 1
+  # \r to return the carriage to the beginning of line.
+  # \033[K to replace the normal \n to erase until the end of the line.
+  # Avoid the default line ending so the next \r overwrites the same line just
+  #     like ninja's output.
+  # TODO(wnwen): When there is just one thread left and it finishes, the last
+  #              output is "[1 thread] FINISHED //...". It may be better to show
+  #              "ALL DONE" or something to that effect.
+  print(f'\r[{num} thread{"" if num == 1 else "s"}] {msg}\033[K', end='')
+
+
+def _run_when_completed(task):
+  _log(f'RUNNING {task.name}')
+  stdout, _ = task.proc.communicate()
+
+  # Avoid printing anything since the task is now outdated.
+  if task.terminated:
+    return
+
+  _log(f'FINISHED {task.name}')
+  if stdout:
+    # An extra new line is needed since _log does not end with a new line.
+    print(f'\nFAILED: {task.name}')
+    print(' '.join(task.proc.args))
+    print(stdout.decode('utf-8'))
+    # Force ninja to always re-run failed tasks.
+    try:
+      os.unlink(task.stamp_path)
+    except FileNotFoundError:
+      pass
+  # TODO(wnwen): Reset timestamp for stamp file to when the original request was
+  #              sent since otherwise if a file is edited while the task is
+  #              running, then the target would appear newer than the edit.
+
+
+def _init_task(*, name, cwd, cmd, stamp_file):
+  _log(f'STARTING {name}')
   # The environment variable forces the script to actually run in order to avoid
   # infinite recursion.
   env = os.environ.copy()
   env[server_utils.BUILD_SERVER_ENV_VARIABLE] = '1'
   # Use os.nice(19) to ensure the lowest priority (idle) for these analysis
   # tasks since we want to avoid slowing down the actual build.
-  # pylint: disable=no-member
-  completed_process = subprocess.run(
+  proc = subprocess.Popen(
       cmd,
-      capture_output=True,
+      stdout=subprocess.PIPE,
+      stderr=subprocess.STDOUT,  # Interleave outputs to match running locally.
       cwd=cwd,
       env=env,
       preexec_fn=lambda: os.nice(19),
-      text=True,
   )
-  if completed_process.stdout or completed_process.stderr:
-    # Since this logging is done in the main process (just in separate threads),
-    # and logging is threadsafe, we do not need additional synchronization.
-    logging.error('Finished %s, but had output:\n%s', name,
-                  completed_process.stdout + completed_process.stderr)
-  else:
-    logging.info('Finished %s', name)
+  task = Task(name=name, stamp_path=os.path.join(cwd, stamp_file), proc=proc)
+  # Set daemon=True so that one Ctrl-C terminates the server.
+  # TODO(wnwen): Handle Ctrl-C and updating stamp files before exiting.
+  io_thread = threading.Thread(target=_run_when_completed,
+                               args=(task, ),
+                               daemon=True)
+  io_thread.start()
+  return task
 
 
 def _listen_for_request_data(sock):
@@ -56,47 +107,37 @@
         if not data:
           break
         received.append(data)
-    yield json.loads(b''.join(received))
+    if received:
+      yield json.loads(b''.join(received))
 
 
-def _bind_and_process_requests(sock, executor):
-  sock.bind(server_utils.SOCKET_ADDRESS)
-  sock.listen()
-  running = set()
+def _terminate_task(task):
+  task.terminated = True
+  task.proc.terminate()
+  task.proc.wait()
+  _log(f'TERMINATED {task.name}')
+
+
+def _process_requests(sock):
+  tasks = {}
+  # TODO(wnwen): Record and update start_time whenever we go from 0 to 1 active
+  #              threads so logging can display a reasonable time, e.g.
+  #              "[2 threads : 32.553s ] RUNNING //..."
   for data in _listen_for_request_data(sock):
-    name, cwd, cmd = data['name'], data['cwd'], data['cmd']
-    key = (name, cwd)
-    if key in running:
-      logging.info('Already running %s', name)
-    else:
-      running.add(key)
-      future = executor.submit(_run_command, name=name, cwd=cwd, cmd=cmd)
-      # Capture the current key in the lambda's default parameter.
-      # Ignore the first parameter as it is just the future.
-      future.add_done_callback(lambda _, k=key: running.discard(k))
+    key = (data['name'], data['cwd'])
+    task = tasks.get(key)
+    if task and task.is_running():
+      _terminate_task(task)
+    tasks[key] = _init_task(**data)
 
 
 def main():
-  parser = argparse.ArgumentParser(
-      description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
-  parser.add_argument('-v',
-                      '--verbose',
-                      action='count',
-                      default=0,
-                      help='-v to print info logs, -vv to print debug logs.')
+  parser = argparse.ArgumentParser(description=__doc__)
   args = parser.parse_args()
-  if args.verbose == 1:
-    level = logging.INFO
-  elif args.verbose == 2:
-    level = logging.DEBUG
-  else:
-    level = logging.WARNING
-  logging.basicConfig(
-      level=level,
-      format='%(levelname).1s %(process)d %(relativeCreated)6d %(message)s')
   with socket.socket(socket.AF_UNIX) as sock:
-    with concurrent.futures.ThreadPoolExecutor() as executor:
-      _bind_and_process_requests(sock, executor)
+    sock.bind(server_utils.SOCKET_ADDRESS)
+    sock.listen()
+    _process_requests(sock)
 
 
 if __name__ == '__main__':
diff --git a/build/android/gyp/compile_java.py b/build/android/gyp/compile_java.py
index ea0e4f5..57f177a 100755
--- a/build/android/gyp/compile_java.py
+++ b/build/android/gyp/compile_java.py
@@ -408,8 +408,11 @@
 
   # Compiles with Error Prone take twice as long to run as pure javac. Thus GN
   # rules run both in parallel, with Error Prone only used for checks.
-  _RunCompiler(options, javac_cmd + javac_args, java_files,
-               options.classpath, options.jar_path,
+  _RunCompiler(options,
+               javac_cmd + javac_args,
+               java_files,
+               options.classpath,
+               options.jar_path,
                save_outputs=not options.enable_errorprone)
   logging.info('Completed all steps in _OnStaleMd5')
 
@@ -635,8 +638,8 @@
   options, java_files = _ParseOptions(argv)
 
   # Only use the build server for errorprone runs.
-  if (options.enable_errorprone
-      and server_utils.MaybeRunCommand(options.target_name, sys.argv)):
+  if options.enable_errorprone and server_utils.MaybeRunCommand(
+      name=options.target_name, argv=sys.argv, stamp_file=options.jar_path):
     return
 
   colorama.init()
@@ -725,10 +728,9 @@
     input_paths.append(options.header_jar)
   input_paths += [x[0] for x in options.additional_jar_files]
 
-  output_paths = [
-      options.jar_path,
-      options.jar_path + '.info',
-  ]
+  output_paths = [options.jar_path]
+  if not options.enable_errorprone:
+    output_paths += [options.jar_path + '.info']
 
   input_strings = javac_cmd + javac_args + options.classpath + java_files + [
       options.warnings_as_errors, options.jar_info_exclude_globs
diff --git a/build/android/gyp/lint.py b/build/android/gyp/lint.py
index 7b35ad3..0f08532 100755
--- a/build/android/gyp/lint.py
+++ b/build/android/gyp/lint.py
@@ -437,8 +437,8 @@
   #              invocations.
   # Avoid parallelizing cache creation since lint runs without the cache defeat
   # the purpose of creating the cache in the first place.
-  if (not args.create_cache
-      and server_utils.MaybeRunCommand(args.target_name, sys.argv)):
+  if not args.create_cache and server_utils.MaybeRunCommand(
+      name=args.target_name, argv=sys.argv, stamp_file=args.stamp):
     return
 
   sources = []
diff --git a/build/android/gyp/util/server_utils.py b/build/android/gyp/util/server_utils.py
index 0196f828..0139393 100644
--- a/build/android/gyp/util/server_utils.py
+++ b/build/android/gyp/util/server_utils.py
@@ -9,13 +9,15 @@
 import socket
 import tempfile
 
+from util import build_utils
+
 # Use a unix abstract domain socket:
 # https://man7.org/linux/man-pages/man7/unix.7.html#:~:text=abstract:
 SOCKET_ADDRESS = '\0chromium_build_server_socket'
 BUILD_SERVER_ENV_VARIABLE = 'INVOKED_BY_BUILD_SERVER'
 
 
-def MaybeRunCommand(name, cmd):
+def MaybeRunCommand(name, argv, stamp_file):
   """Returns True if the command was successfully sent to the build server."""
 
   # When the build server runs a command, it sets this environment variable.
@@ -27,13 +29,17 @@
   with contextlib.closing(socket.socket(socket.AF_UNIX)) as sock:
     try:
       sock.connect(SOCKET_ADDRESS)
-      sock.sendall(json.dumps({
-          'name': name,
-          'cmd': cmd,
-          'cwd': os.getcwd(),
-      }))
+      sock.sendall(
+          json.dumps({
+              'name': name,
+              'cmd': argv,
+              'cwd': os.getcwd(),
+              'stamp_file': stamp_file,
+          }))
     except socket.error as e:
-      if e.errno == 111:  # [Errno 111] Connection refused
+      # [Errno 111] Connection refused. Either the server has not been started
+      #             or the server is not currently accepting new connections.
+      if e.errno == 111:
         return False
       raise e
   return True
diff --git a/build/config/c++/BUILD.gn b/build/config/c++/BUILD.gn
index 918047c..6494bb0 100644
--- a/build/config/c++/BUILD.gn
+++ b/build/config/c++/BUILD.gn
@@ -60,7 +60,18 @@
     }
   }
 
-  defines += [ "_LIBCPP_ENABLE_NODISCARD" ]
+  defines += [
+    "_LIBCPP_ENABLE_NODISCARD",
+
+    # TODO(crbug.com/1166707): libc++ requires this macro.
+    "_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS",
+  ]
+
+  # Work around a symbol conflict between GRPC and the Fuchsia SDK.
+  # TODO(crbug.com/1166970): Remove this when resolved.
+  if (is_fuchsia) {
+    defines += [ "_LIBCPP_NO_NATIVE_SEMAPHORES" ]
+  }
 
   # The Windows component build fails to link with libc++'s debug mode. See
   # https://crbug.com/923166#c33, https://crbug.com/923166#c44, and
@@ -93,6 +104,13 @@
     # does not match ours.
     defines += [ "_LIBCPP_NO_AUTO_LINK" ]
 
+    if (is_component_build) {
+      # TODO(crbug.com/1090975): Disable the exclude_from_explicit_instantiation
+      # to work around compiler bugs in the interaction between it and
+      # dllimport/dllexport.
+      defines += [ "_LIBCPP_HIDE_FROM_ABI=_LIBCPP_HIDDEN" ]
+    }
+
     # Add a debug visualizer for Microsoft's debuggers so that they can display
     # libc++ types well.
     if (libcxx_natvis_include) {
@@ -108,7 +126,7 @@
     ]
     cflags_objcc = cflags_cc
 
-    defines += [ "CR_LIBCXX_REVISION=$libcxx_svn_revision" ]
+    defines += [ "CR_LIBCXX_REVISION=$libcxx_revision" ]
 
     # Make sure we don't link against the system libstdc++ or libc++.
     if (is_clang) {
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
index 7b3d259..747e92a5 100644
--- a/build/config/compiler/compiler.gni
+++ b/build/config/compiler/compiler.gni
@@ -68,7 +68,7 @@
   # not ARC or linux-chromeos since it's been seen to not play nicely with
   # Chrome's clang. crbug.com/1033839
   use_thin_lto = is_cfi || (is_official_build &&
-                            (is_win || target_os == "android" ||
+                            (target_os == "android" ||
                              ((is_chromeos_ash || is_chromeos_lacros) &&
                               is_chromeos_device)))
 
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn
index 51437c6..4870f67 100644
--- a/build/config/win/BUILD.gn
+++ b/build/config/win/BUILD.gn
@@ -80,9 +80,6 @@
   ]
 
   if (is_clang) {
-    # Don't look for includes in %INCLUDE%.
-    cflags += [ "/X" ]
-
     # Required to make the 19041 SDK compatible with clang-cl.
     # See https://crbug.com/1089996 issue #2 for details.
     cflags += [ "/D__WRL_ENABLE_FUNCTION_STATICS__" ]
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 8869afb..e3cdef3 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-0.20210208.2.1
+0.20210209.0.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 8869afb..aeff336f 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-0.20210208.2.1
+0.20210209.1.1
diff --git a/build/nocompile.gni b/build/nocompile.gni
index 0b5bf35..4f178372f 100644
--- a/build/nocompile.gni
+++ b/build/nocompile.gni
@@ -107,6 +107,9 @@
 
         # TODO(https://crbug.com/989932): Track build/config/compiler/BUILD.gn
         "-Wno-implicit-int-float-conversion",
+
+        # TODO(crbug.com/1166707): libc++ now requires this macro to be defined.
+        "-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS",
       ]
 
       if (is_apple && host_os != "mac") {
diff --git a/build/toolchain/win/rc/rc.py b/build/toolchain/win/rc/rc.py
index 74761866..2ab4122 100755
--- a/build/toolchain/win/rc/rc.py
+++ b/build/toolchain/win/rc/rc.py
@@ -10,6 +10,7 @@
 -h, --help     Print this message.
 -I<dir>        Add include path, used for both headers and resources.
 -imsvc<dir>    Add system include path, used for preprocessing only.
+/winsysroot<d> Set winsysroot, used for preprocessing only.
 -D<sym>        Define a macro for the preprocessor.
 /fo<out>       Set path of output .res file.
 /nologo        Ignored (rc.py doesn't print a logo by default).
@@ -35,6 +36,7 @@
   # Can't use optparse / argparse because of /fo flag :-/
   includes = []
   imsvcs = []
+  winsysroot = []
   defines = []
   output = None
   input = None
@@ -48,6 +50,8 @@
       includes.append(flag)
     elif flag.startswith('-imsvc'):
       imsvcs.append(flag)
+    elif flag.startswith('/winsysroot'):
+      winsysroot = [flag]
     elif flag.startswith('-D'):
       defines.append(flag)
     elif flag.startswith('/fo'):
@@ -76,10 +80,17 @@
     sys.exit(1)
   if not output:
     output = os.path.splitext(input)[0] + '.res'
-  Flags = namedtuple('Flags', ['includes', 'defines', 'output', 'imsvcs',
-                               'input', 'show_includes'])
-  return Flags(includes=includes, defines=defines, output=output, imsvcs=imsvcs,
-               input=input, show_includes=show_includes)
+  Flags = namedtuple('Flags', [
+      'includes', 'defines', 'output', 'imsvcs', 'winsysroot', 'input',
+      'show_includes'
+  ])
+  return Flags(includes=includes,
+               defines=defines,
+               output=output,
+               imsvcs=imsvcs,
+               winsysroot=winsysroot,
+               input=input,
+               show_includes=show_includes)
 
 
 def ReadInput(input):
@@ -131,7 +142,7 @@
     clang_cmd.append('-I' + os.path.dirname(flags.input))
   if flags.show_includes:
     clang_cmd.append('/showIncludes')
-  clang_cmd += flags.imsvcs + flags.includes + flags.defines
+  clang_cmd += flags.imsvcs + flags.winsysroot + flags.includes + flags.defines
   p = subprocess.Popen(clang_cmd, stdin=subprocess.PIPE)
   p.communicate(input=rc_file_data)
   if p.returncode != 0:
diff --git a/build/toolchain/win/setup_toolchain.py b/build/toolchain/win/setup_toolchain.py
index bdb2b45..f66de0aa 100644
--- a/build/toolchain/win/setup_toolchain.py
+++ b/build/toolchain/win/setup_toolchain.py
@@ -249,6 +249,15 @@
   # TODO(scottmg|goma): Do we need an equivalent of
   # ninja_use_custom_environment_files?
 
+  def relflag(s):  # Make s relative to builddir when cwd and sdk on same drive.
+    try:
+      return os.path.relpath(s)
+    except ValueError:
+      return s
+
+  def q(s):  # Quote s if it contains spaces or other weird characters.
+    return s if re.match(r'^[a-zA-Z0-9._/\\:-]*$', s) else '"' + s + '"'
+
   for cpu in cpus:
     if cpu == target_cpu:
       # Extract environment variables for subprocesses.
@@ -264,22 +273,11 @@
       # The separator for INCLUDE here must match the one used in
       # _LoadToolchainEnv() above.
       include = [p.replace('"', r'\"') for p in env['INCLUDE'].split(';') if p]
-
-      # Make include path relative to builddir when cwd and sdk in same drive.
-      try:
-        include = list(map(os.path.relpath, include))
-      except ValueError:
-        pass
+      include = list(map(relflag, include))
 
       lib = [p.replace('"', r'\"') for p in env['LIB'].split(';') if p]
-      # Make lib path relative to builddir when cwd and sdk in same drive.
-      try:
-        lib = list(map(os.path.relpath, lib))
-      except ValueError:
-        pass
+      lib = list(map(relflag, lib))
 
-      def q(s):  # Quote s if it contains spaces or other weird characters.
-        return s if re.match(r'^[a-zA-Z0-9._/\\:-]*$', s) else '"' + s + '"'
       include_I = ' '.join([q('/I' + i) for i in include])
       include_imsvc = ' '.join([q('-imsvc' + i) for i in include])
       libpath_flags = ' '.join([q('-libpath:' + i) for i in lib])
@@ -293,7 +291,11 @@
   assert include_I
   print('include_flags_I = ' + gn_helpers.ToGNString(include_I))
   assert include_imsvc
-  print('include_flags_imsvc = ' + gn_helpers.ToGNString(include_imsvc))
+  if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', 1))) and win_sdk_path:
+    print('include_flags_imsvc = ' +
+          gn_helpers.ToGNString(q('/winsysroot' + relflag(toolchain_root))))
+  else:
+    print('include_flags_imsvc = ' + gn_helpers.ToGNString(include_imsvc))
   print('vc_lib_path = ' + gn_helpers.ToGNString(vc_lib_path))
   # Possible atlmfc library path gets introduced in the future for store thus
   # output result if a result exists.
diff --git a/buildtools/DEPS b/buildtools/DEPS
index eaecc8f..3427640 100644
--- a/buildtools/DEPS
+++ b/buildtools/DEPS
@@ -25,7 +25,7 @@
   # When changing these, also update the svn revisions in deps_revisions.gni
   # TODO(crbug.com/1166332) rename to clang_format_revision.
   'clang_fmt_revision':    '99803d74e35962f63a775f29477882afd4d57d94',
-  'libcxx_revision':       'd9040c75cfea5928c804ab7c235fed06a63f743a',
+  'libcxx_revision':       '69897abe2d4eae76816211fb408a07ba9b9e801f',
   'libcxxabi_revision':    '196ba1aaa8ac285d94f4ea8d9836390a45360533',
   'libunwind_revision':    'd999d54f4bca789543a2eb6c995af2d9b5a1f3ed',
 }
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni
index caed65f..767164d2 100644
--- a/buildtools/deps_revisions.gni
+++ b/buildtools/deps_revisions.gni
@@ -3,7 +3,7 @@
 # found in the LICENSE file.
 
 declare_args() {
-  # The libc++ svn revision that belongs to the git hash in DEPS. Used to cause
-  # full rebuilds on libc++ rolls.
-  libcxx_svn_revision = "375504"
+  # Used to cause full rebuilds on libc++ rolls. This should be kept in sync
+  # with the libcxx_revision vars in //DEPS and //buildtools/DEPS.
+  libcxx_revision = "491802ef67bee9c47208c0f79f41c3ecc88bf4fa"
 }
diff --git a/buildtools/third_party/libc++/BUILD.gn b/buildtools/third_party/libc++/BUILD.gn
index 88ad27d..301d2fd 100644
--- a/buildtools/third_party/libc++/BUILD.gn
+++ b/buildtools/third_party/libc++/BUILD.gn
@@ -54,6 +54,8 @@
   sources = [
     "trunk/src/algorithm.cpp",
     "trunk/src/any.cpp",
+    "trunk/src/atomic.cpp",
+    "trunk/src/barrier.cpp",
     "trunk/src/bind.cpp",
     "trunk/src/charconv.cpp",
     "trunk/src/chrono.cpp",
@@ -65,6 +67,7 @@
     "trunk/src/future.cpp",
     "trunk/src/hash.cpp",
     "trunk/src/ios.cpp",
+    "trunk/src/ios.instantiations.cpp",
     "trunk/src/iostream.cpp",
     "trunk/src/locale.cpp",
     "trunk/src/memory.cpp",
@@ -73,6 +76,7 @@
     "trunk/src/new.cpp",
     "trunk/src/optional.cpp",
     "trunk/src/random.cpp",
+    "trunk/src/random_shuffle.cpp",
     "trunk/src/regex.cpp",
     "trunk/src/shared_mutex.cpp",
     "trunk/src/stdexcept.cpp",
@@ -128,13 +132,7 @@
   }
 
   defines = [ "_LIBCPP_BUILDING_LIBRARY" ]
-  if (!is_clang && libcxx_is_shared) {
-    # This is a temporary workaround to get libc++ builds working with
-    # gcc.  It can be removed with either
-    # https://reviews.llvm.org/D35326 or
-    # https://reviews.llvm.org/D35388 lands.
-    defines += [ "_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS=__attribute__((__visibility__(\"default\")))" ]
-  }
+
   if (!libcxx_is_shared) {
     # TODO(https://crbug.com/946629): Remove use_xcode_clang condition once
     # XCode clang is updated to support -fvisibility-global-new-delete-hidden.
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 4102f30..74e07f54 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -415,7 +415,6 @@
     "//components/externalauth/android:java",
     "//components/favicon/android:java",
     "//components/feature_engagement:feature_engagement_java",
-    "//components/feed/core/proto:proto_java",
     "//components/feed/core/proto:proto_java_v2",
     "//components/find_in_page/android:java",
     "//components/gcm_driver/android:gcm_driver_java",
@@ -817,6 +816,7 @@
     "//chrome/browser/browser_controls/android:java",
     "//chrome/browser/browser_controls/android:junit",
     "//chrome/browser/contextmenu:java",
+    "//chrome/browser/continuous_search:junit",
     "//chrome/browser/continuous_search/internal:junit",
     "//chrome/browser/device:java",
     "//chrome/browser/device:junit",
@@ -904,7 +904,6 @@
     "//components/externalauth/android:junit",
     "//components/favicon/android:java",
     "//components/feature_engagement/public:public_java",
-    "//components/feed/core/proto:proto_java",
     "//components/feed/core/proto:proto_java_v2",
     "//components/infobars/android:java",
     "//components/messages/android:java",
@@ -927,8 +926,8 @@
     "//components/security_state/core:security_state_enums_java",
     "//components/signin/core/browser:signin_enums_java",
     "//components/signin/core/browser/android:java",
-    "//components/signin/core/browser/android:signin_java_test_support",
     "//components/signin/public/android:java",
+    "//components/signin/public/android:signin_java_test_support",
     "//components/sync/android:sync_java",
     "//components/url_formatter/android:url_formatter_java",
     "//components/user_prefs/android:java",
@@ -1230,9 +1229,9 @@
     "//components/security_state/core:security_state_enums_java",
     "//components/signin/core/browser:signin_enums_java",
     "//components/signin/core/browser/android:java",
-    "//components/signin/core/browser/android:signin_java_test_support",
     "//components/signin/public/android:java",
     "//components/signin/public/android:javatests",
+    "//components/signin/public/android:signin_java_test_support",
     "//components/site_engagement/content/android:java",
     "//components/strictmode/android:javatests",
     "//components/sync/android:sync_java",
@@ -3492,19 +3491,6 @@
     sources += [ "java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java" ]
   }
 
-  if (enable_feed_v1) {
-    sources += [
-      "feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedContentBridge.java",
-      "feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedDebuggingBridge.java",
-      "feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedJournalBridge.java",
-      "feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedLifecycleBridge.java",
-      "feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedLoggingBridge.java",
-      "feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedNetworkBridge.java",
-      "feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedOfflineBridge.java",
-      "feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedSchedulerBridge.java",
-    ]
-  }
-
   if (enable_vr) {
     sources += [ "java/src/org/chromium/chrome/browser/component_updater/VrAssetsComponentInstaller.java" ]
   }
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni
index 4f1e4beec..2be1c0a 100644
--- a/chrome/android/chrome_test_java_sources.gni
+++ b/chrome/android/chrome_test_java_sources.gni
@@ -634,13 +634,6 @@
   "javatests/src/org/chromium/chrome/test/crash/IntentionalCrashTest.java",
 ]
 
-if (enable_feed_v1) {
-  chrome_test_java_sources += [
-    "javatests/src/org/chromium/chrome/browser/ntp/NewTabPageColorTest.java",
-    "javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchFeedFlowTest.java",
-  ]
-}
-
 if (enable_feed_v2) {
   chrome_test_java_sources += [ "javatests/src/org/chromium/chrome/browser/ntp/NewTabPageColorWithFeedV2Test.java" ]
 }
diff --git a/chrome/android/features/start_surface/DEPS b/chrome/android/features/start_surface/DEPS
index 6535a88f..69a3c08 100644
--- a/chrome/android/features/start_surface/DEPS
+++ b/chrome/android/features/start_surface/DEPS
@@ -4,7 +4,6 @@
   "+chrome/browser/tabmodel/android/java",
   "+chrome/browser/tabpersistence/android/java",
   "+chrome/browser/profiles/android/java",
-  "+chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java",
   "+components/browser_ui/widget/android",
   "+content/public/android/java/src/org/chromium/content_public",
 ]
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
index 6193124..a4eb0a9d 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
@@ -76,6 +76,7 @@
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.base.test.util.DisableIf;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.ScalableTimeout;
@@ -86,7 +87,6 @@
 import org.chromium.chrome.browser.compositor.layouts.StaticLayout;
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
 import org.chromium.chrome.browser.device.DeviceClassManager;
-import org.chromium.chrome.browser.feed.FeedV1;
 import org.chromium.chrome.browser.feed.FeedV2;
 import org.chromium.chrome.browser.feed.shared.FeedFeatures;
 import org.chromium.chrome.browser.flags.CachedFeatureFlags;
@@ -178,9 +178,6 @@
         @Override
         public List<ParameterSet> getParameters() {
             List<ParameterSet> feedParams = new ArrayList<ParameterSet>();
-            if (FeedV1.IS_AVAILABLE) {
-                feedParams.add(new ParameterSet().value(false).name("FeedV1"));
-            }
             if (FeedV2.IS_AVAILABLE) {
                 feedParams.add(new ParameterSet().value(true).name("FeedV2"));
             }
@@ -615,10 +612,9 @@
     @CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION,
             "force-fieldtrials=Study/Group",
             IMMEDIATE_RETURN_PARAMS + "/start_surface_variation/omniboxonly"})
+    @DisabledTest(message = "Test doesn't work with FeedV2. FeedV1 is removed crbug.com/1165828.")
     public void renderTabSwitcher() throws IOException, InterruptedException {
         // clang-format on
-        if (!FeedV1.IS_AVAILABLE) return; // Test not yet working for FeedV2.
-
         createTabStateFile(new int[] {0, 1, 2});
         createThumbnailBitmapAndWriteToFile(0);
         createThumbnailBitmapAndWriteToFile(1);
@@ -684,7 +680,7 @@
         CriteriaHelper.pollUiThread(() -> allCardsHaveThumbnail(recyclerView));
         // TODO(crbug.com/1065314): Tab group cards should not have favicons.
         mRenderTestRule.render(mActivityTestRule.getActivity().findViewById(R.id.tab_list_view),
-                "tabSwitcher_tabGroups");
+                "tabSwitcher_tabGroups_aspect_ratio_point85");
 
         // Resume native initialization and make sure the GTS looks the same.
         startAndWaitNativeInitialization();
@@ -748,8 +744,7 @@
         ViewUtils.onViewWaiting(AllOf.allOf(withId(R.id.single_tab_view), isDisplayed()));
         ChromeRenderTestRule.sanitize(surface);
         // TODO(crbug.com/1065314): fix favicon.
-        mRenderTestRule.render(
-                surface, "singlePane_singleTab_noMV4" + (isFeedV2 ? "_FeedV2" : "_FeedV1"));
+        mRenderTestRule.render(surface, "singlePane_singleTab_noMV4_FeedV2");
 
         // Initializes native.
         startAndWaitNativeInitialization();
@@ -1112,8 +1107,7 @@
         });
         View surface =
                 mActivityTestRule.getActivity().findViewById(R.id.primary_tasks_surface_view);
-        mRenderTestRule.render(
-                surface, "singlePane_landscape" + (isFeedV2 ? "_FeedV2" : "_FeedV1"));
+        mRenderTestRule.render(surface, "singlePane_landscape_FeedV2");
     }
 
     @Test
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
index 98a80dc..5504ec4 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
@@ -182,7 +182,7 @@
 
     @Rule
     public ChromeRenderTestRule mRenderTestRule =
-            ChromeRenderTestRule.Builder.withPublicCorpus().build();
+            ChromeRenderTestRule.Builder.withPublicCorpus().setRevision(1).build();
 
     @SuppressWarnings("FieldCanBeLocal")
     private EmbeddedTestServer mTestServer;
@@ -731,7 +731,6 @@
     @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.M,
             message = "https://crbug.com/1023833")
     public void testIncognitoToggle_thumbnailFetchCount() throws InterruptedException {
-        mActivityTestRule.loadUrl(mUrl);
         ChromeTabbedActivity cta = mActivityTestRule.getActivity();
         int oldFetchCount = mTabListDelegate.getBitmapFetchCountForTesting();
 
@@ -1326,8 +1325,8 @@
     @Feature({"RenderTest"})
     // clang-format off
     @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID})
-    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/0.85"})
-    public void testRenderGrid_withAspectRatioPoint85() throws IOException {
+    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/1.0"})
+    public void testRenderGrid_withAspectRatioOfOne() throws IOException {
         // clang-format on
         ChromeTabbedActivity cta = mActivityTestRule.getActivity();
         prepareTabs(3, 0, "about:blank");
@@ -1337,7 +1336,7 @@
         createTabGroup(cta, false, tabGroup);
         // Make sure all tabs have thumbnail.
         enterGTSWithThumbnailRetry();
-        mRenderTestRule.render(cta.findViewById(R.id.tab_list_view), "aspect_ratio_point_85");
+        mRenderTestRule.render(cta.findViewById(R.id.tab_list_view), "aspect_ratio_of_one");
     }
 
     @Test
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
index d6eaed3..800b1b8 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
@@ -102,7 +102,6 @@
 import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter;
 import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities;
 import org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper;
-import org.chromium.chrome.browser.toolbar.HomeButton;
 import org.chromium.chrome.browser.toolbar.top.ToolbarPhone;
 import org.chromium.chrome.start_surface.R;
 import org.chromium.chrome.test.ChromeActivityTestRule;
@@ -405,7 +404,7 @@
     @Test
     @MediumTest
     @Feature({"StartSurface"})
-    @CommandLineFlags.Add({BASE_PARAMS + "/single/home_button_on_grid_tab_switcher/false"})
+    @CommandLineFlags.Add({BASE_PARAMS + "/single"})
     public void testShow_SingleAsHomepage() {
         if (!mImmediateReturn) {
             onView(withId(org.chromium.chrome.tab_ui.R.id.home_button)).perform(click());
@@ -442,10 +441,6 @@
             fail("Failed to tap 'more tabs' " + e.toString());
         }
         onViewWaiting(withId(R.id.secondary_tasks_surface_view));
-        assertEquals(mActivityTestRule.getActivity()
-                             .findViewById(R.id.home_button_on_tab_switcher)
-                             .getVisibility(),
-                View.GONE);
 
         pressBack();
         onViewWaiting(withId(R.id.primary_tasks_surface_view));
@@ -1315,7 +1310,7 @@
                 .perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));
         assertFalse(bottomSheetTestSupport.hasSuppressionTokens());
 
-        pressHomePageButton();
+        onView(withId(org.chromium.chrome.tab_ui.R.id.home_button)).perform(click());
         assertFalse(bottomSheetTestSupport.hasSuppressionTokens());
 
         try {
@@ -1331,15 +1326,6 @@
         assertTrue(bottomSheetTestSupport.hasSuppressionTokens());
     }
 
-    private void pressHomePageButton() {
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            mActivityTestRule.getActivity()
-                    .getToolbarManager()
-                    .getToolbarTabControllerForTesting()
-                    .openHomepage();
-        });
-    }
-
     @Test
     @MediumTest
     @Feature({"StartSurface"})
@@ -1413,7 +1399,7 @@
 
         if (isInstantReturn()
                 && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
-                        && Build.VERSION.SDK_INT < Build.VERSION_CODES.P)) {
+                        && Build.VERSION.SDK_INT <= Build.VERSION_CODES.P)) {
             // Fix the issue that failed to perform a single click on the back button.
             return;
         }
@@ -1428,7 +1414,9 @@
         onView(allOf(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container), isDisplayed()));
         TestThreadUtils.runOnUiThreadBlocking(() -> tilesLayout.getChildAt(0).performClick());
         CriteriaHelper.pollUiThread(() -> !cta.getLayoutManager().overviewVisible());
-        pressHomePageButton();
+        onViewWaiting(allOf(withId(org.chromium.chrome.R.id.home_button), isDisplayed()));
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> { cta.findViewById(org.chromium.chrome.R.id.home_button).performClick(); });
         onViewWaiting(withId(R.id.primary_tasks_surface_view));
         onView(allOf(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view), isDisplayed()));
         // Verifies a new Tab is created, and can be seen in the Start surface.
@@ -1535,7 +1523,8 @@
         TabUiTestHelper.verifyTabModelTabCount(cta, 2, 0);
 
         TabUiTestHelper.mergeAllNormalTabsToAGroup(cta);
-        pressHomePageButton();
+        onViewWaiting(withId(org.chromium.chrome.tab_ui.R.id.home_button));
+        onView(withId(org.chromium.chrome.tab_ui.R.id.home_button)).perform(click());
         CriteriaHelper.pollUiThread(() -> cta.getLayoutManager().overviewVisible());
 
         onView(allOf(withParent(withId(
@@ -1600,7 +1589,8 @@
 
         // Goes to the Start surface from tapping home button, and navigate from the Omnibox. The
         // new created Tab shouldn't get focus.
-        pressHomePageButton();
+        waitForView(withId(org.chromium.chrome.tab_ui.R.id.home_button));
+        onView(withId(org.chromium.chrome.tab_ui.R.id.home_button)).perform(click());
         CriteriaHelper.pollUiThread(this::isOverviewVisible);
 
         onView(allOf(withId(R.id.search_box_text), isDisplayed()))
@@ -1659,42 +1649,6 @@
         TabUiTestHelper.verifyTabModelTabCount(mActivityTestRule.getActivity(), 1, 0);
     }
 
-    @Test
-    @MediumTest
-    @Feature({"StartSurface"})
-    @CommandLineFlags.Add({BASE_PARAMS + "/single/home_button_on_grid_tab_switcher/true"})
-    public void testHomeButtonOnTabSwitcher() {
-        if (!mImmediateReturn) {
-            onView(withId(org.chromium.chrome.tab_ui.R.id.home_button)).perform(click());
-        }
-        CriteriaHelper.pollUiThread(this::isOverviewVisible);
-        waitForTabModel();
-        TabUiTestHelper.verifyTabModelTabCount(mActivityTestRule.getActivity(), 1, 0);
-
-        // Note that onView(R.id.more_tabs).perform(click()) can not be used since it requires 90
-        // percent of the view's area is displayed to the users. However, this view has negative
-        // margin which makes the percentage is less than 90.
-        // TODO(crbug.com/1025296): Investigate whether this would be a problem for real users.
-        try {
-            TestThreadUtils.runOnUiThreadBlocking(
-                    ()
-                            -> mActivityTestRule.getActivity()
-                                       .findViewById(org.chromium.chrome.tab_ui.R.id.more_tabs)
-                                       .performClick());
-        } catch (ExecutionException e) {
-            fail("Failed to tap 'more tabs' " + e.toString());
-        }
-        waitForView(withId(R.id.secondary_tasks_surface_view));
-        onView(withId(org.chromium.chrome.tab_ui.R.id.home_button_on_tab_switcher))
-                .check(matches(isDisplayed()));
-        HomeButton homeButton = mActivityTestRule.getActivity().findViewById(
-                org.chromium.chrome.tab_ui.R.id.home_button_on_tab_switcher);
-        Assert.assertFalse(homeButton.isLongClickable());
-        onView(withId(R.id.home_button_on_tab_switcher)).perform(click());
-
-        onView(withId(R.id.primary_tasks_surface_view)).check(matches(isDisplayed()));
-    }
-
     private boolean isKeyboardShown() {
         Activity activity = mActivityTestRule.getActivity();
         if (activity.getCurrentFocus() == null) return false;
diff --git a/chrome/android/features/start_surface/public/java/src/org/chromium/chrome/features/start_surface/StartSurfaceConfiguration.java b/chrome/android/features/start_surface/public/java/src/org/chromium/chrome/features/start_surface/StartSurfaceConfiguration.java
index bbc02aae..242b4f6 100644
--- a/chrome/android/features/start_surface/public/java/src/org/chromium/chrome/features/start_surface/StartSurfaceConfiguration.java
+++ b/chrome/android/features/start_surface/public/java/src/org/chromium/chrome/features/start_surface/StartSurfaceConfiguration.java
@@ -86,12 +86,6 @@
             new BooleanCachedFieldTrialParameter(ChromeFeatureList.START_SURFACE_ANDROID,
                     OMNIBOX_FOCUSED_ON_NEW_TAB_PARAM, false);
 
-    private static final String HOME_BUTTON_ON_GRID_TAB_SWITCHER_PARAM =
-            "home_button_on_grid_tab_switcher";
-    public static final BooleanCachedFieldTrialParameter HOME_BUTTON_ON_GRID_TAB_SWITCHER =
-            new BooleanCachedFieldTrialParameter(ChromeFeatureList.START_SURFACE_ANDROID,
-                    HOME_BUTTON_ON_GRID_TAB_SWITCHER_PARAM, false);
-
     private static final String STARTUP_UMA_PREFIX = "Startup.Android.";
     private static final String INSTANT_START_SUBFIX = ".Instant";
     private static final String REGULAR_START_SUBFIX = ".NoInstant";
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java
index f29b4de..b438954 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java
@@ -44,7 +44,7 @@
     public static final String THUMBNAIL_ASPECT_RATIO_PARAM = "thumbnail_aspect_ratio";
     public static final DoubleCachedFieldTrialParameter THUMBNAIL_ASPECT_RATIO =
             new DoubleCachedFieldTrialParameter(
-                    ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, THUMBNAIL_ASPECT_RATIO_PARAM, 1.0);
+                    ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, THUMBNAIL_ASPECT_RATIO_PARAM, 0.85);
 
     private static final String SEARCH_CHIP_PARAM = "enable_search_term_chip";
     public static final BooleanCachedFieldTrialParameter ENABLE_SEARCH_CHIP =
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherThumbnailTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherThumbnailTest.java
index 26b3a7d..ba5d73bc 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherThumbnailTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherThumbnailTest.java
@@ -75,7 +75,7 @@
 
     @Test
     @MediumTest
-    @CommandLineFlags.Add({BASE_PARAMS})
+    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/1.0"})
     public void testThumbnailAspectRatio_one() {
         int tabCounts = 11;
         TabUiTestHelper.prepareTabsWithThumbnail(mActivityTestRule, tabCounts, 0, "about:blank");
@@ -90,7 +90,7 @@
 
     @Test
     @MediumTest
-    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/0.85"})
+    @CommandLineFlags.Add({BASE_PARAMS})
     public void testThumbnailAspectRatio_point85() {
         int tabCounts = 11;
         TabUiTestHelper.prepareTabsWithThumbnail(mActivityTestRule, tabCounts, 0, "about:blank");
@@ -105,7 +105,7 @@
         int tabCounts = 11;
         TabUiTestHelper.prepareTabsWithThumbnail(mActivityTestRule, tabCounts, 0, "about:blank");
         TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity());
-        verifyAllThumbnailHeightWithAspectRatio(tabCounts, 1.f);
+        verifyAllThumbnailHeightWithAspectRatio(tabCounts, .85f);
 
         // With soft cleanup.
         TabUiTestHelper.leaveTabSwitcher(mActivityTestRule.getActivity());
@@ -113,7 +113,7 @@
         // There is a chance this will fail without the current changes. Soft cleanup sets the
         // fetcher to null, which triggers TabGridViewBinder#releaseThumbnail. If the view still
         // under measuring, then its height can be zero after measurement.
-        verifyAllThumbnailHeightWithAspectRatio(tabCounts, 1.f);
+        verifyAllThumbnailHeightWithAspectRatio(tabCounts, .85f);
     }
 
     private void verifyAllThumbnailHeightWithAspectRatio(int tabCounts, float ratio) {
diff --git a/chrome/android/feed/BUILD.gn b/chrome/android/feed/BUILD.gn
index 2f38f26..218326f5 100644
--- a/chrome/android/feed/BUILD.gn
+++ b/chrome/android/feed/BUILD.gn
@@ -7,7 +7,6 @@
 import("//components/feed/features.gni")
 
 android_resources("chrome_feed_java_resources") {
-  # TODO(crbug.com/1129187): Determine if more resources can be moved to v1-only.
   sources = [
     "core/java/res/drawable/feed_text_ripple_drawable_dark.xml",
     "core/java/res/drawable/feed_text_ripple_drawable_light.xml",
@@ -22,27 +21,6 @@
     "core/java/res/values/styles.xml",
   ]
 
-  if (enable_feed_v1) {
-    # Note that we had to move v1 resources to a new directory because the
-    # android_resources rule ensures that you include all files in your resource
-    # directories.
-    sources += [
-      "core/java/resv1/drawable-hdpi/ic_amp_24dp.png",
-      "core/java/resv1/drawable-mdpi/ic_amp_24dp.png",
-      "core/java/resv1/drawable-xhdpi/ic_amp_24dp.png",
-      "core/java/resv1/drawable-xxhdpi/ic_amp_24dp.png",
-      "core/java/resv1/drawable-xxxhdpi/ic_amp_24dp.png",
-      "core/java/resv1/layout/feed_more_button.xml",
-      "core/java/resv1/layout/feed_simple_list_item.xml",
-      "core/java/resv1/layout/feed_spinner_gone.xml",
-      "core/java/resv1/layout/no_content.xml",
-      "core/java/resv1/layout/zero_state.xml",
-      "core/java/resv1/values-v16/styles.xml",
-      "core/java/resv1/values-v17/styles.xml",
-      "core/java/resv1/values/dimens.xml",
-    ]
-  }
-
   deps = [
     "//chrome/android:chrome_app_java_resources",
     "//ui/android:ui_java_resources",
diff --git a/chrome/android/feed/core/java/resv1/drawable-hdpi/ic_amp_24dp.png b/chrome/android/feed/core/java/resv1/drawable-hdpi/ic_amp_24dp.png
deleted file mode 100644
index 2216d7d..0000000
--- a/chrome/android/feed/core/java/resv1/drawable-hdpi/ic_amp_24dp.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/feed/core/java/resv1/drawable-mdpi/ic_amp_24dp.png b/chrome/android/feed/core/java/resv1/drawable-mdpi/ic_amp_24dp.png
deleted file mode 100644
index 4998126..0000000
--- a/chrome/android/feed/core/java/resv1/drawable-mdpi/ic_amp_24dp.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/feed/core/java/resv1/drawable-xhdpi/ic_amp_24dp.png b/chrome/android/feed/core/java/resv1/drawable-xhdpi/ic_amp_24dp.png
deleted file mode 100644
index 3f5b945..0000000
--- a/chrome/android/feed/core/java/resv1/drawable-xhdpi/ic_amp_24dp.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/feed/core/java/resv1/drawable-xxhdpi/ic_amp_24dp.png b/chrome/android/feed/core/java/resv1/drawable-xxhdpi/ic_amp_24dp.png
deleted file mode 100644
index fea7a785..0000000
--- a/chrome/android/feed/core/java/resv1/drawable-xxhdpi/ic_amp_24dp.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/feed/core/java/resv1/drawable-xxxhdpi/ic_amp_24dp.png b/chrome/android/feed/core/java/resv1/drawable-xxxhdpi/ic_amp_24dp.png
deleted file mode 100644
index c5d24b9..0000000
--- a/chrome/android/feed/core/java/resv1/drawable-xxxhdpi/ic_amp_24dp.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/feed/core/java/resv1/layout/feed_more_button.xml b/chrome/android/feed/core/java/resv1/layout/feed_more_button.xml
deleted file mode 100644
index 9586eab..0000000
--- a/chrome/android/feed/core/java/resv1/layout/feed_more_button.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright 2019 The Chromium Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
--->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/FeedMoreButtonContainer"
-    android:id="@+id/more_button">
-
-  <Button
-      style="@style/FeedSuggestionCardAction"
-      android:id="@+id/action_button"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:text="@string/more"
-      android:layout_gravity="center" />
-  <include layout="@layout/feed_spinner_gone"/>
-</FrameLayout>
diff --git a/chrome/android/feed/core/java/resv1/layout/feed_simple_list_item.xml b/chrome/android/feed/core/java/resv1/layout/feed_simple_list_item.xml
deleted file mode 100644
index ab95401..0000000
--- a/chrome/android/feed/core/java/resv1/layout/feed_simple_list_item.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright 2019 The Chromium Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
--->
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/feed_simple_list_item"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:gravity="center_vertical"
-    android:minHeight="?android:attr/listPreferredItemHeightSmall"
-    android:textAppearance="@style/TextAppearance.TextLarge.Primary"
-    style="@style/FeedMenuTextPaddingStyle"
-/>
diff --git a/chrome/android/feed/core/java/resv1/layout/feed_spinner_gone.xml b/chrome/android/feed/core/java/resv1/layout/feed_spinner_gone.xml
deleted file mode 100644
index f94f72bf..0000000
--- a/chrome/android/feed/core/java/resv1/layout/feed_spinner_gone.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright 2019 The Chromium Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
--->
-<org.chromium.chrome.browser.feed.shared.ui.MaterialSpinnerView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/loading_spinner"
-    android:layout_width="match_parent"
-    android:visibility="gone"
-    android:layout_height="@dimen/feed_suggestion_card_action_min_height"
-    android:layout_gravity="center" />
diff --git a/chrome/android/feed/core/java/resv1/layout/no_content.xml b/chrome/android/feed/core/java/resv1/layout/no_content.xml
deleted file mode 100644
index 659e70a3..0000000
--- a/chrome/android/feed/core/java/resv1/layout/no_content.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright 2019 The Chromium Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
--->
-<LinearLayout
-  xmlns:android="http://schemas.android.com/apk/res/android"
-  android:layout_width="match_parent"
-  android:layout_height="wrap_content"
-  android:orientation="vertical"
-  android:id="@+id/no_content"
-  android:padding="@dimen/no_content_padding">
-  <TextView
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:paddingBottom="@dimen/no_content_text_padding"
-      android:textAppearance="@style/TextAppearance.TextLarge.Primary"
-      android:text="@string/ntp_title_no_suggestions" />
-  <TextView
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:textAppearance="@style/TextAppearance.TextLarge.Secondary"
-      android:text="@string/ntp_article_suggestions_section_empty" />
-</LinearLayout>
diff --git a/chrome/android/feed/core/java/resv1/layout/zero_state.xml b/chrome/android/feed/core/java/resv1/layout/zero_state.xml
deleted file mode 100644
index 6b49818a2b..0000000
--- a/chrome/android/feed/core/java/resv1/layout/zero_state.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright 2019 The Chromium Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
--->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/zero_state_container"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content">
-
-    <include layout="@layout/feed_spinner_gone"/>
-    <LinearLayout
-        android:id="@+id/zero_state"
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-        <FrameLayout
-            android:id="@+id/no_content_container"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-            <include layout="@layout/no_content"/>
-        </FrameLayout>
-        <FrameLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-            <include layout="@layout/feed_more_button"/>
-        </FrameLayout>
-    </LinearLayout>
-</FrameLayout>
-
diff --git a/chrome/android/feed/core/java/resv1/values-v16/styles.xml b/chrome/android/feed/core/java/resv1/values-v16/styles.xml
deleted file mode 100644
index e9399b20f..0000000
--- a/chrome/android/feed/core/java/resv1/values-v16/styles.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright 2020 The Chromium Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
--->
-<resources xmlns:tools="http://schemas.android.com/tools">
-  <!-- Buttons -->
-  <style name="FeedButtonCompatBase">
-    <item name="android:minWidth">88dp</item>
-    <item name="android:minHeight">36dp</item>
-    <item name="android:paddingLeft">20dp</item>
-    <item name="android:paddingRight">20dp</item>
-    <item name="android:paddingTop">5dp</item>
-    <item name="android:paddingBottom">5dp</item>
-    <item name="android:focusable">true</item>
-    <item name="android:clickable">true</item>
-    <item name="android:gravity">center_vertical|center_horizontal</item>
-  </style>
-
-  <style name="FeedTextButton" parent="FeedButtonCompatBase">
-    <item name="android:paddingLeft">8dp</item>
-    <item name="android:paddingRight">8dp</item>
-    <item name="android:textAppearance">@style/TextAppearance.Button.Text.Blue</item>
-    <item name="android:background">?feedTextRippleDrawable</item>
-  </style>
-
-  <style name="FeedSuggestionCardAction" parent="FeedTextButton">
-    <item name="android:minHeight">@dimen/feed_suggestion_card_action_min_height</item>
-  </style>
-
-  <style name="FeedMoreButtonContainer">
-    <item name="android:layout_width">match_parent</item>
-    <item name="android:layout_height">wrap_content</item>
-    <item name="android:paddingLeft">@dimen/more_button_padding</item>
-    <item name="android:paddingRight">@dimen/more_button_padding</item>
-    <item name="android:paddingBottom">@dimen/more_button_padding</item>
-  </style>
-
-  <!-- Menu Text Padding Styles -->
-  <style name="FeedMenuTextPaddingStyle">
-    <item name="android:paddingLeft">?android:attr/listPreferredItemPaddingLeft</item>
-    <item name="android:paddingRight">?android:attr/listPreferredItemPaddingRight</item>
-  </style>
-</resources>
diff --git a/chrome/android/feed/core/java/resv1/values-v17/styles.xml b/chrome/android/feed/core/java/resv1/values-v17/styles.xml
deleted file mode 100644
index d8bc113..0000000
--- a/chrome/android/feed/core/java/resv1/values-v17/styles.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright 2020 The Chromium Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
--->
-<resources xmlns:tools="http://schemas.android.com/tools">
-  <!-- Buttons -->
-  <style name="FeedButtonCompatBase">
-    <item name="android:minWidth">88dp</item>
-    <item name="android:minHeight">36dp</item>
-    <item name="android:paddingStart">20dp</item>
-    <item name="android:paddingEnd">20dp</item>
-    <item name="android:paddingTop">5dp</item>
-    <item name="android:paddingBottom">5dp</item>
-    <item name="android:focusable">true</item>
-    <item name="android:clickable">true</item>
-    <item name="android:gravity">center_vertical|center_horizontal</item>
-  </style>
-
-  <style name="FeedTextButton" parent="FeedButtonCompatBase">
-    <item name="android:paddingStart">8dp</item>
-    <item name="android:paddingEnd">8dp</item>
-    <item name="android:textAppearance">@style/TextAppearance.Button.Text.Blue</item>
-    <item name="android:background">?feedTextRippleDrawable</item>
-  </style>
-
-  <style name="FeedMoreButtonContainer">
-    <item name="android:layout_width">match_parent</item>
-    <item name="android:layout_height">wrap_content</item>
-    <item name="android:paddingStart">@dimen/more_button_padding</item>
-    <item name="android:paddingEnd">@dimen/more_button_padding</item>
-    <item name="android:paddingBottom">@dimen/more_button_padding</item>
-  </style>
-
-  <!-- Menu Text Padding Styles -->
-  <style name="FeedMenuTextPaddingStyle">
-    <item name="android:paddingStart">?android:attr/listPreferredItemPaddingStart</item>
-    <item name="android:paddingEnd">?android:attr/listPreferredItemPaddingEnd</item>
-  </style>
-
-</resources>
diff --git a/chrome/android/feed/core/java/resv1/values/dimens.xml b/chrome/android/feed/core/java/resv1/values/dimens.xml
deleted file mode 100644
index dd8021c..0000000
--- a/chrome/android/feed/core/java/resv1/values/dimens.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2020 The Chromium Authors. All rights reserved.
-     Use of this source code is governed by a BSD-style license that can be
-     found in the LICENSE file. -->
-
-<resources xmlns:tools="http://schemas.android.com/tools">
-  <!-- More button dimensions. -->
-  <dimen name="more_button_padding">8dp</dimen>
-  <dimen name="feed_more_button_container_top_margins">-20dp</dimen>
-  <!-- The Material spec specifies that the width of a menu must be a multiple of 56dp. -->
-  <!-- TODO(crbug.com/1039415): Not feed-specific. Try to unify with the rest of Chrome -->
-  <dimen name="menu_width_multiple">56dp</dimen>
-</resources>
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/DEPS b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/DEPS
index 2b1d5f7..28f8ef6 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/DEPS
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/DEPS
@@ -1,14 +1,8 @@
 include_rules = [
-  "-chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1",
   "-chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2",
-  "-chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library",
 ]
 
 specific_include_rules = {
-    "FeedV1\.java": [
-        "+chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1",
-        "+chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library",
-    ],
     "FeedV2\.java": [
         "+chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2",
     ],
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
index 1c9f62f..28d52b67 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
@@ -239,11 +239,7 @@
             @Nullable NativePageNavigationDelegate pageNavigationDelegate, Profile profile,
             boolean isPlaceholderShownInitially, BottomSheetController bottomSheetController,
             Supplier<ShareDelegate> shareDelegateSupplier) {
-        if (FeedFeatures.isV2Enabled()) {
-            mStreamWrapper = FeedV2.createStreamWrapper();
-        } else {
-            mStreamWrapper = FeedV1.createStreamWrapper();
-        }
+        mStreamWrapper = FeedV2.createStreamWrapper();
 
         mActivity = activity;
         mSnackbarManager = snackbarManager;
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedV1.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedV1.java
deleted file mode 100644
index e9d5bed23..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedV1.java
+++ /dev/null
@@ -1,36 +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.
-
-package org.chromium.chrome.browser.feed;
-
-import org.chromium.chrome.browser.feed.v1.FeedProcessScopeFactory;
-import org.chromium.chrome.browser.feed.v1.FeedRefreshTask;
-import org.chromium.chrome.browser.feed.v1.FeedStreamWrapper;
-import org.chromium.components.background_task_scheduler.BackgroundTask;
-
-/**
- * Provides access to FeedV1. Stubbed out when V1 is removed from the build.
- */
-public class FeedV1 {
-    // Whether FeedV1 is compiled in.
-    public static final boolean IS_AVAILABLE = true;
-
-    public static void startup() {
-        // We call getFeedAppLifecycle() here to ensure the app lifecycle is created so
-        // that it can start listening for state changes.
-        FeedProcessScopeFactory.getFeedAppLifecycle();
-    }
-
-    public static FeedSurfaceCoordinator.StreamWrapper createStreamWrapper() {
-        return new FeedStreamWrapper();
-    }
-
-    public static BackgroundTask createRefreshTask() {
-        return new FeedRefreshTask();
-    }
-
-    public static void destroy() {
-        FeedProcessScopeFactory.destroy();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedV1ActionOptions.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedV1ActionOptions.java
index 6e6d0a1..acd81df 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedV1ActionOptions.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedV1ActionOptions.java
@@ -4,7 +4,10 @@
 
 package org.chromium.chrome.browser.feed;
 
-/** Options for handling actions in Feed V1. */
+/**
+ * Options for handling actions in Feed V1.
+ * TODO(crbug.com/1165828): V1 was removed, these do nothing.
+ */
 public class FeedV1ActionOptions {
     public boolean inhibitDownload;
     public boolean inhibitOpenInIncognito;
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/BUILD.gn b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/BUILD.gn
deleted file mode 100644
index 36141df..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/BUILD.gn
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/android/config.gni")
-import("//build/config/android/rules.gni")
-import("//components/feed/features.gni")
-import("//third_party/protobuf/proto_library.gni")
-
-if (enable_feed_v1) {
-  android_resources("piet_resources") {
-    sources = [
-      "piet/res/drawable-v21/piet_clickable_ripple.xml",
-      "piet/res/values/styles.xml",
-    ]
-  }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/knowncontent/ContentMetadata.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/knowncontent/ContentMetadata.java
deleted file mode 100644
index 3c58648..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/knowncontent/ContentMetadata.java
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.client.knowncontent;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.OfflineMetadata;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.RepresentationData;
-
-/** Metadata for content. */
-public final class ContentMetadata {
-    static final long UNKNOWN_TIME_PUBLISHED = -1L;
-
-    private static final String TAG = "ContentMetadata";
-
-    private final String mUrl;
-    private final String mTitle;
-    private final long mTimePublished;
-    @Nullable
-    private final String mImageUrl;
-    @Nullable
-    private final String mPublisher;
-    @Nullable
-    private final String mFaviconUrl;
-    @Nullable
-    private final String mSnippet;
-
-    @Nullable
-    public static ContentMetadata maybeCreateContentMetadata(
-            OfflineMetadata offlineMetadata, RepresentationData representationData) {
-        if (!representationData.hasUri()) {
-            Logger.w(TAG, "Can't build ContentMetadata with no URL");
-            return null;
-        }
-
-        if (!offlineMetadata.hasTitle()) {
-            Logger.w(TAG, "Can't build ContentMetadata with no title");
-            return null;
-        }
-
-        String imageUrl = offlineMetadata.hasImageUrl() ? offlineMetadata.getImageUrl() : null;
-        String publisher = offlineMetadata.hasPublisher() ? offlineMetadata.getPublisher() : null;
-        String faviconUrl =
-                offlineMetadata.hasFaviconUrl() ? offlineMetadata.getFaviconUrl() : null;
-        String snippet = offlineMetadata.hasSnippet() ? offlineMetadata.getSnippet() : null;
-        long publishedTimeSeconds = representationData.hasPublishedTimeSeconds()
-                ? representationData.getPublishedTimeSeconds()
-                : UNKNOWN_TIME_PUBLISHED;
-
-        return new ContentMetadata(representationData.getUri(), offlineMetadata.getTitle(),
-                publishedTimeSeconds, imageUrl, publisher, faviconUrl, snippet);
-    }
-
-    public ContentMetadata(String url, String title, long timePublished, @Nullable String imageUrl,
-            @Nullable String publisher, @Nullable String faviconUrl, @Nullable String snippet) {
-        this.mUrl = url;
-        this.mTitle = title;
-        this.mImageUrl = imageUrl;
-        this.mPublisher = publisher;
-        this.mFaviconUrl = faviconUrl;
-        this.mSnippet = snippet;
-        this.mTimePublished = timePublished;
-    }
-
-    public String getUrl() {
-        return mUrl;
-    }
-
-    /** Title for the content. */
-    public String getTitle() {
-        return mTitle;
-    }
-
-    @Nullable
-    public String getImageUrl() {
-        return mImageUrl;
-    }
-
-    /** {@link String} representation of the publisher. */
-    @Nullable
-    public String getPublisher() {
-        return mPublisher;
-    }
-
-    /**
-     * Seconds of UTC time since the Unix Epoch 1970-01-01 T00:00:00Z or {@code
-     * UNKNOWN_TIME_PUBLISHED} if unknown.
-     */
-    public long getTimePublished() {
-        return mTimePublished;
-    }
-
-    @Nullable
-    public String getFaviconUrl() {
-        return mFaviconUrl;
-    }
-
-    /** A {@link String} that can be displayed that is part of the content, typically the start. */
-    @Nullable
-    public String getSnippet() {
-        return mSnippet;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/knowncontent/ContentRemoval.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/knowncontent/ContentRemoval.java
deleted file mode 100644
index e940402..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/knowncontent/ContentRemoval.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.client.knowncontent;
-
-/** Information on the removal of a piece of content. */
-public final class ContentRemoval {
-    private final String mUrl;
-    private final boolean mRequestedByUser;
-
-    public ContentRemoval(String url, boolean requestedByUser) {
-        this.mUrl = url;
-        this.mRequestedByUser = requestedByUser;
-    }
-
-    /** Url for removed content. */
-    public String getUrl() {
-        return mUrl;
-    }
-
-    /** Whether the removal was performed through an action of the user. */
-    public boolean isRequestedByUser() {
-        return mRequestedByUser;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/knowncontent/KnownContent.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/knowncontent/KnownContent.java
deleted file mode 100644
index 17a8807..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/knowncontent/KnownContent.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.client.knowncontent;
-
-import org.chromium.base.Consumer;
-
-import java.util.List;
-
-/** Allows the host to request and subscribe to information about the Feed's content. */
-public interface KnownContent {
-    /**
-     * Async call to get the list of all content that is known about by the Feed. The list will be
-     * in the same order that the content will appear.
-     *
-     * <p>Note: This method can be expensive. As such it should not be called at latency critical
-     * moments, namely during startup.
-     */
-    void getKnownContent(Consumer<List<ContentMetadata>> knownContentConsumer);
-
-    /** Adds listener for new content. */
-    void addListener(Listener listener);
-
-    /** Removes listener for new content. */
-    void removeListener(Listener listener);
-
-    /** Listener for when content is added or removed. */
-    interface Listener {
-        /**
-         * Called when content is removed.
-         *
-         * @param contentRemoved {@link List} of removed content.
-         */
-        void onContentRemoved(List<ContentRemoval> contentRemoved);
-
-        /**
-         * Notifies host that new content has been received.
-         *
-         * @param isNewRefresh {@code true} if the content is from a new refresh, {@code false}
-         *     otherwise, such as from a pagination request.
-         * @param contentCreationDateTimeMs the date/time of when the content was added in
-         *         milliseconds.
-         */
-        void onNewContentReceived(boolean isNewRefresh, long contentCreationDateTimeMs);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/lifecycle/AppLifecycleListener.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/lifecycle/AppLifecycleListener.java
deleted file mode 100644
index 433f06ba..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/lifecycle/AppLifecycleListener.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.client.lifecycle;
-
-/**
- * Interface to allow host applications to communicate changes in state to Feed.
- *
- * <p>Note that these are related to app lifecycle, not UI lifecycle
- */
-public interface AppLifecycleListener {
-    /** Called after critical loading has completed but before Feed is rendered. */
-    void onEnterForeground();
-
-    /** Called when the app is backgrounded, will perform clean up. */
-    void onEnterBackground();
-
-    /**
-     * Called when host wants to clear all data. Will delete content without changing opt-in /
-     * opt-out status.
-     */
-    void onClearAll();
-
-    /** Called to clear all data then initiate a refresh. */
-    void onClearAllWithRefresh();
-
-    /** Called when user signs in. */
-    void onSignedIn();
-
-    /** Called when user signs out. */
-    void onSignedOut();
-
-    /**
-     * Called when the host wants the Feed to perform any heavyweight initialization it might need
-     * to do. This is the only trigger for the initialization process; if it’s not called, the host
-     * should not expect the Feed to be able to render cards.
-     */
-    void initialize();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/requestmanager/RequestManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/requestmanager/RequestManager.java
deleted file mode 100644
index 5c9e782..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/requestmanager/RequestManager.java
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.client.requestmanager;
-
-/** Creates and issues requests to the server. */
-public interface RequestManager {
-    /** Issues a request to refresh the entire feed. */
-    void triggerScheduledRefresh();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/ProcessScope.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/ProcessScope.java
deleted file mode 100644
index 8d2d742..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/ProcessScope.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.client.scope;
-
-import android.app.Activity;
-
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.KnownContent;
-import org.chromium.chrome.browser.feed.library.api.client.lifecycle.AppLifecycleListener;
-import org.chromium.chrome.browser.feed.library.api.client.requestmanager.RequestManager;
-import org.chromium.chrome.browser.feed.library.api.host.action.ActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.imageloader.ImageLoaderApi;
-import org.chromium.chrome.browser.feed.library.api.host.offlineindicator.OfflineIndicatorApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.CardConfiguration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.SnackbarApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.StreamConfiguration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipApi;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-
-/** Allows interaction with the Feed library at the process leve. */
-public interface ProcessScope extends Dumpable {
-    /** Returns the Feed library request manager. */
-    RequestManager getRequestManager();
-
-    /** Returns the Feed library task queue. */
-    TaskQueue getTaskQueue();
-
-    /** Returns the Feed library lifecycle listener. */
-    AppLifecycleListener getAppLifecycleListener();
-
-    /** Returns the Feed library known content. */
-    KnownContent getKnownContent();
-
-    /** Returns a {@link StreamScopeBuilder.Builder}. */
-    StreamScopeBuilder createStreamScopeBuilder(Activity activity, ImageLoaderApi imageLoaderApi,
-            ActionApi actionApi, StreamConfiguration streamConfiguration,
-            CardConfiguration cardConfiguration, SnackbarApi snackbarApi,
-            OfflineIndicatorApi offlineIndicatorApi, TooltipApi tooltipApi);
-
-    /** Called to destroy the scope object. */
-    void onDestroy();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/ProcessScopeBuilder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/ProcessScopeBuilder.java
deleted file mode 100644
index 59a830a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/ProcessScopeBuilder.java
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.client.scope;
-
-import android.content.Context;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.api.host.config.ApplicationInfo;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.feed.library.api.host.config.DebugBehavior;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.network.NetworkClient;
-import org.chromium.chrome.browser.feed.library.api.host.proto.ProtoExtensionProvider;
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorage;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorageDirect;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorage;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorageDirect;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipSupportedApi;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionReader;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.knowncontent.FeedKnownContent;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.api.internal.requestmanager.ActionUploadRequestManager;
-import org.chromium.chrome.browser.feed.library.api.internal.requestmanager.FeedRequestManager;
-import org.chromium.chrome.browser.feed.library.api.internal.scope.ClearAllListener;
-import org.chromium.chrome.browser.feed.library.api.internal.scope.FeedProcessScope;
-import org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager;
-import org.chromium.chrome.browser.feed.library.common.Validators;
-import org.chromium.chrome.browser.feed.library.common.concurrent.DirectHostSupported;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.protoextensions.FeedExtensionRegistry;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.common.time.SystemClockImpl;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.feedactionmanager.FeedActionManagerImpl;
-import org.chromium.chrome.browser.feed.library.feedactionreader.FeedActionReader;
-import org.chromium.chrome.browser.feed.library.feedapplifecyclelistener.FeedAppLifecycleListener;
-import org.chromium.chrome.browser.feed.library.feedknowncontent.FeedKnownContentImpl;
-import org.chromium.chrome.browser.feed.library.feedprotocoladapter.FeedProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.feedrequestmanager.FeedActionUploadRequestManager;
-import org.chromium.chrome.browser.feed.library.feedrequestmanager.FeedRequestManagerImpl;
-import org.chromium.chrome.browser.feed.library.feedrequestmanager.RequestManagerImpl;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.FeedSessionManagerFactory;
-import org.chromium.chrome.browser.feed.library.feedstore.ContentStorageDirectImpl;
-import org.chromium.chrome.browser.feed.library.feedstore.FeedStore;
-import org.chromium.chrome.browser.feed.library.feedstore.JournalStorageDirectImpl;
-import org.chromium.chrome.browser.feed.library.hostimpl.network.NetworkClientWrapper;
-import org.chromium.chrome.browser.feed.library.hostimpl.scheduler.SchedulerApiWrapper;
-import org.chromium.chrome.browser.feed.library.sharedstream.piet.PietRequiredContentAdapter;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.concurrent.Executor;
-
-/** Creates an instance of {@link ProcessScope} */
-public final class ProcessScopeBuilder {
-    // Required fields.
-    private final Configuration mConfiguration;
-    private final Executor mSequencedExecutor;
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final TooltipSupportedApi mTooltipSupportedApi;
-    private final NetworkClient mUnwrappedNetworkClient;
-    private final SchedulerApi mUnwrappedSchedulerApi;
-    private final DebugBehavior mDebugBehavior;
-    private final Context mContext;
-    private final ApplicationInfo mApplicationInfo;
-
-    // Optional fields - if they are not provided, we will use default implementations.
-    private ProtoExtensionProvider mProtoExtensionProvider;
-    private Clock mClock;
-
-    // Either contentStorage or rawContentStorage must be provided.
-    ContentStorageDirect mContentStorage;
-    private ContentStorage mRawContentStorage;
-
-    // Either journalStorage or rawJournalStorage must be provided.
-    JournalStorageDirect mJournalStorage;
-    private JournalStorage mRawJournalStorage;
-
-    /** The APIs are all required to construct the scope. */
-    public ProcessScopeBuilder(Configuration configuration, Executor sequencedExecutor,
-            BasicLoggingApi basicLoggingApi, NetworkClient networkClient, SchedulerApi schedulerApi,
-            DebugBehavior debugBehavior, Context context, ApplicationInfo applicationInfo,
-            TooltipSupportedApi tooltipSupportedApi) {
-        this.mConfiguration = configuration;
-        this.mSequencedExecutor = sequencedExecutor;
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mDebugBehavior = debugBehavior;
-        this.mContext = context;
-        this.mApplicationInfo = applicationInfo;
-        this.mUnwrappedNetworkClient = networkClient;
-        this.mUnwrappedSchedulerApi = schedulerApi;
-        this.mTooltipSupportedApi = tooltipSupportedApi;
-    }
-
-    public ProcessScopeBuilder setProtoExtensionProvider(
-            ProtoExtensionProvider protoExtensionProvider) {
-        this.mProtoExtensionProvider = protoExtensionProvider;
-        return this;
-    }
-
-    public ProcessScopeBuilder setContentStorage(ContentStorage contentStorage) {
-        mRawContentStorage = contentStorage;
-        return this;
-    }
-
-    public ProcessScopeBuilder setContentStorageDirect(ContentStorageDirect contentStorage) {
-        this.mContentStorage = contentStorage;
-        return this;
-    }
-
-    public ProcessScopeBuilder setJournalStorage(JournalStorage journalStorage) {
-        mRawJournalStorage = journalStorage;
-        return this;
-    }
-
-    public ProcessScopeBuilder setJournalStorageDirect(JournalStorageDirect journalStorage) {
-        this.mJournalStorage = journalStorage;
-        return this;
-    }
-
-    @VisibleForTesting
-    ContentStorageDirect buildContentStorage(MainThreadRunner mainThreadRunner) {
-        if (mContentStorage == null) {
-            boolean useDirect =
-                    mConfiguration.getValueOrDefault(ConfigKey.USE_DIRECT_STORAGE, false);
-            if (useDirect && mRawContentStorage != null
-                    && mRawContentStorage instanceof ContentStorageDirect) {
-                mContentStorage = (ContentStorageDirect) mRawContentStorage;
-            } else if (mRawContentStorage != null) {
-                mContentStorage =
-                        new ContentStorageDirectImpl(mRawContentStorage, mainThreadRunner);
-            } else {
-                throw new IllegalStateException(
-                        "one of ContentStorage, ContentStorageDirect must be provided");
-            }
-        }
-        return mContentStorage;
-    }
-
-    @VisibleForTesting
-    JournalStorageDirect buildJournalStorage(MainThreadRunner mainThreadRunner) {
-        if (mJournalStorage == null) {
-            boolean useDirect =
-                    mConfiguration.getValueOrDefault(ConfigKey.USE_DIRECT_STORAGE, false);
-            if (useDirect && mRawJournalStorage != null
-                    && mRawJournalStorage instanceof JournalStorageDirect) {
-                mJournalStorage = (JournalStorageDirect) mRawJournalStorage;
-            } else if (mRawJournalStorage != null) {
-                mJournalStorage =
-                        new JournalStorageDirectImpl(mRawJournalStorage, mainThreadRunner);
-            } else {
-                throw new IllegalStateException(
-                        "one of JournalStorage, JournalStorageDirect must be provided");
-            }
-        }
-        return mJournalStorage;
-    }
-
-    public ProcessScope build() {
-        MainThreadRunner mainThreadRunner = new MainThreadRunner();
-        mContentStorage = buildContentStorage(mainThreadRunner);
-        mJournalStorage = buildJournalStorage(mainThreadRunner);
-
-        ThreadUtils threadUtils = new ThreadUtils();
-
-        boolean directHostCallEnabled =
-                mConfiguration.getValueOrDefault(ConfigKey.USE_DIRECT_STORAGE, false);
-        NetworkClient networkClient;
-        SchedulerApi schedulerApi;
-        if (mUnwrappedNetworkClient instanceof DirectHostSupported && directHostCallEnabled) {
-            networkClient = mUnwrappedNetworkClient;
-        } else {
-            networkClient = new NetworkClientWrapper(
-                    mUnwrappedNetworkClient, threadUtils, mainThreadRunner);
-        }
-        if (mUnwrappedSchedulerApi instanceof DirectHostSupported && directHostCallEnabled) {
-            schedulerApi = mUnwrappedSchedulerApi;
-        } else {
-            schedulerApi =
-                    new SchedulerApiWrapper(mUnwrappedSchedulerApi, threadUtils, mainThreadRunner);
-        }
-
-        // Build default component instances if necessary.
-        if (mProtoExtensionProvider == null) {
-            // Return an empty list of extensions by default.
-            mProtoExtensionProvider = ArrayList::new;
-        }
-        FeedExtensionRegistry extensionRegistry =
-                new FeedExtensionRegistry(mProtoExtensionProvider);
-        if (mClock == null) {
-            mClock = new SystemClockImpl();
-        }
-        TimingUtils timingUtils = new TimingUtils();
-        TaskQueue taskQueue =
-                new TaskQueue(mBasicLoggingApi, mSequencedExecutor, mainThreadRunner, mClock);
-        FeedStore store = new FeedStore(mConfiguration, timingUtils, extensionRegistry,
-                mContentStorage, mJournalStorage, threadUtils, taskQueue, mClock, mBasicLoggingApi,
-                mainThreadRunner);
-
-        FeedAppLifecycleListener lifecycleListener = new FeedAppLifecycleListener(threadUtils);
-        lifecycleListener.registerObserver(store);
-
-        ProtocolAdapter protocolAdapter = new FeedProtocolAdapter(
-                Collections.singletonList(new PietRequiredContentAdapter()), timingUtils);
-        ActionReader actionReader =
-                new FeedActionReader(store, mClock, protocolAdapter, taskQueue, mConfiguration);
-        FeedRequestManager feedRequestManager = new FeedRequestManagerImpl(mConfiguration,
-                networkClient, protocolAdapter, extensionRegistry, schedulerApi, taskQueue,
-                timingUtils, threadUtils, actionReader, mContext, mApplicationInfo,
-                mainThreadRunner, mBasicLoggingApi, mTooltipSupportedApi);
-        FeedActionManagerImpl actionManager = new FeedActionManagerImpl(
-                store, threadUtils, taskQueue, mainThreadRunner, mClock, mBasicLoggingApi);
-        ActionUploadRequestManager actionUploadRequestManager = new FeedActionUploadRequestManager(
-                actionManager, mConfiguration, networkClient, protocolAdapter, extensionRegistry,
-                mainThreadRunner, taskQueue, threadUtils, store, mClock);
-        FeedSessionManagerFactory fsmFactory = new FeedSessionManagerFactory(taskQueue, store,
-                timingUtils, threadUtils, protocolAdapter, feedRequestManager,
-                actionUploadRequestManager, schedulerApi, mConfiguration, mClock, lifecycleListener,
-                mainThreadRunner, mBasicLoggingApi, actionManager);
-        FeedSessionManager feedSessionManager = fsmFactory.create();
-        actionManager.initialize(feedSessionManager);
-        RequestManagerImpl clientRequestManager =
-                new RequestManagerImpl(feedRequestManager, feedSessionManager);
-
-        FeedKnownContent feedKnownContent =
-                new FeedKnownContentImpl(feedSessionManager, mainThreadRunner, threadUtils);
-
-        ClearAllListener clearAllListener = new ClearAllListener(
-                taskQueue, feedSessionManager, store, threadUtils, lifecycleListener);
-        return new FeedProcessScope(mBasicLoggingApi, networkClient,
-                Validators.checkNotNull(protocolAdapter),
-                Validators.checkNotNull(clientRequestManager),
-                Validators.checkNotNull(feedSessionManager), store, timingUtils, threadUtils,
-                taskQueue, mainThreadRunner, lifecycleListener, mClock, mDebugBehavior,
-                actionManager, mConfiguration, feedKnownContent, extensionRegistry,
-                clearAllListener, mTooltipSupportedApi, mApplicationInfo);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/StreamScope.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/StreamScope.java
deleted file mode 100644
index 7007984..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/StreamScope.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.client.scope;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProviderFactory;
-import org.chromium.chrome.browser.feed.shared.stream.Stream;
-
-/** Allows interacting with the Feed library on a per-stream level */
-public interface StreamScope {
-    /** Returns the current {@link Stream}. */
-    Stream getStream();
-
-    /** Returns the current {@link ModelProviderFactory}. */
-    ModelProviderFactory getModelProviderFactory();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/StreamScopeBuilder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/StreamScopeBuilder.java
deleted file mode 100644
index 1ec06bc..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/StreamScopeBuilder.java
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.client.scope;
-
-import android.app.Activity;
-
-import org.chromium.chrome.browser.feed.library.api.host.action.ActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.config.ApplicationInfo;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.DebugBehavior;
-import org.chromium.chrome.browser.feed.library.api.host.imageloader.ImageLoaderApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.offlineindicator.OfflineIndicatorApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.CardConfiguration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.SnackbarApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.StreamConfiguration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipSupportedApi;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionParserFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.knowncontent.FeedKnownContent;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProviderFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.api.internal.scope.FeedStreamScope;
-import org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.stream.BasicStreamFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.stream.StreamFactory;
-import org.chromium.chrome.browser.feed.library.common.Validators;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.protoextensions.FeedExtensionRegistry;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.feedactionparser.FeedActionParserFactory;
-import org.chromium.chrome.browser.feed.library.feedmodelprovider.FeedModelProviderFactory;
-import org.chromium.chrome.browser.feed.library.piet.host.CustomElementProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.HostBindingProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.ThrowingCustomElementProvider;
-import org.chromium.chrome.browser.feed.shared.stream.Stream;
-
-/** A builder that creates a {@link StreamScope}. */
-public final class StreamScopeBuilder {
-    // Required external dependencies.
-    private final Activity mActivity;
-    private final ActionApi mActionApi;
-    private final ImageLoaderApi mImageLoaderApi;
-
-    private final ProtocolAdapter mProtocolAdapter;
-    private final FeedSessionManager mFeedSessionManager;
-    private final ThreadUtils mThreadUtils;
-    private final TimingUtils mTimingUtils;
-    private final TaskQueue mTaskQueue;
-    private final MainThreadRunner mMainThreadRunner;
-    private final Clock mClock;
-    private final ActionManager mActionManager;
-    private final CardConfiguration mCardConfiguration;
-    private final StreamConfiguration mStreamConfiguration;
-    private final DebugBehavior mDebugBehavior;
-    private final Configuration mConfig;
-    private final SnackbarApi mSnackbarApi;
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final OfflineIndicatorApi mOfflineIndicatorApi;
-    private final FeedKnownContent mFeedKnownContent;
-    private final TooltipApi mTooltipApi;
-    private final ApplicationInfo mApplicationInfo;
-    private final FeedExtensionRegistry mFeedExtensionRegistry;
-    private boolean mIsBackgroundDark;
-    private boolean mIsPlaceholderShown;
-
-    // Optional internal components to override the default implementations.
-    private ActionParserFactory mActionParserFactory;
-    private ModelProviderFactory mModelProviderFactory;
-    private Stream mStream;
-    private StreamFactory mStreamFactory;
-    private CustomElementProvider mCustomElementProvider;
-    private HostBindingProvider mHostBindingProvider;
-
-    /** Construct this builder using {@link ProcessScope#createStreamScopeBuilder} */
-    public StreamScopeBuilder(Activity activity, ActionApi actionApi, ImageLoaderApi imageLoaderApi,
-            ProtocolAdapter protocolAdapter, FeedSessionManager feedSessionManager,
-            ThreadUtils threadUtils, TimingUtils timingUtils, TaskQueue taskQueue,
-            MainThreadRunner mainThreadRunner, Clock clock, DebugBehavior debugBehavior,
-            StreamConfiguration streamConfiguration, CardConfiguration cardConfiguration,
-            ActionManager actionManager, Configuration config, SnackbarApi snackbarApi,
-            BasicLoggingApi basicLoggingApi, OfflineIndicatorApi offlineIndicatorApi,
-            FeedKnownContent feedKnownContent, TooltipApi tooltipApi,
-            TooltipSupportedApi tooltipSupportedApi, ApplicationInfo applicationInfo,
-            FeedExtensionRegistry feedExtensionRegistry) {
-        this.mActivity = activity;
-        this.mActionApi = actionApi;
-        this.mImageLoaderApi = imageLoaderApi;
-        this.mProtocolAdapter = protocolAdapter;
-        this.mFeedSessionManager = feedSessionManager;
-        this.mThreadUtils = threadUtils;
-        this.mTimingUtils = timingUtils;
-        this.mTaskQueue = taskQueue;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mStreamConfiguration = streamConfiguration;
-        this.mCardConfiguration = cardConfiguration;
-        this.mClock = clock;
-        this.mDebugBehavior = debugBehavior;
-        this.mActionManager = actionManager;
-        this.mConfig = config;
-        this.mSnackbarApi = snackbarApi;
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mOfflineIndicatorApi = offlineIndicatorApi;
-        this.mFeedKnownContent = feedKnownContent;
-        this.mTooltipApi = tooltipApi;
-        this.mApplicationInfo = applicationInfo;
-        this.mFeedExtensionRegistry = feedExtensionRegistry;
-    }
-
-    public StreamScopeBuilder setIsBackgroundDark(boolean isBackgroundDark) {
-        this.mIsBackgroundDark = isBackgroundDark;
-        return this;
-    }
-
-    public StreamScopeBuilder setIsPlaceholderShown(boolean isPlaceholderShown) {
-        this.mIsPlaceholderShown = isPlaceholderShown;
-        return this;
-    }
-
-    public StreamScopeBuilder setStreamFactory(StreamFactory streamFactory) {
-        this.mStreamFactory = streamFactory;
-        return this;
-    }
-
-    public StreamScopeBuilder setModelProviderFactory(ModelProviderFactory modelProviderFactory) {
-        this.mModelProviderFactory = modelProviderFactory;
-        return this;
-    }
-
-    public StreamScopeBuilder setCustomElementProvider(
-            CustomElementProvider customElementProvider) {
-        this.mCustomElementProvider = customElementProvider;
-        return this;
-    }
-
-    public StreamScopeBuilder setHostBindingProvider(HostBindingProvider hostBindingProvider) {
-        this.mHostBindingProvider = hostBindingProvider;
-        return this;
-    }
-
-    public StreamScope build() {
-        if (mModelProviderFactory == null) {
-            mModelProviderFactory = new FeedModelProviderFactory(mFeedSessionManager, mThreadUtils,
-                    mTimingUtils, mTaskQueue, mMainThreadRunner, mConfig, mBasicLoggingApi);
-        }
-        if (mActionParserFactory == null) {
-            mActionParserFactory = new FeedActionParserFactory(mProtocolAdapter, mBasicLoggingApi);
-        }
-        if (mCustomElementProvider == null) {
-            mCustomElementProvider = new ThrowingCustomElementProvider();
-        }
-        if (mHostBindingProvider == null) {
-            mHostBindingProvider = new HostBindingProvider();
-        }
-        if (mStreamFactory == null) {
-            mStreamFactory = new BasicStreamFactory();
-        }
-        mStream = mStreamFactory.build(Validators.checkNotNull(mActionParserFactory), mActivity,
-                mApplicationInfo.getBuildType(), mCardConfiguration, mImageLoaderApi,
-                Validators.checkNotNull(mCustomElementProvider), mDebugBehavior, mClock,
-                Validators.checkNotNull(mModelProviderFactory),
-                Validators.checkNotNull(mHostBindingProvider), mOfflineIndicatorApi, mConfig,
-                mActionApi, mActionManager, mSnackbarApi, mStreamConfiguration,
-                mFeedExtensionRegistry, mBasicLoggingApi, mMainThreadRunner, mIsBackgroundDark,
-                mTooltipApi, mThreadUtils, mFeedKnownContent, mIsPlaceholderShown);
-        return new FeedStreamScope(
-                Validators.checkNotNull(mStream), Validators.checkNotNull(mModelProviderFactory));
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/common/MutationContext.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/common/MutationContext.java
deleted file mode 100644
index 526cb0b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/common/MutationContext.java
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.common;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-
-/**
- * This tracks the context of a mutation. When a request is made, this will track the reason for the
- * request and pass this information back with the response.
- */
-public final class MutationContext {
-    @Nullable
-    private final StreamToken mContinuationToken;
-    @Nullable
-    private final String mRequestingSessionId;
-    private final boolean mUserInitiated;
-
-    /** Static used to represent an empty Mutation Context */
-    public static final MutationContext EMPTY_CONTEXT =
-            new MutationContext(null, null, UiContext.getDefaultInstance(), false);
-
-    private final UiContext mUiContext;
-
-    private MutationContext(@Nullable StreamToken continuationToken,
-            @Nullable String requestingSessionId, UiContext uiContext, boolean userInitiated) {
-        this.mContinuationToken = continuationToken;
-        this.mRequestingSessionId = requestingSessionId;
-        this.mUserInitiated = userInitiated;
-        this.mUiContext = uiContext;
-    }
-
-    /** Returns the continuation token used to make the request. */
-    @Nullable
-    public StreamToken getContinuationToken() {
-        return mContinuationToken;
-    }
-
-    /** Returns the session which made the request. */
-    @Nullable
-    public String getRequestingSessionId() {
-        return mRequestingSessionId;
-    }
-
-    /**
-     * Returns the {@link UiContext} which made the request or {@link
-     * UiContext#getDefaultInstance()} if none was present.
-     */
-    public UiContext getUiContext() {
-        return mUiContext;
-    }
-
-    /** Returns {@code true} if the mutation was user initiated. */
-    public boolean isUserInitiated() {
-        return mUserInitiated;
-    }
-
-    /**
-     * Builder for creating a {@link
-     * org.chromium.chrome.browser.feed.library.api.common.MutationContext
-     */
-    public static final class Builder {
-        private StreamToken mContinuationToken;
-        private String mRequestingSessionId;
-        private UiContext mUiContext = UiContext.getDefaultInstance();
-        private boolean mUserInitiated;
-
-        public Builder() {}
-
-        public Builder setContinuationToken(StreamToken continuationToken) {
-            this.mContinuationToken = continuationToken;
-            return this;
-        }
-
-        public Builder setRequestingSessionId(String requestingSessionId) {
-            this.mRequestingSessionId = requestingSessionId;
-            return this;
-        }
-
-        public Builder setUserInitiated(boolean userInitiated) {
-            this.mUserInitiated = userInitiated;
-            return this;
-        }
-
-        public Builder setUiContext(UiContext uiContext) {
-            this.mUiContext = uiContext;
-            return this;
-        }
-
-        public MutationContext build() {
-            return new MutationContext(
-                    mContinuationToken, mRequestingSessionId, mUiContext, mUserInitiated);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/ActionApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/ActionApi.java
deleted file mode 100644
index bb19f24..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/ActionApi.java
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.action;
-
-/**
- * The ActionApi combines the {@link ActionPeformerApi} and the {@link ActionEnabledApi} to allow
- * the Feed to query the host as to what actions can be performed and instruct the host to perform
- * such actions.
- */
-public interface ActionApi extends ActionEnabledApi, ActionPeformerApi {}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/ActionEnabledApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/ActionEnabledApi.java
deleted file mode 100644
index 8437cb3..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/ActionEnabledApi.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.action;
-
-/** Allows the Feed to query the host as to what actions are enabled. */
-public interface ActionEnabledApi {
-    /** Whether the host can open a URL. */
-    boolean canOpenUrl();
-
-    /** Whether the host can open a URL in incognito mode. */
-    boolean canOpenUrlInIncognitoMode();
-
-    /** Whether the host can open a URL in a new tab. */
-    boolean canOpenUrlInNewTab();
-
-    /** Whether the host can open a URL in a new window. */
-    boolean canOpenUrlInNewWindow();
-
-    /** Whether the host can download a URL. */
-    boolean canDownloadUrl();
-
-    /** Whether the host can open the Google Product Help page. */
-    boolean canLearnMore();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/ActionPeformerApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/ActionPeformerApi.java
deleted file mode 100644
index 8de2abf..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/ActionPeformerApi.java
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.action;
-
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.ContentMetadata;
-
-/**
- * Allows the Feed instruct the host to perform actions. In the case that an action is triggered
- * that is not enabled the host has one of two options:
- *
- * <ol>
- *   <li>The host can ignore the action.
- *   <li>The host can throw an exception which the Stream will not catch, crashing the app.
- * </ol>
- */
-public interface ActionPeformerApi {
-    /** Opens the given URL. */
-    void openUrl(String url);
-
-    /** Opens the given URL in incognito mode. */
-    void openUrlInIncognitoMode(String url);
-
-    /** Opens the given URL in a new tab. */
-    void openUrlInNewTab(String url);
-
-    /** Opens the given URL in a new window. */
-    void openUrlInNewWindow(String url);
-
-    /**
-     * Downloads the given url.
-     *
-     * @param contentMetadata The {@link ContentMetadata} defining the content to be downloaded.
-     */
-    void downloadUrl(ContentMetadata contentMetadata);
-
-    /** Opens the SendFeedback dialog for the user to report problems. */
-    void sendFeedback(ContentMetadata contentMetadata);
-
-    /** Opens the Google Product Help page for the Feed. */
-    void learnMore();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/StreamActionApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/StreamActionApi.java
deleted file mode 100644
index 43fcf2c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/StreamActionApi.java
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.action;
-
-import android.view.View;
-
-import org.chromium.chrome.browser.feed.library.api.host.logging.ActionType;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipInfo;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.OpenContextMenuData;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.UndoAction;
-import org.chromium.components.feed.core.proto.wire.ActionPayloadProto.ActionPayload;
-
-import java.util.List;
-
-/**
- * Allows the {@link org.chromium.chrome.browser.feed.library.internalapi.actionparser.ActionParser}
- * to communicate actions back to the Stream after parsing.
- */
-public interface StreamActionApi extends ActionApi {
-    /** Whether or not a context menu can be opened */
-    boolean canOpenContextMenu();
-
-    /** Opens context menu. */
-    void openContextMenu(OpenContextMenuData openContextMenuData, View anchorView);
-
-    /** Whether or not a card can be dismissed. */
-    boolean canDismiss();
-
-    /** Dismisses card. */
-    void dismiss(String contentId, List<StreamDataOperation> dataOperations, UndoAction undoAction,
-            ActionPayload payload);
-
-    /** Whether or not the not interested in action can be handled. */
-    boolean canHandleNotInterestedIn();
-
-    /** Handles the Not interested in <source> action. */
-    void handleNotInterestedIn(List<StreamDataOperation> dataOperations, UndoAction undoAction,
-            ActionPayload payload, int interestType);
-
-    /** Handles the block content action. **/
-    void handleBlockContent(List<StreamDataOperation> dataOperations, ActionPayload payload);
-
-    /** Called when a client action has been performed. */
-    void onClientAction(@ActionType int actionType);
-
-    /** Whether or not the not view actions can be handled. */
-    boolean canHandleElementView();
-
-    /** Whether or not the not hide actions can be handled. */
-    boolean canHandleElementHide();
-
-    /** Whether or not the not click actions can be handled. */
-    boolean canHandleElementClick();
-
-    /**
-     * Called when a view action has been performed on a server-defined {@link
-     * org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.ElementType}
-     * value.
-     */
-    void onElementView(int elementType);
-
-    /**
-     * Called when a hide action has been performed on a server-defined {@link
-     * org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.ElementType}
-     * value.
-     */
-    void onElementHide(int elementType);
-
-    /**
-     * Called when a click action has been performed on a server-defined {@link
-     * org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.ElementType}
-     * value.
-     */
-    void onElementClick(int elementType);
-
-    /* Reports a click action on given content ID with the given action payload. */
-    void reportClickAction(String contentId, ActionPayload payload);
-
-    /** Whether or not show tooltip actions can be handled. */
-    boolean canShowTooltip();
-
-    /**
-     * Called when the show tooltip action has been preformed. Tooltip might not be shown if it does
-     * not meet triggering conditions.
-     */
-    void maybeShowTooltip(TooltipInfo tooltipInfo, View view);
-
-    /* Called to open a url after uploading actions and attaching the consistency token to it. */
-    void openUrl(String url, String consistencyTokenQueryParamName);
-
-    /**
-     * Opens the given URL in incognito mode after uploading actions and attaching the consistency
-     * token to it.
-     */
-    void openUrlInIncognitoMode(String url, String consistencyTokenQueryParamName);
-
-    /**
-     * Opens the given URL in a new tab after uploading actions and attaching the consistency token
-     * to it.
-     */
-    void openUrlInNewTab(String url, String consistencyTokenQueryParamName);
-
-    /**
-     * Opens the given URL in a new windowafter uploading actions and attaching the consistency
-     * token to it.
-     */
-    void openUrlInNewWindow(String url, String consistencyTokenQueryParamName);
-
-    /**
-     * Reports that a particular view with corresponding content and action payload has become
-     * visible.
-     */
-    void reportViewVisible(View view, String contentId, ActionPayload payload);
-
-    /**
-     * Reports that a particular view with corresponding content and action payload has become
-     * hidden.
-     */
-    void reportViewHidden(View view, String contentId);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/config/ApplicationInfo.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/config/ApplicationInfo.java
deleted file mode 100644
index 81ffd083..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/config/ApplicationInfo.java
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.config;
-
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-
-import androidx.annotation.IntDef;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-/** API to allow the Feed to get information about the host application. */
-// TODO: This can't be final because we mock it
-public class ApplicationInfo {
-    @IntDef({AppType.UNKNOWN_APP, AppType.SEARCH_APP, AppType.CHROME, AppType.TEST_APP})
-    public @interface AppType {
-        int UNKNOWN_APP = 0;
-        int SEARCH_APP = 1;
-        int CHROME = 2;
-        int TEST_APP = 3;
-    }
-
-    @IntDef({
-            Architecture.UNKNOWN_ACHITECTURE,
-            Architecture.ARM,
-            Architecture.ARM64,
-            Architecture.MIPS,
-            Architecture.MIPS64,
-            Architecture.X86,
-            Architecture.X86_64,
-    })
-    public @interface Architecture {
-        int UNKNOWN_ACHITECTURE = 0;
-        int ARM = 1;
-        int ARM64 = 2;
-        int MIPS = 3;
-        int MIPS64 = 4;
-        int X86 = 5;
-        int X86_64 = 6;
-    }
-
-    @IntDef({BuildType.UNKNOWN_BUILD_TYPE, BuildType.DEV, BuildType.ALPHA, BuildType.BETA,
-            BuildType.RELEASE})
-    public @interface BuildType {
-        int UNKNOWN_BUILD_TYPE = 0;
-        int DEV = 1;
-        int ALPHA = 2;
-        int BETA = 3;
-        int RELEASE = 4;
-    }
-
-    @AppType
-    private final int mAppType;
-    @Architecture
-    private final int mArchitecture;
-    @BuildType
-    private final int mBuildType;
-    private final String mVersionString;
-
-    private ApplicationInfo(int appType, int architecture, int buildType, String versionString) {
-        this.mAppType = appType;
-        this.mArchitecture = architecture;
-        this.mBuildType = buildType;
-        this.mVersionString = versionString;
-    }
-
-    @AppType
-    public int getAppType() {
-        return mAppType;
-    }
-
-    @Architecture
-    public int getArchitecture() {
-        return mArchitecture;
-    }
-
-    @BuildType
-    public int getBuildType() {
-        return mBuildType;
-    }
-
-    public String getVersionString() {
-        return mVersionString;
-    }
-
-    /** Builder class used to create {@link ApplicationInfo} objects. */
-    public static final class Builder {
-        private static final String TAG = "Builder";
-
-        private final Context mContext;
-        @AppType
-        private int mAppType = AppType.UNKNOWN_APP;
-        @Architecture
-        private int mAchitecture = Architecture.UNKNOWN_ACHITECTURE;
-        @BuildType
-        private int mBuildType = BuildType.UNKNOWN_BUILD_TYPE;
-
-        private String mVersionString;
-
-        public Builder(Context context) {
-            this.mContext = context;
-        }
-
-        /** Sets the type of client application. */
-        public Builder setAppType(@AppType int appType) {
-            this.mAppType = appType;
-            return this;
-        }
-
-        /** Sets the CPU architecture that the client application was built for. */
-        public Builder setArchitecture(@Architecture int architecture) {
-            this.mAchitecture = architecture;
-            return this;
-        }
-
-        /** Sets the release stage of the build for the client application. */
-        public Builder setBuildType(@BuildType int buildType) {
-            this.mBuildType = buildType;
-            return this;
-        }
-
-        /**
-         * Sets the major/minor/build/revision numbers of the application version from the given
-         * string. A version string typically looks like: 'major.minor.build.revision'. If not set
-         * here, it will be retrieved from the application's versionName string defined in the
-         * manifest (see https://developer.android.com/studio/publish/versioning).
-         */
-        public Builder setVersionString(String versionString) {
-            this.mVersionString = versionString;
-            return this;
-        }
-
-        public ApplicationInfo build() {
-            if (mVersionString == null) {
-                mVersionString = getDefaultVersionString();
-            }
-            return new ApplicationInfo(mAppType, mAchitecture, mBuildType, mVersionString);
-        }
-
-        private String getDefaultVersionString() {
-            try {
-                PackageInfo pInfo =
-                        mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
-                return pInfo.versionName;
-            } catch (NameNotFoundException e) {
-                Logger.w(TAG, e, "Cannot find package name.");
-            }
-            return "";
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/config/Configuration.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/config/Configuration.java
deleted file mode 100644
index 4d4d3ab..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/config/Configuration.java
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.config;
-
-import androidx.annotation.StringDef;
-
-import java.util.HashMap;
-
-/**
- * Contains an immutable collection of {@link ConfigKey} {@link String}, {@link Object} pairs.
- *
- * <p>Note: this class should not be mocked. Use the {@link Builder} instead.
- */
-// TODO: This can't be final because we mock it
-public class Configuration {
-    /** A unique string identifier for a config value */
-    @StringDef({
-            // Keep sorted.
-            // Configuration to have Stream abort restores if user is past configured fold count.
-            ConfigKey.ABANDON_RESTORE_BELOW_FOLD,
-            // Configuration on threshold of cards which abandons a restore if scroll is past that
-            // content
-            // count.
-            ConfigKey.ABANDON_RESTORE_BELOW_FOLD_THRESHOLD,
-            // Boolean which if true, will allow tooltips to show.
-            ConfigKey.CARD_MENU_TOOLTIP_ELIGIBLE,
-            // Boolean which causes synthetic tokens to be consumed when they are found.
-            ConfigKey.CONSUME_SYNTHETIC_TOKENS,
-            // Boolean which causes synthetic tokens to be automatically consume when restoring.
-            // This will
-            // not cause synthetic tokens to be consumed when opening with a new session.
-            ConfigKey.CONSUME_SYNTHETIC_TOKENS_WHILE_RESTORING,
-            ConfigKey.DEFAULT_ACTION_TTL_SECONDS,
-            // When enabled, will ask server to add carousels in response.
-            ConfigKey.ENABLE_CAROUSELS,
-            // Time in ms to wait for image loading before showing a fade in animation.
-            ConfigKey.FADE_IMAGE_THRESHOLD_MS,
-            // Maximum number of times we will try to upload an action before deleting it.
-            ConfigKey.FEED_ACTION_MAX_UPLOAD_ATTEMPTS,
-            // The endpoint used for recording uploaded actions to the server.
-            ConfigKey.FEED_ACTION_SERVER_ENDPOINT,
-            // Maximum number of actions to be uploaded to the enpoint in a single request.
-            ConfigKey.FEED_ACTION_SERVER_MAX_ACTIONS_PER_REQUEST,
-            // Maximum size of the request to be uploaded to the enpoint in a single request.
-            ConfigKey.FEED_ACTION_SERVER_MAX_SIZE_PER_REQUEST,
-            // The method call to the feed action server  (put/post/etc)
-            ConfigKey.FEED_ACTION_SERVER_METHOD,
-            // If the feedActionServer response is length prefixed
-            ConfigKey.FEED_ACTION_SERVER_RESPONSE_LENGTH_PREFIXED,
-            // Ttl of an action that has failed to be uploaded.
-            ConfigKey.FEED_ACTION_TTL_SECONDS,
-            ConfigKey.FEED_SERVER_ENDPOINT,
-            ConfigKey.FEED_SERVER_METHOD,
-            ConfigKey.FEED_SERVER_RESPONSE_LENGTH_PREFIXED,
-            // Boolean which if true, will ask the server for the feed ui response.
-            ConfigKey.FEED_UI_ENABLED,
-            ConfigKey.INITIAL_NON_CACHED_PAGE_SIZE,
-            // Only update HEAD and the session making a page request
-            ConfigKey.LIMIT_PAGE_UPDATES,
-            // Do not update HEAD when making a page request
-            ConfigKey.LIMIT_PAGE_UPDATES_IN_HEAD,
-            // Time in ms that content should be rendered in order to be considered an immediate
-            // open
-            ConfigKey.LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS,
-            // Boolean which if true, will ask the server for an menu option to launch the interest
-            // management customize page.
-            ConfigKey.MANAGE_INTERESTS_ENABLED,
-            // The maximum number of times that the GC task can re-enqueue itself.
-            ConfigKey.MAXIMUM_GC_ATTEMPTS,
-            ConfigKey.MINIMUM_VALID_ACTION_RATIO,
-            ConfigKey.NON_CACHED_MIN_PAGE_SIZE,
-            ConfigKey.NON_CACHED_PAGE_SIZE,
-            // Boolean which if true, will ask the server for a menu option to allow the user to
-            // provide feedback on that article.
-            ConfigKey.SEND_FEEDBACK_ENABLED,
-            ConfigKey.SESSION_LIFETIME_MS,
-            // Boolean which if true, will ask the server for a snippet from the article.
-            ConfigKey.SNIPPETS_ENABLED,
-            // Delay before a spinner should be shown after content is requested. Only used for feed
-            // wide
-            // spinners, not for more button spinners.
-            ConfigKey.SPINNER_DELAY_MS,
-            // Minimum time before a spinner should show before disappearing. Only used for feed
-            // wide
-            // spinners, not for more button spinners.
-            ConfigKey.SPINNER_MINIMUM_SHOW_TIME_MS,
-            // The number of items that can be missing from a call to FeedStore before failing.
-            ConfigKey.STORAGE_MISS_THRESHOLD,
-            // Time in ms for the length of the timeout
-            ConfigKey.TIMEOUT_TIMEOUT_MS,
-            ConfigKey.TRIGGER_IMMEDIATE_PAGINATION,
-            // Turn on the Timeout Scheduler
-            // Boolean which if true, will ask the server for not interested in actions and a
-            // durable
-            // dismiss action.
-            ConfigKey.UNDOABLE_ACTIONS_ENABLED,
-            // Use direct storage
-            ConfigKey.USE_DIRECT_STORAGE,
-            // Boolean which if true, will ask the server for a different pagination strategy.
-            ConfigKey.USE_SECONDARY_PAGE_REQUEST,
-            ConfigKey.USE_TIMEOUT_SCHEDULER,
-            // Percentage of the view that should be on screen to log a view
-            ConfigKey.VIEW_LOG_THRESHOLD,
-            // Time in ms for the minimum amount of time a view must be onscreen to count as a view.
-            ConfigKey.VIEW_MIN_TIME_MS,
-    })
-    public @interface ConfigKey {
-        // Keep sorted.
-        String ABANDON_RESTORE_BELOW_FOLD = "abandon_restore_below_fold";
-        String ABANDON_RESTORE_BELOW_FOLD_THRESHOLD = "abandon_restore_below_fold_threshold";
-        String CARD_MENU_TOOLTIP_ELIGIBLE = "card_menu_tooltip_eligible";
-        String CONSUME_SYNTHETIC_TOKENS = "consume_synthetic_tokens_bool";
-        String CONSUME_SYNTHETIC_TOKENS_WHILE_RESTORING =
-                "consume_synthetic_tokens_while_restoring_bool";
-        String DEFAULT_ACTION_TTL_SECONDS = "default_action_ttl_seconds";
-        String ENABLE_CAROUSELS = "enable_carousels";
-        String FADE_IMAGE_THRESHOLD_MS = "fade_image_threshold_ms";
-        String FEED_ACTION_MAX_UPLOAD_ATTEMPTS = "feed_action_max_upload_attempts";
-        String FEED_ACTION_SERVER_ENDPOINT = "feed_action_server_endpoint";
-        String FEED_ACTION_SERVER_MAX_ACTIONS_PER_REQUEST =
-                "feed_action_server_max_actions_per_request";
-        String FEED_ACTION_SERVER_MAX_SIZE_PER_REQUEST = "feed_action_server_max_size_per_request";
-        String FEED_ACTION_SERVER_METHOD = "feed_action_server_method";
-        String FEED_ACTION_SERVER_RESPONSE_LENGTH_PREFIXED =
-                "feed_action_server_response_length_prefixed";
-        String FEED_ACTION_TTL_SECONDS = "feed_action_ttl_seconds";
-        String FEED_SERVER_ENDPOINT = "feed_server_endpoint";
-        String FEED_SERVER_METHOD = "feed_server_method";
-        String FEED_SERVER_RESPONSE_LENGTH_PREFIXED = "feed_server_response_length_prefixed";
-        String FEED_UI_ENABLED = "feed_ui_enabled";
-        String INITIAL_NON_CACHED_PAGE_SIZE = "initial_non_cached_page_size";
-        String LIMIT_PAGE_UPDATES = "limit_page_updates";
-        String LIMIT_PAGE_UPDATES_IN_HEAD = "limit_page_updates_in_head";
-        String LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS = "logging_immediate_content_threshold_ms";
-        String MANAGE_INTERESTS_ENABLED = "manage_interests_enabled";
-        String MAXIMUM_GC_ATTEMPTS = "maximum_gc_attempts";
-        String MINIMUM_VALID_ACTION_RATIO = "minimum_valid_action_ratio";
-        String NON_CACHED_MIN_PAGE_SIZE = "non_cached_min_page_size";
-        String NON_CACHED_PAGE_SIZE = "non_cached_page_size";
-        String SEND_FEEDBACK_ENABLED = "send_feedback_enabled";
-        String SESSION_LIFETIME_MS = "session_lifetime_ms";
-        String SNIPPETS_ENABLED = "snippets_enabled";
-        String SPINNER_DELAY_MS = "spinner_delay";
-        String SPINNER_MINIMUM_SHOW_TIME_MS = "spinner_minimum_show_time";
-        String STORAGE_MISS_THRESHOLD = "storage_miss_threshold";
-        String TIMEOUT_TIMEOUT_MS = "timeout_timeout_ms";
-        String TRIGGER_IMMEDIATE_PAGINATION = "trigger_immediate_pagination_bool";
-        String UNDOABLE_ACTIONS_ENABLED = "undoable_actions_enabled";
-        String USE_DIRECT_STORAGE = "use_direct_storage";
-        String USE_SECONDARY_PAGE_REQUEST = "use_secondary_page_request";
-        String USE_TIMEOUT_SCHEDULER = "use_timeout_scheduler";
-        String VIEW_LOG_THRESHOLD = "view_log_threshold";
-        String VIEW_MIN_TIME_MS = "view_min_time_ms";
-    }
-
-    private final HashMap<String, Object> mValues;
-
-    private Configuration(HashMap<String, Object> values) {
-        this.mValues = values;
-    }
-
-    public String getValueOrDefault(String key, String defaultValue) {
-        return this.<String>getValueOrDefaultUnchecked(key, defaultValue);
-    }
-
-    public long getValueOrDefault(String key, long defaultValue) {
-        return this.<Long>getValueOrDefaultUnchecked(key, defaultValue);
-    }
-
-    public boolean getValueOrDefault(String key, boolean defaultValue) {
-        return this.<Boolean>getValueOrDefaultUnchecked(key, defaultValue);
-    }
-
-    public double getValueOrDefault(String key, double defaultValue) {
-        return this.<Double>getValueOrDefaultUnchecked(key, defaultValue);
-    }
-
-    /**
-     * Returns the value if it exists, or {@code defaultValue} otherwise.
-     *
-     * @throws ClassCastException if the value can't be cast to {@code T}.
-     */
-    private <T> T getValueOrDefaultUnchecked(String key, T defaultValue) {
-        if (mValues.containsKey(key)) {
-            // The caller assumes the responsibility of ensuring this cast succeeds
-            @SuppressWarnings("unchecked")
-            T castedValue = (T) mValues.get(key);
-            return castedValue;
-        } else {
-            return defaultValue;
-        }
-    }
-
-    /** Returns true if a value exists for the {@code key}. */
-    public boolean hasValue(String key) {
-        return mValues.containsKey(key);
-    }
-
-    /** Returns a {@link Builder} for this {@link Configuration}. */
-    public Builder toBuilder() {
-        return new Builder(mValues);
-    }
-
-    /** Returns a default {@link Configuration}. */
-    public static Configuration getDefaultInstance() {
-        return new Builder().build();
-    }
-
-    /** Builder class used to create {@link Configuration} objects. */
-    public static final class Builder {
-        private final HashMap<String, Object> mValues;
-
-        private Builder(HashMap<String, Object> values) {
-            this.mValues = new HashMap<>(values);
-        }
-
-        public Builder() {
-            this(new HashMap<>());
-        }
-
-        public Builder put(@ConfigKey String key, String value) {
-            mValues.put(key, value);
-            return this;
-        }
-
-        public Builder put(@ConfigKey String key, long value) {
-            mValues.put(key, value);
-            return this;
-        }
-
-        public Builder put(@ConfigKey String key, boolean value) {
-            mValues.put(key, value);
-            return this;
-        }
-
-        public Builder put(@ConfigKey String key, double value) {
-            mValues.put(key, value);
-            return this;
-        }
-
-        public Configuration build() {
-            return new Configuration(mValues);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/config/DebugBehavior.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/config/DebugBehavior.java
deleted file mode 100644
index d0a24b2..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/config/DebugBehavior.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.config;
-
-/**
- * Provides configuration details about the build, such as how much debug logging should occur.
- *
- * <p>Member booleans should control _behavior_ (turning debug features on or off), rather than
- * reporting a build state (like dev or release).
- */
-// TODO: This can't be final because we mock it
-public class DebugBehavior {
-    /** Convenience constant for configuration that enables all debug behavior. */
-    public static final DebugBehavior VERBOSE = new DebugBehavior(true);
-
-    /** Convenience constant for configuration that disables all debug behavior. */
-    public static final DebugBehavior SILENT = new DebugBehavior(false);
-
-    private final boolean mShowDebugViews;
-
-    private DebugBehavior(boolean showDebugViews) {
-        this.mShowDebugViews = showDebugViews;
-    }
-
-    public boolean getShowDebugViews() {
-        return mShowDebugViews;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/imageloader/BundledAssets.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/imageloader/BundledAssets.java
deleted file mode 100644
index 90f2a86..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/imageloader/BundledAssets.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.imageloader;
-
-import androidx.annotation.StringDef;
-
-/** Enumerates the set of bundled assets which could be requested via the {@link ImageLoaderApi}. */
-@StringDef({BundledAssets.OFFLINE_INDICATOR_BADGE, BundledAssets.OFFLINE_INDICATOR_BADGE_DARK_BG,
-        BundledAssets.VIDEO_INDICATOR_BADGE, BundledAssets.VIDEO_INDICATOR_BADGE_DARK_BG,
-        BundledAssets.MENU_ICON, BundledAssets.MENU_ICON_DARK_BG, BundledAssets.AMP_ICON,
-        BundledAssets.AMP_ICON_DARK_BG, BundledAssets.SPARK_ICON, BundledAssets.SPARK_ICON_DARK_BG})
-public @interface BundledAssets {
-    /** Icon that indicates amp content */
-    String AMP_ICON = "amp_icon";
-
-    /** Dark Theme Background Icon that indicates amp content */
-    String AMP_ICON_DARK_BG = "amp_icon_dark";
-
-    /** Icon that indicates a click will take the user to a menu. */
-    String MENU_ICON = "menu_icon";
-
-    /** Dark Theme Background Icon that indicates a click will take the user to a menu. */
-    String MENU_ICON_DARK_BG = "menu_icon_dark";
-
-    /** Badge to show indicating content is available offline. */
-    String OFFLINE_INDICATOR_BADGE = "offline_indicator_badge";
-
-    /** Dark Theme Background Badge to show indicating content is available offline. */
-    String OFFLINE_INDICATOR_BADGE_DARK_BG = "offline_indicator_badge_dark";
-
-    /** Branding interest spark icon. */
-    String SPARK_ICON = "spark_icon";
-
-    /** Dark Theme Background Branding interest spark icon. */
-    String SPARK_ICON_DARK_BG = "spark_icon_dark";
-
-    /** Badge to show indicating content links to a video. */
-    String VIDEO_INDICATOR_BADGE = "video_indicator_badge";
-
-    /** Dark Theme Background Badge to show indicating content links to a video. */
-    String VIDEO_INDICATOR_BADGE_DARK_BG = "video_indicator_badge_dark";
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/imageloader/ImageLoaderApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/imageloader/ImageLoaderApi.java
deleted file mode 100644
index 1aadf38..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/imageloader/ImageLoaderApi.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.imageloader;
-
-import android.graphics.drawable.Drawable;
-
-import org.chromium.base.Consumer;
-
-import java.util.List;
-
-/** Feed Host API to load images. */
-public interface ImageLoaderApi {
-    /** Constant used to notify host that an image's height or width is not known. */
-    int DIMENSION_UNKNOWN = -1;
-
-    /**
-     * Asks host to load an image from the web, a bundled asset, or some other type of drawable like
-     * a monogram if supported.
-     *
-     * <p>The width and the height of the image can be provided preemptively, however it is not
-     * guaranteed that both dimensions will be known. In the case that only one dimension is known,
-     * the host should be careful to preserve the aspect ratio.
-     *
-     * <p>Feed will not cache any images, so if caching is desired, it should be done on the host
-     * side.
-     *
-     * @param urls A list of urls, tried in order until a load succeeds. Urls may be bundled. The
-     *         list
-     *     of bundled assets will be defined via the {@link BundledAssets} StringDef.
-     * @param widthPx The width of the image in pixels. Will be {@link #DIMENSION_UNKNOWN} if
-     *         unknown.
-     * @param heightPx The height of the image in pixels. Will be {@link #DIMENSION_UNKNOWN} if
-     *     unknown.
-     * @param consumer Callback to return the Drawable to if one of the urls provided is successful.
-     *     {@literal null} if no Drawable is found (or could not be loaded) after trying all
-     * possible urls.
-     */
-    void loadDrawable(List<String> urls, int widthPx, int heightPx, Consumer<Drawable> consumer);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ActionType.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ActionType.java
deleted file mode 100644
index 254b45f0..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ActionType.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.logging;
-
-import androidx.annotation.IntDef;
-
-/**
- * IntDef representing the different types of actions.
- *
- * <p>When adding new values, the value of {@link ActionType#NEXT_VALUE} should be used and
- * incremented. When removing values, {@link ActionType#NEXT_VALUE} should not be changed, and those
- * values should not be reused.
- */
-@IntDef({ActionType.UNKNOWN, ActionType.OPEN_URL, ActionType.OPEN_URL_INCOGNITO,
-        ActionType.OPEN_URL_NEW_TAB, ActionType.OPEN_URL_NEW_WINDOW, ActionType.DOWNLOAD,
-        ActionType.LEARN_MORE, ActionType.MANAGE_INTERESTS, ActionType.BLOCK_CONTENT,
-        ActionType.NEXT_VALUE})
-// LINT.IfChange
-public @interface ActionType {
-    int UNKNOWN = -1;
-    int OPEN_URL = 1;
-    int OPEN_URL_INCOGNITO = 2;
-    int OPEN_URL_NEW_TAB = 4;
-    int OPEN_URL_NEW_WINDOW = 3;
-    int DOWNLOAD = 5;
-    int LEARN_MORE = 6;
-    int MANAGE_INTERESTS = 7;
-    int BLOCK_CONTENT = 8;
-    int NEXT_VALUE = 9;
-}
-// LINT.ThenChange
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/BasicLoggingApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/BasicLoggingApi.java
deleted file mode 100644
index 0475ca72..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/BasicLoggingApi.java
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.logging;
-
-import java.util.List;
-
-/** The BasicLoggingApi is used by the Feed to log actions performed on the Feed. */
-public interface BasicLoggingApi {
-    /**
-     * Called when a section of content (generally a card) comes into view. Will not get called by
-     * Stream if content has already been logged. If the stream is recreated this will get logged
-     * again.
-     *
-     * <p>Content viewed will get logged as soon as content is 2/3 (will be configurable in {@link
-     * org.chromium.chrome.browser.feed.library.api.host.config.Configuration.
-     *    ConfigKey#VIEW_LOG_THRESHOLD})
-     * visible in view-port. This means logging will not be tied to scroll state events (scroll
-     * start/stop) but rather raw scrolling events.
-     */
-    void onContentViewed(ContentLoggingData data);
-
-    /**
-     * Called when content has been dismissed by a user. This could be done via a swipe or through
-     * the context menu.
-     *
-     * @param data data for content on which swipe was performed.
-     * @param wasCommitted true if the action was committed and thus important to the user model
-     *         false
-     *     if the action was undone.
-     */
-    void onContentDismissed(ContentLoggingData data, boolean wasCommitted);
-
-    /**
-     * Called when content has been swiped by a user.
-     *
-     * @param data data for content on which swipe was performed.
-     */
-    void onContentSwiped(ContentLoggingData data);
-
-    /** Called when content is clicked/tapped. */
-    void onContentClicked(ContentLoggingData data);
-
-    /**
-     * Called when a client action has been performed on a piece of content.
-     *
-     * @param data data for content on which action was performed.
-     * @param actionType describes the type of action which is being performed by user.
-     */
-    void onClientAction(ContentLoggingData data, @ActionType int actionType);
-
-    /** Called when the context menu for content has been opened. */
-    void onContentContextMenuOpened(ContentLoggingData data);
-
-    /**
-     * Called when the more button appears at the bottom of the screen. This is a view on the more
-     * button which is created from continuation features (paging). A view from the more button due
-     * to having zero cards will not trigger this event.
-     *
-     * @param position index of the more button in the Stream.
-     */
-    void onMoreButtonViewed(int position);
-
-    /**
-     * Called when the more button appears at the bottom of the screen and is clicked. This is a
-     * click on the more button which is created from continuation features (paging). A click from
-     * the more button due to having zero cards will not trigger this event.
-     *
-     * @param position index of the more button in the Stream.
-     */
-    void onMoreButtonClicked(int position);
-
-    /**
-     * Called when the user has indicated they aren't interested in the story's topic.
-     *
-     * @param interestType type of content a user is not interested in
-     * @param data data for content on which swipe was performed.
-     * @param wasCommitted true if the action was committed and thus important to the user model
-     *         false
-     *     if the action was undone.
-     */
-    void onNotInterestedIn(int interestType, ContentLoggingData data, boolean wasCommitted);
-
-    /**
-     * Called when Stream is shown and content was shown to the user. Content could have been cached
-     * or a network fetch may have been needed.
-     *
-     * @param timeToPopulateMs time in milliseconds, since {@link
-     *     org.chromium.chrome.browser.feed.library.api.client.stream.Stream#onShow()}, it took to
-     * show content to the user. This does not include time to render but time to populate data in
-     * the UI.
-     * @param contentCount Count of content shown to user. This will generally be the number of
-     *         cards.
-     */
-    void onOpenedWithContent(int timeToPopulateMs, int contentCount);
-
-    /**
-     * Called when Stream was shown and no content was immediately available to be shown. Content
-     * may have been shown after a network fetch.
-     */
-    void onOpenedWithNoImmediateContent();
-
-    /**
-     * Called when Stream was shown and no content could be shown to the user at all. This means
-     * that there was no cached content and a network request to fetch new content was not allowed,
-     * could not complete, or failed.
-     */
-    void onOpenedWithNoContent();
-
-    /**
-     * Called when a loading spinner starts showing.
-     *
-     * @param spinnerType type of spinner that is shown.
-     */
-    void onSpinnerStarted(@SpinnerType int spinnerType);
-
-    /**
-     * Called when a loading spinner finishes showing.
-     *
-     * @param timeShownMs time in milliseconds that the spinner was shown before completing.
-     * @param spinnerType type of spinner that was shown.
-     */
-    void onSpinnerFinished(int timeShownMs, @SpinnerType int spinnerType);
-
-    /**
-     * Called when a spinner is destroyed without completing.
-     *
-     * @param timeShownMs time in milliseconds that the spinner was shown before being destroyed.
-     * @param spinnerType type of spinner that was shown.
-     */
-    void onSpinnerDestroyedWithoutCompleting(int timeShownMs, @SpinnerType int spinnerType);
-
-    /**
-     * Called when Piet wants to report events that occurred during Frame rendering.
-     *
-     * @param pietErrorCodes int versions of values from Piet {@link
-     *     org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode} enum
-     */
-    void onPietFrameRenderingEvent(List<Integer> pietErrorCodes);
-
-    /**
-     * Called when a user has clicked on an element. This is similar to onContentClicked, but
-     * records the specific elementType that was clicked.
-     *
-     * @param data data for content on which action was performed.
-     * @param elementType describes the server-defined type of element which was clicked.
-     *         Corresponds
-     *     to the int numbers of the server-defined {@link
-     *     org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.
-     *       ElementType}
-     * value.
-     */
-    void onVisualElementClicked(ElementLoggingData data, int elementType);
-
-    /**
-     * Called when a user has viewed an element. This is similar to onContentViewed, but records the
-     * view after it has been on the screen for a given amount of time instead of on predraw.
-     *
-     * @param data data for content on which action was performed.
-     * @param elementType describes the type of element which was clicked.
-     */
-    void onVisualElementViewed(ElementLoggingData data, int elementType);
-
-    /**
-     * Reports an internal error. This error should be logged by hosts, but not handled. In
-     * particular, the host should not crash if this method is called.
-     */
-    void onInternalError(@InternalFeedError int internalError);
-
-    /**
-     * Called when a token successfully completes.
-     *
-     * @param wasSynthetic whether the token was synthetic.
-     * @param contentCount how many top level features were in the response, typically clusters.
-     * @param tokenCount how many tokens were in the response.
-     */
-    void onTokenCompleted(boolean wasSynthetic, int contentCount, int tokenCount);
-
-    /**
-     * Called when a token fails to complete.
-     *
-     * @param wasSynthetic whether the token was synthetic.
-     * @param failureCount How many times the token has failed to complete, including this failure.
-     */
-    void onTokenFailedToComplete(boolean wasSynthetic, int failureCount);
-
-    /**
-     * Called when a request is made.
-     *
-     * @param requestReason the reason the request was made.
-     */
-    void onServerRequest(@RequestReason int requestReason);
-
-    /**
-     * Logged when the zero state is shown. Shown in this context specifically means created, but
-     * doesn't necessarily indicate that the user saw the zero state.
-     *
-     * @param zeroStateShowReason the reason the zero state was shown.
-     */
-    void onZeroStateShown(@ZeroStateShowReason int zeroStateShowReason);
-
-    /**
-     * Called when a refresh from a zero state is completed.
-     *
-     * @param newContentCount Number of content created. Note: content here refers to content from
-     *         the
-     *     server. If the zero state refresh completes to show another zero state, this value would
-     * be zero.
-     * @param newTokenCount Number of tokens created.
-     */
-    void onZeroStateRefreshCompleted(int newContentCount, int newTokenCount);
-
-    /**
-     * Called with the first event that occurs after the UI registers for a new session. If, for
-     * example, multiple errors occurred repeatedly due to a user pressing a refresh button on the
-     * zero-state UI, those would not be reported by this, as the UI would have only registered for
-     * a new session before the first error.
-     *
-     * @param sessionEvent the event that first occurred after the UI registered for a session.
-     * @param timeFromRegisteringMs how long it took, in milliseconds, for the event to occur after
-     *     the UI registered for a session.
-     * @param sessionCount the number of sessions that have been requested by the UI. This would
-     *         never
-     *     be reset until the UI is destroyed, and would start at {@literal 1}.
-     */
-    void onInitialSessionEvent(
-            @SessionEvent int sessionEvent, int timeFromRegisteringMs, int sessionCount);
-
-    /**
-     * Called when a client scrolls in the feed
-     *
-     * @param scrollType describes the type of scroll which is being performed by user.
-     * @param distanceScrolled distance in px the user scrolled for this particular scroll.
-     */
-    void onScroll(@ScrollType int scrollType, int distanceScrolled);
-
-    /**
-     * Called when a task finishes executing.
-     *
-     * @param task the task that is being run.
-     * @param delayTime how long it took from enqueuing the task to when it was run.
-     * @param taskTime how long it took from the task starting to when it finished executing.
-     */
-    void onTaskFinished(@Task int task, int delayTime, int taskTime);
-
-    /**
-     * For activity monitoring, report that the user scrolled.
-     *
-     * @param scrollAmount Distance scrolled in pixels
-     */
-    public void reportScrollActivity(int scrollAmount);
-
-    /** For activity monitoring, report that the user opened a page. */
-    public void reportFeedInteraction();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ContentLoggingData.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ContentLoggingData.java
deleted file mode 100644
index 4f2881ec..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ContentLoggingData.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.logging;
-
-/** Object used to hold content data for logging events. */
-public interface ContentLoggingData extends ElementLoggingData {
-    /** Gets the time, in seconds from epoch, for when the content was published/made available. */
-    long getPublishedTimeSeconds();
-
-    /** Gets the score which was given to content from NowStream. */
-    float getScore();
-
-    /**
-     * Gets offline availability status.
-     *
-     * <p>Note: The offline availability status for one piece of content can change. When this is
-     * logged, it should be logged with the offline status as of logging time. This means that one
-     * piece of content can emit multiple {@link ContentLoggingData} instances which are not equal
-     * to each other.
-     */
-    boolean isAvailableOffline();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ElementLoggingData.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ElementLoggingData.java
deleted file mode 100644
index efa6baf3..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ElementLoggingData.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.logging;
-
-/** Object used to hold content data for logging events. */
-public interface ElementLoggingData {
-    /**
-     * Returns the position of the content in the stream not accounting for header views. The top
-     * being 0. Position does not change after initial layout. Specifically the position does not
-     * update if dismisses/removes are performed.
-     */
-    int getPositionInStream();
-
-    /**
-     * Gets the time, in seconds from epoch, for when this content was made available on the device.
-     * This could be the time for when this content was retrieved from the server or the time the
-     * data was pushed to the device.
-     */
-    long getTimeContentBecameAvailable();
-
-    /**
-     * Gets the URI which represents this content. This will normally be the URI which this content
-     * links to.
-     */
-    String getRepresentationUri();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/InternalFeedError.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/InternalFeedError.java
deleted file mode 100644
index c2aed6d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/InternalFeedError.java
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.logging;
-
-import androidx.annotation.IntDef;
-
-/**
- * Represents internal errors of the Feed libraries.
- *
- * <p>When adding new values, the value of {@link InternalFeedError#NEXT_VALUE} should be used and
- * incremented. When removing values, {@link InternalFeedError#NEXT_VALUE} should not be changed,
- * and those values should not be reused.
- */
-@IntDef({InternalFeedError.SWITCH_TO_EPHEMERAL, InternalFeedError.NO_URL_FOR_OPEN,
-        InternalFeedError.FAILED_TO_RESTORE, InternalFeedError.NO_ROOT_FEATURE,
-        InternalFeedError.TOP_LEVEL_UNBOUND_CHILD, InternalFeedError.TOP_LEVEL_INVALID_FEATURE_TYPE,
-        InternalFeedError.CLUSTER_CHILD_MISSING_FEATURE, InternalFeedError.CLUSTER_CHILD_NOT_CARD,
-        InternalFeedError.CARD_CHILD_MISSING_FEATURE, InternalFeedError.NULL_SHARED_STATES,
-        InternalFeedError.FAILED_TO_CREATE_LEAF, InternalFeedError.UNHANDLED_TOKEN,
-        InternalFeedError.TASK_QUEUE_STARVATION, InternalFeedError.CONTENT_STORAGE_MISSING_ITEM,
-        InternalFeedError.ITEM_NOT_PARSED, InternalFeedError.STORAGE_MISS_BEYOND_THRESHOLD,
-        InternalFeedError.CONTENT_MUTATION_FAILED, InternalFeedError.ROOT_NOT_BOUND_TO_FEATURE,
-        InternalFeedError.NEXT_VALUE})
-public @interface InternalFeedError {
-    /** Represents when memory fails so the Feed libraries switch to ephemeral mode. */
-    int SWITCH_TO_EPHEMERAL = 0;
-
-    /** Represents when opening a URL fails as there is no URL available. */
-    int NO_URL_FOR_OPEN = 1;
-
-    /** Represents a failure to restore. */
-    int FAILED_TO_RESTORE = 2;
-
-    /** Represents getting a session with no root feature. */
-    int NO_ROOT_FEATURE = 3;
-
-    /** Represents a top level child being unbound when initializing. */
-    int TOP_LEVEL_UNBOUND_CHILD = 4;
-
-    /** Represents a top level feature being neither a card nor a cluster. */
-    int TOP_LEVEL_INVALID_FEATURE_TYPE = 5;
-
-    /** Represents a child of a cluster not having a feature. */
-    int CLUSTER_CHILD_MISSING_FEATURE = 6;
-
-    /** Represents a child of a cluster not being a card. */
-    int CLUSTER_CHILD_NOT_CARD = 7;
-
-    /** Represents a child of a card not having a feature. */
-    int CARD_CHILD_MISSING_FEATURE = 8;
-
-    /** Represents a failure to load shared states for Piet content. */
-    int NULL_SHARED_STATES = 9;
-
-    /** Represents a failure to create a leaf child. */
-    int FAILED_TO_CREATE_LEAF = 10;
-
-    /** Represents a token that could not be handled. */
-    int UNHANDLED_TOKEN = 11;
-
-    /**
-     * Represents that the task queue timed out waiting for a network request and began executing
-     * queued tasks.
-     */
-    int TASK_QUEUE_STARVATION = 12;
-
-    /** Represents a call to ContentStorage that returned with a missing item. */
-    int CONTENT_STORAGE_MISSING_ITEM = 13;
-
-    /** Represents bytes from ContentStorage that cannot be parsed into the proto. */
-    int ITEM_NOT_PARSED = 14;
-
-    /**
-     * Represents a storage miss where FeedStore reports success but is missing a number of items
-     * that exceeds the configurable threshold.
-     */
-    int STORAGE_MISS_BEYOND_THRESHOLD = 15;
-
-    /** Represents a failed content mutation in FeedSessionManager. */
-    int CONTENT_MUTATION_FAILED = 16;
-
-    /** Represents a root feature that is not bound as expected. */
-    int ROOT_NOT_BOUND_TO_FEATURE = 17;
-
-    /** The next value that should be used when adding additional values to the IntDef. */
-    int NEXT_VALUE = 18;
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/LoggingApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/LoggingApi.java
deleted file mode 100644
index 26a66ef..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/LoggingApi.java
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.logging;
-
-/** A placeholder API to write log messages. */
-public interface LoggingApi {}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/RequestReason.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/RequestReason.java
deleted file mode 100644
index e45df5aa..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/RequestReason.java
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.logging;
-
-import androidx.annotation.IntDef;
-
-/**
- * The reason a request is being made.
- *
- * <p>When adding new values, the value of {@link RequestReason#NEXT_VALUE} should be used and
- * incremented. When removing values, {@link RequestReason#NEXT_VALUE} should not be changed, and
- * those values should not be reused.
- */
-@IntDef({
-        RequestReason.UNKNOWN,
-        RequestReason.ZERO_STATE,
-        RequestReason.HOST_REQUESTED,
-        RequestReason.OPEN_WITH_CONTENT,
-        RequestReason.MANUAL_CONTINUATION,
-        RequestReason.AUTOMATIC_CONTINUATION,
-        RequestReason.OPEN_WITHOUT_CONTENT,
-        RequestReason.CLEAR_ALL,
-        RequestReason.NEXT_VALUE,
-})
-public @interface RequestReason {
-    // An unknown refresh reason.
-    int UNKNOWN = 0;
-
-    // Refresh triggered because the user manually hit the refresh button from the
-    // zero-state.
-    int ZERO_STATE = 1;
-
-    // Refresh triggered because the host requested a refresh.
-    int HOST_REQUESTED = 2;
-
-    // Refresh triggered because there was stale content. The stale content was
-    // shown while a background refresh would occur, which would be appended below
-    // content the user had seen.
-    int OPEN_WITH_CONTENT = 3;
-
-    // Refresh triggered because the user tapped on a 'More' button.
-    int MANUAL_CONTINUATION = 4;
-
-    // Refresh triggered via automatically consuming a continuation token, without
-    // showing the user a 'More' button.
-    int AUTOMATIC_CONTINUATION = 5;
-
-    // Refresh made when the Stream starts up and no content is showing.
-    int OPEN_WITHOUT_CONTENT = 6;
-
-    // Refresh made because the host requested a clear all.
-    int CLEAR_ALL = 7;
-
-    // The next value that should be used when adding additional values to the IntDef.
-    int NEXT_VALUE = 8;
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ScrollType.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ScrollType.java
deleted file mode 100644
index bf57315..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ScrollType.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.logging;
-
-import androidx.annotation.IntDef;
-
-/** IntDef representing the different types of scrolls. */
-@IntDef({ScrollType.UNKNOWN, ScrollType.STREAM_SCROLL, ScrollType.NEXT_VALUE})
-public @interface ScrollType {
-    // Type of scroll that occurs
-    int UNKNOWN = 0;
-    // Scroll the stream of cards
-    int STREAM_SCROLL = 1;
-    int NEXT_VALUE = 2;
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/SessionEvent.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/SessionEvent.java
deleted file mode 100644
index 43d962e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/SessionEvent.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.logging;
-
-import androidx.annotation.IntDef;
-
-/**
- * IntDef representing the different results of requesting sessions.
- *
- * <p>When adding new values, the value of {@link SessionEvent#NEXT_VALUE} should be used and
- * incremented. When removing values, {@link SessionEvent#NEXT_VALUE} should not be changed, and
- * those values should not be reused.
- */
-@IntDef({
-        SessionEvent.STARTED,
-        SessionEvent.FINISHED_IMMEDIATELY,
-        SessionEvent.ERROR,
-        SessionEvent.USER_ABANDONED,
-        SessionEvent.NEXT_VALUE,
-})
-public @interface SessionEvent {
-    // Indicates that a session was successfully started when requested.
-    int STARTED = 0;
-
-    // Indicates that a session was immediately finished when requested.
-    int FINISHED_IMMEDIATELY = 1;
-
-    // Indicates that a session failed when requested.
-    int ERROR = 2;
-
-    // Indicates the session requested was abandoned by the user taking action.
-    // Note: some of these events will be dropped, as they will be reported in
-    // onDestroy(), which may not be called in all instances.
-    int USER_ABANDONED = 3;
-
-    // The next value that should be used when adding additional values to the IntDef.
-    int NEXT_VALUE = 4;
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/SpinnerType.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/SpinnerType.java
deleted file mode 100644
index 4b72c46..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/SpinnerType.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.logging;
-
-import androidx.annotation.IntDef;
-
-/**
- * IntDef representing the different types of spinners.
- *
- * <p>When adding new values, the value of {@link SpinnerType#NEXT_VALUE} should be used and
- * incremented. When removing values, {@link SpinnerType#NEXT_VALUE} should not be changed, and
- * those values should not be reused.
- */
-@IntDef({
-        SpinnerType.INITIAL_LOAD,
-        SpinnerType.ZERO_STATE_REFRESH,
-        SpinnerType.MORE_BUTTON,
-        SpinnerType.SYNTHETIC_TOKEN,
-        SpinnerType.INFINITE_FEED,
-        SpinnerType.NEXT_VALUE,
-})
-public @interface SpinnerType {
-    // Spinner shown on initial load of the Feed.
-    int INITIAL_LOAD = 1;
-    // Spinner shown when Feed is refreshed.
-    int ZERO_STATE_REFRESH = 2;
-    // Spinner shown when more button is clicked.
-    int MORE_BUTTON = 3;
-    // Spinner shown when a synthetic token is consumed.
-    int SYNTHETIC_TOKEN = 4;
-    // Spinner shown when a spinner is shown for loading the infinite feed.
-    int INFINITE_FEED = 5;
-    // The next value that should be used when adding additional values to the IntDef.
-    int NEXT_VALUE = 6;
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/Task.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/Task.java
deleted file mode 100644
index 73e63c78..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/Task.java
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.logging;
-
-import androidx.annotation.IntDef;
-
-/**
- * IntDef representing the different tasks that can be queued on the {@link
- * org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue}.
- *
- * <p>When adding new values, the value of {@link Task#NEXT_VALUE} should be used and incremented.
- * When removing values, {@link Task#NEXT_VALUE} should not be changed, and those values should not
- * be reused.
- */
-@IntDef({
-        Task.UNKNOWN,
-        Task.CLEAN_UP_SESSION_JOURNALS,
-        Task.CLEAR_ALL,
-        Task.CLEAR_ALL_WITH_REFRESH,
-        Task.CLEAR_PERSISTENT_STORE_TASK,
-        Task.COMMIT_TASK,
-        Task.CREATE_AND_STORE,
-        Task.CREATE_AND_UPLOAD,
-        Task.DETACH_SESSION,
-        Task.DISMISS_LOCAL,
-        Task.DUMP_EPHEMERAL_ACTIONS,
-        Task.EXECUTE_UPLOAD_ACTION_REQUEST,
-        Task.GARBAGE_COLLECT_CONTENT,
-        Task.GET_EXISTING_SESSION,
-        Task.GET_NEW_SESSION,
-        Task.GET_STREAM_FEATURES_FROM_HEAD,
-        Task.HANDLE_RESPONSE_BYTES,
-        Task.HANDLE_SYNTHETIC_TOKEN,
-        Task.HANDLE_TOKEN,
-        Task.HANDLE_UPLOADABLE_ACTION_RESPONSE_BYTES,
-        Task.INVALIDATE_HEAD,
-        Task.INVALIDATE_SESSION,
-        Task.LOCAL_ACTION_GC,
-        Task.NO_CARD_ERROR_CLEAR,
-        Task.PERSIST_MUTATION,
-        Task.POPULATE_NEW_SESSION,
-        Task.REQUEST_FAILURE,
-        Task.REQUEST_MANAGER_TRIGGER_REFRESH,
-        Task.SEND_REQUEST,
-        Task.SESSION_MANAGER_TRIGGER_REFRESH,
-        Task.SESSION_MUTATION,
-        Task.STORE_VIEW_ACTIONS,
-        Task.TASK_QUEUE_INITIALIZE,
-        Task.UPLOAD_ALL_ACTIONS,
-        Task.UPLOAD_ALL_ACTIONS_FOR_URL,
-        Task.NEXT_VALUE,
-})
-public @interface Task {
-    // Unknown task.
-    int UNKNOWN = 0;
-
-    int CLEAN_UP_SESSION_JOURNALS = 1;
-    int CLEAR_ALL = 2;
-    int CLEAR_ALL_WITH_REFRESH = 3;
-    int CLEAR_PERSISTENT_STORE_TASK = 4;
-    int COMMIT_TASK = 5;
-    int CREATE_AND_UPLOAD = 6;
-    int DETACH_SESSION = 7;
-    int DISMISS_LOCAL = 8;
-    int DUMP_EPHEMERAL_ACTIONS = 9;
-    int EXECUTE_UPLOAD_ACTION_REQUEST = 10;
-    int GARBAGE_COLLECT_CONTENT = 11;
-    int GET_EXISTING_SESSION = 12;
-    int GET_NEW_SESSION = 13;
-    int GET_STREAM_FEATURES_FROM_HEAD = 14;
-    int HANDLE_RESPONSE_BYTES = 15;
-    int HANDLE_SYNTHETIC_TOKEN = 16;
-    int HANDLE_TOKEN = 17;
-    int HANDLE_UPLOADABLE_ACTION_RESPONSE_BYTES = 18;
-    int INVALIDATE_HEAD = 19;
-    int INVALIDATE_SESSION = 20;
-    int LOCAL_ACTION_GC = 21;
-    int NO_CARD_ERROR_CLEAR = 22;
-    int PERSIST_MUTATION = 23;
-    int POPULATE_NEW_SESSION = 24;
-    int REQUEST_FAILURE = 25;
-    int REQUEST_MANAGER_TRIGGER_REFRESH = 26;
-    int SEND_REQUEST = 27;
-    int SESSION_MANAGER_TRIGGER_REFRESH = 28;
-    int SESSION_MUTATION = 29;
-    int TASK_QUEUE_INITIALIZE = 30;
-    int UPLOAD_ALL_ACTIONS_FOR_URL = 32;
-    int CREATE_AND_STORE = 33;
-    int STORE_VIEW_ACTIONS = 34;
-    int UPLOAD_ALL_ACTIONS = 35;
-
-    // The next value that should be used when adding additional values to the IntDef.
-    int NEXT_VALUE = 36;
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ZeroStateShowReason.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ZeroStateShowReason.java
deleted file mode 100644
index 2e789dc..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ZeroStateShowReason.java
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.logging;
-
-import androidx.annotation.IntDef;
-
-/**
- * The reason a zero state is shown.
- *
- * <p>When adding new values, the value of {@link ZeroStateShowReason#NEXT_VALUE} should be used and
- * incremented. When removing values, {@link ZeroStateShowReason#NEXT_VALUE} should not be changed,
- * and those values should not be reused.
- */
-@IntDef({
-        ZeroStateShowReason.ERROR,
-        ZeroStateShowReason.NO_CONTENT,
-        ZeroStateShowReason.CONTENT_DISMISSED,
-        ZeroStateShowReason.NO_CONTENT_FROM_CONTINUATION_TOKEN,
-        ZeroStateShowReason.NEXT_VALUE,
-})
-public @interface ZeroStateShowReason {
-    // Indicates the zero state was shown due to an error. This would most commonly happen if a
-    // request fails.
-    int ERROR = 0;
-
-    // Indicates the zero state was shown because no content is available. This can happen if the
-    // host does not schedule a refresh when the app is opened.
-    int NO_CONTENT = 1;
-
-    // Indicates the zero state was shown because all content, including any tokens, were dismissed.
-    int CONTENT_DISMISSED = 2;
-
-    // Indicates that the only content showing was a continuation token, and that token completed
-    // with no additional content, resulting in no content showing. This shouldn't occur, as a token
-    // should at least return another token.
-    int NO_CONTENT_FROM_CONTINUATION_TOKEN = 3;
-
-    // The next value that should be used when adding additional values to the IntDef.
-    int NEXT_VALUE = 4;
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/HttpHeader.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/HttpHeader.java
deleted file mode 100644
index 2260881b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/HttpHeader.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.network;
-
-import androidx.annotation.StringDef;
-
-public final class HttpHeader {
-    /** These string values correspond with the actual header name. */
-    @StringDef({
-            HttpHeaderName.X_PROTOBUFFER_REQUEST_PAYLOAD,
-    })
-    public @interface HttpHeaderName {
-        String X_PROTOBUFFER_REQUEST_PAYLOAD = "X-Protobuffer-Request-Payload";
-    }
-
-    public HttpHeader(@HttpHeaderName String name, String value) {
-        this.name = name;
-        this.value = value;
-    }
-
-    public final @HttpHeaderName String name;
-    public final String value;
-
-    public @HttpHeaderName String getName() {
-        return name;
-    }
-
-    public String getValue() {
-        return value;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/HttpRequest.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/HttpRequest.java
deleted file mode 100644
index b710682..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/HttpRequest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.network;
-
-import android.net.Uri;
-
-import androidx.annotation.StringDef;
-
-import java.net.HttpURLConnection;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/** Representation of an HTTP request. */
-public final class HttpRequest {
-    /**
-     * These string values line up with HTTP method values, see {@link
-     * HttpURLConnection#setRequestMethod(String)}.
-     */
-    @StringDef({
-            HttpMethod.GET,
-            HttpMethod.POST,
-            HttpMethod.PUT,
-            HttpMethod.DELETE,
-    })
-    public @interface HttpMethod {
-        String GET = "GET";
-        String POST = "POST";
-        String PUT = "PUT";
-        String DELETE = "DELETE";
-    }
-
-    private final Uri mUri;
-    private final byte[] mBody;
-    private final @HttpMethod String mMethod;
-    private final List<HttpHeader> mHeaders;
-
-    public HttpRequest(Uri uri, @HttpMethod String method, List<HttpHeader> headers, byte[] body) {
-        this.mUri = uri;
-        this.mBody = body;
-        this.mMethod = method;
-        this.mHeaders = Collections.unmodifiableList(new ArrayList<>(headers));
-    }
-
-    public Uri getUri() {
-        return mUri;
-    }
-
-    public byte[] getBody() {
-        return mBody;
-    }
-
-    public @HttpMethod String getMethod() {
-        return mMethod;
-    }
-
-    public List<HttpHeader> getHeaders() {
-        return mHeaders;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/HttpResponse.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/HttpResponse.java
deleted file mode 100644
index ad748299..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/HttpResponse.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.network;
-
-/** Representation of an HTTP response. */
-public final class HttpResponse {
-    private final int mResponseCode;
-    private final byte[] mResponseBody;
-    private final boolean mIsSignedIn;
-
-    public HttpResponse(int responseCode, byte[] responseBody, boolean isSignedIn) {
-        this.mResponseCode = responseCode;
-        this.mResponseBody = responseBody;
-        this.mIsSignedIn = isSignedIn;
-    }
-
-    /**
-     * Gets the response code for the response.
-     *
-     * <p>Note: this does not have to correspond to an HTTP response code, e.g. if there is a
-     * network issue and no request was able to be sent.
-     */
-    public int getResponseCode() {
-        return mResponseCode;
-    }
-
-    /** Gets the body for the response. */
-    public byte[] getResponseBody() {
-        return mResponseBody;
-    }
-
-    public boolean isSignedIn() {
-        return mIsSignedIn;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/NetworkClient.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/NetworkClient.java
deleted file mode 100644
index 371d7953..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/NetworkClient.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.network;
-
-import org.chromium.base.Consumer;
-
-/**
- * An object that can send an {@link HttpRequest} and receive an {@link HttpResponse} in response.
- */
-public interface NetworkClient extends AutoCloseable {
-    /**
-     * Sends the HttpRequest. Upon completion, asynchronously calls the consumer with the
-     * HttpResponse.
-     *
-     * <p>Requests and responses should be uncompressed when in the Feed. It is up to the host to
-     * gzip / ungzip any requests or responses.
-     *
-     * @param request The request to send
-     * @param responseConsumer The callback to be used when the response comes back.
-     */
-    void send(HttpRequest request, Consumer<HttpResponse> responseConsumer);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/offlineindicator/OfflineIndicatorApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/offlineindicator/OfflineIndicatorApi.java
deleted file mode 100644
index b1183c4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/offlineindicator/OfflineIndicatorApi.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.offlineindicator;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.annotations.MockedInTests;
-
-import java.util.List;
-
-/** Api to allow the Feed to get information about offline availability status of content. */
-@MockedInTests
-public interface OfflineIndicatorApi {
-    /**
-     * Requests information on the offline status of content shown in the Feed.
-     *
-     * @param urlsToRetrieve list of urls we want to know about.
-     * @param urlListConsumer subset of {@code urlsToRetrieve} which are available offline.
-     */
-    void getOfflineStatus(List<String> urlsToRetrieve, Consumer<List<String>> urlListConsumer);
-
-    /** Adds a listener for changes to the offline availability of content. */
-    void addOfflineStatusListener(OfflineStatusListener offlineStatusListener);
-
-    /** Removes listener for changes the offline availability of content. */
-    void removeOfflineStatusListener(OfflineStatusListener offlineStatusListener);
-
-    /** Listener for changes in the offline availability of content. */
-    interface OfflineStatusListener {
-        void updateOfflineStatus(String url, boolean availableOffline);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/proto/ProtoExtensionProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/proto/ProtoExtensionProvider.java
deleted file mode 100644
index 23933d58..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/proto/ProtoExtensionProvider.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.proto;
-
-import com.google.protobuf.GeneratedMessageLite.GeneratedExtension;
-
-import java.util.List;
-
-/** Allows the host application to register proto extensions in the Feed's global registry. */
-public interface ProtoExtensionProvider {
-    /**
-     * The Feed will call this method on startup. Any proto extensions that will need to be
-     * serialized by the Feed should be returned at that time.
-     *
-     * @return a list of the proto extensions the host application will use in the Feed.
-     */
-    List<GeneratedExtension<?, ?>> getProtoExtensions();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/scheduler/SchedulerApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/scheduler/SchedulerApi.java
deleted file mode 100644
index 99fd8747..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/scheduler/SchedulerApi.java
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.scheduler;
-
-import androidx.annotation.IntDef;
-
-import org.chromium.base.annotations.MockedInTests;
-
-/** Allows host to change behavior based on Feed requests and their status */
-@MockedInTests
-public interface SchedulerApi {
-    /**
-     * Define the request behavior of when a new session is created.
-     *
-     * <ul>
-     *   <li>UNKNOWN - Default invalid value, this should not be returned.
-     *   <li>REQUEST_WITH_WAIT - Make a request and then wait for it to complete before showing any
-     *       content in the Stream.
-     *   <li>REQUEST_WITH_CONTENT - Show the user the existing content and make a request. When the
-     *       response completes, append the content below any content seen by the user, removing the
-     *       old content below that level.
-     *   <li>REQUEST_WITH_TIMEOUT - Make a request and if the response takes longer than the
-     *       configured timeout, show existing content. When the response completes, the new content
-     *       will be displayed below any content the user has viewed.
-     *   <li>NO_REQUEST_WITH_WAIT - Show the current content, if an existing request is being made,
-     *       wait for it to complete.
-     *   <li>NO_REQUEST_WITH_CONTENT - Show the existing content, don't wait if a request is
-     * currently being made. <li>NO_REQUEST_WITH_TIMEOUT - Show the current content. If an existing
-     * request is being made, wait for the configured timeout for it to complete. When the response
-     * completes, the new content will be displayed below any content the user has viewed.
-     * </ul>
-     *
-     * <p>When adding new values, the value of {@link RequestBehavior#NEXT_VALUE} should be used and
-     * incremented. When removing values, {@link RequestBehavior#NEXT_VALUE} should not be changed,
-     * and those values should not be reused.
-     */
-    @IntDef({
-            RequestBehavior.UNKNOWN,
-            RequestBehavior.REQUEST_WITH_WAIT,
-            RequestBehavior.REQUEST_WITH_CONTENT,
-            RequestBehavior.REQUEST_WITH_TIMEOUT,
-            RequestBehavior.NO_REQUEST_WITH_WAIT,
-            RequestBehavior.NO_REQUEST_WITH_CONTENT,
-            RequestBehavior.NO_REQUEST_WITH_TIMEOUT,
-            RequestBehavior.NEXT_VALUE,
-    })
-    @interface RequestBehavior {
-        int UNKNOWN = 0;
-        int REQUEST_WITH_WAIT = 1;
-        int REQUEST_WITH_CONTENT = 2;
-        int REQUEST_WITH_TIMEOUT = 3;
-        int NO_REQUEST_WITH_WAIT = 4;
-        int NO_REQUEST_WITH_CONTENT = 5;
-        int NO_REQUEST_WITH_TIMEOUT = 6;
-        int NEXT_VALUE = 7;
-    }
-
-    /** Object which contains the current state of the session. */
-    final class SessionState {
-        /** Does the session have content? */
-        public final boolean hasContent;
-        /**
-         * Returns the date/time of when the content was added. This will only be set when {@code
-         * hasContent == true},
-         */
-        public final long contentCreationDateTimeMs;
-        /** Is there an outstanding request being made? */
-        public final boolean hasOutstandingRequest;
-
-        public SessionState(
-                boolean hasContent, long contentCreationDateTimeMs, boolean hasOutstandingRequest) {
-            this.hasContent = hasContent;
-            this.contentCreationDateTimeMs = contentCreationDateTimeMs;
-            this.hasOutstandingRequest = hasOutstandingRequest;
-        }
-    }
-
-    /** Called when a Session is created to determine what behavior we should implement. */
-    @RequestBehavior
-    int shouldSessionRequestData(SessionState sessionState);
-
-    /** Notify scheduler that new content has been received. */
-    void onReceiveNewContent(long contentCreationDateTimeMs);
-
-    /** Notify scheduler that an error occurred while handling a request. */
-    void onRequestError(int networkResponseCode);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/CommitResult.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/CommitResult.java
deleted file mode 100644
index e4bd8384..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/CommitResult.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.storage;
-
-import androidx.annotation.IntDef;
-
-/** Status after completion of a commit to storage. */
-public final class CommitResult {
-    /** IntDef that defines result values. */
-    @IntDef({Result.SUCCESS, Result.FAILURE})
-    public @interface Result {
-        int SUCCESS = 0;
-        int FAILURE = 1;
-    }
-
-    public @Result int getResult() {
-        return mResult;
-    }
-
-    private final @Result int mResult;
-
-    // Private constructor - use static instances
-    private CommitResult(@Result int result) {
-        this.mResult = result;
-    }
-
-    public static final CommitResult SUCCESS = new CommitResult(Result.SUCCESS);
-    public static final CommitResult FAILURE = new CommitResult(Result.FAILURE);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentMutation.java
deleted file mode 100644
index e1399135..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentMutation.java
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.storage;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Delete;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.DeleteAll;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.DeleteByPrefix;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Upsert;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A sequence of {@link ContentOperation} instances. This class is used to commit changes to {@link
- * ContentStorage}.
- */
-public final class ContentMutation {
-    private final List<ContentOperation> mOperations;
-
-    private ContentMutation(List<ContentOperation> operations) {
-        this.mOperations = Collections.unmodifiableList(operations);
-    }
-
-    /** An unmodifiable list of operations to be committed by {@link ContentStorage}. */
-    public List<ContentOperation> getOperations() {
-        return mOperations;
-    }
-
-    /**
-     * Creates a {@link ContentMutation}, which can be used to apply mutations to the underlying
-     * {@link ContentStorage}.
-     */
-    public static final class Builder {
-        private final ArrayList<ContentOperation> mOperations = new ArrayList<>();
-        private final ContentOperationListSimplifier mSimplifier =
-                new ContentOperationListSimplifier();
-
-        /**
-         * Sets the key/value pair in {@link ContentStorage}, or inserts it if it doesn't exist.
-         *
-         * <p>This method can be called repeatedly to assign multiple key/values. If the same key is
-         * assigned multiple times, only the last value will be persisted.
-         */
-        public Builder upsert(String key, byte[] value) {
-            mOperations.add(new Upsert(key, value));
-            return this;
-        }
-
-        /**
-         * Deletes the value from {@link ContentStorage} with a matching key, if it exists.
-         *
-         * <p>{@link ContentStorage#commit(ContentMutation)} will fulfill with result is {@code
-         * TRUE}, even if {@code key} is not found in {@link ContentStorage}.
-         *
-         * <p>If {@link Delete} and {@link Upsert} are committed for the same key, only the last
-         * operation will take effect.
-         */
-        public Builder delete(String key) {
-            mOperations.add(new Delete(key));
-            return this;
-        }
-
-        /**
-         * Deletes all values from {@link ContentStorage} with matching key prefixes.
-         *
-         * <p>{@link ContentStorage#commit(ContentMutation)} will fulfill with result equal to
-         * {@code TRUE}, even if no keys have a matching prefix.
-         *
-         * <p>If {@link DeleteByPrefix} and {@link Upsert} are committed for the same matching key,
-         * only the last operation will take effect.
-         */
-        public Builder deleteByPrefix(String prefix) {
-            mOperations.add(new DeleteByPrefix(prefix));
-            return this;
-        }
-
-        /** Deletes all values from {@link ContentStorage}. */
-        public Builder deleteAll() {
-            mOperations.add(new DeleteAll());
-            return this;
-        }
-
-        /**
-         * Simplifies the sequence of {@link ContentOperation} instances, and returns a new {@link
-         * ContentMutation} the simplified list.
-         */
-        public ContentMutation build() {
-            return new ContentMutation(mSimplifier.simplify(mOperations));
-        }
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        ContentMutation that = (ContentMutation) o;
-
-        return mOperations != null ? mOperations.equals(that.mOperations)
-                                   : that.mOperations == null;
-    }
-
-    @Override
-    public int hashCode() {
-        return mOperations != null ? mOperations.hashCode() : 0;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentOperation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentOperation.java
deleted file mode 100644
index d451d40..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentOperation.java
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.storage;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
-
-import java.util.Arrays;
-
-/** A mutation to the underlying {@link ContentStorage}. */
-public abstract class ContentOperation {
-    /** The types of operations. */
-    @IntDef({Type.DELETE, Type.DELETE_BY_PREFIX, Type.UPSERT, Type.DELETE_ALL})
-    public @interface Type {
-        /** Delete the content for the provided key */
-        int DELETE = 0;
-        /** Delete all content with keys beginning with the specified prefix */
-        int DELETE_BY_PREFIX = 1;
-        /** Insert or update the content for the provided key */
-        int UPSERT = 3;
-        /** Delete all content for all keys. */
-        int DELETE_ALL = 4;
-    }
-
-    public @Type int getType() {
-        return mType;
-    }
-
-    private final @Type int mType;
-
-    // Only the following classes may extend ContentOperation
-    private ContentOperation(@Type int type) {
-        this.mType = type;
-    }
-
-    /**
-     * A {@link ContentOperation} created by calling {@link ContentMutation.Builder#upsert(String,
-     * byte[])}.
-     */
-    public static final class Upsert extends ContentOperation {
-        private final String mKey;
-        private final byte[] mValue;
-
-        Upsert(String key, byte[] value) {
-            super(Type.UPSERT);
-            this.mKey = key;
-            this.mValue = value;
-        }
-
-        public String getKey() {
-            return mKey;
-        }
-
-        public byte[] getValue() {
-            return mValue;
-        }
-
-        @Override
-        public boolean equals(@Nullable Object o) {
-            if (!super.equals(o)) {
-                return false;
-            }
-
-            if (o instanceof Upsert) {
-                Upsert upsert = (Upsert) o;
-                return mKey.equals(upsert.mKey) && Arrays.equals(mValue, upsert.mValue);
-            } else {
-                return false;
-            }
-        }
-
-        @Override
-        public int hashCode() {
-            int result = mKey.hashCode();
-            result = 31 * result + Arrays.hashCode(mValue);
-            return result;
-        }
-    }
-
-    /**
-     * A {@link ContentOperation} created by calling {@link ContentMutation.Builder#delete(String)}.
-     */
-    public static final class Delete extends ContentOperation {
-        private final String mKey;
-
-        Delete(String key) {
-            super(Type.DELETE);
-            this.mKey = key;
-        }
-
-        public String getKey() {
-            return mKey;
-        }
-
-        @Override
-        public boolean equals(@Nullable Object o) {
-            if (!super.equals(o)) {
-                return false;
-            }
-
-            if (o instanceof Delete) {
-                Delete delete = (Delete) o;
-                return mKey.equals(delete.mKey);
-            } else {
-                return false;
-            }
-        }
-
-        @Override
-        public int hashCode() {
-            return mKey.hashCode();
-        }
-    }
-
-    /**
-     * A {@link ContentOperation} created by calling {@link
-     * ContentMutation.Builder#deleteByPrefix(String)}.
-     */
-    public static final class DeleteByPrefix extends ContentOperation {
-        private final String mPrefix;
-
-        DeleteByPrefix(String prefix) {
-            super(Type.DELETE_BY_PREFIX);
-            this.mPrefix = prefix;
-        }
-
-        public String getPrefix() {
-            return mPrefix;
-        }
-
-        @Override
-        public boolean equals(@Nullable Object o) {
-            if (!super.equals(o)) {
-                return false;
-            }
-
-            if (o instanceof DeleteByPrefix) {
-                DeleteByPrefix that = (DeleteByPrefix) o;
-                return mPrefix.equals(that.mPrefix);
-            } else {
-                return false;
-            }
-        }
-
-        @Override
-        public int hashCode() {
-            return mPrefix.hashCode();
-        }
-    }
-
-    // TODO: replace these comments with better details
-    /** A {@link ContentOperation} created by calling {@link ContentMutation.Builder#deleteAll()} */
-    static final class DeleteAll extends ContentOperation {
-        DeleteAll() {
-            super(Type.DELETE_ALL);
-        }
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof ContentOperation)) {
-            return false;
-        }
-
-        ContentOperation operation = (ContentOperation) o;
-
-        return mType == operation.mType;
-    }
-
-    @Override
-    public int hashCode() {
-        return mType;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentOperationListSimplifier.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentOperationListSimplifier.java
deleted file mode 100644
index 92f536e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentOperationListSimplifier.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.storage;
-
-import java.util.List;
-
-/**
- * Simplifies a {@link List<ContentOperation>} by combining and removing Operations according to the
- * methods in {@link ContentMutation.Builder}.
- */
-final class ContentOperationListSimplifier {
-    /**
-     * Returns a new {@link List<ContentOperation>}, which is a simplification of {@code
-     * contentOperations}.
-     *
-     * <p>The returned list will have a length at most equal to {@code contentOperations}.
-     */
-    List<ContentOperation> simplify(List<ContentOperation> contentOperations) {
-        // TODO: implement
-        return contentOperations;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentStorage.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentStorage.java
deleted file mode 100644
index d05902b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentStorage.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.storage;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.common.Result;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Allows reading and writing of content, currently key-value pairs.
- *
- * <p>Storage instances can be accessed from multiple threads.
- */
-public interface ContentStorage {
-    /**
-     * Asynchronously requests the value for multiple keys. If a key does not have a value, it will
-     * not be included in the map.
-     */
-    void get(List<String> keys, Consumer<Result<Map<String, byte[]>>> consumer);
-
-    /** Asynchronously requests all key/value pairs from storage with a matching key prefix. */
-    void getAll(String prefix, Consumer<Result<Map<String, byte[]>>> consumer);
-
-    /**
-     * Commits the operations in the {@link ContentMutation} in order and asynchronously reports the
-     * {@link CommitResult}.
-     *
-     * <p>This operation is not guaranteed to be atomic. In the event of a failure, processing is
-     * halted immediately, so the database may be left in an invalid state. Should this occur, Feed
-     * behavior is undefined. Currently the plan is to wipe out existing data and start over.
-     */
-    void commit(ContentMutation mutation, Consumer<CommitResult> consumer);
-
-    /** Fetch all keys currently present in the content storage */
-    void getAllKeys(Consumer<Result<List<String>>> consumer);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentStorageDirect.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentStorageDirect.java
deleted file mode 100644
index fced434..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentStorageDirect.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.storage;
-
-import org.chromium.chrome.browser.feed.library.common.Result;
-
-import java.util.List;
-import java.util.Map;
-
-/** A content storage API which is a synchronous implementation of {@link ContentStorage}. */
-public interface ContentStorageDirect {
-    /**
-     * Requests the value for multiple keys. If a key does not have a value, it will not be included
-     * in the map.
-     */
-    Result<Map<String, byte[]>> get(List<String> keys);
-
-    /** Requests all key/value pairs from storage with a matching key prefix. */
-    Result<Map<String, byte[]>> getAll(String prefix);
-
-    /**
-     * Commits the operations in the {@link ContentMutation} in order.
-     *
-     * <p>This operation is not guaranteed to be atomic. In the event of a failure, processing is
-     * halted immediately, so the database may be left in an invalid state. Should this occur, Feed
-     * behavior is undefined. Currently the plan is to wipe out existing data and start over.
-     */
-    CommitResult commit(ContentMutation mutation);
-
-    /** Fetch all keys currently present in the content storage */
-    Result<List<String>> getAllKeys();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalMutation.java
deleted file mode 100644
index 688e4b14..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalMutation.java
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.storage;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Append;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Copy;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Delete;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A mutation described by a journal name and a sequence of {@link JournalOperation} instances. This
- * class is used to commit changes to a journal in {@link JournalStorage}.
- */
-public final class JournalMutation {
-    private final String mJournalName;
-    private final List<JournalOperation> mOperations;
-
-    private JournalMutation(String journalName, List<JournalOperation> operations) {
-        this.mJournalName = journalName;
-        this.mOperations = Collections.unmodifiableList(operations);
-    }
-
-    /** An unmodifiable list of operations to be committed by {@link JournalStorage}. */
-    public List<JournalOperation> getOperations() {
-        return mOperations;
-    }
-
-    /** The name of the journal this mutation should be applied to. */
-    public String getJournalName() {
-        return mJournalName;
-    }
-
-    /**
-     * Creates a {@link JournalMutation}, which can be used to apply mutations to a journal in the
-     * underlying {@link JournalStorage}.
-     */
-    public static final class Builder {
-        private final ArrayList<JournalOperation> mOperations = new ArrayList<>();
-        private final String mJournalName;
-
-        public Builder(String journalName) {
-            this.mJournalName = journalName;
-        }
-
-        /**
-         * Appends {@code value} to the journal in {@link JournalStorage}.
-         *
-         * <p>This method can be called repeatedly to append multiple times.
-         */
-        public Builder append(byte[] value) {
-            mOperations.add(new Append(value));
-            return this;
-        }
-
-        /** Copies the journal to {@code toJournalName}. */
-        public Builder copy(String toJournalName) {
-            mOperations.add(new Copy(toJournalName));
-            return this;
-        }
-
-        /** Deletes the journal. */
-        public Builder delete() {
-            mOperations.add(new Delete());
-            return this;
-        }
-
-        /** Creates a {@link JournalMutation} based on the operations added in this builder. */
-        public JournalMutation build() {
-            return new JournalMutation(mJournalName, new ArrayList<>(mOperations));
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalOperation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalOperation.java
deleted file mode 100644
index af65c075..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalOperation.java
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.storage;
-
-import androidx.annotation.IntDef;
-
-/** A mutation to the underlying {@link JournalStorage}. */
-public abstract class JournalOperation {
-    /** The types of operations. */
-    @IntDef({Type.APPEND, Type.COPY, Type.DELETE})
-    public @interface Type {
-        /** Append bytes to the provided journal */
-        int APPEND = 0;
-        /** Copy the provided journal to the given journal name */
-        int COPY = 1;
-        /** Delete the provided journal */
-        int DELETE = 2;
-    }
-
-    public @Type int getType() {
-        return mType;
-    }
-
-    private final @Type int mType;
-
-    // Only the following classes may extend JournalOperation
-    private JournalOperation(@Type int type) {
-        this.mType = type;
-    }
-
-    /**
-     * A {@link JournalOperation} created by calling {@link JournalMutation.Builder#append(byte[])}.
-     */
-    public static final class Append extends JournalOperation {
-        private final byte[] mValue;
-
-        Append(byte[] value) {
-            super(Type.APPEND);
-            this.mValue = value;
-        }
-
-        public byte[] getValue() {
-            return mValue;
-        }
-    }
-
-    /**
-     * A {@link JournalOperation} created by calling {@link JournalMutation.Builder#copy(String)}.
-     */
-    public static final class Copy extends JournalOperation {
-        private final String mToJournalName;
-
-        Copy(String toJournalName) {
-            super(Type.COPY);
-            this.mToJournalName = toJournalName;
-        }
-
-        public String getToJournalName() {
-            return mToJournalName;
-        }
-    }
-
-    /** A {@link JournalOperation} created by calling {@link JournalMutation.Builder#delete()}. */
-    public static final class Delete extends JournalOperation {
-        Delete() {
-            super(Type.DELETE);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalStorage.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalStorage.java
deleted file mode 100644
index a6540c5..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalStorage.java
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.storage;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.common.Result;
-
-import java.util.List;
-
-/**
- * Allows reading and writing to an append-only storage medium.
- *
- * <p>Storage instances can be accessed from multiple threads.
- *
- * <p>[INTERNAL LINK]
- */
-public interface JournalStorage {
-    /**
-     * Reads the journal and asynchronously returns the contents.
-     *
-     * <p>Reads on journals that do not exist will fulfill with an empty list.
-     */
-    void read(String journalName, Consumer<Result<List<byte[]>>> consumer);
-
-    /**
-     * Commits the operations in {@link JournalMutation} in order and asynchronously reports the
-     * {@link CommitResult}. If all the operations succeed, {@code callback} is called with a
-     * success result. If any operation fails, {@code callback} is called with a failure result and
-     * the remaining operations are not processed.
-     *
-     * <p>This operation is not guaranteed to be atomic.
-     */
-    void commit(JournalMutation mutation, Consumer<CommitResult> consumer);
-
-    /** Determines whether a journal exists and asynchronously responds. */
-    void exists(String journalName, Consumer<Result<Boolean>> consumer);
-
-    /** Asynchronously retrieve a list of all current journals */
-    void getAllJournals(Consumer<Result<List<String>>> consumer);
-
-    /** Delete all journals. Reports success or failure with the {@code consumer}. */
-    void deleteAll(Consumer<CommitResult> consumer);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalStorageDirect.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalStorageDirect.java
deleted file mode 100644
index 73d3164..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalStorageDirect.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.storage;
-
-import org.chromium.chrome.browser.feed.library.common.Result;
-
-import java.util.List;
-
-/** Define a version of the {@link JournalStorage} which runs synchronously. */
-public interface JournalStorageDirect {
-    /**
-     * Reads the journal and a returns the contents.
-     *
-     * <p>Reads on journals that do not exist will fulfill with an empty list.
-     */
-    Result<List<byte[]>> read(String journalName);
-
-    /**
-     * Commits the operations in {@link JournalMutation} in order and reports the {@link
-     * CommitResult}. If all the operations succeed returns a success result, otherwise reports a
-     * failure.
-     *
-     * <p>This operation is not guaranteed to be atomic.
-     */
-    CommitResult commit(JournalMutation mutation);
-
-    /** Determines whether a journal exists. */
-    Result<Boolean> exists(String journalName);
-
-    /** Retrieve a list of all current journals */
-    Result<List<String>> getAllJournals();
-
-    /** Delete all journals. */
-    CommitResult deleteAll();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/CardConfiguration.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/CardConfiguration.java
deleted file mode 100644
index 59b5d30..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/CardConfiguration.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.stream;
-
-import android.graphics.drawable.Drawable;
-
-/** Class which is able to provide host configuration for default card look and feel. */
-// TODO: Look into allowing server configuration of this.
-public interface CardConfiguration {
-    int getDefaultCornerRadius();
-
-    Drawable getCardBackground();
-
-    /** Returns the amount of margin (in px) at the end of a card in the Stream */
-    int getCardBottomMargin();
-
-    /** Returns the amount of margin (in px) to the left (in LTR locales) of cards. */
-    int getCardStartMargin();
-
-    /** Returns the amount of margin (in px) to the right (in LTR locales) of cards. */
-    int getCardEndMargin();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/SnackbarApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/SnackbarApi.java
deleted file mode 100644
index 93057cb4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/SnackbarApi.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.stream;
-
-/** The SnackbarApi is used by the Feed to render snackbars. */
-public interface SnackbarApi {
-    /**
-     * Displays a snackbar on the host.
-     *
-     * @param message Text to display in the snackbar.
-     */
-    void show(String message);
-
-    /**
-     * Displays a snackbar on the host.
-     *
-     * @param message Text to display in the snackbar.
-     * @param message Text to display in the snackbar's action. e.g. "undo"
-     * @param callback A Callback for the client to know why and when the snackbar goes away.
-     */
-    void show(String message, String action, SnackbarCallbackApi callback);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/SnackbarCallbackApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/SnackbarCallbackApi.java
deleted file mode 100644
index 41579d5..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/SnackbarCallbackApi.java
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.stream;
-
-/** The SnackbarCallbackApi is a Callback class for Snackbar events. */
-public interface SnackbarCallbackApi {
-    /** Called when the user clicks the action button on the snackbar. */
-    void onDismissedWithAction();
-
-    /** Called when the snackbar is dismissed by timeout or UI environment change. */
-    void onDismissNoAction();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/StreamConfiguration.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/StreamConfiguration.java
deleted file mode 100644
index 92a17562..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/StreamConfiguration.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.stream;
-
-/** Interface which is able to provide host configuration for default stream look and feel. */
-public interface StreamConfiguration {
-    /**
-     * Returns the padding (in px) that appears to the start (left in LtR)) of each view in the
-     * Stream.
-     */
-    int getPaddingStart();
-
-    /**
-     * Returns the padding (in px) that appears to the end (right in LtR)) of each view in the
-     * Stream.
-     */
-    int getPaddingEnd();
-
-    /** Returns the padding (in px) that appears before the first view in the Stream. */
-    int getPaddingTop();
-
-    /** Returns the padding (in px) that appears after the last view in the Stream. */
-    int getPaddingBottom();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipApi.java
deleted file mode 100644
index 420e8ec..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipApi.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.stream;
-
-import android.view.View;
-
-/** Interface used to show a tooltip to reference a view. */
-public interface TooltipApi {
-    /**
-     * Shows a tooltip to reference a view if the user is eligible to see the tooltip.
-     *
-     * @param tooltipInfo information used to show this tooltip including placement info.
-     * @param view the view the tooltip is centered on.
-     * @param tooltipCallback the callback that will be evoked on tooltip events.
-     * @return true if the tooltip is actually shown.
-     */
-    boolean maybeShowHelpUi(TooltipInfo tooltipInfo, View view, TooltipCallbackApi tooltipCallback);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipCallbackApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipCallbackApi.java
deleted file mode 100644
index 5cd9098..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipCallbackApi.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.stream;
-
-import androidx.annotation.IntDef;
-
-/** Interface for callbacks for tooltip events. */
-public interface TooltipCallbackApi {
-    /** The ways a tooltip can be dismissed. */
-    @IntDef({
-            TooltipDismissType.UNKNOWN,
-            TooltipDismissType.TIMEOUT,
-            TooltipDismissType.CLICK,
-            TooltipDismissType.CLICK_OUTSIDE,
-    })
-    @interface TooltipDismissType {
-        int UNKNOWN = 0;
-        int TIMEOUT = 1;
-        int CLICK = 2;
-        int CLICK_OUTSIDE = 3;
-    }
-
-    /** The callback that will be triggered when the tooltip is shown. */
-    void onShow();
-
-    /**
-     * The callback that will be triggered when the tooltip is hidden.
-     *
-     * @param dismissType the type of event that caused the tooltip to be hidden.
-     */
-    void onHide(@TooltipDismissType int dismissType);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipInfo.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipInfo.java
deleted file mode 100644
index 74bf1f73..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipInfo.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.stream;
-
-import androidx.annotation.StringDef;
-
-/** All the information necessary to render a tooltip. */
-public interface TooltipInfo {
-    /** The list of features that the tooltip can highlight. */
-    @StringDef({FeatureName.UNKNOWN, FeatureName.CARD_MENU_TOOLTIP})
-    @interface FeatureName {
-        String UNKNOWN = "unknown";
-        String CARD_MENU_TOOLTIP = "card_menu_tooltip";
-    }
-
-    /** Returns the text to display in the tooltip. */
-    String getLabel();
-
-    /** Returns the talkback string to attach to tooltip. */
-    String getAccessibilityLabel();
-
-    /** Returns the Feature that the tooltip should reference. */
-    @FeatureName
-    String getFeatureName();
-
-    /**
-     * Returns the number of dp units that the tooltip arrow should point to below the center of the
-     * top of the view it is referencing.
-     */
-    int getTopInset();
-
-    /**
-     * Returns the number of dp units that the tooltip arrow should point to above the center of the
-     * bottom of the view it is referencing.
-     */
-    int getBottomInset();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipSupportedApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipSupportedApi.java
deleted file mode 100644
index b1ed679..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipSupportedApi.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.host.stream;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipInfo.FeatureName;
-
-/** Interface to communicate if particular types of tooltips meet triggering conditions. */
-public interface TooltipSupportedApi {
-    /**
-     * Checks if the tooltip would be shown if {@link TooltipApi#maybeShowHelpUi} is called.
-     *
-     * @param featureName the name of the tooltip feature that might be triggered.
-     * @param consumer a callback that contains a boolean indicating that the tooltip would be shown
-     *     if {@link TooltipApi#maybeShowHelpUi} is called.
-     */
-    void wouldTriggerHelpUi(@FeatureName String featureName, Consumer<Boolean> consumer);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionmanager/ActionManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionmanager/ActionManager.java
deleted file mode 100644
index 2342fca..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionmanager/ActionManager.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.actionmanager;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.base.Consumer;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.wire.ActionPayloadProto.ActionPayload;
-
-import java.util.List;
-
-/** Allows Stream to notify the Feed library of actions taken */
-public interface ActionManager extends ViewActionManager {
-    public static enum UploadActionType { MISC, CLICK, VIEW }
-
-    /**
-     * Dismiss content for the content ID in the session, along with executing the provided stream
-     * data operations on the session.
-     *
-     * @param contentIds The content IDs for the feature being dismissed. These are recorded and
-     *         sent to the server in subsequent requests.
-     * @param streamDataOperations Any stream data operations that should be applied to the session
-     *     (e.g. removing a cluster when the content is removed)
-     * @param sessionId The current session id
-     */
-    void dismissLocal(List<String> contentIds, List<StreamDataOperation> streamDataOperations,
-            @Nullable String sessionId);
-
-    /**
-     * Executes the provided stream data operations on the session.
-     *
-     * @param contentId The id for the content that triggered this action.
-     * @param streamDataOperations Any stream data operations that should be applied to the session
-     *     (e.g. removing a cluster when the content is removed)
-     * @param sessionId The current session id
-     */
-    void dismiss(List<StreamDataOperation> streamDataOperations, @Nullable String sessionId);
-
-    /**
-     * Issues a request to record a set of actions, with the consumer being called back with the
-     * resulting {@link ConsistencyToken}.
-     */
-    void createAndUploadAction(
-            String contentId, ActionPayload payload, UploadActionType actionType);
-
-    /**
-     * Issues a request to record a single action and store it for future upload.
-     */
-    void createAndStoreAction(String contentId, ActionPayload payload, UploadActionType actionType);
-
-    /**
-     * Issues a request to record a set of action and update the url with consistency token with the
-     * consumer being called on the main thread with the resulting url.
-     */
-    void uploadAllActionsAndUpdateUrl(
-            String url, String consistencyTokenQueryParamName, Consumer<String> consumer);
-
-    /**
-     * Sets the bit that determines whether clicks and views can be uploaded when the notice card is
-     * present.
-     */
-    void setCanUploadClicksAndViewsWhenNoticeCardIsPresent(boolean canUploadClicksAndViews);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionmanager/ActionReader.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionmanager/ActionReader.java
deleted file mode 100644
index be76e97a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionmanager/ActionReader.java
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.actionmanager;
-
-import org.chromium.chrome.browser.feed.library.api.internal.common.DismissActionWithSemanticProperties;
-import org.chromium.chrome.browser.feed.library.common.Result;
-
-import java.util.List;
-
-/** Interface for reading various {@link StreamAction}s. */
-public interface ActionReader {
-    /**
-     * Retrieves list of {@link DismissActionWithSemanticProperties} for all valid dismiss actions
-     */
-    Result<List<DismissActionWithSemanticProperties>> getDismissActionsWithSemanticProperties();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionmanager/ViewActionManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionmanager/ViewActionManager.java
deleted file mode 100644
index 6aea1be..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionmanager/ViewActionManager.java
+++ /dev/null
@@ -1,56 +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.
-
-package org.chromium.chrome.browser.feed.library.api.internal.actionmanager;
-
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ScrollListener;
-import org.chromium.components.feed.core.proto.wire.ActionPayloadProto.ActionPayload;
-
-/** Manages the collection of View actions for cards in the feed. **/
-public interface ViewActionManager {
-    /**
-     * Sets the container (usually a {@link android.view.ViewGroup}) representing the current
-     * viewport.
-     */
-    public void setViewport(@Nullable View viewport);
-
-    /** Signals that a view with associated reportable content has become visible. */
-    public void onViewVisible(View view, String contentId, ActionPayload actionPayload);
-
-    /** Signals that a view with associated reportable content has become hidden. */
-    public void onViewHidden(View view, String contentId);
-
-    /** Return a scroll listener that passes scroll state changes to this ViewReporter. */
-    public ScrollListener getScrollListener();
-
-    /**
-     * Signal an {@link androidx.recyclerview.widget.RecyclerView.ItemAnimator#onAnimationFinished}
-     * event at the stream level.
-     */
-    public void onAnimationFinished();
-
-    /** Signal an {@link android.view.View.OnLayoutChangeListener#onLayoutChange} event. */
-    public void onLayoutChange();
-
-    /**
-     * Signal an {@link org.chromium.chrome.browser.feed.library.api.client.stream.Stream#onShow}
-     * event.
-     */
-    public void onShow();
-
-    /**
-     * Signal an {@link org.chromium.chrome.browser.feed.library.api.client.stream.Stream#onHide}
-     * event.
-     */
-    public void onHide();
-
-    /**
-     * Asynchronously collect and store pending View actions, then call given Runnable.
-     */
-    public void storeViewActions(Runnable doneCallback);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionParser.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionParser.java
deleted file mode 100644
index d48ca4b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionParser.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.actionparser;
-
-import android.view.View;
-
-import org.chromium.chrome.browser.feed.library.api.host.action.StreamActionApi;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionPayloadProto.FeedActionPayload;
-import org.chromium.components.feed.core.proto.ui.piet.ActionsProto.Action;
-import org.chromium.components.feed.core.proto.ui.piet.LogDataProto.LogData;
-
-/** Parses actions from Piet and directs the Stream to handle the action. */
-public interface ActionParser {
-    void parseAction(Action action, StreamActionApi streamActionApi, View view, LogData logData,
-            @ActionSource int actionSource);
-
-    void parseFeedActionPayload(FeedActionPayload feedActionPayload,
-            StreamActionApi streamActionApi, View view, @ActionSource int actionSource);
-
-    boolean canPerformAction(FeedActionPayload feedActionPayload, StreamActionApi streamActionApi);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionParserFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionParserFactory.java
deleted file mode 100644
index 5014f53..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionParserFactory.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.actionparser;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.ContentMetadata;
-
-/** Factory for {@link ActionParser}. */
-public interface ActionParserFactory {
-    /**
-     * Builds the ActionParser.
-     *
-     * @param contentMetadata A {@link Supplier} for {@link ContentMetadata} required for the {@link
-     *     org.chromium.chrome.browser.feed.library.api.host.action.
-     *      ActionApi#downloadUrl(ContentMetadata)}
-     *     action. If the {@link Supplier} returns {@code null}, the download action will be
-     *     suppressed. A {@link Supplier} is used instead of just a {@link ContentMetadata} to save
-     * on memory and startup time. The {@link Supplier} will not be accessed until an action is
-     * taken that requires it.
-     */
-    ActionParser build(Supplier<ContentMetadata> contentMetadata);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionSource.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionSource.java
deleted file mode 100644
index 6fb04ef..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionSource.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.actionparser;
-
-import androidx.annotation.IntDef;
-
-/** Possible action types. */
-@IntDef({ActionSource.UNKNOWN, ActionSource.VIEW, ActionSource.CLICK, ActionSource.LONG_CLICK,
-        ActionSource.SWIPE, ActionSource.CONTEXT_MENU})
-public @interface ActionSource {
-    int UNKNOWN = 0;
-    /** View action */
-    int VIEW = 1;
-
-    /** Click action */
-    int CLICK = 2;
-
-    /** Long click action */
-    int LONG_CLICK = 3;
-
-    /* Swipe action */
-    int SWIPE = 4;
-
-    /* Action performed from context menu*/
-    int CONTEXT_MENU = 5;
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionSourceConverter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionSourceConverter.java
deleted file mode 100644
index 8d5d6554..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionSourceConverter.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.actionparser;
-
-import org.chromium.chrome.browser.feed.library.piet.host.ActionHandler.ActionType;
-
-/** Utility class to convert a {@link ActionType} to {@link ActionSource}. */
-public final class ActionSourceConverter {
-    private ActionSourceConverter() {}
-
-    @ActionSource
-    public static int convertPietAction(@ActionType int type) {
-        switch (type) {
-            case ActionType.VIEW:
-                return ActionSource.VIEW;
-            case ActionType.CLICK:
-                return ActionSource.CLICK;
-            case ActionType.LONG_CLICK:
-                return ActionSource.LONG_CLICK;
-            default:
-                return ActionSource.UNKNOWN;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/DismissActionWithSemanticProperties.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/DismissActionWithSemanticProperties.java
deleted file mode 100644
index a06d918c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/DismissActionWithSemanticProperties.java
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.common;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-
-import java.util.Arrays;
-
-/**
- * Represents the content needed for a dismiss action internally. Holds the content ID of the
- * dismissed content, and any semantic properties associated with it.
- */
-public final class DismissActionWithSemanticProperties {
-    private final ContentId mContentId;
-    @Nullable
-    private final byte[] mSemanticProperties;
-
-    public DismissActionWithSemanticProperties(
-            ContentId contentId, @Nullable byte[] semanticProperties) {
-        this.mContentId = contentId;
-        this.mSemanticProperties = semanticProperties;
-    }
-
-    public ContentId getContentId() {
-        return mContentId;
-    }
-
-    public byte[] getSemanticProperties() {
-        return mSemanticProperties;
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        DismissActionWithSemanticProperties that = (DismissActionWithSemanticProperties) o;
-
-        if (!mContentId.equals(that.mContentId)) {
-            return false;
-        }
-        return Arrays.equals(mSemanticProperties, that.mSemanticProperties);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = mContentId.hashCode();
-        result = 31 * result + Arrays.hashCode(mSemanticProperties);
-        return result;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/Model.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/Model.java
deleted file mode 100644
index 7c206969..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/Model.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.common;
-
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/** Contains a list of {@link StreamDataOperations}s and a schema version. */
-public final class Model {
-    /** The current schema version. */
-    public static final int CURRENT_SCHEMA_VERSION = 2;
-
-    public final List<StreamDataOperation> streamDataOperations;
-    public final int schemaVersion;
-
-    private Model(List<StreamDataOperation> streamDataOperations, int schemaVersion) {
-        this.streamDataOperations =
-                Collections.unmodifiableList(new ArrayList(streamDataOperations));
-        this.schemaVersion = schemaVersion;
-    }
-
-    public static Model of(List<StreamDataOperation> streamDataOperations) {
-        return of(streamDataOperations, CURRENT_SCHEMA_VERSION);
-    }
-
-    public static Model of(List<StreamDataOperation> streamDataOperations, int schemaVersion) {
-        return new Model(streamDataOperations, schemaVersion);
-    }
-
-    public static Model empty() {
-        return new Model(Collections.emptyList(), CURRENT_SCHEMA_VERSION);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/PayloadWithId.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/PayloadWithId.java
deleted file mode 100644
index 52cd11c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/PayloadWithId.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.common;
-
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-
-/**
- * Structure style class which binds a String contentId with a {@link StreamPayload}. The class is
- * immutable and provides access to the fields directly.
- */
-public final class PayloadWithId {
-    public final String contentId;
-    public final StreamPayload payload;
-
-    public PayloadWithId(String contentId, StreamPayload payload) {
-        this.contentId = contentId;
-        this.payload = payload;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/SemanticPropertiesWithId.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/SemanticPropertiesWithId.java
deleted file mode 100644
index 8e96f62..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/SemanticPropertiesWithId.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.common;
-
-import androidx.annotation.Nullable;
-
-import java.util.Arrays;
-
-/**
- * Structure style class which binds a String contentId with the semantic properties data for that
- * contentId. The class is immutable and provides access to the fields directly.
- */
-public final class SemanticPropertiesWithId {
-    public final String contentId;
-    public final byte[] semanticData;
-
-    public SemanticPropertiesWithId(String contentId, byte[] semanticData) {
-        this.contentId = contentId;
-        this.semanticData = semanticData;
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        SemanticPropertiesWithId that = (SemanticPropertiesWithId) o;
-
-        if (!contentId.equals(that.contentId)) {
-            return false;
-        }
-        return Arrays.equals(semanticData, that.semanticData);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = contentId.hashCode();
-        result = 31 * result + Arrays.hashCode(semanticData);
-        return result;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/ThreadUtils.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/ThreadUtils.java
deleted file mode 100644
index 2e85a5a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/ThreadUtils.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.common;
-
-import android.os.Looper;
-
-/** Thread utilities. */
-// TODO: Need to make this class file for Tiktok compliance.  This is mocked in a bunch
-// of tests which run on the main thread.
-public class ThreadUtils {
-    public ThreadUtils() {}
-
-    /** Returns {@code true} if this method is being called from the main/UI thread. */
-    public boolean isMainThread() {
-        return Looper.getMainLooper() == Looper.myLooper();
-    }
-
-    public void checkNotMainThread() {
-        check(!isMainThread(), "checkNotMainThread failed");
-    }
-
-    public void checkMainThread() {
-        check(isMainThread(), "checkMainThread failed");
-    }
-
-    protected void check(boolean condition, String message) {
-        if (!condition) {
-            throw new IllegalStateException(message);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/testing/ContentIdGenerators.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/testing/ContentIdGenerators.java
deleted file mode 100644
index d64bb2c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/testing/ContentIdGenerators.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.common.testing;
-
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-
-/** Test support class which creates Jardin content ids. */
-public class ContentIdGenerators {
-    private static final String FEATURE = "feature";
-    private static final String ROOT_DOMAIN = "stream_root";
-    private static final ContentId FEATURE_CONTENT_ID =
-            ContentId.newBuilder().setContentDomain(FEATURE).setId(0).setTable(FEATURE).build();
-    private static final ContentId TOKEN_ID =
-            ContentId.newBuilder().setContentDomain("token").setId(0).setTable(FEATURE).build();
-    private static final ContentId SHARED_STATE_CONTENT_ID =
-            ContentId.newBuilder()
-                    .setContentDomain("shared-state")
-                    .setId(0)
-                    .setTable(FEATURE)
-                    .build();
-
-    public static final String ROOT_PREFIX = FEATURE + "::" + ROOT_DOMAIN;
-
-    public String createFeatureContentId(long id) {
-        return createContentId(FEATURE_CONTENT_ID.toBuilder().setId(id).build());
-    }
-
-    public String createTokenContentId(long id) {
-        return createContentId(TOKEN_ID.toBuilder().setId(id).build());
-    }
-
-    public String createSharedStateContentId(long id) {
-        return createContentId(SHARED_STATE_CONTENT_ID.toBuilder().setId(id).build());
-    }
-
-    public String createRootContentId(int id) {
-        return createContentId(ContentId.newBuilder()
-                                       .setContentDomain(ROOT_DOMAIN)
-                                       .setId(id)
-                                       .setTable(FEATURE)
-                                       .build());
-    }
-
-    public String createContentId(ContentId contentId) {
-        // Using String concat for performance reasons.  This is called a lot for large feed
-        // responses.
-        return contentId.getTable() + "::" + contentId.getContentDomain()
-                + "::" + contentId.getId();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/testing/InternalProtocolBuilder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/testing/InternalProtocolBuilder.java
deleted file mode 100644
index 182a23f6..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/testing/InternalProtocolBuilder.java
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.common.testing;
-
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamFeature;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure.Operation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** This is a builder class for creating internal protocol elements. */
-public class InternalProtocolBuilder {
-    private final ContentIdGenerators mIdGenerators = new ContentIdGenerators();
-    private final List<StreamDataOperation> mDataOperations = new ArrayList<>();
-
-    /** This adds a Root Feature into the Stream of data operations */
-    public InternalProtocolBuilder addRootFeature() {
-        StreamFeature streamFeature = StreamFeature.newBuilder()
-                                              .setContentId(mIdGenerators.createRootContentId(0))
-                                              .build();
-        StreamStructure streamStructure =
-                StreamStructure.newBuilder()
-                        .setOperation(Operation.UPDATE_OR_APPEND)
-                        .setContentId(mIdGenerators.createRootContentId(0))
-                        .build();
-        StreamPayload streamPayload =
-                StreamPayload.newBuilder().setStreamFeature(streamFeature).build();
-        mDataOperations.add(StreamDataOperation.newBuilder()
-                                    .setStreamStructure(streamStructure)
-                                    .setStreamPayload(streamPayload)
-                                    .build());
-        return this;
-    }
-
-    public InternalProtocolBuilder addClearOperation() {
-        StreamStructure streamStructure =
-                StreamStructure.newBuilder().setOperation(Operation.CLEAR_ALL).build();
-        mDataOperations.add(
-                StreamDataOperation.newBuilder().setStreamStructure(streamStructure).build());
-        return this;
-    }
-
-    public InternalProtocolBuilder addSharedState(String contentId) {
-        StreamSharedState streamSharedState =
-                StreamSharedState.newBuilder().setContentId(contentId).build();
-        StreamStructure streamStructure = StreamStructure.newBuilder()
-                                                  .setOperation(Operation.UPDATE_OR_APPEND)
-                                                  .setContentId(contentId)
-                                                  .build();
-        StreamPayload streamPayload =
-                StreamPayload.newBuilder().setStreamSharedState(streamSharedState).build();
-        mDataOperations.add(StreamDataOperation.newBuilder()
-                                    .setStreamStructure(streamStructure)
-                                    .setStreamPayload(streamPayload)
-                                    .build());
-        return this;
-    }
-
-    public InternalProtocolBuilder addToken(String contentId) {
-        StreamToken streamToken = StreamToken.newBuilder().setContentId(contentId).build();
-        StreamStructure streamStructure = StreamStructure.newBuilder()
-                                                  .setOperation(Operation.UPDATE_OR_APPEND)
-                                                  .setContentId(contentId)
-                                                  .build();
-        StreamPayload streamPayload =
-                StreamPayload.newBuilder().setStreamToken(streamToken).build();
-        mDataOperations.add(StreamDataOperation.newBuilder()
-                                    .setStreamStructure(streamStructure)
-                                    .setStreamPayload(streamPayload)
-                                    .build());
-        return this;
-    }
-
-    public InternalProtocolBuilder addFeature(String contentId, String parentId) {
-        StreamFeature streamFeature =
-                StreamFeature.newBuilder().setContentId(contentId).setParentId(parentId).build();
-        StreamStructure streamStructure = StreamStructure.newBuilder()
-                                                  .setOperation(Operation.UPDATE_OR_APPEND)
-                                                  .setContentId(contentId)
-                                                  .setParentContentId(parentId)
-                                                  .build();
-        StreamPayload streamPayload =
-                StreamPayload.newBuilder().setStreamFeature(streamFeature).build();
-        mDataOperations.add(StreamDataOperation.newBuilder()
-                                    .setStreamStructure(streamStructure)
-                                    .setStreamPayload(streamPayload)
-                                    .build());
-        return this;
-    }
-
-    public InternalProtocolBuilder removeFeature(String contentId, String parentId) {
-        StreamStructure streamStructure = StreamStructure.newBuilder()
-                                                  .setOperation(Operation.REMOVE)
-                                                  .setContentId(contentId)
-                                                  .setParentContentId(parentId)
-                                                  .build();
-        mDataOperations.add(
-                StreamDataOperation.newBuilder().setStreamStructure(streamStructure).build());
-        return this;
-    }
-
-    public InternalProtocolBuilder addRequiredContent(String contentId) {
-        mDataOperations.add(
-                StreamDataOperation.newBuilder()
-                        .setStreamStructure(StreamStructure.newBuilder()
-                                                    .setOperation(Operation.REQUIRED_CONTENT)
-                                                    .setContentId(contentId))
-                        .build());
-        return this;
-    }
-
-    public List<StreamDataOperation> build() {
-        return new ArrayList<>(mDataOperations);
-    }
-
-    /**
-     * This will return the StreamStructure part only, filtering out any shared state. This is the
-     * form structure is represented in the Store.
-     */
-    public List<StreamStructure> buildAsStreamStructure() {
-        List<StreamStructure> streamStructures = new ArrayList<>();
-        for (StreamDataOperation operation : mDataOperations) {
-            // For the structure, ignore the shared state
-            if (operation.getStreamPayload().hasStreamSharedState()) {
-                continue;
-            }
-            streamStructures.add(operation.getStreamStructure());
-        }
-        return streamStructures;
-    }
-
-    public List<PayloadWithId> buildAsPayloadWithId() {
-        List<PayloadWithId> payloads = new ArrayList<>();
-        for (StreamDataOperation operation : mDataOperations) {
-            // For the structure, ignore the shared state
-            if (operation.getStreamPayload().hasStreamSharedState()) {
-                continue;
-            }
-            // Only include payloads with UPDATE_OR_APPEND.
-            if (operation.getStreamStructure().getOperation() != Operation.UPDATE_OR_APPEND) {
-                continue;
-            }
-            payloads.add(new PayloadWithId(
-                    operation.getStreamStructure().getContentId(), operation.getStreamPayload()));
-        }
-        return payloads;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/knowncontent/FeedKnownContent.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/knowncontent/FeedKnownContent.java
deleted file mode 100644
index 8dcae3f8..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/knowncontent/FeedKnownContent.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.knowncontent;
-
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.KnownContent;
-
-import java.util.List;
-
-/** Allows the feed libraries to request and subscribe to information about the Feed's content. */
-public interface FeedKnownContent extends KnownContent {
-    /**
-     * Gets listener that notifies all added listeners of {@link
-     * KnownContent.Listener#onContentRemoved(List)} or {@link
-     * KnownContent.Listener#onNewContentReceived(boolean, long)}.
-     *
-     * <p>Note: This method is internal to the Feed. It provides a {@link Listener} that, when
-     * notified, will propagate the notification to the host.
-     */
-    KnownContent.Listener getKnownContentHostNotifier();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/lifecycle/Resettable.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/lifecycle/Resettable.java
deleted file mode 100644
index 246235c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/lifecycle/Resettable.java
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.lifecycle;
-
-/** Interface for objects which support reset to an initial state. */
-public interface Resettable {
-    /* Reset the object. */
-    void reset();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/FeatureChange.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/FeatureChange.java
deleted file mode 100644
index 6929475..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/FeatureChange.java
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.modelprovider;
-
-import java.util.List;
-
-/**
- * Class defining the specific changes made to feature nodes within the model. This is passed to the
- * observer to handle model changes. There are a few types of changes described here:
- *
- * <ol>
- *   <li>if {@link #isFeatureChanged()} returns {@code true}, then the ModelFeature was changed
- *   <li>{@link #getChildChanges()} returns a list of features either, appended, prepended, or
- *       removed from a parent
- * </ol>
- */
-public interface FeatureChange {
-    /** Returns the contentId of the ModelFeature which was changed. */
-    String getContentId();
-
-    /** Returns {@code true} if the ModelFeature changed. */
-    boolean isFeatureChanged();
-
-    /** Returns the ModelFeature that was changed. */
-    ModelFeature getModelFeature();
-
-    /** Returns the structural changes to the ModelFeature. */
-    ChildChanges getChildChanges();
-
-    /** Class describing changes to the children. */
-    interface ChildChanges {
-        /**
-         * Returns a List of the children added to this ModelFeature. These children are in the same
-         * order they would be displayed in the stream.
-         */
-        List<ModelChild> getAppendedChildren();
-
-        /** Returns a List of the children removed from this ModelFeature. */
-        List<ModelChild> getRemovedChildren();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/FeatureChangeObserver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/FeatureChangeObserver.java
deleted file mode 100644
index 5de73a3fb..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/FeatureChangeObserver.java
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.modelprovider;
-
-/**
- * Defines an interface which observes changes features within the stream model. The {@link
- * #onChange(FeatureChange)} is called when a feature changes.
- */
-public interface FeatureChangeObserver {
-    /** Called when children of the feature or the underlying payload proto instance change. */
-    void onChange(FeatureChange change);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelChild.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelChild.java
deleted file mode 100644
index 40730c2..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelChild.java
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.modelprovider;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
-
-/**
- * Abstract Interface defining a Child of a feature which may be returned by a {@link ModelCursor}.
- * A ModelChild must be bound to either a feature or token.
- */
-public interface ModelChild {
-    /** Define the concrete type of the children. */
-    @IntDef({Type.UNBOUND, Type.FEATURE, Type.TOKEN})
-    @interface Type {
-        // A feature that isn't yet bound to a specific data type
-        // This should never be exposed outside of the model.
-        int UNBOUND = 0;
-
-        // A stream feature child.
-        int FEATURE = 1;
-
-        // The child is a continuation token.  This means the cursor is at end
-        // and a request has been made to create a new cursor with additional
-        // children.
-        int TOKEN = 2;
-    }
-
-    /** Returns the type of the child. */
-    @Type
-    int getType();
-
-    /** Returns the ContentId of the child, all children will have a Content ID. */
-    String getContentId();
-
-    /** Returns true there is a parent to this child; false if this is a root. */
-    boolean hasParentId();
-
-    /**
-     * Returns the parent contentId of the child, this may return {@code Null} if the child is a
-     * root.
-     */
-    @Nullable
-    String getParentId();
-
-    /**
-     * Returns a the {@link ModelFeature}. This will throw an {@link IllegalStateException} if the
-     * {@link Type} is not equal to {@code FEATURE}.
-     */
-    ModelFeature getModelFeature();
-
-    /**
-     * Returns the {@link ModelToken}. This will throw an {@link IllegalStateException} if the
-     * {@link Type} is not equal to {@code TOKEN}.
-     */
-    ModelToken getModelToken();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelCursor.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelCursor.java
deleted file mode 100644
index 6f53966..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelCursor.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.modelprovider;
-
-import androidx.annotation.Nullable;
-
-/**
- * This represents a Cursor through the children of a {@link ModelFeature}. A Cursor will provide
- * forward only access to the children of the container. When a cursor is created by calling {@link
- * ModelFeature#getCursor()}, it is positioned at the first child.
- */
-public interface ModelCursor {
-    /** Returns the next {@link ModelChild} in the cursor or {@code null} if at end. */
-    @Nullable
-    ModelChild getNextItem();
-
-    /** Returns {@literal true} if the cursor is at the end. */
-    boolean isAtEnd();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelError.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelError.java
deleted file mode 100644
index d2be1390..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelError.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.modelprovider;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
-
-import com.google.protobuf.ByteString;
-
-/**
- * Class which contains information needed by the {@link
- * org.chromium.chrome.browser.feed.library.api.client.stream.Stream} about errors which may occur
- * in the infrastructure.
- */
-public final class ModelError {
-    /** Defines errors are exposed through the ModelProvider to the Stream. */
-    @IntDef({ErrorType.UNKNOWN, ErrorType.NO_CARDS_ERROR, ErrorType.PAGINATION_ERROR,
-            ErrorType.SYNTHETIC_TOKEN_ERROR})
-    public @interface ErrorType {
-        // An unknown error, this is not expected to ever be used.
-        int UNKNOWN = 0;
-        // No cards are available due to an error such as, no network available or a request failed,
-        // etc.
-        int NO_CARDS_ERROR = 1;
-        // Pagination failed due to some type of error such as no network available or a request
-        // failed, etc.
-        int PAGINATION_ERROR = 2;
-        // Pagination failed due to a synthetic token error.
-        int SYNTHETIC_TOKEN_ERROR = 3;
-    }
-
-    private final @ErrorType int mErrorType;
-    @Nullable
-    private final ByteString mContinuationToken;
-
-    public ModelError(@ErrorType int errorType, @Nullable ByteString continuationToken) {
-        this.mErrorType = errorType;
-        this.mContinuationToken = continuationToken;
-    }
-
-    /** Returns the ErrorType assocated with the error. */
-    public @ErrorType int getErrorType() {
-        return mErrorType;
-    }
-
-    /** This should be non-null if the ErrorType is PAGINATION_ERROR. */
-    @Nullable
-    public ByteString getContinuationToken() {
-        return mContinuationToken;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelFeature.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelFeature.java
deleted file mode 100644
index caf3ef2d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelFeature.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.modelprovider;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.common.feedobservable.Observable;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamFeature;
-
-/**
- * This represents a Feature model within the stream tree structure. This represents things such as
- * a Cluster, Carousel, Piet Content, etc. Features provide an {@link ModelCursor} for accessing the
- * children of the feature.
- */
-public interface ModelFeature extends Observable<FeatureChangeObserver> {
-    /**
-     * Returns the {@link StreamFeature} proto instance allowing for access of the metadata and
-     * payload.
-     */
-    StreamFeature getStreamFeature();
-
-    /**
-     * An Cursor over the children of the feature. This Cursor is a one way iterator over the
-     * children. If the feature does not contain children, an empty cursor will be returned.
-     *
-     * <p>Each call to this method will return a new instance of the ModelCursor.
-     */
-    ModelCursor getCursor();
-
-    /**
-     * Create a ModelCursor which advances in the defined direction (forward or reverse), it may
-     * also start at a specific child. If the specified child is not found, this will return {@code
-     * null}. If {@code startingChild} is {@code null}, the cursor starts at the start (beginning or
-     * end) of the child list.
-     */
-    @Nullable
-    ModelCursor getDirectionalCursor(boolean forward, @Nullable String startingChild);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelMutation.java
deleted file mode 100644
index 21eb750..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelMutation.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.modelprovider;
-
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-
-/**
- * Mutation which will batch a set of atomic changes to the Model maintained by the ModelProvider.
- * Order is important, things will be stored in the order they are added to a parent feature.
- */
-public interface ModelMutation {
-    /** Add the structural information to the model as a child */
-    ModelMutation addChild(StreamStructure streamStructure);
-
-    /** Remove the model child defined by the structural information */
-    ModelMutation removeChild(StreamStructure streamStructure);
-
-    /** Content for a child was updated. */
-    ModelMutation updateChild(StreamStructure streamStructure);
-
-    /**
-     * Set the MutationContext used to create the ModelMutation. This may contain the {@link
-     * StreamToken} which represents the source of the response.
-     */
-    ModelMutation setMutationContext(MutationContext mutationContext);
-
-    /** Set the session id of the session backing this ModelProvider. */
-    ModelMutation setSessionId(String sessionId);
-
-    /** Indicates that the SessionManager has cached the payload bindings. */
-    ModelMutation hasCachedBindings(boolean cachedBindings);
-
-    /** Commits the pending changes to the store. */
-    void commit();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelProvider.java
deleted file mode 100644
index 19ac7d24..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelProvider.java
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.modelprovider;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.common.feedobservable.Observable;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-
-import java.util.List;
-
-/**
- * A ModelProvider provides access to the Stream Model for the UI layer. It is populated by the
- * Session Manager. The ModelProvider is backed by a Session instance, there is a one-to-one
- * relationship between the ModelProvider and Session implementation. The Stream Library uses the
- * model to build the UI displayed to the user.
- */
-public interface ModelProvider extends Observable<ModelProviderObserver> {
-    /**
-     * Provides the contentId of the lowest child of the root viewed by the user, or {@code null} if
-     * no content with a ContentId has been seen.
-     */
-    interface ViewDepthProvider {
-        /** Returns a contentId of the lowest root child seen by the user. */
-        @Nullable
-        String getChildViewDepth();
-    }
-
-    /** Returns a Mutator used to change the model. */
-    ModelMutation edit();
-
-    /**
-     * This is called to invalidate the model. The SessionManager calls this to free all resources
-     * held by this ModelProvider instance.
-     */
-    void invalidate();
-
-    /**
-     * This is called to invalidate the model. The SessionManager calls this to free all resources
-     * held by this ModelProvider instance.
-     */
-    void invalidate(UiContext uiContext);
-
-    /**
-     * This is called to detach the ModelProvider from the SessionManager. The Session will continue
-     * to be persisted, but the SessionManager will drop connections to this ModelProvider. The
-     * ModelProvider will enter a {@code State.INVALIDATED}. This will not call the {@link
-     * ModelProviderObserver#onSessionFinished(UiContext)}.
-     */
-    void detachModelProvider();
-
-    /** Used by the session to raises a {@link ModelError} with the ModelProvider. */
-    void raiseError(ModelError error);
-
-    /**
-     * Returns a {@code ModelFeature} which represents the root of the stream tree. Returns {@code
-     * null} if the stream is empty.
-     */
-    @Nullable
-    ModelFeature getRootFeature();
-
-    /** Return a ModelChild for a String ContentId */
-    @Nullable
-    ModelChild getModelChild(String contentId);
-
-    /**
-     * Returns a {@code StreamSharedState} containing shared state such as the Piet shard state.
-     * Returns {@code null} if the shared state is not found.
-     */
-    @Nullable
-    StreamSharedState getSharedState(ContentId contentId);
-
-    /**
-     * Handle the processing of a {@code ModelToken}. For example start a request for the next page
-     * of content. The results of handling the token will be available through Observers on the
-     * ModelToken. Returns {@literal false} if a {@code modelToken} is not recognized and observers
-     * will not be fired.
-     */
-    boolean handleToken(ModelToken modelToken);
-
-    /**
-     * Allow the stream to force a refresh. This will result in the current model being invalidated
-     * if the requested refresh is successful.
-     *
-     * @param requestReason The reason for this refresh.
-     */
-    void triggerRefresh(@RequestReason int requestReason);
-
-    /**
-     * Allow the stream to force a refresh. This will result in the current model being invalidated
-     * if the requested refresh is successful.
-     *
-     * @param requestReason The reason for this refresh.
-     * @param uiContext The {@link UiContext} that caused this mutation. Will be round-tripped to
-     *     {@link ModelProviderObserver#onSessionFinished(UiContext)}
-     */
-    void triggerRefresh(@RequestReason int requestReason, UiContext uiContext);
-
-    /** Defines the Lifecycle of the ModelProvider */
-    @IntDef({State.INITIALIZING, State.READY, State.INVALIDATED})
-    @interface State {
-        /**
-         * State of the Model Provider before it has been fully initialized. The model shouldn't be
-         * accessed before it enters the {@code READY} state. You should register an Observer to
-         * receive an event when the model is ready.
-         */
-        int INITIALIZING = 0;
-        /** State of the Model Provider when it is ready for normal use. */
-        int READY = 1;
-        /**
-         * State of the Model Provider when it has been invalidated. In this mode, the Model is no
-         * longer valid and methods will fail.
-         */
-        int INVALIDATED = 2;
-    }
-
-    /** Returns the current state of the ModelProvider */
-    @State
-    int getCurrentState();
-
-    /** A String which represents the session bound to the ModelProvider. */
-    @Nullable
-    String getSessionId();
-
-    /**
-     * Returns a List of ModelChild for the root. These children may not be bound. This is not
-     * intended to be used by the Stream to access children directly. Instead the ModelCursor should
-     * be used.
-     */
-    List<ModelChild> getAllRootChildren();
-
-    /** Allow the Stream to provide a RemoveTracking based upon mutation context. */
-    interface RemoveTrackingFactory<T> {
-        /**
-         * Returns the {@link RemoveTracking}, if this returns {@code null} then no remove tracking
-         * will be preformed on this ModelProvider mutation.
-         */
-        @Nullable
-        RemoveTracking<T> create(MutationContext mutationContext);
-    }
-
-    /** Called by the stream to set the {@link RemoveTrackingFactory}. */
-    void enableRemoveTracking(RemoveTrackingFactory<?> removeTrackingFactory);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelProviderFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelProviderFactory.java
deleted file mode 100644
index a4349036..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelProviderFactory.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.modelprovider;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider.ViewDepthProvider;
-import org.chromium.chrome.browser.feed.library.common.functional.Predicate;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-
-/** Factory method for creating {@link ModelProvider} instances. */
-public interface ModelProviderFactory {
-    /**
-     * Returns a new instance of a {@link ModelProvider} from an existing session. This session may
-     * become INVALIDATED if the session was garbage collected by the Session Manager.
-     */
-    ModelProvider create(String sessionId, UiContext uiContext);
-
-    /** Returns a new instance of a {@link ModelProvider} from $HEAD. */
-    ModelProvider createNew(@Nullable ViewDepthProvider viewDepthProvider, UiContext uiContext);
-
-    ModelProvider createNew(@Nullable ViewDepthProvider viewDepthProvider,
-            @Nullable Predicate<StreamStructure> filterPredicate, UiContext uiContext);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelProviderObserver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelProviderObserver.java
deleted file mode 100644
index 90f3f7df..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelProviderObserver.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.modelprovider;
-
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-
-/** Interface used to observe events on the {@link ModelProvider}. */
-public interface ModelProviderObserver {
-    /**
-     * This event is triggered when the ModelProvider is fully initialized and it can be accessed by
-     * the UI. If you register for the ModelProvider after the Session is Ready, we will call the
-     * Observer. Otherwise the Observer is called once initialization is finished.
-     */
-    void onSessionStart(UiContext uiContext);
-
-    /**
-     * This event is triggered when the Session is invalidated. Once this is called, the UI should
-     * no longer call this model. The ModelProvider will free all resources assocated with it
-     * including invalidating all existing Cursors.
-     *
-     * @param uiContext If the session is being finished because of the UI, then this will be the
-     *     context given by the UI, otherwise it will be {@link UiContext#getDefaultInstance()}.
-     */
-    void onSessionFinished(UiContext uiContext);
-
-    /**
-     * This is called in the event of an error. For example, if we are making a request and it fails
-     * due to network connectivity issues, this event will indicate the error.
-     */
-    void onError(ModelError modelError);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelToken.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelToken.java
deleted file mode 100644
index 21f2d38e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelToken.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.modelprovider;
-
-import org.chromium.chrome.browser.feed.library.common.feedobservable.Observable;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-
-/** Defines the behavior of a Continuation Token. */
-public interface ModelToken extends Observable<TokenCompletedObserver> {
-    /** Returns the {@link StreamToken} proto instance. */
-    StreamToken getStreamToken();
-
-    /** Returns {@code true} if token was generated on-device and can complete quickly. */
-    boolean isSynthetic();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/RemoveTracking.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/RemoveTracking.java
deleted file mode 100644
index eebfc94..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/RemoveTracking.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.modelprovider;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.Function;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamFeature;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Class which implements the filtering portion of remove tracking. This class creates a {@code
- * List<T>} of items using the {@code filterPredicate} function to both filter and transform a
- * {@link StreamFeature}. The function may return null, these values will be filtered.
- *
- * <p>The {@link #triggerConsumerUpdate()} will call the {@link Consumer}. It will be called when
- * all remove within the ModelProvider mutation have been processed.
- *
- * <p>The {@code Consumer} will be called on the main thread and called once per mutation. In
- * addition, the {@code Consumer} is called before the change operation.
- */
-public final class RemoveTracking<T> {
-    private final Function<StreamFeature, T> mFilterPredicate;
-    private final Consumer<List<T>> mConsumer;
-    private final List<T> mMatchingItems = new ArrayList<>();
-
-    /**
-     * Create the state necessary to call transform and filter the removed subtree before calling
-     * the
-     * {@link Consumer}.
-     */
-    public RemoveTracking(Function<StreamFeature, T> filterPredicate, Consumer<List<T>> consumer) {
-        this.mFilterPredicate = filterPredicate;
-        this.mConsumer = consumer;
-    }
-
-    /**
-     * Called to transform and filter a {@link StreamFeature} found within a subtree being removed.
-     */
-    public void filterStreamFeature(StreamFeature streamFeature) {
-        T value = mFilterPredicate.apply(streamFeature);
-        if (value != null) {
-            mMatchingItems.add(value);
-        }
-    }
-
-    /**
-     * Called on the main thread call the {@link Consumer} after all removes have been processed.
-     */
-    public void triggerConsumerUpdate() {
-        mConsumer.accept(mMatchingItems);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/TokenCompleted.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/TokenCompleted.java
deleted file mode 100644
index 2966948c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/TokenCompleted.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.modelprovider;
-
-/** Defines completion of a continuation token initiated request. */
-public final class TokenCompleted {
-    private final ModelCursor mModelCursor;
-
-    public TokenCompleted(ModelCursor modelCursor) {
-        this.mModelCursor = modelCursor;
-    }
-
-    /**
-     * Returns a cursor representing the continuation from the point in the stream the continuation
-     * token was found.
-     */
-    public ModelCursor getCursor() {
-        return mModelCursor;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/TokenCompletedObserver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/TokenCompletedObserver.java
deleted file mode 100644
index 1b23111b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/TokenCompletedObserver.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.modelprovider;
-
-/** Observes for when the Token fetch completes, producing a new cursor. */
-public interface TokenCompletedObserver {
-    /** Called when the token processing has completed. */
-    void onTokenCompleted(TokenCompleted tokenCompleted);
-
-    /**
-     * This is called in the event of an error. For example, if we are making a pagination request
-     * and it fails due to network connectivity issues, this event will indicate the error.
-     */
-    void onError(ModelError modelError);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/protocoladapter/ProtocolAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/protocoladapter/ProtocolAdapter.java
deleted file mode 100644
index 71080d27..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/protocoladapter/ProtocolAdapter.java
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.protocoladapter;
-
-import org.chromium.chrome.browser.feed.library.api.internal.common.Model;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-import org.chromium.components.feed.core.proto.wire.DataOperationProto.DataOperation;
-import org.chromium.components.feed.core.proto.wire.ResponseProto.Response;
-
-import java.util.List;
-
-/** Converts the wire protocol (protos sent from the server) into an internal representation. */
-public interface ProtocolAdapter {
-    /**
-     * Create the internal protocol from a wire protocol response definition. The wire protocol is
-     * turned into a {@link Model} containing a list of {@link StreamDataOperation}s and a schema
-     * version.
-     */
-    Result<Model> createModel(Response response);
-
-    /**
-     * Create {@link StreamDataOperation}s from the internal protocol for the wire protocol
-     * DataOperations.
-     */
-    List<StreamDataOperation> createOperations(List<DataOperation> dataOperations);
-
-    /**
-     * Convert a wire protocol ContentId into the {@code String} version. Inverse of {@link
-     * #getWireContentId(String)}
-     */
-    String getStreamContentId(ContentId contentId);
-
-    /**
-     * Convert a string ContentId into the wire protocol version. Inverse of {@link
-     * #getStreamContentId(ContentId)}. Note that due to default proto values, if no ID was set in
-     * {@link #getStreamContentId(ContentId)}, this method will set the ID to 0.
-     */
-    Result<ContentId> getWireContentId(String contentId);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/protocoladapter/RequiredContentAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/protocoladapter/RequiredContentAdapter.java
deleted file mode 100644
index 409fb6fa..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/protocoladapter/RequiredContentAdapter.java
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.protocoladapter;
-
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-import org.chromium.components.feed.core.proto.wire.DataOperationProto.DataOperation;
-
-import java.util.List;
-
-/**
- * Interface that creates an extension point where implementers can indicate that a DataOperation is
- * dependent on other content.
- */
-public interface RequiredContentAdapter {
-    List<ContentId> determineRequiredContentIds(DataOperation dataOperation);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/requestmanager/ActionUploadRequestManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/requestmanager/ActionUploadRequestManager.java
deleted file mode 100644
index bb07fab..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/requestmanager/ActionUploadRequestManager.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.requestmanager;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-import org.chromium.components.feed.core.proto.wire.ConsistencyTokenProto.ConsistencyToken;
-
-import java.util.Set;
-
-/** Creates and issues upload action requests to the server. */
-public interface ActionUploadRequestManager {
-    /**
-     * Issues a request to record a set of actions.
-     *
-     * <p>The provided {@code consumer} will be executed on a background thread.
-     */
-    void triggerUploadActions(Set<StreamUploadableAction> actions, ConsistencyToken token,
-            Consumer<Result<ConsistencyToken>> consumer);
-
-    /**
-     * Issues a request to collect all pending actions (such as View actions) and record them.
-     *
-     * <p> The provided {@code consumer} will be executed on a background thread.
-     */
-    void triggerUploadAllActions(
-            ConsistencyToken token, Consumer<Result<ConsistencyToken>> consumer);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/requestmanager/FeedRequestManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/requestmanager/FeedRequestManager.java
deleted file mode 100644
index 7be7ca03..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/requestmanager/FeedRequestManager.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.requestmanager;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.api.internal.common.Model;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-import org.chromium.components.feed.core.proto.wire.ConsistencyTokenProto.ConsistencyToken;
-
-/**
- * Creates and issues requests to the server.
- *
- * <p>Note: this is the internal version of FeedRequestManager. See {@link RequestManager} for the
- * client version.
- */
-public interface FeedRequestManager {
-    /**
-     * Issues a request for the next page of data. The {@code streamToken} described to the server
-     * what the next page means. The{@code token} is used by the server for consistent data across
-     * requests. The response will be sent to a {@link Consumer} with a {@link Model} created by the
-     * ProtocolAdapter.
-     */
-    void loadMore(
-            StreamToken streamToken, ConsistencyToken token, Consumer<Result<Model>> consumer);
-
-    /**
-     * Issues a request to refresh the entire feed, with the consumer being called back with the
-     * resulting {@link Model}.
-     *
-     * @param reason The reason for this refresh.
-     */
-    void triggerRefresh(@RequestReason int reason, Consumer<Result<Model>> consumer);
-
-    /**
-     * Issues a request to refresh the entire feed, with the consumer being called back with the
-     * resulting {@link Model}.
-     *
-     * @param reason The reason for this refresh.
-     * @param token Used by the server for consistent data across requests.
-     * @param consumer The consumer called after the refresh is performed.
-     */
-    void triggerRefresh(
-            @RequestReason int reason, ConsistencyToken token, Consumer<Result<Model>> consumer);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/scope/ClearAllListener.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/scope/ClearAllListener.java
deleted file mode 100644
index b1ec9b63..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/scope/ClearAllListener.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.scope;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.lifecycle.Resettable;
-import org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue.TaskType;
-import org.chromium.chrome.browser.feed.library.common.feedobservable.FeedObservable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.feedapplifecyclelistener.FeedLifecycleListener;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-
-/**
- * This class will implements Clear All in Jardin. It will run all of the clear operations on a
- * single background thread.
- */
-public final class ClearAllListener implements FeedLifecycleListener, Dumpable {
-    private static final String TAG = "ClearAllListener";
-
-    private final TaskQueue mTaskQueue;
-    private final FeedSessionManager mFeedSessionManager;
-    private final @Nullable Resettable mStore;
-    private final ThreadUtils mThreadUtils;
-    private int mClearCount;
-    private int mRefreshCount;
-
-    @SuppressWarnings("argument.type.incompatible") // ok call to registerObserver
-    public ClearAllListener(TaskQueue taskQueue, FeedSessionManager feedSessionManager,
-            @Nullable Resettable store, ThreadUtils threadUtils,
-            FeedObservable<FeedLifecycleListener> lifecycleListenerObservable) {
-        this.mTaskQueue = taskQueue;
-        this.mFeedSessionManager = feedSessionManager;
-        this.mStore = store;
-        this.mThreadUtils = threadUtils;
-
-        lifecycleListenerObservable.registerObserver(this);
-    }
-
-    @Override
-    public void onLifecycleEvent(String event) {
-        switch (event) {
-            case LifecycleEvent.CLEAR_ALL:
-                mTaskQueue.execute(Task.CLEAR_ALL, TaskType.IMMEDIATE, this::clearAll);
-                break;
-            case LifecycleEvent.CLEAR_ALL_WITH_REFRESH:
-                mTaskQueue.execute(
-                        Task.CLEAR_ALL_WITH_REFRESH, TaskType.IMMEDIATE, this::clearAllWithRefresh);
-                break;
-            default:
-                // Do nothing
-        }
-    }
-
-    private void clearAll() {
-        mThreadUtils.checkNotMainThread();
-        mClearCount++;
-
-        Logger.i(TAG, "starting clearAll");
-        // Clear the task queue first, preventing any tasks from running until initialization
-        mTaskQueue.reset();
-        // reset the session state
-        mFeedSessionManager.reset();
-        if (mStore != null) {
-            mStore.reset();
-        }
-        // Initialize the TaskQueue so new tasks will start running
-        mTaskQueue.completeReset();
-    }
-
-    private void clearAllWithRefresh() {
-        mThreadUtils.checkNotMainThread();
-        clearAll();
-        mFeedSessionManager.triggerRefresh(
-                null, RequestReason.CLEAR_ALL, UiContext.getDefaultInstance());
-        mRefreshCount++;
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        dumper.forKey("clearCount").value(mClearCount);
-        dumper.forKey("clearWithRefreshCount").value(mRefreshCount);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/scope/FeedProcessScope.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/scope/FeedProcessScope.java
deleted file mode 100644
index 31850f6..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/scope/FeedProcessScope.java
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.scope;
-
-import android.app.Activity;
-
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.KnownContent;
-import org.chromium.chrome.browser.feed.library.api.client.lifecycle.AppLifecycleListener;
-import org.chromium.chrome.browser.feed.library.api.client.requestmanager.RequestManager;
-import org.chromium.chrome.browser.feed.library.api.client.scope.ProcessScope;
-import org.chromium.chrome.browser.feed.library.api.client.scope.StreamScopeBuilder;
-import org.chromium.chrome.browser.feed.library.api.host.action.ActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.config.ApplicationInfo;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.DebugBehavior;
-import org.chromium.chrome.browser.feed.library.api.host.imageloader.ImageLoaderApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.network.NetworkClient;
-import org.chromium.chrome.browser.feed.library.api.host.offlineindicator.OfflineIndicatorApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.CardConfiguration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.SnackbarApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.StreamConfiguration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipSupportedApi;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.knowncontent.FeedKnownContent;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.protoextensions.FeedExtensionRegistry;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-
-/**
- * Per-process instance of the feed library.
- *
- * <p>It's the host's responsibility to make sure there's only one instance of this per process, per
- * user.
- */
-public final class FeedProcessScope implements ProcessScope {
-    private static final String TAG = "FeedProcessScope";
-
-    private final NetworkClient mNetworkClient;
-    private final ProtocolAdapter mProtocolAdapter;
-    private final RequestManager mRequestManager;
-    private final FeedSessionManager mFeedSessionManager;
-    private final Store mStore;
-    private final TimingUtils mTimingUtils;
-    private final ThreadUtils mThreadUtils;
-    private final TaskQueue mTaskQueue;
-    private final MainThreadRunner mMainThreadRunner;
-    private final AppLifecycleListener mAppLifecycleListener;
-    private final Clock mClock;
-    private final DebugBehavior mDebugBehavior;
-    private final ActionManager mActionManager;
-    private final Configuration mConfiguration;
-    private final FeedKnownContent mFeedKnownContent;
-    private final FeedExtensionRegistry mFeedExtensionRegistry;
-    private final ClearAllListener mClearAllListener;
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final TooltipSupportedApi mTooltipSupportedApi;
-    private final ApplicationInfo mApplicationInfo;
-
-    /** Created through the {@link Builder}. */
-    public FeedProcessScope(BasicLoggingApi basicLoggingApi, NetworkClient networkClient,
-            ProtocolAdapter protocolAdapter, RequestManager requestManager,
-            FeedSessionManager feedSessionManager, Store store, TimingUtils timingUtils,
-            ThreadUtils threadUtils, TaskQueue taskQueue, MainThreadRunner mainThreadRunner,
-            AppLifecycleListener appLifecycleListener, Clock clock, DebugBehavior debugBehavior,
-            ActionManager actionManager, Configuration configuration,
-            FeedKnownContent feedKnownContent, FeedExtensionRegistry feedExtensionRegistry,
-            ClearAllListener clearAllListener, TooltipSupportedApi tooltipSupportedApi,
-            ApplicationInfo applicationInfo) {
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mNetworkClient = networkClient;
-        this.mProtocolAdapter = protocolAdapter;
-        this.mRequestManager = requestManager;
-        this.mFeedSessionManager = feedSessionManager;
-        this.mStore = store;
-        this.mTimingUtils = timingUtils;
-        this.mThreadUtils = threadUtils;
-        this.mTaskQueue = taskQueue;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mAppLifecycleListener = appLifecycleListener;
-        this.mClock = clock;
-        this.mDebugBehavior = debugBehavior;
-        this.mActionManager = actionManager;
-        this.mConfiguration = configuration;
-        this.mFeedKnownContent = feedKnownContent;
-        this.mFeedExtensionRegistry = feedExtensionRegistry;
-        this.mClearAllListener = clearAllListener;
-        this.mTooltipSupportedApi = tooltipSupportedApi;
-        this.mApplicationInfo = applicationInfo;
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        if (mProtocolAdapter instanceof Dumpable) {
-            dumper.dump((Dumpable) mProtocolAdapter);
-        }
-        dumper.dump(mTimingUtils);
-        if (mFeedSessionManager instanceof Dumpable) {
-            dumper.dump((Dumpable) mFeedSessionManager);
-        }
-        if (mStore instanceof Dumpable) {
-            dumper.dump((Dumpable) mStore);
-        }
-        dumper.dump(mClearAllListener);
-    }
-
-    @Override
-    public void onDestroy() {
-        try {
-            Logger.i(TAG, "FeedProcessScope onDestroy called");
-            mNetworkClient.close();
-            mTaskQueue.reset();
-            mTaskQueue.completeReset();
-        } catch (Exception ignored) {
-            // Ignore exception when closing.
-        }
-    }
-
-    @Deprecated
-    public ProtocolAdapter getProtocolAdapter() {
-        return mProtocolAdapter;
-    }
-
-    @Override
-    public RequestManager getRequestManager() {
-        return mRequestManager;
-    }
-
-    @Deprecated
-    public TimingUtils getTimingUtils() {
-        return mTimingUtils;
-    }
-
-    @Override
-    public TaskQueue getTaskQueue() {
-        return mTaskQueue;
-    }
-
-    @Override
-    public AppLifecycleListener getAppLifecycleListener() {
-        return mAppLifecycleListener;
-    }
-
-    @Deprecated
-    public ActionManager getActionManager() {
-        return mActionManager;
-    }
-    @Override
-    public KnownContent getKnownContent() {
-        return mFeedKnownContent;
-    }
-
-    @Deprecated
-    public FeedExtensionRegistry getFeedExtensionRegistry() {
-        return mFeedExtensionRegistry;
-    }
-
-    /**
-     * Return a {@link Builder} to create a FeedProcessScope
-     *
-     * <p>This is called by hosts so it must be public
-     */
-    @Override
-    public StreamScopeBuilder createStreamScopeBuilder(Activity activity,
-            ImageLoaderApi imageLoaderApi, ActionApi actionApi,
-            StreamConfiguration streamConfiguration, CardConfiguration cardConfiguration,
-            SnackbarApi snackbarApi, OfflineIndicatorApi offlineIndicatorApi,
-            TooltipApi tooltipApi) {
-        return new StreamScopeBuilder(activity, actionApi, imageLoaderApi, mProtocolAdapter,
-                mFeedSessionManager, mThreadUtils, mTimingUtils, mTaskQueue, mMainThreadRunner,
-                mClock, mDebugBehavior, streamConfiguration, cardConfiguration, mActionManager,
-                mConfiguration, snackbarApi, mBasicLoggingApi, offlineIndicatorApi,
-                mFeedKnownContent, tooltipApi, mTooltipSupportedApi, mApplicationInfo,
-                mFeedExtensionRegistry);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/scope/FeedStreamScope.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/scope/FeedStreamScope.java
deleted file mode 100644
index 8e33315..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/scope/FeedStreamScope.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.scope;
-
-import org.chromium.chrome.browser.feed.library.api.client.scope.StreamScope;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProviderFactory;
-import org.chromium.chrome.browser.feed.shared.stream.Stream;
-
-/** Per-stream instance of the feed library. */
-public final class FeedStreamScope implements StreamScope {
-    private final Stream mStream;
-    private final ModelProviderFactory mModelProviderFactory;
-
-    public FeedStreamScope(Stream stream, ModelProviderFactory modelProviderFactory) {
-        this.mStream = stream;
-        this.mModelProviderFactory = modelProviderFactory;
-    }
-
-    @Override
-    public Stream getStream() {
-        return mStream;
-    }
-
-    @Override
-    public ModelProviderFactory getModelProviderFactory() {
-        return mModelProviderFactory;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/sessionmanager/FeedSessionManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/sessionmanager/FeedSessionManager.java
deleted file mode 100644
index 3fa0513..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/sessionmanager/FeedSessionManager.java
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.sessionmanager;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.Function;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.KnownContent;
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.api.internal.common.Model;
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.lifecycle.Resettable;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider.ViewDepthProvider;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-import org.chromium.components.feed.core.proto.wire.ConsistencyTokenProto.ConsistencyToken;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * The FeedSessionManager is responsible for creating and updating. A session has a one-to-one
- * relationship with a ModelProvider. The FeedSessionManager implements the session functionality
- * and management.
- */
-public interface FeedSessionManager extends Resettable {
-    /**
-     * This is called by the UI to get a new session. The life of the session is controlled by the
-     * Session manager. The FeedSessionManager maintains HEAD$ which represents the most current
-     * state of the stream. It will also decide which changes should be made to existing sessions
-     * and the life time of existing sessions.
-     */
-    void getNewSession(ModelProvider modelProvider, @Nullable ViewDepthProvider viewDepthProvider,
-            UiContext uiContext);
-
-    /**
-     * Create a new Session attached to the ModelProvider for an existing sessionId. This will
-     * invalidate any existing ModelProvider instances attached to the session.
-     */
-    void getExistingSession(String sessionId, ModelProvider modelProvider, UiContext uiContext);
-
-    /** This is called by the ModelProvider when it is invalidated. */
-    void invalidateSession(String sessionId);
-
-    /** This is called by the ModelProvider to detach the ModelProvider for the session. */
-    void detachSession(String sessionId);
-
-    /**
-     * This method will invalidate head. All {@link #getNewSession(ModelProvider, ViewDepthProvider,
-     * UiContext)} will block until a new a response updates the FeedSessionManager providing the
-     * new head.
-     */
-    void invalidateHead();
-
-    /**
-     * Method which causes a request to be created for the next page of content based upon the
-     * continuation token. This could be called from multiple Model Providers.
-     */
-    void handleToken(String sessionId, StreamToken streamToken);
-
-    /** Method which causes a refresh */
-    void triggerRefresh(@Nullable String sessionId);
-
-    /**
-     * Method which causes a refresh
-     *
-     * @param sessionId The session id associated with the request.
-     * @param requestReason The reason for triggering a refresh.
-     * @param uiContext The UI only context for the refresh.
-     */
-    void triggerRefresh(
-            @Nullable String sessionId, @RequestReason int requestReason, UiContext uiContext);
-
-    /**
-     * Returns a List of {@link StreamPayload} for each of the keys. This must be called on the
-     * background thread.
-     */
-    Result<List<PayloadWithId>> getStreamFeatures(List<String> contentIds);
-
-    /**
-     * Return the shared state. This operation will be fast, so it can be called on the UI Thread.
-     * This method will return {@code null} if the shared state is not found.
-     */
-    @Nullable
-    StreamSharedState getSharedState(ContentId contentId);
-
-    /**
-     * Create a filtered {@link List} of {@code T} objects and return it through the {@link
-     * Consumer}. The {@code filterPredicate} function will be applied to each node in the
-     * structured tree defined by $HEAD. The method acts as both a transformer to create type {@code
-     * T} and as a filter over the input {@link StreamPayload}. If {@code filterPredicate} returns
-     * {@code null}, the value will not be added to the filtered list. This is an expensive
-     * operation and will run on a background thread.
-     */
-    <T> void getStreamFeaturesFromHead(
-            Function<StreamPayload, T> filterPredicate, Consumer<Result<List<T>>> consumer);
-
-    /** Sets {@link KnownContentListener} to allow for informing host of when content is added. */
-    void setKnownContentListener(KnownContent.Listener knownContentListener);
-
-    /**
-     * Issues a request to record a set of actions, with the consumer being called back with the
-     * resulting {@link ConsistencyToken}.
-     */
-    void triggerUploadActions(Set<StreamUploadableAction> actions);
-
-    /**
-     * Issues a request to record a set of actions, with the consumer being called back with the
-     * resulting {@link ConsistencyToken}.
-     */
-    void fetchActionsAndUpload(Consumer<Result<ConsistencyToken>> consumer);
-
-    /**
-     * Return a {@link Consumer} which is able to handle an update to the SessionManager. An update
-     * consists of {@link Model} containing a list of {@link StreamDataOperation} objects. The
-     * {@link MutationContext} captures the context which is initiating the update operation.
-     */
-    Consumer<Result<Model>> getUpdateConsumer(MutationContext mutationContext);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/ContentMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/ContentMutation.java
deleted file mode 100644
index 1d74136..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/ContentMutation.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.store;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-
-/**
- * Mutation for adding and updating Content in the Feed Store. Remove will be handled by a task
- * which garbage collects the content that is not longer defined in any sessions.
- */
-public interface ContentMutation {
-    /** Add a new Mutation to the Store */
-    ContentMutation add(String contentId, StreamPayload payload);
-
-    /** Commit the mutations to the backing store */
-    CommitResult commit();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/LocalActionMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/LocalActionMutation.java
deleted file mode 100644
index e9fe0f4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/LocalActionMutation.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.store;
-
-import androidx.annotation.IntDef;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-
-/** Mutation for adding and updating actions in the Feed Store. */
-public interface LocalActionMutation {
-    @IntDef({ActionType.DISMISS})
-    @interface ActionType {
-        int DISMISS = 1;
-    }
-
-    /** Add a new Mutation to the Store */
-    LocalActionMutation add(@ActionType int action, String contentId);
-
-    /** Commit the mutations to the backing store */
-    CommitResult commit();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/SemanticPropertiesMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/SemanticPropertiesMutation.java
deleted file mode 100644
index dacd078..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/SemanticPropertiesMutation.java
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.store;
-
-import com.google.protobuf.ByteString;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-
-/** Used to commit mutations to semantic properties data within the {@link Store} */
-public interface SemanticPropertiesMutation {
-    /** Add a new semantic properties mutation */
-    SemanticPropertiesMutation add(String contentId, ByteString semanticData);
-
-    /** Commit the current mutations */
-    CommitResult commit();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/SessionMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/SessionMutation.java
deleted file mode 100644
index 6fe0e09..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/SessionMutation.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.store;
-
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-
-/** A structural mutation against a session. */
-public interface SessionMutation {
-    /** Add or update a structure in the store. */
-    SessionMutation add(StreamStructure streamStructure);
-
-    /** Commit the mutations to the backing store */
-    Boolean commit();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/Store.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/Store.java
deleted file mode 100644
index c5f0a8c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/Store.java
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.store;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.common.SemanticPropertiesWithId;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.feedobservable.Observable;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamLocalAction;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * Interface defining the Store API used by the feed library to persist the internal proto objects
- * into a an underlying store. The store is divided into content and structure portions. Content is
- * retrieved using String representing the {@code ContentId}. The structure is defined through a set
- * of {@link StreamDataOperation} which define the structure of the stream. $HEAD defines the full
- * set of {@code StreamDataOperation}s defining the full stream. A {@link
- * org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSession}
- * represents an instance of the stream defined by a possible subset of $HEAD.
- *
- * <p>This object should not be used on the UI thread, as it may block on slow IO operations.
- */
-public interface Store extends Observable<StoreListener> {
-    /** The session id representing $HEAD */
-    String HEAD_SESSION_ID = "$HEAD";
-
-    /**
-     * Returns an {@code List} of the {@link PayloadWithId}s for the ContentId Strings passed in
-     * through {@code contentIds}.
-     */
-    Result<List<PayloadWithId>> getPayloads(List<String> contentIds);
-
-    /** Get the {@link StreamSharedState}s stored as content. */
-    Result<List<StreamSharedState>> getSharedStates();
-
-    /**
-     * Returns a list of all {@link StreamStructure}s for the session. The Stream Structure does not
-     * contain the content. This represents the full structure of the stream for a particular
-     * session.
-     */
-    Result<List<StreamStructure>> getStreamStructures(String sessionId);
-
-    /** Returns a list of all the session ids, excluding the $HEAD session. */
-    Result<List<String>> getAllSessions();
-
-    /** Gets all semantic properties objects associated with a given list of contentIds */
-    Result<List<SemanticPropertiesWithId>> getSemanticProperties(List<String> contentIds);
-
-    /**
-     * Gets an set of ALL {@link UploadableStreamAction}. Note that this includes expired actions.
-     */
-    Result<Set<StreamUploadableAction>> getAllUploadableActions();
-
-    /**
-     * Gets an increasing, time-ordered list of ALL {@link StreamLocalAction} dismisses. Note that
-     * this includes expired actions.
-     */
-    Result<List<StreamLocalAction>> getAllDismissLocalActions();
-
-    /**
-     * Create a new session and return the id. The session is defined by all the {@link
-     * StreamDataOperation}s which are currently stored in $HEAD.
-     */
-    Result<String> createNewSession();
-
-    /** Remove a specific session. It is illegal to attempt to remove $HEAD. */
-    void removeSession(String sessionId);
-
-    /**
-     * Clears out all data operations defining $HEAD. Only $HEAD supports reset, all other session
-     * may not be reset. Instead they should be invalidated and removed, then a new session is
-     * created from $HEAD.
-     */
-    void clearHead();
-
-    /** Returns a mutation used to modify the content in the persistent store. */
-    ContentMutation editContent();
-
-    /** Returns a session mutation applied to a Session. */
-    SessionMutation editSession(String sessionId);
-
-    /** Returns a semantic properties mutation used to modify the properties in the store */
-    SemanticPropertiesMutation editSemanticProperties();
-
-    /** Returns an action mutation used to modify actions in the store */
-    LocalActionMutation editLocalActions();
-
-    /** Returns an action mutation used to modify uploadable actions in the store */
-    UploadableActionMutation editUploadableActions();
-
-    /**
-     * Returns a runnable which will garbage collect the persisted content. This is called by the
-     * SessionManager which controls the scheduling of cleanup tasks.
-     */
-    Runnable triggerContentGc(Set<String> reservedContentIds,
-            Supplier<Set<String>> accessibleContent, boolean keepSharedStates);
-
-    /**
-     * Returns a runnable that will garbage collect actions. All valid actions will be copied over
-     * to a new copy of the journal.
-     */
-    Runnable triggerLocalActionGc(List<StreamLocalAction> actions, List<String> validContentIds);
-
-    /**
-     * Switches to an ephemeral version of the store. Ephemeral mode of the store should run in
-     * memory and not attempt to write to disk.
-     */
-    void switchToEphemeralMode();
-
-    /** Whether the store is in ephemeral mode */
-    boolean isEphemeralMode();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/StoreListener.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/StoreListener.java
deleted file mode 100644
index 3fb01e6..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/StoreListener.java
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.store;
-
-/** Allows classes to listen to changes to {@link Store} */
-public interface StoreListener {
-    /**
-     * Called when {@link Store} switches to ephemeral mode. This will be called on a background
-     * thread.
-     */
-    void onSwitchToEphemeralMode();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/UploadableActionMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/UploadableActionMutation.java
deleted file mode 100644
index 843286a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/UploadableActionMutation.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.store;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-
-/** Mutation for adding and updating uploadable actions in the Feed Store. */
-public interface UploadableActionMutation {
-    /** Upsert a new Mutation to the Store */
-    UploadableActionMutation upsert(StreamUploadableAction action, String contentId);
-
-    /** Remove Mutation from the Store */
-    UploadableActionMutation remove(StreamUploadableAction action, String contentId);
-
-    /** Commit the mutations to the backing store */
-    CommitResult commit();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/stream/BasicStreamFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/stream/BasicStreamFactory.java
deleted file mode 100644
index 5baeca5..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/stream/BasicStreamFactory.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.stream;
-
-import android.content.Context;
-
-import org.chromium.chrome.browser.feed.library.api.host.action.ActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.config.ApplicationInfo.BuildType;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.DebugBehavior;
-import org.chromium.chrome.browser.feed.library.api.host.imageloader.ImageLoaderApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.offlineindicator.OfflineIndicatorApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.CardConfiguration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.SnackbarApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.StreamConfiguration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipApi;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionParserFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.knowncontent.FeedKnownContent;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProviderFactory;
-import org.chromium.chrome.browser.feed.library.basicstream.BasicStream;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.protoextensions.FeedExtensionRegistry;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.piet.host.CustomElementProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.HostBindingProvider;
-import org.chromium.chrome.browser.feed.shared.stream.Stream;
-
-import java.util.ArrayList;
-
-/** Factory to create {@link BasicStream} classes */
-public class BasicStreamFactory implements StreamFactory {
-    @Override
-    public Stream build(ActionParserFactory actionParserFactory, Context context,
-            @BuildType int buildType, CardConfiguration cardConfiguration,
-            ImageLoaderApi imageLoaderApi, CustomElementProvider customElementProvider,
-            DebugBehavior debugBehavior, Clock clock, ModelProviderFactory modelProviderFactory,
-            HostBindingProvider hostBindingProvider, OfflineIndicatorApi offlineIndicatorApi,
-            Configuration configuration, ActionApi actionApi, ActionManager actionManager,
-            SnackbarApi snackbarApi, StreamConfiguration streamConfiguration,
-            FeedExtensionRegistry feedExtensionRegistry, BasicLoggingApi basicLoggingApi,
-            MainThreadRunner mainThreadRunner, boolean isBackgroundDark, TooltipApi tooltipApi,
-            ThreadUtils threadUtils, FeedKnownContent feedKnownContent,
-            boolean isPlaceholderShown) {
-        return new BasicStream(context, streamConfiguration, cardConfiguration, imageLoaderApi,
-                actionParserFactory, actionApi, customElementProvider, debugBehavior, threadUtils,
-                /* headers = */ new ArrayList<>(0), clock, modelProviderFactory,
-                hostBindingProvider, actionManager, configuration, snackbarApi, basicLoggingApi,
-                offlineIndicatorApi, mainThreadRunner, feedKnownContent, tooltipApi,
-                isBackgroundDark, isPlaceholderShown);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/stream/StreamFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/stream/StreamFactory.java
deleted file mode 100644
index e2644f4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/stream/StreamFactory.java
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.api.internal.stream;
-
-import android.content.Context;
-
-import org.chromium.chrome.browser.feed.library.api.host.action.ActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.config.ApplicationInfo.BuildType;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.DebugBehavior;
-import org.chromium.chrome.browser.feed.library.api.host.imageloader.ImageLoaderApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.offlineindicator.OfflineIndicatorApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.CardConfiguration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.SnackbarApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.StreamConfiguration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipApi;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionParserFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.knowncontent.FeedKnownContent;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProviderFactory;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.protoextensions.FeedExtensionRegistry;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.piet.host.CustomElementProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.HostBindingProvider;
-import org.chromium.chrome.browser.feed.shared.stream.Stream;
-
-/** Factory to allow creation of {@link Stream} instances that depend on common components. */
-public interface StreamFactory {
-    /** Create the {@link Stream} */
-    Stream build(ActionParserFactory actionParserFactory, Context context, @BuildType int buildType,
-            CardConfiguration cardConfiguration, ImageLoaderApi imageLoaderApi,
-            CustomElementProvider customElementProvider, DebugBehavior debugBehavior, Clock clock,
-            ModelProviderFactory modelProviderFactory, HostBindingProvider hostBindingProvider,
-            OfflineIndicatorApi offlineIndicatorApi, Configuration configuration,
-            ActionApi actionApi, ActionManager actionManager, SnackbarApi snackbarApi,
-            StreamConfiguration streamConfiguration, FeedExtensionRegistry feedExtensionRegistry,
-            BasicLoggingApi basicLoggingApi, MainThreadRunner mainThreadRunner,
-            boolean isBackgroundDark, TooltipApi tooltipApi, ThreadUtils threadUtils,
-            FeedKnownContent feedKnownContent, boolean isPlaceholderShown);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/BasicStream.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/BasicStream.java
deleted file mode 100644
index 8a30006..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/BasicStream.java
+++ /dev/null
@@ -1,854 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream;
-
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Build.VERSION;
-import android.os.Build.VERSION_CODES;
-import android.util.Base64;
-import android.util.TypedValue;
-import android.view.ContextThemeWrapper;
-import android.view.View;
-import android.view.View.OnLayoutChangeListener;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.recyclerview.widget.ItemTouchHelper;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.library.api.host.action.ActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.feed.library.api.host.config.DebugBehavior;
-import org.chromium.chrome.browser.feed.library.api.host.imageloader.ImageLoaderApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ZeroStateShowReason;
-import org.chromium.chrome.browser.feed.library.api.host.offlineindicator.OfflineIndicatorApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.CardConfiguration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.SnackbarApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.StreamConfiguration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipApi;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionParserFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.knowncontent.FeedKnownContent;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelError;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelError.ErrorType;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider.State;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProviderFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProviderObserver;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.StreamItemAnimator;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.StreamItemTouchCallbacks;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.StreamRecyclerViewAdapter;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.drivers.StreamDriver;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.scroll.BasicStreamScrollMonitor;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.scroll.ScrollRestorer;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.PietViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewloggingupdater.ViewLoggingUpdater;
-import org.chromium.chrome.browser.feed.library.common.concurrent.CancelableTask;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.functional.Suppliers;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.piet.PietManager;
-import org.chromium.chrome.browser.feed.library.piet.host.CustomElementProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.HostBindingProvider;
-import org.chromium.chrome.browser.feed.library.sharedstream.contentchanged.StreamContentChangedListener;
-import org.chromium.chrome.browser.feed.library.sharedstream.contextmenumanager.ContextMenuManager;
-import org.chromium.chrome.browser.feed.library.sharedstream.contextmenumanager.ContextMenuManagerImpl;
-import org.chromium.chrome.browser.feed.library.sharedstream.contextmenumanager.FloatingContextMenuManager;
-import org.chromium.chrome.browser.feed.library.sharedstream.deepestcontenttracker.DeepestContentTracker;
-import org.chromium.chrome.browser.feed.library.sharedstream.logging.UiSessionRequestLogger;
-import org.chromium.chrome.browser.feed.library.sharedstream.offlinemonitor.StreamOfflineMonitor;
-import org.chromium.chrome.browser.feed.library.sharedstream.piet.PietCustomElementProvider;
-import org.chromium.chrome.browser.feed.library.sharedstream.piet.PietEventLogger;
-import org.chromium.chrome.browser.feed.library.sharedstream.piet.PietHostBindingProvider;
-import org.chromium.chrome.browser.feed.library.sharedstream.piet.PietImageLoader;
-import org.chromium.chrome.browser.feed.library.sharedstream.piet.PietStringFormatter;
-import org.chromium.chrome.browser.feed.library.sharedstream.publicapi.menumeasurer.MenuMeasurer;
-import org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll.ScrollObservable;
-import org.chromium.chrome.browser.feed.library.sharedstream.scroll.ScrollListenerNotifier;
-import org.chromium.chrome.browser.feed.shared.stream.Header;
-import org.chromium.chrome.browser.feed.shared.stream.Stream;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.preferences.Pref;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-import org.chromium.components.feed.core.proto.libraries.basicstream.internal.StreamSavedInstanceStateProto.StreamSavedInstanceState;
-import org.chromium.components.feed.core.proto.libraries.sharedstream.ScrollStateProto.ScrollState;
-import org.chromium.components.feed.core.proto.libraries.sharedstream.UiRefreshReasonProto.UiRefreshReason;
-import org.chromium.components.user_prefs.UserPrefs;
-
-import java.util.List;
-
-/**
- * A basic implementation of a Feed {@link Stream} that is just able to render a vertical stream of
- * cards.
- */
-public class BasicStream implements Stream, ModelProviderObserver, OnLayoutChangeListener {
-    private static final String TAG = "BasicStream";
-
-    private static final long DEFAULT_LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS = 1000L;
-    private static final long DEFAULT_MINIMUM_SPINNER_SHOW_TIME_MS = 500L;
-    private static final long DEFAULT_SPINNER_DELAY_TIME_MS = 500L;
-    // The height of dense Feed article card is always 157dp based on the Feed Piet templates which
-    // are server-driven and may change later.
-    private static final int FEED_CARD_HEIGHT_DENSE_PX = dpToPx(157);
-
-    private final CardConfiguration mCardConfiguration;
-    private final Clock mClock;
-    private final Context mContext;
-    private final ThreadUtils mThreadUtils;
-    private final PietManager mPietManager;
-    private final ModelProviderFactory mModelProviderFactory;
-    private final ActionParserFactory mActionParserFactory;
-    private final ActionApi mActionApi;
-    private final ActionManager mActionManager;
-    private final Configuration mConfiguration;
-    private final SnackbarApi mSnackbarApi;
-    private final StreamContentChangedListener mStreamContentChangedListener;
-    private final DeepestContentTracker mDeepestContentTracker;
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final long mImmediateContentThreshold;
-    private final StreamOfflineMonitor mStreamOfflineMonitor;
-    private final MainThreadRunner mMainThreadRunner;
-    private final FeedKnownContent mFeedKnownContent;
-    private final ViewLoggingUpdater mViewLoggingUpdater;
-    private final TooltipApi mTooltipApi;
-    private final UiSessionRequestLogger mUiSessionRequestLogger;
-    private final StreamConfiguration mStreamConfiguration;
-    private final BasicStreamScrollMonitor mScrollMonitor;
-    private final long mMinimumSpinnerShowTime;
-    private final long mSpinnerDelayTime;
-
-    private RecyclerView mRecyclerView;
-    private ContextMenuManager mContextMenuManager;
-    private List<Header> mHeaders;
-    private StreamRecyclerViewAdapter mAdapter;
-    private ScrollListenerNotifier mScrollListenerNotifier;
-    private ScrollRestorer mScrollRestorer;
-    private long mSessionStartTimestamp;
-    private long mInitialLoadingSpinnerStartTime;
-    private boolean mIsInitialLoad = true;
-    private boolean mIsRestoring;
-    private boolean mIsDestroyed;
-    private boolean mIsStreamContentVisible = true;
-    private boolean mIsPlaceholderShown;
-
-    @LoggingState
-    private int mLoggingState = LoggingState.STARTING;
-
-    private ModelProvider mModelProvider;
-    private StreamDriver mStreamDriver;
-
-    @Nullable
-    private String mSavedSessionId;
-    @Nullable
-    private CancelableTask mCancellableShowSpinnerRunnable;
-
-    // TODO: instead of using a nullable field, pipe UiContext through the creation of
-    // ModelProviders to onSessionStart().
-    private UiRefreshReason mUiRefreshReason = UiRefreshReason.getDefaultInstance();
-    private StreamItemAnimator mItemAnimator;
-
-    public BasicStream(Context context, StreamConfiguration streamConfiguration,
-            CardConfiguration cardConfiguration, ImageLoaderApi imageLoaderApi,
-            ActionParserFactory actionParserFactory, ActionApi actionApi,
-            @Nullable CustomElementProvider customElementProvider, DebugBehavior debugBehavior,
-            ThreadUtils threadUtils, List<Header> headers, Clock clock,
-            ModelProviderFactory modelProviderFactory,
-            @Nullable HostBindingProvider hostBindingProvider, ActionManager actionManager,
-            Configuration configuration, SnackbarApi snackbarApi, BasicLoggingApi basicLoggingApi,
-            OfflineIndicatorApi offlineIndicatorApi, MainThreadRunner mainThreadRunner,
-            FeedKnownContent feedKnownContent, TooltipApi tooltipApi, boolean isBackgroundDark,
-            boolean isPlaceholderShown) {
-        this.mCardConfiguration = cardConfiguration;
-        this.mClock = clock;
-        this.mThreadUtils = threadUtils;
-        this.mStreamOfflineMonitor = new StreamOfflineMonitor(offlineIndicatorApi);
-        this.mHeaders = headers;
-        this.mModelProviderFactory = modelProviderFactory;
-        this.mStreamConfiguration = streamConfiguration;
-        this.mActionParserFactory = actionParserFactory;
-        this.mActionApi = actionApi;
-        this.mActionManager = actionManager;
-        this.mConfiguration = configuration;
-        this.mSnackbarApi = snackbarApi;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mStreamContentChangedListener = createStreamContentChangedListener();
-        this.mDeepestContentTracker = new DeepestContentTracker();
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mImmediateContentThreshold =
-                configuration.getValueOrDefault(ConfigKey.LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS,
-                        DEFAULT_LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS);
-        this.mFeedKnownContent = feedKnownContent;
-        mViewLoggingUpdater = createViewLoggingUpdater();
-        this.mUiSessionRequestLogger = new UiSessionRequestLogger(clock, basicLoggingApi);
-        this.mTooltipApi = tooltipApi;
-        this.mPietManager = createPietManager(context, cardConfiguration, imageLoaderApi,
-                customElementProvider, debugBehavior, clock, hostBindingProvider,
-                mStreamOfflineMonitor, configuration, isBackgroundDark);
-        this.mContext =
-                new ContextThemeWrapper(context, (isBackgroundDark ? R.style.Dark : R.style.Light));
-        this.mScrollMonitor = new BasicStreamScrollMonitor(clock);
-        this.mMinimumSpinnerShowTime = configuration.getValueOrDefault(
-                ConfigKey.SPINNER_MINIMUM_SHOW_TIME_MS, DEFAULT_MINIMUM_SPINNER_SHOW_TIME_MS);
-        this.mSpinnerDelayTime = configuration.getValueOrDefault(
-                ConfigKey.SPINNER_DELAY_MS, DEFAULT_SPINNER_DELAY_TIME_MS);
-        this.mIsPlaceholderShown = isPlaceholderShown;
-    }
-
-    @VisibleForTesting
-    PietManager createPietManager(Context context, CardConfiguration cardConfiguration,
-            ImageLoaderApi imageLoaderApi, @Nullable CustomElementProvider customElementProvider,
-            DebugBehavior debugBehavior, Clock clock,
-            @Nullable HostBindingProvider hostBindingProvider,
-            StreamOfflineMonitor streamOfflineMonitor, Configuration configuration,
-            boolean isBackgroundDark) {
-        return PietManager.builder()
-                .setImageLoader(new PietImageLoader(imageLoaderApi))
-                .setStringFormatter(new PietStringFormatter(clock))
-                .setFadeImageThresholdMs(Suppliers.of(
-                        configuration.getValueOrDefault(ConfigKey.FADE_IMAGE_THRESHOLD_MS, 80L)))
-                .setDefaultCornerRadius(() -> cardConfiguration.getDefaultCornerRadius())
-                .setDebugBehavior(debugBehavior)
-                .setCustomElementProvider(
-                        new PietCustomElementProvider(context, customElementProvider))
-                .setHostBindingProvider(
-                        new PietHostBindingProvider(hostBindingProvider, streamOfflineMonitor))
-                .setClock(clock)
-                .setIsDarkTheme(Suppliers.of(isBackgroundDark))
-                .build();
-    }
-
-    @Override
-    public void onCreate(@Nullable String savedInstanceState) {
-        checkState(mRecyclerView == null, "Can't call onCreate() multiple times.");
-        setupRecyclerView();
-
-        if (savedInstanceState == null) {
-            mScrollRestorer = createScrollRestorer(
-                    mConfiguration, mRecyclerView, mScrollListenerNotifier, null);
-            return;
-        }
-
-        try {
-            StreamSavedInstanceState streamSavedInstanceState = StreamSavedInstanceState.parseFrom(
-                    Base64.decode(savedInstanceState, Base64.DEFAULT));
-
-            if (streamSavedInstanceState.hasSessionId()) {
-                mSavedSessionId = streamSavedInstanceState.getSessionId();
-            }
-
-            mScrollRestorer = createScrollRestorer(mConfiguration, mRecyclerView,
-                    mScrollListenerNotifier, streamSavedInstanceState.getScrollState());
-        } catch (IllegalArgumentException | InvalidProtocolBufferException e) {
-            Logger.wtf(TAG, "Could not parse saved instance state String.");
-            mScrollRestorer = createScrollRestorer(
-                    mConfiguration, mRecyclerView, mScrollListenerNotifier, null);
-        }
-    }
-
-    @Override
-    public void onShow() {
-        // Only create model provider if Stream content is visible.
-        if (mIsStreamContentVisible) {
-            createModelProviderAndStreamDriver();
-        } else {
-            if (mLoggingState == LoggingState.STARTING) {
-                mBasicLoggingApi.onOpenedWithNoContent();
-                mLoggingState = LoggingState.LOGGED_NO_CONTENT;
-            }
-
-            // If Stream content is not visible, we will not create the StreamDriver and restore the
-            // scroll position automatically. So we try to restore the scroll position before.
-            mScrollRestorer.maybeRestoreScroll();
-        }
-        mAdapter.setShown(true);
-        mActionManager.onShow();
-    }
-
-    @Override
-    public void onHide() {
-        mAdapter.setShown(false);
-        mContextMenuManager.dismissPopup();
-        mActionManager.onHide();
-    }
-
-    @Override
-    public void onDestroy() {
-        if (mIsDestroyed) {
-            Logger.e(TAG, "onDestroy() called multiple times.");
-            return;
-        }
-        mAdapter.onDestroy();
-        mRecyclerView.removeOnLayoutChangeListener(this);
-        if (mModelProvider != null) {
-            mModelProvider.unregisterObserver(this);
-            mModelProvider.detachModelProvider();
-        }
-        if (mStreamDriver != null) {
-            mStreamDriver.onDestroy();
-        }
-        mStreamOfflineMonitor.onDestroy();
-        mUiSessionRequestLogger.onDestroy();
-        mActionManager.setViewport(null);
-        mActionManager.setCanUploadClicksAndViewsWhenNoticeCardIsPresent(canUpload());
-        mIsDestroyed = true;
-    }
-
-    @Override
-    public String getSavedInstanceStateString() {
-        StreamSavedInstanceState.Builder builder = StreamSavedInstanceState.newBuilder();
-        if (mModelProvider != null && mModelProvider.getSessionId() != null) {
-            builder.setSessionId(checkNotNull(mModelProvider.getSessionId()));
-        }
-
-        ScrollState scrollState =
-                mScrollRestorer.getScrollStateForScrollRestore(mAdapter.getHeaderCount());
-        if (scrollState != null) {
-            builder.setScrollState(scrollState);
-        }
-
-        return convertStreamSavedInstanceStateToString(builder.build());
-    }
-
-    @Override
-    public View getView() {
-        checkState(mRecyclerView != null, "Must call onCreate() before getView()");
-        return mRecyclerView;
-    }
-
-    @VisibleForTesting
-    StreamRecyclerViewAdapter getAdapter() {
-        return mAdapter;
-    }
-
-    @Override
-    public void setHeaderViews(List<Header> headers) {
-        Logger.i(TAG, "Setting %s header views, currently have %s headers", headers.size(),
-                this.mHeaders.size());
-
-        this.mHeaders = headers;
-        mAdapter.setHeaders(headers);
-    }
-
-    @Override
-    public void setStreamContentVisibility(boolean visible) {
-        checkNotNull(mAdapter, "onCreate must be called before setStreamContentVisibility");
-
-        if (visible == mIsStreamContentVisible) {
-            return;
-        }
-
-        mIsStreamContentVisible = visible;
-
-        if (mIsStreamContentVisible) {
-            mViewLoggingUpdater.resetViewTracking();
-        }
-
-        // If Stream content was previously not visible, ModelProvider might need to be created.
-        if (mIsStreamContentVisible && mModelProvider == null) {
-            createModelProviderAndStreamDriver();
-        }
-
-        mItemAnimator.setStreamVisibility(mIsStreamContentVisible);
-        mAdapter.setStreamContentVisible(mIsStreamContentVisible);
-    }
-
-    @Override
-    public void trim() {
-        mPietManager.purgeRecyclerPools();
-        mRecyclerView.getRecycledViewPool().clear();
-    }
-
-    @Override
-    public void smoothScrollBy(int dx, int dy) {
-        mRecyclerView.smoothScrollBy(dx, dy);
-    }
-
-    @Override
-    public int getChildTopAt(int position) {
-        if (!isChildAtPositionVisible(position)) {
-            return POSITION_NOT_KNOWN;
-        }
-
-        LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
-        if (layoutManager == null) {
-            return POSITION_NOT_KNOWN;
-        }
-
-        View view = layoutManager.findViewByPosition(position);
-        if (view == null) {
-            return POSITION_NOT_KNOWN;
-        }
-
-        return view.getTop();
-    }
-
-    @Override
-    public boolean isChildAtPositionVisible(int position) {
-        LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
-        if (layoutManager == null) {
-            return false;
-        }
-
-        int firstItemPosition = layoutManager.findFirstVisibleItemPosition();
-        int lastItemPosition = layoutManager.findLastVisibleItemPosition();
-        if (firstItemPosition == RecyclerView.NO_POSITION
-                || lastItemPosition == RecyclerView.NO_POSITION) {
-            return false;
-        }
-
-        return position >= firstItemPosition && position <= lastItemPosition;
-    }
-
-    @Override
-    public void addScrollListener(ScrollListener listener) {
-        mScrollListenerNotifier.addScrollListener(listener);
-    }
-
-    @Override
-    public void removeScrollListener(ScrollListener listener) {
-        mScrollListenerNotifier.removeScrollListener(listener);
-    }
-
-    @Override
-    public void addOnContentChangedListener(ContentChangedListener listener) {
-        mStreamContentChangedListener.addContentChangedListener(listener);
-    }
-
-    @Override
-    public void removeOnContentChangedListener(ContentChangedListener listener) {
-        mStreamContentChangedListener.removeContentChangedListener(listener);
-    }
-
-    @Override
-    public void triggerRefresh() {
-        if (mStreamDriver == null || mModelProvider == null) {
-            Logger.w(TAG,
-                    "Refresh requested before Stream was shown.  Scheduler should be used instead "
-                            + "in this instance.");
-            return;
-        }
-
-        // This invalidates the mModelProvider, which results in onSessionFinished() then
-        // onSessionStart() being called, leading to recreating the entire stream.
-        mStreamDriver.showSpinner();
-        mModelProvider.triggerRefresh(RequestReason.HOST_REQUESTED);
-    }
-
-    @Override
-    public boolean isPlaceholderShown() {
-        return mIsPlaceholderShown;
-    }
-
-    @Override
-    public void hidePlaceholder() {
-        mRecyclerView.getBackground().setAlpha(255);
-        mIsPlaceholderShown = false;
-    }
-
-    @Override
-    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
-            int oldTop, int oldRight, int oldBottom) {
-        if ((oldLeft != 0 && left != oldLeft) || (oldRight != 0 && right != oldRight)) {
-            checkNotNull(mAdapter, "onCreate must be called before so that adapter is set.")
-                    .rebind();
-        }
-        mContextMenuManager.dismissPopup();
-        mActionManager.onLayoutChange();
-    }
-
-    @Override
-    public int getFirstCardDensity() {
-        if (mContext.getResources().getConfiguration().orientation == ORIENTATION_PORTRAIT) {
-            RecyclerView.ViewHolder firstArticleCard =
-                    mRecyclerView.findViewHolderForAdapterPosition(mHeaders.size());
-            for (int i = mHeaders.size();
-                    firstArticleCard != null && !(firstArticleCard instanceof PietViewHolder);
-                    i++) {
-                firstArticleCard = mRecyclerView.findViewHolderForAdapterPosition(i);
-            }
-            if (firstArticleCard != null) {
-                int firstCardHeight = firstArticleCard.itemView.getHeight();
-                return firstCardHeight <= FEED_CARD_HEIGHT_DENSE_PX
-                        ? FeedFirstCardDensity.DENSE
-                        : FeedFirstCardDensity.NOT_DENSE;
-            }
-        }
-        return FeedFirstCardDensity.UNKNOWN;
-    }
-
-    private static int dpToPx(int dp) {
-        return (int) TypedValue.applyDimension(
-                TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().getDisplayMetrics());
-    }
-
-    private void setupRecyclerView() {
-        mRecyclerView = new RecyclerView(mContext);
-        mScrollListenerNotifier = createScrollListenerNotifier(
-                mStreamContentChangedListener, mScrollMonitor, mMainThreadRunner);
-        mRecyclerView.addOnScrollListener(mScrollMonitor);
-        mAdapter = createRecyclerViewAdapter(mContext, mCardConfiguration, mPietManager,
-                mDeepestContentTracker, mStreamContentChangedListener, mScrollMonitor,
-                mConfiguration, new PietEventLogger(mBasicLoggingApi));
-        mAdapter.setHeaders(mHeaders);
-        mRecyclerView.setId(R.id.feed_stream_recycler_view);
-        mRecyclerView.setLayoutManager(createRecyclerViewLayoutManager(mContext));
-        mContextMenuManager = createContextMenuManager(mRecyclerView, new MenuMeasurer(mContext));
-        new ItemTouchHelper(new StreamItemTouchCallbacks()).attachToRecyclerView(mRecyclerView);
-        mRecyclerView.setAdapter(mAdapter);
-        mRecyclerView.setClipToPadding(false);
-        mRecyclerView.setPaddingRelative(mStreamConfiguration.getPaddingStart(),
-                mStreamConfiguration.getPaddingTop(), mStreamConfiguration.getPaddingEnd(),
-                mStreamConfiguration.getPaddingBottom());
-
-        mItemAnimator = new StreamItemAnimator(
-                mStreamContentChangedListener, mActionManager, mRecyclerView);
-        mItemAnimator.setStreamVisibility(mIsStreamContentVisible);
-
-        mRecyclerView.setItemAnimator(mItemAnimator);
-        mRecyclerView.addOnLayoutChangeListener(this);
-
-        mActionManager.setViewport(mRecyclerView);
-        mActionManager.setCanUploadClicksAndViewsWhenNoticeCardIsPresent(canUpload());
-        addScrollListener(mActionManager.getScrollListener());
-    }
-
-    private boolean canUpload() {
-        if (ChromeFeatureList.isEnabled(
-                    ChromeFeatureList.INTEREST_FEEDV1_CLICKS_AND_VIEWS_CONDITIONAL_UPLOAD)) {
-            return UserPrefs.get(Profile.getLastUsedRegularProfile())
-                    .getBoolean(Pref.HAS_REACHED_CLICK_AND_VIEW_ACTIONS_UPLOAD_CONDITIONS);
-        }
-        return true;
-    }
-
-    private void updateAdapterAfterSessionStart(ModelProvider modelProvider) {
-        StreamDriver newStreamDriver = createStreamDriver(mActionApi, mActionManager,
-                mActionParserFactory, modelProvider, mThreadUtils, mClock, mConfiguration, mContext,
-                mSnackbarApi, mStreamContentChangedListener, mScrollRestorer, mBasicLoggingApi,
-                mStreamOfflineMonitor, mFeedKnownContent, mContextMenuManager, mIsRestoring,
-                /* isInitialLoad= */ false, mMainThreadRunner, mTooltipApi, mUiRefreshReason,
-                mScrollListenerNotifier);
-
-        mUiRefreshReason = UiRefreshReason.getDefaultInstance();
-
-        // If after starting a new session the Stream is still empty, we should show the zero state.
-        if (newStreamDriver.getLeafFeatureDrivers().isEmpty()) {
-            newStreamDriver.showZeroState(ZeroStateShowReason.NO_CONTENT);
-        }
-        if (mLoggingState == LoggingState.STARTING && modelProvider.getCurrentState() == State.READY
-                && modelProvider.getRootFeature() == null) {
-            mBasicLoggingApi.onOpenedWithNoContent();
-            mLoggingState = LoggingState.LOGGED_NO_CONTENT;
-        }
-
-        // If old and new stream driver are both showing the zero state, do not replace the old
-        // stream driver. This prevents the zero state flashing if the old and new stream drivers
-        // are both displaying the same content. The old stream driver will be updated with the new
-        // model provider.
-        if (mStreamDriver != null && mStreamDriver.isZeroStateBeingShown()
-                && newStreamDriver.isZeroStateBeingShown()) {
-            mStreamDriver.setModelProviderForZeroState(modelProvider);
-            newStreamDriver.onDestroy();
-            return;
-        }
-        if (mStreamDriver != null) {
-            mStreamDriver.onDestroy();
-        }
-        mStreamDriver = newStreamDriver;
-        mAdapter.setDriver(newStreamDriver);
-        mDeepestContentTracker.reset();
-
-        if (mStreamDriver.hasContent()) {
-            mIsInitialLoad = false;
-        }
-
-        logContent();
-    }
-
-    @Override
-    public void onSessionStart(UiContext uiContext) {
-        mThreadUtils.checkMainThread();
-
-        if (mCancellableShowSpinnerRunnable != null) {
-            mCancellableShowSpinnerRunnable.cancel();
-            mCancellableShowSpinnerRunnable = null;
-        }
-
-        ModelProvider localModelProvider =
-                checkNotNull(mModelProvider, "Model Provider must be set if a session is active");
-        // On initial load, if a loading spinner is currently being shown, the spinner must be shown
-        // for at least the time specified in MINIMUM_SPINNER_SHOW_TIME.
-        if (mIsInitialLoad && mInitialLoadingSpinnerStartTime != 0L) {
-            long spinnerDisplayTime = mClock.currentTimeMillis() - mInitialLoadingSpinnerStartTime;
-            // If MINIMUM_SPINNER_SHOW_TIME has elapsed, the new content can be shown immediately.
-            if (spinnerDisplayTime >= mMinimumSpinnerShowTime) {
-                updateAdapterAfterSessionStart(localModelProvider);
-            } else {
-                // If MINIMUM_SPINNER_SHOW_TIME has not elapsed, the new content should only be
-                // shown once the remaining time has been fulfilled.
-                mMainThreadRunner.executeWithDelay(TAG + " onSessionStart", () -> {
-                    // Only show content if model providers are the same. If they are different,
-                    // this indicates that the session finished before the spinner show time
-                    // elapsed.
-                    if (mModelProvider == localModelProvider) {
-                        updateAdapterAfterSessionStart(localModelProvider);
-                    }
-                }, mMinimumSpinnerShowTime - spinnerDisplayTime);
-            }
-        } else {
-            updateAdapterAfterSessionStart(localModelProvider);
-        }
-    }
-
-    private void logContent() {
-        if (mLoggingState == LoggingState.STARTING) {
-            long timeToPopulateMs = mClock.currentTimeMillis() - mSessionStartTimestamp;
-            if (timeToPopulateMs > mImmediateContentThreshold) {
-                mBasicLoggingApi.onOpenedWithNoImmediateContent();
-            }
-
-            if (checkNotNull(mStreamDriver).hasContent()) {
-                mBasicLoggingApi.onOpenedWithContent((int) timeToPopulateMs,
-                        checkNotNull(mStreamDriver).getLeafFeatureDrivers().size());
-                // onOpenedWithContent should only be logged the first time the Stream is opened up.
-                mLoggingState = LoggingState.LOGGED_CONTENT_SHOWN;
-            } else {
-                mBasicLoggingApi.onOpenedWithNoContent();
-                mLoggingState = LoggingState.LOGGED_NO_CONTENT;
-            }
-        }
-    }
-
-    @Override
-    public void onSessionFinished(UiContext uiContext) {
-        if (mIsDestroyed) {
-            // This seems to be getting called after onDestroy(), resulting in unregistering from
-            // the ModelProvider twice, which causes a crash.
-            Logger.e(TAG, "onSessionFinished called after onDestroy()");
-            return;
-        }
-
-        // Our previous session isn't valid anymore.  There are some circumstances we could probably
-        // restore our scroll (say if scroll was in headers), other times, if we were to restore
-        // scroll it would be to a card which is no longer present.  For simplicity just abandon
-        // scroll restoring for now.  We can improve logic if this doesn't prove to be sufficient
-        // enough.
-        mScrollRestorer.abandonRestoringScroll();
-
-        // At this point, the StreamDriver shouldn't be null. However, the
-        // mCancellableShowSpinnerRunnable could be null or not, depending on whether this spinner
-        // is finishing because a failed restore or because the session started. If a spinner is
-        // queued to show, we want to show that one with its delay, otherwise we show a new one with
-        // a new delay.
-        if (mStreamDriver != null && mCancellableShowSpinnerRunnable == null) {
-            showSpinnerWithDelay();
-        }
-
-        mIsRestoring = false;
-
-        if (mModelProvider != null) {
-            mModelProvider.unregisterObserver(this);
-        }
-        mUiRefreshReason = uiContext.getExtension(UiRefreshReason.uiRefreshReasonExtension);
-
-        // TODO: Instead of setting the refresh reseason, pipe the UiContext through here.
-        mModelProvider = mModelProviderFactory.createNew(
-                mDeepestContentTracker, UiContext.getDefaultInstance());
-
-        registerObserversOnModelProvider(mModelProvider);
-    }
-
-    @Override
-    public void onError(ModelError modelError) {
-        if (modelError.getErrorType() != ErrorType.NO_CARDS_ERROR) {
-            Logger.wtf(TAG, "Not expecting non NO_CARDS_ERROR type.");
-        }
-
-        if (mLoggingState == LoggingState.STARTING) {
-            mBasicLoggingApi.onOpenedWithNoContent();
-            mLoggingState = LoggingState.LOGGED_NO_CONTENT;
-        }
-
-        mScrollRestorer.abandonRestoringScroll();
-        if (mStreamDriver != null) {
-            mStreamDriver.showZeroState(ZeroStateShowReason.ERROR);
-        }
-    }
-
-    private void createModelProviderAndStreamDriver() {
-        if (mModelProvider == null) {
-            // For nullness checker
-            ModelProvider localModelProvider = null;
-            String localSavedSessionId = mSavedSessionId;
-            if (localSavedSessionId != null) {
-                mIsRestoring = true;
-                Logger.d(TAG, "Attempting to restoring session with id: %s.", localSavedSessionId);
-                localModelProvider = mModelProviderFactory.create(
-                        localSavedSessionId, UiContext.getDefaultInstance());
-            }
-
-            if (localModelProvider == null) {
-                // If a session is no longer valid then a ModelProvider will not have been created
-                // above.
-                Logger.d(TAG, "Creating new session for showing.");
-                localModelProvider = mModelProviderFactory.createNew(
-                        mDeepestContentTracker, UiContext.getDefaultInstance());
-            }
-
-            mSessionStartTimestamp = mClock.currentTimeMillis();
-            mModelProvider = localModelProvider;
-
-            registerObserversOnModelProvider(mModelProvider);
-        }
-
-        if (mStreamDriver == null) {
-            // If the ModelProvider is not ready we don't want to restore the Stream at all. Instead
-            // we need to wait for it to become active and we can reset the StreamDriver with the
-            // correct scroll restorer in order to finally restore scroll position.
-            ScrollRestorer initialScrollRestorer = mModelProvider.getCurrentState() == State.READY
-                    ? mScrollRestorer
-                    : createNonRestoringScrollRestorer(
-                            mConfiguration, mRecyclerView, mScrollListenerNotifier);
-
-            mStreamDriver = createStreamDriver(mActionApi, mActionManager, mActionParserFactory,
-                    mModelProvider, mThreadUtils, mClock, mConfiguration, mContext, mSnackbarApi,
-                    mStreamContentChangedListener, initialScrollRestorer, mBasicLoggingApi,
-                    mStreamOfflineMonitor, mFeedKnownContent, mContextMenuManager, mIsRestoring,
-                    mIsInitialLoad, mMainThreadRunner, mTooltipApi,
-                    UiRefreshReason.getDefaultInstance(), mScrollListenerNotifier);
-
-            if (!mIsPlaceholderShown) {
-                showSpinnerWithDelay();
-            }
-            mAdapter.setDriver(mStreamDriver);
-        }
-    }
-
-    private void showSpinnerWithDelay() {
-        mCancellableShowSpinnerRunnable = mMainThreadRunner.executeWithDelay(
-                TAG + " onShow", new ShowSpinnerRunnable(), mSpinnerDelayTime);
-    }
-
-    private String convertStreamSavedInstanceStateToString(
-            StreamSavedInstanceState savedInstanceState) {
-        return Base64.encodeToString(savedInstanceState.toByteArray(), Base64.DEFAULT);
-    }
-
-    private void registerObserversOnModelProvider(ModelProvider modelProvider) {
-        modelProvider.registerObserver(this);
-        mUiSessionRequestLogger.onSessionRequested(modelProvider);
-    }
-
-    @VisibleForTesting
-    StreamDriver createStreamDriver(ActionApi actionApi, ActionManager actionManager,
-            ActionParserFactory actionParserFactory, ModelProvider modelProvider,
-            ThreadUtils threadUtils, Clock clock, Configuration configuration, Context context,
-            SnackbarApi snackbarApi, ContentChangedListener contentChangedListener,
-            ScrollRestorer scrollRestorer, BasicLoggingApi basicLoggingApi,
-            StreamOfflineMonitor streamOfflineMonitor, FeedKnownContent feedKnownContent,
-            ContextMenuManager contextMenuManager, boolean restoring, boolean isInitialLoad,
-            MainThreadRunner mainThreadRunner, TooltipApi tooltipApi,
-            UiRefreshReason uiRefreshReason, ScrollListenerNotifier scrollListenerNotifier) {
-        return new StreamDriver(actionApi, actionManager, actionParserFactory, modelProvider,
-                threadUtils, clock, configuration, context, snackbarApi, contentChangedListener,
-                scrollRestorer, basicLoggingApi, streamOfflineMonitor, feedKnownContent,
-                contextMenuManager, restoring, isInitialLoad, mainThreadRunner, mViewLoggingUpdater,
-                tooltipApi, uiRefreshReason, mScrollMonitor);
-    }
-
-    @VisibleForTesting
-    StreamRecyclerViewAdapter createRecyclerViewAdapter(Context context,
-            CardConfiguration cardConfiguration, PietManager pietManager,
-            DeepestContentTracker deepestContentTracker,
-            StreamContentChangedListener streamContentChangedListener,
-            ScrollObservable scrollObservable, Configuration configuration,
-            PietEventLogger pietEventLogger) {
-        return new StreamRecyclerViewAdapter(context, mRecyclerView, cardConfiguration, pietManager,
-                deepestContentTracker, streamContentChangedListener, scrollObservable,
-                configuration, pietEventLogger);
-    }
-
-    @VisibleForTesting
-    ScrollListenerNotifier createScrollListenerNotifier(
-            ContentChangedListener contentChangedListener, BasicStreamScrollMonitor scrollMonitor,
-            MainThreadRunner mainThreadRunner) {
-        return new ScrollListenerNotifier(contentChangedListener, scrollMonitor, mainThreadRunner);
-    }
-
-    @VisibleForTesting
-    LinearLayoutManager createRecyclerViewLayoutManager(Context context) {
-        return new LinearLayoutManager(context);
-    }
-
-    @VisibleForTesting
-    StreamContentChangedListener createStreamContentChangedListener() {
-        return new StreamContentChangedListener();
-    }
-
-    @VisibleForTesting
-    ScrollRestorer createScrollRestorer(Configuration configuration, RecyclerView recyclerView,
-            ScrollListenerNotifier scrollListenerNotifier, @Nullable ScrollState scrollState) {
-        return new ScrollRestorer(configuration, recyclerView, scrollListenerNotifier, scrollState);
-    }
-
-    @VisibleForTesting
-    ScrollRestorer createNonRestoringScrollRestorer(Configuration configuration,
-            RecyclerView recyclerView, ScrollListenerNotifier scrollListenerNotifier) {
-        return ScrollRestorer.nonRestoringRestorer(
-                configuration, recyclerView, scrollListenerNotifier);
-    }
-
-    @VisibleForTesting
-    ContextMenuManager createContextMenuManager(
-            RecyclerView recyclerView, MenuMeasurer menuMeasurer) {
-        ContextMenuManager manager;
-        if (VERSION.SDK_INT > VERSION_CODES.M) {
-            manager = new ContextMenuManagerImpl(menuMeasurer, mContext);
-        } else {
-            manager = new FloatingContextMenuManager(mContext);
-        }
-        manager.setView(recyclerView);
-        return manager;
-    }
-
-    @VisibleForTesting
-    ViewLoggingUpdater createViewLoggingUpdater() {
-        return new ViewLoggingUpdater();
-    }
-
-    @IntDef({LoggingState.STARTING, LoggingState.LOGGED_NO_CONTENT,
-            LoggingState.LOGGED_CONTENT_SHOWN})
-    @interface LoggingState {
-        int STARTING = 0;
-        int LOGGED_NO_CONTENT = 1;
-        int LOGGED_CONTENT_SHOWN = 2;
-    }
-
-    private final class ShowSpinnerRunnable implements Runnable {
-        @Override
-        public void run() {
-            checkNotNull(mStreamDriver).showSpinner();
-            mInitialLoadingSpinnerStartTime = mClock.currentTimeMillis();
-            BasicStream.this.mCancellableShowSpinnerRunnable = null;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamItemAnimator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamItemAnimator.java
deleted file mode 100644
index 152cb26..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamItemAnimator.java
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal;
-
-import androidx.annotation.VisibleForTesting;
-import androidx.recyclerview.widget.DefaultItemAnimator;
-import androidx.recyclerview.widget.RecyclerView;
-
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ViewActionManager;
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ContentChangedListener;
-
-/**
- * {@link DefaultItemAnimator} implementation that notifies the given {@link ContentChangedListener}
- * after animations occur.
- */
-public class StreamItemAnimator extends DefaultItemAnimator {
-    private final ContentChangedListener mContentChangedListener;
-    private final ViewActionManager mViewActionManager;
-    private boolean mIsStreamContentVisible;
-    private RecyclerView mParent;
-
-    public StreamItemAnimator(ContentChangedListener contentChangedListener,
-            ViewActionManager viewActionManager, RecyclerView parent) {
-        this.mContentChangedListener = contentChangedListener;
-        this.mViewActionManager = viewActionManager;
-        mParent = parent;
-    }
-
-    @Override
-    public void onAddFinished(RecyclerView.ViewHolder item) {
-        super.onAddFinished(item);
-        mContentChangedListener.onAddFinished();
-    }
-
-    @Override
-    public void onAddStarting(RecyclerView.ViewHolder item) {
-        super.onAddStarting(item);
-        mContentChangedListener.onAddStarting();
-    }
-
-    @Override
-    public void onAnimationFinished(RecyclerView.ViewHolder viewHolder) {
-        super.onAnimationFinished(viewHolder);
-        mContentChangedListener.onContentChanged();
-        if (this.mIsStreamContentVisible) mViewActionManager.onAnimationFinished();
-    }
-
-    public void setStreamVisibility(boolean isStreamContentVisible) {
-        if (this.mIsStreamContentVisible == isStreamContentVisible) {
-            return;
-        }
-
-        if (isStreamContentVisible) {
-            // Ending animations so that if any content is animating out the RecyclerView will be
-            // able to remove those views. This can occur if a user quickly presses hide and then
-            // show on the stream.
-            endAnimations();
-        }
-
-        this.mIsStreamContentVisible = isStreamContentVisible;
-    }
-
-    @VisibleForTesting
-    public boolean getStreamContentVisibility() {
-        return mIsStreamContentVisible;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamItemTouchCallbacks.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamItemTouchCallbacks.java
deleted file mode 100644
index debb25716..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamItemTouchCallbacks.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal;
-
-import android.graphics.Canvas;
-import android.view.animation.Interpolator;
-
-import androidx.interpolator.view.animation.FastOutLinearInInterpolator;
-import androidx.recyclerview.widget.ItemTouchHelper;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.SwipeableViewHolder;
-
-/** {@link ItemTouchHelper.Callback} to allow dismissing cards via swiping. */
-public final class StreamItemTouchCallbacks extends ItemTouchHelper.Callback {
-    private static final Interpolator DISMISS_INTERPOLATOR = new FastOutLinearInInterpolator();
-
-    @Override
-    public int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder) {
-        int swipeFlags = 0;
-        if (viewHolder instanceof SwipeableViewHolder
-                && ((SwipeableViewHolder) viewHolder).canSwipe()) {
-            swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
-        }
-        return makeMovementFlags(/* dragFlags= */ 0, swipeFlags);
-    }
-
-    @Override
-    public boolean onMove(
-            RecyclerView recyclerView, ViewHolder viewHolder, ViewHolder viewHolder1) {
-        throw new AssertionError("onMove not supported."); // Drag and drop not supported, the
-                                                           // method will never be called.
-    }
-
-    @Override
-    public void onSwiped(ViewHolder viewHolder, int i) {
-        // Only PietViewHolders support swipe to dismiss. If new ViewHolders support swipe to
-        // dismiss, this should instead use an interface.
-        ((SwipeableViewHolder) viewHolder).onSwiped();
-    }
-
-    @Override
-    public void onChildDraw(Canvas canvas, RecyclerView recyclerView, ViewHolder viewHolder,
-            float dX, float dY, int i, boolean isCurrentlyActive) {
-        float input = Math.abs(dX) / viewHolder.itemView.getMeasuredWidth();
-        float alpha = 1 - DISMISS_INTERPOLATOR.getInterpolation(input);
-
-        viewHolder.itemView.setTranslationX(dX);
-        viewHolder.itemView.setAlpha(alpha);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamRecyclerViewAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamRecyclerViewAdapter.java
deleted file mode 100644
index af08947..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamRecyclerViewAdapter.java
+++ /dev/null
@@ -1,404 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal;
-
-import static org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ViewHolderType.TYPE_CONTINUATION;
-import static org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ViewHolderType.TYPE_HEADER;
-import static org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ViewHolderType.TYPE_NO_CONTENT;
-import static org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ViewHolderType.TYPE_ZERO_STATE;
-
-import android.content.Context;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.FrameLayout;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.recyclerview.widget.DiffUtil;
-import androidx.recyclerview.widget.DiffUtil.DiffResult;
-import androidx.recyclerview.widget.ListUpdateCallback;
-import androidx.recyclerview.widget.RecyclerView;
-
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.CardConfiguration;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.drivers.HeaderDriver;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.drivers.LeafFeatureDriver;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.drivers.StreamDriver;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.drivers.StreamDriver.StreamContentListener;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ContinuationViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.FeedViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.HeaderViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.NoContentViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.PietViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ViewHolderType;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ZeroStateViewHolder;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.piet.PietManager;
-import org.chromium.chrome.browser.feed.library.sharedstream.deepestcontenttracker.DeepestContentTracker;
-import org.chromium.chrome.browser.feed.library.sharedstream.piet.PietEventLogger;
-import org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll.ScrollObservable;
-import org.chromium.chrome.browser.feed.shared.stream.Header;
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ContentChangedListener;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-
-/** A RecyclerView adapter which can show a list of views with Piet Stream features. */
-public class StreamRecyclerViewAdapter
-        extends RecyclerView.Adapter<FeedViewHolder> implements StreamContentListener {
-    private static final String TAG = "StreamRecyclerViewAdapt";
-
-    private final Context mContext;
-    private final View mViewport;
-    private final CardConfiguration mCardConfiguration;
-    private final PietManager mPietManager;
-    private final Configuration mConfiguration;
-    private final List<LeafFeatureDriver> mLeafFeatureDrivers;
-    private final List<HeaderDriver> mHeaders;
-    private final HashMap<FeedViewHolder, LeafFeatureDriver> mBoundViewHolderToLeafFeatureDriverMap;
-    private final DeepestContentTracker mDeepestContentTracker;
-    private final ContentChangedListener mContentChangedListener;
-    private final PietEventLogger mEventLogger;
-
-    private boolean mStreamContentVisible;
-    private boolean mShown;
-
-    @Nullable
-    private StreamDriver mStreamDriver;
-    private final ScrollObservable mScrollObservable;
-
-    // Suppress initialization warnings for calling setHasStableIds on RecyclerView.Adapter
-    @SuppressWarnings("initialization")
-    public StreamRecyclerViewAdapter(Context context, View viewport,
-            CardConfiguration cardConfiguration, PietManager pietManager,
-            DeepestContentTracker deepestContentTracker,
-            ContentChangedListener contentChangedListener, ScrollObservable scrollObservable,
-            Configuration configuration, PietEventLogger eventLogger) {
-        this.mContext = context;
-        this.mViewport = viewport;
-        this.mCardConfiguration = cardConfiguration;
-        this.mPietManager = pietManager;
-        this.mContentChangedListener = contentChangedListener;
-        this.mConfiguration = configuration;
-        mHeaders = new ArrayList<>();
-        mLeafFeatureDrivers = new ArrayList<>();
-        setHasStableIds(true);
-        mBoundViewHolderToLeafFeatureDriverMap = new HashMap<>();
-        mStreamContentVisible = true;
-        this.mDeepestContentTracker = deepestContentTracker;
-        this.mScrollObservable = scrollObservable;
-        this.mEventLogger = eventLogger;
-    }
-
-    @Override
-    public FeedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
-        FrameLayout frameLayout = new FrameLayout(parent.getContext());
-        frameLayout.setLayoutParams(
-                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
-        if (viewType == TYPE_HEADER) {
-            return new HeaderViewHolder(frameLayout);
-        } else if (viewType == TYPE_CONTINUATION) {
-            return new ContinuationViewHolder(
-                    mConfiguration, parent.getContext(), frameLayout, mCardConfiguration);
-        } else if (viewType == TYPE_NO_CONTENT) {
-            return new NoContentViewHolder(mCardConfiguration, parent.getContext(), frameLayout);
-        } else if (viewType == TYPE_ZERO_STATE) {
-            return new ZeroStateViewHolder(parent.getContext(), frameLayout, mCardConfiguration);
-        }
-
-        return new PietViewHolder(mCardConfiguration, frameLayout, mPietManager, mScrollObservable,
-                mViewport, mContext, mConfiguration, mEventLogger);
-    }
-
-    @Override
-    public void onBindViewHolder(FeedViewHolder viewHolder, int index) {
-        Logger.d(TAG, "onBindViewHolder for index: %s", index);
-        if (isHeader(index)) {
-            Logger.d(TAG, "Binding header at index %s", index);
-            HeaderDriver headerDriver = mHeaders.get(index);
-            headerDriver.bind(viewHolder);
-            mBoundViewHolderToLeafFeatureDriverMap.put(viewHolder, headerDriver);
-            return;
-        }
-
-        int streamIndex = positionToStreamIndex(index);
-
-        Logger.d(TAG, "onBindViewHolder for stream index: %s", streamIndex);
-        LeafFeatureDriver leafFeatureDriver = mLeafFeatureDrivers.get(streamIndex);
-
-        mDeepestContentTracker.updateDeepestContentTracker(
-                streamIndex, leafFeatureDriver.getContentId());
-
-        leafFeatureDriver.bind(viewHolder);
-        mBoundViewHolderToLeafFeatureDriverMap.put(viewHolder, leafFeatureDriver);
-    }
-
-    @Override
-    public void onViewRecycled(FeedViewHolder viewHolder) {
-        LeafFeatureDriver leafFeatureDriver =
-                mBoundViewHolderToLeafFeatureDriverMap.get(viewHolder);
-
-        if (leafFeatureDriver == null) {
-            Logger.wtf(TAG, "Could not find driver for unbinding");
-            return;
-        }
-
-        leafFeatureDriver.unbind();
-        mBoundViewHolderToLeafFeatureDriverMap.remove(viewHolder);
-    }
-
-    @Override
-    public int getItemCount() {
-        int driverSize = mStreamContentVisible ? mLeafFeatureDrivers.size() : 0;
-        return driverSize + mHeaders.size();
-    }
-
-    @Override
-    @ViewHolderType
-    public int getItemViewType(int position) {
-        if (isHeader(position)) {
-            return TYPE_HEADER;
-        }
-
-        return mLeafFeatureDrivers.get(positionToStreamIndex(position)).getItemViewType();
-    }
-
-    @Override
-    public long getItemId(int position) {
-        if (isHeader(position)) {
-            return mHeaders.get(position).hashCode();
-        }
-
-        return mLeafFeatureDrivers.get(positionToStreamIndex(position)).itemId();
-    }
-
-    public void rebind() {
-        for (LeafFeatureDriver driver : mBoundViewHolderToLeafFeatureDriverMap.values()) {
-            driver.maybeRebind();
-        }
-    }
-
-    @VisibleForTesting
-    public List<LeafFeatureDriver> getLeafFeatureDrivers() {
-        return mLeafFeatureDrivers;
-    }
-
-    private boolean isHeader(int position) {
-        return position < mHeaders.size();
-    }
-
-    private int positionToStreamIndex(int position) {
-        return position - mHeaders.size();
-    }
-
-    public void setHeaders(List<Header> newHeaders) {
-        // TODO: Move header orchestration into separate class once header orchestration
-        // logic is complex enough.
-        List<Header> oldHeaders = new ArrayList<>();
-        for (HeaderDriver headerDriver : mHeaders) {
-            oldHeaders.add(headerDriver.getHeader());
-        }
-        DiffResult diffResult =
-                DiffUtil.calculateDiff(new HeaderDiffCallback(oldHeaders, newHeaders), true);
-        diffResult.dispatchUpdatesTo(new HeaderListUpdateCallback(newHeaders));
-    }
-
-    public int getHeaderCount() {
-        return mHeaders.size();
-    }
-
-    public void setStreamContentVisible(boolean streamContentVisible) {
-        if (this.mStreamContentVisible == streamContentVisible) {
-            return;
-        }
-        this.mStreamContentVisible = streamContentVisible;
-
-        if (mLeafFeatureDrivers.isEmpty()) {
-            // Nothing to alter in RecyclerView if there is no leaf content.
-            return;
-        }
-
-        if (streamContentVisible) {
-            notifyItemRangeInserted(mHeaders.size(), mLeafFeatureDrivers.size());
-        } else {
-            notifyItemRangeRemoved(mHeaders.size(), mLeafFeatureDrivers.size());
-        }
-    }
-
-    public void setDriver(StreamDriver newStreamDriver) {
-        if (mStreamDriver != null) {
-            mStreamDriver.setStreamContentListener(null);
-        }
-
-        notifyItemRangeRemoved(mHeaders.size(), mLeafFeatureDrivers.size());
-        mLeafFeatureDrivers.clear();
-
-        // It is important that we get call getLeafFeatureDrivers before setting the content
-        // listener. If this is done in the other order, it is possible that the StreamDriver
-        // notifies us of something being added inside of the getLeafFeatureDrivers() call,
-        // resulting in two copies of the LeafFeatureDriver being shown.
-        mLeafFeatureDrivers.addAll(newStreamDriver.getLeafFeatureDrivers());
-        newStreamDriver.setStreamContentListener(this);
-
-        mStreamDriver = newStreamDriver;
-        if (mStreamContentVisible) {
-            notifyItemRangeInserted(mHeaders.size(), mLeafFeatureDrivers.size());
-        }
-
-        newStreamDriver.maybeRestoreScroll();
-    }
-
-    @Override
-    public void notifyContentsAdded(int index, List<LeafFeatureDriver> newFeatureDrivers) {
-        if (newFeatureDrivers.size() == 0) {
-            return;
-        }
-
-        mLeafFeatureDrivers.addAll(index, newFeatureDrivers);
-
-        int insertionIndex = mHeaders.size() + index;
-
-        if (mStreamContentVisible) {
-            notifyItemRangeInserted(insertionIndex, newFeatureDrivers.size());
-        }
-        maybeNotifyContentChanged();
-    }
-
-    @Override
-    public void notifyContentRemoved(int index) {
-        int removalIndex = mHeaders.size() + index;
-
-        mLeafFeatureDrivers.remove(index);
-        mDeepestContentTracker.removeContentId(index);
-
-        if (mStreamContentVisible) {
-            notifyItemRemoved(removalIndex);
-        }
-        maybeNotifyContentChanged();
-    }
-
-    @Override
-    public void notifyContentsCleared() {
-        int itemCount = mLeafFeatureDrivers.size();
-        mLeafFeatureDrivers.clear();
-
-        if (mStreamContentVisible) {
-            notifyItemRangeRemoved(mHeaders.size(), itemCount);
-        }
-        maybeNotifyContentChanged();
-    }
-
-    public void onDestroy() {
-        for (HeaderDriver header : mHeaders) {
-            header.unbind();
-        }
-
-        setHeaders(Collections.emptyList());
-    }
-
-    public void setShown(boolean shown) {
-        this.mShown = shown;
-    }
-
-    private void maybeNotifyContentChanged() {
-        // If Stream is not shown on screen, host should be notified as animations will not run and
-        // the host will not be notified through StreamItemAnimator.
-        if (!mShown) {
-            mContentChangedListener.onContentChanged();
-        }
-    }
-
-    @VisibleForTesting
-    void dismissHeader(Header header) {
-        int indexToRemove = -1;
-        for (int i = 0; i < mHeaders.size(); i++) {
-            if (mHeaders.get(i).getHeader() == header) {
-                indexToRemove = i;
-            }
-        }
-        if (indexToRemove == -1) {
-            Logger.w(TAG, "Header has already been removed.");
-            return;
-        }
-
-        mHeaders.remove(indexToRemove).onDestroy();
-        notifyItemRemoved(indexToRemove);
-        header.onDismissed();
-    }
-
-    @VisibleForTesting
-    HeaderDriver createHeaderDriver(Header header) {
-        return new HeaderDriver(header, () -> dismissHeader(header));
-    }
-
-    private static class HeaderDiffCallback extends DiffUtil.Callback {
-        private final List<Header> mOldHeaders;
-        private final List<Header> mNewHeaders;
-
-        private HeaderDiffCallback(List<Header> oldHeaders, List<Header> newHeaders) {
-            this.mOldHeaders = oldHeaders;
-            this.mNewHeaders = newHeaders;
-        }
-
-        @Override
-        public int getOldListSize() {
-            return mOldHeaders.size();
-        }
-
-        @Override
-        public int getNewListSize() {
-            return mNewHeaders.size();
-        }
-
-        @Override
-        public boolean areItemsTheSame(int i, int i1) {
-            return mOldHeaders.get(i).getView().equals(mNewHeaders.get(i1).getView());
-        }
-
-        @Override
-        public boolean areContentsTheSame(int i, int i1) {
-            return mOldHeaders.get(i).getView().equals(mNewHeaders.get(i1).getView());
-        }
-    }
-
-    private class HeaderListUpdateCallback implements ListUpdateCallback {
-        private final List<Header> mNewHeaders;
-
-        public HeaderListUpdateCallback(List<Header> newHeaders) {
-            this.mNewHeaders = newHeaders;
-        }
-
-        @Override
-        public void onInserted(int i, int i1) {
-            for (int index = i; index < mNewHeaders.size() && index < i + i1; index++) {
-                HeaderDriver headerDriver = createHeaderDriver(mNewHeaders.get(index));
-                mHeaders.add(index, headerDriver);
-            }
-            notifyItemRangeInserted(i, i1);
-        }
-
-        @Override
-        public void onRemoved(int i, int i1) {
-            for (int index = i + i1 - 1; index >= 0 && index > i - i1; index--) {
-                mHeaders.get(index).onDestroy();
-                mHeaders.remove(index);
-            }
-            notifyItemRangeRemoved(i, i1);
-        }
-
-        @Override
-        public void onMoved(int i, int i1) {
-            notifyItemMoved(i, i1);
-        }
-
-        @Override
-        public void onChanged(int i, int i1, @Nullable Object o) {
-            notifyItemRangeChanged(i, i1, o);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/actions/StreamActionApiImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/actions/StreamActionApiImpl.java
deleted file mode 100644
index 0e8ae85f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/actions/StreamActionApiImpl.java
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.actions;
-
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.ContentMetadata;
-import org.chromium.chrome.browser.feed.library.api.host.action.ActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.action.StreamActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ActionType;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ContentLoggingData;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipCallbackApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipInfo;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionParser;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionSource;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.pendingdismiss.ClusterPendingDismissHelper;
-import org.chromium.chrome.browser.feed.library.sharedstream.contextmenumanager.ContextMenuManager;
-import org.chromium.chrome.browser.feed.library.sharedstream.pendingdismiss.PendingDismissCallback;
-import org.chromium.chrome.browser.feed.shared.FeedFeatures;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.ElementType;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.LabelledFeedActionData;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.OpenContextMenuData;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.UndoAction;
-import org.chromium.components.feed.core.proto.wire.ActionPayloadProto.ActionPayload;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/** Action handler for Stream. */
-public class StreamActionApiImpl implements StreamActionApi {
-    private static final String TAG = "StreamActionApiImpl";
-
-    private final ActionApi mActionApi;
-    private final ActionParser mActionParser;
-    private final ActionManager mActionManager;
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final Supplier<ContentLoggingData> mContentLoggingData;
-    private final ContextMenuManager mContextMenuManager;
-    private final ClusterPendingDismissHelper mClusterPendingDismissHelper;
-    private final ViewElementActionHandler mViewElementActionHandler;
-    private final String mContentId;
-    private final TooltipApi mTooltipApi;
-
-    @Nullable
-    private final String mSessionId;
-
-    public StreamActionApiImpl(ActionApi actionApi, ActionParser actionParser,
-            ActionManager actionManager, BasicLoggingApi basicLoggingApi,
-            Supplier<ContentLoggingData> contentLoggingData, ContextMenuManager contextMenuManager,
-            @Nullable String sessionId, ClusterPendingDismissHelper clusterPendingDismissHelper,
-            ViewElementActionHandler viewElementActionHandler, String contentId,
-            TooltipApi tooltipApi) {
-        this.mActionApi = actionApi;
-        this.mActionParser = actionParser;
-        this.mActionManager = actionManager;
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mContentLoggingData = contentLoggingData;
-        this.mContextMenuManager = contextMenuManager;
-        this.mSessionId = sessionId;
-        this.mClusterPendingDismissHelper = clusterPendingDismissHelper;
-        this.mViewElementActionHandler = viewElementActionHandler;
-        this.mContentId = contentId;
-        this.mTooltipApi = tooltipApi;
-    }
-
-    @Override
-    public void openContextMenu(OpenContextMenuData openContextMenuData, View anchorView) {
-        List<String> actionLabels = new ArrayList<>();
-        List<LabelledFeedActionData> enabledActions = new ArrayList<>();
-        for (LabelledFeedActionData labelledFeedActionData :
-                openContextMenuData.getContextMenuDataList()) {
-            if (mActionParser.canPerformAction(
-                        labelledFeedActionData.getFeedActionPayload(), this)) {
-                actionLabels.add(labelledFeedActionData.getLabel());
-                enabledActions.add(labelledFeedActionData);
-            }
-        }
-
-        boolean menuOpened = mContextMenuManager.openContextMenu(anchorView, actionLabels,
-                (int position)
-                        -> mActionParser.parseFeedActionPayload(
-                                enabledActions.get(position).getFeedActionPayload(),
-                                StreamActionApiImpl.this, anchorView, ActionSource.CONTEXT_MENU));
-
-        if (menuOpened) {
-            mBasicLoggingApi.onContentContextMenuOpened(mContentLoggingData.get());
-        }
-    }
-
-    @Override
-    public boolean canOpenContextMenu() {
-        return true;
-    }
-
-    @Override
-    public boolean canDismiss() {
-        return true;
-    }
-
-    @Override
-    public boolean canHandleNotInterestedIn() {
-        return true;
-    }
-
-    @Override
-    public void handleNotInterestedIn(List<StreamDataOperation> dataOperations,
-            UndoAction undoAction, ActionPayload payload, int interestType) {
-        if (!undoAction.hasConfirmationLabel()) {
-            dismiss(dataOperations);
-            mBasicLoggingApi.onNotInterestedIn(
-                    interestType, mContentLoggingData.get(), /* wasCommitted = */ true);
-        } else {
-            dismissWithSnackbar(undoAction, new PendingDismissCallback() {
-                @Override
-                public void onDismissReverted() {
-                    mBasicLoggingApi.onNotInterestedIn(
-                            interestType, mContentLoggingData.get(), /* wasCommitted = */ false);
-                }
-
-                @Override
-                public void onDismissCommitted() {
-                    dismiss(dataOperations);
-                    mActionManager.createAndUploadAction(
-                            mContentId, payload, ActionManager.UploadActionType.MISC);
-                    mBasicLoggingApi.onNotInterestedIn(
-                            interestType, mContentLoggingData.get(), /* wasCommitted = */ true);
-                }
-            });
-        }
-    }
-
-    @Override
-    public void handleBlockContent(
-            List<StreamDataOperation> dataOperations, ActionPayload payload) {
-        dismiss(dataOperations);
-        mActionManager.createAndUploadAction(
-                mContentId, payload, ActionManager.UploadActionType.MISC);
-    }
-
-    @Override
-    public void dismiss(String contentId, List<StreamDataOperation> dataOperations,
-            UndoAction undoAction, ActionPayload payload) {
-        if (!undoAction.hasConfirmationLabel()) {
-            dismissLocal(contentId, dataOperations);
-            mBasicLoggingApi.onContentDismissed(
-                    mContentLoggingData.get(), /* wasCommitted = */ true);
-        } else {
-            dismissWithSnackbar(undoAction, new PendingDismissCallback() {
-                @Override
-                public void onDismissReverted() {
-                    mBasicLoggingApi.onContentDismissed(
-                            mContentLoggingData.get(), /* wasCommitted = */ false);
-                }
-
-                @Override
-                public void onDismissCommitted() {
-                    dismissLocal(contentId, dataOperations);
-                    dismiss(dataOperations);
-                    mActionManager.createAndUploadAction(
-                            contentId, payload, ActionManager.UploadActionType.MISC);
-                    mBasicLoggingApi.onContentDismissed(
-                            mContentLoggingData.get(), /* wasCommitted = */ true);
-                }
-            });
-        }
-    }
-
-    private void dismiss(List<StreamDataOperation> dataOperations) {
-        mActionManager.dismiss(dataOperations, mSessionId);
-    }
-
-    private void dismissLocal(String contentId, List<StreamDataOperation> dataOperations) {
-        mActionManager.dismissLocal(
-                Collections.singletonList(contentId), dataOperations, mSessionId);
-    }
-
-    private void dismissWithSnackbar(
-            UndoAction undoAction, PendingDismissCallback pendingDismissCallback) {
-        mClusterPendingDismissHelper.triggerPendingDismissForCluster(
-                undoAction, pendingDismissCallback);
-    }
-
-    @Override
-    public void onClientAction(@ActionType int actionType) {
-        mBasicLoggingApi.onClientAction(mContentLoggingData.get(), actionType);
-    }
-
-    @Override
-    public void openUrl(String url) {
-        mActionApi.openUrl(url);
-    }
-
-    @Override
-    public void openUrl(String url, String consistencyTokenQueryParamName) {
-        mActionManager.uploadAllActionsAndUpdateUrl(
-                url, consistencyTokenQueryParamName, result -> { mActionApi.openUrl(result); });
-    }
-
-    @Override
-    public boolean canOpenUrl() {
-        return mActionApi.canOpenUrl();
-    }
-
-    @Override
-    public void openUrlInIncognitoMode(String url) {
-        mActionApi.openUrlInIncognitoMode(url);
-    }
-
-    @Override
-    public void openUrlInIncognitoMode(String url, String consistencyTokenQueryParamName) {
-        mActionManager.uploadAllActionsAndUpdateUrl(url, consistencyTokenQueryParamName,
-                result -> { mActionApi.openUrlInIncognitoMode(result); });
-    }
-
-    @Override
-    public boolean canOpenUrlInIncognitoMode() {
-        return mActionApi.canOpenUrlInIncognitoMode();
-    }
-
-    @Override
-    public void openUrlInNewTab(String url) {
-        mActionApi.openUrlInNewTab(url);
-    }
-
-    @Override
-    public void openUrlInNewTab(String url, String consistencyTokenQueryParamName) {
-        mActionManager.uploadAllActionsAndUpdateUrl(url, consistencyTokenQueryParamName,
-                result -> { mActionApi.openUrlInNewTab(result); });
-    }
-
-    @Override
-    public boolean canOpenUrlInNewTab() {
-        return mActionApi.canOpenUrlInNewTab();
-    }
-
-    @Override
-    public void openUrlInNewWindow(String url) {
-        mActionApi.openUrlInNewWindow(url);
-    }
-
-    @Override
-    public void openUrlInNewWindow(String url, String consistencyTokenQueryParamName) {
-        mActionManager.uploadAllActionsAndUpdateUrl(url, consistencyTokenQueryParamName,
-                result -> { mActionApi.openUrlInNewWindow(result); });
-    }
-
-    @Override
-    public boolean canOpenUrlInNewWindow() {
-        return mActionApi.canOpenUrlInNewWindow();
-    }
-
-    @Override
-    public void downloadUrl(ContentMetadata contentMetadata) {
-        mActionApi.downloadUrl(contentMetadata);
-    }
-
-    @Override
-    public boolean canDownloadUrl() {
-        return mActionApi.canDownloadUrl();
-    }
-
-    @Override
-    public void sendFeedback(ContentMetadata contentMetadata) {
-        mActionApi.sendFeedback(contentMetadata);
-    }
-
-    @Override
-    public void learnMore() {
-        mActionApi.learnMore();
-    }
-
-    @Override
-    public boolean canLearnMore() {
-        return mActionApi.canLearnMore();
-    }
-
-    @Override
-    public boolean canHandleElementView() {
-        return true;
-    }
-
-    @Override
-    public boolean canHandleElementHide() {
-        return true;
-    }
-
-    @Override
-    public boolean canHandleElementClick() {
-        return true;
-    }
-
-    @Override
-    public void onElementView(int elementType) {
-        mViewElementActionHandler.onElementView(elementType);
-    }
-
-    @Override
-    public void onElementHide(int elementType) {
-        mViewElementActionHandler.onElementHide(elementType);
-    }
-
-    @Override
-    public void onElementClick(int elementType) {
-        mBasicLoggingApi.onVisualElementClicked(mContentLoggingData.get(), elementType);
-    }
-
-    @Override
-    public boolean canShowTooltip() {
-        return true;
-    }
-
-    @Override
-    public void maybeShowTooltip(TooltipInfo tooltipInfo, View view) {
-        mTooltipApi.maybeShowHelpUi(tooltipInfo, view, new TooltipCallbackApi() {
-            @Override
-            public void onShow() {
-                onElementView(ElementType.TOOLTIP.getNumber());
-            }
-
-            @Override
-            public void onHide(int dismissType) {
-                onElementHide(ElementType.TOOLTIP.getNumber());
-            }
-        });
-    }
-
-    @Override
-    public void reportClickAction(String contentId, ActionPayload payload) {
-        if (FeedFeatures.isReportingUserActions()) {
-            mActionManager.createAndUploadAction(
-                    contentId, payload, ActionManager.UploadActionType.CLICK);
-        }
-    }
-
-    @Override
-    public void reportViewVisible(View view, String contentId, ActionPayload payload) {
-        if (FeedFeatures.isReportingUserActions()) {
-            mActionManager.onViewVisible(view, contentId, payload);
-        }
-    }
-
-    @Override
-    public void reportViewHidden(View view, String contentId) {
-        if (FeedFeatures.isReportingUserActions()) {
-            mActionManager.onViewHidden(view, contentId);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/actions/ViewElementActionHandler.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/actions/ViewElementActionHandler.java
deleted file mode 100644
index 992cf5d8..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/actions/ViewElementActionHandler.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-package org.chromium.chrome.browser.feed.library.basicstream.internal.actions;
-
-/** Interface used for communicating view and hide events */
-public interface ViewElementActionHandler {
-    /**
-     * Called when a hide action has been performed on a {@link
-     * org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.
-     *   ElementType}
-     * value.
-     */
-    void onElementHide(int elementType);
-
-    /**
-     * Called when a view action has been performed on a {@link
-     * org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.
-     *   ElementType}
-     * value.
-     */
-    void onElementView(int elementType);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/CardDriver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/CardDriver.java
deleted file mode 100644
index bc47165..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/CardDriver.java
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.drivers;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.api.host.action.ActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.InternalFeedError;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipApi;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionParserFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild.Type;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelCursor;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.pendingdismiss.ClusterPendingDismissHelper;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewloggingupdater.ViewLoggingUpdater;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.sharedstream.contextmenumanager.ContextMenuManager;
-import org.chromium.chrome.browser.feed.library.sharedstream.offlinemonitor.StreamOfflineMonitor;
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ContentChangedListener;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionPayloadProto.FeedActionPayload;
-import org.chromium.components.feed.core.proto.ui.stream.StreamSwipeExtensionProto.SwipeActionExtension;
-
-/** {@link FeatureDriver} for cards. */
-public class CardDriver implements FeatureDriver {
-    private static final String TAG = "CardDriver";
-
-    private final ActionApi mActionApi;
-    private final ActionManager mActionManager;
-    private final ActionParserFactory mActionParserFactory;
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final ModelFeature mCardModel;
-    private final ModelProvider mModelProvider;
-    private final int mPosition;
-    private final ClusterPendingDismissHelper mClusterPendingDismissHelper;
-    private final StreamOfflineMonitor mStreamOfflineMonitor;
-    private final ContentChangedListener mContentChangedListener;
-    private final ContextMenuManager mContextMenuManager;
-    private final MainThreadRunner mMainThreadRunner;
-    private final Configuration mConfiguration;
-    private final ViewLoggingUpdater mViewLoggingUpdater;
-    private final TooltipApi mTooltipApi;
-
-    @Nullable
-    private ContentDriver mContentDriver;
-
-    CardDriver(ActionApi actionApi, ActionManager actionManager,
-            ActionParserFactory actionParserFactory, BasicLoggingApi basicLoggingApi,
-            ModelFeature cardModel, ModelProvider modelProvider, int position,
-            ClusterPendingDismissHelper clusterPendingDismissHelper,
-            StreamOfflineMonitor streamOfflineMonitor,
-            ContentChangedListener contentChangedListener, ContextMenuManager contextMenuManager,
-            MainThreadRunner mainThreadRunner, Configuration configuration,
-            ViewLoggingUpdater viewLoggingUpdater, TooltipApi tooltipApi) {
-        this.mActionApi = actionApi;
-        this.mActionManager = actionManager;
-        this.mActionParserFactory = actionParserFactory;
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mCardModel = cardModel;
-        this.mModelProvider = modelProvider;
-        this.mPosition = position;
-        this.mClusterPendingDismissHelper = clusterPendingDismissHelper;
-        this.mStreamOfflineMonitor = streamOfflineMonitor;
-        this.mContentChangedListener = contentChangedListener;
-        this.mContextMenuManager = contextMenuManager;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mConfiguration = configuration;
-        this.mViewLoggingUpdater = viewLoggingUpdater;
-        this.mTooltipApi = tooltipApi;
-    }
-
-    @Override
-    public void onDestroy() {
-        if (mContentDriver != null) {
-            mContentDriver.onDestroy();
-        }
-    }
-
-    @Override
-    @Nullable
-    public LeafFeatureDriver getLeafFeatureDriver() {
-        if (mContentDriver == null) {
-            mContentDriver = createContentChild(mCardModel);
-        }
-
-        if (mContentDriver != null) {
-            return mContentDriver.getLeafFeatureDriver();
-        }
-
-        return null;
-    }
-
-    @Nullable
-    private ContentDriver createContentChild(ModelFeature modelFeature) {
-        ModelCursor cursor = modelFeature.getCursor();
-        // TODO: add change listener to ModelFeature.
-        ModelChild child;
-        if ((child = cursor.getNextItem()) != null) {
-            if (child.getType() != Type.FEATURE) {
-                mBasicLoggingApi.onInternalError(InternalFeedError.CARD_CHILD_MISSING_FEATURE);
-                Logger.e(TAG, "ContentChild was not bound to a Feature, found type: %s",
-                        child.getType());
-                return null;
-            }
-            ModelFeature contentModel = child.getModelFeature();
-            checkState(
-                    contentModel.getStreamFeature().hasContent(), "Expected content for feature");
-            return createContentDriver(contentModel,
-                    mCardModel.getStreamFeature()
-                            .getCard()
-                            .getExtension(SwipeActionExtension.swipeActionExtension)
-                            .getSwipeAction());
-        }
-
-        return null;
-    }
-
-    @VisibleForTesting
-    ContentDriver createContentDriver(ModelFeature contentModel, FeedActionPayload swipeAction) {
-        return new ContentDriver(mActionApi, mActionManager, mActionParserFactory, mBasicLoggingApi,
-                contentModel, mModelProvider, mPosition, swipeAction, mClusterPendingDismissHelper,
-                mStreamOfflineMonitor, mContentChangedListener, mContextMenuManager,
-                mMainThreadRunner, mConfiguration, mViewLoggingUpdater, mTooltipApi);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ClusterDriver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ClusterDriver.java
deleted file mode 100644
index e83a740..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ClusterDriver.java
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.drivers;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.api.host.action.ActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.InternalFeedError;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipApi;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionParserFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild.Type;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelCursor;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.pendingdismiss.ClusterPendingDismissHelper;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.pendingdismiss.PendingDismissHandler;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewloggingupdater.ViewLoggingUpdater;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.sharedstream.contextmenumanager.ContextMenuManager;
-import org.chromium.chrome.browser.feed.library.sharedstream.offlinemonitor.StreamOfflineMonitor;
-import org.chromium.chrome.browser.feed.library.sharedstream.pendingdismiss.PendingDismissCallback;
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ContentChangedListener;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.UndoAction;
-
-/** {@link FeatureDriver} for Clusters. */
-public class ClusterDriver implements FeatureDriver, ClusterPendingDismissHelper {
-    private static final String TAG = "ClusterDriver";
-    private final ActionApi mActionApi;
-    private final ActionManager mActionManager;
-    private final ActionParserFactory mActionParserFactory;
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final ModelFeature mClusterModel;
-    private final ModelProvider mModelProvider;
-    private final int mPosition;
-    private final PendingDismissHandler mPendingDismissHandler;
-    private final StreamOfflineMonitor mStreamOfflineMonitor;
-    private final ContentChangedListener mContentChangedListener;
-    private final ContextMenuManager mContextMenuManager;
-    private final MainThreadRunner mMainThreadRunner;
-    private final Configuration mConfiguration;
-    private final ViewLoggingUpdater mViewLoggingUpdater;
-    private final TooltipApi mTooltipApi;
-
-    @Nullable
-    private CardDriver mCardDriver;
-
-    ClusterDriver(ActionApi actionApi, ActionManager actionManager,
-            ActionParserFactory actionParserFactory, BasicLoggingApi basicLoggingApi,
-            ModelFeature clusterModel, ModelProvider modelProvider, int position,
-            PendingDismissHandler pendingDismissHandler, StreamOfflineMonitor streamOfflineMonitor,
-            ContentChangedListener contentChangedListener, ContextMenuManager contextMenuManager,
-            MainThreadRunner mainThreadRunner, Configuration configuration,
-            ViewLoggingUpdater viewLoggingUpdater, TooltipApi tooltipApi) {
-        this.mActionApi = actionApi;
-        this.mActionManager = actionManager;
-        this.mActionParserFactory = actionParserFactory;
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mClusterModel = clusterModel;
-        this.mModelProvider = modelProvider;
-        this.mPosition = position;
-        this.mPendingDismissHandler = pendingDismissHandler;
-        this.mStreamOfflineMonitor = streamOfflineMonitor;
-        this.mContentChangedListener = contentChangedListener;
-        this.mContextMenuManager = contextMenuManager;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mConfiguration = configuration;
-        this.mViewLoggingUpdater = viewLoggingUpdater;
-        this.mTooltipApi = tooltipApi;
-    }
-
-    @Override
-    public void onDestroy() {
-        if (mCardDriver != null) {
-            mCardDriver.onDestroy();
-        }
-    }
-
-    @Override
-    @Nullable
-    public LeafFeatureDriver getLeafFeatureDriver() {
-        if (mCardDriver == null) {
-            mCardDriver = createCardChild(mClusterModel);
-        }
-
-        if (mCardDriver != null) {
-            return mCardDriver.getLeafFeatureDriver();
-        }
-
-        return null;
-    }
-
-    @Nullable
-    private CardDriver createCardChild(ModelFeature clusterFeature) {
-        ModelCursor cursor = clusterFeature.getCursor();
-        // TODO: add change listener to clusterCursor.
-        ModelChild child;
-        while ((child = cursor.getNextItem()) != null) {
-            if (child.getType() != Type.FEATURE) {
-                mBasicLoggingApi.onInternalError(InternalFeedError.CLUSTER_CHILD_MISSING_FEATURE);
-                Logger.e(TAG, "Child of cursor is not a feature");
-                continue;
-            }
-
-            ModelFeature childModelFeature = child.getModelFeature();
-
-            if (!childModelFeature.getStreamFeature().hasCard()) {
-                mBasicLoggingApi.onInternalError(InternalFeedError.CLUSTER_CHILD_NOT_CARD);
-                Logger.e(TAG, "Content not card.");
-                continue;
-            }
-
-            return createCardDriver(childModelFeature);
-        }
-
-        return null;
-    }
-
-    @VisibleForTesting
-    CardDriver createCardDriver(ModelFeature content) {
-        return new CardDriver(mActionApi, mActionManager, mActionParserFactory, mBasicLoggingApi,
-                content, mModelProvider, mPosition, this, mStreamOfflineMonitor,
-                mContentChangedListener, mContextMenuManager, mMainThreadRunner, mConfiguration,
-                mViewLoggingUpdater, mTooltipApi);
-    }
-
-    @Override
-    public void triggerPendingDismissForCluster(
-            UndoAction undoAction, PendingDismissCallback pendingDismissCallback) {
-        // Get the content id assoc with this ClusterDriver and pass the dismiss to the
-        // StreamDriver.
-        mPendingDismissHandler.triggerPendingDismiss(
-                mClusterModel.getStreamFeature().getContentId(), undoAction,
-                pendingDismissCallback);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ContentDriver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ContentDriver.java
deleted file mode 100644
index f162888d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ContentDriver.java
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.drivers;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.recyclerview.widget.RecyclerView;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.ContentMetadata;
-import org.chromium.chrome.browser.feed.library.api.host.action.ActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.action.StreamActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ContentLoggingData;
-import org.chromium.chrome.browser.feed.library.api.host.logging.InternalFeedError;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipApi;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionParser;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionParserFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.actions.StreamActionApiImpl;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.actions.ViewElementActionHandler;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.pendingdismiss.ClusterPendingDismissHelper;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.FeedViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.PietViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ViewHolderType;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewloggingupdater.ResettableOneShotVisibilityLoggingListener;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewloggingupdater.ViewLoggingUpdater;
-import org.chromium.chrome.browser.feed.library.common.concurrent.CancelableTask;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.sharedstream.constants.Constants;
-import org.chromium.chrome.browser.feed.library.sharedstream.contextmenumanager.ContextMenuManager;
-import org.chromium.chrome.browser.feed.library.sharedstream.logging.LoggingListener;
-import org.chromium.chrome.browser.feed.library.sharedstream.logging.StreamContentLoggingData;
-import org.chromium.chrome.browser.feed.library.sharedstream.offlinemonitor.StreamOfflineMonitor;
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ContentChangedListener;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionPayloadProto.FeedActionPayload;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Frame;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.PietSharedState;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.Content;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.PietContent;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.RepresentationData;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-/** {@link FeatureDriver} for content. */
-public class ContentDriver
-        extends LeafFeatureDriver implements LoggingListener, ViewElementActionHandler {
-    private static final String TAG = "ContentDriver";
-
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final List<PietSharedState> mPietSharedStates;
-    private final Frame mFrame;
-    private final StreamActionApi mStreamActionApi;
-    private final FeedActionPayload mSwipeAction;
-    private final String mContentId;
-    private final StreamOfflineMonitor mStreamOfflineMonitor;
-    private final OfflineStatusConsumer mOfflineStatusConsumer;
-    private final String mContentUrl;
-    private final ContentChangedListener mContentChangedListener;
-    private final ActionParser mActionParser;
-    private final MainThreadRunner mMainThreadRunner;
-    private final long mViewDelayMs;
-    private final HashMap<Integer, CancelableTask> mViewActionTaskMap = new HashMap<>();
-    private final ViewLoggingUpdater mViewLoggingUpdater;
-    private final ResettableOneShotVisibilityLoggingListener mLoggingListener;
-
-    private StreamContentLoggingData mContentLoggingData;
-    private boolean mAvailableOffline;
-    @Nullable
-    private PietViewHolder mViewHolder;
-
-    // TODO: Remove these suppressions when drivers have a proper lifecycle.
-    @SuppressWarnings(
-            {"nullness:argument.type.incompatible", "nullness:assignment.type.incompatible"})
-    ContentDriver(ActionApi actionApi, ActionManager actionManager,
-            ActionParserFactory actionParserFactory, BasicLoggingApi basicLoggingApi,
-            ModelFeature contentFeatureModel, ModelProvider modelProvider, int position,
-            FeedActionPayload swipeAction, ClusterPendingDismissHelper clusterPendingDismissHelper,
-            StreamOfflineMonitor streamOfflineMonitor,
-            ContentChangedListener contentChangedListener, ContextMenuManager contextMenuManager,
-            MainThreadRunner mainThreadRunner, Configuration configuration,
-            ViewLoggingUpdater viewLoggingUpdater, TooltipApi tooltipApi) {
-        this.mMainThreadRunner = mainThreadRunner;
-        mViewDelayMs = configuration.getValueOrDefault(
-                ConfigKey.VIEW_MIN_TIME_MS, Constants.VIEW_MIN_TIME_MS_DEFAULT);
-        Content content = contentFeatureModel.getStreamFeature().getContent();
-
-        PietContent pietContent = getPietContent(content);
-        this.mBasicLoggingApi = basicLoggingApi;
-        mFrame = pietContent.getFrame();
-        mPietSharedStates = getPietSharedStates(pietContent, modelProvider, basicLoggingApi);
-        mContentId = contentFeatureModel.getStreamFeature().getContentId();
-        RepresentationData representationData = content.getRepresentationData();
-        mContentUrl = representationData.getUri();
-        mAvailableOffline = streamOfflineMonitor.isAvailableOffline(mContentUrl);
-        mOfflineStatusConsumer = new OfflineStatusConsumer();
-        streamOfflineMonitor.addOfflineStatusConsumer(mContentUrl, mOfflineStatusConsumer);
-        mContentLoggingData = new StreamContentLoggingData(
-                position, content.getBasicLoggingMetadata(), representationData, mAvailableOffline);
-        mActionParser = actionParserFactory.build(
-                ()
-                        -> ContentMetadata.maybeCreateContentMetadata(
-                                content.getOfflineMetadata(), representationData));
-        mStreamActionApi =
-                createStreamActionApi(actionApi, mActionParser, actionManager, basicLoggingApi,
-                        ()
-                                -> mContentLoggingData,
-                        modelProvider.getSessionId(), contextMenuManager,
-                        clusterPendingDismissHelper, this, mContentId, tooltipApi);
-        this.mSwipeAction = swipeAction;
-        this.mStreamOfflineMonitor = streamOfflineMonitor;
-        this.mContentChangedListener = contentChangedListener;
-        this.mViewLoggingUpdater = viewLoggingUpdater;
-        mLoggingListener = new ResettableOneShotVisibilityLoggingListener(this);
-        viewLoggingUpdater.registerObserver(mLoggingListener);
-    }
-
-    @Override
-    public void onDestroy() {
-        mStreamOfflineMonitor.removeOfflineStatusConsumer(mContentUrl, mOfflineStatusConsumer);
-        removeAllPendingTasks();
-        mViewLoggingUpdater.unregisterObserver(mLoggingListener);
-    }
-
-    @Override
-    public LeafFeatureDriver getLeafFeatureDriver() {
-        return this;
-    }
-
-    private PietContent getPietContent(Content content) {
-        checkState(content.getType() == StreamStructureProto.Content.Type.PIET,
-                "Expected Piet type for feature");
-
-        checkState(content.hasExtension(PietContent.pietContentExtension),
-                "Expected Piet content for feature");
-
-        return content.getExtension(PietContent.pietContentExtension);
-    }
-
-    private List<PietSharedState> getPietSharedStates(
-            PietContent pietContent, ModelProvider modelProvider, BasicLoggingApi basicLoggingApi) {
-        List<PietSharedState> sharedStates = new ArrayList<>();
-        for (ContentId contentId : pietContent.getPietSharedStatesList()) {
-            PietSharedState pietSharedState =
-                    extractPietSharedState(contentId, modelProvider, basicLoggingApi);
-            if (pietSharedState == null) {
-                return new ArrayList<>();
-            }
-
-            sharedStates.add(pietSharedState);
-        }
-        return sharedStates;
-    }
-
-    @Nullable
-    private PietSharedState extractPietSharedState(ContentId pietSharedStateId,
-            ModelProvider modelProvider, BasicLoggingApi basicLoggingApi) {
-        StreamSharedState sharedState = modelProvider.getSharedState(pietSharedStateId);
-        if (sharedState != null) {
-            return sharedState.getPietSharedStateItem().getPietSharedState();
-        }
-
-        basicLoggingApi.onInternalError(InternalFeedError.NULL_SHARED_STATES);
-        Logger.e(TAG,
-                "Shared state was null. Stylesheets and templates on PietSharedState "
-                        + "will not be loaded.");
-        return null;
-    }
-
-    @Override
-    public void bind(FeedViewHolder viewHolder) {
-        if (!(viewHolder instanceof PietViewHolder)) {
-            throw new AssertionError();
-        }
-
-        this.mViewHolder = (PietViewHolder) viewHolder;
-
-        ((PietViewHolder) viewHolder)
-                .bind(mFrame, mPietSharedStates, mStreamActionApi, mSwipeAction, mLoggingListener,
-                        mActionParser);
-    }
-
-    @Override
-    public void unbind() {
-        if (mViewHolder == null) {
-            return;
-        }
-
-        mViewHolder.unbind();
-        mViewHolder = null;
-    }
-
-    @Override
-    public void maybeRebind() {
-        if (mViewHolder == null) {
-            return;
-        }
-
-        // Unbinding clears the viewHolder, so storing to rebind.
-        PietViewHolder localViewHolder = mViewHolder;
-        unbind();
-        bind(localViewHolder);
-        mContentChangedListener.onContentChanged();
-    }
-
-    @Override
-    public int getItemViewType() {
-        return ViewHolderType.TYPE_CARD;
-    }
-
-    @Override
-    public long itemId() {
-        return hashCode();
-    }
-
-    @VisibleForTesting
-    boolean isBound() {
-        return mViewHolder != null;
-    }
-
-    @Override
-    public String getContentId() {
-        return mContentId;
-    }
-
-    @Override
-    public void onViewVisible() {
-        mBasicLoggingApi.onContentViewed(mContentLoggingData);
-    }
-
-    @Override
-    public void onContentClicked() {
-        mBasicLoggingApi.onContentClicked(mContentLoggingData);
-    }
-
-    @Override
-    public void onContentSwiped() {
-        mBasicLoggingApi.onContentSwiped(mContentLoggingData);
-    }
-
-    @Override
-    public void onScrollStateChanged(int newScrollState) {
-        if (newScrollState != RecyclerView.SCROLL_STATE_IDLE) {
-            removeAllPendingTasks();
-        }
-    }
-
-    private void removeAllPendingTasks() {
-        for (CancelableTask cancellable : mViewActionTaskMap.values()) {
-            cancellable.cancel();
-        }
-
-        mViewActionTaskMap.clear();
-    }
-
-    private void removePendingViewActionTaskForElement(int elementType) {
-        CancelableTask cancelable = mViewActionTaskMap.remove(elementType);
-        if (cancelable != null) {
-            cancelable.cancel();
-        }
-    }
-
-    @VisibleForTesting
-    StreamActionApi createStreamActionApi(ActionApi actionApi, ActionParser actionParser,
-            ActionManager actionManager, BasicLoggingApi basicLoggingApi,
-            Supplier<ContentLoggingData> contentLoggingData, @Nullable String sessionId,
-            ContextMenuManager contextMenuManager,
-            ClusterPendingDismissHelper clusterPendingDismissHelper,
-            ViewElementActionHandler handler, String contentId, TooltipApi tooltipApi) {
-        return new StreamActionApiImpl(actionApi, actionParser, actionManager, basicLoggingApi,
-                contentLoggingData, contextMenuManager, sessionId, clusterPendingDismissHelper,
-                handler, contentId, tooltipApi);
-    }
-
-    @Override
-    public void onElementView(int elementType) {
-        removePendingViewActionTaskForElement(elementType);
-        CancelableTask cancelableTask = mMainThreadRunner.executeWithDelay(TAG + elementType,
-                ()
-                        -> mBasicLoggingApi.onVisualElementViewed(mContentLoggingData, elementType),
-                mViewDelayMs);
-        mViewActionTaskMap.put(elementType, cancelableTask);
-    }
-
-    @Override
-    public void onElementHide(int elementType) {
-        removePendingViewActionTaskForElement(elementType);
-    }
-
-    private class OfflineStatusConsumer implements Consumer<Boolean> {
-        @Override
-        public void accept(Boolean offlineStatus) {
-            if (offlineStatus.equals(mAvailableOffline)) {
-                return;
-            }
-
-            mAvailableOffline = offlineStatus;
-            mContentLoggingData = mContentLoggingData.createWithOfflineStatus(offlineStatus);
-            maybeRebind();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ContinuationDriver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ContinuationDriver.java
deleted file mode 100644
index 1904cb1..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ContinuationDriver.java
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.drivers;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import android.content.Context;
-import android.view.View;
-import android.view.View.OnClickListener;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.InternalFeedError;
-import org.chromium.chrome.browser.feed.library.api.host.logging.SpinnerType;
-import org.chromium.chrome.browser.feed.library.api.host.stream.SnackbarApi;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild.Type;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelCursor;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelError;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelToken;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.TokenCompleted;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.TokenCompletedObserver;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ContinuationViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.FeedViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ViewHolderType;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.sharedstream.logging.LoggingListener;
-import org.chromium.chrome.browser.feed.library.sharedstream.logging.SpinnerLogger;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** {@link FeatureDriver} for the more button. */
-public class ContinuationDriver extends LeafFeatureDriver
-        implements OnClickListener, LoggingListener, TokenCompletedObserver {
-    private static final String TAG = "ContinuationDriver";
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final Context mContext;
-    private final CursorChangedListener mCursorChangedListener;
-    private final ModelChild mModelChild;
-    private final ModelToken mModelToken;
-    private final ModelProvider mModelProvider;
-    private final int mPosition;
-    private final SnackbarApi mSnackbarApi;
-    private final SpinnerLogger mSpinnerLogger;
-    private final ThreadUtils mThreadUtils;
-    private final boolean mConsumeSyntheticTokens;
-
-    private boolean mShowSpinner;
-    private boolean mInitialized;
-    private boolean mViewLogged;
-    private boolean mDestroyed;
-    private boolean mTokenHandled;
-    private int mFailureCount;
-    @SpinnerType
-    private int mSpinnerType = SpinnerType.INFINITE_FEED;
-    @Nullable
-    private ContinuationViewHolder mContinuationViewHolder;
-
-    ContinuationDriver(BasicLoggingApi basicLoggingApi, Clock clock, Configuration configuration,
-            Context context, CursorChangedListener cursorChangedListener, ModelChild modelChild,
-            ModelProvider modelProvider, int position, SnackbarApi snackbarApi,
-            ThreadUtils threadUtils, boolean restoring) {
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mContext = context;
-        this.mCursorChangedListener = cursorChangedListener;
-        this.mModelChild = modelChild;
-        this.mModelProvider = modelProvider;
-        this.mModelToken = modelChild.getModelToken();
-        this.mPosition = position;
-        this.mSnackbarApi = snackbarApi;
-        this.mSpinnerLogger = createSpinnerLogger(basicLoggingApi, clock);
-        this.mThreadUtils = threadUtils;
-        this.mShowSpinner =
-                configuration.getValueOrDefault(ConfigKey.TRIGGER_IMMEDIATE_PAGINATION, false);
-        this.mConsumeSyntheticTokens =
-                configuration.getValueOrDefault(ConfigKey.CONSUME_SYNTHETIC_TOKENS, false)
-                || (restoring
-                        && configuration.getValueOrDefault(
-                                ConfigKey.CONSUME_SYNTHETIC_TOKENS_WHILE_RESTORING, false));
-    }
-
-    public boolean hasTokenBeenHandled() {
-        return mTokenHandled;
-    }
-
-    public void initialize() {
-        if (mInitialized) {
-            return;
-        }
-
-        mInitialized = true;
-        mModelToken.registerObserver(this);
-        if (mModelToken.isSynthetic() && mConsumeSyntheticTokens) {
-            Logger.d(TAG, "Handling synthetic token");
-            boolean tokenWillBeHandled = mModelProvider.handleToken(mModelToken);
-            if (tokenWillBeHandled) {
-                mShowSpinner = true;
-                mSpinnerType = SpinnerType.SYNTHETIC_TOKEN;
-                mTokenHandled = true;
-            } else {
-                Logger.e(TAG, "Synthetic token was not handled");
-                mBasicLoggingApi.onInternalError(InternalFeedError.UNHANDLED_TOKEN);
-            }
-        }
-    }
-
-    @Override
-    public void onDestroy() {
-        mDestroyed = true;
-
-        if (mInitialized) {
-            mModelToken.unregisterObserver(this);
-        }
-        // If the spinner was being shown, it will only be removed when the ContinuationDriver is
-        // destroyed. So onSpinnerShown should be logged then.
-        if (mSpinnerLogger.isSpinnerActive()) {
-            mSpinnerLogger.spinnerDestroyedWithoutCompleting();
-        }
-    }
-
-    // TODO: Instead of implementing an onClickListener, define a new interface with a method
-    // with no view argument.
-    @Override
-    public void onClick(View v) {
-        if (!isBound()) {
-            Logger.wtf(TAG, "Calling onClick before binding.");
-            return;
-        }
-        boolean tokenWillBeHandled = mModelProvider.handleToken(mModelToken);
-        if (tokenWillBeHandled) {
-            mShowSpinner = true;
-            mSpinnerLogger.spinnerStarted(SpinnerType.MORE_BUTTON);
-            checkNotNull(mContinuationViewHolder).setShowSpinner(true);
-            mTokenHandled = true;
-        } else {
-            Logger.e(TAG, "Continuation token was not handled");
-            mBasicLoggingApi.onInternalError(InternalFeedError.UNHANDLED_TOKEN);
-            showErrorUi();
-        }
-    }
-
-    @Override
-    public void bind(FeedViewHolder viewHolder) {
-        checkState(mInitialized);
-        if (isBound()) {
-            Logger.wtf(TAG, "Rebinding.");
-        }
-        checkState(viewHolder instanceof ContinuationViewHolder);
-
-        mContinuationViewHolder = (ContinuationViewHolder) viewHolder;
-        mContinuationViewHolder.bind(
-                /* onClickListener= */ this, /* loggingListener= */ this, mShowSpinner);
-        if (mShowSpinner && !mSpinnerLogger.isSpinnerActive()) {
-            mSpinnerLogger.spinnerStarted(mSpinnerType);
-        }
-    }
-
-    @Override
-    public int getItemViewType() {
-        return ViewHolderType.TYPE_CONTINUATION;
-    }
-
-    @Override
-    public void unbind() {
-        if (mContinuationViewHolder == null) {
-            return;
-        }
-
-        mContinuationViewHolder.unbind();
-        mContinuationViewHolder = null;
-    }
-
-    @Override
-    public void maybeRebind() {
-        if (mContinuationViewHolder == null) {
-            return;
-        }
-
-        // Unbinding clears the viewHolder, so storing to rebind.
-        ContinuationViewHolder localViewHolder = mContinuationViewHolder;
-        unbind();
-        bind(localViewHolder);
-    }
-
-    @Override
-    public void onTokenCompleted(TokenCompleted tokenCompleted) {
-        mThreadUtils.checkMainThread();
-        if (mDestroyed) {
-            // Tokens are able to send onTokenCompleted even after unregistering.  This can happen
-            // due to thread switching.  This prevents tokens from being handled after the driver
-            // has been destroyed and should no longer be handled.
-            Logger.w(TAG, "Received onTokenCompleted after being destroyed.");
-            return;
-        }
-
-        // Spinner wouldn't be active if we are automatically consuming a synthetic token on
-        // restore.
-        if (mSpinnerLogger.isSpinnerActive()) {
-            mSpinnerLogger.spinnerFinished();
-        }
-
-        ModelCursor cursor = tokenCompleted.getCursor();
-        List<ModelChild> modelChildren = extractModelChildrenFromCursor(cursor);
-
-        // Display snackbar if there are no more cards. The snackbar should only be shown if the
-        // spinner is being shown. This ensures the snackbar is only shown in the instance of the
-        // Stream that triggered the pagination.
-        if (mShowSpinner
-                && (modelChildren.isEmpty()
-                        || (modelChildren.size() == 1
-                                && modelChildren.get(0).getType() == Type.TOKEN))) {
-            mSnackbarApi.show(mContext.getResources().getString(
-                    R.string.ntp_suggestions_fetch_no_new_suggestions));
-        }
-
-        mCursorChangedListener.onNewChildren(mModelChild, modelChildren, mModelToken.isSynthetic());
-    }
-
-    @Override
-    public void onError(ModelError modelError) {
-        mBasicLoggingApi.onTokenFailedToComplete(mModelToken.isSynthetic(), ++mFailureCount);
-        showErrorUi();
-        if (mSpinnerLogger.isSpinnerActive()) {
-            mSpinnerLogger.spinnerFinished();
-        }
-    }
-
-    private void showErrorUi() {
-        mShowSpinner = false;
-
-        if (mContinuationViewHolder != null) {
-            mContinuationViewHolder.setShowSpinner(false);
-        }
-
-        mSnackbarApi.show(mContext.getString(R.string.ntp_suggestions_fetch_failed));
-    }
-
-    @Override
-    public void onViewVisible() {
-        // Do not log a view if the spinner is being shown.
-        if (mViewLogged || mShowSpinner) {
-            return;
-        }
-
-        mBasicLoggingApi.onMoreButtonViewed(mPosition);
-        mViewLogged = true;
-    }
-
-    @Override
-    public void onContentClicked() {
-        mBasicLoggingApi.onMoreButtonClicked(mPosition);
-    }
-
-    @Override
-    public void onContentSwiped() {}
-
-    // TODO: add similar view logging cancelation and time delay for the More button
-    @Override
-    public void onScrollStateChanged(int newScrollState) {}
-
-    private List<ModelChild> extractModelChildrenFromCursor(ModelCursor cursor) {
-        List<ModelChild> modelChildren = new ArrayList<>();
-        ModelChild child;
-        while ((child = cursor.getNextItem()) != null) {
-            if (child.getType() == Type.UNBOUND) {
-                Logger.e(TAG, "Found unbound child %s, ignoring it", child.getContentId());
-                continue;
-            } else if (child.getType() != Type.FEATURE && child.getType() != Type.TOKEN) {
-                Logger.wtf(TAG, "Received illegal child: %s from cursor.", child.getType());
-                continue;
-            }
-            modelChildren.add(child);
-        }
-
-        return modelChildren;
-    }
-
-    /** Interface for notifying parents of new model children from a token. */
-    public interface CursorChangedListener {
-        /**
-         * Called to inform parent of new model children.
-         *
-         * @param modelChild the {@link ModelChild} representing the token that was processed.
-         * @param modelChildren the list of new {@link ModelChild} from the token.
-         * @param wasSynthetic whether the token was synthetic.
-         */
-        void onNewChildren(
-                ModelChild modelChild, List<ModelChild> modelChildren, boolean wasSynthetic);
-    }
-
-    @VisibleForTesting
-    boolean isBound() {
-        return mContinuationViewHolder != null;
-    }
-
-    @VisibleForTesting
-    SpinnerLogger createSpinnerLogger(BasicLoggingApi basicLoggingApi, Clock clock) {
-        return new SpinnerLogger(basicLoggingApi, clock);
-    }
-
-    @Override
-    public String getContentId() {
-        return mModelToken.getStreamToken().getContentId();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/FeatureDriver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/FeatureDriver.java
deleted file mode 100644
index 12834879..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/FeatureDriver.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.drivers;
-
-import androidx.annotation.Nullable;
-/**
- * A FeatureDriver is an object which can generate a {@link LeafFeatureDriver} from a {@link
- * org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature}.
- */
-public interface FeatureDriver {
-    void onDestroy();
-
-    @Nullable
-    LeafFeatureDriver getLeafFeatureDriver();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/HeaderDriver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/HeaderDriver.java
deleted file mode 100644
index 29528624..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/HeaderDriver.java
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.drivers;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.FeedViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.HeaderViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.SwipeNotifier;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ViewHolderType;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.shared.stream.Header;
-
-/** {@link FeatureDriver} for headers. */
-public class HeaderDriver extends LeafFeatureDriver {
-    private static final String TAG = "HeaderDriver";
-
-    private final Header mHeader;
-    private final SwipeNotifier mSwipeNotifier;
-    @Nullable
-    private HeaderViewHolder mHeaderViewHolder;
-
-    public HeaderDriver(Header header, SwipeNotifier swipeNotifier) {
-        this.mHeader = header;
-        this.mSwipeNotifier = swipeNotifier;
-    }
-
-    @Override
-    public void bind(FeedViewHolder viewHolder) {
-        if (isBound()) {
-            if (viewHolder == this.mHeaderViewHolder) {
-                Logger.e(TAG, "Being rebound to the previously bound viewholder");
-                return;
-            }
-            unbind();
-        }
-
-        checkState(viewHolder instanceof HeaderViewHolder);
-        mHeaderViewHolder = (HeaderViewHolder) viewHolder;
-        mHeaderViewHolder.bind(mHeader, mSwipeNotifier);
-    }
-
-    @Override
-    public void unbind() {
-        if (mHeaderViewHolder == null) {
-            return;
-        }
-
-        mHeaderViewHolder.unbind();
-        mHeaderViewHolder = null;
-    }
-
-    @Override
-    public void maybeRebind() {
-        if (mHeaderViewHolder == null) {
-            return;
-        }
-
-        // Unbinding clears the viewHolder, so storing to rebind.
-        HeaderViewHolder localViewHolder = mHeaderViewHolder;
-        unbind();
-        bind(localViewHolder);
-    }
-
-    @Override
-    public int getItemViewType() {
-        return ViewHolderType.TYPE_HEADER;
-    }
-
-    @Override
-    public void onDestroy() {}
-
-    public Header getHeader() {
-        return mHeader;
-    }
-
-    @VisibleForTesting
-    boolean isBound() {
-        return mHeaderViewHolder != null;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/LeafFeatureDriver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/LeafFeatureDriver.java
deleted file mode 100644
index d768637..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/LeafFeatureDriver.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.drivers;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.FeedViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ViewHolderType;
-
-/** A {@link FeatureDriver} that can bind to a {@link FeedViewHolder}. */
-public abstract class LeafFeatureDriver implements FeatureDriver {
-    @Override
-    public LeafFeatureDriver getLeafFeatureDriver() {
-        return this;
-    }
-
-    /** Bind to the given {@link FeedViewHolder}. */
-    public abstract void bind(FeedViewHolder viewHolder);
-
-    /**
-     * Returns a {@link ViewHolderType} that corresponds to the type of {@link FeedViewHolder} that
-     * can be bound to.
-     */
-    @ViewHolderType
-    public abstract int getItemViewType();
-
-    /** Returns an ID corresponding to this item, typically a hashcode. */
-    public long itemId() {
-        return hashCode();
-    }
-
-    /**
-     * Called when the {@link
-     * org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.FeedViewHolder} is
-     * offscreen/unbound.
-     *
-     * <p>Note: {@link LeafFeatureDriver} instances should do work they need to to unbind themselves
-     * and their previously bound {@link FeedViewHolder}.
-     */
-    public abstract void unbind();
-
-    /**
-     * This will cause the FeatureHolder associated with the Driver to rebind (unbind followed by
-     * bind).
-     */
-    public abstract void maybeRebind();
-
-    /** Returns the contentId of the {@link LeafFeatureDriver} if it has one. */
-    @Nullable
-    public String getContentId() {
-        return null;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/NoContentDriver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/NoContentDriver.java
deleted file mode 100644
index 849a23d8..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/NoContentDriver.java
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.drivers;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.FeedViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.NoContentViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ViewHolderType;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-/** {@link FeatureDriver} for NoContent card. */
-public class NoContentDriver extends LeafFeatureDriver {
-    private static final String TAG = "NoContentDriver";
-    @Nullable
-    private NoContentViewHolder mNoContentViewHolder;
-
-    @Override
-    public void bind(FeedViewHolder viewHolder) {
-        if (isBound()) {
-            Logger.wtf(TAG, "Rebinding.");
-        }
-
-        checkState(viewHolder instanceof NoContentViewHolder);
-        mNoContentViewHolder = (NoContentViewHolder) viewHolder;
-        mNoContentViewHolder.bind();
-    }
-
-    @Override
-    public int getItemViewType() {
-        return ViewHolderType.TYPE_NO_CONTENT;
-    }
-
-    @Override
-    public void unbind() {
-        if (mNoContentViewHolder == null) {
-            return;
-        }
-
-        mNoContentViewHolder.unbind();
-        mNoContentViewHolder = null;
-    }
-
-    @Override
-    public void maybeRebind() {
-        if (mNoContentViewHolder == null) {
-            return;
-        }
-
-        // Unbinding clears the viewHolder, so storing to rebind.
-        NoContentViewHolder localViewHolder = mNoContentViewHolder;
-        unbind();
-        bind(localViewHolder);
-    }
-
-    @VisibleForTesting
-    boolean isBound() {
-        return mNoContentViewHolder != null;
-    }
-
-    @Override
-    public void onDestroy() {}
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/StreamDriver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/StreamDriver.java
deleted file mode 100644
index 29f62c4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/StreamDriver.java
+++ /dev/null
@@ -1,677 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.drivers;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-
-import android.content.Context;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.library.api.host.action.ActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.InternalFeedError;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ZeroStateShowReason;
-import org.chromium.chrome.browser.feed.library.api.host.stream.SnackbarApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.SnackbarCallbackApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipApi;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionParserFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.knowncontent.FeedKnownContent;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.FeatureChange;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.FeatureChangeObserver;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild.Type;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelCursor;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider.State;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.drivers.ContinuationDriver.CursorChangedListener;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.pendingdismiss.PendingDismissHandler;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.scroll.BasicStreamScrollMonitor;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.scroll.BasicStreamScrollTracker;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.scroll.ScrollRestorer;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewloggingupdater.ViewLoggingUpdater;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.sharedstream.contextmenumanager.ContextMenuManager;
-import org.chromium.chrome.browser.feed.library.sharedstream.offlinemonitor.StreamOfflineMonitor;
-import org.chromium.chrome.browser.feed.library.sharedstream.pendingdismiss.PendingDismissCallback;
-import org.chromium.chrome.browser.feed.library.sharedstream.removetrackingfactory.StreamRemoveTrackingFactory;
-import org.chromium.chrome.browser.feed.library.sharedstream.scroll.ScrollLogger;
-import org.chromium.chrome.browser.feed.shared.ScrollTracker;
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ContentChangedListener;
-import org.chromium.components.feed.core.proto.libraries.sharedstream.UiRefreshReasonProto.UiRefreshReason;
-import org.chromium.components.feed.core.proto.libraries.sharedstream.UiRefreshReasonProto.UiRefreshReason.Reason;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.UndoAction;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/** Generates a list of {@link LeafFeatureDriver} instances for an entire stream. */
-public class StreamDriver
-        implements CursorChangedListener, FeatureChangeObserver, PendingDismissHandler {
-    private static final String TAG = "StreamDriver";
-    private final ActionApi mActionApi;
-    private final ActionManager mActionManager;
-    private final ActionParserFactory mActionParserFactory;
-    private final ThreadUtils mThreadUtils;
-    private final ModelProvider mModelProvider;
-    private final Map<ModelChild, FeatureDriver> mModelChildFeatureDriverMap;
-    private final List<FeatureDriver> mFeatureDrivers;
-    private final Clock mClock;
-    private final Configuration mConfiguration;
-    private final Context mContext;
-    private final SnackbarApi mSnackbarApi;
-    private final ContentChangedListener mContentChangedListener;
-    private final ScrollRestorer mScrollRestorer;
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final StreamOfflineMonitor mStreamOfflineMonitor;
-    private final ContextMenuManager mContextMenuManager;
-    private final boolean mIsInitialLoad;
-    private final MainThreadRunner mMainThreadRunner;
-    private final ViewLoggingUpdater mViewLoggingUpdater;
-    private final TooltipApi mTooltipApi;
-    private final UiRefreshReason mUiRefreshReason;
-    private final ScrollTracker mScrollTracker;
-
-    private boolean mRestoring;
-    private boolean mRootFeatureConsumed;
-    private boolean mModelFeatureChangeObserverRegistered;
-    @Nullable
-    private StreamContentListener mContentListener;
-
-    public StreamDriver(ActionApi actionApi, ActionManager actionManager,
-            ActionParserFactory actionParserFactory, ModelProvider modelProvider,
-            ThreadUtils threadUtils, Clock clock, Configuration configuration, Context context,
-            SnackbarApi snackbarApi, ContentChangedListener contentChangedListener,
-            ScrollRestorer scrollRestorer, BasicLoggingApi basicLoggingApi,
-            StreamOfflineMonitor streamOfflineMonitor, FeedKnownContent feedKnownContent,
-            ContextMenuManager contextMenuManager, boolean restoring, boolean isInitialLoad,
-            MainThreadRunner mainThreadRunner, ViewLoggingUpdater viewLoggingUpdater,
-            TooltipApi tooltipApi, UiRefreshReason uiRefreshReason,
-            BasicStreamScrollMonitor scrollMonitor) {
-        this.mActionApi = actionApi;
-        this.mActionManager = actionManager;
-        this.mActionParserFactory = actionParserFactory;
-        this.mThreadUtils = threadUtils;
-        this.mModelProvider = modelProvider;
-        this.mClock = clock;
-        this.mContext = context;
-        this.mSnackbarApi = snackbarApi;
-        this.mContextMenuManager = contextMenuManager;
-        this.mModelChildFeatureDriverMap = new HashMap<>();
-        this.mFeatureDrivers = new ArrayList<>();
-        this.mConfiguration = configuration;
-        this.mContentChangedListener = contentChangedListener;
-        this.mScrollRestorer = scrollRestorer;
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mStreamOfflineMonitor = streamOfflineMonitor;
-        this.mRestoring = restoring;
-        this.mIsInitialLoad = isInitialLoad;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mViewLoggingUpdater = viewLoggingUpdater;
-        this.mTooltipApi = tooltipApi;
-        this.mUiRefreshReason = uiRefreshReason;
-        mScrollTracker =
-                new BasicStreamScrollTracker(new ScrollLogger(basicLoggingApi), scrollMonitor);
-
-        modelProvider.enableRemoveTracking(
-                new StreamRemoveTrackingFactory(modelProvider, feedKnownContent));
-    }
-
-    /**
-     * Returns a the list of {@link LeafFeatureDriver} instances for the children generated from the
-     * given {@link ModelFeature}.
-     */
-    public List<LeafFeatureDriver> getLeafFeatureDrivers() {
-        if (mModelProvider.getCurrentState() == State.READY && !mRootFeatureConsumed) {
-            ChildCreationPayload childCreationPayload;
-            mRootFeatureConsumed = true;
-            ModelFeature rootFeature = mModelProvider.getRootFeature();
-            if (rootFeature != null) {
-                childCreationPayload = createAndInsertChildren(rootFeature, mModelProvider);
-                rootFeature.registerObserver(this);
-                mModelFeatureChangeObserverRegistered = true;
-                if (mUiRefreshReason.getReason().equals(Reason.ZERO_STATE)) {
-                    mBasicLoggingApi.onZeroStateRefreshCompleted(
-                            childCreationPayload.mContentCount, childCreationPayload.mTokenCount);
-                }
-            } else {
-                mBasicLoggingApi.onInternalError(InternalFeedError.NO_ROOT_FEATURE);
-                Logger.w(TAG, "found null root feature loading Leaf Feature Drivers");
-                if (mUiRefreshReason.getReason().equals(Reason.ZERO_STATE)) {
-                    mBasicLoggingApi.onZeroStateRefreshCompleted(
-                            /* newContentCount= */ 0, /* newTokenCount= */ 0);
-                }
-            }
-        }
-
-        if (!mIsInitialLoad) {
-            addNoContentCardOrZeroStateIfNecessary(ZeroStateShowReason.NO_CONTENT);
-        }
-
-        return buildLeafFeatureDrivers(mFeatureDrivers);
-    }
-
-    public void maybeRestoreScroll() {
-        if (!mRestoring) {
-            return;
-        }
-
-        if (isLastDriverContinuationDriver()) {
-            ContinuationDriver continuationDriver =
-                    (ContinuationDriver) mFeatureDrivers.get(mFeatureDrivers.size() - 1);
-            // If there is a synthetic token, we should only restore if it has not been handled yet.
-            if (continuationDriver.hasTokenBeenHandled()) {
-                return;
-            }
-        }
-
-        mRestoring = false;
-
-        mScrollRestorer.maybeRestoreScroll();
-    }
-
-    private ChildCreationPayload createAndInsertChildren(
-            ModelFeature streamFeature, ModelProvider modelProvider) {
-        return createAndInsertChildren(streamFeature.getCursor(), modelProvider);
-    }
-
-    private ChildCreationPayload createAndInsertChildren(
-            ModelCursor streamCursor, ModelProvider modelProvider) {
-        return createAndInsertChildrenAtIndex(streamCursor, modelProvider, 0);
-    }
-
-    private ChildCreationPayload createAndInsertChildrenAtIndex(
-            ModelCursor streamCursor, ModelProvider modelProvider, int insertionIndex) {
-        Iterable<ModelChild> cursorIterable = () -> new Iterator<ModelChild>() {
-            @Nullable
-            private ModelChild mNext;
-
-            @Override
-            public boolean hasNext() {
-                mNext = streamCursor.getNextItem();
-                return mNext != null;
-            }
-
-            @Override
-            public ModelChild next() {
-                return checkNotNull(mNext);
-            }
-        };
-        return createAndInsertChildrenAtIndex(cursorIterable, modelProvider, insertionIndex);
-    }
-
-    private ChildCreationPayload createAndInsertChildrenAtIndex(
-            Iterable<ModelChild> modelChildren, ModelProvider modelProvider, int insertionIndex) {
-        List<FeatureDriver> newChildren = new ArrayList<>();
-
-        int tokenCount = 0;
-        int contentCount = 0;
-
-        for (ModelChild child : modelChildren) {
-            FeatureDriver featureDriverChild = createChild(child, modelProvider, insertionIndex);
-            if (featureDriverChild != null) {
-                if (child.getType() == Type.FEATURE) {
-                    contentCount++;
-                } else if (child.getType() == Type.TOKEN) {
-                    tokenCount++;
-                }
-                newChildren.add(featureDriverChild);
-                mFeatureDrivers.add(insertionIndex, featureDriverChild);
-                mModelChildFeatureDriverMap.put(child, featureDriverChild);
-                insertionIndex++;
-            }
-        }
-
-        return new ChildCreationPayload(newChildren, tokenCount, contentCount);
-    }
-
-    @Nullable
-    private FeatureDriver createChild(ModelChild child, ModelProvider modelProvider, int position) {
-        switch (child.getType()) {
-            case Type.FEATURE:
-                return createFeatureChild(child.getModelFeature(), position);
-            case Type.TOKEN:
-                ContinuationDriver continuationDriver =
-                        createContinuationDriver(mBasicLoggingApi, mClock, mConfiguration, mContext,
-                                child, modelProvider, position, mSnackbarApi, mRestoring);
-
-                // TODO: Look into moving initialize() into a more generic location. We don't
-                // really want work to be done in the constructor so we call an initialize() method
-                // to kick off any expensive work the driver may need to do.
-                continuationDriver.initialize();
-                return continuationDriver;
-            case Type.UNBOUND:
-                mBasicLoggingApi.onInternalError(InternalFeedError.TOP_LEVEL_UNBOUND_CHILD);
-                Logger.e(TAG, "Found unbound child %s, ignoring it", child.getContentId());
-                return null;
-            default:
-                Logger.wtf(TAG, "Received illegal child: %s from cursor.", child.getType());
-                return null;
-        }
-    }
-
-    private @Nullable FeatureDriver createFeatureChild(ModelFeature modelFeature, int position) {
-        if (modelFeature.getStreamFeature().hasCard()) {
-            return createCardDriver(modelFeature, position);
-        } else if (modelFeature.getStreamFeature().hasCluster()) {
-            return createClusterDriver(modelFeature, position);
-        }
-
-        mBasicLoggingApi.onInternalError(InternalFeedError.TOP_LEVEL_INVALID_FEATURE_TYPE);
-        Logger.w(TAG, "Invalid StreamFeature Type, must be Card or Cluster but was %s",
-                modelFeature.getStreamFeature().getFeaturePayloadCase());
-        return null;
-    }
-
-    private List<LeafFeatureDriver> buildLeafFeatureDrivers(List<FeatureDriver> featureDrivers) {
-        List<LeafFeatureDriver> leafFeatureDrivers = new ArrayList<>();
-        List<FeatureDriver> removes = new ArrayList<>();
-        for (FeatureDriver featureDriver : featureDrivers) {
-            LeafFeatureDriver leafFeatureDriver = featureDriver.getLeafFeatureDriver();
-            if (leafFeatureDriver != null) {
-                leafFeatureDrivers.add(leafFeatureDriver);
-            } else {
-                mBasicLoggingApi.onInternalError(InternalFeedError.FAILED_TO_CREATE_LEAF);
-                removes.add(featureDriver);
-            }
-        }
-        for (FeatureDriver driver : removes) {
-            this.mFeatureDrivers.remove(driver);
-            driver.onDestroy();
-        }
-
-        mStreamOfflineMonitor.requestOfflineStatusForNewContent();
-
-        return leafFeatureDrivers;
-    }
-
-    @Override
-    public void onChange(FeatureChange change) {
-        Logger.v(TAG, "Received change.");
-
-        List<ModelChild> removedChildren = change.getChildChanges().getRemovedChildren();
-
-        for (ModelChild removedChild : removedChildren) {
-            if (!(removedChild.getType() == Type.FEATURE || removedChild.getType() == Type.TOKEN)) {
-                Logger.e(TAG, "Attempting to remove non-removable child of type: %s",
-                        removedChild.getType());
-                continue;
-            }
-
-            removeDriver(removedChild);
-        }
-
-        List<ModelChild> appendedChildren = change.getChildChanges().getAppendedChildren();
-
-        if (!appendedChildren.isEmpty()) {
-            int insertionIndex = mFeatureDrivers.size();
-
-            notifyContentsAdded(insertionIndex,
-                    buildLeafFeatureDrivers(createAndInsertChildrenAtIndex(
-                            appendedChildren, mModelProvider, insertionIndex)
-                                                    .mFeatureDrivers));
-        }
-
-        addNoContentCardOrZeroStateIfNecessary(ZeroStateShowReason.CONTENT_DISMISSED);
-    }
-
-    @Override
-    public void onNewChildren(
-            ModelChild modelChild, List<ModelChild> modelChildren, boolean wasSynthetic) {
-        int continuationIndex = removeDriver(modelChild);
-        if (continuationIndex < 0) {
-            Logger.wtf(TAG, "Received an onNewChildren for an unknown child.");
-            return;
-        }
-        ChildCreationPayload tokenPayload =
-                createAndInsertChildrenAtIndex(modelChildren, mModelProvider, continuationIndex);
-
-        List<FeatureDriver> newChildren = tokenPayload.mFeatureDrivers;
-
-        mBasicLoggingApi.onTokenCompleted(
-                wasSynthetic, tokenPayload.mContentCount, tokenPayload.mTokenCount);
-        notifyContentsAdded(continuationIndex, buildLeafFeatureDrivers(newChildren));
-        maybeRemoveNoContentOrZeroStateCard();
-        // Swap no content card with zero state if there are no more drivers.
-        if (newChildren.isEmpty() && mFeatureDrivers.size() == 1
-                && mFeatureDrivers.get(0) instanceof NoContentDriver) {
-            showZeroState(ZeroStateShowReason.NO_CONTENT_FROM_CONTINUATION_TOKEN);
-        }
-
-        maybeRestoreScroll();
-    }
-
-    private void alwaysRemoveNoContentOrZeroStateCardIfPresent() {
-        if (mFeatureDrivers.size() == 1
-                && ((mFeatureDrivers.get(0) instanceof NoContentDriver)
-                        || (mFeatureDrivers.get(0) instanceof ZeroStateDriver))) {
-            mFeatureDrivers.get(0).onDestroy();
-            mFeatureDrivers.remove(0);
-            notifyContentRemoved(0);
-        }
-    }
-
-    private void maybeRemoveNoContentOrZeroStateCard() {
-        if (shouldRemoveNoContentCardOrZeroState()) {
-            mFeatureDrivers.get(0).onDestroy();
-            mFeatureDrivers.remove(0);
-            notifyContentRemoved(0);
-        }
-    }
-
-    public void onDestroy() {
-        for (FeatureDriver featureDriver : mFeatureDrivers) {
-            featureDriver.onDestroy();
-        }
-        ModelFeature modelFeature = mModelProvider.getRootFeature();
-        if (modelFeature != null && mModelFeatureChangeObserverRegistered) {
-            modelFeature.unregisterObserver(this);
-            mModelFeatureChangeObserverRegistered = false;
-        }
-        mFeatureDrivers.clear();
-        mModelChildFeatureDriverMap.clear();
-        mScrollTracker.onUnbind();
-    }
-
-    public boolean hasContent() {
-        if (mFeatureDrivers.isEmpty()) {
-            return false;
-        }
-        return !(mFeatureDrivers.get(0) instanceof NoContentDriver)
-                && !(mFeatureDrivers.get(0) instanceof ZeroStateDriver);
-    }
-
-    public boolean isZeroStateBeingShown() {
-        return !mFeatureDrivers.isEmpty() && mFeatureDrivers.get(0) instanceof ZeroStateDriver
-                && !((ZeroStateDriver) mFeatureDrivers.get(0)).isSpinnerShowing();
-    }
-
-    public void setModelProviderForZeroState(ModelProvider modelProvider) {
-        if (!isZeroStateBeingShown()) {
-            Logger.wtf(TAG,
-                    "setModelProviderForZeroState should only be called when zero state is shown");
-            return;
-        }
-        ((ZeroStateDriver) mFeatureDrivers.get(0)).setModelProvider(modelProvider);
-    }
-
-    private void addNoContentCardOrZeroStateIfNecessary(
-            @ZeroStateShowReason int zeroStateShowReason) {
-        LeafFeatureDriver leafFeatureDriver = null;
-        if (!mRestoring && mFeatureDrivers.isEmpty()) {
-            leafFeatureDriver = createAndLogZeroState(zeroStateShowReason);
-        } else if (mFeatureDrivers.size() == 1 && isLastDriverContinuationDriver()) {
-            leafFeatureDriver = createNoContentDriver();
-        }
-
-        if (leafFeatureDriver != null) {
-            mFeatureDrivers.add(0, leafFeatureDriver);
-            notifyContentsAdded(0, Collections.singletonList(leafFeatureDriver));
-        }
-    }
-
-    private boolean shouldRemoveNoContentCardOrZeroState() {
-        if (mFeatureDrivers.isEmpty()) {
-            return false;
-        }
-
-        if (!(mFeatureDrivers.get(0) instanceof NoContentDriver)
-                && !(mFeatureDrivers.get(0) instanceof ZeroStateDriver)) {
-            return false;
-        }
-
-        return mFeatureDrivers.size() > 2
-                || (mFeatureDrivers.size() == 2 && !isLastDriverContinuationDriver());
-    }
-
-    private boolean isLastDriverContinuationDriver() {
-        return !mFeatureDrivers.isEmpty()
-                && mFeatureDrivers.get(mFeatureDrivers.size() - 1) instanceof ContinuationDriver;
-    }
-
-    /**
-     * Removes the {@link FeatureDriver} represented by the {@link ModelChild} from all collections
-     * containing it and updates any listening instances of {@link StreamContentListener} of the
-     * removal.
-     *
-     * <p>Returns the index at which the {@link FeatureDriver} was removed, or -1 if it was not
-     * found.
-     */
-    private int removeDriver(ModelChild modelChild) {
-        FeatureDriver featureDriver = mModelChildFeatureDriverMap.get(modelChild);
-        if (featureDriver == null) {
-            Logger.w(TAG, "Attempting to remove feature from ModelChild not in map, %s",
-                    modelChild.getContentId());
-            return -1;
-        }
-
-        for (int i = 0; i < mFeatureDrivers.size(); i++) {
-            if (mFeatureDrivers.get(i) == featureDriver) {
-                mFeatureDrivers.remove(i);
-                featureDriver.onDestroy();
-                mModelChildFeatureDriverMap.remove(modelChild);
-                notifyContentRemoved(i);
-                return i;
-            }
-        }
-
-        Logger.wtf(
-                TAG, "Attempting to remove feature contained on map but not on list of children.");
-        return -1;
-    }
-
-    private void notifyContentsAdded(int index, List<LeafFeatureDriver> leafFeatureDrivers) {
-        if (mContentListener != null) {
-            mContentListener.notifyContentsAdded(index, leafFeatureDrivers);
-        }
-    }
-
-    private void notifyContentRemoved(int index) {
-        if (mContentListener != null) {
-            mContentListener.notifyContentRemoved(index);
-        }
-    }
-
-    private void notifyContentsCleared() {
-        if (mContentListener != null) {
-            mContentListener.notifyContentsCleared();
-        }
-    }
-
-    /** Dismisses all content and immediately shows a spinner. */
-    public void showSpinner() {
-        ZeroStateDriver zeroStateDriver = createSpinner();
-        clearAllContent();
-        mFeatureDrivers.add(zeroStateDriver);
-        notifyContentsAdded(0, Collections.singletonList(zeroStateDriver));
-    }
-
-    /** Dismisses all content and shows the zero-state. */
-    public void showZeroState(@ZeroStateShowReason int zeroStateShowReason) {
-        ZeroStateDriver zeroStateDriver = createAndLogZeroState(zeroStateShowReason);
-        clearAllContent();
-        mFeatureDrivers.add(zeroStateDriver);
-        notifyContentsAdded(0, Collections.singletonList(zeroStateDriver));
-    }
-
-    private void clearAllContent() {
-        // TODO: Make sure to not notify listeners when driver is destroyed.
-        for (FeatureDriver featureDriver : mFeatureDrivers) {
-            featureDriver.onDestroy();
-        }
-        mFeatureDrivers.clear();
-        notifyContentsCleared();
-    }
-
-    private ZeroStateDriver createAndLogZeroState(@ZeroStateShowReason int zeroStateShowReason) {
-        mBasicLoggingApi.onZeroStateShown(zeroStateShowReason);
-
-        return createZeroStateDriver();
-    }
-
-    @VisibleForTesting
-    FeatureDriver createClusterDriver(ModelFeature modelFeature, int position) {
-        return new ClusterDriver(mActionApi, mActionManager, mActionParserFactory, mBasicLoggingApi,
-                modelFeature, mModelProvider, position, this, mStreamOfflineMonitor,
-                mContentChangedListener, mContextMenuManager, mMainThreadRunner, mConfiguration,
-                mViewLoggingUpdater, mTooltipApi);
-    }
-
-    @VisibleForTesting
-    FeatureDriver createCardDriver(ModelFeature modelFeature, int position) {
-        return new CardDriver(mActionApi, mActionManager, mActionParserFactory, mBasicLoggingApi,
-                modelFeature, mModelProvider, position,
-                (undoAction, pendingDismissCallback)
-                        -> {
-                    Logger.wtf(TAG, "Dismissing a card without a cluster is not supported.");
-                },
-                mStreamOfflineMonitor, mContentChangedListener, mContextMenuManager,
-                mMainThreadRunner, mConfiguration, mViewLoggingUpdater, mTooltipApi);
-    }
-
-    @VisibleForTesting
-    ContinuationDriver createContinuationDriver(BasicLoggingApi basicLoggingApi, Clock clock,
-            Configuration configuration, Context context, ModelChild modelChild,
-            ModelProvider modelProvider, int position, SnackbarApi snackbarApi, boolean restoring) {
-        return new ContinuationDriver(basicLoggingApi, clock, configuration, context, this,
-                modelChild, modelProvider, position, snackbarApi, mThreadUtils, restoring);
-    }
-
-    @VisibleForTesting
-    NoContentDriver createNoContentDriver() {
-        return new NoContentDriver();
-    }
-
-    @VisibleForTesting
-    ZeroStateDriver createZeroStateDriver() {
-        return new ZeroStateDriver(mBasicLoggingApi, mClock, mModelProvider,
-                mContentChangedListener,
-                /* spinnerShown = */ false);
-    }
-
-    @VisibleForTesting
-    ZeroStateDriver createSpinner() {
-        return new ZeroStateDriver(mBasicLoggingApi, mClock, mModelProvider,
-                mContentChangedListener,
-                /* spinnerShown= */ true);
-    }
-
-    public void setStreamContentListener(@Nullable StreamContentListener contentListener) {
-        this.mContentListener = contentListener;
-    }
-
-    @Override
-    public void triggerPendingDismiss(String contentId, UndoAction undoAction,
-            PendingDismissCallback pendingDismissCallback) {
-        // Remove the feature driver to temporarily hide the card. Find the modelChild and index so
-        // the driver can be recreated and inserted if dismiss is undone.
-        ModelChild modelChild = getModelChildForContentId(contentId);
-        if (modelChild == null) {
-            Logger.wtf(TAG, "No model child found with that content id.");
-            pendingDismissCallback.onDismissCommitted();
-            return;
-        }
-
-        FeatureDriver featureDriver = mModelChildFeatureDriverMap.get(modelChild);
-        if (featureDriver == null) {
-            Logger.wtf(TAG, "No FeatureDriver found for that model child.");
-            pendingDismissCallback.onDismissCommitted();
-            return;
-        }
-
-        int index = mFeatureDrivers.indexOf(featureDriver);
-        if (index < 0) {
-            Logger.wtf(TAG, "No FeatureDriver found in the FeatureDriver list.");
-            pendingDismissCallback.onDismissCommitted();
-            return;
-        }
-
-        removeDriver(modelChild);
-        addNoContentCardOrZeroStateIfNecessary(ZeroStateShowReason.CONTENT_DISMISSED);
-        mSnackbarApi.show(undoAction.getConfirmationLabel(),
-                undoAction.hasUndoLabel() ? undoAction.getUndoLabel()
-                                          : mContext.getResources().getString(R.string.undo),
-                new SnackbarCallbackApi() {
-                    @Override
-                    public void onDismissNoAction() {
-                        pendingDismissCallback.onDismissCommitted();
-                    }
-
-                    @Override
-                    public void onDismissedWithAction() {
-                        alwaysRemoveNoContentOrZeroStateCardIfPresent();
-                        pendingDismissCallback.onDismissReverted();
-                        createFeatureChildAndInsertAtIndex(modelChild, index);
-                    }
-                });
-    }
-
-    private void createFeatureChildAndInsertAtIndex(ModelChild modelChild, int index) {
-        FeatureDriver featureDriver = createFeatureChild(modelChild.getModelFeature(), index);
-        if (featureDriver == null) {
-            Logger.wtf(TAG, "Could not recreate the FeatureDriver.");
-            return;
-        }
-        mFeatureDrivers.add(index, featureDriver);
-        if (modelChild != null) {
-            mModelChildFeatureDriverMap.put(modelChild, featureDriver);
-        }
-        LeafFeatureDriver leafFeatureDriver = featureDriver.getLeafFeatureDriver();
-        if (leafFeatureDriver == null) {
-            Logger.wtf(TAG, "No LeafFeatureDriver found.");
-            return;
-        }
-        notifyContentsAdded(mFeatureDrivers.indexOf(featureDriver),
-                Collections.singletonList(leafFeatureDriver));
-    }
-
-    @Nullable
-    private ModelChild getModelChildForContentId(String contentId) {
-        for (ModelChild model : mModelChildFeatureDriverMap.keySet()) {
-            if (model.getContentId().equals(contentId)) {
-                return model;
-            }
-        }
-        return null;
-    }
-
-    /** Contains the {@link FeatureDriver} instances that were created and metadata about them. */
-    private static class ChildCreationPayload {
-        private final List<FeatureDriver> mFeatureDrivers;
-        private final int mTokenCount;
-        private final int mContentCount;
-
-        private ChildCreationPayload(
-                List<FeatureDriver> featureDrivers, int tokenCount, int contentCount) {
-            this.mFeatureDrivers = featureDrivers;
-            this.mTokenCount = tokenCount;
-            this.mContentCount = contentCount;
-        }
-    }
-
-    /** Allows listening for changes in the contents held by a {@link StreamDriver} */
-    public interface StreamContentListener {
-        /** Called when the given content has been added at the given index of stream content. */
-        void notifyContentsAdded(int index, List<LeafFeatureDriver> newFeatureDrivers);
-
-        /** Called when the content at the given index of stream content has been removed. */
-        void notifyContentRemoved(int index);
-
-        /** Called when the content in the stream has been cleared. */
-        void notifyContentsCleared();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ZeroStateDriver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ZeroStateDriver.java
deleted file mode 100644
index 83d0603c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ZeroStateDriver.java
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.drivers;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import android.view.View;
-import android.view.View.OnClickListener;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.api.host.logging.SpinnerType;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.FeedViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ViewHolderType;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ZeroStateViewHolder;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.sharedstream.logging.SpinnerLogger;
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ContentChangedListener;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-import org.chromium.components.feed.core.proto.libraries.sharedstream.UiRefreshReasonProto.UiRefreshReason;
-import org.chromium.components.feed.core.proto.libraries.sharedstream.UiRefreshReasonProto.UiRefreshReason.Reason;
-
-/** {@link FeatureDriver} for the zero state. */
-public class ZeroStateDriver extends LeafFeatureDriver implements OnClickListener {
-    private static final String TAG = "ZeroStateDriver";
-
-    private final ContentChangedListener mContentChangedListener;
-    private final SpinnerLogger mSpinnerLogger;
-
-    private ModelProvider mModelProvider;
-    private boolean mSpinnerShown;
-    @Nullable
-    private ZeroStateViewHolder mZeroStateViewHolder;
-
-    ZeroStateDriver(BasicLoggingApi basicLoggingApi, Clock clock, ModelProvider modelProvider,
-            ContentChangedListener contentChangedListener, boolean spinnerShown) {
-        this.mContentChangedListener = contentChangedListener;
-        this.mModelProvider = modelProvider;
-        this.mSpinnerLogger = createSpinnerLogger(basicLoggingApi, clock);
-        this.mSpinnerShown = spinnerShown;
-    }
-
-    @Override
-    public void bind(FeedViewHolder viewHolder) {
-        if (isBound()) {
-            Logger.w(TAG, "Rebinding.");
-            if (viewHolder == mZeroStateViewHolder) {
-                Logger.e(TAG, "Being rebound to the previously bound viewholder");
-                return;
-            }
-            unbind();
-        }
-        checkState(viewHolder instanceof ZeroStateViewHolder);
-
-        mZeroStateViewHolder = (ZeroStateViewHolder) viewHolder;
-        mZeroStateViewHolder.bind(this, mSpinnerShown);
-        // Only log that spinner is being shown if it has not been logged before.
-        if (mSpinnerShown && !mSpinnerLogger.isSpinnerActive()) {
-            mSpinnerLogger.spinnerStarted(SpinnerType.INITIAL_LOAD);
-        }
-    }
-
-    @Override
-    public int getItemViewType() {
-        return ViewHolderType.TYPE_ZERO_STATE;
-    }
-
-    @Override
-    public void unbind() {
-        if (mZeroStateViewHolder == null) {
-            return;
-        }
-
-        mZeroStateViewHolder.unbind();
-        mZeroStateViewHolder = null;
-    }
-
-    @Override
-    public void maybeRebind() {
-        if (mZeroStateViewHolder == null) {
-            return;
-        }
-
-        // Unbinding clears the viewHolder, so storing to rebind.
-        ZeroStateViewHolder localViewHolder = mZeroStateViewHolder;
-        unbind();
-        bind(localViewHolder);
-    }
-
-    @Override
-    public void onClick(View v) {
-        if (mZeroStateViewHolder == null) {
-            Logger.wtf(TAG, "Calling onClick before binding.");
-            return;
-        }
-
-        mSpinnerShown = true;
-        mZeroStateViewHolder.showSpinner(mSpinnerShown);
-        mContentChangedListener.onContentChanged();
-        UiContext uiContext =
-                UiContext.newBuilder()
-                        .setExtension(UiRefreshReason.uiRefreshReasonExtension,
-                                UiRefreshReason.newBuilder().setReason(Reason.ZERO_STATE).build())
-                        .build();
-        mModelProvider.triggerRefresh(RequestReason.ZERO_STATE, uiContext);
-
-        mSpinnerLogger.spinnerStarted(SpinnerType.ZERO_STATE_REFRESH);
-    }
-
-    @Override
-    public void onDestroy() {
-        // If the spinner was being shown, it will only be removed when the ZeroStateDriver is
-        // destroyed. So spinner should be logged then.
-        if (mSpinnerLogger.isSpinnerActive()) {
-            mSpinnerLogger.spinnerFinished();
-        }
-    }
-
-    /**
-     * Updates the model provider.
-     *
-     * <p>This is a hacky way to keep the model providers in sync in the situation where switching
-     * stream drivers would result in the zero state flashing.
-     */
-    void setModelProvider(ModelProvider modelProvider) {
-        mModelProvider = modelProvider;
-    }
-
-    @VisibleForTesting
-    boolean isBound() {
-        return mZeroStateViewHolder != null;
-    }
-
-    @VisibleForTesting
-    SpinnerLogger createSpinnerLogger(BasicLoggingApi basicLoggingApi, Clock clock) {
-        return new SpinnerLogger(basicLoggingApi, clock);
-    }
-
-    /** Returns whether the spinner is showing. */
-    boolean isSpinnerShowing() {
-        return mSpinnerShown;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/testing/FakeFeatureDriver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/testing/FakeFeatureDriver.java
deleted file mode 100644
index bf389752..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/testing/FakeFeatureDriver.java
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.drivers.testing;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.drivers.FeatureDriver;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.drivers.LeafFeatureDriver;
-import org.chromium.chrome.browser.feed.library.testing.modelprovider.FakeModelFeature;
-
-/** Fake for {@link FeatureDriver}. */
-public class FakeFeatureDriver implements FeatureDriver {
-    @Nullable
-    private final LeafFeatureDriver mLeafFeatureDriver;
-    private final ModelFeature mModelFeature;
-
-    private FakeFeatureDriver(
-            @Nullable LeafFeatureDriver leafFeatureDriver, ModelFeature modelFeature) {
-        this.mLeafFeatureDriver = leafFeatureDriver;
-        this.mModelFeature = modelFeature;
-    }
-
-    @Override
-    public void onDestroy() {}
-
-    @Override
-    @Nullable
-    public LeafFeatureDriver getLeafFeatureDriver() {
-        return mLeafFeatureDriver;
-    }
-
-    public ModelFeature getModelFeature() {
-        return mModelFeature;
-    }
-
-    public static class Builder {
-        @Nullable
-        private LeafFeatureDriver mLeafFeatureDriver = new FakeLeafFeatureDriver.Builder().build();
-
-        private ModelFeature mModelFeature = FakeModelFeature.newBuilder().build();
-
-        public Builder setLeafFeatureDriver(@Nullable LeafFeatureDriver contentModel) {
-            this.mLeafFeatureDriver = contentModel;
-            return this;
-        }
-
-        public Builder setModelFeature(ModelFeature modelFeature) {
-            this.mModelFeature = modelFeature;
-            return this;
-        }
-
-        public FakeFeatureDriver build() {
-            return new FakeFeatureDriver(mLeafFeatureDriver, mModelFeature);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/testing/FakeLeafFeatureDriver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/testing/FakeLeafFeatureDriver.java
deleted file mode 100644
index cb0cbdd..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/testing/FakeLeafFeatureDriver.java
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.drivers.testing;
-
-import org.chromium.chrome.browser.feed.library.basicstream.internal.drivers.LeafFeatureDriver;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.FeedViewHolder;
-import org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ViewHolderType;
-
-/** Fake for {@link LeafFeatureDriver}. */
-public class FakeLeafFeatureDriver extends LeafFeatureDriver {
-    private final int mItemViewType;
-
-    private FakeLeafFeatureDriver(int itemViewType) {
-        this.mItemViewType = itemViewType;
-    }
-
-    @Override
-    public void bind(FeedViewHolder viewHolder) {}
-
-    @Override
-    public void unbind() {}
-
-    @Override
-    public void maybeRebind() {}
-
-    @Override
-    @ViewHolderType
-    public int getItemViewType() {
-        return mItemViewType;
-    }
-
-    @Override
-    public long itemId() {
-        return hashCode();
-    }
-
-    @Override
-    public void onDestroy() {}
-
-    @Override
-    public LeafFeatureDriver getLeafFeatureDriver() {
-        return this;
-    }
-
-    public static class Builder {
-        @ViewHolderType
-        private int mItemViewType = ViewHolderType.TYPE_CARD;
-
-        public Builder setItemViewType(@ViewHolderType int viewType) {
-            mItemViewType = viewType;
-            return this;
-        }
-
-        public LeafFeatureDriver build() {
-            return new FakeLeafFeatureDriver(mItemViewType);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/pendingdismiss/ClusterPendingDismissHelper.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/pendingdismiss/ClusterPendingDismissHelper.java
deleted file mode 100644
index f00ac8f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/pendingdismiss/ClusterPendingDismissHelper.java
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.pendingdismiss;
-
-import org.chromium.chrome.browser.feed.library.sharedstream.pendingdismiss.PendingDismissCallback;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.UndoAction;
-
-/**
- * Interface that is passed through the stream hierarchy so during a dismissLocal we can find the
- * cluster FeatureDriver and pass that to the StreamDriver to handle a pending dismissLocal.
- */
-public interface ClusterPendingDismissHelper {
-    /**
-     * Triggers the temporary removal of the content with snackbar. Content will either come back or
-     * be fully removed based on the interactions with the snackbar.
-     *
-     * @param undoAction - Information for the rendering of the snackbar.
-     * @param pendingDismissCallback - Callbacks to call once content has been committed or
-     *         reversed.
-     */
-    void triggerPendingDismissForCluster(
-            UndoAction undoAction, PendingDismissCallback pendingDismissCallback);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/pendingdismiss/PendingDismissHandler.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/pendingdismiss/PendingDismissHandler.java
deleted file mode 100644
index 76242628..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/pendingdismiss/PendingDismissHandler.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.pendingdismiss;
-
-import org.chromium.chrome.browser.feed.library.sharedstream.pendingdismiss.PendingDismissCallback;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.UndoAction;
-
-/** Interface that handles dismissing a card with an undo option. */
-public interface PendingDismissHandler {
-    /**
-     * Triggers the temporary removal of the content with snackbar. Content will either come back or
-     * be fully removed based on the interactions with the snackbar.
-     *
-     * @param contentId - The content that should be temporary hidden until the dismiss is
-     *         committed.
-     * @param undoAction - Information for the rendering of the snackbar.
-     * @param pendingDismissCallback - Callbacks to call once content has been committed or
-     *         reversed.
-     */
-    void triggerPendingDismiss(
-            String contentId, UndoAction undoAction, PendingDismissCallback pendingDismissCallback);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/BasicStreamScrollMonitor.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/BasicStreamScrollMonitor.java
deleted file mode 100644
index dca53bb..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/BasicStreamScrollMonitor.java
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.scroll;
-
-import androidx.recyclerview.widget.RecyclerView;
-
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll.ScrollObservable;
-import org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll.ScrollObserver;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Monitors and dispatches scroll events to the registered listeners.
- *
- * <p>Note: This is intentionally unscoped, because we want features to be able to manage their
- * scroll locally, instead of having a singleton ScrollMonitor.
- */
-public class BasicStreamScrollMonitor
-        extends RecyclerView.OnScrollListener implements ScrollObservable {
-    private final Set<ScrollObserver> mScrollObservers;
-    private final Clock mClock;
-
-    private int mCurrentScrollState = RecyclerView.SCROLL_STATE_IDLE;
-
-    public BasicStreamScrollMonitor(Clock clock) {
-        this.mClock = clock;
-        mScrollObservers = Collections.synchronizedSet(new HashSet<>());
-    }
-
-    @Override
-    public void addScrollObserver(ScrollObserver scrollObserver) {
-        mScrollObservers.add(scrollObserver);
-    }
-
-    @Override
-    public void removeScrollObserver(ScrollObserver scrollObserver) {
-        mScrollObservers.remove(scrollObserver);
-    }
-
-    @Override
-    public int getCurrentScrollState() {
-        return mCurrentScrollState;
-    }
-
-    public int getObserverCount() {
-        return mScrollObservers.size();
-    }
-
-    /**
-     * Notify the monitor of a scroll state change event that should be dispatched to the observers.
-     */
-    @Override
-    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
-        mCurrentScrollState = newState;
-        for (ScrollObserver observer : mScrollObservers) {
-            observer.onScrollStateChanged(recyclerView, "", newState, mClock.currentTimeMillis());
-        }
-    }
-
-    /** Notify the monitor of a scroll event that should be dispatched to its observers. */
-    @Override
-    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
-        for (ScrollObserver observer : mScrollObservers) {
-            observer.onScroll(recyclerView, "", dx, dy);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/BasicStreamScrollTracker.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/BasicStreamScrollTracker.java
deleted file mode 100644
index 9593d70..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/BasicStreamScrollTracker.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.scroll;
-
-import android.view.View;
-
-import org.chromium.chrome.browser.feed.library.api.host.logging.ScrollType;
-import org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll.ScrollObservable;
-import org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll.ScrollObserver;
-import org.chromium.chrome.browser.feed.library.sharedstream.scroll.ScrollLogger;
-import org.chromium.chrome.browser.feed.shared.ScrollTracker;
-
-/** A @link{ScrollTracker} used by BasicStream */
-public class BasicStreamScrollTracker extends ScrollTracker {
-    private final ScrollLogger mScrollLogger;
-    private final ScrollObserver mScrollObserver;
-    private final ScrollObservable mScrollObservable;
-
-    public BasicStreamScrollTracker(ScrollLogger scrollLogger, ScrollObservable scrollObservable) {
-        this.mScrollLogger = scrollLogger;
-        this.mScrollObservable = scrollObservable;
-        this.mScrollObserver = new BasicStreamScrollObserver();
-        mScrollObservable.addScrollObserver(mScrollObserver);
-    }
-
-    @Override
-    protected void onScrollEvent(int scrollAmount) {
-        mScrollLogger.handleScroll(ScrollType.STREAM_SCROLL, scrollAmount);
-    }
-
-    @Override
-    public void onUnbind() {
-        super.onUnbind();
-        mScrollObservable.removeScrollObserver(mScrollObserver);
-    }
-
-    private class BasicStreamScrollObserver implements ScrollObserver {
-        @Override
-        public void onScrollStateChanged(
-                View view, String featureId, int newState, long timestamp) {}
-
-        @Override
-        public void onScroll(View view, String featureId, int dx, int dy) {
-            trackScroll(dx, dy);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/ScrollRestorer.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/ScrollRestorer.java
deleted file mode 100644
index 6842dda..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/ScrollRestorer.java
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.scroll;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.sharedstream.scroll.ScrollListenerNotifier;
-import org.chromium.chrome.browser.feed.library.sharedstream.scroll.ScrollRestoreHelper;
-import org.chromium.components.feed.core.proto.libraries.sharedstream.ScrollStateProto.ScrollState;
-
-/**
- * Class which is able to save a scroll position for a RecyclerView and restore to that scroll
- * position at a later time.
- */
-public class ScrollRestorer {
-    private static final String TAG = "ScrollRestorer";
-
-    private final Configuration mConfiguration;
-    private final RecyclerView mRecyclerView;
-    private final ScrollListenerNotifier mScrollListenerNotifier;
-    private final int mScrollPosition;
-    private final int mScrollOffset;
-
-    private boolean mCanRestore;
-
-    public ScrollRestorer(Configuration configuration, RecyclerView recyclerView,
-            ScrollListenerNotifier scrollListenerNotifier, @Nullable ScrollState scrollState) {
-        this.mConfiguration = configuration;
-        this.mRecyclerView = recyclerView;
-        this.mScrollListenerNotifier = scrollListenerNotifier;
-
-        if (scrollState != null) {
-            mCanRestore = true;
-            mScrollPosition = scrollState.getPosition();
-            mScrollOffset = scrollState.getOffset();
-        } else {
-            this.mScrollPosition = 0;
-            this.mScrollOffset = 0;
-        }
-    }
-
-    private ScrollRestorer(Configuration configuration, RecyclerView recyclerView,
-            ScrollListenerNotifier scrollListenerNotifier) {
-        mCanRestore = false;
-        this.mConfiguration = configuration;
-        this.mRecyclerView = recyclerView;
-        this.mScrollListenerNotifier = scrollListenerNotifier;
-        mScrollPosition = 0;
-        mScrollOffset = 0;
-    }
-
-    /**
-     * Creates a {@code StreamRestorer} which will never restore state. This can be used to fulfill
-     * {@code StreamRestorer} requests when no restore state is present.
-     */
-    public static ScrollRestorer nonRestoringRestorer(Configuration configuration,
-            RecyclerView recyclerView, ScrollListenerNotifier scrollListenerNotifier) {
-        return new ScrollRestorer(configuration, recyclerView, scrollListenerNotifier);
-    }
-
-    /**
-     * Disables the ability of the {@code ScrollRestorer} from restoring the scroll. This should be
-     * call if the previous scroll position is no longer valid. An example use case of this would be
-     * if the restoring session is no longer valid.
-     */
-    public void abandonRestoringScroll() {
-        mCanRestore = false;
-    }
-
-    /**
-     * Attempts to restore scroll position if possible. If the scroll position has already been
-     * restored, then this method will no-op.
-     */
-    public void maybeRestoreScroll() {
-        if (!mCanRestore) {
-            return;
-        }
-        Logger.d(TAG, "Restoring scroll");
-        getLayoutManager().scrollToPositionWithOffset(mScrollPosition, mScrollOffset);
-        mScrollListenerNotifier.onProgrammaticScroll(mRecyclerView);
-        mCanRestore = false;
-    }
-
-    /**
-     * Returns a bundle which can be used for restoring scroll state on an activity restart.
-     *
-     * @param currentHeaderCount The amount of headers which appear before Stream content.
-     */
-    @Nullable
-    public ScrollState getScrollStateForScrollRestore(int currentHeaderCount) {
-        return ScrollRestoreHelper.getScrollStateForScrollRestore(
-                getLayoutManager(), mConfiguration, currentHeaderCount);
-    }
-
-    private LinearLayoutManager getLayoutManager() {
-        checkState(mRecyclerView.getLayoutManager() instanceof LinearLayoutManager,
-                "Scroll state can only be restored when using a LinearLayoutManager.");
-        return checkNotNull((LinearLayoutManager) mRecyclerView.getLayoutManager());
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/ContinuationViewHolder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/ContinuationViewHolder.java
deleted file mode 100644
index 6c15a144..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/ContinuationViewHolder.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.ViewGroup.MarginLayoutParams;
-import android.widget.FrameLayout;
-
-import androidx.annotation.VisibleForTesting;
-import androidx.recyclerview.widget.RecyclerView.LayoutParams;
-
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.CardConfiguration;
-import org.chromium.chrome.browser.feed.library.common.ui.LayoutUtils;
-import org.chromium.chrome.browser.feed.library.sharedstream.logging.LoggingListener;
-import org.chromium.chrome.browser.feed.library.sharedstream.logging.VisibilityMonitor;
-
-/** {@link androidx.recyclerview.widget.RecyclerView.ViewHolder} for the more button. */
-public class ContinuationViewHolder extends FeedViewHolder {
-    private final View mActionButton;
-    private final View mSpinner;
-    private final VisibilityMonitor mVisibilityMonitor;
-    private final CardConfiguration mCardConfiguration;
-    private final Context mContext;
-
-    public ContinuationViewHolder(Configuration configuration, Context context,
-            FrameLayout frameLayout, CardConfiguration cardConfiguration) {
-        super(frameLayout);
-        View containerView =
-                LayoutInflater.from(context).inflate(R.layout.feed_more_button, frameLayout);
-        mActionButton = checkNotNull(frameLayout.findViewById(R.id.action_button));
-        mSpinner = checkNotNull(frameLayout.findViewById(R.id.loading_spinner));
-        mVisibilityMonitor = createVisibilityMonitor(containerView, configuration);
-        this.mCardConfiguration = cardConfiguration;
-        this.mContext = context;
-    }
-
-    public void bind(
-            OnClickListener onClickListener, LoggingListener loggingListener, boolean showSpinner) {
-        ViewGroup.LayoutParams layoutParams = itemView.getLayoutParams();
-        if (layoutParams == null) {
-            layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
-            itemView.setLayoutParams(layoutParams);
-        } else if (!(layoutParams instanceof MarginLayoutParams)) {
-            layoutParams = new LayoutParams(layoutParams);
-            itemView.setLayoutParams(layoutParams);
-        }
-        LayoutUtils.setMarginsRelative((MarginLayoutParams) layoutParams,
-                mCardConfiguration.getCardStartMargin(),
-                (int) mContext.getResources().getDimension(
-                        R.dimen.feed_more_button_container_top_margins),
-                mCardConfiguration.getCardEndMargin(), mCardConfiguration.getCardBottomMargin());
-
-        mActionButton.setOnClickListener(v -> {
-            onClickListener.onClick(v);
-            loggingListener.onContentClicked();
-        });
-        mVisibilityMonitor.setListener(loggingListener);
-        setButtonSpinnerVisibility(showSpinner);
-    }
-
-    @Override
-    public void unbind() {
-        // Clear OnClickListener to null to allow for GC.
-        mActionButton.setOnClickListener(null);
-        mVisibilityMonitor.setListener(null);
-
-        // Set clickable to false as setting OnClickListener to null sets clickable to true.
-        mActionButton.setClickable(false);
-    }
-
-    public void setShowSpinner(boolean showSpinner) {
-        setButtonSpinnerVisibility(/* showSpinner= */ showSpinner);
-    }
-
-    private void setButtonSpinnerVisibility(boolean showSpinner) {
-        mActionButton.setVisibility(showSpinner ? View.GONE : View.VISIBLE);
-        mSpinner.setVisibility(showSpinner ? View.VISIBLE : View.GONE);
-    }
-
-    @VisibleForTesting
-    VisibilityMonitor createVisibilityMonitor(View view, Configuration configuration) {
-        return new VisibilityMonitor(view, configuration);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/FeedViewHolder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/FeedViewHolder.java
deleted file mode 100644
index 7d454f85..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/FeedViewHolder.java
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders;
-
-import android.view.View;
-
-import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-
-/** {@link androidx.recyclerview.widget.RecyclerView.ViewHolder} for the Feed. */
-public abstract class FeedViewHolder extends ViewHolder {
-    public FeedViewHolder(View view) {
-        super(view);
-    }
-
-    public abstract void unbind();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/HeaderViewHolder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/HeaderViewHolder.java
deleted file mode 100644
index 1d20594..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/HeaderViewHolder.java
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders;
-
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.widget.FrameLayout;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.shared.stream.Header;
-
-/** {@link FeedViewHolder} for headers. */
-public class HeaderViewHolder extends FeedViewHolder implements SwipeableViewHolder {
-    private static final String TAG = "HeaderViewHolder";
-    private final FrameLayout mFrameLayout;
-
-    @Nullable
-    private Header mHeader;
-    @Nullable
-    private SwipeNotifier mSwipeNotifier;
-
-    public HeaderViewHolder(FrameLayout itemView) {
-        super(itemView);
-        this.mFrameLayout = itemView;
-    }
-
-    public void bind(Header header, SwipeNotifier swipeNotifier) {
-        this.mHeader = header;
-        this.mSwipeNotifier = swipeNotifier;
-        ViewParent parent = header.getView().getParent();
-        if (parent == mFrameLayout) {
-            return;
-        }
-        // If header was bound to another HeaderViewHolder but not unbound properly, remove it from
-        // its parent view.
-        if (parent != null) {
-            ((ViewGroup) parent).removeView(header.getView());
-        }
-        mFrameLayout.addView(header.getView());
-    }
-
-    @Override
-    public void unbind() {
-        mFrameLayout.removeAllViews();
-        this.mHeader = null;
-        this.mSwipeNotifier = null;
-    }
-
-    @Override
-    public boolean canSwipe() {
-        if (mHeader == null) {
-            Logger.w(TAG, "canSwipe should not be called before viewholder is bound.");
-
-            // Instead of crashing if viewholder is not bound, disable swiping behavior.
-            return false;
-        }
-        return mHeader.isDismissible();
-    }
-
-    @Override
-    public void onSwiped() {
-        if (mSwipeNotifier == null) {
-            Logger.w(TAG, "onSwiped should not be called before viewholder is bound.");
-
-            // Instead of crashing if viewholder is not bound, disable swiping behavior.
-            return;
-        }
-
-        mSwipeNotifier.onSwiped();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/NoContentViewHolder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/NoContentViewHolder.java
deleted file mode 100644
index 669bd9c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/NoContentViewHolder.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewGroup.MarginLayoutParams;
-import android.widget.FrameLayout;
-
-import androidx.recyclerview.widget.RecyclerView.LayoutParams;
-
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.library.api.host.stream.CardConfiguration;
-import org.chromium.chrome.browser.feed.library.common.ui.LayoutUtils;
-
-/** {@link androidx.recyclerview.widget.RecyclerView.ViewHolder} for no content card. */
-public class NoContentViewHolder extends FeedViewHolder {
-    private final CardConfiguration mCardConfiguration;
-    private final View mView;
-
-    public NoContentViewHolder(
-            CardConfiguration cardConfiguration, Context context, FrameLayout frameLayout) {
-        super(frameLayout);
-        this.mCardConfiguration = cardConfiguration;
-        mView = LayoutInflater.from(context).inflate(R.layout.no_content, frameLayout);
-    }
-
-    public void bind() {
-        ViewGroup.LayoutParams layoutParams = itemView.getLayoutParams();
-        if (layoutParams == null) {
-            layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
-            itemView.setLayoutParams(layoutParams);
-        } else if (!(layoutParams instanceof MarginLayoutParams)) {
-            layoutParams = new LayoutParams(layoutParams);
-            itemView.setLayoutParams(layoutParams);
-        }
-        LayoutUtils.setMarginsRelative((MarginLayoutParams) layoutParams,
-                mCardConfiguration.getCardStartMargin(), 0, mCardConfiguration.getCardEndMargin(),
-                mCardConfiguration.getCardBottomMargin());
-
-        mView.setBackground(mCardConfiguration.getCardBackground());
-    }
-
-    @Override
-    public void unbind() {}
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/PietViewHolder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/PietViewHolder.java
deleted file mode 100644
index 92de26b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/PietViewHolder.java
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-
-import android.content.Context;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewGroup.MarginLayoutParams;
-import android.widget.FrameLayout;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.recyclerview.widget.RecyclerView.LayoutParams;
-
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.library.api.host.action.StreamActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.CardConfiguration;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionParser;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionSource;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionSourceConverter;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.ui.LayoutUtils;
-import org.chromium.chrome.browser.feed.library.piet.FrameAdapter;
-import org.chromium.chrome.browser.feed.library.piet.PietManager;
-import org.chromium.chrome.browser.feed.library.piet.host.ActionHandler.ActionType;
-import org.chromium.chrome.browser.feed.library.sharedstream.logging.LoggingListener;
-import org.chromium.chrome.browser.feed.library.sharedstream.logging.VisibilityMonitor;
-import org.chromium.chrome.browser.feed.library.sharedstream.piet.PietEventLogger;
-import org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll.ScrollObservable;
-import org.chromium.chrome.browser.feed.library.sharedstream.scroll.PietScrollObserver;
-import org.chromium.chrome.browser.feed.library.sharedstream.scroll.ScrollListenerNotifier;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionPayloadProto.FeedActionPayload;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Frame;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.PietSharedState;
-
-import java.util.List;
-
-/**
- * {@link androidx.recyclerview.widget.RecyclerView.ViewHolder} for {@link
- * org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.PietContent}.
- */
-public class PietViewHolder extends FeedViewHolder implements SwipeableViewHolder {
-    private static final String TAG = "PietViewHolder";
-    private final CardConfiguration mCardConfiguration;
-    private final FrameLayout mCardView;
-    private final ScrollObservable mScrollObservable;
-    private final FrameAdapter mFrameAdapter;
-    private final VisibilityMonitor mVisibilityMonitor;
-    private final View mViewport;
-    private boolean mBound;
-
-    @Nullable
-    private ActionParser mActionParser;
-    @Nullable
-    private LoggingListener mLoggingListener;
-    @Nullable
-    private StreamActionApi mStreamActionApi;
-    @Nullable
-    private FeedActionPayload mSwipeAction;
-    @Nullable
-    private PietViewActionScrollObserver mScrollobserver;
-
-    public PietViewHolder(CardConfiguration cardConfiguration, FrameLayout cardView,
-            PietManager pietManager, ScrollObservable scrollObservable, View viewport,
-            Context context, Configuration configuration, PietEventLogger eventLogger) {
-        super(cardView);
-        this.mCardConfiguration = cardConfiguration;
-        this.mCardView = cardView;
-        this.mScrollObservable = scrollObservable;
-        this.mViewport = viewport;
-        cardView.setId(R.id.feed_content_card);
-        this.mFrameAdapter = pietManager.createPietFrameAdapter(
-                () -> cardView, (action, actionType, frame, view, logData) -> {
-                    if (mActionParser == null) {
-                        Logger.wtf(TAG, "Action being performed while unbound.");
-                        return;
-                    }
-
-                    if (actionType == ActionType.CLICK) {
-                        getLoggingListener().onContentClicked();
-                    }
-                    getActionParser().parseAction(action, getStreamActionApi(), view, logData,
-                            ActionSourceConverter.convertPietAction(actionType));
-                }, eventLogger::logEvents, context);
-        mVisibilityMonitor = createVisibilityMonitor(cardView, configuration);
-        cardView.addView(mFrameAdapter.getFrameContainer());
-    }
-
-    public void bind(Frame frame, List<PietSharedState> pietSharedStates,
-            StreamActionApi streamActionApi, FeedActionPayload swipeAction,
-            LoggingListener loggingListener, ActionParser actionParser) {
-        if (mBound) {
-            return;
-        }
-        mVisibilityMonitor.setListener(loggingListener);
-        this.mLoggingListener = loggingListener;
-        this.mStreamActionApi = streamActionApi;
-        this.mSwipeAction = swipeAction;
-        this.mActionParser = actionParser;
-        mScrollobserver = new PietViewActionScrollObserver(
-                mFrameAdapter, mViewport, mScrollObservable, loggingListener);
-        // Need to reset padding here.  Setting a background can affect padding so if we switch from
-        // a background which has padding to one that does not, then the padding needs to be
-        // removed.
-        mCardView.setPadding(0, 0, 0, 0);
-
-        mCardView.setBackground(mCardConfiguration.getCardBackground());
-
-        ViewGroup.LayoutParams layoutParams = mCardView.getLayoutParams();
-        if (layoutParams == null) {
-            layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
-            mCardView.setLayoutParams(layoutParams);
-        } else if (!(layoutParams instanceof MarginLayoutParams)) {
-            layoutParams = new LayoutParams(layoutParams);
-            mCardView.setLayoutParams(layoutParams);
-        }
-        LayoutUtils.setMarginsRelative((MarginLayoutParams) layoutParams,
-                mCardConfiguration.getCardStartMargin(), 0, mCardConfiguration.getCardEndMargin(),
-                mCardConfiguration.getCardBottomMargin());
-
-        mFrameAdapter.bindModel(frame,
-                0, // TODO: set the frame width here
-                null, pietSharedStates);
-        if (mScrollobserver != null) {
-            mScrollObservable.addScrollObserver(mScrollobserver);
-        }
-
-        mBound = true;
-    }
-
-    @Override
-    public void unbind() {
-        if (!mBound) {
-            return;
-        }
-
-        mFrameAdapter.unbindModel();
-        mActionParser = null;
-        mLoggingListener = null;
-        mStreamActionApi = null;
-        mSwipeAction = null;
-        mVisibilityMonitor.setListener(null);
-        if (mScrollobserver != null) {
-            mScrollObservable.removeScrollObserver(mScrollobserver);
-            mScrollobserver.uninstallFirstDrawTrigger();
-        }
-        mBound = false;
-    }
-
-    @Override
-    public boolean canSwipe() {
-        return mSwipeAction != null && !mSwipeAction.equals(FeedActionPayload.getDefaultInstance());
-    }
-
-    @Override
-    public void onSwiped() {
-        if (mSwipeAction == null || mActionParser == null) {
-            Logger.wtf(TAG, "Swipe performed on unbound ViewHolder.");
-            return;
-        }
-        mActionParser.parseFeedActionPayload(
-                mSwipeAction, getStreamActionApi(), itemView, ActionSource.SWIPE);
-
-        if (mLoggingListener == null) {
-            Logger.wtf(TAG, "Logging listener is null. Swipe perfomred on unbound ViewHolder.");
-            return;
-        }
-        mLoggingListener.onContentSwiped();
-    }
-
-    @VisibleForTesting
-    VisibilityMonitor createVisibilityMonitor(View view, Configuration configuration) {
-        return new VisibilityMonitor(view, configuration);
-    }
-
-    private LoggingListener getLoggingListener() {
-        return checkNotNull(mLoggingListener,
-                "Logging listener can only be retrieved once view holder has been bound.");
-    }
-
-    private StreamActionApi getStreamActionApi() {
-        return checkNotNull(mStreamActionApi,
-                "Stream action api can only be retrieved once view holder has been bound.");
-    }
-
-    private ActionParser getActionParser() {
-        return checkNotNull(mActionParser,
-                "Action parser can only be retrieved once view holder has been bound");
-    }
-
-    static class PietViewActionScrollObserver extends PietScrollObserver {
-        private final LoggingListener mLoggingListener;
-
-        PietViewActionScrollObserver(FrameAdapter frameAdapter, View viewport,
-                ScrollObservable scrollObservable, LoggingListener loggingListener) {
-            super(frameAdapter, viewport, scrollObservable);
-            this.mLoggingListener = loggingListener;
-        }
-
-        @Override
-        public void onScrollStateChanged(
-                View view, String featureId, int newState, long timestamp) {
-            super.onScrollStateChanged(view, featureId, newState, timestamp);
-            mLoggingListener.onScrollStateChanged(
-                    ScrollListenerNotifier.convertRecyclerViewScrollStateToListenerState(newState));
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/SwipeNotifier.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/SwipeNotifier.java
deleted file mode 100644
index eb50d98..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/SwipeNotifier.java
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders;
-
-/** Interface used to notify users of swipe events. */
-public interface SwipeNotifier { void onSwiped(); }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/SwipeableViewHolder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/SwipeableViewHolder.java
deleted file mode 100644
index a921e40..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/SwipeableViewHolder.java
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders;
-
-/** Interface that {@link ViewHolder} instances can implement to enable swipe functionality. */
-public interface SwipeableViewHolder {
-    /** Determines whether this {@link ViewHolder} can have a swipe performed on it. */
-    boolean canSwipe();
-
-    /** Called when this {@link ViewHolder} is swiped. */
-    void onSwiped();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/ViewHolderType.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/ViewHolderType.java
deleted file mode 100644
index cbc2a0d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/ViewHolderType.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders;
-
-import androidx.annotation.IntDef;
-
-/**
- * Constants to specify the type of ViewHolder to create in the {@link StreamRecyclerViewAdapter}.
- */
-@IntDef({ViewHolderType.TYPE_HEADER, ViewHolderType.TYPE_CARD, ViewHolderType.TYPE_CONTINUATION,
-        ViewHolderType.TYPE_NO_CONTENT, ViewHolderType.TYPE_ZERO_STATE})
-public @interface ViewHolderType {
-    int TYPE_HEADER = 0;
-    int TYPE_CARD = 1;
-    int TYPE_CONTINUATION = 2;
-    int TYPE_NO_CONTENT = 3;
-    int TYPE_ZERO_STATE = 4;
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/ZeroStateViewHolder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/ZeroStateViewHolder.java
deleted file mode 100644
index 9bb1555a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/ZeroStateViewHolder.java
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.ViewGroup.MarginLayoutParams;
-import android.widget.FrameLayout;
-import android.widget.FrameLayout.LayoutParams;
-
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.library.api.host.stream.CardConfiguration;
-import org.chromium.chrome.browser.feed.library.common.ui.LayoutUtils;
-
-/** {@link androidx.recyclerview.widget.RecyclerView.ViewHolder} for zero state. */
-public class ZeroStateViewHolder extends FeedViewHolder {
-    private final View mZeroStateView;
-    private final View mLoadingSpinner;
-    private final View mActionButton;
-    private final CardConfiguration mCardConfiguration;
-
-    public ZeroStateViewHolder(
-            Context context, FrameLayout frameLayout, CardConfiguration cardConfiguration) {
-        super(frameLayout);
-        View view = LayoutInflater.from(context).inflate(R.layout.zero_state, frameLayout);
-
-        mLoadingSpinner = view.findViewById(R.id.loading_spinner);
-        mZeroStateView = view.findViewById(R.id.zero_state);
-        mActionButton = view.findViewById(R.id.action_button);
-        this.mCardConfiguration = cardConfiguration;
-    }
-
-    public void bind(OnClickListener onClickListener, boolean showSpinner) {
-        View noContentView = itemView.findViewById(R.id.no_content_container);
-        setCardLayout(noContentView, mCardConfiguration);
-
-        mActionButton.setOnClickListener(onClickListener);
-        showSpinner(showSpinner);
-    }
-
-    @Override
-    public void unbind() {
-        // Clear OnClickListener to null to allow for GC.
-        mActionButton.setOnClickListener(null);
-
-        // Set clickable to false as setting OnClickListener to null sets clickable to true.
-        mActionButton.setClickable(false);
-    }
-
-    public void showSpinner(boolean showSpinner) {
-        mLoadingSpinner.setVisibility(showSpinner ? View.VISIBLE : View.GONE);
-        mZeroStateView.setVisibility(showSpinner ? View.GONE : View.VISIBLE);
-    }
-
-    private void setCardLayout(View cardView, CardConfiguration cardConfiguration) {
-        // Need to reset padding here.  Setting a background can affect padding so if we switch from
-        // a background which has padding to one that does not, then the padding needs to be
-        // removed.
-        cardView.setPadding(0, 0, 0, 0);
-
-        cardView.setBackground(cardConfiguration.getCardBackground());
-
-        ViewGroup.LayoutParams layoutParams = cardView.getLayoutParams();
-        if (layoutParams == null) {
-            layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
-        } else if (!(layoutParams instanceof MarginLayoutParams)) {
-            layoutParams = new LayoutParams(layoutParams);
-        }
-        cardView.setLayoutParams(layoutParams);
-
-        LayoutUtils.setMarginsRelative((MarginLayoutParams) layoutParams,
-                cardConfiguration.getCardStartMargin(),
-                0, // The top margin is not configurable by the host, so is always zero.
-                cardConfiguration.getCardEndMargin(), cardConfiguration.getCardBottomMargin());
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewloggingupdater/ResettableOneShotVisibilityLoggingListener.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewloggingupdater/ResettableOneShotVisibilityLoggingListener.java
deleted file mode 100644
index 6d18e97..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewloggingupdater/ResettableOneShotVisibilityLoggingListener.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.viewloggingupdater;
-
-import org.chromium.chrome.browser.feed.library.sharedstream.logging.LoggingListener;
-import org.chromium.chrome.browser.feed.library.sharedstream.logging.OneShotVisibilityLoggingListener;
-
-/** Extension of {@link OneShotVisibilityLoggingListener} that allows for re-logging visibility. */
-public class ResettableOneShotVisibilityLoggingListener extends OneShotVisibilityLoggingListener {
-    public ResettableOneShotVisibilityLoggingListener(LoggingListener loggingListener) {
-        super(loggingListener);
-    }
-
-    /**
-     * Resets whether this view has been logged as visible. This will result in the view being
-     * re-logged as visible once it is visible.
-     */
-    public void reset() {
-        mViewLogged = false;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewloggingupdater/ViewLoggingUpdater.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewloggingupdater/ViewLoggingUpdater.java
deleted file mode 100644
index 8fc33c9..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewloggingupdater/ViewLoggingUpdater.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.basicstream.internal.viewloggingupdater;
-
-import org.chromium.chrome.browser.feed.library.common.feedobservable.FeedObservable;
-
-/** {@link FeedObservable} to reset whether views have been logged as visible. */
-public class ViewLoggingUpdater extends FeedObservable<ResettableOneShotVisibilityLoggingListener> {
-    /** Resets views logging state to allow them to be re-logged as visible. */
-    public void resetViewTracking() {
-        for (ResettableOneShotVisibilityLoggingListener loggingListener : mObservers) {
-            loggingListener.reset();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/Result.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/Result.java
deleted file mode 100644
index 1008c8c4a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/Result.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common;
-
-import androidx.annotation.Nullable;
-
-/** Wrapper that allows callbacks to return a value as well as whether the call was successful. */
-public class Result<T> {
-    @Nullable
-    private final T mValue;
-    private final boolean mIsSuccessful;
-
-    private Result(@Nullable T value, boolean isSuccessful) {
-        this.mValue = value;
-        this.mIsSuccessful = isSuccessful;
-    }
-
-    public static <T> Result<T> success(T value) {
-        return new Result<>(value, /* isSuccessful= */ true);
-    }
-
-    public static <T> Result<T> failure() {
-        return new Result<>(null, false);
-    }
-
-    /** Retrieves the value for the result. */
-    public T getValue() {
-        if (!mIsSuccessful) {
-            throw new IllegalStateException("Cannot retrieve value for failed result");
-        }
-        return Validators.checkNotNull(mValue);
-    }
-
-    // TODO: replace isSuccessful with failed()
-    public boolean isSuccessful() {
-        return mIsSuccessful;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/Validators.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/Validators.java
deleted file mode 100644
index f0c9ead..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/Validators.java
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common;
-
-import androidx.annotation.Nullable;
-
-/**
- * Class similar to Guava's Preconditions. Not all users of Feed can use Guava libraries so we
- * define our own here.
- */
-public class Validators {
-    private Validators() {}
-
-    /**
-     * Ensures that an object reference passed as a parameter to the calling method is not null.
-     *
-     * @param reference an object reference
-     * @param debugString a debug string to add to the NPE if reference is null
-     * @param formatArgs arguments to populate the debugString using String.format
-     * @return the non-null reference that was validated
-     * @throws NullPointerException if {@code reference} is null
-     */
-    @SuppressWarnings("AnnotateFormatMethod")
-    public static <T> T checkNotNull(
-            @Nullable T reference, String debugString, Object... formatArgs) {
-        if (reference == null) {
-            throw new NullPointerException(String.format(debugString, formatArgs));
-        }
-        return reference;
-    }
-
-    /**
-     * Ensures that an object reference passed as a parameter to the calling method is not null.
-     *
-     * @param reference an object reference
-     * @return the non-null reference that was validated
-     * @throws NullPointerException if {@code reference} is null
-     */
-    public static <T> T checkNotNull(@Nullable T reference) {
-        if (reference == null) {
-            throw new NullPointerException();
-        }
-        return reference;
-    }
-
-    /**
-     * Assert that {@code expression} is {@code true}.
-     *
-     * @param expression a boolean value that should be true
-     * @param formatString a format string for the message for the IllegalStateException
-     * @param formatArgs arguments to the format string
-     * @throws IllegalStateException thrown if the expression is false
-     */
-    @SuppressWarnings("AnnotateFormatMethod")
-    public static void checkState(boolean expression, String formatString, Object... formatArgs) {
-        if (!expression) {
-            throw new IllegalStateException(String.format(formatString, formatArgs));
-        }
-    }
-
-    /**
-     * Assert that {@code expression} is {@code true}.
-     *
-     * @param expression a boolean value that should be true
-     * @throws IllegalStateException thrown if the expression is false
-     */
-    public static void checkState(boolean expression) {
-        if (!expression) {
-            throw new IllegalStateException();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/CancelableRunnableTask.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/CancelableRunnableTask.java
deleted file mode 100644
index e6b706e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/CancelableRunnableTask.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-package org.chromium.chrome.browser.feed.library.common.concurrent;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/** A thread safe runnable that can be canceled. */
-public class CancelableRunnableTask implements CancelableTask, Runnable {
-    private final AtomicBoolean mCanceled = new AtomicBoolean(false);
-    private final Runnable mRunnable;
-
-    public CancelableRunnableTask(Runnable runnable) {
-        this.mRunnable = runnable;
-    }
-
-    @Override
-    public void run() {
-        if (!mCanceled.get()) {
-            mRunnable.run();
-        }
-    }
-
-    @Override
-    public boolean canceled() {
-        return mCanceled.get();
-    }
-
-    @Override
-    public void cancel() {
-        mCanceled.set(true);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/CancelableTask.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/CancelableTask.java
deleted file mode 100644
index d29d872..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/CancelableTask.java
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-package org.chromium.chrome.browser.feed.library.common.concurrent;
-
-/** Interface for a task that can be canceled. */
-public interface CancelableTask {
-    /** Returns if the task has been canceled. */
-    boolean canceled();
-
-    /** Cancels the task to prevent it from running. */
-    void cancel();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/DirectHostSupported.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/DirectHostSupported.java
deleted file mode 100644
index 84fb2cf..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/DirectHostSupported.java
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.concurrent;
-
-/**
- * Marker interface indicating that the Host API supports direct calls, instead of requiring call to
- * be on the main thread.
- */
-public interface DirectHostSupported {}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/MainThreadCaller.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/MainThreadCaller.java
deleted file mode 100644
index b85dc9b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/MainThreadCaller.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.concurrent;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-import java.util.concurrent.ExecutionException;
-
-/** Abstract class which support calling Host methods on the {@link MainThreadRunner}. */
-public abstract class MainThreadCaller {
-    private static final String TAG = "MainThreadCaller";
-    private final MainThreadRunner mMainThreadRunner;
-
-    protected MainThreadCaller(MainThreadRunner mainThreadRunner) {
-        this.mMainThreadRunner = mainThreadRunner;
-    }
-
-    /** Execute a task with a {@link Consumer}. */
-    protected interface ConsumerTask<T> { void execute(Consumer<T> consumer); }
-
-    /**
-     * Run a {@link ConsumerTask} on the main thread, providing a Consumer to receive the results.
-     */
-    protected <T> T mainThreadCaller(String location, ConsumerTask<T> task, T failure) {
-        SimpleSettableFuture<T> sharedStatesFuture = new SimpleSettableFuture<>();
-        mMainThreadRunner.execute(
-                TAG + " " + location, () -> task.execute(sharedStatesFuture::put));
-        try {
-            return sharedStatesFuture.get();
-        } catch (InterruptedException | ExecutionException e) {
-            Logger.e(TAG, e, null);
-            return failure;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/MainThreadRunner.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/MainThreadRunner.java
deleted file mode 100644
index afbb0e5..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/MainThreadRunner.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.concurrent;
-
-import android.os.Handler;
-import android.os.Looper;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-import java.util.concurrent.Executor;
-
-/** Executes a task on the main thread (UI thread) with optional delay. */
-/*@DoNotMock("Use org.chromium.chrome.browser.feed.library.common.concurrent.FakeMainThreadRunner
- * instead")*/
-public class MainThreadRunner {
-    private static final String TAG = "MainThreadRunner";
-    private static final Handler sHandler = new Handler(Looper.getMainLooper());
-
-    private final Executor mExecutor;
-
-    public MainThreadRunner() {
-        this.mExecutor = sHandler::post;
-    }
-
-    /** Executes the {@code runnable} on the {@link Executor} used to initialize this class. */
-    public void execute(String name, Runnable runnable) {
-        Logger.i(TAG, "Running task [%s] on the Main Thread", name);
-        mExecutor.execute(runnable);
-    }
-
-    public CancelableTask executeWithDelay(String name, Runnable runnable, long delayMs) {
-        CancelableRunnableTask cancelable = new CancelableRunnableTask(runnable);
-        Logger.i(TAG, "Running task [%s] on the Main Thread with a delay of %d milliseconds", name,
-                delayMs);
-        sHandler.postDelayed(cancelable, delayMs);
-        return cancelable;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/SimpleSettableFuture.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/SimpleSettableFuture.java
deleted file mode 100644
index 9f3f9ab..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/SimpleSettableFuture.java
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.concurrent;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.common.Validators;
-
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-/** Simple future that allows for setting a value from another thread */
-public final class SimpleSettableFuture<V> implements Future<V> {
-    private final CountDownLatch mLatch = new CountDownLatch(1);
-    private boolean mCancelled;
-    @Nullable
-    private V mValue;
-    @Nullable
-    private Exception mException;
-
-    /** Note that this will not interrupt tasks as tasks aren't running within the future */
-    @Override
-    public boolean cancel(boolean mayInterruptIfRunning) {
-        // If already cancelled, return true;
-        if (isCancelled()) {
-            return true;
-        }
-
-        // If already complete, cannot cancel
-        if (isDone()) {
-            return false;
-        }
-
-        // Count down latch (to free the future up)
-        mLatch.countDown();
-        mCancelled = true;
-        return true;
-    }
-
-    @Override
-    public boolean isCancelled() {
-        return mCancelled;
-    }
-
-    @Override
-    public boolean isDone() {
-        return mLatch.getCount() == 0;
-    }
-
-    @Override
-    public V get() throws InterruptedException, ExecutionException {
-        mLatch.await();
-        if (isCancelled()) {
-            throw new ExecutionException(new CancellationException());
-        }
-        if (mException != null) {
-            throw new ExecutionException(mException);
-        }
-        return Validators.checkNotNull(mValue, "Unable to return null from a Future.get()");
-    }
-
-    @Override
-    public V get(long timeout, TimeUnit unit)
-            throws InterruptedException, ExecutionException, TimeoutException {
-        boolean timedOut = !mLatch.await(timeout, unit);
-        if (timedOut) {
-            throw new TimeoutException();
-        }
-        if (isCancelled()) {
-            throw new ExecutionException(new CancellationException());
-        }
-        if (mException != null) {
-            throw new ExecutionException(mException);
-        }
-        return Validators.checkNotNull(mValue, "Unable to return null from a Future.get()");
-    }
-
-    public void put(V value) {
-        if (!isDone()) {
-            this.mValue = value;
-            mLatch.countDown();
-        }
-    }
-
-    public void putException(Exception e) {
-        if (!isDone()) {
-            this.mException = e;
-            mLatch.countDown();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/TaskQueue.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/TaskQueue.java
deleted file mode 100644
index 0d76b0c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/TaskQueue.java
+++ /dev/null
@@ -1,618 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.concurrent;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.InternalFeedError;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.logging.StringFormattingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-
-import java.util.ArrayDeque;
-import java.util.Queue;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/**
- * This class is responsible for running tasks on the Feed single-threaded Executor. The primary job
- * of this class is to run high priority tasks and to delay certain task until other complete. When
- * we are delaying tasks, they will be added to a set of queues and will run in order within the
- * task priority. There are three priorities of tasks defined:
- *
- * <ol>
- *   <li>Initialization, HEAD_INVALIDATE, HEAD_RESET - These tasks will be placed on the Executor
- *       when they are received.
- *   <li>USER_FACING - These tasks are high priority, running after the immediate tasks.
- *   <li>BACKGROUND - These are low priority tasks which run after all other tasks finish.
- * </ol>
- *
- * <p>The {@code TaskQueue} start in initialization mode. All tasks will be delayed until we
- * initialization is completed. The {@link #initialize(Runnable)} method is run to initialize the
- * FeedSessionManager. We also enter delayed mode when we either reset the $HEAD or invalidate the
- * $HEAD. For HEAD_RESET, we are making a request which will complete. Once it's complete, we will
- * process any delayed tasks. HEAD_INVALIDATE simply clears the contents of $HEAD. The expectation
- * is a future HEAD_RESET will populate $HEAD. Once the delay is cleared, we will run the
- * USER_FACING tasks followed by the BACKGROUND tasks. Once all of these tasks have run, we will run
- * tasks immediately until we either have a task which is of type HEAD_INVALIDATE or HEAD_RESET.
- */
-// TODO: This class should be final for Tiktok conformance
-public class TaskQueue implements Dumpable {
-    private static final String TAG = "TaskQueue";
-
-    /**
-     * Once we delay the queue, if we are not making any progress after the initial {@code
-     * #STARVATION_TIMEOUT_MS}, we will start running tasks. {@link #STARVATION_CHECK_MS} is the
-     * amount of time until we check for starvation. Checking for starvation is done on the main
-     * thread. Starvation checks are started when we initially delay the queue and only runs while
-     * the queue is delayed.
-     */
-    @VisibleForTesting
-    public static final long STARVATION_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(15);
-
-    @VisibleForTesting
-    static final long STARVATION_CHECK_MS = TimeUnit.SECONDS.toMillis(6);
-
-    /** TaskType identifies the type of task being run and implicitly the priority of the task */
-    @IntDef({
-            TaskType.UNKNOWN,
-            TaskType.IMMEDIATE,
-            TaskType.HEAD_INVALIDATE,
-            TaskType.HEAD_RESET,
-            TaskType.USER_FACING,
-            TaskType.BACKGROUND,
-    })
-    public @interface TaskType {
-        // Unknown task priority, shouldn't be used, this will be treated as a background task
-        int UNKNOWN = 0;
-        // Runs immediately.  IMMEDIATE tasks will wait for initialization to be finished
-        int IMMEDIATE = 1;
-        // Runs immediately, $HEAD is invalidated (cleared) and delay tasks until HEAD_RESET
-        int HEAD_INVALIDATE = 2;
-        // Runs immediately, indicates the task will create a new $HEAD instance.
-        // Once finished, start running other tasks until the delayed tasks are all run.
-        int HEAD_RESET = 3;
-        // User facing task which should run at a higher priority than Background.
-        int USER_FACING = 4;
-        // Background tasks run at the lowest priority
-        int BACKGROUND = 5;
-    }
-
-    private final Object mLock = new Object();
-
-    @GuardedBy("mLock")
-    private final Queue<TaskWrapper> mImmediateTasks = new ArrayDeque<>();
-
-    @GuardedBy("mLock")
-    private final Queue<TaskWrapper> mUserTasks = new ArrayDeque<>();
-
-    @GuardedBy("mLock")
-    private final Queue<TaskWrapper> mBackgroundTasks = new ArrayDeque<>();
-
-    @GuardedBy("mLock")
-    private boolean mWaitingForHeadReset;
-
-    @GuardedBy("mLock")
-    private boolean mInitialized;
-
-    /**
-     * CancelableTask that tracks the current starvation runnable. {@liternal null} means that
-     * starvation checks are not running.
-     */
-    @GuardedBy("mLock")
-    @Nullable
-    private CancelableTask mStarvationCheckTask;
-
-    // Tracks the current task running on the executor
-    @Nullable
-    private TaskWrapper mCurrentTask;
-
-    /** Track the time the last task finished. Used for Starvation checks. */
-    private final AtomicLong mLastTaskFinished = new AtomicLong();
-
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final Executor mExecutor;
-    private final Clock mClock;
-    private final MainThreadRunner mMainThreadRunner;
-
-    // counters used for dump
-    protected int mTaskCount;
-    protected int mImmediateRunCount;
-    protected int mDelayedRunCount;
-    protected int mImmediateTaskCount;
-    protected int mHeadInvalidateTaskCount;
-    protected int mHeadResetTaskCount;
-    protected int mUserFacingTaskCount;
-    protected int mBackgroundTaskCount;
-    protected int mMaxImmediateTasks;
-    protected int mMaxUserFacingTasks;
-    protected int mMaxBackgroundTasks;
-
-    public TaskQueue(BasicLoggingApi basicLoggingApi, Executor executor,
-            MainThreadRunner mainThreadRunner, Clock clock) {
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mExecutor = executor;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mClock = clock;
-    }
-
-    /** Returns {@code true} if we are delaying for a request */
-    public boolean isMakingRequest() {
-        synchronized (mLock) {
-            return mWaitingForHeadReset;
-        }
-    }
-
-    /**
-     * This method will reset the task queue. This means we will delay all tasks created until the
-     * {@link #initialize(Runnable)} task is called again. Also any currently delayed tasks will be
-     * removed from the Queue and not run.
-     */
-    public void reset() {
-        synchronized (mLock) {
-            mWaitingForHeadReset = false;
-            mInitialized = false;
-
-            // clear all delayed tasks
-            Logger.i(TAG, " - Reset i: %s, u: %s, b: %s", mImmediateTasks.size(), mUserTasks.size(),
-                    mBackgroundTasks.size());
-            mImmediateTasks.clear();
-            mUserTasks.clear();
-            mBackgroundTasks.clear();
-
-            // Since we are delaying thing, start the starvation checker
-            startStarvationCheck();
-        }
-    }
-
-    /** this is called post reset to clear the initialized flag. */
-    public void completeReset() {
-        Logger.i(TAG, "completeReset");
-        synchronized (mLock) {
-            mInitialized = true;
-        }
-
-        maybeCancelStarvationCheck();
-    }
-
-    /**
-     * Called to initialize the {@link FeedSessionManager}. This needs to be the first task run, all
-     * other tasks are delayed until initialization finishes.
-     */
-    public void initialize(Runnable runnable) {
-        synchronized (mLock) {
-            if (mInitialized) {
-                Logger.w(TAG, " - Calling initialize on an initialized TaskQueue");
-            }
-        }
-
-        TaskWrapper task = new InitializationTaskWrapper(runnable);
-        countTask(task.mTaskType);
-        task.runTask();
-    }
-
-    /** Execute a Task on the Executor. */
-    public void execute(@Task int task, @TaskType int taskType, Runnable runnable) {
-        execute(task, taskType, runnable, null, 0);
-    }
-
-    /** Execute a task providing a timeout task. */
-    public void execute(@Task int task, @TaskType int taskType, Runnable runnable,
-            @Nullable Runnable timeOutRunnable, long timeoutMillis) {
-        countTask(taskType);
-        TaskWrapper taskWrapper = getTaskWrapper(task, taskType, runnable);
-        if (timeOutRunnable != null) {
-            taskWrapper = new TimeoutTaskWrapper(task, taskType, taskWrapper, timeOutRunnable)
-                                  .startTimeout(timeoutMillis);
-        }
-        // TODO: Log task name instead of task number
-        Logger.i(TAG, " - task [%s - d: %s, b: %s]: %s", taskTypeToString(taskType), isDelayed(),
-                backlogSize(), task);
-        scheduleTask(taskWrapper, taskType);
-    }
-
-    private void startStarvationCheck() {
-        synchronized (mLock) {
-            if (mStarvationCheckTask != null) {
-                Logger.i(TAG, "Starvation Checks are already running");
-                return;
-            }
-
-            if (isDelayed()) {
-                Logger.i(TAG, " * Starting starvation checks");
-                mStarvationCheckTask = mMainThreadRunner.executeWithDelay(
-                        "starvationChecks", new StarvationChecker(), STARVATION_CHECK_MS);
-            }
-        }
-    }
-
-    private void maybeCancelStarvationCheck() {
-        synchronized (mLock) {
-            CancelableTask localTask = mStarvationCheckTask;
-            if (!isDelayed() && localTask != null) {
-                Logger.i(TAG, "Cancelling starvation checks");
-                localTask.cancel();
-                mStarvationCheckTask = null;
-            }
-        }
-    }
-
-    private final class StarvationChecker implements Runnable {
-        @Override
-        public void run() {
-            // TODO: isDelayed shouldn't be called if starvationCheckTask is properly
-            // cancelled.
-            if (!isDelayed() && !hasBacklog()) {
-                // Quick out, we are not delaying things, this stops starvation checking
-                Logger.i(TAG, " * Starvation checks being turned off");
-                synchronized (mLock) {
-                    mStarvationCheckTask = null;
-                }
-                return;
-            }
-            long lastTask = mLastTaskFinished.get();
-            Logger.i(TAG, " * Starvation Check, last task %s",
-                    StringFormattingUtils.formatLogDate(lastTask));
-            if (mClock.currentTimeMillis() >= lastTask + STARVATION_TIMEOUT_MS) {
-                Logger.e(TAG, " - Starvation check failed, stopping the delay and running tasks");
-                mBasicLoggingApi.onInternalError(InternalFeedError.TASK_QUEUE_STARVATION);
-                // Reset the delay since things aren't being run
-                synchronized (mLock) {
-                    if (mWaitingForHeadReset) {
-                        mWaitingForHeadReset = false;
-                    }
-                    if (!mInitialized) {
-                        mInitialized = true;
-                    }
-                    mStarvationCheckTask = null;
-                }
-                executeNextTask();
-            } else {
-                synchronized (mLock) {
-                    mStarvationCheckTask = mMainThreadRunner.executeWithDelay(
-                            "StarvationChecks", this, STARVATION_CHECK_MS);
-                }
-            }
-        }
-    }
-
-    private void scheduleTask(TaskWrapper taskWrapper, @TaskType int taskType) {
-        if (isDelayed() || hasBacklog()) {
-            mDelayedRunCount++;
-            queueTask(taskWrapper, taskType);
-        } else {
-            mImmediateRunCount++;
-            taskWrapper.runTask();
-        }
-    }
-
-    private TaskWrapper getTaskWrapper(@Task int task, @TaskType int taskType, Runnable runnable) {
-        if (taskType == TaskType.HEAD_RESET) {
-            return new HeadResetTaskWrapper(task, taskType, runnable);
-        }
-        if (taskType == TaskType.HEAD_INVALIDATE) {
-            return new HeadInvalidateTaskWrapper(task, taskType, runnable);
-        }
-        return new TaskWrapper(task, taskType, runnable);
-    }
-
-    private void queueTask(TaskWrapper taskWrapper, @TaskType int taskType) {
-        synchronized (mLock) {
-            if (taskType == TaskType.HEAD_INVALIDATE || taskType == TaskType.HEAD_RESET
-                    || taskType == TaskType.IMMEDIATE) {
-                if (taskType == TaskType.HEAD_INVALIDATE && haveHeadInvalidate()) {
-                    Logger.w(TAG, " - Duplicate HeadInvalidate Task Found, ignoring new one");
-                    return;
-                }
-                mImmediateTasks.add(taskWrapper);
-                mMaxImmediateTasks = Math.max(mImmediateTasks.size(), mMaxImmediateTasks);
-                // An immediate could be created in a delayed state (invalidate head), so we check
-                // to see if we need to run tasks
-                if (mInitialized && (mCurrentTask == null)) {
-                    Logger.i(TAG, " - queueTask starting immediate task");
-                    executeNextTask();
-                }
-            } else if (taskType == TaskType.USER_FACING) {
-                mUserTasks.add(taskWrapper);
-                mMaxUserFacingTasks = Math.max(mUserTasks.size(), mMaxUserFacingTasks);
-            } else {
-                mBackgroundTasks.add(taskWrapper);
-                mMaxBackgroundTasks = Math.max(mBackgroundTasks.size(), mMaxBackgroundTasks);
-            }
-        }
-    }
-
-    private boolean haveHeadInvalidate() {
-        synchronized (mLock) {
-            for (TaskWrapper taskWrapper : mImmediateTasks) {
-                if (taskWrapper.mTaskType == TaskType.HEAD_INVALIDATE) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private void countTask(@TaskType int taskType) {
-        mTaskCount++;
-        if (taskType == TaskType.IMMEDIATE) {
-            mImmediateTaskCount++;
-        } else if (taskType == TaskType.HEAD_INVALIDATE) {
-            mHeadInvalidateTaskCount++;
-        } else if (taskType == TaskType.HEAD_RESET) {
-            mHeadResetTaskCount++;
-        } else if (taskType == TaskType.USER_FACING) {
-            mUserFacingTaskCount++;
-        } else if (taskType == TaskType.BACKGROUND) {
-            mBackgroundTaskCount++;
-        }
-    }
-
-    /** Indicates that tasks are being delayed until a response is processed */
-    public boolean isDelayed() {
-        synchronized (mLock) {
-            return !mInitialized || mWaitingForHeadReset;
-        }
-    }
-
-    /** Returns {@literal true} if no tasks are running and no tasks are enqueued. */
-    public boolean isIdle() {
-        return !hasBacklog() && mCurrentTask == null;
-    }
-
-    /** Returns {@literal true} if there are tests enqueued to run. */
-    public boolean hasBacklog() {
-        synchronized (mLock) {
-            return !mBackgroundTasks.isEmpty() || !mUserTasks.isEmpty()
-                    || !mImmediateTasks.isEmpty();
-        }
-    }
-
-    @VisibleForTesting
-    boolean hasPendingStarvationCheck() {
-        synchronized (mLock) {
-            return mStarvationCheckTask != null && !mStarvationCheckTask.canceled();
-        }
-    }
-
-    private int backlogSize() {
-        synchronized (mLock) {
-            return mBackgroundTasks.size() + mUserTasks.size() + mImmediateTasks.size();
-        }
-    }
-
-    private void executeNextTask() {
-        mLastTaskFinished.set(mClock.currentTimeMillis());
-        synchronized (mLock) {
-            TaskWrapper task = null;
-            if (!mImmediateTasks.isEmpty()) {
-                task = mImmediateTasks.remove();
-            } else if (!mUserTasks.isEmpty() && !isDelayed()) {
-                task = mUserTasks.remove();
-            } else if (!mBackgroundTasks.isEmpty() && !isDelayed()) {
-                task = mBackgroundTasks.remove();
-            }
-            if (task != null) {
-                task.runTask();
-            }
-        }
-    }
-
-    /**
-     * This class wraps the Runnable as a Runnable. It provides common handling of all tasks. This
-     * is the default which supports the basic Task, subclasses will manage state changes.
-     */
-    private class TaskWrapper implements Runnable {
-        @Task
-        protected final int mTask;
-        final int mTaskType;
-        protected final Runnable mRunnable;
-        private final long mQueueTimeMs;
-
-        TaskWrapper(@Task int task, @TaskType int taskType, Runnable runnable) {
-            this.mTask = task;
-            this.mTaskType = taskType;
-            this.mRunnable = runnable;
-            this.mQueueTimeMs = mClock.elapsedRealtime();
-        }
-
-        /** This will run the task on the {@link Executor}. */
-        void runTask() {
-            mExecutor.execute(this);
-        }
-
-        /**
-         * Run the task (Runnable) then trigger execution of the next task. Prevent subclasses from
-         * overriding this method because it tracks state of tasks on the Executor. Protected
-         * methods allow subclasses to customize the {@code run} behavior.
-         */
-        @Override
-        public final void run() {
-            long startTimeMs = mClock.elapsedRealtime();
-            // TODO: Log task name instead of task number
-            Logger.i(TAG, "Execute task [%s - d: %s, b: %s]: %s", taskTypeToString(mTaskType),
-                    isDelayed(), backlogSize(), mTask);
-            // maintain the currentTask on the stack encase we queue multiple tasks to the Executor
-            TaskWrapper saveTask = mCurrentTask;
-            mCurrentTask = this;
-            mRunnable.run();
-            postRunnableRun();
-
-            mCurrentTask = saveTask;
-
-            int taskExecutionTime = (int) (mClock.elapsedRealtime() - startTimeMs);
-            int taskDelayTime = (int) (startTimeMs - mQueueTimeMs);
-
-            // TODO: Log task name instead of task number
-            Logger.i(TAG, " - Finished %s, time %s ms", mTask, taskExecutionTime);
-            mBasicLoggingApi.onTaskFinished(mTask, taskDelayTime, taskExecutionTime);
-            executeNextTask();
-        }
-
-        /** This allows subclasses to run code post execution of the Task itself. */
-        protected void postRunnableRun() {}
-    }
-
-    /**
-     * Initialization will flip the {@link #mInitialized} state to {@code true} when the
-     * initialization task completes.
-     */
-    private final class InitializationTaskWrapper extends TaskWrapper {
-        InitializationTaskWrapper(Runnable runnable) {
-            super(Task.TASK_QUEUE_INITIALIZE, TaskType.IMMEDIATE, runnable);
-        }
-
-        @Override
-        protected void postRunnableRun() {
-            synchronized (mLock) {
-                mInitialized = true;
-            }
-        }
-    }
-
-    /**
-     * HeadReset will run a task which resets $HEAD. It clears the {@link #mWaitingForHeadReset}
-     * state.
-     */
-    private final class HeadResetTaskWrapper extends TaskWrapper {
-        HeadResetTaskWrapper(@Task int task, @TaskType int taskType, Runnable runnable) {
-            super(task, taskType, runnable);
-        }
-
-        @Override
-        protected void postRunnableRun() {
-            synchronized (mLock) {
-                mWaitingForHeadReset = false;
-            }
-            maybeCancelStarvationCheck();
-        }
-    }
-
-    /**
-     * HeadInvalidate is a task which marks the current head as invalid. The TaskQueue will then be
-     * delayed until {@link HeadResetTaskWrapper} has completed. This will set the {@link
-     * #mWaitingForHeadReset}. In addition starvation checks will be started.
-     */
-    private final class HeadInvalidateTaskWrapper extends TaskWrapper {
-        HeadInvalidateTaskWrapper(@Task int task, @TaskType int taskType, Runnable runnable) {
-            super(task, taskType, runnable);
-        }
-
-        @Override
-        void runTask() {
-            synchronized (mLock) {
-                mWaitingForHeadReset = true;
-            }
-            super.runTask();
-        }
-
-        @Override
-        protected void postRunnableRun() {
-            startStarvationCheck();
-        }
-    }
-
-    /**
-     * Runs a Task which has a timeout. The timeout task (Runnable) will run if the primary task is
-     * not started before the timeout millis.
-     */
-    private final class TimeoutTaskWrapper extends TaskWrapper {
-        private final AtomicBoolean mStarted = new AtomicBoolean(false);
-        private final Runnable mTimeoutRunnable;
-        @Nullable
-        private CancelableTask mTimeoutTask;
-
-        TimeoutTaskWrapper(@Task int task, @TaskType int taskType, Runnable taskRunnable,
-                Runnable timeoutRunnable) {
-            super(task, taskType, taskRunnable);
-            this.mTimeoutRunnable = timeoutRunnable;
-        }
-
-        /**
-         * Start the timeout period. If we reach the timeout before the Task is run, the {@link
-         * #mTimeoutRunnable} will run.
-         */
-        private TimeoutTaskWrapper startTimeout(long timeoutMillis) {
-            mTimeoutTask = mMainThreadRunner.executeWithDelay(
-                    "taskTimeout", this::runTimeoutCallback, timeoutMillis);
-            return this;
-        }
-
-        @Override
-        void runTask() {
-            // If the boolean is already set then runTimeoutCallback has run.
-            if (mStarted.getAndSet(true)) {
-                Logger.w(TAG, " - runTimeoutCallback already ran [%s]", mTask);
-                executeNextTask();
-                return;
-            }
-
-            CancelableTask localTask = mTimeoutTask;
-            if (localTask != null) {
-                Logger.i(TAG, "Cancelling timeout [%s]", mTask);
-                localTask.cancel();
-                mTimeoutTask = null;
-            }
-
-            super.runTask();
-        }
-
-        private void runTimeoutCallback() {
-            // If the boolean is already set then runTask has run.
-            if (mStarted.getAndSet(true)) {
-                Logger.w(TAG, " - runTask already ran [%s]", mTask);
-                return;
-            }
-
-            Logger.w(TAG, "Execute Timeout [%s]: %s", mTaskType, mTask);
-            mExecutor.execute(mTimeoutRunnable);
-        }
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        dumper.forKey("tasks").value(mTaskCount);
-        dumper.forKey("immediateRun").value(mImmediateRunCount).compactPrevious();
-        dumper.forKey("delayedRun").value(mDelayedRunCount).compactPrevious();
-
-        dumper.forKey("immediateTasks").value(mImmediateTaskCount);
-        dumper.forKey("headInvalidateTasks").value(mHeadInvalidateTaskCount).compactPrevious();
-        dumper.forKey("headResetTasks").value(mHeadResetTaskCount).compactPrevious();
-        dumper.forKey("userFacingTasks").value(mUserFacingTaskCount).compactPrevious();
-        dumper.forKey("backgroundTasks").value(mBackgroundTaskCount).compactPrevious();
-
-        dumper.forKey("maxImmediateQueue").value(mMaxImmediateTasks);
-        dumper.forKey("maxUserFacingQueue").value(mMaxUserFacingTasks).compactPrevious();
-        dumper.forKey("maxBackgroundQueue").value(mMaxBackgroundTasks).compactPrevious();
-    }
-
-    private static String taskTypeToString(@TaskType int taskType) {
-        switch (taskType) {
-            case TaskType.IMMEDIATE:
-                return "IMMEDIATE";
-            case TaskType.HEAD_INVALIDATE:
-                return "HEAD_INVALIDATE";
-            case TaskType.HEAD_RESET:
-                return "HEAD_RESET";
-            case TaskType.USER_FACING:
-                return "USER_FACING";
-            case TaskType.BACKGROUND:
-                return "BACKGROUND";
-            default:
-                return "UNKNOWN";
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeDirectExecutor.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeDirectExecutor.java
deleted file mode 100644
index 61cf397..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeDirectExecutor.java
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.concurrent.testing;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/** Fake {@link Executor} that enforces a background thread. */
-public final class FakeDirectExecutor implements Executor {
-    private final AtomicBoolean mCurrentlyExecutingTasks = new AtomicBoolean();
-    private final FakeThreadUtils mFakeThreadUtils;
-    private final List<Runnable> mTasksToRun = new ArrayList<>();
-    private final boolean mShouldQueueTasks;
-
-    public static FakeDirectExecutor runTasksImmediately(FakeThreadUtils fakeThreadUtils) {
-        return new FakeDirectExecutor(fakeThreadUtils, /* shouldQueueTasks= */ false);
-    }
-
-    public static FakeDirectExecutor queueAllTasks(FakeThreadUtils fakeThreadUtils) {
-        return new FakeDirectExecutor(fakeThreadUtils, /* shouldQueueTasks= */ true);
-    }
-
-    private FakeDirectExecutor(FakeThreadUtils fakeThreadUtils, boolean shouldQueueTasks) {
-        this.mFakeThreadUtils = fakeThreadUtils;
-        this.mShouldQueueTasks = shouldQueueTasks;
-    }
-
-    @Override
-    public void execute(Runnable command) {
-        mTasksToRun.add(command);
-        if (!mShouldQueueTasks) {
-            runAllTasks();
-        }
-    }
-
-    public void runAllTasks() {
-        if (mCurrentlyExecutingTasks.getAndSet(true)) {
-            return;
-        }
-
-        boolean policy = mFakeThreadUtils.enforceMainThread(false);
-        try {
-            while (!mTasksToRun.isEmpty()) {
-                Runnable task = mTasksToRun.remove(0);
-                task.run();
-            }
-        } finally {
-            mFakeThreadUtils.enforceMainThread(policy);
-            mCurrentlyExecutingTasks.set(false);
-        }
-    }
-
-    public boolean hasTasks() {
-        return !mTasksToRun.isEmpty();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeMainThreadRunner.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeMainThreadRunner.java
deleted file mode 100644
index 32a279bd..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeMainThreadRunner.java
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.concurrent.testing;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-
-import org.chromium.chrome.browser.feed.library.common.concurrent.CancelableRunnableTask;
-import org.chromium.chrome.browser.feed.library.common.concurrent.CancelableTask;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.time.testing.FakeClock;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.PriorityQueue;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * A {@link MainThreadRunner} which listens to a {@link FakeClock} to determine when to execute
- * delayed tasks. This class can optionally execute tasks immediately and enforce thread checks.
- */
-public final class FakeMainThreadRunner extends MainThreadRunner {
-    private final AtomicBoolean mCurrentlyExecutingTasks = new AtomicBoolean();
-    private final FakeClock mFakeClock;
-    private final FakeThreadUtils mFakeThreadUtils;
-    private final List<Runnable> mTasksToRun = new ArrayList<>();
-    private final boolean mShouldQueueTasks;
-
-    private final PriorityQueue<TimedRunnable> mDelayedTasks = new PriorityQueue<>(
-            1, (a, b) -> Long.compare(a.getExecutionTime(), b.getExecutionTime()));
-
-    private int mCompletedTaskCount;
-
-    public static FakeMainThreadRunner create(FakeClock fakeClock) {
-        return new FakeMainThreadRunner(
-                fakeClock, FakeThreadUtils.withoutThreadChecks(), /* shouldQueueTasks= */ false);
-    }
-
-    public static FakeMainThreadRunner runTasksImmediately() {
-        return create(new FakeClock());
-    }
-
-    public static FakeMainThreadRunner runTasksImmediatelyWithThreadChecks(
-            FakeThreadUtils fakeThreadUtils) {
-        return new FakeMainThreadRunner(
-                new FakeClock(), fakeThreadUtils, /* shouldQueueTasks= */ false);
-    }
-
-    public static FakeMainThreadRunner queueAllTasks() {
-        return new FakeMainThreadRunner(new FakeClock(), FakeThreadUtils.withoutThreadChecks(),
-                /* shouldQueueTasks= */ true);
-    }
-
-    private FakeMainThreadRunner(
-            FakeClock fakeClock, FakeThreadUtils fakeThreadUtils, boolean shouldQueueTasks) {
-        this.mFakeClock = fakeClock;
-        this.mFakeThreadUtils = fakeThreadUtils;
-        this.mShouldQueueTasks = shouldQueueTasks;
-        fakeClock.registerObserver(
-                (newCurrentTime, newElapsedRealtime) -> runTasksBefore(newElapsedRealtime));
-    }
-
-    private void runTasksBefore(long newElapsedRealtime) {
-        TimedRunnable nextTask;
-        while ((nextTask = mDelayedTasks.peek()) != null) {
-            if (nextTask.getExecutionTime() > newElapsedRealtime) {
-                break;
-            }
-
-            Runnable task = checkNotNull(mDelayedTasks.poll());
-            mTasksToRun.add(task);
-        }
-
-        if (!mShouldQueueTasks) {
-            runAllTasks();
-        }
-    }
-
-    @Override
-    public void execute(String name, Runnable runnable) {
-        mTasksToRun.add(runnable);
-        if (!mShouldQueueTasks) {
-            runAllTasks();
-        }
-    }
-
-    @Override
-    public CancelableTask executeWithDelay(String name, Runnable runnable, long delayMs) {
-        CancelableRunnableTask cancelable = new CancelableRunnableTask(runnable);
-        mDelayedTasks.add(new TimedRunnable(cancelable, mFakeClock.elapsedRealtime() + delayMs));
-        return cancelable;
-    }
-
-    /** Runs all eligible tasks. */
-    public void runAllTasks() {
-        if (mCurrentlyExecutingTasks.getAndSet(true)) {
-            return;
-        }
-
-        boolean policy = mFakeThreadUtils.enforceMainThread(true);
-        try {
-            while (!mTasksToRun.isEmpty()) {
-                Runnable task = mTasksToRun.remove(0);
-                task.run();
-                mCompletedTaskCount++;
-            }
-        } finally {
-            mFakeThreadUtils.enforceMainThread(policy);
-            mCurrentlyExecutingTasks.set(false);
-        }
-    }
-
-    /** Returns {@literal true} if there are tasks to run in the future. */
-    public boolean hasPendingTasks() {
-        if (!mTasksToRun.isEmpty()) {
-            return true;
-        }
-
-        for (TimedRunnable runnable : mDelayedTasks) {
-            if (!runnable.isCanceled()) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /** Returns {@literal true} if there are tasks to run or tasks have run. */
-    public boolean hasTasks() {
-        return !mTasksToRun.isEmpty() || mCompletedTaskCount != 0;
-    }
-
-    /** Returns the number of tasks that have run. */
-    public int getCompletedTaskCount() {
-        return mCompletedTaskCount;
-    }
-
-    private static final class TimedRunnable implements Runnable {
-        private final CancelableRunnableTask mRunnable;
-        private final long mExecutionTime;
-
-        private TimedRunnable(CancelableRunnableTask runnable, long executeTime) {
-            this.mRunnable = runnable;
-            this.mExecutionTime = executeTime;
-        }
-
-        private long getExecutionTime() {
-            return mExecutionTime;
-        }
-
-        private boolean isCanceled() {
-            return mRunnable.canceled();
-        }
-
-        @Override
-        public void run() {
-            mRunnable.run();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeTaskQueue.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeTaskQueue.java
deleted file mode 100644
index 260d15e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeTaskQueue.java
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.concurrent.testing;
-
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.time.testing.FakeClock;
-import org.chromium.chrome.browser.feed.library.testing.host.logging.FakeBasicLoggingApi;
-
-/** A fake {@link TaskQueue} implementation. */
-public final class FakeTaskQueue extends TaskQueue {
-    private boolean mResetWasCalled;
-    private boolean mCompleteResetWasCalled;
-
-    public FakeTaskQueue(FakeClock fakeClock, FakeThreadUtils fakeThreadUtils) {
-        this(fakeClock, FakeDirectExecutor.runTasksImmediately(fakeThreadUtils));
-    }
-
-    public FakeTaskQueue(FakeClock fakeClock, FakeDirectExecutor fakeDirectExecutor) {
-        super(new FakeBasicLoggingApi(), fakeDirectExecutor, FakeMainThreadRunner.create(fakeClock),
-                fakeClock);
-    }
-
-    @Override
-    public void reset() {
-        super.reset();
-        mResetWasCalled = true;
-    }
-
-    @Override
-    public void completeReset() {
-        super.completeReset();
-        mCompleteResetWasCalled = true;
-    }
-
-    public void resetCounts() {
-        mTaskCount = 0;
-        mImmediateTaskCount = 0;
-        mHeadInvalidateTaskCount = 0;
-        mHeadResetTaskCount = 0;
-        mUserFacingTaskCount = 0;
-        mBackgroundTaskCount = 0;
-    }
-
-    public int getBackgroundTaskCount() {
-        return mBackgroundTaskCount;
-    }
-
-    public int getImmediateTaskCount() {
-        return mImmediateTaskCount;
-    }
-
-    public int getUserFacingTaskCount() {
-        return mUserFacingTaskCount;
-    }
-
-    public boolean resetWasCalled() {
-        return mResetWasCalled;
-    }
-
-    public boolean completeResetWasCalled() {
-        return mCompleteResetWasCalled;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeThreadUtils.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeThreadUtils.java
deleted file mode 100644
index ad37cf8..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeThreadUtils.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.concurrent.testing;
-
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-
-/** Fake implements of {@link ThreadUtils} that allows callers to control the thread policy. */
-public final class FakeThreadUtils extends ThreadUtils {
-    private boolean mIsMainThread = true;
-    private boolean mEnforceThreadChecks = true;
-
-    private FakeThreadUtils(boolean enforceThreadChecks) {
-        this.mEnforceThreadChecks = enforceThreadChecks;
-    }
-
-    @Override
-    public boolean isMainThread() {
-        return mIsMainThread;
-    }
-
-    @Override
-    protected void check(boolean condition, String message) {
-        if (mEnforceThreadChecks) {
-            super.check(condition, message);
-        }
-    }
-
-    /**
-     * Updates whether the current execution is considered to be on the main thread. Returns the
-     * existing thread policy.
-     */
-    public boolean enforceMainThread(boolean enforceMainThread) {
-        boolean result = mIsMainThread;
-        mIsMainThread = enforceMainThread;
-        return result;
-    }
-
-    /** Create a {@link FakeThreadUtils} with thread enforcement. */
-    public static FakeThreadUtils withThreadChecks() {
-        return new FakeThreadUtils(/* enforceThreadChecks= */ true);
-    }
-
-    /** Create a {@link FakeThreadUtils} without thread enforcement. */
-    public static FakeThreadUtils withoutThreadChecks() {
-        return new FakeThreadUtils(/* enforceThreadChecks= */ false);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/FeedObservable.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/FeedObservable.java
deleted file mode 100644
index 5651eb2..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/FeedObservable.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.feedobservable;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/** Provides methods for registering or unregistering arbitrary observers. */
-public abstract class FeedObservable<ObserverT> implements Observable<ObserverT> {
-    private static final String TAG = "FeedObservable";
-
-    protected final Set<ObserverT> mObservers = new HashSet<>();
-
-    /** Adds given {@code observer}. No-op if the observer has already been added. */
-    @Override
-    public void registerObserver(ObserverT observer) {
-        synchronized (mObservers) {
-            if (!mObservers.add(observer)) {
-                Logger.w(TAG, "Registering observer: %s multiple times.", observer);
-            }
-        }
-    }
-
-    /** Removes given {@code observer}. No-op if the observer is not currently added. */
-    @Override
-    public void unregisterObserver(ObserverT observer) {
-        synchronized (mObservers) {
-            if (!mObservers.remove(observer)) {
-                Logger.w(TAG, "Unregistering observer: %s that isn't registered.", observer);
-            }
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/ImmediatelyNotifyingObservableNotifier.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/ImmediatelyNotifyingObservableNotifier.java
deleted file mode 100644
index a7adaf1b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/ImmediatelyNotifyingObservableNotifier.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.feedobservable;
-
-import org.chromium.base.Consumer;
-
-/**
- * A FeedObservable implementation that allows calling a notify method on all observers, and
- * immediately triggers observers when they are registered.
- */
-public final class ImmediatelyNotifyingObservableNotifier<ObserverT>
-        extends FeedObservable<ObserverT> {
-    private Consumer<ObserverT> mCurrentConsumer;
-
-    public ImmediatelyNotifyingObservableNotifier(Consumer<ObserverT> listenerMethod) {
-        mCurrentConsumer = listenerMethod;
-    }
-
-    @Override
-    public void registerObserver(ObserverT observerT) {
-        super.registerObserver(observerT);
-        mCurrentConsumer.accept(observerT);
-    }
-
-    /** Calls all the registered listeners using the given listener method. */
-    public void notifyListeners(Consumer<ObserverT> listenerMethod) {
-        mCurrentConsumer = listenerMethod;
-        synchronized (mObservers) {
-            for (ObserverT listener : mObservers) {
-                listenerMethod.accept(listener);
-            }
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/Observable.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/Observable.java
deleted file mode 100644
index 2a315127..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/Observable.java
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.feedobservable;
-
-/** Allows for registering and unregistering observers */
-public interface Observable<ObserverT> {
-    /** Register a new observer. If already registered, will have no effect. */
-    void registerObserver(ObserverT observer);
-
-    /** Unregister an observer. If not registered, will have no effect. */
-    void unregisterObserver(ObserverT observer);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/ObservableNotifier.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/ObservableNotifier.java
deleted file mode 100644
index 03115a4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/ObservableNotifier.java
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.feedobservable;
-
-import org.chromium.base.Consumer;
-
-/** A FeedObservable implementation that allows calling a notify method on all observers. */
-public class ObservableNotifier<ObserverT> extends FeedObservable<ObserverT> {
-    /** Calls all the registered listeners using the given listener method. */
-    public void notifyListeners(Consumer<ObserverT> listenerMethod) {
-        synchronized (mObservers) {
-            for (ObserverT listener : mObservers) {
-                listenerMethod.accept(listener);
-            }
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/functional/Committer.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/functional/Committer.java
deleted file mode 100644
index aed6f91..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/functional/Committer.java
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.functional;
-
-/**
- * Interface which externalizes the action of committing a mutation from the class implementing the
- * mutation. This is a common design pattern used to mutate the library components. The mutation
- * builder will call a {@code Committer} to commit the accumulated changes.
- *
- * @param <R> The return value
- * @param <C> A class containing the changes which will be committed.
- */
-public interface Committer<R, C> {
-    /** Commit the change T, and optionally return a value R */
-    R commit(C change);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/functional/Predicate.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/functional/Predicate.java
deleted file mode 100644
index 5810cbad..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/functional/Predicate.java
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.functional;
-
-/** Predicate support for the Feed. This is a copy of the Java 8 defined Predicate. */
-public interface Predicate<T> {
-    /** Evaluates this predicate on the argument. */
-    boolean test(T t);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/functional/Suppliers.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/functional/Suppliers.java
deleted file mode 100644
index ae1af89f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/functional/Suppliers.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.functional;
-
-import org.chromium.base.supplier.Supplier;
-
-/** Utility methods for working with the {@link Supplier} class. */
-public class Suppliers {
-    /**
-     * Instead of {@link #of(T)} returning a lambda, use this inner class to avoid making new
-     * classes for each lambda.
-     */
-    private static class InstancesSupplier<T> implements Supplier<T> {
-        private final T mInstance;
-
-        InstancesSupplier(T instance) {
-            this.mInstance = instance;
-        }
-
-        @Override
-        public T get() {
-            return mInstance;
-        }
-    }
-
-    /** Return a {@link Supplier} that always returns the provided instance. */
-    public static <T> Supplier<T> of(T instance) {
-        return new InstancesSupplier<>(instance);
-    }
-
-    /** Prevent instantiation */
-    private Suppliers() {}
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/HashPoolInterner.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/HashPoolInterner.java
deleted file mode 100644
index be06ba9a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/HashPoolInterner.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.intern;
-
-import androidx.annotation.Nullable;
-import androidx.collection.SparseArrayCompat;
-
-import java.lang.ref.WeakReference;
-
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * An {@link Interner} implementation using weak references for the values and object hashcodes for
- * the keys. As compared to WeakPoolInterner this interner will only automatically garbage collect
- * values, not the keys. This interner version is suitable for very large protos where running a
- * .equals() is expensive compared with .hashCode().
- */
-@ThreadSafe
-public class HashPoolInterner<T> extends PoolInternerBase<T> {
-    public HashPoolInterner() {
-        super(new HashPool<>());
-    }
-
-    private static final class HashPool<T> implements Pool<T> {
-        private final SparseArrayCompat<WeakReference<T>> mPool = new SparseArrayCompat<>();
-
-        @Override
-        @Nullable
-        public T get(T input) {
-            WeakReference<T> weakRef = (input != null) ? mPool.get(input.hashCode()) : null;
-            return weakRef != null ? weakRef.get() : null;
-        }
-
-        @Override
-        public void put(T input) {
-            if (input != null) {
-                mPool.put(input.hashCode(), new WeakReference<>(input));
-            }
-        }
-
-        @Override
-        public void clear() {
-            mPool.clear();
-        }
-
-        @Override
-        public int size() {
-            return mPool.size();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/InternedMap.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/InternedMap.java
deleted file mode 100644
index 7342dd2..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/InternedMap.java
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.intern;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.common.Validators;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-/** Map wrapper that interns the values on put operations, using the given interner. */
-public class InternedMap<K, V> implements Map<K, V> {
-    private final Map<K, V> mDelegate;
-    private final Interner<V> mInterner;
-
-    public InternedMap(Map<K, V> delegate, Interner<V> interner) {
-        this.mDelegate = Validators.checkNotNull(delegate);
-        this.mInterner = Validators.checkNotNull(interner);
-    }
-
-    @Override
-    public int size() {
-        synchronized (mDelegate) {
-            return mDelegate.size();
-        }
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return mDelegate.isEmpty();
-    }
-
-    @Override
-    public boolean containsKey(@Nullable Object key) {
-        return mDelegate.containsKey(key);
-    }
-
-    @Override
-    public boolean containsValue(@Nullable Object value) {
-        return mDelegate.containsValue(value);
-    }
-
-    @Override
-    @Nullable
-    public V get(@Nullable Object key) {
-        synchronized (mDelegate) {
-            return mDelegate.get(key);
-        }
-    }
-
-    @Override
-    @Nullable
-    public V put(K key, V value) {
-        synchronized (mDelegate) {
-            return mDelegate.put(key, mInterner.intern(value));
-        }
-    }
-
-    @Override
-    @Nullable
-    public V remove(@Nullable Object key) {
-        return mDelegate.remove(key);
-    }
-
-    @Override
-    public void putAll(Map<? extends K, ? extends V> m) {
-        for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
-            K key = e.getKey();
-            V value = e.getValue();
-            put(key, value);
-        }
-    }
-
-    @Override
-    public void clear() {
-        synchronized (mDelegate) {
-            mDelegate.clear();
-            mInterner.clear();
-        }
-    }
-
-    @Override
-    public Set<K> keySet() {
-        return mDelegate.keySet();
-    }
-
-    @Override
-    public Collection<V> values() {
-        return mDelegate.values();
-    }
-
-    @Override
-    public Set<Entry<K, V>> entrySet() {
-        return mDelegate.entrySet();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/Interner.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/Interner.java
deleted file mode 100644
index 11fdda3..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/Interner.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.intern;
-
-/**
- * Similar to {@link String#intern} but for other immutable types. An interner will de-duplicate
- * objects that are identical so only one copy is stored in memory.
- */
-public interface Interner<T> {
-    /**
-     * Returns a canonical representation for the give input object. If there is already an internal
-     * object equal to the input object, then the internal object is returned. Otherwise, the input
-     * object is added internally and a reference to it is returned.
-     */
-    T intern(T input);
-
-    /** Clears the internally store objects. */
-    void clear();
-
-    /** Returns the number of the internally stored objects. */
-    int size();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/InternerWithStats.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/InternerWithStats.java
deleted file mode 100644
index 0db9e30..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/InternerWithStats.java
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.intern;
-
-import org.chromium.chrome.browser.feed.library.common.Validators;
-
-import java.util.Locale;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.annotation.concurrent.ThreadSafe;
-
-/** Wrapper for {@link Interner} that also tracks cache hits/misses. */
-public class InternerWithStats<T> implements Interner<T> {
-    private final Interner<T> mDelegate;
-    private final CacheStats mStats = new CacheStats();
-
-    public InternerWithStats(Interner<T> delegate) {
-        this.mDelegate = Validators.checkNotNull(delegate);
-    }
-
-    @Override
-    public T intern(T arg) {
-        T internedArg = mDelegate.intern(arg);
-        if (internedArg != arg) {
-            mStats.incrementHitCount();
-        } else {
-            mStats.incrementMissCount();
-        }
-        return internedArg;
-    }
-
-    @Override
-    public void clear() {
-        mDelegate.clear();
-        mStats.reset();
-    }
-
-    @Override
-    public int size() {
-        return mDelegate.size();
-    }
-
-    public String getStats() {
-        int hits = mStats.hitCount();
-        int total = hits + mStats.missCount();
-        double ratio = (total == 0) ? 1.0 : (double) hits / total;
-        return String.format(Locale.US, "Cache Hit Ratio: %d/%d (%.2f)", hits, total, ratio);
-    }
-
-    /** Similar to Guava CacheStats but thread safe. */
-    @ThreadSafe
-    private static final class CacheStats {
-        private final AtomicInteger mHitCount = new AtomicInteger();
-        private final AtomicInteger mMissCount = new AtomicInteger();
-
-        private CacheStats() {}
-
-        private void incrementHitCount() {
-            mHitCount.incrementAndGet();
-        }
-
-        private void incrementMissCount() {
-            mMissCount.incrementAndGet();
-        }
-
-        private int hitCount() {
-            return mHitCount.get();
-        }
-
-        private int missCount() {
-            return mMissCount.get();
-        }
-
-        public void reset() {
-            mHitCount.set(0);
-            mMissCount.set(0);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/PoolInternerBase.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/PoolInternerBase.java
deleted file mode 100644
index 3f2fa7e7..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/PoolInternerBase.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.intern;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.common.Validators;
-
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * An {@link Interner} base implementation using a given {@link Pool} to store interned objects.
- * Subclasses need to provide an actual {@link Pool} implementation.
- */
-@ThreadSafe
-public abstract class PoolInternerBase<T> implements Interner<T> {
-    private final Pool<T> mPool;
-
-    PoolInternerBase(Pool<T> pool) {
-        this.mPool = Validators.checkNotNull(pool);
-    }
-
-    @Override
-    public T intern(T input) {
-        synchronized (mPool) {
-            T output = mPool.get(input);
-            if (output != null) {
-                return output;
-            }
-
-            mPool.put(input);
-            return input;
-        }
-    }
-
-    @Override
-    public void clear() {
-        synchronized (mPool) {
-            mPool.clear();
-        }
-    }
-
-    @Override
-    public int size() {
-        synchronized (mPool) {
-            return mPool.size();
-        }
-    }
-
-    /** Interface for a pool used by the PoolInternerBase. */
-    protected interface Pool<T> {
-        /** Retrieves the give object from the pool if it is found, or null otherwise. */
-        @Nullable
-        T get(T input);
-
-        /** Stores the given object into the pool. */
-        void put(T input);
-
-        /** Clears the pool. */
-        void clear();
-
-        /** Returns the size of the pool. */
-        int size();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/ProtoStringInternerBase.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/ProtoStringInternerBase.java
deleted file mode 100644
index 8aead9b1..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/ProtoStringInternerBase.java
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.intern;
-
-import android.annotation.SuppressLint;
-
-import androidx.annotation.Nullable;
-
-import com.google.protobuf.GeneratedMessageLite;
-import com.google.protobuf.MessageLite;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * A string-specific {@link Interner} base implementation that provides common helper methods to
- * help in proto string interning.
- */
-@ThreadSafe
-public abstract class ProtoStringInternerBase<P extends MessageLite> implements Interner<P> {
-    private final Interner<String> mInterner;
-
-    protected ProtoStringInternerBase(Interner<String> interner) {
-        this.mInterner = interner;
-    }
-
-    protected interface SingleStringFieldGetter<T extends GeneratedMessageLite<T, ?>> {
-        String getField(T input);
-    }
-
-    protected interface SingleStringFieldSetter<B extends GeneratedMessageLite.Builder<?, B>> {
-        void setField(B builder, String value);
-    }
-
-    @SuppressWarnings("ReferenceEquality") // Intentional reference comparison for interned != orig
-    @SuppressLint("StringEquality")
-    @Nullable
-    protected <T extends GeneratedMessageLite<T, B>, B extends GeneratedMessageLite.Builder<T, B>> B
-    internSingleStringField(T input, @Nullable B builder,
-            SingleStringFieldGetter<T> singleStringFieldGetter,
-            SingleStringFieldSetter<B> singleStringFieldSetter) {
-        String orig = singleStringFieldGetter.getField(input);
-        String interned = mInterner.intern(orig);
-        if (interned != orig) {
-            builder = ensureBuilder(input, builder);
-            singleStringFieldSetter.setField(builder, interned);
-        }
-        return builder;
-    }
-
-    protected interface RepeatedStringFieldGetter<T extends GeneratedMessageLite<T, ?>> {
-        List<String> getField(T input);
-    }
-
-    protected interface RepeatedStringFieldClearer<B extends GeneratedMessageLite.Builder<?, B>> {
-        void clearField(B builder);
-    }
-
-    protected interface RepeatedStringFieldAllAdder<B extends GeneratedMessageLite.Builder<?, B>> {
-        void addAllField(B builder, List<String> value);
-    }
-
-    @SuppressWarnings("ReferenceEquality") // Intentional reference comparison for interned != orig
-    @SuppressLint("StringEquality")
-    @Nullable
-    protected <T extends GeneratedMessageLite<T, B>, B extends GeneratedMessageLite.Builder<T, B>> B
-    internRepeatedStringField(T input, @Nullable B builder,
-            RepeatedStringFieldGetter<T> repeatedStringFieldGetter,
-            RepeatedStringFieldClearer<B> repeatedStringFieldClearer,
-            RepeatedStringFieldAllAdder<B> repeatedStringFieldAllAdder) {
-        boolean modified = false;
-        List<String> internedValues = new ArrayList<>();
-        for (String orig : repeatedStringFieldGetter.getField(input)) {
-            String interned = mInterner.intern(orig);
-            internedValues.add(interned);
-            if (interned != orig) {
-                modified = true;
-            }
-        }
-        if (modified) {
-            builder = ensureBuilder(input, builder);
-            repeatedStringFieldClearer.clearField(builder);
-            repeatedStringFieldAllAdder.addAllField(builder, internedValues);
-        }
-        return builder;
-    }
-
-    protected <T extends GeneratedMessageLite<T, B>, B extends GeneratedMessageLite.Builder<T, B>> B
-    ensureBuilder(T input, @Nullable B builder) {
-        if (builder == null) {
-            builder = input.toBuilder();
-        }
-        return builder;
-    }
-
-    @Override
-    public void clear() {
-        mInterner.clear();
-    }
-
-    @Override
-    public int size() {
-        return mInterner.size();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/WeakPoolInterner.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/WeakPoolInterner.java
deleted file mode 100644
index 184bf7df..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/WeakPoolInterner.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.intern;
-
-import androidx.annotation.Nullable;
-
-import java.lang.ref.WeakReference;
-import java.util.WeakHashMap;
-
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * An {@link Interner} implementation using a WeakHashMap pool. Objects from the pool are
- * automatically garbage collected when there are no more references to them. Objects in the pool
- * are keyed by their own implementation so this interner is suitable for strings or relatively
- * small protos where the .equals() operation is not too expensive (see {@link WeakPoolInterner} for
- * an alternative implementation for that case).
- */
-@ThreadSafe
-public class WeakPoolInterner<T> extends PoolInternerBase<T> {
-    public WeakPoolInterner() {
-        super(new WeakPool<T>());
-    }
-
-    private static final class WeakPool<T> implements Pool<T> {
-        private final WeakHashMap<T, WeakReference<T>> mPool = new WeakHashMap<>();
-
-        @Override
-        @Nullable
-        public T get(T input) {
-            WeakReference<T> weakRef = mPool.get(input);
-            return weakRef != null ? weakRef.get() : null;
-        }
-
-        @Override
-        public void put(T input) {
-            mPool.put(input, new WeakReference<>(input));
-        }
-
-        @Override
-        public void clear() {
-            mPool.clear();
-        }
-
-        @Override
-        public int size() {
-            return mPool.size();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/locale/LocaleUtils.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/locale/LocaleUtils.java
deleted file mode 100644
index ec33406d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/locale/LocaleUtils.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.locale;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-
-import java.util.Locale;
-
-/** Utility methods for retrieving information about device language. */
-public final class LocaleUtils {
-    private LocaleUtils() {}
-
-    /** Returns the top user specified locale. */
-    // TODO: Look into allowing multiple languages to be returned.
-    @TargetApi(Build.VERSION_CODES.N)
-    public static Locale getLocale(Context context) {
-        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
-                ? context.getResources().getConfiguration().getLocales().get(0)
-                : context.getResources().getConfiguration().locale;
-    }
-
-    /** Returns a string which represents the top locale and region of the device. */
-    public static String getLanguageTag(Context context) {
-        return getLocale(context).toLanguageTag();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/Dumpable.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/Dumpable.java
deleted file mode 100644
index 3a38375..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/Dumpable.java
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.logging;
-
-/** Interface for objects that know how to dump details of their state to a {@link Dumper}. */
-public interface Dumpable {
-    /** Called to dump an object into a {@link Dumper}. */
-    void dump(Dumper dumper);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/Dumper.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/Dumper.java
deleted file mode 100644
index cb3bc725..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/Dumper.java
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.logging;
-
-import android.text.TextUtils;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import java.io.IOException;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Simple Dumper modelled after the AGSA Dumper. This will dump a tree of objects which implement
- * the {@link Dumpable} interface.
- */
-public final class Dumper {
-    private static final String TAG = "Dumper";
-    private static final String SINGLE_INDENT = "  ";
-
-    private final int mIndentLevel;
-
-    // Walk up the chain of parents to
-    // ensure none are currently dumping a given dumpable, to prevent cycles. The WeakReference
-    // itself is always non-null, but the Dumpable may be null.
-    private final WeakReference<Dumpable> mCurrentDumpable;
-    @Nullable
-    private final Dumper mParent;
-    private final boolean mRedacted;
-
-    // The root Dumper will create the values used by all children Dumper instances.  This flattens
-    // the output into one list.
-    @VisibleForTesting
-    final List<DumperValue> mValues;
-
-    /** Returns the default Dumper, this will show sensitive content. */
-    public static Dumper newDefaultDumper() {
-        return new Dumper(1, null, new WeakReference<>(null), new ArrayList<>(), false);
-    }
-
-    /** Returns a Dumper which will redact sensitive content. */
-    public static Dumper newRedactedDumper() {
-        return new Dumper(1, null, new WeakReference<>(null), new ArrayList<>(), true);
-    }
-
-    // Private constructor, these are created through the static newDefaultDumper} method.
-    private Dumper(int indentLevel, @Nullable Dumper parent,
-            WeakReference<Dumpable> currentDumpable, List<DumperValue> values, boolean redacted) {
-        this.mIndentLevel = indentLevel;
-        this.mParent = parent;
-        this.mCurrentDumpable = currentDumpable;
-        this.mValues = values;
-        this.mRedacted = redacted;
-    }
-
-    private boolean isDescendentOf(Dumpable dumpable) {
-        return (mCurrentDumpable.get() == dumpable)
-                || (mParent != null && mParent.isDescendentOf(dumpable));
-    }
-
-    /** Creates a new Dumper with a indent level one greater than the current indent level. */
-    public Dumper getChildDumper() {
-        return getChildDumper(null);
-    }
-
-    private Dumper getChildDumper(@Nullable Dumpable dumpable) {
-        return new Dumper(
-                mIndentLevel + 1, this, new WeakReference<>(dumpable), mValues, mRedacted);
-    }
-
-    /** Set the title of the section. This is output at the previous indent level. */
-    public void title(String title) {
-        mValues.add(new DumperValue(mIndentLevel - 1, title));
-    }
-
-    /** Adds a String as an indented line to the dump */
-    public void format(String format, Object... args) {
-        addLine("", String.format(Locale.US, format, args));
-    }
-
-    /** Create a Dumper value with the specified name. */
-    public DumperValue forKey(String name) {
-        return addLine(mIndentLevel, name);
-    }
-
-    /** Allow the indent level to be adjusted. */
-    public DumperValue forKey(String name, int indentAdjustment) {
-        return addLine(mIndentLevel + indentAdjustment, name);
-    }
-
-    /** Dump a Dumpable as a child of the current Dumper */
-    public void dump(@Nullable Dumpable dumpable) {
-        if (dumpable == null) {
-            return;
-        }
-        if (isDescendentOf(dumpable)) {
-            format("[cycle detected]");
-            return;
-        }
-        Dumper child = getChildDumper(dumpable);
-        try {
-            dumpable.dump(child);
-        } catch (Exception e) {
-            Logger.e(TAG, e, "Dump Failed");
-        }
-    }
-
-    /** Write the Dumpable to an {@link Appendable}. */
-    public void write(Appendable writer) throws IOException {
-        boolean newLine = true;
-        for (DumperValue value : mValues) {
-            String stringValue = value.toString(mRedacted);
-            if (!newLine) {
-                if (value.mCompactPrevious) {
-                    writer.append(" | ");
-                } else {
-                    String indent = getIndent(value.mIndentLevel);
-                    writer.append("\n").append(indent);
-                }
-            }
-            writer.append(stringValue);
-            newLine = false;
-        }
-        writer.append("\n");
-    }
-
-    private DumperValue addLine(int indentLevel, String title) {
-        DumperValue dumperValue = new DumperValue(indentLevel, title);
-        mValues.add(dumperValue);
-        return dumperValue;
-    }
-
-    private DumperValue addLine(String name, String value) {
-        return forKey(name).value(value);
-    }
-
-    /**
-     * Class which represents a name value pair within the dump. It is used for both titles and for
-     * the name value pair content within the dump. The indent level is used to specify the indent
-     * level for content appearing on a new line. Multiple DumperValues may be compacted into a
-     * single line in the output.
-     */
-    public static final class DumperValue {
-        @VisibleForTesting
-        static final String REDACTED = "[REDACTED]";
-        @VisibleForTesting
-        final String mName;
-        @VisibleForTesting
-        final StringBuilder mContent;
-        @VisibleForTesting
-        final int mIndentLevel;
-        private boolean mCompactPrevious;
-        private boolean mSensitive;
-
-        // create a DumpValue with just a name, this is not public, it will is called by Dumper
-        DumperValue(int indentLevel, String name) {
-            this.mIndentLevel = indentLevel;
-            this.mName = name;
-            this.mContent = new StringBuilder();
-        }
-
-        /** Append an int to the current content of this value */
-        public DumperValue value(int value) {
-            this.mContent.append(value);
-            return this;
-        }
-
-        /** Append an String to the current content of this value */
-        public DumperValue value(String value) {
-            this.mContent.append(value);
-            return this;
-        }
-
-        /** Append an boolean to the current content of this value */
-        public DumperValue value(boolean value) {
-            this.mContent.append(value);
-            return this;
-        }
-
-        /** Add a Date value. It will be formatted as Logcat Dates are formatted */
-        public DumperValue value(Date value) {
-            this.mContent.append(StringFormattingUtils.formatLogDate(value));
-            return this;
-        }
-
-        /** Add a value specified as an object. */
-        public DumperValue valueObject(Object value) {
-            if (value instanceof Integer) {
-                return value((Integer) value);
-            }
-            if (value instanceof Boolean) {
-                return value((Boolean) value);
-            }
-            return value(value.toString());
-        }
-
-        /**
-         * When output, this DumperValue will be compacted to the same output line as the previous
-         * value.
-         */
-        public DumperValue compactPrevious() {
-            mCompactPrevious = true;
-            return this;
-        }
-
-        /** Mark the Value as containing sensitive data */
-        public DumperValue sensitive() {
-            mSensitive = true;
-            return this;
-        }
-
-        /**
-         * Output the value as a Name/Value pair. This will convert sensitive data to "REDACTED" if
-         * we are not dumping sensitive data.
-         */
-        String toString(boolean suppressSensitive) {
-            String value = "";
-            if (!TextUtils.isEmpty(mContent)) {
-                value = (suppressSensitive && mSensitive) ? REDACTED : mContent.toString();
-            }
-            if (!TextUtils.isEmpty(mName) && !TextUtils.isEmpty(value)) {
-                return mName + ": " + value;
-            } else if (!TextUtils.isEmpty(mName)) {
-                return mName + ":";
-            } else if (!TextUtils.isEmpty(value)) {
-                return value;
-            } else {
-                return "";
-            }
-        }
-    }
-
-    private static final String[] INDENTATIONS = new String[] {
-            "",
-            createIndent(1),
-            createIndent(2),
-            createIndent(3),
-            createIndent(4),
-            createIndent(5),
-    };
-
-    private static String createIndent(int size) {
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < size; i++) {
-            sb.append(SINGLE_INDENT);
-        }
-        return sb.toString();
-    }
-
-    private static String getIndent(int indentLevel) {
-        if (indentLevel < 0) {
-            return INDENTATIONS[0];
-        } else if (indentLevel < INDENTATIONS.length) {
-            return INDENTATIONS[indentLevel];
-        } else {
-            return createIndent(indentLevel);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/Logger.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/Logger.java
deleted file mode 100644
index 2ff77e4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/Logger.java
+++ /dev/null
@@ -1,776 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.logging;
-
-import static android.util.Log.ASSERT;
-import static android.util.Log.DEBUG;
-import static android.util.Log.ERROR;
-import static android.util.Log.INFO;
-import static android.util.Log.VERBOSE;
-import static android.util.Log.WARN;
-
-import android.os.Build;
-import android.util.Base64;
-import android.util.Log;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.base.annotations.RemovableInRelease;
-
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-import java.util.IllegalFormatException;
-import java.util.Locale;
-
-/**
- * Helper class for logging in GSA. This class only logs if the tag for the log request is loggable.
- * For debug and verbose logs, it also looks at the {@link #isEnabled} flag to determine whether to
- * log or not.
- *
- * <p>Usage:
- *
- * <ul>
- *   <li>Use {@code adb shell setprop log.tag.TAG DEBUG} to enable debug logs from <i>TAG</i>.
- *   <li>Use {@code adb shell setprop log.tag.TAG VERBOSE} to enable verbose logs from <i>TAG</i>.
- *   <li>Use {@code adb shell setprop log.tag.TAG SUPPRESS} to disable all logs from <i>TAG</i>.
- * </ul>
- *
- * <p>To log a formatter string, use the syntax specified for {@link java.util.Formatter} or see
- * {@link String#format(String, Object...)}. For example:
- *
- * <pre>{@code
- * L.d(TAG, "%s did something to %s resulting in %s", A, B, C);
- * }</pre>
- *
- * <p>Note: All {@code toString()} operations are evaluated lazily and only when necessary, so it's
- * recommended to pass in objects rather than pre-formatted string representations (e.g. using
- * {@link Object#toString} or {@link String#format}).
- *
- * <p>Note that arrays are automatically represented using {@link Arrays#deepToString} instead of
- * {@link Object#toString} for better readability.
- *
- * <p>TODO: We need to verify the Proguard behaviors
- *
- * <p>TODO: Implementation of Redactable is removed, do we need to support this?
- *
- * <p>TODO: Should we remove the crashing behavior?
- *
- * <p>Note: in release builds Proguard should remove all calls to
- * L#{d,v,dWithStackTrace,vWithStackTrace}. See proguard_release.flags and
- * [INTERNAL LINK]
- *
- * <p>WARNING: Do not add vararg overloaded versions of L#{d,v,dWithStackTrace,vWithStackTrace}.
- * Proguard cannot properly shrink vararg statements.
- */
-public final class Logger {
-    private static final String STRING_MEANING_NULL = "null";
-    private static final String NOT_AN_EXCEPTION = "DEBUG: Not an Exception";
-
-    // private-constructor
-    private Logger() {}
-
-    /**
-     * Log a verbose message.
-     *
-     * <p>NOTE: All calls to this method must be wrapped inside if(L.isDebugEnabled(TAG)) {}.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string message to log.
-     */
-    @RemovableInRelease
-    public static void v(String tag, String message) {
-        internalLog(VERBOSE, tag, null, message, false);
-    }
-
-    /**
-     * Log a verbose message.
-     *
-     * <p>NOTE: All calls to this method must be wrapped inside if(L.isDebugEnabled(TAG)) {}.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string format recognized by {@link String#format(String, Object...)}.
-     * @param arg1 the formatting arg for the previous string.
-     */
-    @RemovableInRelease
-    public static void v(String tag, String message, @Nullable Object arg1) {
-        internalLog(VERBOSE, tag, null, message, false, arg1);
-    }
-
-    /** @see #v(String, String, Object) */
-    @RemovableInRelease
-    public static void v(String tag, String message, @Nullable Object arg1, @Nullable Object arg2) {
-        internalLog(VERBOSE, tag, null, message, false, arg1, arg2);
-    }
-
-    /** @see #v(String, String, Object) */
-    @RemovableInRelease
-    public static void v(String tag, String message, @Nullable Object arg1, @Nullable Object arg2,
-            @Nullable Object arg3) {
-        internalLog(VERBOSE, tag, null, message, false, arg1, arg2, arg3);
-    }
-
-    /** @see #v(String, String, Object) */
-    @RemovableInRelease
-    public static void v(String tag, String message, @Nullable Object arg1, @Nullable Object arg2,
-            @Nullable Object arg3, @Nullable Object arg4) {
-        internalLog(VERBOSE, tag, null, message, false, arg1, arg2, arg3, arg4);
-    }
-
-    /** @see #v(String, String, Object) */
-    @RemovableInRelease
-    public static void v(String tag, String message, @Nullable Object arg1, @Nullable Object arg2,
-            @Nullable Object arg3, @Nullable Object arg4, @Nullable Object arg5) {
-        internalLog(VERBOSE, tag, null, message, false, arg1, arg2, arg3, arg4, arg5);
-    }
-
-    /**
-     * Log a verbose message and include the current stack trace in the log.
-     *
-     * <p>NOTE: All calls to this method must be wrapped inside if(L.isDebugEnabled(TAG)) {}.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string message to log.
-     */
-    @RemovableInRelease
-    public static void vWithStackTrace(String tag, String message) {
-        internalLog(VERBOSE, tag, null, message, true);
-    }
-
-    /**
-     * Log a verbose message and include the current stack trace in the log.
-     *
-     * <p>NOTE: All calls to this method must be wrapped inside if(L.isDebugEnabled(TAG)) {}.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string format recognized by {@link String#format(String, Object...)}.
-     * @param arg1 the formatting arg for the previous string.
-     */
-    @RemovableInRelease
-    public static void vWithStackTrace(String tag, String message, @Nullable Object arg1) {
-        internalLog(VERBOSE, tag, null, message, true, arg1);
-    }
-
-    /** @see #vWithStackTrace(String, String, Object) */
-    @RemovableInRelease
-    public static void vWithStackTrace(
-            String tag, String message, @Nullable Object arg1, @Nullable Object arg2) {
-        internalLog(VERBOSE, tag, null, message, true, arg1, arg2);
-    }
-
-    /** @see #vWithStackTrace(String, String, Object) */
-    @RemovableInRelease
-    public static void vWithStackTrace(String tag, String message, @Nullable Object arg1,
-            @Nullable Object arg2, @Nullable Object arg3) {
-        internalLog(VERBOSE, tag, null, message, true, arg1, arg2, arg3);
-    }
-
-    /** @see #vWithStackTrace(String, String, Object) */
-    @RemovableInRelease
-    public static void vWithStackTrace(String tag, String message, @Nullable Object arg1,
-            @Nullable Object arg2, @Nullable Object arg3, @Nullable Object arg4) {
-        internalLog(VERBOSE, tag, null, message, true, arg1, arg2, arg3, arg4);
-    }
-
-    /** @see #vWithStackTrace(String, String, Object) */
-    @RemovableInRelease
-    public static void vWithStackTrace(String tag, String message, @Nullable Object arg1,
-            @Nullable Object arg2, @Nullable Object arg3, @Nullable Object arg4,
-            @Nullable Object arg5) {
-        internalLog(VERBOSE, tag, null, message, true, arg1, arg2, arg3, arg4, arg5);
-    }
-
-    /**
-     * Log a debug message.
-     *
-     * <p>NOTE: All calls to this method must be wrapped inside if(L.isDebugEnabled(TAG)) {}.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string message to log.
-     */
-    @RemovableInRelease
-    public static void d(String tag, String message) {
-        internalLog(DEBUG, tag, null, message, false);
-    }
-
-    /**
-     * Log a debug message.
-     *
-     * <p>NOTE: All calls to this method must be wrapped inside if(L.isDebugEnabled(TAG)) {}.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string format recognized by {@link String#format(String, Object...)}.
-     * @param arg1 the formatting arg for the previous string.
-     */
-    @RemovableInRelease
-    public static void d(String tag, String message, @Nullable Object arg1) {
-        internalLog(DEBUG, tag, null, message, false, arg1);
-    }
-
-    /** @see #d(String, String, Object) */
-    @RemovableInRelease
-    public static void d(String tag, String message, @Nullable Object arg1, @Nullable Object arg2) {
-        internalLog(DEBUG, tag, null, message, false, arg1, arg2);
-    }
-
-    /** @see #d(String, String, Object) */
-    @RemovableInRelease
-    public static void d(String tag, String message, @Nullable Object arg1, @Nullable Object arg2,
-            @Nullable Object arg3) {
-        internalLog(DEBUG, tag, null, message, false, arg1, arg2, arg3);
-    }
-
-    /** @see #d(String, String, Object) */
-    @RemovableInRelease
-    public static void d(String tag, String message, @Nullable Object arg1, @Nullable Object arg2,
-            @Nullable Object arg3, @Nullable Object arg4) {
-        internalLog(DEBUG, tag, null, message, false, arg1, arg2, arg3, arg4);
-    }
-
-    /** @see #d(String, String, Object) */
-    @RemovableInRelease
-    public static void d(String tag, String message, @Nullable Object arg1, @Nullable Object arg2,
-            @Nullable Object arg3, @Nullable Object arg4, @Nullable Object arg5) {
-        internalLog(DEBUG, tag, null, message, false, arg1, arg2, arg3, arg4, arg5);
-    }
-
-    /** @see #d(String, String, Object) */
-    @RemovableInRelease
-    public static void d(String tag, String message, @Nullable Object arg1, @Nullable Object arg2,
-            @Nullable Object arg3, @Nullable Object arg4, @Nullable Object arg5,
-            @Nullable Object arg6) {
-        internalLog(DEBUG, tag, null, message, false, arg1, arg2, arg3, arg4, arg5, arg6);
-    }
-
-    /** @see #d(String, String, Object) */
-    @RemovableInRelease
-    public static void d(String tag, String message, @Nullable Object arg1, @Nullable Object arg2,
-            @Nullable Object arg3, @Nullable Object arg4, @Nullable Object arg5,
-            @Nullable Object arg6, @Nullable Object arg7) {
-        internalLog(DEBUG, tag, null, message, false, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
-    }
-
-    /** @see #d(String, String, Object) */
-    @RemovableInRelease
-    public static void d(String tag, String message, @Nullable Object arg1, @Nullable Object arg2,
-            @Nullable Object arg3, @Nullable Object arg4, @Nullable Object arg5,
-            @Nullable Object arg6, @Nullable Object arg7, @Nullable Object arg8) {
-        internalLog(
-                DEBUG, tag, null, message, false, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
-    }
-
-    /** @see #d(String, String, Object) */
-    @RemovableInRelease
-    public static void d(String tag, String message, @Nullable Object arg1, @Nullable Object arg2,
-            @Nullable Object arg3, @Nullable Object arg4, @Nullable Object arg5,
-            @Nullable Object arg6, @Nullable Object arg7, @Nullable Object arg8,
-            @Nullable Object arg9) {
-        internalLog(DEBUG, tag, null, message, false, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
-                arg8, arg9);
-    }
-
-    /** @see #d(String, String, Object) */
-    @RemovableInRelease
-    public static void d(String tag, String message, @Nullable Object arg1, @Nullable Object arg2,
-            @Nullable Object arg3, @Nullable Object arg4, @Nullable Object arg5,
-            @Nullable Object arg6, @Nullable Object arg7, @Nullable Object arg8,
-            @Nullable Object arg9, @Nullable Object arg10) {
-        internalLog(DEBUG, tag, null, message, false, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
-                arg8, arg9, arg10);
-    }
-
-    /**
-     * Log a debug message that includes the current stack trace in the log.
-     *
-     * <p>NOTE: All calls to this method must be wrapped inside if(L.isDebugEnabled(TAG)) {}.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string message to log.
-     */
-    @RemovableInRelease
-    public static void dWithStackTrace(String tag, String message) {
-        internalLog(DEBUG, tag, null, message, true);
-    }
-
-    /**
-     * Log a debug message that includes the current stack trace in the log.
-     *
-     * <p>NOTE: All calls to this method must be wrapped inside if(L.isDebugEnabled(TAG)) {}.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string format recognized by {@link String#format(String, Object...)}.
-     * @param arg1 the formatting arg for the previous string.
-     */
-    @RemovableInRelease
-    public static void dWithStackTrace(String tag, String message, @Nullable Object arg1) {
-        internalLog(DEBUG, tag, null, message, true, arg1);
-    }
-
-    /** @see #dWithStackTrace(String, String, Object) */
-    @RemovableInRelease
-    public static void dWithStackTrace(
-            String tag, String message, @Nullable Object arg1, @Nullable Object arg2) {
-        internalLog(DEBUG, tag, null, message, true, arg1, arg2);
-    }
-
-    /** @see #dWithStackTrace(String, String, Object) */
-    @RemovableInRelease
-    public static void dWithStackTrace(String tag, String message, @Nullable Object arg1,
-            @Nullable Object arg2, @Nullable Object arg3) {
-        internalLog(DEBUG, tag, null, message, true, arg1, arg2, arg3);
-    }
-
-    /** @see #dWithStackTrace(String, String, Object) */
-    @RemovableInRelease
-    public static void dWithStackTrace(String tag, String message, @Nullable Object arg1,
-            @Nullable Object arg2, @Nullable Object arg3, @Nullable Object arg4) {
-        internalLog(DEBUG, tag, null, message, true, arg1, arg2, arg3, arg4);
-    }
-
-    /** @see #dWithStackTrace(String, String, Object) */
-    @RemovableInRelease
-    public static void dWithStackTrace(String tag, String message, @Nullable Object arg1,
-            @Nullable Object arg2, @Nullable Object arg3, @Nullable Object arg4,
-            @Nullable Object arg5) {
-        internalLog(DEBUG, tag, null, message, true, arg1, arg2, arg3, arg4, arg5);
-    }
-
-    /**
-     * Log an info message.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string message to log. This can also be a string format that's recognized
-     *         by
-     *     {@link String#format(String, Object...)}. e.g. "%s did something to %s, and %d happened
-     * as a result".
-     * @param args the formatting args for the previous string.
-     */
-    public static void i(String tag, @Nullable String message, @Nullable Object... args) {
-        internalLog(INFO, tag, null, message, false, args);
-    }
-
-    /**
-     * Log an info message that includes the current stack trace in the log.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string message to log. This can also be a string format that's recognized
-     *         by
-     *     {@link String#format(String, Object...)}. e.g. "%s did something to %s, and %d happened
-     * as a result".
-     * @param args the formatting args for the previous string.
-     */
-    public static void iWithStackTrace(String tag, String message, @Nullable Object... args) {
-        internalLog(INFO, tag, null, message, true, args);
-    }
-
-    /**
-     * Log a warning message.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string message to log. This can also be a string format that's recognized
-     *         by
-     *     {@link String#format(String, Object...)}. e.g. "%s did something to %s, and %d happened
-     * as a result".
-     * @param args the formatting args for the previous string.
-     */
-    public static void w(String tag, @Nullable String message, @Nullable Object... args) {
-        internalLog(WARN, tag, null, message, false, args);
-    }
-
-    /**
-     * Log a warning message.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param th a throwable to log.
-     * @param message the string message to log. This can also be a string format that's recognized
-     *         by
-     *     {@link String#format(String, Object...)}. e.g. "%s did something to %s, and %d happened
-     * as a result".
-     * @param args the formatting args for the previous string.
-     */
-    public static void w(
-            String tag, Throwable th, @Nullable String message, @Nullable Object... args) {
-        internalLog(WARN, tag, th, message, false, args);
-    }
-
-    /**
-     * Log a warning message that includes the current stack trace in the log.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string message to log. This can also be a string format that's recognized
-     *         by
-     *     {@link String#format(String, Object...)}. e.g. "%s did something to %s, and %d happened
-     * as a result".
-     * @param args the formatting args for the previous string.
-     */
-    public static void wWithStackTrace(
-            String tag, @Nullable String message, @Nullable Object... args) {
-        internalLog(WARN, tag, null, message, true, args);
-    }
-
-    /**
-     * Log an error message.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string message to log. This can also be a string format that's recognized
-     *         by
-     *     {@link String#format(String, Object...)}. e.g. "%s did something to %s, and %d happened
-     * as a result".
-     * @param args the formatting args for the previous string.
-     */
-    public static void e(String tag, @Nullable String message, @Nullable Object... args) {
-        internalLog(ERROR, tag, null, message, false, args);
-    }
-
-    /**
-     * Log an error message.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param th a throwable to log.
-     * @param message the string message to log. This can also be a string format that's recognized
-     *         by
-     *     {@link String#format(String, Object...)}. e.g. "%s did something to %s, and %d happened
-     * as a result".
-     * @param args the formatting args for the previous string.
-     */
-    public static void e(
-            String tag, Throwable th, @Nullable String message, @Nullable Object... args) {
-        internalLog(ERROR, tag, th, message, false, args);
-    }
-
-    /**
-     * Log an error message that includes the current stack trace in the log.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string message to log. This can also be a string format that's recognized
-     *         by
-     *     {@link String#format(String, Object...)}. e.g. "%s did something to %s, and %d happened
-     * as a result".
-     * @param args the formatting args for the previous string.
-     */
-    public static void eWithStackTrace(
-            String tag, @Nullable String message, @Nullable Object... args) {
-        internalLog(ERROR, tag, null, message, true, args);
-    }
-
-    /**
-     * What a terrible failure! ASSERT level log. On non-prod(dogfood/dev) builds, this crashes the
-     * app. On prod builds, this logs at WARN level.
-     *
-     * <p>This is for failures that need to be caught during development/dogfood, but which
-     * shouldn't crash the app in production.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param message the string message to log. This can also be a string format that's recognized
-     *         by
-     *     {@link String#format(String, Object...)}. e.g. "%s did something to %s, and %d happened
-     * as a result".
-     * @param args the formatting args for the previous string.
-     */
-    public static void wtf(String tag, @Nullable String message, @Nullable Object... args) {
-        internalLog(WARN, tag, null, message, false, args);
-        if (shouldWtfCrash()) {
-            throw new RuntimeException(buildMessage(message, args));
-        }
-    }
-
-    /**
-     * What a terrible failure! ASSERT level log. On non-prod(dogfood/dev) builds, this crashes the
-     * app. On prod builds, this logs at WARN level.
-     *
-     * <p>This is for failures that need to be caught during development/dogfood, but which
-     * shouldn't crash the app in production.
-     *
-     * @param tag the tag shouldn't be more than 23 characters as {@link Log#isLoggable(String,
-     *         int)}
-     *     has this restriction.
-     * @param th a throwable to log.
-     * @param message the string message to log. This can also be a string format that's recognized
-     *         by
-     *     {@link String#format(String, Object...)}. e.g. "%s did something to %s, and %d happened
-     * as a result".
-     * @param args the formatting args for the previous string.
-     */
-    public static void wtf(
-            String tag, Throwable th, @Nullable String message, @Nullable Object... args) {
-        internalLog(WARN, tag, th, message, false, args);
-        if (shouldWtfCrash()) {
-            throw new RuntimeException(buildMessage(message, args), th);
-        }
-    }
-
-    // TODO: this should be consistent across build types
-    @RemovableInRelease
-    private static boolean shouldWtfCrash() {
-        // L.wtf should crash for DEV and ALPHA builds.
-        // Since Proguard is definitely being run for RELEASE builds, the method returns true by
-        // default, but Proguard will assume it returns false for RELEASE build.
-        return true;
-    }
-
-    /**
-     * Tests if verbose logging is enabled for a given tag. It's used to guard some potentially
-     * expensive logging code.
-     *
-     * @param tag The tag that we want to test
-     * @return true if this tag is enabled for verbose logging, false otherwise
-     */
-    @RemovableInRelease
-    public static boolean isVerboseEnabled(String tag) {
-        return isEnabled(tag, VERBOSE);
-    }
-
-    /**
-     * Tests if debug logging is enabled for a given tag. It's used to guard some potentially
-     * expensive logging code.
-     *
-     * @param tag The tag that we want to test
-     * @return true if this tag is enabled for debug logging, false otherwise
-     */
-    @RemovableInRelease
-    public static boolean isDebugEnabled(String tag) {
-        return isEnabled(tag, DEBUG);
-    }
-
-    private static String capTag(String tag) {
-        String cappedTag;
-        if (tag.length() > 23) {
-            cappedTag = tag.substring(0, 23);
-            internalLog(WARN, cappedTag, null, "Tag [%s] is too long; truncated to [%s]", false,
-                    tag, cappedTag);
-            return cappedTag;
-        }
-        return tag;
-    }
-
-    public static boolean isEnabled(String tag, int level) {
-        String cappedTag = capTag(tag);
-
-        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
-            // Android M has a bug which makes isLoggable() inconsistent. Only suppress debug and
-            // verbose level logging, to ensure that log messages of other levels are never
-            // suppressed. Note that this effectively disables suppression of the log tag. See:
-            // [INTERNAL LINK]
-            return ((level != DEBUG && level != VERBOSE) || Log.isLoggable(cappedTag, level));
-        } else {
-            return Log.isLoggable(cappedTag, level);
-        }
-    }
-
-    public static void log(
-            int level, String tag, @Nullable String message, @Nullable Object... args) {
-        internalLog(level, tag, null, message, false, args);
-    }
-
-    public static void log(int level, String tag, @Nullable Throwable th, @Nullable String message,
-            @Nullable Object... args) {
-        internalLog(level, tag, th, message, false, args);
-    }
-
-    // if (sensitive), all args must be instances of Redactable
-    // uses array rather than varargs to avoid ambiguous conversion of @Nullable Redactable...
-    private static void internalLog(int level, String tag, @Nullable Throwable th,
-            @Nullable String message, boolean withStackTrace, @Nullable Object... args) {
-        tag = capTag(tag);
-
-        // Return early if we should not be logging this tag at the given level.
-        if (!isEnabled(tag, level)) {
-            return;
-        }
-
-        String formattedMessage = buildMessage(message, args);
-        if (th == null && withStackTrace) {
-            String throwableMessage;
-            if (message == null) {
-                throwableMessage = NOT_AN_EXCEPTION;
-            } else {
-                throwableMessage = formattedMessage;
-            }
-            th = new DebugStackTraceLogger(tag + ": " + throwableMessage);
-        }
-        // TODO: Remove self from the stack trace.
-        switch (level) {
-            case VERBOSE:
-                if (th != null) {
-                    Log.v(tag, formattedMessage, th);
-                } else {
-                    Log.v(tag, formattedMessage);
-                }
-                break;
-            case DEBUG:
-                if (th != null) {
-                    Log.d(tag, formattedMessage, th);
-                } else {
-                    Log.d(tag, formattedMessage);
-                }
-                break;
-            case INFO:
-                if (th != null) {
-                    Log.i(tag, formattedMessage, th);
-                } else {
-                    Log.i(tag, formattedMessage);
-                }
-                break;
-            case WARN:
-                if (th != null) {
-                    Log.w(tag, formattedMessage, th);
-                } else {
-                    Log.w(tag, formattedMessage);
-                }
-                break;
-            case ERROR:
-                if (th != null) {
-                    Log.e(tag, formattedMessage, th);
-                } else {
-                    Log.e(tag, formattedMessage);
-                }
-                break;
-            case ASSERT:
-                if (th != null) {
-                    Log.wtf(tag, formattedMessage, th);
-                } else {
-                    Log.wtf(tag, formattedMessage);
-                }
-                break;
-            default:
-                // If we hit this it's a code error in this class, handling as verbose
-                if (th != null) {
-                    Log.v(tag, formattedMessage, th);
-                } else {
-                    Log.v(tag, formattedMessage);
-                }
-        }
-    }
-
-    static String buildMessage(@Nullable String message, @Nullable Object[] args) {
-        // If the message is null, ignore the args and return "null";
-        if (message == null) {
-            return STRING_MEANING_NULL;
-        }
-
-        // else if the args are null or 0-length, return message
-        if (args == null || args.length == 0) {
-            return message;
-        }
-
-        // Use deepToString to get a more useful representation of any arrays in args
-        for (int i = 0; i < args.length; i++) {
-            if (args[i] != null && args[i].getClass().isArray()) {
-                // Wrap in an array, deepToString, then remove the extra [] from the wrapper. This
-                // allows handling all array types rather than having separate branches for all
-                // primitive array types plus Object[].
-                String string = Arrays.deepToString(new Object[] {args[i]});
-                // Strip the outer [] from the wrapper array.
-                args[i] = string.substring(1, string.length() - 1);
-            }
-        }
-
-        // else try formatting the string.
-        try {
-            return String.format(Locale.US, message, args);
-        } catch (IllegalFormatException ex) {
-            return message + Arrays.toString(args);
-        }
-    }
-
-    /**
-     * Print the raw protobuffer with the indicated data using the TAG and the fake html tags marked
-     * by &lt;name&gt; and &lt;end-name&gt;
-     *
-     * <p>A utility called parse-request-response.sh can then be used to pick up the log lines,
-     * extract lines called request and response and write them out to a developer's workstation.
-     *
-     * <p>This should only be done during development or during a limited Alpha. Protocol buffers
-     * are large. The ring-buffer in logcat is small, and a shared resource with other apps. Your
-     * misuse of logging Protocol buffers limits the utility of logcat to other teams like Maps,
-     * Youtube, Play Store. Please do not enable logging of large protocol buffers in production,
-     * and please do not remove the IS_DEV_BUILD check.
-     *
-     * <p>If you find yourself requiring protocol buffers, a much more sensible solution is to write
-     * them to disk in /sdcard/, and allow developers to pull this out of dogfood devices. This
-     * avoids spamming the log ringbuffer, and also persists beyond a reboot.
-     */
-    @RemovableInRelease
-    public static void debugLogRawProto(String tag, byte[] rawProto, String name) {
-        // Create a string representation of the raw data.
-        String request;
-        try {
-            // A lot is happening in this line.  We are encoding the raw data into Base64: we
-            // skip wrapping because the default wrapping is at 76 chars which leads to too many
-            // calls into Log.i.  Instead, we chunk up later in logLongString(...) where we
-            // break at 2000 chars.  Also, the encoded bytes are then encoded into UTF-8 by the
-            // String class which maintains the encoding since the entire charset of Base64
-            // encoding fits without modification in utf-8.
-            request = new String(Base64.encode(rawProto, Base64.NO_WRAP), "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            // Ceaseless wonder!  We failed to do UTF-8 encoding.  Give up with a message
-            // that is easy to trace in the source code.
-            request = "<Exception: UTF-8 encoding failed in VelvetNetworkClient>";
-        }
-        // Indicate how to view this data.
-        Logger.d(tag, "Use tools/mnc_assist/parse-request-response.sh\n<%s>", name);
-        // Log.d truncates long lines.  This is a workaround to print long lines by chunking
-        // into 2000 chars per line.  The line limit here is arbitrary but cannot be pushed past
-        // 4000 chars.  Keeping it at 3500 or lower should be safe.
-        int lengthMax = 2000;
-        int total = request.length();
-        for (int start = 0; start < total; start += lengthMax) {
-            // String.substring(...) expects the end to be the string length, never more.
-            int end = Math.min(start + lengthMax, total);
-            Logger.d(tag, "%s", request.substring(start, end));
-        }
-        // End-tag is not a standard HTML </end> because the utility
-        // used to parse these treats the backlash characters / in a
-        // special way.  Instead we use a marker called end-name instead.
-        Logger.d(tag, "\n<end-%s>", name);
-    }
-
-    /**
-     * Exception subclass that makes it clear that in a log, this is not an exception but a log
-     * statement for debugging.
-     */
-    public static final class DebugStackTraceLogger extends Throwable {
-        public DebugStackTraceLogger(String formattedMessage) {
-            super(formattedMessage);
-        }
-
-        public DebugStackTraceLogger() {
-            this(NOT_AN_EXCEPTION);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/StringFormattingUtils.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/StringFormattingUtils.java
deleted file mode 100644
index 14b4505..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/StringFormattingUtils.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.logging;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-
-/** Date-formatting static methods. */
-public final class StringFormattingUtils {
-    // Do not instantiate
-    private StringFormattingUtils() {}
-
-    private static SimpleDateFormat sLogDateFormat;
-
-    /** Formats {@code date} in the same format as used by logcat. */
-    static synchronized String formatLogDate(Date date) {
-        if (sLogDateFormat == null) {
-            // Getting the date format is mildly expensive, so don't do it unless we need it.
-            sLogDateFormat = new SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US);
-        }
-        return sLogDateFormat.format(date);
-    }
-
-    /** Formats a long as a Date */
-    public static String formatLogDate(long timeMs) {
-        return formatLogDate(new Date(timeMs));
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/protoextensions/FeedExtensionRegistry.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/protoextensions/FeedExtensionRegistry.java
deleted file mode 100644
index f6ba9e43..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/protoextensions/FeedExtensionRegistry.java
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.protoextensions;
-
-import com.google.protobuf.ExtensionRegistryLite;
-import com.google.protobuf.GeneratedMessageLite.GeneratedExtension;
-
-import org.chromium.chrome.browser.feed.library.api.host.proto.ProtoExtensionProvider;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.ClientBasicLoggingMetadata;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedAction;
-import org.chromium.components.feed.core.proto.ui.action.PietExtensionsProto.PietFeedActionPayload;
-import org.chromium.components.feed.core.proto.ui.stream.StreamOfflineExtensionProto.OfflineExtension;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.Card;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.Content;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.PietContent;
-import org.chromium.components.feed.core.proto.ui.stream.StreamSwipeExtensionProto.SwipeActionExtension;
-import org.chromium.components.feed.core.proto.wire.FeedActionRequestProto.FeedActionRequest;
-import org.chromium.components.feed.core.proto.wire.FeedActionResponseProto.FeedActionResponse;
-import org.chromium.components.feed.core.proto.wire.FeedRequestProto.FeedRequest;
-import org.chromium.components.feed.core.proto.wire.FeedResponseProto.FeedResponse;
-import org.chromium.components.feed.core.proto.wire.TokenProto;
-
-/**
- * Creates and initializes the proto extension registry, adding feed-internal extensions as well as
- * those provided by the host through the {@link ProtoExtensionProvider}.
- */
-public class FeedExtensionRegistry {
-    private final ExtensionRegistryLite mExtensionRegistry = ExtensionRegistryLite.newInstance();
-
-    /**
-     * Creates the registry.
-     *
-     * <p>TODO: Move this initialization code into Feed initialization, once that exists.
-     */
-    public FeedExtensionRegistry(ProtoExtensionProvider extensionProvider) {
-        // Set up all the extensions we use inside the Feed.
-        mExtensionRegistry.add(Card.cardExtension);
-        mExtensionRegistry.add(ClientBasicLoggingMetadata.clientBasicLoggingMetadata);
-        mExtensionRegistry.add(Content.contentExtension);
-        mExtensionRegistry.add(FeedAction.feedActionExtension);
-        mExtensionRegistry.add(FeedRequest.feedRequest);
-        mExtensionRegistry.add(FeedResponse.feedResponse);
-        mExtensionRegistry.add(FeedActionRequest.feedActionRequest);
-        mExtensionRegistry.add(FeedActionResponse.feedActionResponse);
-        mExtensionRegistry.add(OfflineExtension.offlineExtension);
-        mExtensionRegistry.add(PietContent.pietContentExtension);
-        mExtensionRegistry.add(PietFeedActionPayload.pietFeedActionPayloadExtension);
-        mExtensionRegistry.add(StreamStructureProto.Stream.streamExtension);
-        mExtensionRegistry.add(SwipeActionExtension.swipeActionExtension);
-        mExtensionRegistry.add(TokenProto.Token.tokenExtension);
-
-        // Call the host and add all the extensions it uses.
-        for (GeneratedExtension<?, ?> extension : extensionProvider.getProtoExtensions()) {
-            mExtensionRegistry.add(extension);
-        }
-    }
-
-    /** Returns the {@link ExtensionRegistryLite}. */
-    public ExtensionRegistryLite getExtensionRegistry() {
-        return mExtensionRegistry.getUnmodifiable();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/InfraIntegrationScope.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/InfraIntegrationScope.java
deleted file mode 100644
index 0759b05..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/InfraIntegrationScope.java
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.testing;
-
-import static org.mockito.Mockito.mock;
-
-import com.google.protobuf.GeneratedMessageLite.GeneratedExtension;
-
-import org.chromium.chrome.browser.feed.library.api.client.lifecycle.AppLifecycleListener;
-import org.chromium.chrome.browser.feed.library.api.client.requestmanager.RequestManager;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.feed.library.api.host.proto.ProtoExtensionProvider;
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorageDirect;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorageDirect;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProviderFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.api.internal.scope.ClearAllListener;
-import org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.testing.FakeDirectExecutor;
-import org.chromium.chrome.browser.feed.library.common.concurrent.testing.FakeMainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.testing.FakeThreadUtils;
-import org.chromium.chrome.browser.feed.library.common.protoextensions.FeedExtensionRegistry;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.testing.FakeClock;
-import org.chromium.chrome.browser.feed.library.feedapplifecyclelistener.FeedAppLifecycleListener;
-import org.chromium.chrome.browser.feed.library.feedmodelprovider.FeedModelProviderFactory;
-import org.chromium.chrome.browser.feed.library.feedprotocoladapter.FeedProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.feedrequestmanager.RequestManagerImpl;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.FeedSessionManagerFactory;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.FeedSessionManagerImpl;
-import org.chromium.chrome.browser.feed.library.feedstore.FeedStore;
-import org.chromium.chrome.browser.feed.library.hostimpl.storage.testing.InMemoryContentStorage;
-import org.chromium.chrome.browser.feed.library.hostimpl.storage.testing.InMemoryJournalStorage;
-import org.chromium.chrome.browser.feed.library.sharedstream.piet.PietRequiredContentAdapter;
-import org.chromium.chrome.browser.feed.library.testing.actionmanager.FakeViewActionManager;
-import org.chromium.chrome.browser.feed.library.testing.host.logging.FakeBasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.testing.host.scheduler.FakeSchedulerApi;
-import org.chromium.chrome.browser.feed.library.testing.requestmanager.FakeActionUploadRequestManager;
-import org.chromium.chrome.browser.feed.library.testing.requestmanager.FakeFeedRequestManager;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/**
- * This is a Scope type object which is used in the Infrastructure Integration tests. It sets the
- * Feed objects from ProtocolAdapter through the FeedSessionManager.
- */
-public class InfraIntegrationScope {
-    private static final boolean USE_TIMEOUT_SCHEDULER = true;
-
-    /**
-     * For the TimeoutSession tests, this is how long we allow it to run before declaring a timeout
-     * error.
-     */
-    public static final long TIMEOUT_TEST_TIMEOUT = TimeUnit.SECONDS.toMillis(20);
-
-    private final Configuration mConfiguration;
-    private final ContentStorageDirect mContentStorage;
-    private final FakeClock mFakeClock;
-    private final FakeDirectExecutor mFakeDirectExecutor;
-    private final FakeMainThreadRunner mFakeMainThreadRunner;
-    private final FakeFeedRequestManager mFakeFeedRequestManager;
-    private final FakeThreadUtils mFakeThreadUtils;
-    private final FeedAppLifecycleListener mAppLifecycleListener;
-    private final FeedModelProviderFactory mModelProviderFactory;
-    private final FeedProtocolAdapter mFeedProtocolAdapter;
-    private final FeedSessionManagerImpl mFeedSessionManager;
-    private final FeedStore mStore;
-    private final JournalStorageDirect mJournalStorage;
-    private final SchedulerApi mSchedulerApi;
-    private final TaskQueue mTaskQueue;
-    private final RequestManager mRequestManager;
-
-    private InfraIntegrationScope(FakeThreadUtils fakeThreadUtils,
-            FakeDirectExecutor fakeDirectExecutor, SchedulerApi schedulerApi, FakeClock fakeClock,
-            Configuration configuration, ContentStorageDirect contentStorage,
-            JournalStorageDirect journalStorage, FakeMainThreadRunner fakeMainThreadRunner) {
-        this.mFakeClock = fakeClock;
-        this.mConfiguration = configuration;
-        this.mContentStorage = contentStorage;
-        this.mJournalStorage = journalStorage;
-        this.mFakeDirectExecutor = fakeDirectExecutor;
-        this.mFakeMainThreadRunner = fakeMainThreadRunner;
-        this.mSchedulerApi = schedulerApi;
-        this.mFakeThreadUtils = fakeThreadUtils;
-        TimingUtils timingUtils = new TimingUtils();
-        mAppLifecycleListener = new FeedAppLifecycleListener(fakeThreadUtils);
-        FakeBasicLoggingApi fakeBasicLoggingApi = new FakeBasicLoggingApi();
-
-        FeedExtensionRegistry extensionRegistry =
-                new FeedExtensionRegistry(new ExtensionProvider());
-        mTaskQueue = new TaskQueue(
-                fakeBasicLoggingApi, fakeDirectExecutor, fakeMainThreadRunner, fakeClock);
-        mStore = new FeedStore(configuration, timingUtils, extensionRegistry, contentStorage,
-                journalStorage, fakeThreadUtils, mTaskQueue, fakeClock, fakeBasicLoggingApi,
-                fakeMainThreadRunner);
-        mFeedProtocolAdapter = new FeedProtocolAdapter(
-                Collections.singletonList(new PietRequiredContentAdapter()), timingUtils);
-        mFakeFeedRequestManager = new FakeFeedRequestManager(
-                fakeThreadUtils, fakeMainThreadRunner, mFeedProtocolAdapter, mTaskQueue);
-        FakeActionUploadRequestManager fakeActionUploadRequestManager =
-                new FakeActionUploadRequestManager(mStore, new FakeViewActionManager(mStore),
-                        FakeThreadUtils.withThreadChecks());
-        ActionManager actionManager = mock(ActionManager.class);
-        mFeedSessionManager = new FeedSessionManagerFactory(mTaskQueue, mStore, timingUtils,
-                fakeThreadUtils, mFeedProtocolAdapter, mFakeFeedRequestManager,
-                fakeActionUploadRequestManager, schedulerApi, configuration, fakeClock,
-                mAppLifecycleListener, fakeMainThreadRunner, fakeBasicLoggingApi, actionManager)
-                                      .create();
-        new ClearAllListener(
-                mTaskQueue, mFeedSessionManager, mStore, fakeThreadUtils, mAppLifecycleListener);
-        mFeedSessionManager.initialize();
-        mModelProviderFactory = new FeedModelProviderFactory(mFeedSessionManager, fakeThreadUtils,
-                timingUtils, mTaskQueue, fakeMainThreadRunner, configuration, fakeBasicLoggingApi);
-        mRequestManager = new RequestManagerImpl(mFakeFeedRequestManager, mFeedSessionManager);
-    }
-
-    public ProtocolAdapter getProtocolAdapter() {
-        return mFeedProtocolAdapter;
-    }
-
-    public FeedSessionManager getFeedSessionManager() {
-        return mFeedSessionManager;
-    }
-
-    public ModelProviderFactory getModelProviderFactory() {
-        return mModelProviderFactory;
-    }
-
-    public FakeClock getFakeClock() {
-        return mFakeClock;
-    }
-
-    public FakeDirectExecutor getFakeDirectExecutor() {
-        return mFakeDirectExecutor;
-    }
-
-    public FakeMainThreadRunner getFakeMainThreadRunner() {
-        return mFakeMainThreadRunner;
-    }
-
-    public FakeThreadUtils getFakeThreadUtils() {
-        return mFakeThreadUtils;
-    }
-
-    public FeedStore getStore() {
-        return mStore;
-    }
-
-    public TaskQueue getTaskQueue() {
-        return mTaskQueue;
-    }
-
-    public FakeFeedRequestManager getFakeFeedRequestManager() {
-        return mFakeFeedRequestManager;
-    }
-
-    public AppLifecycleListener getAppLifecycleListener() {
-        return mAppLifecycleListener;
-    }
-
-    public RequestManager getRequestManager() {
-        return mRequestManager;
-    }
-
-    @Override
-    public InfraIntegrationScope clone() {
-        return new InfraIntegrationScope(mFakeThreadUtils, mFakeDirectExecutor, mSchedulerApi,
-                mFakeClock, mConfiguration, mContentStorage, mJournalStorage,
-                mFakeMainThreadRunner);
-    }
-
-    private static class ExtensionProvider implements ProtoExtensionProvider {
-        @Override
-        public List<GeneratedExtension<?, ?>> getProtoExtensions() {
-            return new ArrayList<>();
-        }
-    }
-
-    /** Builder for creating the {@link InfraIntegrationScope} */
-    public static class Builder {
-        private final FakeClock mFakeClock = new FakeClock();
-        private final FakeMainThreadRunner mFakeMainThreadRunner =
-                FakeMainThreadRunner.create(mFakeClock);
-        private final FakeThreadUtils mFakeThreadUtils = FakeThreadUtils.withThreadChecks();
-
-        private Configuration mConfiguration = Configuration.getDefaultInstance();
-        private FakeDirectExecutor mFakeDirectExecutor =
-                FakeDirectExecutor.runTasksImmediately(mFakeThreadUtils);
-        private SchedulerApi mSchedulerApi1 = new FakeSchedulerApi(mFakeThreadUtils);
-
-        public Builder() {}
-
-        public Builder setConfiguration(Configuration configuration) {
-            this.mConfiguration = configuration;
-            return this;
-        }
-
-        public Builder setSchedulerApi(SchedulerApi schedulerApi) {
-            this.mSchedulerApi1 = schedulerApi;
-            return this;
-        }
-
-        public Builder withQueuingTasks() {
-            mFakeDirectExecutor = FakeDirectExecutor.queueAllTasks(mFakeThreadUtils);
-            return this;
-        }
-
-        public Builder withTimeoutSessionConfiguration(long timeoutMs) {
-            mConfiguration = mConfiguration.toBuilder()
-                                     .put(ConfigKey.USE_TIMEOUT_SCHEDULER, USE_TIMEOUT_SCHEDULER)
-                                     .put(ConfigKey.TIMEOUT_TIMEOUT_MS, timeoutMs)
-                                     .build();
-            return this;
-        }
-
-        public InfraIntegrationScope build() {
-            return new InfraIntegrationScope(mFakeThreadUtils, mFakeDirectExecutor, mSchedulerApi1,
-                    mFakeClock, mConfiguration, new InMemoryContentStorage(),
-                    new InMemoryJournalStorage(), mFakeMainThreadRunner);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/ModelProviderValidator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/ModelProviderValidator.java
deleted file mode 100644
index dae92104..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/ModelProviderValidator.java
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.testing;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.fail;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild.Type;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelCursor;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
-/** Helper class providing validation method for a ModelProvider. */
-public class ModelProviderValidator {
-    private final ProtocolAdapter mProtocolAdapter;
-
-    public ModelProviderValidator(ProtocolAdapter protocolAdapter) {
-        this.mProtocolAdapter = protocolAdapter;
-    }
-
-    public void assertRoot(ModelProvider modelProvider) {
-        assertRoot(modelProvider, ResponseBuilder.ROOT_CONTENT_ID);
-    }
-
-    // Suppress nullness since it's just another failure type for tests
-    @SuppressWarnings("nullness")
-    public void assertRoot(ModelProvider modelProvider, ContentId contentId) {
-        ModelFeature modelFeature = modelProvider.getRootFeature();
-        assertThat(modelFeature).isNotNull();
-        assertThat(modelFeature.getStreamFeature()).isNotNull();
-        assertStreamContentId(modelFeature.getStreamFeature().getContentId(),
-                mProtocolAdapter.getStreamContentId(contentId));
-    }
-
-    public void assertStreamContentId(String contentId, String expectedContentId) {
-        assertThat(contentId).isEqualTo(expectedContentId);
-    }
-
-    public void assertStreamContentId(String contentId, ContentId expectedContentId) {
-        assertThat(contentId).isEqualTo(mProtocolAdapter.getStreamContentId(expectedContentId));
-    }
-
-    public void verifyContent(ModelProvider modelProvider, List<ContentId> features) {
-        for (ContentId contentId : features) {
-            String streamContentId = mProtocolAdapter.getStreamContentId(contentId);
-            if (modelProvider.getModelChild(streamContentId) == null) {
-                fail("Feature was not found for " + streamContentId);
-            }
-        }
-    }
-
-    public void assertCardStructure(ModelChild modelChild) {
-        AtomicInteger cursorCount = new AtomicInteger();
-        assertThat(modelChild.getType()).isEqualTo(Type.FEATURE);
-        ModelFeature feature = modelChild.getModelFeature();
-        ModelCursor cursor = feature.getCursor();
-        ModelChild child;
-        while ((child = cursor.getNextItem()) != null) {
-            cursorCount.incrementAndGet();
-            assertThat(child.getType()).isEqualTo(Type.FEATURE);
-        }
-        assertThat(cursorCount.get()).isEqualTo(1);
-    }
-
-    public void assertCursorSize(ModelCursor cursor, int expectedSize) {
-        int size = 0;
-        while (cursor.getNextItem() != null) {
-            size++;
-        }
-        assertThat(size).isEqualTo(expectedSize);
-    }
-
-    @SuppressWarnings("nullness")
-    public void assertCursorContents(ModelProvider modelProvider, ContentId... cards) {
-        ModelFeature rootFeature = modelProvider.getRootFeature();
-        assertThat(rootFeature).isNotNull();
-        ModelCursor cursor = rootFeature.getCursor();
-        assertCursorContents(cursor, cards);
-    }
-
-    public void assertCursorContents(ModelCursor cursor, ContentId... args) {
-        AtomicInteger size = new AtomicInteger(0);
-        ModelChild child;
-        while ((child = cursor.getNextItem()) != null) {
-            int pos = size.getAndIncrement();
-            assertStreamContentId(child.getContentId(), args[pos]);
-        }
-        assertThat(cursor.isAtEnd()).isTrue();
-        assertThat(args.length).isEqualTo(size.get());
-    }
-
-    @SuppressWarnings("nullness")
-    public ModelChild assertCursorContentsWithToken(
-            ModelProvider modelProvider, ContentId... cards) {
-        ModelFeature rootFeature = modelProvider.getRootFeature();
-        assertThat(rootFeature).isNotNull();
-        ModelCursor cursor = rootFeature.getCursor();
-        ModelChild tokenFeature = assertCursorContentsWithToken(cursor, cards);
-        assertThat(tokenFeature).isNotNull();
-        return tokenFeature;
-    }
-
-    public ModelChild assertCursorContentsWithToken(ModelCursor cursor, ContentId... args) {
-        AtomicInteger size = new AtomicInteger(0);
-        AtomicReference<ModelChild> tokenFeature = new AtomicReference<>();
-        ModelChild child;
-        while ((child = cursor.getNextItem()) != null) {
-            int pos = size.getAndIncrement();
-            if (pos == args.length) {
-                assertThat(child.getType()).isEqualTo(Type.TOKEN);
-                tokenFeature.set(child);
-            } else {
-                assertStreamContentId(child.getContentId(), args[pos]);
-            }
-        }
-
-        assertThat(cursor.isAtEnd()).isTrue();
-        return tokenFeature.get();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/PagingState.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/PagingState.java
deleted file mode 100644
index 4bea5a5..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/PagingState.java
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.testing;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.chromium.chrome.browser.feed.library.common.testing.ResponseBuilder.ROOT_CONTENT_ID;
-
-import com.google.protobuf.ByteString;
-
-import org.chromium.chrome.browser.feed.library.api.internal.common.testing.ContentIdGenerators;
-import org.chromium.chrome.browser.feed.library.common.testing.ResponseBuilder.WireProtocolInfo;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-import org.chromium.components.feed.core.proto.wire.ResponseProto.Response;
-
-import java.nio.charset.Charset;
-
-/**
- * Creates a paging based responses. Create two {@link Response} object, and initial response and a
- * page response. In addition, create a {@link StreamToken} which is used to trigger the paged
- * response.
- */
-public class PagingState {
-    public final Response initialResponse;
-    public final Response pageResponse;
-    public final StreamToken streamToken;
-
-    public PagingState(ContentId[] initialCards, ContentId[] pageCards, int tokenId,
-            ContentIdGenerators idGenerator) {
-        ByteString token = ByteString.copyFrom(Integer.toString(tokenId), Charset.defaultCharset());
-        initialResponse = getInitialResponse(initialCards, tokenId, token);
-        streamToken = getSessionId(token, tokenId, idGenerator);
-        pageResponse = getPageResponse(pageCards);
-    }
-
-    private static Response getInitialResponse(ContentId[] cards, int tokenId, ByteString token) {
-        ResponseBuilder responseBuilder =
-                ResponseBuilder.forClearAllWithCards(cards).addStreamToken(tokenId, token);
-        WireProtocolInfo info = responseBuilder.getWireProtocolInfo();
-        assertThat(info.hasToken).isTrue();
-        return responseBuilder.build();
-    }
-
-    private static Response getPageResponse(ContentId[] pagedCards) {
-        return ResponseBuilder.builder().addCardsToRoot(pagedCards).build();
-    }
-
-    private static StreamToken getSessionId(
-            ByteString token, int id, ContentIdGenerators idGenerator) {
-        ContentId tokenId = ContentId.newBuilder()
-                                    .setContentDomain("token")
-                                    .setId(id)
-                                    .setTable("feature")
-                                    .build();
-
-        StreamToken.Builder tokenBuilder = StreamToken.newBuilder();
-        tokenBuilder.setParentId(idGenerator.createContentId(ROOT_CONTENT_ID));
-        tokenBuilder.setContentId(idGenerator.createContentId(tokenId));
-        tokenBuilder.setNextPageToken(token);
-        return tokenBuilder.build();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/RequiredConsumer.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/RequiredConsumer.java
deleted file mode 100644
index 5be5a2c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/RequiredConsumer.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.testing;
-
-import org.chromium.base.Consumer;
-
-/** Test helper class that ensures that the asynchronous consumer is called. */
-public class RequiredConsumer<T> implements Consumer<T> {
-    private final Consumer<T> mConsumer;
-    private boolean mIsCalled;
-
-    public RequiredConsumer(Consumer<T> consumer) {
-        this.mConsumer = consumer;
-    }
-
-    @Override
-    public void accept(T input) {
-        mIsCalled = true;
-        mConsumer.accept(input);
-    }
-
-    public boolean isCalled() {
-        return mIsCalled;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/ResponseBuilder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/ResponseBuilder.java
deleted file mode 100644
index 838d6ac7..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/ResponseBuilder.java
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.testing;
-
-import androidx.annotation.Nullable;
-
-import com.google.protobuf.ByteString;
-
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.PietSharedState;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.Content;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.PietContent;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-import org.chromium.components.feed.core.proto.wire.DataOperationProto.DataOperation;
-import org.chromium.components.feed.core.proto.wire.DataOperationProto.DataOperation.Operation;
-import org.chromium.components.feed.core.proto.wire.FeatureProto.Feature;
-import org.chromium.components.feed.core.proto.wire.FeatureProto.Feature.RenderableUnit;
-import org.chromium.components.feed.core.proto.wire.FeedResponseProto.FeedResponse;
-import org.chromium.components.feed.core.proto.wire.PayloadMetadataProto.PayloadMetadata;
-import org.chromium.components.feed.core.proto.wire.ResponseProto.Response;
-import org.chromium.components.feed.core.proto.wire.SemanticPropertiesProto.SemanticProperties;
-import org.chromium.components.feed.core.proto.wire.TokenProto.Token;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Builder making creation of wire protocol Response object easier. */
-public class ResponseBuilder {
-    // this needs to match the root content_id defined in the FeedProtocolAdapter.
-    public static final ContentId ROOT_CONTENT_ID = ContentId.newBuilder()
-                                                            .setContentDomain("stream_root")
-                                                            .setId(0)
-                                                            .setTable("feature")
-                                                            .build();
-    public static final ContentId PIET_SHARED_STATE = ContentId.newBuilder()
-                                                              .setContentDomain("piet-shared-state")
-                                                              .setId(1)
-                                                              .setTable("feature")
-                                                              .build();
-    private static final int CONTENT_ID_CARD_INCREMENT = 100;
-    private static final ContentId TOKEN_CONTENT_ID =
-            ContentId.newBuilder().setContentDomain("token").setId(0).setTable("token").build();
-
-    public static ContentId createFeatureContentId(int id) {
-        return ContentId.newBuilder()
-                .setContentDomain("feature")
-                .setId(id)
-                .setTable("feature")
-                .build();
-    }
-
-    private final WireProtocolInfo mWireProtocolInfo = new WireProtocolInfo();
-    private final FeedResponse.Builder mFeedResponseBuilder = FeedResponse.newBuilder();
-    private final List<ContentId> mPietSharedStateContentIds = new ArrayList<>();
-
-    private int mTokenId;
-    @Nullable
-    private ByteString mToken;
-
-    /** Add a CLEAR_ALL data operation to the response */
-    public ResponseBuilder addClearOperation() {
-        mWireProtocolInfo.hasClearOperation = true;
-        mFeedResponseBuilder.addDataOperation(
-                DataOperation.newBuilder().setOperation(Operation.CLEAR_ALL).build());
-        return this;
-    }
-
-    public ResponseBuilder addStreamToken(int tokenId, ByteString token) {
-        this.mToken = token;
-        this.mTokenId = tokenId;
-        mWireProtocolInfo.hasToken = true;
-        return this;
-    }
-
-    public ResponseBuilder addPietSharedState() {
-        return addPietSharedState(PIET_SHARED_STATE);
-    }
-
-    public ResponseBuilder addPietSharedState(ContentId pietSharedStateContentId) {
-        mPietSharedStateContentIds.add(pietSharedStateContentId);
-        PayloadMetadata payloadMetadata =
-                PayloadMetadata.newBuilder().setContentId(pietSharedStateContentId).build();
-        mFeedResponseBuilder.addDataOperation(
-                DataOperation.newBuilder()
-                        .setOperation(Operation.UPDATE_OR_APPEND)
-                        .setPietSharedState(PietSharedState.getDefaultInstance())
-                        .setMetadata(payloadMetadata)
-                        .build());
-        return this;
-    }
-
-    /** Add a data operation for a feature that represents the Root of the Stream. */
-    public ResponseBuilder addRootFeature() {
-        return addRootFeature(ROOT_CONTENT_ID);
-    }
-
-    public ResponseBuilder addRootFeature(ContentId contentId) {
-        PayloadMetadata payloadMetadata =
-                PayloadMetadata.newBuilder().setContentId(contentId).build();
-        Feature feature = Feature.newBuilder().setRenderableUnit(RenderableUnit.STREAM).build();
-
-        mFeedResponseBuilder.addDataOperation(DataOperation.newBuilder()
-                                                      .setOperation(Operation.UPDATE_OR_APPEND)
-                                                      .setFeature(feature)
-                                                      .setMetadata(payloadMetadata)
-                                                      .build());
-        mWireProtocolInfo.featuresAdded.add(contentId);
-        return this;
-    }
-
-    public ResponseBuilder addClusterFeature(ContentId contentId, ContentId parentId) {
-        PayloadMetadata payloadMetadata =
-                PayloadMetadata.newBuilder().setContentId(contentId).build();
-        Feature feature = Feature.newBuilder()
-                                  .setRenderableUnit(RenderableUnit.CLUSTER)
-                                  .setParentId(parentId)
-                                  .build();
-        mFeedResponseBuilder.addDataOperation(DataOperation.newBuilder()
-                                                      .setOperation(Operation.UPDATE_OR_APPEND)
-                                                      .setFeature(feature)
-                                                      .setMetadata(payloadMetadata)
-                                                      .build());
-        mWireProtocolInfo.featuresAdded.add(contentId);
-        return this;
-    }
-
-    public ResponseBuilder addCard(ContentId contentId, ContentId parentId) {
-        // Create a Card
-        PayloadMetadata payloadMetadata =
-                PayloadMetadata.newBuilder().setContentId(contentId).build();
-        Feature feature = Feature.newBuilder()
-                                  .setRenderableUnit(RenderableUnit.CARD)
-                                  .setParentId(parentId)
-                                  .build();
-        mFeedResponseBuilder.addDataOperation(DataOperation.newBuilder()
-                                                      .setOperation(Operation.UPDATE_OR_APPEND)
-                                                      .setFeature(feature)
-                                                      .setMetadata(payloadMetadata)
-                                                      .build());
-        mWireProtocolInfo.featuresAdded.add(contentId);
-
-        // Create content within the Card
-        payloadMetadata =
-                PayloadMetadata.newBuilder()
-                        .setContentId(createNewContentId(contentId, CONTENT_ID_CARD_INCREMENT))
-                        .build();
-        feature = Feature.newBuilder()
-                          .setRenderableUnit(RenderableUnit.CONTENT)
-                          .setParentId(contentId)
-                          .setExtension(Content.contentExtension,
-                                  Content.newBuilder()
-                                          .setType(Content.Type.PIET)
-                                          .setExtension(PietContent.pietContentExtension,
-                                                  PietContent.newBuilder()
-                                                          .addAllPietSharedStates(
-                                                                  mPietSharedStateContentIds)
-                                                          .build())
-                                          .build())
-                          .build();
-        mFeedResponseBuilder.addDataOperation(DataOperation.newBuilder()
-                                                      .setOperation(Operation.UPDATE_OR_APPEND)
-                                                      .setFeature(feature)
-                                                      .setMetadata(payloadMetadata)
-                                                      .build());
-        mWireProtocolInfo.featuresAdded.add(payloadMetadata.getContentId());
-        return this;
-    }
-
-    public ResponseBuilder addCardsToRoot(ContentId[] contentIds) {
-        for (ContentId contentId : contentIds) {
-            addCard(contentId, ROOT_CONTENT_ID);
-        }
-        return this;
-    }
-
-    public ResponseBuilder addCardWithSemanticData(ContentId contentId, ByteString semanticData) {
-        mFeedResponseBuilder.addDataOperation(
-                DataOperation.newBuilder()
-                        .setOperation(Operation.UPDATE_OR_APPEND)
-                        .setFeature(Feature.newBuilder().setRenderableUnit(RenderableUnit.CARD))
-                        .setMetadata(
-                                PayloadMetadata.newBuilder()
-                                        .setContentId(contentId)
-                                        .setSemanticProperties(
-                                                SemanticProperties.newBuilder()
-                                                        .setSemanticPropertiesData(semanticData))));
-        mWireProtocolInfo.featuresAdded.add(contentId);
-        return this;
-    }
-
-    public ResponseBuilder removeFeature(ContentId contentId, ContentId parentId) {
-        PayloadMetadata payloadMetadata =
-                PayloadMetadata.newBuilder().setContentId(contentId).build();
-        Feature feature = Feature.newBuilder()
-                                  .setRenderableUnit(RenderableUnit.CARD)
-                                  .setParentId(parentId)
-                                  .build();
-        mFeedResponseBuilder.addDataOperation(DataOperation.newBuilder()
-                                                      .setOperation(Operation.REMOVE)
-                                                      .setFeature(feature)
-                                                      .setMetadata(payloadMetadata)
-                                                      .build());
-        mWireProtocolInfo.featuresAdded.add(contentId);
-        return this;
-    }
-
-    public Response build() {
-        if (mToken != null) {
-            addToken(mTokenId, mToken);
-        }
-        return Response.newBuilder()
-                .setExtension(FeedResponse.feedResponse, mFeedResponseBuilder.build())
-                .build();
-    }
-
-    private void addToken(int tokenId, ByteString token) {
-        PayloadMetadata payloadMetadata =
-                PayloadMetadata.newBuilder()
-                        .setContentId(createNewContentId(TOKEN_CONTENT_ID, tokenId))
-                        .build();
-        Feature.Builder featureBuilder = Feature.newBuilder()
-                                                 .setRenderableUnit(RenderableUnit.TOKEN)
-                                                 .setParentId(ROOT_CONTENT_ID);
-        Token wireToken = Token.newBuilder().setNextPageToken(token).build();
-        featureBuilder.setExtension(Token.tokenExtension, wireToken);
-        mFeedResponseBuilder.addDataOperation(DataOperation.newBuilder()
-                                                      .setOperation(Operation.UPDATE_OR_APPEND)
-                                                      .setFeature(featureBuilder.build())
-                                                      .setMetadata(payloadMetadata)
-                                                      .build());
-    }
-
-    public WireProtocolInfo getWireProtocolInfo() {
-        return mWireProtocolInfo;
-    }
-
-    /** Returns a new {@link ResponseBuilder}. */
-    public static ResponseBuilder builder() {
-        return new ResponseBuilder();
-    }
-
-    /** Returns a {@link ResponseBuilder} with a CLEAR_ALL, root, and cards. */
-    public static ResponseBuilder forClearAllWithCards(ContentId[] cards) {
-        return builder().addClearOperation().addRootFeature().addCardsToRoot(cards);
-    }
-
-    /** Captures information about the wire protocol that was created. */
-    public static class WireProtocolInfo {
-        public final List<ContentId> featuresAdded = new ArrayList<>();
-        public boolean hasClearOperation;
-        public boolean hasToken;
-    }
-
-    private ContentId createNewContentId(ContentId contentId, int idIncrement) {
-        ContentId.Builder builder = contentId.toBuilder();
-        builder.setId(contentId.getId() + idIncrement);
-        return builder.build();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/RunnableSubject.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/RunnableSubject.java
deleted file mode 100644
index 190d067..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/RunnableSubject.java
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.testing;
-
-import static com.google.common.truth.Fact.fact;
-import static com.google.common.truth.Fact.simpleFact;
-import static com.google.common.truth.Truth.assertAbout;
-
-import com.google.common.truth.FailureMetadata;
-import com.google.common.truth.Subject;
-import com.google.common.truth.ThrowableSubject;
-
-import org.chromium.chrome.browser.feed.library.common.testing.RunnableSubject.ThrowingRunnable;
-
-/** A Truth subject for testing exceptions. */
-@SuppressWarnings("nullness")
-public final class RunnableSubject extends Subject {
-    private static final Subject
-            .Factory<RunnableSubject, ThrowingRunnable> RUNNABLE_SUBJECT_FACTORY =
-            RunnableSubject::new;
-
-    /** Gets the subject factory of {@link RunnableSubject}. */
-    public static Subject.Factory<RunnableSubject, ThrowingRunnable> runnables() {
-        return RUNNABLE_SUBJECT_FACTORY;
-    }
-
-    private final ThrowingRunnable mActual;
-
-    public RunnableSubject(FailureMetadata failureMetadata, ThrowingRunnable runnable) {
-        super(failureMetadata, runnable);
-        this.mActual = runnable;
-    }
-
-    /**
-     * Note: Doesn't work when both this method, and Truth.assertThat, are imported statically.
-     * There's a type inference clash.
-     */
-    public static RunnableSubject assertThat(ThrowingRunnable runnable) {
-        return assertAbout(RUNNABLE_SUBJECT_FACTORY).that(runnable);
-    }
-
-    /**
-     * Wraps a RunnableSubject around the given runnable.
-     *
-     * <p>Note: This disambiguated method only exists because just 'assertThat' doesn't work when
-     * both RunnableSubject.assertThat and Truth.assertThat are imported statically. There's a type
-     * inference clash.
-     */
-    public static RunnableSubject assertThatRunnable(ThrowingRunnable runnable) {
-        return assertAbout(RUNNABLE_SUBJECT_FACTORY).that(runnable);
-    }
-
-    @SuppressWarnings("unchecked")
-    private <E extends Throwable> E runAndCaptureOrFail(Class<E> clazz) {
-        if (mActual == null) {
-            failWithoutActual(fact("expected to throw", clazz.getName()),
-                    simpleFact("but didn't run because it's null"));
-            return null;
-        }
-
-        try {
-            mActual.run();
-        } catch (Throwable ex) {
-            if (!clazz.isInstance(ex)) {
-                check("thrownException()").that(ex).isInstanceOf(clazz); // fails
-                return null;
-            }
-            return (E) ex;
-        }
-
-        failWithoutActual(fact("expected to throw", clazz.getName()),
-                simpleFact("but ran to completion"), fact("runnable was", mActual));
-        return null;
-    }
-
-    public <E extends Throwable> ThrowsThenClause<E> throwsAnExceptionOfType(Class<E> clazz) {
-        return new ThrowsThenClause<>(runAndCaptureOrFail(clazz), "thrownException()");
-    }
-
-    /**
-     * Just a fluent class prompting you to type ".that" before asserting things about the
-     * exception.
-     */
-    public class ThrowsThenClause<E extends Throwable> {
-        private final E mThrowable;
-        private final String mDescription;
-
-        private ThrowsThenClause(E throwable, String description) {
-            this.mThrowable = throwable;
-            this.mDescription = description;
-        }
-
-        public ThrowableSubject that() {
-            return check(mDescription).that(mThrowable);
-        }
-
-        public <C extends Throwable> ThrowsThenClause<C> causedByAnExceptionOfType(Class<C> clazz) {
-            if (!clazz.isInstance(mThrowable.getCause())) {
-                that().hasCauseThat().isInstanceOf(clazz); // fails
-                return null;
-            }
-
-            @SuppressWarnings("unchecked")
-            C cause = (C) mThrowable.getCause();
-
-            return new ThrowsThenClause<>(cause, mDescription + ".getCause()");
-        }
-
-        public void causedBy(Throwable cause) {
-            that().hasCauseThat().isSameInstanceAs(cause);
-        }
-
-        public E getCaught() {
-            return mThrowable;
-        }
-    }
-
-    /**
-     * Runnable which is able to throw a {@link Throwable}. Used for subject in order to test that a
-     * block of code actually throws an appropriate exception.
-     */
-    public interface ThrowingRunnable { void run() throws Throwable; }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/SessionTestUtils.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/SessionTestUtils.java
deleted file mode 100644
index d3adeb0b0..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/SessionTestUtils.java
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.testing;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi.RequestBehavior;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider.ViewDepthProvider;
-import org.chromium.chrome.browser.feed.library.common.concurrent.testing.FakeThreadUtils;
-import org.chromium.chrome.browser.feed.library.testing.host.scheduler.FakeSchedulerApi;
-import org.chromium.chrome.browser.feed.library.testing.modelprovider.FakeViewDepthProvider;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-
-import java.util.List;
-
-/** Utilities for tests that are creating new sessions. */
-public final class SessionTestUtils {
-    public static final long TIMEOUT_MS = 50L;
-
-    private static final ContentId[] REQUEST_1 = new ContentId[] {
-            ResponseBuilder.createFeatureContentId(1), ResponseBuilder.createFeatureContentId(2)};
-    private static final ContentId[] REQUEST_2 = new ContentId[] {
-            ResponseBuilder.createFeatureContentId(3), ResponseBuilder.createFeatureContentId(4)};
-    private static final long DELAY_MS = 100L;
-    private static final long SHORT_DELAY_MS = 25L;
-
-    private final InfraIntegrationScope mScope;
-    private long mCurrentDelay;
-
-    public SessionTestUtils(@RequestBehavior int requestBehavior) {
-        mScope =
-                new InfraIntegrationScope.Builder()
-                        .setSchedulerApi(new FakeSchedulerApi(FakeThreadUtils.withoutThreadChecks())
-                                                 .setRequestBehavior(requestBehavior))
-                        .withTimeoutSessionConfiguration(TIMEOUT_MS)
-                        .build();
-        mCurrentDelay = DELAY_MS;
-    }
-
-    /** Shortens the delay on requests so that they complete before timeout. */
-    public SessionTestUtils requestBeforeTimeout() {
-        mCurrentDelay = SHORT_DELAY_MS;
-        return this;
-    }
-
-    /** Returns the {@link InfraIntegrationScope}. */
-    public InfraIntegrationScope getScope() {
-        return mScope;
-    }
-
-    private ViewDepthProvider createViewDepthProvider() {
-        return new FakeViewDepthProvider().setChildViewDepth(
-                mScope.getProtocolAdapter().getStreamContentId(REQUEST_1[1]));
-    }
-
-    /** Creates a new session and returns the {@link ModelProvider}. */
-    public ModelProvider createNewSession() {
-        return mScope.getModelProviderFactory().createNew(
-                createViewDepthProvider(), UiContext.getDefaultInstance());
-    }
-
-    /** Populates HEAD with data. */
-    public void populateHead() {
-        mScope.getFakeFeedRequestManager()
-                .queueResponse(ResponseBuilder.forClearAllWithCards(REQUEST_1).build())
-                .triggerRefresh(RequestReason.OPEN_WITHOUT_CONTENT,
-                        mScope.getFeedSessionManager().getUpdateConsumer(
-                                MutationContext.EMPTY_CONTEXT));
-    }
-
-    /** Enqueues an error response and returns the delay in milliseconds. */
-    public long queueError() {
-        mScope.getFakeFeedRequestManager().queueError(mCurrentDelay);
-        return mCurrentDelay;
-    }
-
-    /** Enqueues a response and returns the delay in milliseconds. */
-    public long queueRequest() {
-        mScope.getFakeFeedRequestManager().queueResponse(
-                ResponseBuilder.forClearAllWithCards(REQUEST_2).build(), mCurrentDelay);
-        return mCurrentDelay;
-    }
-
-    /** Enqueues an error response, triggers the refresh, and returns the delay in milliseconds. */
-    public long startOutstandingRequestWithError() {
-        long delayMs = queueError();
-        mScope.getFakeFeedRequestManager().triggerRefresh(RequestReason.OPEN_WITHOUT_CONTENT,
-                mScope.getFeedSessionManager().getUpdateConsumer(MutationContext.EMPTY_CONTEXT));
-        return delayMs;
-    }
-
-    /** Enqueues a response, triggers the refresh, and returns the delay in milliseconds. */
-    public long startOutstandingRequest() {
-        long delayMs = queueRequest();
-        mScope.getFakeFeedRequestManager().triggerRefresh(RequestReason.OPEN_WITHOUT_CONTENT,
-                mScope.getFeedSessionManager().getUpdateConsumer(MutationContext.EMPTY_CONTEXT));
-        return delayMs;
-    }
-
-    /** Asserts that the children are from HEAD. */
-    public void assertHeadContent(List<ModelChild> rootChildren) {
-        assertThat(rootChildren).hasSize(REQUEST_1.length);
-        for (int i = 0; i < rootChildren.size(); i++) {
-            assertThat(rootChildren.get(i).getContentId())
-                    .isEqualTo(mScope.getProtocolAdapter().getStreamContentId(REQUEST_1[i]));
-        }
-    }
-
-    /** Asserts that the children are from the outstanding request. */
-    public void assertNewContent(List<ModelChild> rootChildren) {
-        assertThat(rootChildren).hasSize(REQUEST_2.length);
-        for (int i = 0; i < rootChildren.size(); i++) {
-            assertThat(rootChildren.get(i).getContentId())
-                    .isEqualTo(mScope.getProtocolAdapter().getStreamContentId(REQUEST_2[i]));
-        }
-    }
-
-    /** Asserts that the children are the union of HEAD and the outstanding request. */
-    public void assertAppendedContent(List<ModelChild> rootChildren) {
-        assertThat(rootChildren).hasSize(REQUEST_1.length + REQUEST_2.length);
-        assertHeadContent(rootChildren.subList(0, REQUEST_1.length));
-        assertNewContent(
-                rootChildren.subList(REQUEST_1.length, REQUEST_1.length + REQUEST_2.length));
-    }
-
-    /**
-     * Asserts that no runnables are pending in the {@link TaskQueue} or {@link MainThreadRunner}.
-     */
-    public void assertWorkComplete() {
-        assertThat(mScope.getTaskQueue().hasBacklog()).isFalse();
-        assertThat(mScope.getFakeMainThreadRunner().hasPendingTasks()).isFalse();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/Clock.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/Clock.java
deleted file mode 100644
index 2c444e6..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/Clock.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.time;
-
-/**
- * Interface of SystemClock; real instances should just delegate the calls to the static methods,
- * while mock instances return values set manually; see {@link android.os.SystemClock}. In addition,
- * this interface also has an instance method for {@link System#currentTimeMillis}, so it can be
- * mocked if needed
- */
-/*@DoNotMock("Use org.chromium.chrome.browser.feed.library.common.time.testing.FakeClock instead")*/
-public interface Clock {
-    /** Number of nanoseconds in a single millisecond. */
-    long NS_IN_MS = 1_000_000;
-
-    /**
-     * Returns the current system time in milliseconds since January 1, 1970 00:00:00 UTC. This
-     * method shouldn't be used for measuring timeouts or other elapsed time measurements, as
-     * changing the system time can affect the results.
-     *
-     * @return the local system time in milliseconds.
-     */
-    long currentTimeMillis();
-
-    /**
-     * Returns milliseconds since boot, including time spent in sleep.
-     *
-     * @return elapsed milliseconds since boot.
-     */
-    long elapsedRealtime();
-
-    /**
-     * Returns nanoseconds since boot, including time spent in sleep.
-     *
-     * @return elapsed nanoseconds since boot.
-     */
-    default long elapsedRealtimeNanos() {
-        return NS_IN_MS * elapsedRealtime();
-    }
-
-    /**
-     * Returns milliseconds since boot, not counting time spent in deep sleep.
-     *
-     * @return milliseconds of non-sleep uptime since boot.
-     */
-    long uptimeMillis();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/SystemClockImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/SystemClockImpl.java
deleted file mode 100644
index a357219..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/SystemClockImpl.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.time;
-
-import android.os.Build;
-import android.os.SystemClock;
-
-/**
- * Implementation of {@link Clock} that delegates to the system clock.
- *
- * <p>This class is intended for use only in contexts where injection is impossible. Where possible,
- * prefer to simply inject a {@link Clock}.
- */
-public class SystemClockImpl implements Clock {
-    @Override
-    public long currentTimeMillis() {
-        return System.currentTimeMillis();
-    }
-
-    @Override
-    public long elapsedRealtime() {
-        return SystemClock.elapsedRealtime();
-    }
-
-    @Override
-    public long elapsedRealtimeNanos() {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            try {
-                return SystemClock.elapsedRealtimeNanos();
-            } catch (NoSuchMethodError ignoredError) {
-                // Some vendors have a SystemClock that doesn't contain the method even though the
-                // SDK should contain it. Fall through to the alternate version.
-            }
-        }
-        return SystemClock.elapsedRealtime() * NS_IN_MS;
-    }
-
-    @Override
-    public long uptimeMillis() {
-        return SystemClock.uptimeMillis();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/TimingUtils.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/TimingUtils.java
deleted file mode 100644
index c6c6c0d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/TimingUtils.java
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.time;
-
-import android.text.TextUtils;
-import android.util.LongSparseArray;
-
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Queue;
-import java.util.Stack;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/**
- * Utility class providing timing related utilities. The primary feature is to created {@link
- * ElapsedTimeTracker} instances, which are used to track elapsed time for tasks. The timing
- * information is output to the state dump.
- */
-public class TimingUtils implements Dumpable {
-    private static final String TAG = "TimingUtils";
-    private static final String BACKGROUND_THREAD = "background-";
-    private static final String UI_THREAD = "ui";
-    private static final int MAX_TO_DUMP = 10;
-
-    private static int sBgThreadId = 1;
-
-    private final ThreadUtils mThreadUtils = new ThreadUtils();
-    private final Object mLock = new Object();
-
-    @GuardedBy("mLock")
-    private final Queue<ThreadState> mThreadDumps = new ArrayDeque<>(MAX_TO_DUMP);
-
-    @GuardedBy("mLock")
-    private final LongSparseArray<ThreadStack> mThreadStacks = new LongSparseArray<>();
-
-    /**
-     * ElapsedTimeTracker works similar to Stopwatch. This is used to track elapsed time for some
-     * task. The start time is tracked when the instance is created. {@code stop} is used to capture
-     * the end time and other statistics about the task. The ElapsedTimeTrackers dumped through the
-     * Dumper. A stack is maintained to log sub-tasks with proper indentation in the Dumper.
-     *
-     * <p>The class will dump only the {@code MAX_TO_DUMP} most recent dumps, discarding older dumps
-     * when new dumps are created.
-     *
-     * <p>ElapsedTimeTracker is designed as a one use class, {@code IllegalStateException}s are
-     * thrown if the class isn't used correctly.
-     */
-    public static class ElapsedTimeTracker {
-        private final ThreadStack mThreadStack;
-        private final String mSource;
-
-        private final long mStartTime;
-        private long mEndTime;
-
-        private ElapsedTimeTracker(ThreadStack threadStack, String source) {
-            this.mThreadStack = threadStack;
-            this.mSource = source;
-            mStartTime = System.nanoTime();
-        }
-
-        /**
-         * Capture the end time for the elapsed time. {@code IllegalStateException} is thrown if
-         * stop is called more than once. Arguments are treated as pairs within the Dumper output.
-         *
-         * <p>For example: dumper.forKey(arg[0]).value(arg[1])
-         */
-        public void stop(Object... args) {
-            if (mEndTime > 0) {
-                throw new IllegalStateException("ElapsedTimeTracker has already been stopped.");
-            }
-            mEndTime = System.nanoTime();
-            TrackerState trackerState = new TrackerState(
-                    mEndTime - mStartTime, mSource, args, mThreadStack.mStack.size());
-            mThreadStack.addTrackerState(trackerState);
-            mThreadStack.popElapsedTimeTracker(this);
-        }
-    }
-
-    /**
-     * Return a new {@link ElapsedTimeTracker} which is added to the Thread scoped stack. When we
-     * dump the tracker, we will indent the source to indicate sub-tasks within a larger task.
-     */
-    public ElapsedTimeTracker getElapsedTimeTracker(String source) {
-        long threadId = Thread.currentThread().getId();
-        synchronized (mLock) {
-            ThreadStack timerStack = mThreadStacks.get(threadId);
-            if (timerStack == null) {
-                timerStack = new ThreadStack(
-                        mThreadUtils.isMainThread() ? UI_THREAD : BACKGROUND_THREAD + sBgThreadId++,
-                        false);
-                mThreadStacks.put(threadId, timerStack);
-            }
-            ElapsedTimeTracker timeTracker = new ElapsedTimeTracker(timerStack, source);
-            timerStack.mStack.push(timeTracker);
-            return timeTracker;
-        }
-    }
-
-    /**
-     * This is called to pin the stack structure for a thread. This should only be done for threads
-     * which are long lived. Non-pinned thread will have their stack structures clean up when the
-     * stack is empty.
-     */
-    public void pinThread(Thread thread, String name) {
-        ThreadStack timerStack = new ThreadStack(name, true);
-        synchronized (mLock) {
-            mThreadStacks.put(thread.getId(), timerStack);
-        }
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        synchronized (mLock) {
-            for (ThreadState threadState : mThreadDumps) {
-                dumpThreadState(dumper, threadState);
-            }
-        }
-    }
-
-    private void dumpThreadState(Dumper dumper, ThreadState threadState) {
-        if (threadState.mTrackerStates.isEmpty()) {
-            Logger.w(TAG, "Found Empty TrackerState List");
-            return;
-        }
-        dumper.forKey("thread").value(threadState.mThreadName);
-        dumper.forKey("timeStamp").value(threadState.mDate).compactPrevious();
-        for (int i = threadState.mTrackerStates.size() - 1; i >= 0; i--) {
-            TrackerState trackerState = threadState.mTrackerStates.get(i);
-            Dumper child = dumper.getChildDumper();
-            child.forKey("time", trackerState.mIndent - 1)
-                    .value(trackerState.mDuration / 1000000 + "ms");
-            child.forKey("source").value(trackerState.mSource).compactPrevious();
-            if (trackerState.mArgs != null && trackerState.mArgs.length > 0) {
-                for (int j = 0; j < trackerState.mArgs.length; j++) {
-                    String key = trackerState.mArgs[j++].toString();
-                    Object value = (j < trackerState.mArgs.length) ? trackerState.mArgs[j] : "";
-                    child.forKey(key, trackerState.mIndent - 1)
-                            .valueObject(value)
-                            .compactPrevious();
-                }
-            }
-        }
-    }
-
-    /** Definition of a Stack of {@link ElapsedTimeTracker} instances. */
-    private class ThreadStack {
-        final String mName;
-        final Stack<ElapsedTimeTracker> mStack = new Stack<>();
-        private List<TrackerState> mTrackerStates = new ArrayList<>();
-        final boolean mPin;
-
-        ThreadStack(String name, boolean pin) {
-            this.mName = name;
-            this.mPin = pin;
-        }
-
-        void addTrackerState(TrackerState trackerState) {
-            mTrackerStates.add(trackerState);
-        }
-
-        void popElapsedTimeTracker(ElapsedTimeTracker tracker) {
-            ElapsedTimeTracker top = mStack.peek();
-            if (top != tracker) {
-                int pos = mStack.search(tracker);
-                if (pos == -1) {
-                    Logger.w(TAG, "Trying to Pop non-top of stack timer, ignoring");
-                    return;
-                } else {
-                    int c = 0;
-                    while (mStack.peek() != tracker) {
-                        c++;
-                        mStack.pop();
-                    }
-                    Logger.w(TAG, "Pop TimingTracker which was not the current top, popped % items",
-                            c);
-                }
-            }
-            mStack.pop();
-            if (mStack.isEmpty()) {
-                StringBuilder sb = new StringBuilder();
-                TrackerState ts = mTrackerStates.get(mTrackerStates.size() - 1);
-                for (int i = 0; i < ts.mArgs.length; i++) {
-                    String key = ts.mArgs[i++].toString();
-                    Object value = (i < ts.mArgs.length) ? ts.mArgs[i] : "";
-                    if (!TextUtils.isEmpty(key)) {
-                        sb.append(key).append(" : ").append(value);
-                    } else {
-                        sb.append(value);
-                    }
-                    if ((i + 1) < ts.mArgs.length) {
-                        sb.append(" | ");
-                    }
-                }
-                Logger.i(TAG, "Task Timing %3sms, thread %s | %s",
-                        ((tracker.mEndTime - tracker.mStartTime) / 1000000),
-                        tracker.mThreadStack.mName, sb);
-                synchronized (mLock) {
-                    if (mThreadDumps.size() == MAX_TO_DUMP) {
-                        // Before adding a new tracker state, remove the oldest one.
-                        mThreadDumps.remove();
-                    }
-                    mThreadDumps.add(new ThreadState(mTrackerStates, mName));
-                    mTrackerStates = new ArrayList<>();
-                    if (!mPin) {
-                        mThreadStacks.remove(Thread.currentThread().getId());
-                    }
-                }
-            }
-        }
-    }
-
-    /** State associated with a thread */
-    private static class ThreadState {
-        final List<TrackerState> mTrackerStates;
-        final String mThreadName;
-        final Date mDate;
-
-        ThreadState(List<TrackerState> trackerStates, String threadName) {
-            this.mTrackerStates = trackerStates;
-            this.mThreadName = threadName;
-            mDate = new Date();
-        }
-    }
-
-    /** State associated with a completed ElapsedTimeTracker */
-    private static class TrackerState {
-        final long mDuration;
-        final String mSource;
-        final Object[] mArgs;
-        final int mIndent;
-
-        TrackerState(long duration, String source, Object[] args, int indent) {
-            this.mDuration = duration;
-            this.mSource = source;
-            this.mArgs = args;
-            this.mIndent = indent;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/testing/FakeClock.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/testing/FakeClock.java
deleted file mode 100644
index 08973ae..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/testing/FakeClock.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.time.testing;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.chromium.chrome.browser.feed.library.common.feedobservable.ObservableNotifier;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.common.time.testing.FakeClock.ClockUpdateListener;
-
-/** Fake implementation of {@link Clock} for testing. */
-public class FakeClock extends ObservableNotifier<ClockUpdateListener> implements Clock {
-    private static final String TAG = "FakeClock";
-
-    private long mCurrentTime;
-    private long mElapsedRealtimeMs;
-
-    public FakeClock() {
-        this(0, 0);
-    }
-
-    public FakeClock(long currentTime, long elapsedRealtime) {
-        this.mCurrentTime = currentTime;
-        mElapsedRealtimeMs = elapsedRealtime;
-    }
-
-    /**
-     * Sets the current time and elapsed real time to the same value. Returns {@code this} for
-     * convenience.
-     */
-    public FakeClock set(long millis) {
-        return set(millis, millis);
-    }
-
-    /**
-     * Sets the current time and elapsed real time individually. Returns {@code this} for
-     * convenience.
-     */
-    public FakeClock set(long currentTime, long elapsedRealtime) {
-        this.mCurrentTime = currentTime;
-        mElapsedRealtimeMs = elapsedRealtime;
-        onClockUpdated(currentTime, elapsedRealtime);
-        return this;
-    }
-
-    public void tick() {
-        advance(1);
-    }
-
-    public void advance(long millis) {
-        assertThat(millis).isAtLeast(0L);
-        mCurrentTime += millis;
-        mElapsedRealtimeMs += millis;
-
-        Logger.i(TAG, "Advancing clock to %d", mCurrentTime);
-        onClockUpdated(mCurrentTime, mElapsedRealtimeMs);
-    }
-
-    /**
-     * Advance the clock forward to the specified time. This will fail if {@link currentTimeMillis}
-     * is not the current time or in the future.
-     */
-    public void advanceTo(long currentTimeMillis) {
-        advance(currentTimeMillis - currentTimeMillis());
-    }
-
-    @Override
-    public long currentTimeMillis() {
-        return mCurrentTime;
-    }
-
-    @Override
-    public long elapsedRealtime() {
-        return mElapsedRealtimeMs;
-    }
-
-    @Override
-    public long uptimeMillis() {
-        return mElapsedRealtimeMs;
-    }
-
-    private void onClockUpdated(long currentTime, long elapsedRealtime) {
-        notifyListeners(listener -> listener.onClockUpdated(currentTime, elapsedRealtime));
-    }
-
-    /** Listener for when the clock time is updated. */
-    public interface ClockUpdateListener {
-        void onClockUpdated(long newCurrentTime, long newElapsedRealtime);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/ui/LayoutUtils.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/ui/LayoutUtils.java
deleted file mode 100644
index 9bddac4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/ui/LayoutUtils.java
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.common.ui;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-import android.text.TextUtils;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.View;
-import android.view.ViewGroup.MarginLayoutParams;
-
-import java.util.Locale;
-
-/** General utilities to help with UI layout. */
-public class LayoutUtils {
-    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
-    public static void setMarginsRelative(
-            MarginLayoutParams params, int start, int top, int end, int bottom) {
-        params.setMargins(start, top, end, bottom);
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            params.setMarginStart(start);
-            params.setMarginEnd(end);
-        }
-    }
-
-    /**
-     * Converts DP to PX, where PX represents the actual number of pixels displayed, based on the
-     * density of the phone screen. DP represents density-independent pixels, which are always the
-     * same size, regardless of density.
-     */
-    public static float dpToPx(float dp, Context context) {
-        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
-        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
-    }
-
-    /**
-     * Converts SP to PX, where SP represents scale-independent pixels (a value that scales with
-     * accessibility settings), and PX represents the actual number of pixels displayed, based on
-     * the density of the phone screen.
-     */
-    public static float spToPx(float sp, Context context) {
-        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
-        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, metrics);
-    }
-
-    /**
-     * Converts PX to SP, where SP represents scale-independent pixels (a value that scales with
-     * accessibility settings), and PX represents the actual number of pixels displayed, based on
-     * the density of the phone screen.
-     */
-    public static float pxToSp(float px, Context context) {
-        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
-        return px / metrics.scaledDensity;
-    }
-
-    /**
-     * Converts PX to DP, where PX represents the actual number of pixels displayed, based on the
-     * density of the phone screen. DP represents density-independent pixels, which are always the
-     * same size, regardless of density.
-     */
-    public static float pxToDp(float px, Context context) {
-        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
-        return px / metrics.density;
-    }
-
-    /** Determines whether current locale is RTL. */
-    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
-    public static boolean isDefaultLocaleRtl() {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            return View.LAYOUT_DIRECTION_RTL
-                    == TextUtils.getLayoutDirectionFromLocale(Locale.getDefault());
-        } else {
-            return false;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionmanager/FeedActionManagerImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionmanager/FeedActionManagerImpl.java
deleted file mode 100644
index c7069f6..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionmanager/FeedActionManagerImpl.java
+++ /dev/null
@@ -1,516 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedactionmanager;
-
-import android.graphics.Rect;
-import android.net.Uri;
-import android.util.Base64;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.Log;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.common.Model;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.store.LocalActionMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.LocalActionMutation.ActionType;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.api.internal.store.UploadableActionMutation;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue.TaskType;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.shared.FeedFeatures;
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ScrollListener;
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ScrollListener.ScrollState;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.preferences.Pref;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-import org.chromium.components.feed.core.proto.wire.ActionPayloadProto.ActionPayload;
-import org.chromium.components.user_prefs.UserPrefs;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/** Default implementation of {@link ActionManager} */
-public class FeedActionManagerImpl implements ActionManager {
-    private static final String TAG = "FeedActionManager";
-
-    /**
-     * Exposure is the fraction of card view visible in the viewport. Coverage is the fraction of
-     * the viewport covered by a card view. A card must pass the exposure or coverage threshold to
-     * be considered visible for a VIEW action.
-     */
-    private static final String VIEW_EXPOSURE_THRESHOLD = "view_exposure_threshold";
-    static final double VIEW_EXPOSURE_THRESHOLD_DEFAULT = 0.5;
-    private static final String VIEWPORT_COVERAGE_THRESHOLD = "viewport_coverage_threshold";
-    static final double VIEWPORT_COVERAGE_THRESHOLD_DEFAULT = 0.5;
-
-    /** Time on screen for a card to be considered visible for a VIEW action. */
-    private static final String VIEW_DURATION_MS_THRESHOLD = "view_duration_threshold";
-    static final long VIEW_DURATION_MS_THRESHOLD_DEFAULT = 500;
-
-    private FeedSessionManager mFeedSessionManager;
-    private final Store mStore;
-    private final ThreadUtils mThreadUtils;
-    private final TaskQueue mTaskQueue;
-    private final MainThreadRunner mMainThreadRunner;
-    private final ViewHandler mViewHandler;
-    private final Clock mClock;
-    private final BasicLoggingApi mBasicLoggingApi;
-
-    private View mViewport;
-    // Maps content to the ViewActionData used to decide if a View action needs to be recorded.
-    // ViewActionData contains the payload that needs to be sent back, and a view duration that is
-    // incremented each time the content is considered "visible" in the viewport.
-    private final Map<String, ViewActionData> mContentData = new HashMap<>();
-    // Time when we started tracking the content meeting the visibility conditions (normally this
-    // happens when the viewport becomes stable).
-    private long mTrackedStartTimeMs = -1L;
-
-    private final double mViewExposureThreshold;
-    private final double mViewportCoverageThreshold;
-    private final long mViewDurationMsThreshold;
-
-    private boolean mCanUploadClicksAndViewsWhenNoticePresent;
-
-    FeedActionManagerImpl(Store store, ThreadUtils threadUtils, TaskQueue taskQueue,
-            MainThreadRunner mainThreadRunner, ViewHandler viewHandler, Clock clock,
-            BasicLoggingApi basicLoggingApi) {
-        this.mStore = store;
-        this.mThreadUtils = threadUtils;
-        this.mTaskQueue = taskQueue;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mViewHandler = viewHandler;
-        this.mClock = clock;
-        this.mBasicLoggingApi = basicLoggingApi;
-
-        mViewExposureThreshold = ChromeFeatureList.getFieldTrialParamByFeatureAsDouble(
-                ChromeFeatureList.REPORT_FEED_USER_ACTIONS, VIEW_EXPOSURE_THRESHOLD,
-                VIEW_EXPOSURE_THRESHOLD_DEFAULT);
-        mViewportCoverageThreshold = ChromeFeatureList.getFieldTrialParamByFeatureAsDouble(
-                ChromeFeatureList.REPORT_FEED_USER_ACTIONS, VIEWPORT_COVERAGE_THRESHOLD,
-                VIEWPORT_COVERAGE_THRESHOLD_DEFAULT);
-        mViewDurationMsThreshold = (long) ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.REPORT_FEED_USER_ACTIONS, VIEW_DURATION_MS_THRESHOLD,
-                (int) VIEW_DURATION_MS_THRESHOLD_DEFAULT);
-    }
-
-    public FeedActionManagerImpl(Store store, ThreadUtils threadUtils, TaskQueue taskQueue,
-            MainThreadRunner mainThreadRunner, Clock clock, BasicLoggingApi basicLoggingApi) {
-        this(store, threadUtils, taskQueue, mainThreadRunner, new ViewHandler(), clock,
-                basicLoggingApi);
-    }
-
-    public void initialize(FeedSessionManager feedSessionManager) {
-        mFeedSessionManager = feedSessionManager;
-    }
-
-    @Override
-    public void setCanUploadClicksAndViewsWhenNoticeCardIsPresent(boolean canUploadClicksAndViews) {
-        mCanUploadClicksAndViewsWhenNoticePresent = canUploadClicksAndViews;
-    }
-
-    @Override
-    public void dismissLocal(List<String> contentIds,
-            List<StreamDataOperation> streamDataOperations, @Nullable String sessionId) {
-        executeStreamDataOperations(streamDataOperations, sessionId);
-        // Store the dismissLocal actions
-        mTaskQueue.execute(Task.DISMISS_LOCAL, TaskType.BACKGROUND, () -> {
-            LocalActionMutation localActionMutation = mStore.editLocalActions();
-            for (String contentId : contentIds) {
-                localActionMutation.add(ActionType.DISMISS, contentId);
-            }
-            localActionMutation.commit();
-        });
-    }
-
-    @Override
-    public void dismiss(
-            List<StreamDataOperation> streamDataOperations, @Nullable String sessionId) {
-        executeStreamDataOperations(streamDataOperations, sessionId);
-        mBasicLoggingApi.reportFeedInteraction();
-    }
-
-    @Override
-    public void createAndUploadAction(
-            String contentId, ActionPayload payload, ActionManager.UploadActionType type) {
-        // Don't upload click actions when logging is disabled.
-        if (!canUploadClicksAndViews() && type == ActionManager.UploadActionType.CLICK) {
-            return;
-        }
-
-        mTaskQueue.execute(Task.CREATE_AND_UPLOAD, TaskType.BACKGROUND, () -> {
-            HashSet<StreamUploadableAction> actionSet = new HashSet<>();
-            long currentTime = TimeUnit.MILLISECONDS.toSeconds(mClock.currentTimeMillis());
-            actionSet.add(StreamUploadableAction.newBuilder()
-                                  .setFeatureContentId(contentId)
-                                  .setPayload(payload)
-                                  .setTimestampSeconds(currentTime)
-                                  .build());
-            mFeedSessionManager.triggerUploadActions(actionSet);
-        });
-    }
-
-    @Override
-    public void createAndStoreAction(
-            String contentId, ActionPayload payload, ActionManager.UploadActionType type) {
-        // Don't store click actions when logging is disabled.
-        if (!canUploadClicksAndViews() && type == ActionManager.UploadActionType.CLICK) {
-            return;
-        }
-
-        mTaskQueue.execute(Task.CREATE_AND_STORE, TaskType.BACKGROUND, () -> {
-            long currentTime = TimeUnit.MILLISECONDS.toSeconds(mClock.currentTimeMillis());
-            StreamUploadableAction action = StreamUploadableAction.newBuilder()
-                                                    .setFeatureContentId(contentId)
-                                                    .setPayload(payload)
-                                                    .setTimestampSeconds(currentTime)
-                                                    .build();
-            mStore.editUploadableActions().upsert(action, action.getFeatureContentId()).commit();
-        });
-    }
-
-    @Override
-    public void uploadAllActionsAndUpdateUrl(
-            String url, String consistencyTokenQueryParamName, Consumer<String> consumer) {
-        mTaskQueue.execute(Task.UPLOAD_ALL_ACTIONS_FOR_URL, TaskType.BACKGROUND, () -> {
-            // TODO: figure out spinner and/or timeout conditions
-            mFeedSessionManager.fetchActionsAndUpload(result -> {
-                mMainThreadRunner.execute("Open url", () -> {
-                    if (result.isSuccessful()) {
-                        consumer.accept(updateParam(url, consistencyTokenQueryParamName,
-                                result.getValue().toByteArray()));
-                    } else {
-                        consumer.accept(url);
-                    }
-                });
-            });
-        });
-    }
-
-    static String updateParam(String url, String consistencyTokenQueryParamName, byte[] value) {
-        Uri.Builder uriBuilder = Uri.parse(url).buildUpon();
-        uriBuilder.appendQueryParameter(consistencyTokenQueryParamName,
-                Base64.encodeToString(value, Base64.URL_SAFE | Base64.NO_WRAP));
-        return uriBuilder.build().toString();
-    }
-
-    private void executeStreamDataOperations(
-            List<StreamDataOperation> streamDataOperations, @Nullable String sessionId) {
-        mThreadUtils.checkMainThread();
-
-        MutationContext.Builder mutationContextBuilder =
-                new MutationContext.Builder().setUserInitiated(true);
-        if (sessionId != null) {
-            mutationContextBuilder.setRequestingSessionId(sessionId);
-        }
-        mFeedSessionManager.getUpdateConsumer(mutationContextBuilder.build())
-                .accept(Result.success(Model.of(streamDataOperations)));
-    }
-
-    @Override
-    public void setViewport(@Nullable View viewport) {
-        mThreadUtils.checkMainThread();
-        mViewport = viewport;
-    }
-
-    @Override
-    public void onViewVisible(View view, String contentId, ActionPayload actionPayload) {
-        mThreadUtils.checkMainThread();
-        mViewHandler.setContentId(view, contentId);
-        if (!mContentData.containsKey(contentId)) {
-            mContentData.put(
-                    contentId, ViewActionData.createUntrackedWithZeroDuration(actionPayload));
-        }
-
-        // Viewport may already be stable, so make sure new visible content is tracked if necessary.
-        if (mTrackedStartTimeMs >= 0) maybeTrack(view);
-    }
-
-    @Override
-    public void onViewHidden(View view, String contentId) {
-        mThreadUtils.checkMainThread();
-        // Viewport may already be stable, so make sure hidden content is not tracked.
-        if (mTrackedStartTimeMs >= 0 && mContentData.containsKey(contentId)) {
-            mContentData.get(contentId).tracked = false;
-        }
-
-        /**
-         * Content is not removed from mContentData as we report view actions across multiple
-         * content appearances, until we decide to send a VIEW action to the server.
-         */
-
-        mViewHandler.setContentId(view, null);
-    }
-
-    @Override
-    public void storeViewActions(Runnable doneCallback) {
-        mThreadUtils.checkMainThread();
-        reportViewActions(doneCallback);
-    }
-
-    @Override
-    public ScrollListener getScrollListener() {
-        return new ScrollListener() {
-            @Override
-            public void onScrollStateChanged(int state) {
-                switch (state) {
-                    case ScrollState.DRAGGING:
-                        FeedActionManagerImpl.this.onScrollStart();
-                        break;
-                    case ScrollState.IDLE:
-                        FeedActionManagerImpl.this.onScrollEnd();
-                        break;
-                }
-            }
-
-            @Override
-            public void onScrolled(int dx, int dy) {}
-        };
-    }
-
-    @Override
-    public void onAnimationFinished() {
-        restartStableViewport();
-    }
-
-    @Override
-    public void onLayoutChange() {
-        restartStableViewport();
-    }
-
-    @Override
-    public void onShow() {
-        startStableViewport();
-    }
-
-    @Override
-    public void onHide() {
-        stopStableViewport();
-        reportViewActions(() -> {});
-        mContentData.clear();
-    }
-
-    /**
-     * Signal an {@link
-     * org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll.ScrollObserver#onScrollStateChanged}
-     * that is {@link androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING}
-     */
-    void onScrollStart() {
-        stopStableViewport();
-    }
-
-    /**
-     * Signal an {@link
-     * org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll.ScrollObserver#onScrollStateChanged}
-     * that is {@link androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE}.
-     * Should be called after view actions are triggered so that new tracked views may be monitored.
-     */
-    void onScrollEnd() {
-        startStableViewport();
-    }
-
-    private void startStableViewport() {
-        mThreadUtils.checkMainThread();
-        // No viewport, or viewport already stable.
-        if (mViewport == null || mTrackedStartTimeMs > 0) return;
-
-        mTrackedStartTimeMs = mClock.currentTimeMillis();
-        traverseViewHierarchy(mViewport);
-    }
-
-    private void stopStableViewport() {
-        mThreadUtils.checkMainThread();
-        // Viewport not stable.
-        if (mTrackedStartTimeMs < 0) return;
-
-        long durationMs = mClock.currentTimeMillis() - mTrackedStartTimeMs;
-        for (Map.Entry<String, ViewActionData> entry : mContentData.entrySet()) {
-            if (entry.getValue().tracked) {
-                entry.getValue().durationMs += durationMs;
-            }
-            entry.getValue().tracked = false;
-        }
-
-        mTrackedStartTimeMs = -1L;
-    }
-
-    private void restartStableViewport() {
-        stopStableViewport();
-        startStableViewport();
-    }
-
-    private void traverseViewHierarchy(View view) {
-        maybeTrack(view);
-        for (int index = 0; index < mViewHandler.getChildCount(view); index++) {
-            traverseViewHierarchy(mViewHandler.getChildAt(view, index));
-        }
-    }
-
-    private void maybeTrack(View view) {
-        String contentId = mViewHandler.getContentId(view);
-        if (contentId != null && mViewport != null && isVisibilityConditionMet(view, mViewport)) {
-            if (mContentData.containsKey(contentId)) {
-                mContentData.get(contentId).tracked = true;
-            }
-        }
-    }
-
-    private void reportViewActions(Runnable doneCallback) {
-        // Don't report when logging is disabled.
-        if (!canUploadClicksAndViews()) {
-            return;
-        }
-
-        Set<StreamUploadableAction> actions = new HashSet<>();
-        if (FeedFeatures.isReportingUserActions()) {
-            Iterator<Map.Entry<String, ViewActionData>> entryIterator =
-                    mContentData.entrySet().iterator();
-
-            while (entryIterator.hasNext()) {
-                Map.Entry<String, ViewActionData> entry = entryIterator.next();
-                String contentId = entry.getKey();
-                ViewActionData viewActionData = entry.getValue();
-
-                long currentTimeS = TimeUnit.MILLISECONDS.toSeconds(mClock.currentTimeMillis());
-                if (isDurationConditionMet(viewActionData.durationMs)) {
-                    actions.add(StreamUploadableAction.newBuilder()
-                                        .setFeatureContentId(contentId)
-                                        .setPayload(viewActionData.actionPayload)
-                                        .setDurationMs(viewActionData.durationMs)
-                                        .setTimestampSeconds(currentTimeS)
-                                        .build());
-                    // Stop tracking this particular content as we're already uploading a view
-                    // action for it.
-                    entryIterator.remove();
-                }
-            }
-        }
-        if (actions.isEmpty()) {
-            doneCallback.run();
-        } else {
-            mTaskQueue.execute(Task.STORE_VIEW_ACTIONS, TaskType.IMMEDIATE, () -> {
-                UploadableActionMutation actionMutation = mStore.editUploadableActions();
-                for (StreamUploadableAction action : actions) {
-                    actionMutation.upsert(action, action.getFeatureContentId());
-                }
-                CommitResult commitResult = actionMutation.commit();
-                if (commitResult != CommitResult.SUCCESS) {
-                    Log.d(TAG, "Upserting view actions failed.");
-                }
-                mMainThreadRunner.execute(
-                        "Store view actions callback", () -> { doneCallback.run(); });
-            });
-        }
-    }
-
-    private boolean isVisibilityConditionMet(View view, View viewport) {
-        double exposure = getViewExposure(view, viewport);
-        double coverage = getViewportCoverage(view, viewport);
-        return exposure >= mViewExposureThreshold || coverage >= mViewportCoverageThreshold;
-    }
-
-    private double getViewExposure(View view, View viewport) {
-        Rect viewRect = mViewHandler.getRectOnScreen(view);
-        Rect viewportRect = mViewHandler.getRectOnScreen(viewport);
-
-        double viewArea = viewRect.height() * viewRect.width();
-        if (viewportRect.intersect(viewRect)) { // viewportRect becomes intersection.
-            double visibleArea = viewportRect.height() * viewportRect.width();
-            return visibleArea / viewArea;
-        }
-        return 0;
-    }
-
-    private double getViewportCoverage(View view, View viewport) {
-        Rect viewRect = mViewHandler.getRectOnScreen(view);
-        Rect viewportRect = mViewHandler.getRectOnScreen(viewport);
-
-        double viewportArea = viewportRect.height() * viewportRect.width();
-        if (viewportRect.intersect(viewRect)) { // viewPortRect becomes intersection.
-            double visibleArea = viewportRect.height() * viewportRect.width();
-            return visibleArea / viewportArea;
-        }
-        return 0;
-    }
-
-    private boolean isDurationConditionMet(long durationMs) {
-        return durationMs >= mViewDurationMsThreshold;
-    }
-
-    // Handles logic specific to Views needed for VIEW action tracking.
-    static class ViewHandler {
-        public final void setContentId(View view, @Nullable String contentId) {
-            view.setTag(R.id.tag_view_actions_content_id, contentId);
-        }
-
-        // Retrieve the content ID that may have been previously set on this View.
-        @Nullable
-        public final String getContentId(View view) {
-            return (String) view.getTag(R.id.tag_view_actions_content_id);
-        }
-
-        public int getChildCount(View view) {
-            return view instanceof ViewGroup ? ((ViewGroup) view).getChildCount() : 0;
-        }
-
-        @Nullable
-        public View getChildAt(View view, int index) {
-            return view instanceof ViewGroup ? ((ViewGroup) view).getChildAt(index) : null;
-        }
-
-        // Get the Rect that this View is occupying on screen.
-        public Rect getRectOnScreen(View view) {
-            int[] viewLocation = new int[2];
-            view.getLocationOnScreen(viewLocation);
-            return new Rect(viewLocation[0], viewLocation[1], viewLocation[0] + view.getWidth(),
-                    viewLocation[1] + view.getHeight());
-        }
-    }
-
-    private static class ViewActionData {
-        public final ActionPayload actionPayload;
-        public long durationMs;
-        public boolean tracked;
-
-        private ViewActionData(ActionPayload actionPayload, long durationMs, boolean tracked) {
-            this.actionPayload = actionPayload;
-            this.durationMs = durationMs;
-            this.tracked = tracked;
-        }
-
-        public static ViewActionData createUntrackedWithZeroDuration(ActionPayload actionPayload) {
-            return new ViewActionData(actionPayload, 0L, false);
-        }
-    }
-
-    private boolean canUploadClicksAndViews() {
-        if (!ChromeFeatureList.isEnabled(
-                    ChromeFeatureList.INTEREST_FEEDV1_CLICKS_AND_VIEWS_CONDITIONAL_UPLOAD)) {
-            return true;
-        }
-        boolean wasNoticePresent = UserPrefs.get(Profile.getLastUsedRegularProfile())
-                                           .getBoolean(Pref.LAST_FETCH_HAD_NOTICE_CARD);
-        return mCanUploadClicksAndViewsWhenNoticePresent || !wasNoticePresent;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParser.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParser.java
deleted file mode 100644
index 60e4f0095..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParser.java
+++ /dev/null
@@ -1,346 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedactionparser;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-import static org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type.BLOCK_CONTENT;
-import static org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type.DOWNLOAD;
-import static org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type.LEARN_MORE;
-import static org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type.MANAGE_INTERESTS;
-import static org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type.OPEN_URL;
-import static org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type.OPEN_URL_INCOGNITO;
-import static org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type.OPEN_URL_NEW_TAB;
-import static org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type.OPEN_URL_NEW_WINDOW;
-import static org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type.REPORT_VIEW;
-
-import android.view.View;
-
-import org.chromium.base.Log;
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.ContentMetadata;
-import org.chromium.chrome.browser.feed.library.api.host.action.StreamActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.InternalFeedError;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionParser;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionSource;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.feedactionparser.internal.ActionTypesConverter;
-import org.chromium.chrome.browser.feed.library.feedactionparser.internal.PietFeedActionPayloadRetriever;
-import org.chromium.chrome.browser.feed.library.feedactionparser.internal.TooltipInfoImpl;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionPayloadProto.FeedActionPayload;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedAction;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.OpenUrlData;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.ViewReportData;
-import org.chromium.components.feed.core.proto.ui.piet.ActionsProto.Action;
-import org.chromium.components.feed.core.proto.ui.piet.LogDataProto.LogData;
-
-/**
- * Action parser which is able to parse Feed actions and notify clients about which action needs to
- * be performed.
- */
-public final class FeedActionParser implements ActionParser {
-    private static final String TAG = "FeedActionParser";
-    static final String EXPECTED_MANAGE_INTERESTS_URL =
-            "https://www.google.com/preferences/interests";
-
-    private final PietFeedActionPayloadRetriever mPietFeedActionPayloadRetriever;
-    private final ProtocolAdapter mProtocolAdapter;
-    private final Supplier<ContentMetadata> mContentMetadata;
-    private final BasicLoggingApi mBasicLoggingApi;
-
-    FeedActionParser(ProtocolAdapter protocolAdapter,
-            PietFeedActionPayloadRetriever pietFeedActionPayloadRetriever,
-            Supplier<ContentMetadata> contentMetadata, BasicLoggingApi basicLoggingApi) {
-        this.mProtocolAdapter = protocolAdapter;
-        this.mPietFeedActionPayloadRetriever = pietFeedActionPayloadRetriever;
-        this.mContentMetadata = contentMetadata;
-        this.mBasicLoggingApi = basicLoggingApi;
-    }
-
-    @Override
-    public void parseAction(Action action, StreamActionApi streamActionApi, View view,
-            LogData logData, @ActionSource int actionSource) {
-        FeedActionPayload feedActionPayload =
-                mPietFeedActionPayloadRetriever.getFeedActionPayload(action);
-        if (feedActionPayload == null) {
-            Logger.w(TAG, "Unable to get FeedActionPayload from PietFeedActionPayloadRetriever");
-            return;
-        }
-        parseFeedActionPayload(feedActionPayload, streamActionApi, view, actionSource);
-    }
-
-    @Override
-    public void parseFeedActionPayload(FeedActionPayload feedActionPayload,
-            StreamActionApi streamActionApi, View view, @ActionSource int actionSource) {
-        FeedActionMetadata feedActionMetadata =
-                feedActionPayload.getExtension(FeedAction.feedActionExtension).getMetadata();
-        switch (feedActionMetadata.getType()) {
-            case OPEN_URL:
-            case OPEN_URL_NEW_WINDOW:
-            case OPEN_URL_INCOGNITO:
-            case OPEN_URL_NEW_TAB:
-                // TODO(freedjm): Use a different action type for Manage Interests to handle it
-                // separately from a simple OPEN_URL action.
-                if (feedActionMetadata.getOpenUrlData().hasUrl()
-                        && feedActionMetadata.getOpenUrlData().getUrl().equals(
-                                EXPECTED_MANAGE_INTERESTS_URL)) {
-                    streamActionApi.onClientAction(ActionTypesConverter.convert(MANAGE_INTERESTS));
-                }
-                handleOpenUrl(feedActionMetadata.getType(), feedActionMetadata.getOpenUrlData(),
-                        streamActionApi);
-                break;
-            case OPEN_CONTEXT_MENU:
-                if (!streamActionApi.canOpenContextMenu()) {
-                    Logger.e(TAG, "Cannot open context menu: StreamActionApi does not support it.");
-                    break;
-                }
-
-                if (!feedActionMetadata.hasOpenContextMenuData()) {
-                    Logger.e(TAG, "Cannot open context menu: does not have context menu data.");
-                    break;
-                }
-
-                streamActionApi.openContextMenu(feedActionMetadata.getOpenContextMenuData(), view);
-                break;
-            case DISMISS:
-            case DISMISS_LOCAL:
-                if (!streamActionApi.canDismiss()) {
-                    Logger.e(TAG, "Cannot dismiss: StreamActionApi does not support it.");
-                    return;
-                }
-
-                if (!feedActionMetadata.getDismissData().hasContentId()) {
-                    Logger.e(TAG, "Cannot dismiss: no Content Id");
-                    return;
-                }
-
-                // TODO: Once we start logging DISMISS via the feed action end point, DISMISS
-                // and DISMISS_LOCAL should not be handled in the exact same way.
-                streamActionApi.dismiss(mProtocolAdapter.getStreamContentId(
-                                                feedActionMetadata.getDismissData().getContentId()),
-                        mProtocolAdapter.createOperations(
-                                feedActionMetadata.getDismissData().getDataOperationsList()),
-                        feedActionMetadata.getDismissData().getUndoAction(),
-                        feedActionMetadata.getDismissData().getPayload());
-
-                break;
-            case NOT_INTERESTED_IN:
-                if (!streamActionApi.canHandleNotInterestedIn()) {
-                    Logger.e(TAG,
-                            "Cannot preform action not interested in action: StreamActionApi does"
-                                    + " not support it.");
-                    return;
-                }
-                streamActionApi.handleNotInterestedIn(
-                        mProtocolAdapter.createOperations(
-                                feedActionMetadata.getNotInterestedInData()
-                                        .getDataOperationsList()),
-                        feedActionMetadata.getNotInterestedInData().getUndoAction(),
-                        feedActionMetadata.getNotInterestedInData().getPayload(),
-                        feedActionMetadata.getNotInterestedInData().getInterestTypeValue());
-                break;
-
-            case DOWNLOAD:
-                if (!streamActionApi.canDownloadUrl()) {
-                    Logger.e(TAG, "Cannot download: StreamActionApi does not support it");
-                    break;
-                }
-                ContentMetadata contentMetadata = this.mContentMetadata.get();
-                if (contentMetadata == null) {
-                    Logger.e(TAG, " Cannot download: no ContentMetadata");
-                    break;
-                }
-
-                streamActionApi.downloadUrl(contentMetadata);
-                streamActionApi.onClientAction(ActionTypesConverter.convert(DOWNLOAD));
-                break;
-            case LEARN_MORE:
-                if (!streamActionApi.canLearnMore()) {
-                    Logger.e(TAG, "Cannot learn more: StreamActionApi does not support it");
-                    break;
-                }
-
-                streamActionApi.learnMore();
-                streamActionApi.onClientAction(ActionTypesConverter.convert(LEARN_MORE));
-                break;
-            case VIEW_ELEMENT:
-                if (!streamActionApi.canHandleElementView()) {
-                    Logger.e(TAG, "Cannot log Element View: StreamActionApi does not support it");
-                    break;
-                } else if (!feedActionMetadata.hasElementTypeValue()) {
-                    Logger.e(TAG, "Cannot log ElementView : no Element Type");
-                    break;
-                }
-                streamActionApi.onElementView(feedActionMetadata.getElementTypeValue());
-                break;
-            case HIDE_ELEMENT:
-                if (!streamActionApi.canHandleElementHide()) {
-                    Logger.e(TAG, "Cannot log Element Hide: StreamActionApi does not support it");
-                    break;
-                } else if (!feedActionMetadata.hasElementTypeValue()) {
-                    Logger.e(TAG, "Cannot log Element Hide : no Element Type");
-                    break;
-                }
-                streamActionApi.onElementHide(feedActionMetadata.getElementTypeValue());
-                break;
-            case SHOW_TOOLTIP:
-                if (!streamActionApi.canShowTooltip()) {
-                    Logger.e(
-                            TAG, "Cannot try to show tooltip: StreamActionApi does not support it");
-                    break;
-                }
-                streamActionApi.maybeShowTooltip(
-                        new TooltipInfoImpl(feedActionMetadata.getTooltipData()), view);
-                break;
-            case SEND_FEEDBACK:
-                Log.d(TAG, "SendFeedback menu item clicked.");
-                streamActionApi.sendFeedback(this.mContentMetadata.get());
-                break;
-            case BLOCK_CONTENT:
-                streamActionApi.handleBlockContent(
-                        mProtocolAdapter.createOperations(
-                                feedActionMetadata.getBlockContentData().getDataOperationsList()),
-                        feedActionMetadata.getBlockContentData().getPayload());
-                streamActionApi.onClientAction(ActionTypesConverter.convert(BLOCK_CONTENT));
-                break;
-            case REPORT_VIEW:
-                ViewReportData viewReportData = feedActionMetadata.getViewReportData();
-                String contentId =
-                        mProtocolAdapter.getStreamContentId(viewReportData.getContentId());
-                switch (viewReportData.getVisibility()) {
-                    case SHOW:
-                        streamActionApi.reportViewVisible(
-                                view, contentId, viewReportData.getPayload());
-                        break;
-                    case HIDE:
-                        streamActionApi.reportViewHidden(view, contentId);
-                        break;
-                    default:
-                        Log.d(TAG, "Unrecognized view report data visibility.");
-                }
-                break;
-            default:
-                Logger.wtf(TAG, "Haven't implemented host handling of %s",
-                        feedActionMetadata.getType());
-        }
-        if (actionSource == ActionSource.CLICK) {
-            if (!streamActionApi.canHandleElementClick()) {
-                Logger.e(TAG, "Cannot log Element Click: StreamActionApi does not support it");
-            } else if (!feedActionMetadata.hasElementTypeValue()) {
-                Logger.e(TAG, "Cannot log Element Click: no Element Type");
-            } else {
-                streamActionApi.onElementClick(feedActionMetadata.getElementTypeValue());
-            }
-        }
-    }
-
-    private void handleOpenUrl(
-            Type urlType, OpenUrlData openUrlData, StreamActionApi streamActionApi) {
-        checkState(urlType.equals(OPEN_URL) || urlType.equals(OPEN_URL_NEW_WINDOW)
-                        || urlType.equals(OPEN_URL_INCOGNITO) || urlType.equals(OPEN_URL_NEW_TAB),
-                "Attempting to handle URL that is not a URL type: %s", urlType);
-        if (!canPerformAction(urlType, streamActionApi)) {
-            Logger.e(TAG, "Cannot open URL action: %s, not supported.", urlType);
-            return;
-        }
-
-        if (!openUrlData.hasUrl()) {
-            mBasicLoggingApi.onInternalError(InternalFeedError.NO_URL_FOR_OPEN);
-            Logger.e(TAG, "Cannot open URL action: %s, no URL available.", urlType);
-            return;
-        }
-
-        if (urlType != OPEN_URL_INCOGNITO && openUrlData.hasContentId()
-                && openUrlData.hasPayload()) {
-            streamActionApi.reportClickAction(
-                    mProtocolAdapter.getStreamContentId(openUrlData.getContentId()),
-                    openUrlData.getPayload());
-        }
-
-        String url = openUrlData.getUrl();
-        switch (urlType) {
-            case OPEN_URL:
-                if (openUrlData.hasConsistencyTokenQueryParamName()) {
-                    streamActionApi.openUrl(url, openUrlData.getConsistencyTokenQueryParamName());
-                } else {
-                    streamActionApi.openUrl(url);
-                }
-                break;
-            case OPEN_URL_NEW_WINDOW:
-                if (openUrlData.hasConsistencyTokenQueryParamName()) {
-                    streamActionApi.openUrlInNewWindow(
-                            url, openUrlData.getConsistencyTokenQueryParamName());
-                } else {
-                    streamActionApi.openUrlInNewWindow(url);
-                }
-                break;
-            case OPEN_URL_INCOGNITO:
-                if (openUrlData.hasConsistencyTokenQueryParamName()) {
-                    streamActionApi.openUrlInIncognitoMode(
-                            url, openUrlData.getConsistencyTokenQueryParamName());
-                } else {
-                    streamActionApi.openUrlInIncognitoMode(url);
-                }
-                break;
-            case OPEN_URL_NEW_TAB:
-                if (openUrlData.hasConsistencyTokenQueryParamName()) {
-                    streamActionApi.openUrlInNewTab(
-                            url, openUrlData.getConsistencyTokenQueryParamName());
-                } else {
-                    streamActionApi.openUrlInNewTab(url);
-                }
-                break;
-            default:
-                throw new AssertionError("Unhandled URL type: " + urlType);
-        }
-        streamActionApi.onClientAction(ActionTypesConverter.convert(urlType));
-    }
-
-    @Override
-    public boolean canPerformAction(
-            FeedActionPayload feedActionPayload, StreamActionApi streamActionApi) {
-        return canPerformAction(feedActionPayload.getExtension(FeedAction.feedActionExtension)
-                                        .getMetadata()
-                                        .getType(),
-                streamActionApi);
-    }
-
-    private boolean canPerformAction(Type type, StreamActionApi streamActionApi) {
-        switch (type) {
-            case OPEN_URL:
-                return streamActionApi.canOpenUrl();
-            case OPEN_URL_NEW_WINDOW:
-                return streamActionApi.canOpenUrlInNewWindow();
-            case OPEN_URL_INCOGNITO:
-                return streamActionApi.canOpenUrlInIncognitoMode();
-            case OPEN_URL_NEW_TAB:
-                return streamActionApi.canOpenUrlInNewTab();
-            case OPEN_CONTEXT_MENU:
-                return streamActionApi.canOpenContextMenu();
-            case DISMISS:
-            case DISMISS_LOCAL:
-                // TODO: Once we start logging DISMISS via the feed action end point, DISMISS
-                // and DISMISS_LOCAL should not be handled in the exact same way.
-                return streamActionApi.canDismiss();
-            case DOWNLOAD:
-                return mContentMetadata.get() != null && streamActionApi.canDownloadUrl();
-            case LEARN_MORE:
-                return streamActionApi.canLearnMore();
-            case NOT_INTERESTED_IN:
-                return streamActionApi.canHandleNotInterestedIn();
-            // Send Feedback for the feed is available in M81 and later.
-            case SEND_FEEDBACK:
-                return true;
-            case UNKNOWN:
-            default:
-                // TODO : Handle the action types introduced in [INTERNAL LINK]
-        }
-        Logger.e(TAG, "Unhandled feed action type: %s", type);
-        return false;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParserFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParserFactory.java
deleted file mode 100644
index 86f3a1b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParserFactory.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedactionparser;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.ContentMetadata;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionParser;
-import org.chromium.chrome.browser.feed.library.api.internal.actionparser.ActionParserFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.feedactionparser.internal.PietFeedActionPayloadRetriever;
-
-/** Default factory for the default {@link ActionParser} implementation. */
-public final class FeedActionParserFactory implements ActionParserFactory {
-    private final ProtocolAdapter mProtocolAdapter;
-    private final PietFeedActionPayloadRetriever mPietFeedActionPayloadRetriever;
-    private final BasicLoggingApi mBasicLoggingApi;
-
-    public FeedActionParserFactory(
-            ProtocolAdapter protocolAdapter, BasicLoggingApi basicLoggingApi) {
-        this.mProtocolAdapter = protocolAdapter;
-        this.mPietFeedActionPayloadRetriever = new PietFeedActionPayloadRetriever();
-        this.mBasicLoggingApi = basicLoggingApi;
-    }
-
-    @Override
-    public ActionParser build(Supplier<ContentMetadata> contentMetadataSupplier) {
-        return new FeedActionParser(mProtocolAdapter, mPietFeedActionPayloadRetriever,
-                contentMetadataSupplier, mBasicLoggingApi);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/ActionTypesConverter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/ActionTypesConverter.java
deleted file mode 100644
index 275f90f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/ActionTypesConverter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedactionparser.internal;
-
-import org.chromium.chrome.browser.feed.library.api.host.logging.ActionType;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.FeedActionMetadata.Type;
-
-/** Utility class to convert a {@link Type} to {@link ActionType}. */
-public final class ActionTypesConverter {
-    private ActionTypesConverter() {}
-
-    @ActionType
-    public static int convert(Type type) {
-        // LINT.IfChange
-        switch (type) {
-            case OPEN_URL:
-                return ActionType.OPEN_URL;
-            case OPEN_URL_INCOGNITO:
-                return ActionType.OPEN_URL_INCOGNITO;
-            case OPEN_URL_NEW_TAB:
-                return ActionType.OPEN_URL_NEW_TAB;
-            case OPEN_URL_NEW_WINDOW:
-                return ActionType.OPEN_URL_NEW_WINDOW;
-            case DOWNLOAD:
-                return ActionType.DOWNLOAD;
-            case LEARN_MORE:
-                return ActionType.LEARN_MORE;
-            case MANAGE_INTERESTS:
-                return ActionType.MANAGE_INTERESTS;
-            case BLOCK_CONTENT:
-                return ActionType.BLOCK_CONTENT;
-            default:
-                return ActionType.UNKNOWN;
-        }
-        // LINT.ThenChange
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/PietFeedActionPayloadRetriever.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/PietFeedActionPayloadRetriever.java
deleted file mode 100644
index 03fa996..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/PietFeedActionPayloadRetriever.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedactionparser.internal;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionPayloadProto.FeedActionPayload;
-import org.chromium.components.feed.core.proto.ui.action.PietExtensionsProto.PietFeedActionPayload;
-import org.chromium.components.feed.core.proto.ui.piet.ActionsProto.Action;
-
-/** Class which is able to retrieve FeedActions from Piet actions */
-public final class PietFeedActionPayloadRetriever {
-    private static final String TAG = "PietFAPRetriever";
-
-    /**
-     * Gets the feed action from a Piet Action.
-     *
-     * @param action the Piet Action to pull the feed action metadata out of.
-     */
-    @Nullable
-    public FeedActionPayload getFeedActionPayload(Action action) {
-        @Nullable
-        PietFeedActionPayload feedActionPayloadExtension =
-                action.getExtension(PietFeedActionPayload.pietFeedActionPayloadExtension);
-        if (feedActionPayloadExtension != null
-                && feedActionPayloadExtension.hasFeedActionPayload()) {
-            return feedActionPayloadExtension.getFeedActionPayload();
-        }
-        Logger.e(TAG, "FeedActionExtension was null or did not contain a feed action payload");
-        return null;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/TooltipInfoImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/TooltipInfoImpl.java
deleted file mode 100644
index 8b96055..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/TooltipInfoImpl.java
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedactionparser.internal;
-
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipInfo;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto.TooltipData;
-
-/**
- * Implementation for {@link TooltipInfo} that converts a {@link TooltipData} to {@link
- * TooltipInfo}.
- */
-public class TooltipInfoImpl implements TooltipInfo {
-    private final String mLabel;
-    private final String mAccessibilityLabel;
-    @FeatureName
-    private final String mFeatureName;
-    private final int mTopInset;
-    private final int mBottomInset;
-
-    public TooltipInfoImpl(TooltipData tooltipData) {
-        this.mLabel = tooltipData.getLabel();
-        this.mAccessibilityLabel = tooltipData.getAccessibilityLabel();
-        this.mFeatureName = convert(tooltipData.getFeatureName());
-        this.mTopInset = tooltipData.getInsets().getTop();
-        this.mBottomInset = tooltipData.getInsets().getBottom();
-    }
-
-    /** Converts the type in {@link TooltipData#FeatureName} to {@link TooltipInfo#FeatureName}. */
-    @FeatureName
-    private static String convert(TooltipData.FeatureName featureName) {
-        return (featureName == TooltipData.FeatureName.CARD_MENU) ? FeatureName.CARD_MENU_TOOLTIP
-                                                                  : FeatureName.UNKNOWN;
-    }
-
-    @Override
-    public String getLabel() {
-        return mLabel;
-    }
-
-    @Override
-    public String getAccessibilityLabel() {
-        return mAccessibilityLabel;
-    }
-
-    @Override
-    @FeatureName
-    public String getFeatureName() {
-        return mFeatureName;
-    }
-
-    @Override
-    public int getTopInset() {
-        return mTopInset;
-    }
-
-    @Override
-    public int getBottomInset() {
-        return mBottomInset;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionreader/FeedActionReader.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionreader/FeedActionReader.java
deleted file mode 100644
index d5ced5c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionreader/FeedActionReader.java
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedactionreader;
-
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionReader;
-import org.chromium.chrome.browser.feed.library.api.internal.common.DismissActionWithSemanticProperties;
-import org.chromium.chrome.browser.feed.library.api.internal.common.SemanticPropertiesWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue.TaskType;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamLocalAction;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/** Feed implementation of {@link ActionReader} */
-public final class FeedActionReader implements ActionReader {
-    private static final String TAG = "FeedActionReader";
-
-    private final Store mStore;
-    private final Clock mClock;
-    private final ProtocolAdapter mProtocolAdapter;
-    private final TaskQueue mTaskQueue;
-    private final long mDismissActionTTLSeconds;
-    private final double mMinValidActionRatio;
-
-    public FeedActionReader(Store store, Clock clock, ProtocolAdapter protocolAdapter,
-            TaskQueue taskQueue, Configuration configuration) {
-        this.mStore = store;
-        this.mClock = clock;
-        this.mProtocolAdapter = protocolAdapter;
-        this.mTaskQueue = taskQueue;
-        this.mDismissActionTTLSeconds = configuration.getValueOrDefault(
-                ConfigKey.DEFAULT_ACTION_TTL_SECONDS, TimeUnit.DAYS.toSeconds(3L));
-        mMinValidActionRatio =
-                configuration.getValueOrDefault(ConfigKey.MINIMUM_VALID_ACTION_RATIO, 0.3);
-    }
-
-    @Override
-    public Result<List<DismissActionWithSemanticProperties>>
-    getDismissActionsWithSemanticProperties() {
-        Result<List<StreamLocalAction>> dismissActionsResult = mStore.getAllDismissLocalActions();
-        if (!dismissActionsResult.isSuccessful()) {
-            Logger.e(TAG, "Error fetching dismiss actions from store");
-            return Result.failure();
-        }
-        List<StreamLocalAction> dismissActions = dismissActionsResult.getValue();
-        Set<String> contentIds = new HashSet<>(dismissActions.size());
-        long minValidTime = TimeUnit.MILLISECONDS.toSeconds(mClock.currentTimeMillis())
-                - mDismissActionTTLSeconds;
-        for (StreamLocalAction dismissAction : dismissActions) {
-            if (dismissAction.getTimestampSeconds() > minValidTime) {
-                contentIds.add(dismissAction.getFeatureContentId());
-            }
-        }
-
-        // Clean up if necessary
-        // Note that since we're using a Set, it's possible this will trigger prematurely due to
-        // duplicates not being counted as valid.
-        if ((double) contentIds.size() / dismissActions.size() < mMinValidActionRatio) {
-            mTaskQueue.execute(Task.LOCAL_ACTION_GC, TaskType.BACKGROUND,
-                    mStore.triggerLocalActionGc(dismissActions, new ArrayList<>(contentIds)));
-        }
-
-        Result<List<SemanticPropertiesWithId>> semanticPropertiesResult =
-                mStore.getSemanticProperties(new ArrayList<>(contentIds));
-        if (!semanticPropertiesResult.isSuccessful()) {
-            return Result.failure();
-        }
-        List<DismissActionWithSemanticProperties> dismissActionWithSemanticProperties =
-                new ArrayList<>(contentIds.size());
-
-        for (SemanticPropertiesWithId semanticPropertiesWithId :
-                semanticPropertiesResult.getValue()) {
-            Result<ContentId> wireContentIdResult =
-                    mProtocolAdapter.getWireContentId(semanticPropertiesWithId.contentId);
-            if (!wireContentIdResult.isSuccessful()) {
-                Logger.e(TAG, "Error converting to wire result for contentId: %s",
-                        semanticPropertiesWithId.contentId);
-                continue;
-            }
-            dismissActionWithSemanticProperties.add(new DismissActionWithSemanticProperties(
-                    wireContentIdResult.getValue(), semanticPropertiesWithId.semanticData));
-            // Also strip out from the content ids list (so that we can put those in with null
-            // semantic properties
-            contentIds.remove(semanticPropertiesWithId.contentId);
-        }
-        for (String contentId : contentIds) {
-            Result<ContentId> wireContentIdResult = mProtocolAdapter.getWireContentId(contentId);
-            if (!wireContentIdResult.isSuccessful()) {
-                Logger.e(TAG, "Error converting to wire result for contentId: %s", contentId);
-                continue;
-            }
-            dismissActionWithSemanticProperties.add(
-                    new DismissActionWithSemanticProperties(wireContentIdResult.getValue(), null));
-        }
-        return Result.success(dismissActionWithSemanticProperties);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedapplifecyclelistener/FeedAppLifecycleListener.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedapplifecyclelistener/FeedAppLifecycleListener.java
deleted file mode 100644
index a9d2982..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedapplifecyclelistener/FeedAppLifecycleListener.java
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedapplifecyclelistener;
-
-import org.chromium.chrome.browser.feed.library.api.client.lifecycle.AppLifecycleListener;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.common.feedobservable.FeedObservable;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.feedapplifecyclelistener.FeedLifecycleListener.LifecycleEvent;
-
-/** Default implementation of {@link AppLifecycleListener} */
-public final class FeedAppLifecycleListener
-        extends FeedObservable<FeedLifecycleListener> implements AppLifecycleListener {
-    private static final String TAG = "FeedAppLifecycleLstnr";
-
-    private final ThreadUtils mThreadUtils;
-
-    public FeedAppLifecycleListener(ThreadUtils threadUtils) {
-        this.mThreadUtils = threadUtils;
-    }
-
-    @Override
-    public void onEnterForeground() {
-        mThreadUtils.checkMainThread();
-        Logger.i(TAG, "onEnterForeground called");
-        dispatchLifecycleEvent(LifecycleEvent.ENTER_FOREGROUND);
-    }
-
-    @Override
-    public void onEnterBackground() {
-        mThreadUtils.checkMainThread();
-        Logger.i(TAG, "onEnterBackground called");
-        dispatchLifecycleEvent(LifecycleEvent.ENTER_BACKGROUND);
-    }
-
-    @Override
-    public void onClearAll() {
-        Logger.i(TAG, "onClearAll called");
-        mThreadUtils.checkMainThread();
-        dispatchLifecycleEvent(LifecycleEvent.CLEAR_ALL);
-    }
-
-    @Override
-    public void onClearAllWithRefresh() {
-        mThreadUtils.checkMainThread();
-        Logger.i(TAG, "onClearAllWithRefresh called");
-        dispatchLifecycleEvent(LifecycleEvent.CLEAR_ALL_WITH_REFRESH);
-    }
-
-    @Override
-    public void onSignedIn() {
-        mThreadUtils.checkMainThread();
-        dispatchLifecycleEvent(LifecycleEvent.SIGNED_IN);
-    }
-
-    @Override
-    public void onSignedOut() {
-        mThreadUtils.checkMainThread();
-        dispatchLifecycleEvent(LifecycleEvent.SIGNED_OUT);
-    }
-
-    @Override
-    public void initialize() {
-        mThreadUtils.checkMainThread();
-        Logger.i(TAG, "initialize called");
-        dispatchLifecycleEvent(LifecycleEvent.INITIALIZE);
-    }
-
-    private void dispatchLifecycleEvent(@LifecycleEvent String event) {
-        synchronized (mObservers) {
-            for (FeedLifecycleListener listener : mObservers) {
-                listener.onLifecycleEvent(event);
-            }
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedapplifecyclelistener/FeedLifecycleListener.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedapplifecyclelistener/FeedLifecycleListener.java
deleted file mode 100644
index cd8032e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedapplifecyclelistener/FeedLifecycleListener.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedapplifecyclelistener;
-
-import androidx.annotation.StringDef;
-
-/**
- * Internal interface used to register Feed components with the {@link FeedAppLifecycleListener},
- * which is used by consuming hosts to communicate app lifecycle events to the Feed Library.
- */
-public interface FeedLifecycleListener {
-    /** The types of lifecycle events. */
-    @StringDef({LifecycleEvent.ENTER_FOREGROUND, LifecycleEvent.ENTER_BACKGROUND,
-            LifecycleEvent.CLEAR_ALL, LifecycleEvent.CLEAR_ALL_WITH_REFRESH,
-            LifecycleEvent.INITIALIZE, LifecycleEvent.SIGNED_IN, LifecycleEvent.SIGNED_OUT})
-    @interface LifecycleEvent {
-        String ENTER_FOREGROUND = "foreground";
-        String ENTER_BACKGROUND = "background";
-        String CLEAR_ALL = "clearAll";
-        String CLEAR_ALL_WITH_REFRESH = "clearAllWithRefresh";
-        String INITIALIZE = "initialize";
-        String SIGNED_IN = "signedIn";
-        String SIGNED_OUT = "signedOut";
-    }
-
-    void onLifecycleEvent(@LifecycleEvent String event);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedknowncontent/FeedKnownContentImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedknowncontent/FeedKnownContentImpl.java
deleted file mode 100644
index 8049dad..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedknowncontent/FeedKnownContentImpl.java
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedknowncontent;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.ContentMetadata;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.ContentRemoval;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.KnownContent;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.knowncontent.FeedKnownContent;
-import org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.Content;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/** Default implementation of the {@link KnownContent}. */
-public final class FeedKnownContentImpl implements FeedKnownContent {
-    private static final String TAG = "FeedKnownContentImpl";
-    private final FeedSessionManager mFeedSessionManager;
-    private final Set<KnownContent.Listener> mListeners = new HashSet<>();
-    private final MainThreadRunner mMainThreadRunner;
-    private final ThreadUtils mThreadUtils;
-    private final KnownContent.Listener mListener;
-
-    @SuppressWarnings("nullness:method.invocation.invalid")
-    public FeedKnownContentImpl(FeedSessionManager feedSessionManager,
-            MainThreadRunner mainThreadRunner, ThreadUtils threadUtils) {
-        this.mFeedSessionManager = feedSessionManager;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mThreadUtils = threadUtils;
-
-        this.mListener = new KnownContent.Listener() {
-            @Override
-            public void onContentRemoved(List<ContentRemoval> contentRemoved) {
-                runOnMainThread(TAG + " onContentRemoved", () -> {
-                    for (KnownContent.Listener knownContentListener : mListeners) {
-                        knownContentListener.onContentRemoved(contentRemoved);
-                    }
-                });
-            }
-
-            @Override
-            public void onNewContentReceived(boolean isNewRefresh, long contentCreationDateTimeMs) {
-                runOnMainThread(TAG + " onNewContentReceived", () -> {
-                    for (KnownContent.Listener knownContentListener : mListeners) {
-                        knownContentListener.onNewContentReceived(
-                                isNewRefresh, contentCreationDateTimeMs);
-                    }
-                });
-            }
-        };
-
-        feedSessionManager.setKnownContentListener(this.mListener);
-    }
-
-    @Override
-    public void getKnownContent(Consumer<List<ContentMetadata>> knownContentConsumer) {
-        mFeedSessionManager.getStreamFeaturesFromHead(
-                streamPayload
-                -> {
-                    if (!streamPayload.getStreamFeature().hasContent()) {
-                        return null;
-                    }
-
-                    Content content = streamPayload.getStreamFeature().getContent();
-
-                    return ContentMetadata.maybeCreateContentMetadata(
-                            content.getOfflineMetadata(), content.getRepresentationData());
-                },
-                (Result<List<ContentMetadata>> result) -> {
-                    runOnMainThread(TAG + " getKnownContentAccept", () -> {
-                        if (!result.isSuccessful()) {
-                            Logger.e(TAG,
-                                    "Can't inform on known content due to internal feed error.");
-                            return;
-                        }
-
-                        knownContentConsumer.accept(result.getValue());
-                    });
-                });
-    }
-
-    @Override
-    public void addListener(KnownContent.Listener listener) {
-        mListeners.add(listener);
-    }
-
-    @Override
-    public void removeListener(KnownContent.Listener listener) {
-        mListeners.remove(listener);
-    }
-
-    @Override
-    public KnownContent.Listener getKnownContentHostNotifier() {
-        return mListener;
-    }
-
-    private void runOnMainThread(String name, Runnable runnable) {
-        if (mThreadUtils.isMainThread()) {
-            runnable.run();
-            return;
-        }
-
-        mMainThreadRunner.execute(name, runnable);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/FeedModelProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/FeedModelProvider.java
deleted file mode 100644
index 03a0bfe..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/FeedModelProvider.java
+++ /dev/null
@@ -1,1384 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedmodelprovider;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import com.google.protobuf.ByteString;
-
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.InternalFeedError;
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.FeatureChange;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.FeatureChangeObserver;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild.Type;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelError;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelError.ErrorType;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProviderObserver;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelToken;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.RemoveTracking;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.TokenCompleted;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.TokenCompletedObserver;
-import org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager;
-import org.chromium.chrome.browser.feed.library.common.Validators;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue.TaskType;
-import org.chromium.chrome.browser.feed.library.common.feedobservable.FeedObservable;
-import org.chromium.chrome.browser.feed.library.common.functional.Committer;
-import org.chromium.chrome.browser.feed.library.common.functional.Predicate;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.chrome.browser.feed.library.feedmodelprovider.internal.CursorProvider;
-import org.chromium.chrome.browser.feed.library.feedmodelprovider.internal.FeatureChangeImpl;
-import org.chromium.chrome.browser.feed.library.feedmodelprovider.internal.ModelChildBinder;
-import org.chromium.chrome.browser.feed.library.feedmodelprovider.internal.ModelCursorImpl;
-import org.chromium.chrome.browser.feed.library.feedmodelprovider.internal.ModelMutationImpl;
-import org.chromium.chrome.browser.feed.library.feedmodelprovider.internal.ModelMutationImpl.Change;
-import org.chromium.chrome.browser.feed.library.feedmodelprovider.internal.UpdatableModelChild;
-import org.chromium.chrome.browser.feed.library.feedmodelprovider.internal.UpdatableModelFeature;
-import org.chromium.chrome.browser.feed.library.feedmodelprovider.internal.UpdatableModelToken;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure.Operation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.UUID;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/** An implementation of {@link ModelProvider}. This will represent the Stream tree in memory. */
-public final class FeedModelProvider
-        extends FeedObservable<ModelProviderObserver> implements ModelProvider, Dumpable {
-    private static final String TAG = "FeedModelProvider";
-    private static final List<UpdatableModelChild> EMPTY_LIST =
-            Collections.unmodifiableList(new ArrayList<>());
-    private static final String SYNTHETIC_TOKEN_PREFIX = "_token:";
-
-    private final Object mLock = new Object();
-
-    @GuardedBy("mLock")
-    @Nullable
-    private UpdatableModelChild mRoot;
-
-    // The tree is model as a parent with an list of children.  A container is created for every
-    // ModelChild with a child.
-    @GuardedBy("mLock")
-    private final Map<String, ArrayList<UpdatableModelChild>> mContainers = new HashMap<>();
-
-    @GuardedBy("mLock")
-    private final Map<String, UpdatableModelChild> mContents = new HashMap<>();
-
-    @GuardedBy("mLock")
-    private final Map<ByteString, TokenTracking> mTokens = new HashMap<>();
-
-    @GuardedBy("mLock")
-    private final Map<String, SyntheticTokenTracker> mSyntheticTokens = new HashMap<>();
-
-    // TODO: Tiktok doesn't like WeakReference and will report uses as conformance errors
-    @GuardedBy("mLock")
-    private final List<WeakReference<ModelCursorImpl>> mCursors = new ArrayList<>();
-
-    @GuardedBy("mLock")
-    private ModelState mCurrentState = ModelState.initializing();
-
-    // #dump() operation counts
-    private int mRemovedChildrenCount;
-    private int mRemoveScanCount;
-    private int mCommitCount;
-    private int mCommitTokenCount;
-    private int mCommitUpdateCount;
-    private int mCursorsRemoved;
-
-    private final FeedSessionManager mFeedSessionManager;
-    private final ThreadUtils mThreadUtils;
-    private final TaskQueue mTaskQueue;
-    private final MainThreadRunner mMainThreadRunner;
-    private final ModelChildBinder mModelChildBinder;
-    private final TimingUtils mTimingUtils;
-    private final BasicLoggingApi mBasicLoggingApi;
-
-    @Nullable
-    private final Predicate<StreamStructure> mFilterPredicate;
-    @Nullable
-    private RemoveTrackingFactory<?> mRemoveTrackingFactory;
-
-    private final int mInitialPageSize;
-    private final int mPageSize;
-    private final int mMinPageSize;
-
-    @VisibleForTesting
-    @Nullable
-    String mSessionId;
-
-    @GuardedBy("mLock")
-    private boolean mDelayedTriggerRefresh;
-
-    @GuardedBy("mLock")
-    @RequestReason
-    private int mRequestReason = RequestReason.UNKNOWN;
-
-    FeedModelProvider(FeedSessionManager feedSessionManager, ThreadUtils threadUtils,
-            TimingUtils timingUtils, TaskQueue taskQueue, MainThreadRunner mainThreadRunner,
-            @Nullable Predicate<StreamStructure> filterPredicate, Configuration config,
-            BasicLoggingApi basicLoggingApi) {
-        this.mFeedSessionManager = feedSessionManager;
-        this.mThreadUtils = threadUtils;
-        this.mTimingUtils = timingUtils;
-        this.mTaskQueue = taskQueue;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mInitialPageSize =
-                (int) config.getValueOrDefault(ConfigKey.INITIAL_NON_CACHED_PAGE_SIZE, 0L);
-        this.mPageSize = (int) config.getValueOrDefault(ConfigKey.NON_CACHED_PAGE_SIZE, 0L);
-        this.mMinPageSize = (int) config.getValueOrDefault(ConfigKey.NON_CACHED_MIN_PAGE_SIZE, 0L);
-        this.mFilterPredicate = filterPredicate;
-        this.mBasicLoggingApi = basicLoggingApi;
-
-        CursorProvider cursorProvider = parentId -> provideCursor(parentId);
-        mModelChildBinder = new ModelChildBinder(feedSessionManager, cursorProvider, timingUtils);
-    }
-
-    private ModelCursorImpl provideCursor(String parentId) {
-        synchronized (mLock) {
-            ArrayList<UpdatableModelChild> children = mContainers.get(parentId);
-            if (children == null) {
-                Logger.i(TAG, "No children found for Cursor");
-                ModelCursorImpl cursor = new ModelCursorImpl(parentId, EMPTY_LIST);
-                mCursors.add(new WeakReference<>(cursor));
-                return cursor;
-            }
-            ModelCursorImpl cursor = new ModelCursorImpl(parentId, new ArrayList<>(children));
-            mCursors.add(new WeakReference<>(cursor));
-            return cursor;
-        }
-    }
-
-    @Override
-    @Nullable
-    public ModelFeature getRootFeature() {
-        synchronized (mLock) {
-            UpdatableModelChild localRoot = mRoot;
-            if (localRoot == null) {
-                Logger.i(TAG, "Found Empty Stream");
-                return null;
-            }
-            if (localRoot.getType() != Type.FEATURE) {
-                mBasicLoggingApi.onInternalError(InternalFeedError.ROOT_NOT_BOUND_TO_FEATURE);
-                Logger.e(TAG, "Root is bound to the wrong type %s", localRoot.getType());
-                return null;
-            }
-            return localRoot.getModelFeature();
-        }
-    }
-
-    @Override
-    @Nullable
-    public ModelChild getModelChild(String contentId) {
-        synchronized (mLock) {
-            return mContents.get(contentId);
-        }
-    }
-
-    @Override
-    @Nullable
-    public StreamSharedState getSharedState(ContentId contentId) {
-        return mFeedSessionManager.getSharedState(contentId);
-    }
-
-    @Override
-    public boolean handleToken(ModelToken modelToken) {
-        if (modelToken instanceof UpdatableModelToken) {
-            UpdatableModelToken token = (UpdatableModelToken) modelToken;
-            if (token.isSynthetic()) {
-                SyntheticTokenTracker tokenTracker;
-                synchronized (mLock) {
-                    tokenTracker = mSyntheticTokens.get(token.getStreamToken().getContentId());
-                }
-                if (tokenTracker == null) {
-                    Logger.e(TAG, "Unable to find the SyntheticTokenTracker");
-                    return false;
-                }
-                // The nullness checker fails to understand tokenTracker can't be null in the Lambda
-                // usage
-                SyntheticTokenTracker tt = Validators.checkNotNull(tokenTracker);
-                mTaskQueue.execute(Task.HANDLE_SYNTHETIC_TOKEN, TaskType.USER_FACING,
-                        () -> tt.handleSyntheticToken(token));
-                return true;
-            }
-        }
-        String sessionId = Validators.checkNotNull(this.mSessionId);
-        mFeedSessionManager.handleToken(sessionId, modelToken.getStreamToken());
-        return true;
-    }
-
-    @Override
-    public void triggerRefresh(@RequestReason int requestReason) {
-        triggerRefresh(requestReason, UiContext.getDefaultInstance());
-    }
-
-    @Override
-    public void triggerRefresh(@RequestReason int requestReason, UiContext uiContext) {
-        mThreadUtils.checkMainThread();
-        if (mSessionId == null) {
-            synchronized (mLock) {
-                mDelayedTriggerRefresh = true;
-                this.mRequestReason = requestReason;
-            }
-            return;
-        }
-        mFeedSessionManager.triggerRefresh(mSessionId, requestReason, uiContext);
-    }
-
-    @Override
-    public void registerObserver(ModelProviderObserver observer) {
-        super.registerObserver(observer);
-        synchronized (mLock) {
-            // If we are in the ready state, then call the Observer to inform it things are ready.
-            if (mCurrentState.isReady()) {
-                observer.onSessionStart(mCurrentState.mUiContext);
-            } else if (mCurrentState.isInvalidated()) {
-                observer.onSessionFinished(mCurrentState.mUiContext);
-            }
-        }
-    }
-
-    @Override
-    public @State int getCurrentState() {
-        synchronized (mLock) {
-            return mCurrentState.getState();
-        }
-    }
-
-    @Override
-    @Nullable
-    public String getSessionId() {
-        if (mSessionId == null) {
-            Logger.w(TAG, "sessionId is null, this should have been set during population");
-        }
-        return mSessionId;
-    }
-
-    @Override
-    public List<ModelChild> getAllRootChildren() {
-        synchronized (mLock) {
-            if (mRoot == null) {
-                return Collections.emptyList();
-            }
-            List<UpdatableModelChild> rootChildren = mContainers.get(mRoot.getContentId());
-            return (rootChildren != null) ? new ArrayList<>(rootChildren) : Collections.emptyList();
-        }
-    }
-
-    @Override
-    public void enableRemoveTracking(RemoveTrackingFactory<?> removeTrackingFactory) {
-        this.mRemoveTrackingFactory = removeTrackingFactory;
-    }
-
-    @Override
-    public ModelMutation edit() {
-        return new ModelMutationImpl(mCommitter);
-    }
-
-    @Override
-    public void detachModelProvider() {
-        if (!moveToInvalidateState(UiContext.getDefaultInstance())) {
-            Logger.e(TAG, "unable to detach FeedModelProvider");
-            return;
-        }
-        String sessionId = getSessionId();
-        if (sessionId != null) {
-            Logger.i(TAG, "Detach the current ModelProvider: session %s", sessionId);
-            mFeedSessionManager.detachSession(sessionId);
-        }
-    }
-
-    @Override
-    public void invalidate() {
-        invalidate(UiContext.getDefaultInstance());
-    }
-
-    @Override
-    public void invalidate(UiContext uiContext) {
-        if (!moveToInvalidateState(uiContext)) {
-            Logger.e(TAG, "unable to invalidate FeedModelProvider");
-            return;
-        }
-        String sessionId = getSessionId();
-        if (sessionId != null) {
-            Logger.i(TAG, "Invalidating the current ModelProvider: session %s", sessionId);
-            mFeedSessionManager.invalidateSession(sessionId);
-        }
-
-        // Always run the observers on the UI Thread
-        mMainThreadRunner.execute(TAG + " onSessionFinished", () -> {
-            List<ModelProviderObserver> observerList = getObserversToNotify();
-            for (ModelProviderObserver observer : observerList) {
-                observer.onSessionFinished(uiContext);
-            }
-        });
-    }
-
-    private boolean moveToInvalidateState(UiContext uiContext) {
-        synchronized (mLock) {
-            if (mCurrentState.isInvalidated()) {
-                Logger.i(TAG, "Invalidated an already invalid ModelProvider");
-                return false;
-            }
-            Logger.i(TAG, "Moving %s to INVALIDATED",
-                    mSessionId != null ? mSessionId : "No sessionId");
-            mCurrentState = ModelState.invalidated(uiContext);
-            for (WeakReference<ModelCursorImpl> cursorRef : mCursors) {
-                ModelCursorImpl cursor = cursorRef.get();
-                if (cursor != null) {
-                    cursor.release();
-                    cursorRef.clear();
-                }
-            }
-            mCursors.clear();
-            mTokens.clear();
-            mSyntheticTokens.clear();
-            mContainers.clear();
-        }
-        return true;
-    }
-
-    @Override
-    public void raiseError(ModelError error) {
-        if (error.getErrorType() == ErrorType.NO_CARDS_ERROR) {
-            mMainThreadRunner.execute(TAG + " onError", () -> {
-                List<ModelProviderObserver> observerList = getObserversToNotify();
-                for (ModelProviderObserver observer : observerList) {
-                    observer.onError(error);
-                }
-            });
-        } else if (error.getErrorType() == ErrorType.PAGINATION_ERROR) {
-            Logger.i(TAG, "handling Pagination error");
-            TokenTracking token;
-            synchronized (mLock) {
-                token = mTokens.get(error.getContinuationToken());
-            }
-            if (token != null) {
-                raiseErrorOnToken(error, token.mTokenChild);
-            } else {
-                Logger.e(TAG, "The Token Observer was not found during pagination error");
-            }
-        }
-    }
-
-    private void raiseErrorOnToken(ModelError error, UpdatableModelToken token) {
-        mMainThreadRunner.execute(TAG + " onTokenChange", () -> {
-            List<TokenCompletedObserver> observerList = token.getObserversToNotify();
-            for (TokenCompletedObserver observer : observerList) {
-                observer.onError(error);
-            }
-        });
-    }
-
-    /**
-     * This wraps the ViewDepthProvider provided by the UI. It does this so it can verify that the
-     * returned contentId is one with the Root as the parent.
-     */
-    @Nullable
-    ViewDepthProvider getViewDepthProvider(@Nullable ViewDepthProvider delegate) {
-        if (delegate == null) {
-            return null;
-        }
-        return new ViewDepthProvider() {
-            @Override
-            public @Nullable String getChildViewDepth() {
-                String cid = Validators.checkNotNull(delegate).getChildViewDepth();
-                synchronized (mLock) {
-                    if (cid == null || mRoot == null) {
-                        return null;
-                    }
-                    String rootId = mRoot.getContentId();
-                    UpdatableModelChild child = mContents.get(cid);
-                    while (child != null) {
-                        if (child.getParentId() == null) {
-                            return null;
-                        }
-                        if (rootId.equals(child.getParentId())) {
-                            return child.getContentId();
-                        }
-                        child = mContents.get(child.getParentId());
-                    }
-                }
-                return null;
-            }
-        };
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        synchronized (mLock) {
-            dumper.title(TAG);
-            dumper.forKey("currentState").value(mCurrentState.getState());
-            dumper.forKey("contentCount").value(mContents.size()).compactPrevious();
-            dumper.forKey("containers").value(mContainers.size()).compactPrevious();
-            dumper.forKey("tokens").value(mTokens.size()).compactPrevious();
-            dumper.forKey("syntheticTokens").value(mSyntheticTokens.size()).compactPrevious();
-            dumper.forKey("observers").value(mObservers.size()).compactPrevious();
-            dumper.forKey("commitCount").value(mCommitCount);
-            dumper.forKey("commitTokenCount").value(mCommitTokenCount).compactPrevious();
-            dumper.forKey("commitUpdateCount").value(mCommitUpdateCount).compactPrevious();
-            dumper.forKey("removeCount").value(mRemovedChildrenCount);
-            dumper.forKey("removeScanCount").value(mRemoveScanCount).compactPrevious();
-            if (mRoot != null) {
-                // This is here to satisfy the nullness checker.
-                UpdatableModelChild nonNullRoot = Validators.checkNotNull(mRoot);
-                if (nonNullRoot.getType() != Type.FEATURE) {
-                    dumper.forKey("root").value("[ROOT NOT A FEATURE]");
-                    dumper.forKey("type").value(nonNullRoot.getType()).compactPrevious();
-                } else if (nonNullRoot.getModelFeature().getStreamFeature() != null
-                        && nonNullRoot.getModelFeature().getStreamFeature().hasContentId()) {
-                    dumper.forKey("root").value(
-                            nonNullRoot.getModelFeature().getStreamFeature().getContentId());
-                } else {
-                    dumper.forKey("root").value("[FEATURE NOT DEFINED]");
-                }
-            } else {
-                dumper.forKey("root").value("[UNDEFINED]");
-            }
-            int singleChild = 0;
-            Dumper childDumper = dumper.getChildDumper();
-            childDumper.title("Containers With Multiple Children");
-            for (Entry<String, ArrayList<UpdatableModelChild>> entry : mContainers.entrySet()) {
-                if (entry.getValue().size() > 1) {
-                    childDumper.forKey("Container").value(entry.getKey());
-                    childDumper.forKey("childrenCount")
-                            .value(entry.getValue().size())
-                            .compactPrevious();
-                } else {
-                    singleChild++;
-                }
-            }
-            dumper.forKey("singleChildContainers").value(singleChild);
-            dumper.forKey("cursors").value(mCursors.size());
-            int atEnd = 0;
-            int cursorEmptyRefs = 0;
-            for (WeakReference<ModelCursorImpl> cursorRef : mCursors) {
-                ModelCursorImpl cursor = cursorRef.get();
-                if (cursor == null) {
-                    cursorEmptyRefs++;
-                } else if (cursor.isAtEnd()) {
-                    atEnd++;
-                }
-            }
-            dumper.forKey("cursorsRemoved").value(mCursorsRemoved).compactPrevious();
-            dumper.forKey("reclaimedWeakReferences").value(cursorEmptyRefs).compactPrevious();
-            dumper.forKey("cursorsAtEnd").value(atEnd).compactPrevious();
-
-            for (WeakReference<ModelCursorImpl> cursorRef : mCursors) {
-                ModelCursorImpl cursor = cursorRef.get();
-                if (cursor != null && !cursor.isAtEnd()) {
-                    dumper.dump(cursor);
-                }
-            }
-        }
-    }
-
-    @VisibleForTesting
-    List<ModelProviderObserver> getObserversToNotify() {
-        // Make a copy of the observers, so the observers are not mutated while invoking callbacks.
-        // mObservers is locked when adding or removing observers. Also, release the lock before
-        // invoking callbacks to avoid deadlocks. ([INTERNAL LINK])
-        synchronized (mObservers) {
-            return new ArrayList<>(mObservers);
-        }
-    }
-
-    /**
-     * Abstract class used by the {@code ModelMutatorCommitter} to modify the model state based upon
-     * the current model state and the contents of the mutation. We define mutation handlers for the
-     * initialization, for a mutation based upon a continuation token response, and then a standard
-     * update mutation. The default implementation is a no-op.
-     */
-    abstract static class MutationHandler {
-        private MutationHandler() {}
-
-        /**
-         * Called before processing the children of the mutation. This allows the model to be
-         * cleaned up before new children are added.
-         */
-        void preMutation() {}
-
-        /** Append a child to a parent */
-        void appendChild(String parentKey, UpdatableModelChild child) {}
-
-        /** Remove a child from a parent */
-        void removeChild(String parentKey, UpdatableModelChild child) {}
-
-        /**
-         * This is called after the model has been updated. Typically this will notify observers of
-         * the changes made during the mutation.
-         */
-        void postMutation() {}
-    }
-
-    /** This is the {@code ModelMutatorCommitter} which updates the model. */
-    private final Committer<Void, Change> mCommitter = new Committer<Void, Change>() {
-        @Override
-        public Void commit(Change change) {
-            Logger.i(TAG, "FeedModelProvider - committer, structure changes %s, update changes %s",
-                    change.mStructureChanges.size(), change.mUpdateChanges.size());
-            mThreadUtils.checkNotMainThread();
-            ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-            mCommitCount++;
-
-            if (change.mSessionId != null) {
-                mSessionId = change.mSessionId;
-                synchronized (mLock) {
-                    if (mDelayedTriggerRefresh) {
-                        mDelayedTriggerRefresh = false;
-                        final @RequestReason int requestReasonForTrigger = mRequestReason;
-                        mMainThreadRunner.execute(TAG + " TriggerRefresh",
-                                () -> triggerRefresh(requestReasonForTrigger));
-                        mRequestReason = RequestReason.UNKNOWN;
-                    }
-                }
-            }
-
-            // All appends and updates are considered unbound (childrenToBind) and will need to be
-            // sent to the ModelChildBinder.
-            Map<String, UpdatableModelChild> appendedChildren = new HashMap<>();
-            List<UpdatableModelChild> childrenToBind = new ArrayList<>();
-            boolean removedChildren = false;
-            for (StreamStructure structureChange : change.mStructureChanges) {
-                if (mFilterPredicate != null && !mFilterPredicate.test(structureChange)) {
-                    continue;
-                }
-                if (structureChange.getOperation() == Operation.UPDATE_OR_APPEND) {
-                    String contentId = structureChange.getContentId();
-                    UpdatableModelChild child = new UpdatableModelChild(
-                            contentId, structureChange.getParentContentId());
-                    appendedChildren.put(contentId, child);
-                    childrenToBind.add(child);
-                } else if (structureChange.getOperation() == Operation.REMOVE) {
-                    removedChildren = true;
-                }
-            }
-
-            RemoveTracking<?> removeTracking = null;
-            if (mRemoveTrackingFactory != null && change.mMutationContext != null
-                    && removedChildren) {
-                removeTracking = mRemoveTrackingFactory.create(change.mMutationContext);
-            }
-
-            synchronized (mLock) {
-                // Add the updates to the childrenToBind
-                for (StreamStructure updatedChild : change.mUpdateChanges) {
-                    UpdatableModelChild child = mContents.get(updatedChild.getContentId());
-                    if (child != null) {
-                        childrenToBind.add(child);
-                    } else {
-                        Logger.w(TAG, "child %s was not found for updating",
-                                updatedChild.getContentId());
-                    }
-                }
-            }
-
-            // Mutate the Model
-            MutationHandler mutationHandler =
-                    getMutationHandler(change.mUpdateChanges, change.mMutationContext);
-            processMutation(mutationHandler, change.mStructureChanges, appendedChildren,
-                    removeTracking, change.mMutationContext);
-
-            if (removeTracking != null) {
-                // Update the UI on the main thread.
-                mMainThreadRunner.execute(
-                        TAG + " removeTracking", removeTracking::triggerConsumerUpdate);
-            }
-
-            // Determine where to start binding children.
-            int tokenStart = 0;
-            synchronized (mLock) {
-                if (mRoot != null) {
-                    tokenStart = findFirstUnboundChild(mContainers.get(mRoot.getContentId()));
-                }
-            }
-            int tokenPageSize = tokenStart < mInitialPageSize ? mInitialPageSize : mPageSize;
-
-            synchronized (mLock) {
-                if (shouldInsertSyntheticToken()) {
-                    SyntheticTokenTracker tokenTracker = new SyntheticTokenTracker(
-                            Validators.checkNotNull(mRoot), tokenStart, tokenPageSize);
-                    childrenToBind = tokenTracker.insertToken();
-                }
-            }
-
-            boolean success = bindChildrenAndTokens(childrenToBind);
-            if (success) {
-                mutationHandler.postMutation();
-            } else {
-                Logger.e(TAG, "bindChildrenAndTokens failed, not processing mutation");
-                invalidate();
-            }
-            timeTracker.stop("", "modelProviderCommit");
-            StreamToken token = (change.mMutationContext != null)
-                    ? change.mMutationContext.getContinuationToken()
-                    : null;
-            Logger.i(TAG,
-                    "ModelProvider Mutation committed - structure changes %s, childrenToBind %s, "
-                            + "removedChildren %s, Token %s",
-                    change.mStructureChanges.size(), childrenToBind.size(), removedChildren,
-                    token != null);
-            return null;
-        }
-
-        private int findFirstUnboundChild(@Nullable List<UpdatableModelChild> children) {
-            int firstUnboundChild = 0;
-            if (children != null) {
-                firstUnboundChild = children.size() - 1;
-                for (int i = 0; i < children.size() - 1; i++) {
-                    if (children.get(i).getType() == Type.UNBOUND) {
-                        firstUnboundChild = i;
-                        break;
-                    }
-                }
-            }
-            return firstUnboundChild;
-        }
-
-        /** Returns a MutationHandler for processing the mutation */
-        private MutationHandler getMutationHandler(
-                List<StreamStructure> updatedChildren, @Nullable MutationContext mutationContext) {
-            synchronized (mLock) {
-                StreamToken mutationSourceToken =
-                        mutationContext != null ? mutationContext.getContinuationToken() : null;
-                MutationHandler mutationHandler;
-                if (mCurrentState.isInitializing()) {
-                    Validators.checkState(mutationSourceToken == null,
-                            "Initializing the Model Provider from a Continuation Token");
-
-                    UiContext uiContext = mutationContext != null ? mutationContext.getUiContext()
-                                                                  : UiContext.getDefaultInstance();
-                    mutationHandler = new InitializeModel(uiContext);
-                } else if (mutationSourceToken != null) {
-                    mutationHandler = new TokenMutation(mutationSourceToken);
-                    mCommitTokenCount++;
-                } else {
-                    mutationHandler = new UpdateMutation(updatedChildren);
-                    mCommitUpdateCount++;
-                }
-                return mutationHandler;
-            }
-        }
-
-        /** Process the structure changes to update the model. */
-        void processMutation(MutationHandler mutationHandler,
-                List<StreamStructure> structureChanges,
-                Map<String, UpdatableModelChild> appendedChildren,
-                @Nullable RemoveTracking<?> removeTracking,
-                @Nullable MutationContext mutationContext) {
-            ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-            int appends = 0;
-            int removes = 0;
-            synchronized (mLock) {
-                // Processing before the structural mutation
-                mutationHandler.preMutation();
-
-                // process the structure changes
-                String currentParentKey = null;
-                ArrayList<UpdatableModelChild> childrenList = null;
-                for (StreamStructure structure : structureChanges) {
-                    if (structure.getOperation() == Operation.UPDATE_OR_APPEND) {
-                        UpdatableModelChild modelChild =
-                                appendedChildren.get(structure.getContentId());
-                        if (modelChild == null) {
-                            Logger.w(TAG, "Didn't find update child for %s",
-                                    structure.getContentId());
-                            continue;
-                        }
-                        if (!modelChild.hasParentId()) {
-                            if (!createRoot(modelChild)) {
-                                Logger.e(TAG, "Root update failed, invalidating model");
-                                Logger.i(TAG, "Moving %s to INVALIDATED",
-                                        mSessionId != null ? mSessionId : "No sessionId");
-
-                                UiContext uiContext = mutationContext == null
-                                        ? UiContext.getDefaultInstance()
-                                        : mutationContext.getUiContext();
-                                mCurrentState = ModelState.invalidated(uiContext);
-                                mMainThreadRunner.execute(TAG + " multipleRootInvalidation", () -> {
-                                    List<ModelProviderObserver> observerList =
-                                            getObserversToNotify();
-                                    for (ModelProviderObserver observer : observerList) {
-                                        observer.onSessionFinished(uiContext);
-                                    }
-                                });
-                                return;
-                            }
-                            mContents.put(modelChild.getContentId(), modelChild);
-                            appends++;
-                            continue;
-                        }
-
-                        String parentKey = Validators.checkNotNull(modelChild.getParentId());
-                        if (!parentKey.equals(currentParentKey)) {
-                            childrenList = getChildList(parentKey);
-                            currentParentKey = parentKey;
-                        }
-                        if (childrenList == null) {
-                            Logger.e(TAG, "childrenList was not set");
-                            continue;
-                        }
-                        childrenList.add(modelChild);
-                        mContents.put(modelChild.getContentId(), modelChild);
-                        appends++;
-
-                        mutationHandler.appendChild(parentKey, modelChild);
-                    } else if (structure.getOperation() == Operation.REMOVE) {
-                        handleRemoveOperation(mutationHandler, structure, removeTracking);
-                        removes++;
-                        mContents.remove(structure.getContentId());
-                    }
-                }
-            }
-            timeTracker.stop("", "modelMutation", "appends", appends, "removes", removes);
-        }
-    };
-
-    private boolean bindChildrenAndTokens(List<UpdatableModelChild> childrenToBind) {
-        // Bind the unbound children
-        boolean success = mModelChildBinder.bindChildren(childrenToBind);
-
-        synchronized (mLock) {
-            // Track any tokens we added to the tree
-            for (UpdatableModelChild child : childrenToBind) {
-                if (child.getType() == Type.TOKEN) {
-                    String parent = child.getParentId();
-                    if (parent == null) {
-                        Logger.w(TAG, "Found a token for a child %s without a parent, ignoring",
-                                child.getContentId());
-                        continue;
-                    }
-                    ArrayList<UpdatableModelChild> childrenList = getChildList(parent);
-                    TokenTracking tokenTracking =
-                            new TokenTracking(child.getUpdatableModelToken(), parent, childrenList);
-                    mTokens.put(child.getModelToken().getStreamToken().getNextPageToken(),
-                            tokenTracking);
-                }
-            }
-        }
-
-        return success;
-    }
-
-    private boolean shouldInsertSyntheticToken() {
-        synchronized (mLock) {
-            return (mRoot != null && mInitialPageSize > 0);
-        }
-    }
-
-    /** Class which handles Synthetic tokens within the root children list. */
-    @VisibleForTesting
-    final class SyntheticTokenTracker {
-        private final List<UpdatableModelChild> mChildrenToBind = new ArrayList<>();
-        private final UpdatableModelChild mPagingChild;
-        private final int mStartingPosition;
-        private final int mEndPosition;
-        private final boolean mInsertToken;
-
-        private UpdatableModelChild mTokenChild;
-
-        SyntheticTokenTracker(UpdatableModelChild pagingChild, int startingPosition, int pageSize) {
-            this.mPagingChild = pagingChild;
-
-            if (startingPosition < 0) {
-                startingPosition = 0;
-            }
-            List<UpdatableModelChild> children = mContainers.get(pagingChild.getContentId());
-            if (children == null) {
-                Logger.e(TAG, "Paging child doesn't not have children");
-                this.mStartingPosition = 0;
-                this.mEndPosition = 0;
-                this.mInsertToken = false;
-                return;
-            }
-            int start = startingPosition;
-            int end = startingPosition + pageSize;
-            if (children.size() <= start) {
-                Logger.e(TAG,
-                        "SyntheticTokenTrack to start track beyond child count, start %s,"
-                                + " child length %s",
-                        startingPosition, children.size());
-                // Bind everything
-                start = 0;
-                end = children.size();
-            } else if (start + pageSize > children.size()
-                    || start + pageSize + mMinPageSize > children.size()) {
-                end = children.size();
-            }
-            this.mStartingPosition = start;
-            this.mEndPosition = end;
-            this.mInsertToken = end < children.size();
-            Logger.i(TAG, "SyntheticTokenTracker: %d, %d, %d, %b", this.mStartingPosition,
-                    this.mEndPosition, children.size(), this.mInsertToken);
-        }
-
-        /**
-         * Returns the UpdatableModelChild which represents the synthetic token added to the model.
-         */
-        UpdatableModelChild getTokenChild() {
-            return mTokenChild;
-        }
-
-        /** Insert a synthetic token into the tree. */
-        List<UpdatableModelChild> insertToken() {
-            ElapsedTimeTracker tt = mTimingUtils.getElapsedTimeTracker(TAG);
-            traverse(mPagingChild, mStartingPosition, mEndPosition);
-            if (mInsertToken) {
-                synchronized (mLock) {
-                    ArrayList<UpdatableModelChild> rootChildren =
-                            mContainers.get(mPagingChild.getContentId());
-                    if (rootChildren != null) {
-                        mTokenChild = getSyntheticToken();
-                        rootChildren.add(mEndPosition, mTokenChild);
-                        mSyntheticTokens.put(mTokenChild.getContentId(), this);
-                        Logger.i(TAG, "Inserting a Synthetic Token %s at %s",
-                                mTokenChild.getContentId(), mEndPosition);
-                    } else {
-                        Logger.e(TAG, "Unable to find paging node's children");
-                    }
-                }
-            }
-            tt.stop("", "syntheticTokens");
-            return mChildrenToBind;
-        }
-
-        /** Handle the synthetic token */
-        void handleSyntheticToken(UpdatableModelToken token) {
-            StreamToken streamToken = token.getStreamToken();
-            SyntheticTokenTracker tracker = null;
-            UpdatableModelChild tokenChild = null;
-            UpdatableModelChild currentRoot = null;
-            List<UpdatableModelChild> rootChildren = null;
-            int pos = -1;
-            synchronized (mLock) {
-                tracker = mSyntheticTokens.get(streamToken.getContentId());
-                if (tracker != null) {
-                    tokenChild = tracker.getTokenChild();
-                }
-                currentRoot = mRoot;
-                if (tokenChild != null && currentRoot != null) {
-                    rootChildren = mContainers.get(currentRoot.getContentId());
-                }
-                if (rootChildren != null) {
-                    pos = rootChildren.indexOf(tokenChild);
-                }
-            }
-
-            // Raise an error if the token cannot be processed.
-            if (pos < 0 || rootChildren == null || currentRoot == null) {
-                Logger.e(TAG, "Cannot find synthetic token, %b %b %b %b", tracker != null,
-                        tokenChild != null, currentRoot != null, rootChildren != null);
-                raiseErrorOnToken(new ModelError(ErrorType.SYNTHETIC_TOKEN_ERROR,
-                                          /* continuationToken= */ null),
-                        token);
-                return;
-            }
-
-            // Process the synthetic token.
-            synchronized (mLock) {
-                mSyntheticTokens.remove(streamToken.getContentId());
-            }
-            rootChildren.remove(pos);
-            SyntheticTokenTracker tokenTracker =
-                    new SyntheticTokenTracker(currentRoot, pos, mPageSize);
-            List<UpdatableModelChild> childrenToBind = tokenTracker.insertToken();
-            List<UpdatableModelChild> cursorSublist =
-                    rootChildren.subList(pos, rootChildren.size());
-
-            boolean success = bindChildrenAndTokens(childrenToBind);
-            if (!success) {
-                Logger.e(TAG, "bindChildren was unsuccessful");
-            }
-
-            ModelCursorImpl cursor = new ModelCursorImpl(streamToken.getParentId(), cursorSublist);
-            TokenCompleted tokenCompleted = new TokenCompleted(cursor);
-            mMainThreadRunner.execute(TAG + " onTokenChange", () -> {
-                List<TokenCompletedObserver> observerList = token.getObserversToNotify();
-                for (TokenCompletedObserver observer : observerList) {
-                    observer.onTokenCompleted(tokenCompleted);
-                }
-            });
-        }
-
-        private void traverse(UpdatableModelChild node, int start, int end) {
-            synchronized (mLock) {
-                if (node.getType() == Type.UNBOUND) {
-                    mChildrenToBind.add(node);
-                }
-                String nodeId = node.getContentId();
-                List<UpdatableModelChild> children = mContainers.get(nodeId);
-                if (children != null && !children.isEmpty()) {
-                    int maxChildren = Math.min(end, children.size());
-                    for (int i = start; i < maxChildren; i++) {
-                        UpdatableModelChild child = children.get(i);
-                        traverse(child, 0, Integer.MAX_VALUE);
-                    }
-                }
-            }
-        }
-
-        private UpdatableModelChild getSyntheticToken() {
-            synchronized (mLock) {
-                UpdatableModelChild r = Validators.checkNotNull(mRoot);
-                String contentId = SYNTHETIC_TOKEN_PREFIX + UUID.randomUUID();
-                StreamToken streamToken = StreamToken.newBuilder().setContentId(contentId).build();
-                UpdatableModelChild modelChild =
-                        new UpdatableModelChild(contentId, r.getContentId());
-                modelChild.bindToken(new UpdatableModelToken(streamToken, true));
-                return modelChild;
-            }
-        }
-    }
-
-    private void handleRemoveOperation(MutationHandler mutationHandler, StreamStructure removeChild,
-            @Nullable RemoveTracking<?> removeTracking) {
-        if (!removeChild.hasParentContentId()) {
-            // It shouldn't be legal to remove the root, that is what CLEAR_HEAD is for.
-            Logger.e(TAG, "** Unable to remove the root element");
-            return;
-        }
-
-        if (removeTracking != null) {
-            synchronized (mLock) {
-                UpdatableModelChild child = mContents.get(removeChild.getContentId());
-                if (child != null) {
-                    traverseNode(child, removeTracking);
-                } else {
-                    Logger.w(TAG, "Didn't find child %s to do RemoveTracking",
-                            removeChild.getContentId());
-                }
-            }
-        }
-        synchronized (mLock) {
-            String parentKey = removeChild.getParentContentId();
-            List<UpdatableModelChild> childList = mContainers.get(parentKey);
-            if (childList == null) {
-                if (!removeChild.hasParentContentId()) {
-                    Logger.w(TAG, "Remove of root is not yet supported");
-                } else {
-                    Logger.w(TAG, "Parent of removed item is not found");
-                }
-                return;
-            }
-
-            // For FEATURE children, add the remove to the mutation handler to create the
-            // StreamFeatureChange.  We skip this for TOKENS.
-            String childKey = removeChild.getContentId();
-            UpdatableModelChild targetChild = mContents.get(childKey);
-            if (targetChild == null) {
-                if (childKey.startsWith(SYNTHETIC_TOKEN_PREFIX)) {
-                    Logger.i(TAG, "Remove Synthetic Token");
-                    SyntheticTokenTracker token = mSyntheticTokens.get(childKey);
-                    if (token != null) {
-                        targetChild = token.getTokenChild();
-                        mutationHandler.removeChild(parentKey, targetChild);
-                        mSyntheticTokens.remove(childKey);
-                    } else {
-                        Logger.e(TAG, "Unable to find synthetic token %s", childKey);
-                        return;
-                    }
-                } else {
-                    Logger.e(TAG, "Child %s not found in the ModelProvider contents", childKey);
-                    return;
-                }
-            }
-            if (targetChild.getType() == Type.FEATURE) {
-                mutationHandler.removeChild(parentKey, targetChild);
-            } else if (targetChild.getType() == Type.TOKEN) {
-                mutationHandler.removeChild(parentKey, targetChild);
-            }
-
-            // This walks the child list backwards because the most common removal item is a
-            // token which is always the last item in the list.  removeScanCount tracks if we are
-            // walking the list too much
-            ListIterator<UpdatableModelChild> li = childList.listIterator(childList.size());
-            UpdatableModelChild removed = null;
-            while (li.hasPrevious()) {
-                mRemoveScanCount++;
-                UpdatableModelChild child = li.previous();
-                if (child.getContentId().equals(childKey)) {
-                    removed = child;
-                    break;
-                }
-            }
-
-            if (removed != null) {
-                childList.remove(removed);
-                mRemovedChildrenCount++;
-            } else {
-                Logger.w(TAG, "Child to be removed was not found");
-            }
-        }
-    }
-
-    /**
-     * This {@link MutationHandler} handles the initial mutation populating the model. No update
-     * events are triggered. When the model is updated, we trigger a Session Started event.
-     */
-    @VisibleForTesting
-    final class InitializeModel extends MutationHandler {
-        private final UiContext mUiContext;
-
-        InitializeModel(UiContext uiContext) {
-            this.mUiContext = uiContext;
-        }
-
-        @Override
-        public void postMutation() {
-            Logger.i(TAG, "Moving %s to READY", mSessionId != null ? mSessionId : "No sessionId");
-            synchronized (mLock) {
-                mCurrentState = ModelState.ready(mUiContext);
-            }
-            mMainThreadRunner.execute(TAG + " onSessionStart", () -> {
-                List<ModelProviderObserver> observerList = getObserversToNotify();
-                for (ModelProviderObserver observer : observerList) {
-                    observer.onSessionStart(mUiContext);
-                }
-            });
-        }
-    }
-
-    /**
-     * This {@link MutationHandler} handles a mutation based upon a continuation token. For a token
-     * we will not generate changes for the parent updated by the token. Instead, the new children
-     * are appended and a {@link TokenCompleted} will be triggered.
-     */
-    @VisibleForTesting
-    final class TokenMutation extends MutationHandler {
-        private final StreamToken mMutationSourceToken;
-        @Nullable
-        TokenTracking mToken;
-        int mNewCursorStart = -1;
-
-        TokenMutation(StreamToken mutationSourceToken) {
-            this.mMutationSourceToken = mutationSourceToken;
-        }
-
-        @VisibleForTesting
-        TokenTracking getTokenTrackingForTest() {
-            synchronized (mLock) {
-                return Validators.checkNotNull(
-                        mTokens.get(mMutationSourceToken.getNextPageToken()));
-            }
-        }
-
-        @Override
-        public void preMutation() {
-            synchronized (mLock) {
-                mToken = mTokens.remove(mMutationSourceToken.getNextPageToken());
-                if (mToken == null) {
-                    Logger.e(TAG, "Token was not found, positioning to end of list");
-                    return;
-                }
-                // adjust the location because we will remove the token
-                mNewCursorStart = mToken.mLocation.size() - 1;
-            }
-        }
-
-        @Override
-        public void postMutation() {
-            if (mToken == null) {
-                Logger.e(TAG, "Token was not found, mutation is being ignored");
-                return;
-            }
-            ModelCursorImpl cursor = new ModelCursorImpl(mToken.mParentContentId,
-                    mToken.mLocation.subList(mNewCursorStart, mToken.mLocation.size()));
-            TokenCompleted tokenCompleted = new TokenCompleted(cursor);
-            mMainThreadRunner.execute(TAG + " onTokenChange", () -> {
-                if (mToken != null) {
-                    List<TokenCompletedObserver> observerList =
-                            mToken.mTokenChild.getObserversToNotify();
-                    for (TokenCompletedObserver observer : observerList) {
-                        observer.onTokenCompleted(tokenCompleted);
-                    }
-                }
-            });
-        }
-    }
-
-    /**
-     * {@code MutationHandler} which handles updates. All changes are tracked for the UI through
-     * {@link FeatureChange}. One will be created for each {@link ModelFeature} that changed. There
-     * are two types of changes, the content and changes to the children (structure).
-     */
-    @VisibleForTesting
-    final class UpdateMutation extends MutationHandler {
-        private final List<StreamStructure> mUpdates;
-        private final Map<String, FeatureChangeImpl> mChanges = new HashMap<>();
-        private final Set<String> mNewParents = new HashSet<>();
-
-        UpdateMutation(List<StreamStructure> updates) {
-            this.mUpdates = updates;
-        }
-
-        @Override
-        public void preMutation() {
-            Logger.i(TAG, "Updating %s items", mUpdates.size());
-            // Walk all the updates and update the values, creating changes to track these
-            for (StreamStructure update : mUpdates) {
-                FeatureChangeImpl change = getChange(update.getContentId());
-                if (change != null) {
-                    change.setFeatureChanged(true);
-                }
-            }
-        }
-
-        @Override
-        public void removeChild(String parentKey, UpdatableModelChild child) {
-            FeatureChangeImpl change = getChange(parentKey);
-            if (change != null) {
-                change.getChildChangesImpl().removeChild(child);
-            }
-        }
-
-        @Override
-        public void appendChild(String parentKey, UpdatableModelChild child) {
-            // Is this a child of a node that is new to the model?  We only report changes
-            // to existing ModelFeatures.
-            String childKey = child.getContentId();
-            if (mNewParents.contains(parentKey)) {
-                // Don't create a change the child of a new child
-                mNewParents.add(childKey);
-                return;
-            }
-
-            // TODO: this logic assumes that parents are passed before children.
-            mNewParents.add(childKey);
-            FeatureChangeImpl change = getChange(parentKey);
-            if (change != null) {
-                change.getChildChangesImpl().addAppendChild(child);
-            }
-        }
-
-        @Override
-        public void postMutation() {
-            synchronized (mLock) {
-                // Update the cursors before we notify the UI
-                List<WeakReference<ModelCursorImpl>> removeList = new ArrayList<>();
-                for (WeakReference<ModelCursorImpl> cursorRef : mCursors) {
-                    ModelCursorImpl cursor = cursorRef.get();
-                    if (cursor != null) {
-                        FeatureChange change = mChanges.get(cursor.getParentContentId());
-                        if (change != null) {
-                            cursor.updateIterator(change);
-                        }
-                    } else {
-                        removeList.add(cursorRef);
-                    }
-                }
-                mCursorsRemoved += removeList.size();
-                mCursors.removeAll(removeList);
-            }
-
-            // Update the Observers on the UI Thread
-            mMainThreadRunner.execute(TAG + " onFeatureChange", () -> {
-                for (FeatureChangeImpl change : mChanges.values()) {
-                    List<FeatureChangeObserver> observerList =
-                            ((UpdatableModelFeature) change.getModelFeature())
-                                    .getObserversToNotify();
-                    for (FeatureChangeObserver observer : observerList) {
-                        observer.onChange(change);
-                    }
-                }
-            });
-        }
-
-        @Nullable
-        private FeatureChangeImpl getChange(String contentIdKey) {
-            FeatureChangeImpl change = mChanges.get(contentIdKey);
-            if (change == null) {
-                UpdatableModelChild modelChild;
-                synchronized (mLock) {
-                    modelChild = mContents.get(contentIdKey);
-                }
-                if (modelChild == null) {
-                    Logger.e(TAG, "Didn't find '%s' in content", contentIdKey);
-                    return null;
-                }
-                if (modelChild.getType() == Type.UNBOUND) {
-                    Logger.e(TAG, "Looking for unbound child %s, ignore child",
-                            modelChild.getContentId());
-                    return null;
-                }
-                change = new FeatureChangeImpl(modelChild.getModelFeature());
-                mChanges.put(contentIdKey, change);
-            }
-            return change;
-        }
-    }
-
-    // This method will return true if it sets/updates root
-    private boolean createRoot(UpdatableModelChild child) {
-        synchronized (mLock) {
-            // this must be a root
-            if (child.getType() == Type.FEATURE || child.getType() == Type.UNBOUND) {
-                if (mRoot != null) {
-                    // For multiple roots, check to see if they have the same content id, if so then
-                    // ignore the new root.  Otherwise, invalidate the model because we don't
-                    // support multiple roots
-                    if (mRoot.getContentId().equals(child.getContentId())) {
-                        Logger.w(TAG, "Multiple Roots - duplicate root is ignored");
-                        return true;
-                    } else {
-                        Logger.e(TAG,
-                                "Found multiple roots [%s, %s] which is not supported."
-                                        + "  Invalidating model",
-                                Validators.checkNotNull(mRoot).getContentId(),
-                                child.getContentId());
-                        return false;
-                    }
-                }
-                mRoot = child;
-            } else {
-                // continuation tokens can not be roots.
-                Logger.e(TAG, "Invalid Root, type %s", child.getType());
-                return false;
-            }
-            return true;
-        }
-    }
-
-    // Lazy creation of containers
-    private ArrayList<UpdatableModelChild> getChildList(String parentKey) {
-        synchronized (mLock) {
-            if (!mContainers.containsKey(parentKey)) {
-                mContainers.put(parentKey, new ArrayList<>());
-            }
-            return mContainers.get(parentKey);
-        }
-    }
-
-    private void traverseNode(UpdatableModelChild node, RemoveTracking<?> removeTracking) {
-        if (node.getType() == Type.FEATURE) {
-            removeTracking.filterStreamFeature(node.getModelFeature().getStreamFeature());
-            synchronized (mLock) {
-                List<UpdatableModelChild> children = mContainers.get(node.getContentId());
-                if (children != null) {
-                    for (UpdatableModelChild child : children) {
-                        traverseNode(child, removeTracking);
-                    }
-                }
-            }
-        }
-    }
-
-    /** Track the continuation token location and model */
-    @VisibleForTesting
-    static final class TokenTracking {
-        final UpdatableModelToken mTokenChild;
-        final String mParentContentId;
-        final ArrayList<UpdatableModelChild> mLocation;
-
-        TokenTracking(UpdatableModelToken tokenChild, String parentContentId,
-                ArrayList<UpdatableModelChild> location) {
-            this.mTokenChild = tokenChild;
-            this.mParentContentId = parentContentId;
-            this.mLocation = location;
-        }
-    }
-
-    // test only method for returning a copy of the tokens map
-    @VisibleForTesting
-    Map<ByteString, TokenTracking> getTokensForTest() {
-        synchronized (mLock) {
-            return new HashMap<>(mTokens);
-        }
-    }
-
-    @VisibleForTesting
-    boolean getDelayedTriggerRefreshForTest() {
-        synchronized (mLock) {
-            return mDelayedTriggerRefresh;
-        }
-    }
-
-    @VisibleForTesting
-    @RequestReason
-    int getRequestReasonForTest() {
-        synchronized (mLock) {
-            return mRequestReason;
-        }
-    }
-
-    @VisibleForTesting
-    void clearRootChildrenForTest() {
-        synchronized (mLock) {
-            if (mRoot == null) {
-                return;
-            }
-
-            mContainers.remove(mRoot.getContentId());
-        }
-    }
-
-    private static final class ModelState {
-        final UiContext mUiContext;
-        @State
-        final int mState;
-
-        private ModelState(UiContext uiContext, @State int state) {
-            this.mUiContext = uiContext;
-            this.mState = state;
-        }
-
-        static ModelState initializing() {
-            return new ModelState(UiContext.getDefaultInstance(), State.INITIALIZING);
-        }
-
-        static ModelState ready(UiContext uiContext) {
-            return new ModelState(uiContext, State.READY);
-        }
-
-        static ModelState invalidated(UiContext uiContext) {
-            return new ModelState(uiContext, State.INVALIDATED);
-        }
-
-        public boolean isReady() {
-            return mState == State.READY;
-        }
-
-        public boolean isInvalidated() {
-            return mState == State.INVALIDATED;
-        }
-
-        public boolean isInitializing() {
-            return mState == State.INITIALIZING;
-        }
-
-        @State
-        public int getState() {
-            return mState;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/FeedModelProviderFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/FeedModelProviderFactory.java
deleted file mode 100644
index 810d918..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/FeedModelProviderFactory.java
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedmodelprovider;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider.ViewDepthProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProviderFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.functional.Predicate;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-
-/**
- * Factory for creating instances of {@link ModelProviderFactory} using the {@link
- * FeedModelProvider}.
- */
-public final class FeedModelProviderFactory implements ModelProviderFactory {
-    private final FeedSessionManager mFeedSessionManager;
-    private final ThreadUtils mThreadUtils;
-    private final TimingUtils mTimingUtils;
-    private final TaskQueue mTaskQueue;
-    private final MainThreadRunner mMainThreadRunner;
-    private final Configuration mConfig;
-    private final BasicLoggingApi mBasicLoggingApi;
-
-    public FeedModelProviderFactory(FeedSessionManager feedSessionManager, ThreadUtils threadUtils,
-            TimingUtils timingUtils, TaskQueue taskQueue, MainThreadRunner mainThreadRunner,
-            Configuration config, BasicLoggingApi basicLoggingApi) {
-        this.mFeedSessionManager = feedSessionManager;
-        this.mThreadUtils = threadUtils;
-        this.mTimingUtils = timingUtils;
-        this.mTaskQueue = taskQueue;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mConfig = config;
-        this.mBasicLoggingApi = basicLoggingApi;
-    }
-
-    @Override
-    public ModelProvider create(String sessionId, UiContext uiContext) {
-        FeedModelProvider modelProvider = new FeedModelProvider(mFeedSessionManager, mThreadUtils,
-                mTimingUtils, mTaskQueue, mMainThreadRunner, null, mConfig, mBasicLoggingApi);
-        mFeedSessionManager.getExistingSession(sessionId, modelProvider, uiContext);
-        return modelProvider;
-    }
-
-    @Override
-    public ModelProvider createNew(
-            @Nullable ViewDepthProvider viewDepthProvider, UiContext uiContext) {
-        return createNew(viewDepthProvider, null, uiContext);
-    }
-
-    @Override
-    public ModelProvider createNew(@Nullable ViewDepthProvider viewDepthProvider,
-            @Nullable Predicate<StreamStructure> filterPredicate, UiContext uiContext) {
-        FeedModelProvider modelProvider =
-                new FeedModelProvider(mFeedSessionManager, mThreadUtils, mTimingUtils, mTaskQueue,
-                        mMainThreadRunner, filterPredicate, mConfig, mBasicLoggingApi);
-        mFeedSessionManager.getNewSession(
-                modelProvider, modelProvider.getViewDepthProvider(viewDepthProvider), uiContext);
-        return modelProvider;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/CursorProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/CursorProvider.java
deleted file mode 100644
index 13190862..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/CursorProvider.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedmodelprovider.internal;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelCursor;
-
-/** Interface which provides a {@link ModelCursor} */
-public interface CursorProvider {
-    /**
-     * Create a {@link ModelCursor} for the parent, this will iterate against all the children
-     * currently contained by the parent container.
-     */
-    ModelCursor getCursor(String parentId);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/FeatureChangeImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/FeatureChangeImpl.java
deleted file mode 100644
index 7a65e1d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/FeatureChangeImpl.java
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedmodelprovider.internal;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.FeatureChange;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Class defining the specific changes made to feature nodes within the model. This is passed to the
- * observer to handle model changes. There are a few types of changes described here:
- *
- * <ol>
- *   <li>if {@link #isFeatureChanged()} returns {@code true}, then the ModelFeature was changed
- *   <li>{@link #getChildChanges()} returns a list of features either, appended, prepended, or
- *       removed from a parent
- * </ol>
- */
-public final class FeatureChangeImpl implements FeatureChange {
-    private final ModelFeature mModelFeature;
-    private final ChildChangesImpl mChildChanges;
-    private boolean mFeatureChanged;
-
-    public FeatureChangeImpl(ModelFeature modelFeature) {
-        this.mModelFeature = modelFeature;
-        this.mChildChanges = new ChildChangesImpl();
-    }
-
-    /** Returns the String ContentId of the ModelFeature which was changed. */
-    @Override
-    public String getContentId() {
-        return mModelFeature.getStreamFeature().getContentId();
-    }
-
-    /** This is called to indicate the Content changed for this ModelFeature. */
-    public void setFeatureChanged(boolean value) {
-        mFeatureChanged = value;
-    }
-
-    /** Returns {@code true} if the ModelFeature changed. */
-    @Override
-    public boolean isFeatureChanged() {
-        return mFeatureChanged;
-    }
-
-    /** Returns the ModelFeature that was changed. */
-    @Override
-    public ModelFeature getModelFeature() {
-        return mModelFeature;
-    }
-
-    /** Returns the structural changes to the ModelFeature. */
-    @Override
-    public ChildChanges getChildChanges() {
-        return mChildChanges;
-    }
-
-    public ChildChangesImpl getChildChangesImpl() {
-        return mChildChanges;
-    }
-
-    /** Structure used to define the children changes. */
-    public static final class ChildChangesImpl implements ChildChanges {
-        private final List<ModelChild> mAppendChildren;
-        private final List<ModelChild> mRemovedChildren;
-
-        @VisibleForTesting
-        ChildChangesImpl() {
-            this.mAppendChildren = new ArrayList<>();
-            this.mRemovedChildren = new ArrayList<>();
-        }
-
-        /**
-         * Returns a List of the children added to this ModelFeature. These children are in the same
-         * order they would be displayed in the stream.
-         */
-        @Override
-        public List<ModelChild> getAppendedChildren() {
-            return mAppendChildren;
-        }
-
-        @Override
-        public List<ModelChild> getRemovedChildren() {
-            return mRemovedChildren;
-        }
-
-        /** Add a child to be appended to the ModelFeature children List. */
-        public void addAppendChild(ModelChild child) {
-            mAppendChildren.add(child);
-        }
-
-        /** Remove a child from the ModelFeature children List. */
-        public void removeChild(ModelChild child) {
-            mRemovedChildren.add(child);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelChildBinder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelChildBinder.java
deleted file mode 100644
index fe0b8478..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelChildBinder.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedmodelprovider.internal;
-
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild.Type;
-import org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Bind the {@link StreamPayload} objects to the {@link ModelChild} instances. If the model child is
- * UNBOUND, we will bind the initial type. For FEATURE model child instances we will update the
- * data.
- */
-public final class ModelChildBinder {
-    private static final String TAG = "ModelChildBinder";
-
-    private final FeedSessionManager mFeedSessionManager;
-    private final CursorProvider mCursorProvider;
-    private final TimingUtils mTimingUtils;
-
-    public ModelChildBinder(FeedSessionManager feedSessionManager, CursorProvider cursorProvider,
-            TimingUtils timingUtils) {
-        this.mFeedSessionManager = feedSessionManager;
-        this.mCursorProvider = cursorProvider;
-        this.mTimingUtils = timingUtils;
-    }
-
-    public boolean bindChildren(List<UpdatableModelChild> childrenToBind) {
-        ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        Map<String, UpdatableModelChild> bindingChildren = new HashMap<>();
-        List<String> contentIds = new ArrayList<>();
-        for (UpdatableModelChild child : childrenToBind) {
-            String key = child.getContentId();
-            contentIds.add(key);
-            bindingChildren.put(key, child);
-        }
-
-        Result<List<PayloadWithId>> results = mFeedSessionManager.getStreamFeatures(contentIds);
-        if (!results.isSuccessful()) {
-            // If we failed, it's likely that this ModelProvider will soon be invalidated by the
-            // FeedSessionManager
-            Logger.e(TAG, "Unable to get the stream features.");
-            return false;
-        }
-        List<PayloadWithId> payloads = results.getValue();
-        if (contentIds.size() > payloads.size()) {
-            Logger.e(TAG, "Didn't find all of the unbound content, found %s, expected %s",
-                    payloads.size(), contentIds.size());
-        }
-        for (PayloadWithId childPayload : payloads) {
-            String key = childPayload.contentId;
-            UpdatableModelChild child = bindingChildren.get(key);
-            if (child != null) {
-                StreamPayload payload = childPayload.payload;
-                if (child.getType() == Type.UNBOUND) {
-                    if (payload.hasStreamFeature()) {
-                        child.bindFeature(new UpdatableModelFeature(
-                                payload.getStreamFeature(), mCursorProvider));
-                    } else if (payload.hasStreamToken()) {
-                        child.bindToken(new UpdatableModelToken(payload.getStreamToken(), false));
-                        continue;
-                    } else {
-                        Logger.e(TAG, "Unsupported Payload Type");
-                    }
-                    child.updateFeature(childPayload.payload);
-                } else {
-                    child.updateFeature(payload);
-                }
-            }
-        }
-        // TODO: log an error if any children are still left unbounded.
-        timeTracker.stop("", "bindingChildren", "childrenToBind", childrenToBind.size());
-        return true;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelCursorImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelCursorImpl.java
deleted file mode 100644
index b2ab0081..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelCursorImpl.java
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedmodelprovider.internal;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.FeatureChange;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.FeatureChange.ChildChanges;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild.Type;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelCursor;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelToken;
-import org.chromium.chrome.browser.feed.library.common.Validators;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/** Implementation of {@link ModelCursor}. */
-public final class ModelCursorImpl implements ModelCursor, Dumpable {
-    private static final String TAG = "ModelCursorImpl";
-
-    private final Object mLock = new Object();
-
-    private final String mParentContentId;
-
-    @GuardedBy("mLock")
-    private final List<UpdatableModelChild> mChildList;
-
-    @Nullable
-    @GuardedBy("mLock")
-    private CursorIterator mIterator;
-
-    // #dump() operation counts
-    private int mUpdatesAtEnd;
-    private int mAppendCount;
-    private int mRemoveCount;
-
-    /**
-     * Create a new ModelCursorImpl. The {@code childList} needs to be a copy of the original list
-     * to prevent {@link java.util.ConcurrentModificationException} for changes to the Model. The
-     * cursor is informed of changes through the {@link #updateIterator(FeatureChange
-     * featureChang)}.
-     */
-    public ModelCursorImpl(String parentContentId, List<UpdatableModelChild> childList) {
-        this.mParentContentId = parentContentId;
-        this.mChildList = new ArrayList<>(childList);
-        this.mIterator = new CursorIterator();
-    }
-
-    public String getParentContentId() {
-        return mParentContentId;
-    }
-
-    public void updateIterator(FeatureChange featureChange) {
-        // if the state has been released then ignore the change
-        if (isAtEnd()) {
-            Logger.i(TAG, "Ignoring Update on cursor currently at end");
-            mUpdatesAtEnd++;
-            return;
-        }
-        synchronized (mLock) {
-            ChildChanges childChanges = featureChange.getChildChanges();
-            Logger.i(TAG, "Update Cursor, removes %s, appends %s",
-                    childChanges.getRemovedChildren().size(),
-                    childChanges.getAppendedChildren().size());
-
-            removeChildren(childChanges.getRemovedChildren());
-
-            for (ModelChild modelChild : featureChange.getChildChanges().getAppendedChildren()) {
-                if (modelChild instanceof UpdatableModelChild) {
-                    mChildList.add(((UpdatableModelChild) modelChild));
-                    mAppendCount++;
-                } else {
-                    Logger.e(TAG, "non-UpdatableModelChild found, ignored");
-                }
-            }
-        }
-    }
-
-    private void removeChildren(List<ModelChild> children) {
-        if (children.isEmpty()) {
-            return;
-        }
-        // Remove only needs to remove all children that are beyond the current position because we
-        // have visited everything before and can't revisit them with this cursor.
-        synchronized (mLock) {
-            CursorIterator cursorIterator = Validators.checkNotNull(mIterator);
-            int currentPosition = cursorIterator.getPosition();
-            List<UpdatableModelChild> realRemoves = new ArrayList<>();
-            for (ModelChild modelChild : children) {
-                String childKey = modelChild.getContentId();
-                // This assumes removes are rare so we can walk the list for each deleted child.
-                for (int i = currentPosition; i < mChildList.size(); i++) {
-                    UpdatableModelChild child = mChildList.get(i);
-                    if (child.getContentId().equals(childKey)) {
-                        realRemoves.add(child);
-                        break;
-                    }
-                }
-            }
-            mRemoveCount += realRemoves.size();
-            mChildList.removeAll(realRemoves);
-            Logger.i(TAG, "Removed %s children from the Cursor", realRemoves.size());
-        }
-    }
-
-    @Override
-    @Nullable
-    public ModelChild getNextItem() {
-        // The TimeoutSessionImpl may use the cursor to access the model structure
-        ModelChild nextChild;
-        synchronized (mLock) {
-            if (mIterator == null || !mIterator.hasNext()) {
-                release();
-                return null;
-            }
-            nextChild = mIterator.next();
-            // If we just hit the last element in the iterator, free all the resources for this
-            // cursor.
-            if (!mIterator.hasNext()) {
-                release();
-            }
-            // If we have a synthetic token, this is the end of the cursor.
-            if (nextChild.getType() == Type.TOKEN) {
-                ModelToken token = nextChild.getModelToken();
-                if (token instanceof UpdatableModelToken) {
-                    UpdatableModelToken updatableModelToken = (UpdatableModelToken) token;
-                    if (updatableModelToken.isSynthetic()) {
-                        Logger.i(TAG, "Releasing Cursor due to hitting a synthetic token");
-                        release();
-                    }
-                }
-            }
-        }
-        return nextChild;
-    }
-
-    /** Release all the state assocated with this cursor */
-    public void release() {
-        // This could be called on a background thread.
-        synchronized (mLock) {
-            mIterator = null;
-        }
-    }
-
-    @Override
-    public boolean isAtEnd() {
-        synchronized (mLock) {
-            return mIterator == null || !this.mIterator.hasNext();
-        }
-    }
-
-    @VisibleForTesting
-    final class CursorIterator implements Iterator<UpdatableModelChild> {
-        private int mCursor;
-
-        @Override
-        public boolean hasNext() {
-            synchronized (mLock) {
-                return mCursor < mChildList.size();
-            }
-        }
-
-        @Override
-        public UpdatableModelChild next() {
-            synchronized (mLock) {
-                if (mCursor >= mChildList.size()) {
-                    throw new NoSuchElementException();
-                }
-                return mChildList.get(mCursor++);
-            }
-        }
-
-        int getPosition() {
-            return mCursor;
-        }
-    }
-
-    @VisibleForTesting
-    List<UpdatableModelChild> getChildListForTesting() {
-        synchronized (mLock) {
-            return new ArrayList<>(mChildList);
-        }
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        dumper.forKey("atEnd").value(isAtEnd());
-        dumper.forKey("updatesPostAtEnd").value(mUpdatesAtEnd).compactPrevious();
-        dumper.forKey("appendCount").value(mAppendCount).compactPrevious();
-        dumper.forKey("removeCount").value(mRemoveCount).compactPrevious();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelMutationImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelMutationImpl.java
deleted file mode 100644
index 3cd741ee..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelMutationImpl.java
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedmodelprovider.internal;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelMutation;
-import org.chromium.chrome.browser.feed.library.common.functional.Committer;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Implementation of the {@link ModelMutation}. When the mutation is committed updating the Model
- */
-public final class ModelMutationImpl implements ModelMutation {
-    /** The data representing the Change to the model. */
-    public static final class Change {
-        public final List<StreamStructure> mStructureChanges = new ArrayList<>();
-        public final List<StreamStructure> mUpdateChanges = new ArrayList<>();
-        @Nullable
-        public MutationContext mMutationContext;
-        @Nullable
-        public String mSessionId;
-        public boolean mCachedBindings;
-    }
-
-    private final Committer<Void, Change> mCommitter;
-    @VisibleForTesting
-    final Change mChange = new Change();
-
-    public ModelMutationImpl(Committer<Void, Change> committer) {
-        this.mCommitter = committer;
-    }
-
-    @Override
-    public ModelMutation addChild(StreamStructure streamStructure) {
-        mChange.mStructureChanges.add(streamStructure);
-        return this;
-    }
-
-    @Override
-    public ModelMutation removeChild(StreamStructure streamStructure) {
-        mChange.mStructureChanges.add(streamStructure);
-        return this;
-    }
-
-    @Override
-    public ModelMutation updateChild(StreamStructure updateChild) {
-        mChange.mUpdateChanges.add(updateChild);
-        return this;
-    }
-
-    @Override
-    public ModelMutation setMutationContext(MutationContext mutationContext) {
-        mChange.mMutationContext = mutationContext;
-        return this;
-    }
-
-    @Override
-    public ModelMutation setSessionId(String sessionId) {
-        mChange.mSessionId = sessionId;
-        return this;
-    }
-
-    @Override
-    public ModelMutation hasCachedBindings(boolean cachedBindings) {
-        mChange.mCachedBindings = cachedBindings;
-        return this;
-    }
-
-    @Override
-    public void commit() {
-        mCommitter.commit(mChange);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/UpdatableModelChild.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/UpdatableModelChild.java
deleted file mode 100644
index f17daf7..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/UpdatableModelChild.java
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedmodelprovider.internal;
-
-import android.text.TextUtils;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelToken;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-
-/** */
-public final class UpdatableModelChild implements ModelChild {
-    private static final String TAG = "UpdatableModelChild";
-
-    private final String mContentId;
-    @Nullable
-    private final String mParentContentId;
-
-    private @Type int mType = Type.UNBOUND;
-    private UpdatableModelFeature mModelFeature;
-    private UpdatableModelToken mModelToken;
-
-    public UpdatableModelChild(String contentId, @Nullable String parentContentId) {
-        this.mContentId = contentId;
-        this.mParentContentId = parentContentId;
-    }
-
-    void bindFeature(UpdatableModelFeature modelFeature) {
-        validateType(Type.UNBOUND);
-        this.mModelFeature = modelFeature;
-        mType = Type.FEATURE;
-    }
-
-    public void bindToken(UpdatableModelToken modelToken) {
-        validateType(Type.UNBOUND);
-        this.mModelToken = modelToken;
-        mType = Type.TOKEN;
-    }
-
-    @Override
-    public ModelFeature getModelFeature() {
-        validateType(Type.FEATURE);
-        return mModelFeature;
-    }
-
-    @Override
-    public ModelToken getModelToken() {
-        validateType(Type.TOKEN);
-        return mModelToken;
-    }
-
-    public UpdatableModelToken getUpdatableModelToken() {
-        validateType(Type.TOKEN);
-        return mModelToken;
-    }
-
-    void updateFeature(StreamPayload payload) {
-        switch (mType) {
-            case Type.FEATURE:
-                if (payload.hasStreamFeature()) {
-                    mModelFeature.setFeatureValue(payload.getStreamFeature());
-                } else {
-                    Logger.e(
-                            TAG, "Attempting to update a ModelFeature without providing a feature");
-                }
-                break;
-            case Type.TOKEN:
-                Logger.e(TAG, "Update called for TOKEN is unsupported");
-                break;
-            case Type.UNBOUND:
-                Logger.e(TAG, "updateFeature called on UNBOUND child");
-                break;
-            default:
-                Logger.e(TAG, "Update called for unsupported type: %s", mType);
-        }
-    }
-
-    @Override
-    public @Type int getType() {
-        return mType;
-    }
-
-    @Override
-    public String getContentId() {
-        return mContentId;
-    }
-
-    @Nullable
-    @Override
-    public String getParentId() {
-        return mParentContentId;
-    }
-
-    @Override
-    public boolean hasParentId() {
-        return !TextUtils.isEmpty(mParentContentId);
-    }
-
-    private void validateType(@Type int type) {
-        if (this.mType != type) {
-            throw new IllegalStateException(String.format(
-                    "ModelChild type error - Type %s, expected %s", this.mType, type));
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/UpdatableModelFeature.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/UpdatableModelFeature.java
deleted file mode 100644
index 2a6ffe0..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/UpdatableModelFeature.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedmodelprovider.internal;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.FeatureChangeObserver;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelCursor;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-import org.chromium.chrome.browser.feed.library.common.feedobservable.FeedObservable;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamFeature;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Implementation of the {@link ModelFeature} */
-public final class UpdatableModelFeature
-        extends FeedObservable<FeatureChangeObserver> implements ModelFeature {
-    private StreamFeature mStreamFeature;
-    private final CursorProvider mCursorProvider;
-
-    UpdatableModelFeature(StreamFeature streamFeature, CursorProvider cursorProvider) {
-        this.mStreamFeature = streamFeature;
-        this.mCursorProvider = cursorProvider;
-    }
-
-    @Override
-    public StreamFeature getStreamFeature() {
-        return mStreamFeature;
-    }
-
-    @Override
-    public ModelCursor getCursor() {
-        return mCursorProvider.getCursor(mStreamFeature.getContentId());
-    }
-
-    @Override
-    @Nullable
-    public ModelCursor getDirectionalCursor(boolean forward, @Nullable String startingChild) {
-        return null;
-    }
-
-    public List<FeatureChangeObserver> getObserversToNotify() {
-        synchronized (mObservers) {
-            return new ArrayList<>(mObservers);
-        }
-    }
-
-    void setFeatureValue(StreamFeature streamFeature) {
-        this.mStreamFeature = streamFeature;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/UpdatableModelToken.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/UpdatableModelToken.java
deleted file mode 100644
index 7a4a744..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/UpdatableModelToken.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedmodelprovider.internal;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelToken;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.TokenCompletedObserver;
-import org.chromium.chrome.browser.feed.library.common.feedobservable.FeedObservable;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Implementation of the {@link ModelToken}. */
-public final class UpdatableModelToken
-        extends FeedObservable<TokenCompletedObserver> implements ModelToken {
-    private final StreamToken mToken;
-    private final boolean mIsSynthetic;
-
-    public UpdatableModelToken(StreamToken token, boolean isSynthetic) {
-        this.mToken = token;
-        this.mIsSynthetic = isSynthetic;
-    }
-
-    @Override
-    public boolean isSynthetic() {
-        return mIsSynthetic;
-    }
-
-    @Override
-    public StreamToken getStreamToken() {
-        return mToken;
-    }
-
-    public List<TokenCompletedObserver> getObserversToNotify() {
-        synchronized (mObservers) {
-            return new ArrayList<>(mObservers);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/FeedProtocolAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/FeedProtocolAdapter.java
deleted file mode 100644
index 0680194f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/FeedProtocolAdapter.java
+++ /dev/null
@@ -1,337 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedprotocoladapter;
-
-import androidx.annotation.Nullable;
-
-import com.google.protobuf.ByteString;
-
-import org.chromium.chrome.browser.feed.library.api.internal.common.Model;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.RequiredContentAdapter;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.Validators;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.chrome.browser.feed.library.feedprotocoladapter.internal.transformers.ContentDataOperationTransformer;
-import org.chromium.chrome.browser.feed.library.feedprotocoladapter.internal.transformers.DataOperationTransformer;
-import org.chromium.chrome.browser.feed.library.feedprotocoladapter.internal.transformers.FeatureDataOperationTransformer;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamFeature;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure.Operation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-import org.chromium.components.feed.core.proto.wire.DataOperationProto.DataOperation;
-import org.chromium.components.feed.core.proto.wire.FeatureProto.Feature;
-import org.chromium.components.feed.core.proto.wire.FeatureProto.Feature.RenderableUnit;
-import org.chromium.components.feed.core.proto.wire.FeedResponseProto.FeedResponse;
-import org.chromium.components.feed.core.proto.wire.FeedResponseProto.FeedResponseMetadata;
-import org.chromium.components.feed.core.proto.wire.PietSharedStateItemProto.PietSharedStateItem;
-import org.chromium.components.feed.core.proto.wire.ResponseProto.Response;
-import org.chromium.components.feed.core.proto.wire.TokenProto.Token;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/** A ProtocolAdapter which converts from the wire protocol to the internal protocol. */
-public final class FeedProtocolAdapter implements ProtocolAdapter, Dumpable {
-    private static final String TAG = "FeedProtocolAdapter";
-    static final String CONTENT_ID_DELIMITER = "::";
-
-    private final List<DataOperationTransformer> mDataOperationTransformers;
-    private final List<RequiredContentAdapter> mRequiredContentAdapters;
-    private final TimingUtils mTimingUtils;
-
-    // Operation counts for #dump(Dumpable)
-    private int mResponseHandlingCount;
-    private int mConvertContentIdCount;
-
-    public FeedProtocolAdapter(
-            List<RequiredContentAdapter> requiredContentAdapters, TimingUtils timingUtils) {
-        this.mTimingUtils = timingUtils;
-        this.mRequiredContentAdapters = requiredContentAdapters;
-        mDataOperationTransformers = new ArrayList<>(2);
-        mDataOperationTransformers.add(new FeatureDataOperationTransformer());
-        mDataOperationTransformers.add(new ContentDataOperationTransformer());
-    }
-
-    @Override
-    public String getStreamContentId(ContentId contentId) {
-        mConvertContentIdCount++;
-        return createContentId(contentId);
-    }
-
-    @Override
-    public Result<ContentId> getWireContentId(String contentId) {
-        String[] splitContentId = contentId.split(CONTENT_ID_DELIMITER, -1);
-        // Can't create if all 3 parts aren't present (at the very least empty)
-        if (splitContentId.length != 3) {
-            Logger.e(TAG, "Error parsing string content ID - splitting did not result in 3 parts");
-            return Result.failure();
-        }
-        String table = splitContentId[0];
-        String contentDomain = splitContentId[1];
-        long id;
-        try {
-            id = Long.parseLong(splitContentId[2]);
-        } catch (NumberFormatException e) {
-            Logger.e(TAG, e, "Error converting content ID to wire format");
-            return Result.failure();
-        }
-        ContentId.Builder builder = ContentId.newBuilder().setId(id);
-        if (!table.isEmpty()) {
-            builder.setTable(table);
-        }
-        if (!contentDomain.isEmpty()) {
-            builder.setContentDomain(contentDomain);
-        }
-        return Result.success(builder.build());
-    }
-
-    @Override
-    public Result<Model> createModel(Response response) {
-        mResponseHandlingCount++;
-
-        FeedResponse feedResponse = response.getExtension(FeedResponse.feedResponse);
-        Logger.i(TAG, "createModel, operations %s", feedResponse.getDataOperationCount());
-        List<StreamDataOperation> operations = createOperations(
-                feedResponse.getDataOperationList(), feedResponse.getFeedResponseMetadata());
-        return Result.success(Model.of(operations));
-    }
-
-    @Override
-    public List<StreamDataOperation> createOperations(List<DataOperation> dataOperations) {
-        return createOperations(dataOperations, FeedResponseMetadata.getDefaultInstance());
-    }
-
-    private List<StreamDataOperation> createOperations(
-            List<DataOperation> dataOperations, FeedResponseMetadata responseMetadata) {
-        ElapsedTimeTracker totalTimeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        List<StreamDataOperation> streamDataOperations = new ArrayList<>();
-        Set<ContentId> requiredContentIds = new HashSet<>();
-        for (DataOperation operation : dataOperations) {
-            for (RequiredContentAdapter adapter : mRequiredContentAdapters) {
-                requiredContentIds.addAll(adapter.determineRequiredContentIds(operation));
-            }
-
-            Operation streamOperation = operationToStreamOperation(operation.getOperation());
-            String contentId;
-            if (streamOperation == Operation.CLEAR_ALL) {
-                streamDataOperations.add(
-                        createDataOperation(Operation.CLEAR_ALL, null, null).build());
-                continue;
-            } else if (streamOperation == Operation.REMOVE) {
-                if (operation.getMetadata().hasContentId()) {
-                    contentId = createContentId(operation.getMetadata().getContentId());
-                    String parentId = null;
-                    if (operation.getFeature().hasParentId()) {
-                        parentId = createContentId(operation.getFeature().getParentId());
-                    }
-                    streamDataOperations.add(
-                            createDataOperation(Operation.REMOVE, contentId, parentId).build());
-
-                } else {
-                    Logger.w(TAG,
-                            "REMOVE defined without a ContentId identifying the item to remove");
-                }
-                continue;
-            } else if (operation.getMetadata().hasContentId()) {
-                contentId = createContentId(operation.getMetadata().getContentId());
-            } else {
-                // This is an error state, every card should have a content id
-                Logger.e(TAG, "ContentId not defined for DataOperation");
-                continue;
-            }
-
-            if (operation.hasFeature()) {
-                handleFeatureOperation(
-                        operation, responseMetadata, contentId, streamDataOperations);
-            } else if (operation.hasPietSharedState()) {
-                PietSharedStateItem item =
-                        PietSharedStateItem.newBuilder()
-                                .setPietSharedState(operation.getPietSharedState())
-                                .build();
-                StreamSharedState state = StreamSharedState.newBuilder()
-                                                  .setPietSharedStateItem(item)
-                                                  .setContentId(contentId)
-                                                  .build();
-                streamDataOperations.add(
-                        createSharedStateDataOperation(streamOperation, contentId, state).build());
-            }
-
-            if (operation.getMetadata().getSemanticProperties().hasSemanticPropertiesData()) {
-                streamDataOperations.add(createSemanticDataOperation(contentId,
-                        operation.getMetadata().getSemanticProperties().getSemanticPropertiesData())
-                                                 .build());
-            }
-        }
-
-        for (ContentId requiredContentId : requiredContentIds) {
-            streamDataOperations.add(
-                    StreamDataOperation.newBuilder()
-                            .setStreamStructure(
-                                    StreamStructure.newBuilder()
-                                            .setOperation(Operation.REQUIRED_CONTENT)
-                                            .setContentId(createContentId(requiredContentId)))
-                            .build());
-        }
-
-        totalTimeTracker.stop("task", "convertWireProtocol", "mutations", dataOperations.size());
-        return streamDataOperations;
-    }
-
-    private void handleFeatureOperation(DataOperation operation,
-            FeedResponseMetadata feedResponseMetadata, String contentId,
-            List<StreamDataOperation> streamDataOperations) {
-        Operation streamOperation = operationToStreamOperation(operation.getOperation());
-        String parentId = null;
-        if (operation.getFeature().hasParentId()) {
-            parentId = createContentId(operation.getFeature().getParentId());
-        }
-        if (operation.getFeature().getRenderableUnit() == RenderableUnit.TOKEN) {
-            Feature feature = operation.getFeature();
-            if (feature.hasExtension(Token.tokenExtension)) {
-                // Create a StreamToken operation
-                Token token = feature.getExtension(Token.tokenExtension);
-                StreamToken streamToken = Validators.checkNotNull(
-                        createStreamToken(contentId, parentId, token.getNextPageToken()));
-                streamDataOperations.add(
-                        createTokenDataOperation(contentId, streamToken.getParentId(), streamToken)
-                                .build());
-            } else {
-                Logger.e(TAG, "Extension not found for TOKEN");
-            }
-        } else {
-            StreamFeature.Builder streamFeatureBuilder = createStreamFeature(contentId, parentId);
-            StreamDataOperation.Builder streamDataOperation =
-                    StreamDataOperation.newBuilder().setStreamPayload(
-                            StreamPayload.newBuilder().setStreamFeature(streamFeatureBuilder));
-            streamDataOperation =
-                    transformOperation(operation, streamDataOperation, feedResponseMetadata);
-            streamDataOperation =
-                    createDataOperation(streamDataOperation, streamOperation, contentId, parentId);
-            streamDataOperations.add(streamDataOperation.build());
-        }
-    }
-
-    private StreamDataOperation.Builder transformOperation(DataOperation operation,
-            StreamDataOperation.Builder streamDataOperation,
-            FeedResponseMetadata feedResponseMetadata) {
-        for (DataOperationTransformer transformer : mDataOperationTransformers) {
-            streamDataOperation =
-                    transformer.transform(operation, streamDataOperation, feedResponseMetadata);
-        }
-
-        return streamDataOperation;
-    }
-
-    private StreamFeature.Builder createStreamFeature(String contentId, @Nullable String parentId) {
-        StreamFeature.Builder builder = StreamFeature.newBuilder();
-        builder.setContentId(contentId);
-
-        if (parentId != null) {
-            builder.setParentId(parentId);
-        }
-        return builder;
-    }
-
-    @Nullable
-    private StreamToken createStreamToken(
-            String tokenId, @Nullable String parentId, ByteString continuationToken) {
-        if (continuationToken.isEmpty()) {
-            return null;
-        }
-        StreamToken.Builder tokenBuilder = StreamToken.newBuilder();
-        if (parentId != null) {
-            tokenBuilder.setParentId(parentId);
-        }
-        tokenBuilder.setContentId(tokenId);
-        tokenBuilder.setNextPageToken(continuationToken);
-        return tokenBuilder.build();
-    }
-
-    private StreamDataOperation.Builder createSharedStateDataOperation(
-            Operation operation, @Nullable String contentId, StreamSharedState sharedState) {
-        StreamDataOperation.Builder dataOperation = createDataOperation(operation, contentId, null);
-        dataOperation.setStreamPayload(
-                StreamPayload.newBuilder().setStreamSharedState(sharedState));
-        return dataOperation;
-    }
-
-    private StreamDataOperation.Builder createTokenDataOperation(
-            @Nullable String contentId, @Nullable String parentId, StreamToken streamToken) {
-        StreamDataOperation.Builder dataOperation =
-                createDataOperation(Operation.UPDATE_OR_APPEND, contentId, parentId);
-        dataOperation.setStreamPayload(StreamPayload.newBuilder().setStreamToken(streamToken));
-        return dataOperation;
-    }
-
-    private StreamDataOperation.Builder createDataOperation(
-            Operation operation, @Nullable String contentId, @Nullable String parentId) {
-        return createDataOperation(
-                StreamDataOperation.newBuilder(), operation, contentId, parentId);
-    }
-
-    private StreamDataOperation.Builder createDataOperation(
-            StreamDataOperation.Builder streamDataOperation, Operation operation,
-            @Nullable String contentId, @Nullable String parentId) {
-        StreamStructure.Builder streamStructure = StreamStructure.newBuilder();
-        streamStructure.setOperation(operation);
-        if (contentId != null) {
-            streamStructure.setContentId(contentId);
-        }
-        if (parentId != null) {
-            streamStructure.setParentContentId(parentId);
-        }
-        streamDataOperation.setStreamStructure(streamStructure);
-        return streamDataOperation;
-    }
-
-    private StreamDataOperation.Builder createSemanticDataOperation(
-            String contentId, ByteString semanticData) {
-        return StreamDataOperation.newBuilder()
-                .setStreamPayload(StreamPayload.newBuilder().setSemanticData(semanticData))
-                .setStreamStructure(
-                        StreamStructure.newBuilder().setContentId(contentId).setOperation(
-                                Operation.UPDATE_OR_APPEND));
-    }
-
-    private String createContentId(ContentId contentId) {
-        // Using String concat for performance reasons.  This is called a lot for large feed
-        // responses.
-        return contentId.getTable() + CONTENT_ID_DELIMITER + contentId.getContentDomain()
-                + CONTENT_ID_DELIMITER + contentId.getId();
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        dumper.forKey("responseHandlingCount").value(mResponseHandlingCount);
-        dumper.forKey("convertContentIdCount").value(mConvertContentIdCount).compactPrevious();
-    }
-
-    private static Operation operationToStreamOperation(DataOperation.Operation operation) {
-        switch (operation) {
-            case UNKNOWN_OPERATION:
-                return Operation.UNKNOWN;
-            case CLEAR_ALL:
-                return Operation.CLEAR_ALL;
-            case UPDATE_OR_APPEND:
-                return Operation.UPDATE_OR_APPEND;
-            case REMOVE:
-                return Operation.REMOVE;
-        }
-
-        return Operation.UNKNOWN;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/internal/transformers/ContentDataOperationTransformer.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/internal/transformers/ContentDataOperationTransformer.java
deleted file mode 100644
index 46b5e4c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/internal/transformers/ContentDataOperationTransformer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedprotocoladapter.internal.transformers;
-
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.ClientBasicLoggingMetadata;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamFeature;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.BasicLoggingMetadata;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.Content;
-import org.chromium.components.feed.core.proto.wire.DataOperationProto.DataOperation;
-import org.chromium.components.feed.core.proto.wire.FeatureProto.Feature.RenderableUnit;
-import org.chromium.components.feed.core.proto.wire.FeedResponseProto.FeedResponseMetadata;
-
-/**
- * {@link DataOperationTransformer} for {@link Content} that adds {@link
- * ClientBasicLoggingMetadata}.
- */
-public final class ContentDataOperationTransformer implements DataOperationTransformer {
-    @Override
-    public StreamDataOperation.Builder transform(DataOperation dataOperation,
-            StreamDataOperation.Builder streamDataOperation,
-            FeedResponseMetadata feedResponseMetadata) {
-        if (dataOperation.getFeature().getRenderableUnit() != RenderableUnit.CONTENT) {
-            return streamDataOperation;
-        }
-        Content content = dataOperation.getFeature().getExtension(Content.contentExtension);
-        StreamFeature.Builder streamFeature =
-                streamDataOperation.getStreamPayload().getStreamFeature().toBuilder().setContent(
-                        content);
-        if (!feedResponseMetadata.hasResponseTimeMs()) {
-            streamDataOperation.setStreamPayload(
-                    streamDataOperation.getStreamPayload().toBuilder().setStreamFeature(
-                            streamFeature));
-            return streamDataOperation;
-        }
-        BasicLoggingMetadata.Builder basicLoggingData =
-                content.getBasicLoggingMetadata().toBuilder().setExtension(
-                        ClientBasicLoggingMetadata.clientBasicLoggingMetadata,
-                        ClientBasicLoggingMetadata.newBuilder()
-                                .setAvailabilityTimeSeconds(
-                                        feedResponseMetadata.getResponseTimeMs())
-                                .build());
-
-        Content.Builder contentBuilder =
-                content.toBuilder().setBasicLoggingMetadata(basicLoggingData);
-        streamFeature = streamFeature.setContent(contentBuilder);
-        streamDataOperation.setStreamPayload(
-                streamDataOperation.getStreamPayload().toBuilder().setStreamFeature(streamFeature));
-
-        return streamDataOperation;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/internal/transformers/DataOperationTransformer.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/internal/transformers/DataOperationTransformer.java
deleted file mode 100644
index 20449c9..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/internal/transformers/DataOperationTransformer.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedprotocoladapter.internal.transformers;
-
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.wire.DataOperationProto.DataOperation;
-import org.chromium.components.feed.core.proto.wire.FeedResponseProto.FeedResponseMetadata;
-
-/**
- * A DataOperationTransformer transform a {@link DataOperation} into a {@link
- * StreamDataOperation.Builder}. DataOperationTranformer(s) can be chained to perform multiple
- * transformations.
- */
-public interface DataOperationTransformer {
-    /**
-     * Transforms a {@link DataOperation} into a {@link StreamDataOperation.Builder}. {@link
-     * StreamDataOperation.Builder} is returned to allow for multiple transformations.
-     */
-    StreamDataOperation.Builder transform(DataOperation dataOperation,
-            StreamDataOperation.Builder streamDataOperation,
-            FeedResponseMetadata feedResponseMetadata);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/internal/transformers/FeatureDataOperationTransformer.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/internal/transformers/FeatureDataOperationTransformer.java
deleted file mode 100644
index 9ac1f90..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/internal/transformers/FeatureDataOperationTransformer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedprotocoladapter.internal.transformers;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamFeature;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.Card;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.Cluster;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.Stream;
-import org.chromium.components.feed.core.proto.wire.DataOperationProto.DataOperation;
-import org.chromium.components.feed.core.proto.wire.FeedResponseProto.FeedResponseMetadata;
-
-/** {@link DataOperationTransformer} to populate {@link StreamFeature}. */
-public final class FeatureDataOperationTransformer implements DataOperationTransformer {
-    private static final String TAG = "FeatureDataOperationTra";
-
-    @Override
-    public StreamDataOperation.Builder transform(DataOperation dataOperation,
-            StreamDataOperation.Builder dataOperationBuilder,
-            FeedResponseMetadata feedResponseMetadata) {
-        StreamFeature.Builder streamFeature =
-                dataOperationBuilder.getStreamPayload().getStreamFeature().toBuilder();
-        switch (dataOperation.getFeature().getRenderableUnit()) {
-            case STREAM:
-                streamFeature.setStream(
-                        dataOperation.getFeature().getExtension(Stream.streamExtension));
-                break;
-            case CARD:
-                streamFeature.setCard(dataOperation.getFeature().getExtension(Card.cardExtension));
-                break;
-            case CLUSTER:
-                streamFeature.setCluster(
-                        dataOperation.getFeature().getExtension(Cluster.clusterExtension));
-                break;
-            case CONTENT:
-                // Content is handled in ContentDataOperationTransformer
-                break;
-            case TOKEN:
-                // Tokens are handled in FeedProtocolAdapter
-                break;
-            default:
-                Logger.e(TAG, "Unknown Feature payload %s, ignored",
-                        dataOperation.getFeature().getRenderableUnit());
-                return dataOperationBuilder;
-        }
-        dataOperationBuilder.setStreamPayload(
-                dataOperationBuilder.getStreamPayload().toBuilder().setStreamFeature(
-                        streamFeature));
-        return dataOperationBuilder;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedActionUploadRequestManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedActionUploadRequestManager.java
deleted file mode 100644
index 7229716..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedActionUploadRequestManager.java
+++ /dev/null
@@ -1,285 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedrequestmanager;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest.HttpMethod;
-import org.chromium.chrome.browser.feed.library.api.host.network.NetworkClient;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ViewActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.common.SemanticPropertiesWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.api.internal.requestmanager.ActionUploadRequestManager;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.api.internal.store.UploadableActionMutation;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue.TaskType;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.protoextensions.FeedExtensionRegistry;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-import org.chromium.components.feed.core.proto.wire.ConsistencyTokenProto.ConsistencyToken;
-import org.chromium.components.feed.core.proto.wire.FeedActionResponseProto.FeedActionResponse;
-import org.chromium.components.feed.core.proto.wire.ResponseProto.Response;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/** Default implementation of ActionUploadRequestManager. */
-public final class FeedActionUploadRequestManager implements ActionUploadRequestManager {
-    private static final String TAG = "ActionUploadRequest";
-
-    private final ViewActionManager mViewActionManager;
-    private final Configuration mConfiguration;
-    private final NetworkClient mNetworkClient;
-    private final ProtocolAdapter mProtocolAdapter;
-    private final FeedExtensionRegistry mExtensionRegistry;
-    private final MainThreadRunner mMainThreadRunner;
-    private final TaskQueue mTaskQueue;
-    private final ThreadUtils mThreadUtils;
-    private final Store mStore;
-    private final Clock mClock;
-    private final long mMaxActionUploadAttempts;
-    // Total number of actions that can be uploaded in a chained batch request.
-    private final long mMaxActionsUploadsPerBatchedRequest;
-    // Maximum bytes of StreamUploadableAction that can be uploaded in a single request. The actual
-    // request is made of ActionPayloads and SemanticProperties, not StreamUploadableActions, so
-    // this serves as a proxy.
-    private final long mMaxBytesPerRequest;
-    private final long mMaxActionUploadTtl;
-
-    public FeedActionUploadRequestManager(ViewActionManager viewActionManager,
-            Configuration configuration, NetworkClient networkClient,
-            ProtocolAdapter protocolAdapter, FeedExtensionRegistry extensionRegistry,
-            MainThreadRunner mainThreadRunner, TaskQueue taskQueue, ThreadUtils threadUtils,
-            Store store, Clock clock) {
-        this.mViewActionManager = viewActionManager;
-        this.mConfiguration = configuration;
-        this.mNetworkClient = networkClient;
-        this.mProtocolAdapter = protocolAdapter;
-        this.mExtensionRegistry = extensionRegistry;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mTaskQueue = taskQueue;
-        this.mThreadUtils = threadUtils;
-        this.mStore = store;
-        this.mClock = clock;
-        mMaxBytesPerRequest = configuration.getValueOrDefault(
-                ConfigKey.FEED_ACTION_SERVER_MAX_SIZE_PER_REQUEST, 4000L);
-        mMaxActionsUploadsPerBatchedRequest = configuration.getValueOrDefault(
-                ConfigKey.FEED_ACTION_SERVER_MAX_ACTIONS_PER_REQUEST, 10L);
-        mMaxActionUploadAttempts =
-                configuration.getValueOrDefault(ConfigKey.FEED_ACTION_MAX_UPLOAD_ATTEMPTS, 1L);
-        mMaxActionUploadTtl = configuration.getValueOrDefault(
-                ConfigKey.FEED_ACTION_TTL_SECONDS, TimeUnit.DAYS.toSeconds(2));
-    }
-
-    @Override
-    public void triggerUploadActions(Set<StreamUploadableAction> actions, ConsistencyToken token,
-            Consumer<Result<ConsistencyToken>> consumer) {
-        mThreadUtils.checkNotMainThread();
-        if (mMaxActionUploadAttempts == 0 || mMaxBytesPerRequest == 0
-                || mMaxActionsUploadsPerBatchedRequest == 0) {
-            consumer.accept(Result.success(token));
-            return;
-        }
-        triggerUploadActions(actions, token, consumer, /* uploadCount= */ 0);
-    }
-
-    @Override
-    public void triggerUploadAllActions(
-            ConsistencyToken token, Consumer<Result<ConsistencyToken>> consumer) {
-        mThreadUtils.checkNotMainThread();
-        mMainThreadRunner.execute("Store view actions and", () -> {
-            mViewActionManager.storeViewActions(() -> {
-                mTaskQueue.execute(Task.UPLOAD_ALL_ACTIONS, TaskType.IMMEDIATE, () -> {
-                    Result<Set<StreamUploadableAction>> actionsResult =
-                            mStore.getAllUploadableActions();
-                    if (actionsResult.isSuccessful()) {
-                        triggerUploadActions(actionsResult.getValue(), token, consumer);
-                    }
-                });
-            });
-        });
-    }
-
-    private void triggerUploadActions(Set<StreamUploadableAction> actions, ConsistencyToken token,
-            Consumer<Result<ConsistencyToken>> consumer, int uploadCount) {
-        mThreadUtils.checkNotMainThread();
-        // Return the token if there are no actions to upload.
-        if (actions.isEmpty() || uploadCount >= mMaxActionsUploadsPerBatchedRequest) {
-            consumer.accept(Result.success(token));
-            return;
-        }
-        UploadableActionsRequestBuilder requestBuilder =
-                new UploadableActionsRequestBuilder(mProtocolAdapter);
-        int actionPayloadBytes = 0;
-
-        Set<StreamUploadableAction> actionsToUpload = new HashSet<>();
-        Set<StreamUploadableAction> actionsRemaining = new HashSet<>();
-        ArrayList<String> contentIds = new ArrayList<>();
-
-        UploadableActionMutation actionMutation = mStore.editUploadableActions();
-
-        // Select which actions to send in this request, and update their attempt count. Remaining
-        // actions are collected and sent next. Stale actions are removed from the store.
-        for (StreamUploadableAction action : actions) {
-            if (isStale(action)) {
-                actionMutation.remove(action, action.getFeatureContentId());
-                continue;
-            }
-
-            int actionBytes = action.toByteArray().length;
-            if (actionPayloadBytes + actionBytes < mMaxBytesPerRequest) {
-                actionPayloadBytes += actionBytes;
-                actionMutation.remove(action, action.getFeatureContentId());
-                StreamUploadableAction actionToUpload =
-                        action.toBuilder()
-                                .setUploadAttempts(action.getUploadAttempts() + 1)
-                                .build();
-                actionMutation.upsert(actionToUpload, actionToUpload.getFeatureContentId());
-                actionsToUpload.add(actionToUpload);
-
-                contentIds.add(actionToUpload.getFeatureContentId());
-            } else {
-                actionsRemaining.add(action);
-            }
-        }
-
-        CommitResult commitResult = actionMutation.commit();
-        if (commitResult != CommitResult.SUCCESS) {
-            Logger.e(TAG, "Upserting uploaded actions failed");
-            consumer.accept(Result.failure());
-            return;
-        }
-
-        if (actionsToUpload.isEmpty()) {
-            if (actionsRemaining.isEmpty()) {
-                // All actions were too stale to be uploaded.
-                consumer.accept(Result.success(token));
-            } else {
-                Logger.e(TAG, "No action fitted in the request.");
-                consumer.accept(Result.failure());
-            }
-            return;
-        }
-
-        Result<List<SemanticPropertiesWithId>> semanticPropertiesResult =
-                mStore.getSemanticProperties(contentIds);
-        List<SemanticPropertiesWithId> semanticPropertiesList = new ArrayList<>();
-        if (semanticPropertiesResult.isSuccessful()
-                && !semanticPropertiesResult.getValue().isEmpty()) {
-            semanticPropertiesList = semanticPropertiesResult.getValue();
-        }
-
-        Consumer<Result<ConsistencyToken>> tokenConsumer = result -> {
-            mThreadUtils.checkNotMainThread();
-            if (result.isSuccessful()) {
-                if (!actionsRemaining.isEmpty()) {
-                    triggerUploadActions(actionsRemaining, result.getValue(), consumer,
-                            uploadCount + actionsToUpload.size());
-                } else {
-                    consumer.accept(Result.success(result.getValue()));
-                }
-            } else {
-                consumer.accept(uploadCount == 0 ? Result.failure() : Result.success(token));
-            }
-        };
-        requestBuilder.setConsistencyToken(token)
-                .setActions(actionsToUpload)
-                .setSemanticProperties(semanticPropertiesList);
-        executeUploadActionRequest(actionsToUpload, requestBuilder, tokenConsumer);
-    }
-
-    private void executeUploadActionRequest(Set<StreamUploadableAction> actions,
-            UploadableActionsRequestBuilder requestBuilder,
-            Consumer<Result<ConsistencyToken>> consumer) {
-        mThreadUtils.checkNotMainThread();
-
-        String endpoint =
-                mConfiguration.getValueOrDefault(ConfigKey.FEED_ACTION_SERVER_ENDPOINT, "");
-        @HttpMethod
-        String httpMethod = mConfiguration.getValueOrDefault(
-                ConfigKey.FEED_ACTION_SERVER_METHOD, HttpMethod.POST);
-        HttpRequest httpRequest =
-                RequestHelper.buildHttpRequest(httpMethod, requestBuilder.build().toByteArray(),
-                        endpoint, /* locale= */ "", /* priorityParamValue= */ "");
-
-        Logger.i(TAG, "Making Request: %s", httpRequest.getUri().getPath());
-        mNetworkClient.send(httpRequest, input -> {
-            Logger.i(TAG, "Request: %s completed with response code: %s",
-                    httpRequest.getUri().getPath(), input.getResponseCode());
-            if (input.getResponseCode() != 200) {
-                String errorBody = null;
-                try {
-                    errorBody = new String(input.getResponseBody(), "UTF-8");
-                } catch (UnsupportedEncodingException e) {
-                    Logger.e(TAG, "Error handling http error logging", e);
-                }
-                Logger.e(TAG, "errorCode: %d", input.getResponseCode());
-                Logger.e(TAG, "errorResponse: %s", errorBody);
-                mTaskQueue.execute(Task.EXECUTE_UPLOAD_ACTION_REQUEST, TaskType.IMMEDIATE,
-                        () -> { consumer.accept(Result.failure()); });
-                return;
-            }
-            handleUploadableActionResponseBytes(actions, input.getResponseBody(), consumer);
-        });
-    }
-
-    private void handleUploadableActionResponseBytes(Set<StreamUploadableAction> actions,
-            final byte[] responseBytes, final Consumer<Result<ConsistencyToken>> consumer) {
-        mTaskQueue.execute(Task.HANDLE_UPLOADABLE_ACTION_RESPONSE_BYTES, TaskType.IMMEDIATE, () -> {
-            Response response;
-            boolean isLengthPrefixed = mConfiguration.getValueOrDefault(
-                    ConfigKey.FEED_ACTION_SERVER_RESPONSE_LENGTH_PREFIXED, true);
-            try {
-                response = Response.parseFrom(isLengthPrefixed
-                                ? RequestHelper.getLengthPrefixedValue(responseBytes)
-                                : responseBytes,
-                        mExtensionRegistry.getExtensionRegistry());
-            } catch (IOException e) {
-                Logger.e(TAG, e, "Response parse failed");
-                consumer.accept(Result.failure());
-                return;
-            }
-            FeedActionResponse feedActionResponse =
-                    response.getExtension(FeedActionResponse.feedActionResponse);
-            final Result<ConsistencyToken> contextResult;
-            if (feedActionResponse.hasConsistencyToken()) {
-                contextResult = Result.success(feedActionResponse.getConsistencyToken());
-                UploadableActionMutation actionMutation = mStore.editUploadableActions();
-                for (StreamUploadableAction action : actions) {
-                    actionMutation.remove(action, action.getFeatureContentId());
-                }
-                CommitResult commitResult = actionMutation.commit();
-                if (commitResult != CommitResult.SUCCESS) {
-                    // TODO:log failure to the basicLoggingApi
-                    Logger.e(TAG, "Removing actions on success failed");
-                }
-            } else {
-                contextResult = Result.failure();
-            }
-            consumer.accept(contextResult);
-        });
-    }
-
-    private boolean isStale(StreamUploadableAction action) {
-        int uploadAttempts = action.getUploadAttempts();
-        long currentTime = TimeUnit.MILLISECONDS.toSeconds(mClock.currentTimeMillis());
-        long timeSinceUpload = currentTime - action.getTimestampSeconds();
-        return uploadAttempts >= mMaxActionUploadAttempts || timeSinceUpload > mMaxActionUploadTtl;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedRequestManagerImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedRequestManagerImpl.java
deleted file mode 100644
index 0244029b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedRequestManagerImpl.java
+++ /dev/null
@@ -1,617 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedrequestmanager;
-
-import android.content.Context;
-import android.os.Build;
-import android.util.DisplayMetrics;
-
-import com.google.protobuf.ByteString;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.chrome.browser.feed.library.api.host.config.ApplicationInfo;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest.HttpMethod;
-import org.chromium.chrome.browser.feed.library.api.host.network.NetworkClient;
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipInfo.FeatureName;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipSupportedApi;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionReader;
-import org.chromium.chrome.browser.feed.library.api.internal.common.DismissActionWithSemanticProperties;
-import org.chromium.chrome.browser.feed.library.api.internal.common.Model;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.api.internal.requestmanager.FeedRequestManager;
-import org.chromium.chrome.browser.feed.library.api.internal.store.LocalActionMutation.ActionType;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue.TaskType;
-import org.chromium.chrome.browser.feed.library.common.locale.LocaleUtils;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.protoextensions.FeedExtensionRegistry;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.chrome.browser.feed.library.feedrequestmanager.internal.Utils;
-import org.chromium.chrome.browser.feed.shared.FeedFeatures;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.preferences.Pref;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.profiles.ProfileManager;
-import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-import org.chromium.components.feed.core.proto.wire.ActionTypeProto;
-import org.chromium.components.feed.core.proto.wire.CapabilityProto.Capability;
-import org.chromium.components.feed.core.proto.wire.ChromeFulfillmentInfoProto.ChromeFulfillmentInfo;
-import org.chromium.components.feed.core.proto.wire.ClientInfoProto.ClientInfo;
-import org.chromium.components.feed.core.proto.wire.ClientInfoProto.ClientInfo.PlatformType;
-import org.chromium.components.feed.core.proto.wire.ConsistencyTokenProto.ConsistencyToken;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-import org.chromium.components.feed.core.proto.wire.DisplayInfoProto.DisplayInfo;
-import org.chromium.components.feed.core.proto.wire.FeedActionQueryDataProto.Action;
-import org.chromium.components.feed.core.proto.wire.FeedActionQueryDataProto.FeedActionQueryData;
-import org.chromium.components.feed.core.proto.wire.FeedActionQueryDataProto.FeedActionQueryDataItem;
-import org.chromium.components.feed.core.proto.wire.FeedQueryProto.FeedQuery;
-import org.chromium.components.feed.core.proto.wire.FeedRequestProto.FeedRequest;
-import org.chromium.components.feed.core.proto.wire.FeedResponseProto.FeedResponse;
-import org.chromium.components.feed.core.proto.wire.RequestProto.Request;
-import org.chromium.components.feed.core.proto.wire.RequestProto.Request.RequestVersion;
-import org.chromium.components.feed.core.proto.wire.ResponseProto.Response;
-import org.chromium.components.feed.core.proto.wire.SemanticPropertiesProto.SemanticProperties;
-import org.chromium.components.feed.core.proto.wire.VersionProto.Version;
-import org.chromium.components.feed.core.proto.wire.VersionProto.Version.Architecture;
-import org.chromium.components.feed.core.proto.wire.VersionProto.Version.BuildType;
-import org.chromium.components.user_prefs.UserPrefs;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-/** Default implementation of FeedRequestManager. */
-public class FeedRequestManagerImpl implements FeedRequestManager {
-    private static final String TAG = "FeedRequestManagerImpl";
-
-    static final String NOTICE_CARD_VIEWS_COUNT_THRESHOLD_PARAM_NAME =
-            "notice-card-views-count-threshold";
-    static final String NOTICE_CARD_CLICKS_COUNT_THRESHOLD_PARAM_NAME =
-            "notice-card-clicks-count-threshold";
-
-    private final Configuration mConfiguration;
-    private final NetworkClient mNetworkClient;
-    private final ProtocolAdapter mProtocolAdapter;
-    private final FeedExtensionRegistry mExtensionRegistry;
-    private final SchedulerApi mScheduler;
-    private final TaskQueue mTaskQueue;
-    private final TimingUtils mTimingUtils;
-    private final ThreadUtils mThreadUtils;
-    private final ActionReader mActionReader;
-    private final Context mContext;
-    private final MainThreadRunner mMainThreadRunner;
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final TooltipSupportedApi mTooltipSupportedApi;
-    private final ApplicationInfo mApplicationInfo;
-    private final boolean mSignedIn;
-
-    public FeedRequestManagerImpl(Configuration configuration, NetworkClient networkClient,
-            ProtocolAdapter protocolAdapter, FeedExtensionRegistry extensionRegistry,
-            SchedulerApi scheduler, TaskQueue taskQueue, TimingUtils timingUtils,
-            ThreadUtils threadUtils, ActionReader actionReader, Context context,
-            ApplicationInfo applicationInfo, MainThreadRunner mainThreadRunner,
-            BasicLoggingApi basicLoggingApi, TooltipSupportedApi tooltipSupportedApi) {
-        this.mConfiguration = configuration;
-        this.mNetworkClient = networkClient;
-        this.mProtocolAdapter = protocolAdapter;
-        this.mExtensionRegistry = extensionRegistry;
-        this.mScheduler = scheduler;
-        this.mTaskQueue = taskQueue;
-        this.mTimingUtils = timingUtils;
-        this.mThreadUtils = threadUtils;
-        this.mActionReader = actionReader;
-        this.mContext = context;
-        this.mApplicationInfo = applicationInfo;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mTooltipSupportedApi = tooltipSupportedApi;
-        this.mSignedIn = isSignedIn();
-    }
-
-    @Override
-    public void loadMore(
-            StreamToken streamToken, ConsistencyToken token, Consumer<Result<Model>> consumer) {
-        mThreadUtils.checkNotMainThread();
-
-        Logger.i(TAG, "Task: FeedRequestManagerImpl LoadMore");
-        ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        RequestBuilder request = newDefaultRequest(RequestReason.MANUAL_CONTINUATION)
-                                         .setPageToken(streamToken.getNextPageToken())
-                                         .setConsistencyToken(token);
-        executeRequest(request, consumer, false);
-        timeTracker.stop(
-                "task", "FeedRequestManagerImpl LoadMore", "token", streamToken.getNextPageToken());
-    }
-
-    @Override
-    public void triggerRefresh(@RequestReason int reason, Consumer<Result<Model>> consumer) {
-        triggerRefresh(reason, ConsistencyToken.getDefaultInstance(), consumer);
-    }
-
-    @Override
-    public void triggerRefresh(
-            @RequestReason int reason, ConsistencyToken token, Consumer<Result<Model>> consumer) {
-        Logger.i(TAG, "trigger refresh %s", reason);
-        RequestBuilder request = newDefaultRequest(reason).setConsistencyToken(token);
-
-        if (shouldAcknowledgeNoticeCard()) {
-            request.acknowledgeNoticeCard();
-        }
-
-        if (mThreadUtils.isMainThread()) {
-            // This will make a new request, it should invalidate the existing head to delay
-            // everything until the response is obtained.
-            mTaskQueue.execute(Task.REQUEST_MANAGER_TRIGGER_REFRESH, TaskType.HEAD_INVALIDATE,
-                    () -> executeRequest(request, consumer, true));
-        } else {
-            executeRequest(request, consumer, true);
-        }
-    }
-
-    boolean shouldAcknowledgeNoticeCard() {
-        if (!ChromeFeatureList.isEnabled(
-                    ChromeFeatureList.INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS)) {
-            return false;
-        }
-
-        int viewsCountThreshold = ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS,
-                NOTICE_CARD_VIEWS_COUNT_THRESHOLD_PARAM_NAME, 3);
-        assert viewsCountThreshold >= 0 : "view count threshold cannot be negative";
-
-        int clicksCountThreshold = ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS,
-                NOTICE_CARD_CLICKS_COUNT_THRESHOLD_PARAM_NAME, 1);
-        assert clicksCountThreshold >= 0 : "clicks count threshold cannot be negative";
-
-        // Make sure that there is at least one condition to auto-dismiss the notice card.
-        assert (viewsCountThreshold > 0 || clicksCountThreshold > 0)
-            : String.join(" ", "all notice card auto-dismiss thresholds are set to 0",
-                    "when there should be at least one threshold above 0");
-
-        if (viewsCountThreshold > 0 && getNoticeCardViewsCount() >= viewsCountThreshold) {
-            return true;
-        }
-        if (clicksCountThreshold > 0 && getNoticeCardClicksCount() >= clicksCountThreshold) {
-            return true;
-        }
-
-        return false;
-    }
-
-    private static int getNoticeCardViewsCount() {
-        return UserPrefs.get(Profile.getLastUsedRegularProfile())
-                .getInteger(Pref.NOTICE_CARD_VIEWS_COUNT);
-    }
-
-    private static int getNoticeCardClicksCount() {
-        return UserPrefs.get(Profile.getLastUsedRegularProfile())
-                .getInteger(Pref.NOTICE_CARD_CLICKS_COUNT);
-    }
-
-    private RequestBuilder newDefaultRequest(@RequestReason int requestReason) {
-        return new RequestBuilder(mContext, mApplicationInfo, mConfiguration, requestReason);
-    }
-
-    private static FeedQuery.RequestReason getWireRequestReason(@RequestReason int requestReason) {
-        switch (requestReason) {
-            case RequestReason.ZERO_STATE:
-                return FeedQuery.RequestReason.ZERO_STATE_REFRESH;
-            case RequestReason.HOST_REQUESTED:
-                return FeedQuery.RequestReason.SCHEDULED_REFRESH;
-            case RequestReason.OPEN_WITH_CONTENT:
-                return FeedQuery.RequestReason.WITH_CONTENT;
-                // TODO: distinguish between automatic and manual continuation for wire
-                // protocol
-            case RequestReason.MANUAL_CONTINUATION:
-            case RequestReason.AUTOMATIC_CONTINUATION:
-                return FeedQuery.RequestReason.NEXT_PAGE_SCROLL;
-            case RequestReason.OPEN_WITHOUT_CONTENT:
-                return FeedQuery.RequestReason.INITIAL_LOAD;
-            case RequestReason.CLEAR_ALL:
-                return FeedQuery.RequestReason.CLEAR_ALL;
-            case RequestReason.UNKNOWN:
-                return FeedQuery.RequestReason.UNKNOWN_REQUEST_REASON;
-            default:
-                Logger.wtf(TAG, "Cannot map request reason with value %d", requestReason);
-                return FeedQuery.RequestReason.UNKNOWN_REQUEST_REASON;
-        }
-    }
-
-    boolean isSignedIn() {
-        try {
-            return IdentityServicesProvider.get()
-                    .getIdentityManager(Profile.getLastUsedRegularProfile())
-                    .hasPrimaryAccount();
-        } catch (IllegalStateException e) {
-            assert !ProfileManager.isInitialized();
-        }
-        return false;
-    }
-
-    private void executeRequest(RequestBuilder requestBuilder, Consumer<Result<Model>> consumer,
-            boolean isRefreshRequest) {
-        mThreadUtils.checkNotMainThread();
-        // Do not include Dismiss actions in the FeedQuery request for signed in users.
-        // Dismiss actions for signed in users are uploaded via the ActionsUpload endpoint.
-        if (!mSignedIn) {
-            Result<List<DismissActionWithSemanticProperties>> dismissActionsResult =
-                    mActionReader.getDismissActionsWithSemanticProperties();
-            if (dismissActionsResult.isSuccessful()) {
-                requestBuilder.setActions(dismissActionsResult.getValue());
-            }
-        }
-
-        if (mConfiguration.getValueOrDefault(ConfigKey.CARD_MENU_TOOLTIP_ELIGIBLE, false)) {
-            // We need use the main thread to call the {@link
-            // TooltipSupportedApi#wouldTriggerHelpUi}.
-            mMainThreadRunner.execute("Check Tooltips", () -> {
-                mTooltipSupportedApi.wouldTriggerHelpUi(
-                        FeatureName.CARD_MENU_TOOLTIP, (wouldTrigger) -> {
-                            mTaskQueue.execute(Task.SEND_REQUEST, TaskType.IMMEDIATE, () -> {
-                                requestBuilder.setCardMenuTooltipWouldTrigger(wouldTrigger);
-                                sendRequest(requestBuilder, consumer, isRefreshRequest);
-                            });
-                        });
-            });
-        } else {
-            sendRequest(requestBuilder, consumer, isRefreshRequest);
-        }
-    }
-
-    private static boolean isRequestInteractive(FeedQuery.RequestReason reason) {
-        return !(reason == FeedQuery.RequestReason.SCHEDULED_REFRESH
-                || reason == FeedQuery.RequestReason.WITH_CONTENT);
-    }
-
-    private void sendRequest(RequestBuilder requestBuilder, Consumer<Result<Model>> consumer,
-            boolean isRefreshRequest) {
-        mThreadUtils.checkNotMainThread();
-        String endpoint = mConfiguration.getValueOrDefault(ConfigKey.FEED_SERVER_ENDPOINT, "");
-        @HttpMethod
-        String httpMethod =
-                mConfiguration.getValueOrDefault(ConfigKey.FEED_SERVER_METHOD, HttpMethod.GET);
-        HttpRequest httpRequest =
-                RequestHelper.buildHttpRequest(httpMethod, requestBuilder.build().toByteArray(),
-                        endpoint, LocaleUtils.getLanguageTag(mContext),
-                        isRequestInteractive(requestBuilder.mRequestReason)
-                                ? RequestHelper.PRIORITY_VALUE_INTERACTIVE
-                                : RequestHelper.PRIORITY_VALUE_BACKGROUND);
-
-        Logger.i(TAG, "Making Request: %s", httpRequest.getUri().getPath());
-        mNetworkClient.send(httpRequest, input -> {
-            mBasicLoggingApi.onServerRequest(requestBuilder.mClientLoggingRequestReason);
-            Logger.i(TAG, "Request: %s completed with response code: %s",
-                    httpRequest.getUri().getPath(), input.getResponseCode());
-            if (input.getResponseCode() != 200) {
-                String errorBody = null;
-                try {
-                    errorBody = new String(input.getResponseBody(), "UTF-8");
-                } catch (UnsupportedEncodingException e) {
-                    Logger.e(TAG, "Error handling http error logging", e);
-                }
-                Logger.e(TAG, "errorCode: %d", input.getResponseCode());
-                Logger.e(TAG, "errorResponse: %s", errorBody);
-                if (!requestBuilder.hasPageToken()) {
-                    mScheduler.onRequestError(input.getResponseCode());
-                }
-                mMainThreadRunner.execute(
-                        "FeedRequestManagerImpl consumer", () -> consumer.accept(Result.failure()));
-                return;
-            }
-            handleResponseBytes(
-                    input.getResponseBody(), consumer, isRefreshRequest, input.isSignedIn());
-        });
-    }
-
-    private void handleResponseBytes(final byte[] responseBytes,
-            final Consumer<Result<Model>> consumer, boolean isRefreshRequest, boolean isSignedIn) {
-        mTaskQueue.execute(Task.HANDLE_RESPONSE_BYTES, TaskType.IMMEDIATE, () -> {
-            Response response;
-            boolean isLengthPrefixed = mConfiguration.getValueOrDefault(
-                    ConfigKey.FEED_SERVER_RESPONSE_LENGTH_PREFIXED, true);
-            try {
-                response = Response.parseFrom(isLengthPrefixed
-                                ? RequestHelper.getLengthPrefixedValue(responseBytes)
-                                : responseBytes,
-                        mExtensionRegistry.getExtensionRegistry());
-            } catch (IOException e) {
-                Logger.e(TAG, e, "Response parse failed");
-                mMainThreadRunner.execute(
-                        "FeedRequestManagerImpl consumer", () -> consumer.accept(Result.failure()));
-                return;
-            }
-            logServerCapabilities(response, isRefreshRequest);
-            mMainThreadRunner.execute("FeedRequestManagerImpl consumer", () -> {
-                // Update the signed in pref only when the request is a refresh. It shouldn't be
-                // done for other requests such as load more.
-                if (isRefreshRequest) {
-                    updateLastRefreshSignedPref(isSignedIn);
-                }
-                consumer.accept(mProtocolAdapter.createModel(response));
-            });
-        });
-    }
-
-    private void logServerCapabilities(Response response, boolean isRefreshRequest) {
-        FeedResponse feedResponse = response.getExtension(FeedResponse.feedResponse);
-        List<Capability> capabilities = feedResponse.getServerCapabilitiesList();
-        boolean hasNoticeCard =
-                capabilities.contains(Capability.REPORT_FEED_USER_ACTIONS_NOTICE_CARD);
-        RecordHistogram.recordBooleanHistogram(
-                "ContentSuggestions.Feed.NoticeCardFulfilled", hasNoticeCard);
-        if (isRefreshRequest) {
-            RecordHistogram.recordBooleanHistogram(
-                    "ContentSuggestions.Feed.NoticeCardFulfilled2", hasNoticeCard);
-            mMainThreadRunner.execute("Update notice card pref",
-                    ()
-                            -> updateNoticeCardPref(capabilities.contains(
-                                    Capability.REPORT_FEED_USER_ACTIONS_NOTICE_CARD)));
-        }
-    }
-
-    private void updateNoticeCardPref(boolean hasNoticeCard) {
-        UserPrefs.get(Profile.getLastUsedRegularProfile())
-                .setBoolean(Pref.LAST_FETCH_HAD_NOTICE_CARD, hasNoticeCard);
-    }
-
-    private void updateLastRefreshSignedPref(boolean isSignedIn) {
-        UserPrefs.get(Profile.getLastUsedRegularProfile())
-                .setBoolean(Pref.LAST_REFRESH_WAS_SIGNED_IN, isSignedIn);
-    }
-
-    private static final class RequestBuilder {
-        private ByteString mToken;
-        private ConsistencyToken mConsistencyToken;
-        private List<DismissActionWithSemanticProperties> mDismissActionWithSemanticProperties;
-        private final Context mContext;
-        private final ApplicationInfo mApplicationInfo;
-        private final Configuration mConfiguration;
-        public final FeedQuery.RequestReason mRequestReason;
-        @RequestReason
-        private final int mClientLoggingRequestReason;
-        private boolean mCardMenuTooltipWouldTrigger;
-        private boolean mIsNoticeCardAcknowledged;
-
-        RequestBuilder(Context context, ApplicationInfo applicationInfo,
-                Configuration configuration, @RequestReason int requestReason) {
-            this.mContext = context;
-            this.mApplicationInfo = applicationInfo;
-            this.mConfiguration = configuration;
-            this.mClientLoggingRequestReason = requestReason;
-            this.mRequestReason = getWireRequestReason(requestReason);
-        }
-
-        /**
-         * Sets the token used to tell the server which page of results we want in the response.
-         *
-         * @param token the token copied from FeedResponse.next_page_token.
-         */
-        RequestBuilder setPageToken(ByteString token) {
-            this.mToken = token;
-            return this;
-        }
-
-        boolean hasPageToken() {
-            return mToken != null;
-        }
-        /**
-         * Sets the token used to tell the server which storage version to read/write to.
-         *
-         * @param token the token used to maintain read/write consistency.
-         */
-        RequestBuilder setConsistencyToken(ConsistencyToken token) {
-            this.mConsistencyToken = token;
-            return this;
-        }
-
-        RequestBuilder setActions(
-                List<DismissActionWithSemanticProperties> dismissActionsWithSemanticProperties) {
-            this.mDismissActionWithSemanticProperties = dismissActionsWithSemanticProperties;
-            return this;
-        }
-
-        RequestBuilder setCardMenuTooltipWouldTrigger(boolean wouldTrigger) {
-            mCardMenuTooltipWouldTrigger = wouldTrigger;
-            return this;
-        }
-
-        public Request build() {
-            Request.Builder requestBuilder =
-                    Request.newBuilder().setRequestVersion(RequestVersion.FEED_QUERY);
-
-            FeedQuery.Builder feedQuery = FeedQuery.newBuilder().setReason(mRequestReason);
-            if (mToken != null) {
-                feedQuery.setPageToken(mToken);
-            }
-            if (mIsNoticeCardAcknowledged) {
-                feedQuery.setChromeFulfillmentInfo(
-                        ChromeFulfillmentInfo.newBuilder().setNoticeCardAcknowledged(true));
-            }
-            FeedRequest.Builder feedRequestBuilder =
-                    FeedRequest.newBuilder().setFeedQuery(feedQuery);
-            if (mConsistencyToken != null) {
-                feedRequestBuilder.setConsistencyToken(mConsistencyToken);
-                Logger.i(TAG, "Consistency Token: %s", mConsistencyToken);
-            }
-            if (mDismissActionWithSemanticProperties != null
-                    && !mDismissActionWithSemanticProperties.isEmpty()) {
-                feedRequestBuilder.addFeedActionQueryData(buildFeedActionQueryData());
-            }
-            feedRequestBuilder.setClientInfo(buildClientInfo());
-            addCapabilities(feedRequestBuilder);
-            requestBuilder.setExtension(FeedRequest.feedRequest, feedRequestBuilder.build());
-
-            return requestBuilder.build();
-        }
-
-        public void acknowledgeNoticeCard() {
-            mIsNoticeCardAcknowledged = true;
-        }
-
-        private void addCapabilities(FeedRequest.Builder feedRequestBuilder) {
-            addCapabilityIfConfigEnabled(
-                    feedRequestBuilder, ConfigKey.FEED_UI_ENABLED, Capability.FEED_UI);
-            addCapabilityIfConfigEnabled(feedRequestBuilder, ConfigKey.UNDOABLE_ACTIONS_ENABLED,
-                    Capability.UNDOABLE_ACTIONS);
-            addCapabilityIfConfigEnabled(feedRequestBuilder, ConfigKey.MANAGE_INTERESTS_ENABLED,
-                    Capability.MANAGE_INTERESTS);
-            feedRequestBuilder.addClientCapability(Capability.SEND_FEEDBACK);
-            addCapabilityIfConfigEnabled(
-                    feedRequestBuilder, ConfigKey.ENABLE_CAROUSELS, Capability.CAROUSELS);
-            if (mCardMenuTooltipWouldTrigger) {
-                addCapabilityIfConfigEnabled(feedRequestBuilder,
-                        ConfigKey.CARD_MENU_TOOLTIP_ELIGIBLE, Capability.CARD_MENU_TOOLTIP);
-            }
-            addCapabilityIfConfigEnabled(
-                    feedRequestBuilder, ConfigKey.SNIPPETS_ENABLED, Capability.ARTICLE_SNIPPETS);
-            addCapabilityIfConfigEnabled(feedRequestBuilder, ConfigKey.USE_SECONDARY_PAGE_REQUEST,
-                    Capability.USE_SECONDARY_PAGE_REQUEST);
-
-            if (FeedFeatures.isReportingUserActions()) {
-                feedRequestBuilder.addClientCapability(Capability.CLICK_ACTION);
-                feedRequestBuilder.addClientCapability(Capability.VIEW_ACTION);
-                feedRequestBuilder.addClientCapability(
-                        Capability.REPORT_FEED_USER_ACTIONS_NOTICE_CARD);
-            }
-
-            feedRequestBuilder.addClientCapability(Capability.BASE_UI);
-
-            for (Capability capability : feedRequestBuilder.getClientCapabilityList()) {
-                Logger.i(TAG, "Capability: %s", capability.name());
-            }
-        }
-
-        private void addCapabilityIfConfigEnabled(
-                FeedRequest.Builder feedRequestBuilder, String configKey, Capability capability) {
-            if (mConfiguration.getValueOrDefault(configKey, false)) {
-                feedRequestBuilder.addClientCapability(capability);
-            }
-        }
-
-        private FeedActionQueryData buildFeedActionQueryData() {
-            Map<Long, Integer> ids =
-                    new LinkedHashMap<>(mDismissActionWithSemanticProperties.size());
-            Map<String, Integer> tables =
-                    new LinkedHashMap<>(mDismissActionWithSemanticProperties.size());
-            Map<String, Integer> contentDomains =
-                    new LinkedHashMap<>(mDismissActionWithSemanticProperties.size());
-            Map<SemanticProperties, Integer> semanticProperties =
-                    new LinkedHashMap<>(mDismissActionWithSemanticProperties.size());
-            ArrayList<FeedActionQueryDataItem> actionDataItems =
-                    new ArrayList<>(mDismissActionWithSemanticProperties.size());
-
-            for (DismissActionWithSemanticProperties action :
-                    mDismissActionWithSemanticProperties) {
-                ContentId contentId = action.getContentId();
-                byte[] semanticPropertiesBytes = action.getSemanticProperties();
-
-                FeedActionQueryDataItem.Builder actionDataItemBuilder =
-                        FeedActionQueryDataItem.newBuilder();
-
-                actionDataItemBuilder.setIdIndex(getIndexForItem(ids, contentId.getId()));
-                actionDataItemBuilder.setTableIndex(getIndexForItem(tables, contentId.getTable()));
-                actionDataItemBuilder.setContentDomainIndex(
-                        getIndexForItem(contentDomains, contentId.getContentDomain()));
-                if (semanticPropertiesBytes != null) {
-                    actionDataItemBuilder.setSemanticPropertiesIndex(
-                            getIndexForItem(semanticProperties,
-                                    SemanticProperties.newBuilder()
-                                            .setSemanticPropertiesData(
-                                                    ByteString.copyFrom(semanticPropertiesBytes))
-                                            .build()));
-                }
-
-                actionDataItems.add(actionDataItemBuilder.build());
-            }
-            return FeedActionQueryData.newBuilder()
-                    .setAction(Action.newBuilder().setActionType(
-                            ActionTypeProto.ActionType.forNumber(ActionType.DISMISS)))
-                    .addAllUniqueId(ids.keySet())
-                    .addAllUniqueTable(tables.keySet())
-                    .addAllUniqueContentDomain(contentDomains.keySet())
-                    .addAllUniqueSemanticProperties(semanticProperties.keySet())
-                    .addAllFeedActionQueryDataItem(actionDataItems)
-                    .build();
-        }
-
-        private static <T> int getIndexForItem(Map<T, Integer> objectMap, T object) {
-            if (!objectMap.containsKey(object)) {
-                int newIndex = objectMap.size();
-                objectMap.put(object, newIndex);
-                return newIndex;
-            } else {
-                return objectMap.get(object);
-            }
-        }
-
-        private ClientInfo buildClientInfo() {
-            ClientInfo.Builder clientInfoBuilder = ClientInfo.newBuilder();
-            clientInfoBuilder.setPlatformType(PlatformType.ANDROID_ID);
-            clientInfoBuilder.setPlatformVersion(getPlatformVersion());
-            clientInfoBuilder.setLocale(LocaleUtils.getLanguageTag(mContext));
-            clientInfoBuilder.setAppType(Utils.convertAppType(mApplicationInfo.getAppType()));
-            clientInfoBuilder.setAppVersion(getAppVersion());
-            DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
-            clientInfoBuilder.addDisplayInfo(
-                    DisplayInfo.newBuilder()
-                            .setScreenDensity(metrics.density)
-                            .setScreenWidthInPixels(metrics.widthPixels)
-                            .setScreenHeightInPixels(metrics.heightPixels));
-            return clientInfoBuilder.build();
-        }
-
-        private static Version getPlatformVersion() {
-            Version.Builder builder = Version.newBuilder();
-            Utils.fillVersionsFromString(builder, Build.VERSION.RELEASE);
-            builder.setArchitecture(getPlatformArchitecture());
-            builder.setBuildType(getPlatformBuildType());
-            builder.setApiVersion(Build.VERSION.SDK_INT);
-            return builder.build();
-        }
-
-        private static Architecture getPlatformArchitecture() {
-            String androidAbi = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
-                    ? Build.SUPPORTED_ABIS[0]
-                    : Build.CPU_ABI;
-            return Utils.convertArchitectureString(androidAbi);
-        }
-
-        private static BuildType getPlatformBuildType() {
-            if (Build.TAGS != null) {
-                if (Build.TAGS.contains("dev-keys") || Build.TAGS.contains("test-keys")) {
-                    return BuildType.DEV;
-                } else if (Build.TAGS.contains("release-keys")) {
-                    return BuildType.RELEASE;
-                }
-            }
-            return BuildType.UNKNOWN_BUILD_TYPE;
-        }
-
-        private Version getAppVersion() {
-            Version.Builder builder = Version.newBuilder();
-            Utils.fillVersionsFromString(builder, mApplicationInfo.getVersionString());
-            builder.setArchitecture(Utils.convertArchitecture(mApplicationInfo.getArchitecture()));
-            builder.setBuildType(Utils.convertBuildType(mApplicationInfo.getBuildType()));
-            return builder.build();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/RequestHelper.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/RequestHelper.java
deleted file mode 100644
index 8fd90af6..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/RequestHelper.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedrequestmanager;
-
-import android.net.Uri;
-import android.util.Base64;
-
-import com.google.protobuf.CodedInputStream;
-
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest.HttpMethod;
-
-import java.io.IOException;
-import java.util.Collections;
-
-/** A class that helps build and sent requests to the server */
-public final class RequestHelper {
-    public static final String MOTHERSHIP_PARAM_PAYLOAD = "reqpld";
-    public static final String LOCALE_PARAM = "hl";
-    private static final String MOTHERSHIP_PARAM_FORMAT = "fmt";
-    private static final String MOTHERSHIP_VALUE_BINARY = "bin";
-    public static final String PRIORITY_PARAM = "bq";
-    public static final String PRIORITY_VALUE_BACKGROUND = "1";
-    public static final String PRIORITY_VALUE_INTERACTIVE = "0";
-
-    private RequestHelper() {}
-
-    /**
-     * Returns the first length-prefixed value from {@code input}. The first bytes of input are
-     * assumed to be a varint32 encoding the length of the rest of the message. If input contains
-     * more than one message, only the first message is returned.i w
-     *
-     * @throws IOException if input cannot be parsed
-     */
-    static byte[] getLengthPrefixedValue(byte[] input) throws IOException {
-        CodedInputStream codedInputStream = CodedInputStream.newInstance(input);
-        if (codedInputStream.isAtEnd()) {
-            throw new IOException("Empty length-prefixed response");
-        } else {
-            int length = codedInputStream.readRawVarint32();
-            return codedInputStream.readRawBytes(length);
-        }
-    }
-
-    static HttpRequest buildHttpRequest(String httpMethod, byte[] bytes, String endpoint,
-            String locale, String priorityParamValue) {
-        boolean isPostMethod = HttpMethod.POST.equals(httpMethod);
-        Uri.Builder uriBuilder = Uri.parse(endpoint).buildUpon();
-        if (!isPostMethod) {
-            uriBuilder.appendQueryParameter(MOTHERSHIP_PARAM_PAYLOAD,
-                    Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP));
-        }
-
-        uriBuilder.appendQueryParameter(MOTHERSHIP_PARAM_FORMAT, MOTHERSHIP_VALUE_BINARY);
-        if (!locale.isEmpty()) {
-            uriBuilder.appendQueryParameter(LOCALE_PARAM, locale);
-        }
-        if (!priorityParamValue.isEmpty()) {
-            uriBuilder.appendQueryParameter(PRIORITY_PARAM, priorityParamValue);
-        }
-
-        return new HttpRequest(uriBuilder.build(), httpMethod, Collections.emptyList(),
-                isPostMethod ? bytes : new byte[] {});
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/RequestManagerImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/RequestManagerImpl.java
deleted file mode 100644
index ffd34ee..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/RequestManagerImpl.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedrequestmanager;
-
-import org.chromium.chrome.browser.feed.library.api.client.requestmanager.RequestManager;
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.api.internal.requestmanager.FeedRequestManager;
-import org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager;
-
-/** Implementation of Client-visible RequestManagerApi. */
-public final class RequestManagerImpl implements RequestManager {
-    private static final String TAG = "RequestManagerImpl";
-
-    private final FeedRequestManager mFeedRequestManager;
-    private final FeedSessionManager mFeedSessionManager;
-
-    public RequestManagerImpl(
-            FeedRequestManager feedRequestManager, FeedSessionManager feedSessionManager) {
-        this.mFeedRequestManager = feedRequestManager;
-        this.mFeedSessionManager = feedSessionManager;
-    }
-
-    @Override
-    public void triggerScheduledRefresh() {
-        mFeedRequestManager.triggerRefresh(RequestReason.HOST_REQUESTED,
-                mFeedSessionManager.getUpdateConsumer(MutationContext.EMPTY_CONTEXT));
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/UploadableActionsRequestBuilder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/UploadableActionsRequestBuilder.java
deleted file mode 100644
index 8db0e01..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/UploadableActionsRequestBuilder.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedrequestmanager;
-
-import com.google.protobuf.ByteString;
-
-import org.chromium.chrome.browser.feed.library.api.internal.common.SemanticPropertiesWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-import org.chromium.components.feed.core.proto.wire.ActionPayloadProto.ActionPayload;
-import org.chromium.components.feed.core.proto.wire.ActionRequestProto.ActionRequest;
-import org.chromium.components.feed.core.proto.wire.ConsistencyTokenProto.ConsistencyToken;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-import org.chromium.components.feed.core.proto.wire.FeedActionProto.FeedAction;
-import org.chromium.components.feed.core.proto.wire.FeedActionRequestProto.FeedActionRequest;
-import org.chromium.components.feed.core.proto.wire.SemanticPropertiesProto.SemanticProperties;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Set;
-
-// A class that creates an ActionsRequest for uploading actions
-final class UploadableActionsRequestBuilder {
-    private Set<StreamUploadableAction> mUploadableActions;
-    private ConsistencyToken mToken;
-    private final ProtocolAdapter mProtocolAdapter;
-    private final HashMap<String, byte[]> mSemanticPropertiesMap = new HashMap<>();
-
-    UploadableActionsRequestBuilder(ProtocolAdapter protocolAdapter) {
-        this.mProtocolAdapter = protocolAdapter;
-    }
-
-    UploadableActionsRequestBuilder setConsistencyToken(ConsistencyToken token) {
-        this.mToken = token;
-        return this;
-    }
-
-    boolean hasConsistencyToken() {
-        return mToken != null;
-    }
-
-    UploadableActionsRequestBuilder setActions(Set<StreamUploadableAction> uploadableActions) {
-        this.mUploadableActions = uploadableActions;
-        return this;
-    }
-
-    UploadableActionsRequestBuilder setSemanticProperties(
-            List<SemanticPropertiesWithId> semanticPropertiesList) {
-        for (SemanticPropertiesWithId semanticProperties : semanticPropertiesList) {
-            mSemanticPropertiesMap.put(
-                    semanticProperties.contentId, semanticProperties.semanticData);
-        }
-        return this;
-    }
-
-    public ActionRequest build() {
-        ActionRequest.Builder requestBuilder = ActionRequest.newBuilder().setRequestVersion(
-                ActionRequest.RequestVersion.FEED_UPLOAD_ACTION);
-        FeedActionRequest.Builder feedActionRequestBuilder = FeedActionRequest.newBuilder();
-        if (mUploadableActions != null) {
-            for (StreamUploadableAction action : mUploadableActions) {
-                String contentId = action.getFeatureContentId();
-                ActionPayload payload = action.getPayload();
-                FeedAction.Builder feedAction =
-                        FeedAction.newBuilder().setActionPayload(payload).setClientData(
-                                FeedAction.ClientData.newBuilder()
-                                        .setTimestampSeconds(action.getTimestampSeconds())
-                                        .setDurationMs(action.getDurationMs())
-                                        .build());
-                if (mSemanticPropertiesMap.containsKey(contentId)) {
-                    feedAction.setSemanticProperties(
-                            SemanticProperties.newBuilder().setSemanticPropertiesData(
-                                    ByteString.copyFrom(mSemanticPropertiesMap.get(contentId))));
-                }
-                Result<ContentId> contentIdResult = mProtocolAdapter.getWireContentId(contentId);
-                if (contentIdResult.isSuccessful()) {
-                    feedAction.setContentId(contentIdResult.getValue());
-                }
-                feedActionRequestBuilder.addFeedAction(feedAction);
-            }
-        }
-        if (hasConsistencyToken()) {
-            feedActionRequestBuilder.setConsistencyToken(mToken);
-        }
-        requestBuilder.setExtension(
-                FeedActionRequest.feedActionRequest, feedActionRequestBuilder.build());
-
-        return requestBuilder.build();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/internal/Utils.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/internal/Utils.java
deleted file mode 100644
index 10576327..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/internal/Utils.java
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedrequestmanager.internal;
-
-import android.text.TextUtils;
-
-import org.chromium.chrome.browser.feed.library.api.host.config.ApplicationInfo.AppType;
-import org.chromium.chrome.browser.feed.library.api.host.config.ApplicationInfo.Architecture;
-import org.chromium.chrome.browser.feed.library.api.host.config.ApplicationInfo.BuildType;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.components.feed.core.proto.wire.ClientInfoProto.ClientInfo;
-import org.chromium.components.feed.core.proto.wire.VersionProto.Version;
-
-import java.text.NumberFormat;
-import java.text.ParseException;
-
-/** Parsing and conversion static methods. */
-public final class Utils {
-    private static final String TAG = "Utils";
-
-    // Do not instantiate
-    private Utils() {}
-
-    /**
-     * Fills in the major/minor/build/revision part of a {@link Version} builder from a given
-     * string. A version string typically looks like: 'major.minor.build.revision'.
-     */
-    public static void fillVersionsFromString(
-            Version.Builder versionBuilder, String versionString) {
-        String[] values = TextUtils.split(versionString, "\\.");
-        if (values.length >= 1) {
-            try {
-                versionBuilder.setMajor(parseLeadingInt(values[0]));
-                if (values.length >= 2) {
-                    versionBuilder.setMinor(parseLeadingInt(values[1]));
-                    if (values.length >= 3) {
-                        versionBuilder.setBuild(parseLeadingInt(values[2]));
-                        if (values.length >= 4) {
-                            versionBuilder.setRevision(parseLeadingInt(values[3]));
-                        }
-                    }
-                }
-            } catch (ParseException e) {
-                Logger.w(TAG, e, "Invalid int value while parsing string version: %s",
-                        versionString);
-            }
-        } else {
-            Logger.w(TAG, "Invalid format while parsing string version: %s" + versionString);
-        }
-    }
-
-    public static ClientInfo.AppType convertAppType(@AppType int type) {
-        switch (type) {
-            case AppType.SEARCH_APP:
-                return ClientInfo.AppType.GSA;
-            case AppType.CHROME:
-                return ClientInfo.AppType.CHROME;
-            case AppType.TEST_APP:
-                return ClientInfo.AppType.TEST_APP;
-            default:
-                return ClientInfo.AppType.UNKNOWN_APP;
-        }
-    }
-
-    public static Version.Architecture convertArchitecture(@Architecture int architecture) {
-        switch (architecture) {
-            case Architecture.ARM:
-                return Version.Architecture.ARM;
-            case Architecture.ARM64:
-                return Version.Architecture.ARM64;
-            case Architecture.MIPS:
-                return Version.Architecture.MIPS;
-            case Architecture.MIPS64:
-                return Version.Architecture.MIPS64;
-            case Architecture.X86:
-                return Version.Architecture.X86;
-            case Architecture.X86_64:
-                return Version.Architecture.X86_64;
-            default:
-                return Version.Architecture.UNKNOWN_ACHITECTURE;
-        }
-    }
-
-    public static Version.Architecture convertArchitectureString(String architecture) {
-        switch (architecture) {
-            case "armeabi":
-            case "armeabi-v7a":
-                return Version.Architecture.ARM;
-            case "arm64-v8a":
-                return Version.Architecture.ARM64;
-            case "mips":
-                return Version.Architecture.MIPS;
-            case "mips64":
-                return Version.Architecture.MIPS64;
-            case "x86":
-                return Version.Architecture.X86;
-            case "x86_64":
-                return Version.Architecture.X86_64;
-            default:
-                return Version.Architecture.UNKNOWN_ACHITECTURE;
-        }
-    }
-
-    public static Version.BuildType convertBuildType(@BuildType int buildType) {
-        switch (buildType) {
-            case BuildType.DEV:
-                return Version.BuildType.DEV;
-            case BuildType.ALPHA:
-                return Version.BuildType.ALPHA;
-            case BuildType.BETA:
-                return Version.BuildType.BETA;
-            case BuildType.RELEASE:
-                return Version.BuildType.RELEASE;
-            default:
-                return Version.BuildType.UNKNOWN_BUILD_TYPE;
-        }
-    }
-
-    private static int parseLeadingInt(String value) throws ParseException {
-        NumberFormat integerParser = NumberFormat.getIntegerInstance();
-        return integerParser.parse(value).intValue();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/FeedSessionManagerFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/FeedSessionManagerFactory.java
deleted file mode 100644
index 9f801c0..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/FeedSessionManagerFactory.java
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedsessionmanager;
-
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.api.internal.requestmanager.ActionUploadRequestManager;
-import org.chromium.chrome.browser.feed.library.api.internal.requestmanager.FeedRequestManager;
-import org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.feedobservable.FeedObservable;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.feedapplifecyclelistener.FeedLifecycleListener;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.internal.ContentCache;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.internal.SessionCache;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.internal.SessionFactory;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.internal.SessionManagerMutation;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Factory which creates the {@link FeedSessionManager}. This creates all the support classes before
- * creating the FeedSessionManager instead of creating the support objects inside the class
- * constructor.
- */
-public final class FeedSessionManagerFactory {
-    private static final long DEFAULT_LIFETIME_MS = TimeUnit.HOURS.toMillis(1L);
-
-    private final TaskQueue mTaskQueue;
-    private final Store mStore;
-    private final TimingUtils mTimingUtils;
-    private final ThreadUtils mThreadUtils;
-    private final ProtocolAdapter mProtocolAdapter;
-    private final FeedRequestManager mFeedRequestManager;
-    private final ActionUploadRequestManager mActionUploadRequestManager;
-    private final SchedulerApi mSchedulerApi;
-    private final Configuration mConfiguration;
-    private final Clock mClock;
-    private final FeedObservable<FeedLifecycleListener> mLifecycleListenerObservable;
-    private final MainThreadRunner mMainThreadRunner;
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final ActionManager mActionManager;
-
-    public FeedSessionManagerFactory(TaskQueue taskQueue, Store store, TimingUtils timingUtils,
-            ThreadUtils threadUtils, ProtocolAdapter protocolAdapter,
-            FeedRequestManager feedRequestManager,
-            ActionUploadRequestManager actionUploadRequestManager, SchedulerApi schedulerApi,
-            Configuration configuration, Clock clock,
-            FeedObservable<FeedLifecycleListener> lifecycleListenerObservable,
-            MainThreadRunner mainThreadRunner, BasicLoggingApi basicLoggingApi,
-            ActionManager actionManager) {
-        this.mTaskQueue = taskQueue;
-        this.mStore = store;
-        this.mTimingUtils = timingUtils;
-        this.mThreadUtils = threadUtils;
-        this.mProtocolAdapter = protocolAdapter;
-        this.mFeedRequestManager = feedRequestManager;
-        this.mActionUploadRequestManager = actionUploadRequestManager;
-        this.mSchedulerApi = schedulerApi;
-        this.mConfiguration = configuration;
-        this.mClock = clock;
-        this.mLifecycleListenerObservable = lifecycleListenerObservable;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mActionManager = actionManager;
-    }
-
-    /** Creates a new FeedSessionManager and initializes it */
-    public FeedSessionManagerImpl create() {
-        long lifetimeMs = mConfiguration.getValueOrDefault(
-                ConfigKey.SESSION_LIFETIME_MS, DEFAULT_LIFETIME_MS);
-        SessionFactory sessionFactory =
-                new SessionFactory(mStore, mTaskQueue, mTimingUtils, mThreadUtils, mConfiguration);
-        SessionCache sessionCache = new SessionCache(
-                mStore, mTaskQueue, sessionFactory, lifetimeMs, mTimingUtils, mThreadUtils, mClock);
-        ContentCache contentCache = new ContentCache();
-        SessionManagerMutation sessionManagerMutation = new SessionManagerMutation(mStore,
-                sessionCache, contentCache, mTaskQueue, mSchedulerApi, mThreadUtils, mTimingUtils,
-                mClock, mMainThreadRunner, mBasicLoggingApi);
-
-        return new FeedSessionManagerImpl(mTaskQueue, sessionFactory, sessionCache,
-                sessionManagerMutation, contentCache, mStore, mTimingUtils, mThreadUtils,
-                mProtocolAdapter, mFeedRequestManager, mActionUploadRequestManager, mSchedulerApi,
-                mConfiguration, mClock, mLifecycleListenerObservable, mMainThreadRunner,
-                mBasicLoggingApi, mActionManager);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/FeedSessionManagerImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/FeedSessionManagerImpl.java
deleted file mode 100644
index 3817de6..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/FeedSessionManagerImpl.java
+++ /dev/null
@@ -1,986 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedsessionmanager;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.Function;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.KnownContent;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.KnownContent.Listener;
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.InternalFeedError;
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi;
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi.RequestBehavior;
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi.SessionState;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.common.Model;
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelError;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelError.ErrorType;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider.ViewDepthProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.api.internal.requestmanager.ActionUploadRequestManager;
-import org.chromium.chrome.browser.feed.library.api.internal.requestmanager.FeedRequestManager;
-import org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.api.internal.store.StoreListener;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.Validators;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue.TaskType;
-import org.chromium.chrome.browser.feed.library.common.feedobservable.FeedObservable;
-import org.chromium.chrome.browser.feed.library.common.intern.HashPoolInterner;
-import org.chromium.chrome.browser.feed.library.common.intern.InternedMap;
-import org.chromium.chrome.browser.feed.library.common.intern.Interner;
-import org.chromium.chrome.browser.feed.library.common.intern.InternerWithStats;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.logging.StringFormattingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.chrome.browser.feed.library.feedapplifecyclelistener.FeedLifecycleListener;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.internal.ContentCache;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.internal.HeadAsStructure;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.internal.HeadAsStructure.TreeNode;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.internal.InitializableSession;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.internal.Session;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.internal.SessionCache;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.internal.SessionFactory;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.internal.SessionManagerMutation;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.preferences.Pref;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure.Operation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-import org.chromium.components.feed.core.proto.wire.ConsistencyTokenProto.ConsistencyToken;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-import org.chromium.components.feed.core.proto.wire.PietSharedStateItemProto.PietSharedStateItem;
-import org.chromium.components.user_prefs.UserPrefs;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/** Implementation of the FeedSessionManager. All state is kept in memory. */
-public final class FeedSessionManagerImpl
-        implements FeedSessionManager, StoreListener, FeedLifecycleListener, Dumpable {
-    private static final String TAG = "FeedSessionManagerImpl";
-
-    private static final long TIMEOUT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(5L);
-
-    // For the Shared State we will always cache them in the Session Manager
-    // Accessed on main thread, updated on Executor task
-    private final InternerWithStats<StreamSharedState> mSharedStateInterner =
-            new InternerWithStats<>(new StreamSharedStateInterner());
-    private final Map<String, StreamSharedState> mSharedStateCache =
-            new InternedMap<>(new HashMap<>(), mSharedStateInterner);
-
-    // All writes are done on background threads, there are accesses on the main thread.  Leaving
-    // the lock back accessibleContentSupplier may eventually run on a background task and not
-    // on the executor thread.
-    private final SessionCache mSessionCache;
-
-    // All access to the content cache happens on the executor thread so there is no need to
-    // synchronize access.
-    private final ContentCache mContentCache;
-
-    @VisibleForTesting
-    final AtomicBoolean mInitialized = new AtomicBoolean(false);
-
-    private final Object mLock = new Object();
-
-    // Keep track of sessions being created which haven't been added to the SessionCache.
-    // This is accessed on the main thread and the background thread.
-    @GuardedBy("mLock")
-    private final List<InitializableSession> mSessionsUnderConstruction = new ArrayList<>();
-
-    // This captures the NO_CARDS_ERROR when a request fails. The request fails in one task and this
-    // is sent to the ModelProvider in the populateSessionTask.
-    @Nullable
-    private ModelError mNoCardsError;
-
-    private final SessionFactory mSessionFactory;
-    private final SessionManagerMutation mSessionManagerMutation;
-    private final Store mStore;
-    private final ThreadUtils mThreadUtils;
-    private final TimingUtils mTimingUtils;
-    private final ProtocolAdapter mProtocolAdapter;
-    private final FeedRequestManager mRequestManager;
-    private final ActionUploadRequestManager mActionUploadRequestManager;
-    private final SchedulerApi mSchedulerApi;
-    private final TaskQueue mTaskQueue;
-    private final Clock mClock;
-    private final Configuration mConfiguration;
-    private final MainThreadRunner mMainThreadRunner;
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final ActionManager mActionManager;
-    private final long mSessionPopulationTimeoutMs;
-    private final boolean mUploadingActionsEnabled;
-
-    @VisibleForTesting
-    final Set<SessionMutationTracker> mOutstandingMutations = new HashSet<>();
-
-    // operation counts for the dumper
-    private int mNewSessionCount;
-    private int mExistingSessionCount;
-    private int mHandleTokenCount;
-    private Listener mKnownContentListener;
-
-    @SuppressWarnings("argument.type.incompatible") // ok call to registerObserver
-    public FeedSessionManagerImpl(TaskQueue taskQueue, SessionFactory sessionFactory,
-            SessionCache sessionCache, SessionManagerMutation sessionManagerMutation,
-            ContentCache contentCache, Store store, TimingUtils timingUtils,
-            ThreadUtils threadUtils, ProtocolAdapter protocolAdapter,
-            FeedRequestManager feedRequestManager,
-            ActionUploadRequestManager actionUploadRequestManager, SchedulerApi schedulerApi,
-            Configuration configuration, Clock clock,
-            FeedObservable<FeedLifecycleListener> lifecycleListenerObservable,
-            MainThreadRunner mainThreadRunner, BasicLoggingApi basicLoggingApi,
-            ActionManager actionManager) {
-        this.mTaskQueue = taskQueue;
-        this.mSessionFactory = sessionFactory;
-        this.mSessionCache = sessionCache;
-        this.mSessionManagerMutation = sessionManagerMutation;
-        this.mContentCache = contentCache;
-
-        this.mStore = store;
-        this.mTimingUtils = timingUtils;
-        this.mThreadUtils = threadUtils;
-        this.mProtocolAdapter = protocolAdapter;
-        this.mRequestManager = feedRequestManager;
-        this.mActionUploadRequestManager = actionUploadRequestManager;
-        this.mSchedulerApi = schedulerApi;
-        this.mClock = clock;
-        this.mConfiguration = configuration;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mActionManager = actionManager;
-        mUploadingActionsEnabled =
-                configuration.getValueOrDefault(ConfigKey.UNDOABLE_ACTIONS_ENABLED, false);
-        mSessionPopulationTimeoutMs =
-                configuration.getValueOrDefault(ConfigKey.TIMEOUT_TIMEOUT_MS, TIMEOUT_TIMEOUT_MS);
-        lifecycleListenerObservable.registerObserver(this);
-        Logger.i(TAG, "FeedSessionManagerImpl has been created");
-    }
-
-    /**
-     * Called to initialize the session manager. This creates an executor task which does the actual
-     * work of setting up the current state. If this is not called, the session manager will not
-     * populate new or existing sessions. There isn't error checking on this since this happens on
-     * an executor task.
-     */
-    public void initialize() {
-        boolean init = mInitialized.getAndSet(true);
-        if (init) {
-            Logger.w(TAG, "FeedSessionManagerImpl has previously been initialized");
-            return;
-        }
-        mStore.registerObserver(this);
-        mTaskQueue.initialize(this::initializationTask);
-    }
-
-    // Task which initializes the Session Manager.  This must be the first task run on the
-    // Session Manager thread so it's complete before we create any sessions.
-    private void initializationTask() {
-        mThreadUtils.checkNotMainThread();
-        Thread currentThread = Thread.currentThread();
-        currentThread.setName("JardinExecutor");
-        mTimingUtils.pinThread(currentThread, "JardinExecutor");
-
-        ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        // Initialize the Shared States cached here.
-        ElapsedTimeTracker sharedStateTimeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        Result<List<StreamSharedState>> sharedStatesResult = mStore.getSharedStates();
-        if (sharedStatesResult.isSuccessful()) {
-            for (StreamSharedState sharedState : sharedStatesResult.getValue()) {
-                mSharedStateCache.put(sharedState.getContentId(), sharedState);
-            }
-        } else {
-            // without shared states we need to switch to ephemeral mode
-            switchToEphemeralMode("SharedStates failed to load, no shared states are loaded.");
-            mTaskQueue.reset();
-            sharedStateTimeTracker.stop("", "sharedStateTimeTracker", "error", "store error");
-            timeTracker.stop("task", "Initialization", "error", "switchToEphemeralMode");
-            return;
-        }
-        sharedStateTimeTracker.stop("", "sharedStateTimeTracker");
-
-        // create the head session from the data in the Store
-        if (!mSessionCache.initialize()) {
-            // we failed to initialize the sessionCache, so switch to ephemeral mode.
-            switchToEphemeralMode("unable to initialize the sessionCache");
-            timeTracker.stop("task", "Initialization", "error", "switchToEphemeralMode");
-            return;
-        }
-        timeTracker.stop("task", "Initialization");
-    }
-
-    @Override
-    public void getNewSession(ModelProvider modelProvider,
-            @Nullable ViewDepthProvider viewDepthProvider, UiContext uiContext) {
-        mThreadUtils.checkMainThread();
-        if (!mInitialized.get()) {
-            Logger.i(TAG, "Lazy initialization triggered, getNewSession");
-            initialize();
-        }
-        InitializableSession session = mSessionFactory.getSession();
-        session.bindModelProvider(modelProvider, viewDepthProvider);
-        synchronized (mLock) {
-            mSessionsUnderConstruction.add(session);
-        }
-
-        if (!mSessionCache.isHeadInitialized()) {
-            Logger.i(TAG, "Delaying populateSession until initialization is finished");
-            mTaskQueue.execute(Task.GET_NEW_SESSION, TaskType.IMMEDIATE,
-                    () -> populateSession(session, uiContext));
-        } else {
-            populateSession(session, uiContext);
-        }
-    }
-
-    // This method can be run either on the main thread or on the background thread. It calls the
-    // SchedulerApi to determine how the session is created. It creates a new task to populate the
-    // new session.
-    private void populateSession(InitializableSession session, UiContext uiContext) {
-        // Create SessionState and call SchedulerApi to determine what the session-creation
-        // experience should be.
-        SessionState sessionState = new SessionState(!mSessionCache.getHead().isHeadEmpty(),
-                mSessionCache.getHeadLastAddedTimeMillis(), mTaskQueue.isMakingRequest());
-        Logger.i(TAG,
-                "shouldSessionRequestData; hasContent(%b), contentCreationTime(%d),"
-                        + " outstandingRequest(%b)",
-                sessionState.hasContent, sessionState.contentCreationDateTimeMs,
-                sessionState.hasOutstandingRequest);
-        @RequestBehavior
-        int behavior = mSchedulerApi.shouldSessionRequestData(sessionState);
-
-        // Based on sessionState and behavior, determine if FeedSessionManager should start a
-        // request, append an ongoing request to this session, or include a timeout.
-        boolean shouldAppendOutstandingRequest = shouldAppendToSession(sessionState, behavior);
-        boolean shouldStartRequest = shouldStartRequest(sessionState, behavior);
-        Runnable timeoutTask = shouldPopulateWithTimeout(sessionState, behavior) ? ()
-                -> populateSessionTask(session, shouldAppendOutstandingRequest, uiContext)
-                : null;
-        Logger.i(TAG,
-                "shouldSessionRequestDataResult: %s, shouldMakeRequest(%b), withTimeout(%b),"
-                        + " withAppend(%b)",
-                requestBehaviorToString(behavior), shouldStartRequest, timeoutTask != null,
-                shouldAppendOutstandingRequest);
-
-        // If we are making a request, there are two orders, request -> populate for all cases
-        // except for REQUEST_WITH_CONTENT which is populate -> request.
-        if (shouldStartRequest && behavior != RequestBehavior.REQUEST_WITH_CONTENT) {
-            triggerRefresh(/* sessionId= */ null, RequestReason.OPEN_WITHOUT_CONTENT, uiContext);
-        }
-        mTaskQueue.execute(Task.POPULATE_NEW_SESSION, requestBehaviorToTaskType(behavior),
-                ()
-                        -> populateSessionTask(session, shouldAppendOutstandingRequest, uiContext),
-                timeoutTask, mSessionPopulationTimeoutMs);
-        if (shouldStartRequest && behavior == RequestBehavior.REQUEST_WITH_CONTENT) {
-            triggerRefresh(/* sessionId= */ null, RequestReason.OPEN_WITH_CONTENT, uiContext);
-        }
-    }
-
-    private void populateSessionTask(InitializableSession session,
-            boolean shouldAppendOutstandingRequest, UiContext uiContext) {
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-
-        if (mNoCardsError != null && mSessionCache.getHead().isHeadEmpty()) {
-            ModelProvider modelProvider = session.getModelProvider();
-            if (modelProvider == null) {
-                Logger.e(TAG, "populateSessionTask - noCardsError, modelProvider not found");
-                timeTracker.stop("task", "Create/Populate New Session", "Failure", "noCardsError");
-                return;
-            }
-            Logger.w(TAG, "populateSessionTask - noCardsError %s", modelProvider);
-
-            Result<String> streamSessionResult = mStore.createNewSession();
-            if (!streamSessionResult.isSuccessful()) {
-                switchToEphemeralMode("Unable to create a new session during noCardsError failure");
-                timeTracker.stop("task", "Create/Populate New Session", "Failure", "noCardsError");
-                return;
-            }
-
-            // properly track the session so that it's empty.
-            modelProvider.raiseError(Validators.checkNotNull(mNoCardsError));
-            String sessionId = streamSessionResult.getValue();
-            session.setSessionId(sessionId);
-            mSessionCache.putAttached(sessionId, mClock.currentTimeMillis(),
-                    mSessionCache.getHead().getSchemaVersion(), session);
-            synchronized (mLock) {
-                mSessionsUnderConstruction.remove(session);
-            }
-
-            // Set the session id on the ModelProvider.
-            modelProvider.edit().setSessionId(sessionId).commit();
-            timeTracker.stop("task", "Create/Populate New Session", "Failure", "noCardsError");
-            return;
-        }
-
-        Result<String> streamSessionResult = mStore.createNewSession();
-        if (!streamSessionResult.isSuccessful()) {
-            switchToEphemeralMode("Unable to create a new session, createNewSession failed");
-            timeTracker.stop("task", "Create/Populate New Session", "Failure", "createNewSession");
-            return;
-        }
-        String sessionId = streamSessionResult.getValue();
-        session.setSessionId(sessionId);
-        Result<List<StreamStructure>> streamStructuresResult =
-                mStore.getStreamStructures(sessionId);
-        if (!streamStructuresResult.isSuccessful()) {
-            switchToEphemeralMode("Unable to create a new session, getStreamStructures failed");
-            timeTracker.stop(
-                    "task", "Create/Populate New Session", "Failure", "getStreamStructures");
-            return;
-        }
-
-        boolean cachedBindings;
-        cachedBindings = mContentCache.size() > 0;
-        long creationTimeMillis = mClock.currentTimeMillis();
-        session.populateModelProvider(streamStructuresResult.getValue(), cachedBindings,
-                shouldAppendOutstandingRequest, uiContext);
-        mSessionCache.putAttached(
-                sessionId, creationTimeMillis, mSessionCache.getHead().getSchemaVersion(), session);
-        synchronized (mLock) {
-            mSessionsUnderConstruction.remove(session);
-        }
-        mNewSessionCount++;
-        Logger.i(TAG, "Populate new session: %s, creation time %s", session.getSessionId(),
-                StringFormattingUtils.formatLogDate(creationTimeMillis));
-        timeTracker.stop("task", "Create/Populate New Session");
-    }
-
-    @VisibleForTesting
-    void switchToEphemeralMode(String message) {
-        Logger.e(TAG, message);
-        mStore.switchToEphemeralMode();
-    }
-
-    @VisibleForTesting
-    void modelErrorObserver(@Nullable Session session, ModelError error) {
-        if (session == null && error.getErrorType() == ErrorType.NO_CARDS_ERROR) {
-            Logger.e(TAG, "No Cards Found on TriggerRefresh, setting noCardsError");
-            mNoCardsError = error;
-            // queue a clear which will run after all currently delayed tasks.  This allows delayed
-            // session population tasks to inform the ModelProvider of errors then we clear the
-            // error state.
-            mTaskQueue.execute(
-                    Task.NO_CARD_ERROR_CLEAR, TaskType.USER_FACING, () -> mNoCardsError = null);
-            return;
-        } else if (session != null && error.getErrorType() == ErrorType.PAGINATION_ERROR) {
-            Logger.e(TAG, "Pagination Error found");
-            ModelProvider modelProvider = session.getModelProvider();
-            if (modelProvider != null) {
-                modelProvider.raiseError(error);
-            } else {
-                Logger.e(TAG, "handling Pagination Error, didn't find Model Provider");
-            }
-            return;
-        }
-        Logger.e(TAG, "unhandled modelErrorObserver: session, %s, error %s", session != null,
-                error.getErrorType());
-    }
-
-    @Override
-    public void getExistingSession(
-            String sessionId, ModelProvider modelProvider, UiContext uiContext) {
-        mThreadUtils.checkMainThread();
-        if (!mInitialized.get()) {
-            Logger.i(TAG, "Lazy initialization triggered, getExistingSession");
-            initialize();
-        }
-        InitializableSession session = mSessionFactory.getSession();
-        session.bindModelProvider(modelProvider, null);
-
-        // Task which populates the newly created session.  This must be done
-        // on the Session Manager thread so it atomic with the mutations.
-        mTaskQueue.execute(Task.GET_EXISTING_SESSION, TaskType.IMMEDIATE, () -> {
-            mThreadUtils.checkNotMainThread();
-            if (!mSessionCache.hasSession(sessionId)) {
-                modelProvider.invalidate(uiContext);
-                return;
-            }
-            Session existingSession = mSessionCache.getAttached(sessionId);
-            if (existingSession != null && !existingSession.getContentInSession().isEmpty()) {
-                ModelProvider existingModelProvider = existingSession.getModelProvider();
-                if (existingModelProvider != null) {
-                    existingModelProvider.invalidate(uiContext);
-                }
-            }
-
-            Result<List<StreamStructure>> streamStructuresResult =
-                    mStore.getStreamStructures(sessionId);
-            if (streamStructuresResult.isSuccessful()) {
-                session.setSessionId(sessionId);
-                session.populateModelProvider(
-                        streamStructuresResult.getValue(), false, false, uiContext);
-                mSessionCache.putAttachedAndRetainMetadata(sessionId, session);
-                mExistingSessionCount++;
-            } else {
-                Logger.e(TAG, "unable to get stream structure for existing session %s", sessionId);
-                switchToEphemeralMode("unable to get stream structure for existing session");
-            }
-        });
-    }
-
-    @Override
-    public void invalidateSession(String sessionId) {
-        if (mThreadUtils.isMainThread()) {
-            mTaskQueue.execute(Task.INVALIDATE_SESSION, TaskType.USER_FACING,
-                    () -> mSessionCache.removeAttached(sessionId));
-        } else {
-            mSessionCache.removeAttached(sessionId);
-        }
-    }
-
-    @Override
-    public void detachSession(String sessionId) {
-        if (mThreadUtils.isMainThread()) {
-            mTaskQueue.execute(Task.DETACH_SESSION, TaskType.USER_FACING,
-                    () -> mSessionCache.detachModelProvider(sessionId));
-        } else {
-            mSessionCache.detachModelProvider(sessionId);
-        }
-    }
-
-    @Override
-    public void invalidateHead() {
-        mSessionManagerMutation.resetHead();
-    }
-
-    @Override
-    public void handleToken(String sessionId, StreamToken streamToken) {
-        Logger.i(TAG, "HandleToken on stream %s, token %s", sessionId, streamToken.getContentId());
-        mThreadUtils.checkMainThread();
-
-        // At the moment, this doesn't try to prevent multiple requests with the same Token.
-        // We may want to make sure we only make the request a single time.
-        mHandleTokenCount++;
-        MutationContext mutationContext = new MutationContext.Builder()
-                                                  .setContinuationToken(streamToken)
-                                                  .setRequestingSessionId(sessionId)
-                                                  .build();
-        mTaskQueue.execute(Task.HANDLE_TOKEN, TaskType.BACKGROUND, () -> {
-            fetchActionsAndUpload(getConsistencyToken(), result -> {
-                ConsistencyToken token = handleUpdateConsistencyToken(result);
-                mRequestManager.loadMore(
-                        streamToken, token, getCommitter("handleToken", mutationContext));
-            });
-        });
-    }
-
-    @Override
-    public void triggerRefresh(@Nullable String sessionId) {
-        triggerRefresh(sessionId, RequestReason.HOST_REQUESTED, UiContext.getDefaultInstance());
-    }
-
-    @Override
-    public void triggerRefresh(
-            @Nullable String sessionId, @RequestReason int requestReason, UiContext uiContext) {
-        if (!mInitialized.get()) {
-            Logger.i(TAG, "Lazy initialization triggered, triggerRefresh");
-            initialize();
-        }
-        mTaskQueue.execute(Task.SESSION_MANAGER_TRIGGER_REFRESH,
-                TaskType.HEAD_INVALIDATE, // invalidate because we are requesting a refresh
-                () -> triggerRefreshTask(sessionId, requestReason, uiContext));
-    }
-
-    private ConsistencyToken handleUpdateConsistencyToken(Result<ConsistencyToken> result) {
-        mThreadUtils.checkNotMainThread();
-        if (!mUploadingActionsEnabled) {
-            return getConsistencyToken();
-        }
-
-        ConsistencyToken consistencyToken;
-        if (result.isSuccessful()) {
-            consistencyToken = result.getValue();
-            mStore.editContent()
-                    .add(SessionCache.CONSISTENCY_TOKEN_CONTENT_ID,
-                            StreamPayload.newBuilder()
-                                    .setConsistencyToken(consistencyToken)
-                                    .build())
-                    .commit();
-
-        } else {
-            consistencyToken = getConsistencyToken();
-            Logger.w(TAG, "TriggerRefresh didn't get a consistencyToken Back");
-        }
-        return consistencyToken;
-    }
-
-    private void triggerRefreshTask(
-            @Nullable String sessionId, @RequestReason int requestReason, UiContext uiContext) {
-        mThreadUtils.checkNotMainThread();
-
-        fetchActionsAndUpload(getConsistencyToken(), result -> {
-            ConsistencyToken consistencyToken = handleUpdateConsistencyToken(result);
-            mRequestManager.triggerRefresh(requestReason, consistencyToken,
-                    getCommitter("triggerRefresh",
-                            new MutationContext.Builder().setUiContext(uiContext).build()));
-        });
-
-        if (sessionId != null) {
-            Session session = mSessionCache.getAttached(sessionId);
-            if (session != null) {
-                ModelProvider modelProvider = session.getModelProvider();
-                if (modelProvider != null) {
-                    invalidateSessionInternal(modelProvider, session, uiContext);
-                } else {
-                    Logger.w(TAG, "Session didn't have a ModelProvider %s", sessionId);
-                }
-            } else {
-                Logger.w(TAG, "TriggerRefresh didn't find session %s", sessionId);
-            }
-        } else {
-            Logger.i(TAG, "triggerRefreshTask no StreamSession provided");
-        }
-    }
-
-    @Override
-    public void fetchActionsAndUpload(Consumer<Result<ConsistencyToken>> consumer) {
-        mThreadUtils.checkNotMainThread();
-        fetchActionsAndUpload(getConsistencyToken(), consumer);
-    }
-
-    private void fetchActionsAndUpload(
-            ConsistencyToken token, Consumer<Result<ConsistencyToken>> consumer) {
-        // fail fast if we're not actually recording these actions.
-        if (!mUploadingActionsEnabled) {
-            consumer.accept(Result.success(token));
-            return;
-        }
-        mActionUploadRequestManager.triggerUploadAllActions(token, consumer);
-    }
-
-    @Override
-    public Result<List<PayloadWithId>> getStreamFeatures(List<String> contentIds) {
-        mThreadUtils.checkNotMainThread();
-        List<PayloadWithId> results = new ArrayList<>();
-        List<String> cacheMisses = new ArrayList<>();
-        int contentSize = mContentCache.size();
-        for (String contentId : contentIds) {
-            StreamPayload payload = mContentCache.get(contentId);
-            if (payload != null) {
-                results.add(new PayloadWithId(contentId, payload));
-            } else {
-                cacheMisses.add(contentId);
-            }
-        }
-
-        if (!cacheMisses.isEmpty()) {
-            Result<List<PayloadWithId>> contentResult = mStore.getPayloads(cacheMisses);
-            boolean successfulRead = contentResult.isSuccessful()
-                    && (contentResult.getValue().size()
-                                    + mConfiguration.getValueOrDefault(
-                                            ConfigKey.STORAGE_MISS_THRESHOLD, 4L)
-                            >= cacheMisses.size());
-            if (successfulRead) {
-                Logger.i(TAG, "getStreamFeatures; requestedItems(%d), result(%d)",
-                        cacheMisses.size(), contentResult.getValue().size());
-                if (contentResult.getValue().size() < cacheMisses.size()) {
-                    Logger.e(TAG, "ContentStorage is missing content");
-                    mMainThreadRunner.execute("CONTENT_STORAGE_MISSING_ITEM", () -> {
-                        mBasicLoggingApi.onInternalError(
-                                InternalFeedError.CONTENT_STORAGE_MISSING_ITEM);
-                    });
-                }
-                results.addAll(contentResult.getValue());
-            } else {
-                if (contentResult.isSuccessful()) {
-                    Logger.e(TAG, "Storage miss beyond threshold; requestedItems(%d), returned(%d)",
-                            cacheMisses.size(), contentResult.getValue().size());
-                    mMainThreadRunner.execute("STORAGE_MISS_BEYOND_THRESHOLD", () -> {
-                        mBasicLoggingApi.onInternalError(
-                                InternalFeedError.STORAGE_MISS_BEYOND_THRESHOLD);
-                    });
-                }
-
-                // since we couldn't populate the content, switch to ephemeral mode
-                switchToEphemeralMode("Unable to get the payloads in getStreamFeatures");
-                return Result.failure();
-            }
-        }
-        Logger.i(TAG, "Caching getStreamFeatures - items %s, cache misses %s, cache size %s",
-                contentIds.size(), cacheMisses.size(), contentSize);
-        return Result.success(results);
-    }
-
-    @Override
-    @Nullable
-    public StreamSharedState getSharedState(ContentId contentId) {
-        mThreadUtils.checkMainThread();
-        String sharedStateId = mProtocolAdapter.getStreamContentId(contentId);
-        StreamSharedState state = mSharedStateCache.get(sharedStateId);
-        if (state == null) {
-            Logger.e(TAG, "Shared State [%s] was not found", sharedStateId);
-        }
-        return state;
-    }
-
-    @Override
-    public Consumer<Result<Model>> getUpdateConsumer(MutationContext mutationContext) {
-        if (!mInitialized.get()) {
-            Logger.i(TAG, "Lazy initialization triggered, getUpdateConsumer");
-            initialize();
-        }
-        return new SessionMutationTracker(mutationContext, "updateConsumer");
-    }
-
-    @VisibleForTesting
-    class SessionMutationTracker implements Consumer<Result<Model>> {
-        private final MutationContext mMutationContext;
-        private final String mTaskName;
-
-        @SuppressWarnings("argument.type.incompatible") // ok to add this to the map
-        private SessionMutationTracker(MutationContext mutationContext, String taskName) {
-            this.mMutationContext = mutationContext;
-            this.mTaskName = taskName;
-            mOutstandingMutations.add(this);
-        }
-
-        @Override
-        public void accept(Result<Model> input) {
-            if (mOutstandingMutations.remove(this)) {
-                if (input.isSuccessful()) {
-                    updateSharedStateCache(input.getValue().streamDataOperations);
-                }
-                mSessionManagerMutation
-                        .createCommitter(mTaskName, mMutationContext,
-                                FeedSessionManagerImpl.this::modelErrorObserver,
-                                mKnownContentListener)
-                        .accept(input);
-            } else {
-                Logger.w(TAG, "SessionMutationTracker dropping response due to clear");
-            }
-        }
-    }
-
-    @Override
-    public <T> void getStreamFeaturesFromHead(
-            Function<StreamPayload, T> filterPredicate, Consumer<Result<List<T>>> consumer) {
-        mTaskQueue.execute(Task.GET_STREAM_FEATURES_FROM_HEAD, TaskType.BACKGROUND, () -> {
-            HeadAsStructure headAsStructure =
-                    new HeadAsStructure(mStore, mTimingUtils, mThreadUtils);
-            Function<TreeNode, T> toStreamPayload =
-                    treeNode -> filterPredicate.apply(treeNode.getStreamPayload());
-            headAsStructure.initialize(result -> {
-                if (!result.isSuccessful()) {
-                    consumer.accept(Result.failure());
-                    return;
-                }
-                Result<List<T>> filterResults = headAsStructure.filter(toStreamPayload);
-                consumer.accept(filterResults.isSuccessful()
-                                ? Result.success(filterResults.getValue())
-                                : Result.failure());
-            });
-        });
-    }
-
-    @Override
-    public void setKnownContentListener(KnownContent.Listener knownContentListener) {
-        this.mKnownContentListener = knownContentListener;
-    }
-
-    @Override
-    public void onSwitchToEphemeralMode() {
-        reset();
-    }
-
-    private Consumer<Result<Model>> getCommitter(String taskName, MutationContext mutationContext) {
-        return new SessionMutationTracker(mutationContext, taskName);
-    }
-
-    @Override
-    public void reset() {
-        mThreadUtils.checkNotMainThread();
-        mSessionManagerMutation.forceResetHead();
-        mSessionCache.reset();
-        // Invalidate all sessions currently under construction
-        List<InitializableSession> invalidateSessions;
-        synchronized (mLock) {
-            invalidateSessions = new ArrayList<>(mSessionsUnderConstruction);
-            mSessionsUnderConstruction.clear();
-        }
-        for (InitializableSession session : invalidateSessions) {
-            ModelProvider modelProvider = session.getModelProvider();
-            if (modelProvider != null) {
-                modelProvider.invalidate();
-            }
-        }
-        mContentCache.reset();
-        mSharedStateCache.clear();
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        dumper.forKey("newSessionCount").value(mNewSessionCount);
-        dumper.forKey("existingSessionCount").value(mExistingSessionCount).compactPrevious();
-        dumper.forKey("handleTokenCount").value(mHandleTokenCount).compactPrevious();
-        dumper.forKey("sharedStateSize").value(mSharedStateCache.size()).compactPrevious();
-        dumper.forKey("sharedStateInternerSize")
-                .value(mSharedStateInterner.size())
-                .compactPrevious();
-        dumper.forKey("sharedStateInternerStats")
-                .value(mSharedStateInterner.getStats())
-                .compactPrevious();
-        dumper.dump(mContentCache);
-        dumper.dump(mTaskQueue);
-        dumper.dump(mSessionCache);
-        dumper.dump(mSessionManagerMutation);
-    }
-
-    private void invalidateSessionInternal(
-            ModelProvider modelProvider, Session session, UiContext uiContext) {
-        mThreadUtils.checkNotMainThread();
-        Logger.i(TAG, "Invalidate session %s", session.getSessionId());
-        modelProvider.invalidate(uiContext);
-    }
-
-    // This is only used in tests to verify the contents of the shared state cache.
-    @VisibleForTesting
-    Map<String, StreamSharedState> getSharedStateCacheForTest() {
-        return new HashMap<>(mSharedStateCache);
-    }
-
-    // This is only used in tests to access a the associated sessions.
-    @VisibleForTesting
-    SessionCache getSessionCacheForTest() {
-        return mSessionCache;
-    }
-
-    // Called in the integration tests
-    @VisibleForTesting
-    public boolean isDelayed() {
-        return mTaskQueue.isDelayed();
-    }
-
-    @Override
-    public void onLifecycleEvent(@LifecycleEvent String event) {
-        Logger.i(TAG, "onLifecycleEvent %s", event);
-        switch (event) {
-            case LifecycleEvent.INITIALIZE:
-                initialize();
-                break;
-            case LifecycleEvent.CLEAR_ALL:
-                Logger.i(TAG, "CLEAR_ALL will cancel %s mutations", mOutstandingMutations.size());
-                mOutstandingMutations.clear();
-                break;
-            case LifecycleEvent.CLEAR_ALL_WITH_REFRESH:
-                Logger.i(TAG, "CLEAR_ALL_WITH_REFRESH will cancel %s mutations",
-                        mOutstandingMutations.size());
-                mOutstandingMutations.clear();
-                break;
-            case LifecycleEvent.ENTER_FOREGROUND:
-                mActionManager.setCanUploadClicksAndViewsWhenNoticeCardIsPresent(canUpload());
-                break;
-            case LifecycleEvent.ENTER_BACKGROUND:
-                mActionManager.setCanUploadClicksAndViewsWhenNoticeCardIsPresent(canUpload());
-                break;
-            case LifecycleEvent.SIGNED_IN:
-                mActionManager.setCanUploadClicksAndViewsWhenNoticeCardIsPresent(canUpload());
-                break;
-            case LifecycleEvent.SIGNED_OUT:
-                mActionManager.setCanUploadClicksAndViewsWhenNoticeCardIsPresent(canUpload());
-                break;
-            default:
-                // Do nothing
-        }
-    }
-
-    private boolean canUpload() {
-        if (ChromeFeatureList.isEnabled(
-                    ChromeFeatureList.INTEREST_FEEDV1_CLICKS_AND_VIEWS_CONDITIONAL_UPLOAD)) {
-            return UserPrefs.get(Profile.getLastUsedRegularProfile())
-                    .getBoolean(Pref.HAS_REACHED_CLICK_AND_VIEW_ACTIONS_UPLOAD_CONDITIONS);
-        }
-        return true;
-    }
-
-    // TODO: implement longer term fix for reading/saving the consistency token
-    @Override
-    public void triggerUploadActions(Set<StreamUploadableAction> actions) {
-        mThreadUtils.checkNotMainThread();
-
-        mActionUploadRequestManager.triggerUploadActions(
-                actions, getConsistencyToken(), getConsistencyTokenConsumer());
-    }
-
-    @VisibleForTesting
-    ConsistencyToken getConsistencyToken() {
-        mThreadUtils.checkNotMainThread();
-
-        // don't bother with reading consistencytoken if we're not uploading actions.
-        if (!mUploadingActionsEnabled) {
-            return ConsistencyToken.getDefaultInstance();
-        }
-        Result<List<PayloadWithId>> contentResult = mStore.getPayloads(
-                Collections.singletonList(SessionCache.CONSISTENCY_TOKEN_CONTENT_ID));
-        if (contentResult.isSuccessful()) {
-            for (PayloadWithId payload : contentResult.getValue()) {
-                if (payload.payload.hasConsistencyToken()) {
-                    return payload.payload.getConsistencyToken();
-                }
-            }
-        }
-        return ConsistencyToken.getDefaultInstance();
-    }
-
-    @VisibleForTesting
-    Consumer<Result<ConsistencyToken>> getConsistencyTokenConsumer() {
-        return result -> {
-            if (result.isSuccessful()) {
-                mStore.editContent()
-                        .add(SessionCache.CONSISTENCY_TOKEN_CONTENT_ID,
-                                StreamPayload.newBuilder()
-                                        .setConsistencyToken(result.getValue())
-                                        .build())
-                        .commit();
-            }
-        };
-    }
-
-    private void updateSharedStateCache(List<StreamDataOperation> updates) {
-        for (StreamDataOperation dataOperation : updates) {
-            Operation operation = dataOperation.getStreamStructure().getOperation();
-            if ((operation == Operation.UPDATE_OR_APPEND)
-                    && SessionManagerMutation.validDataOperation(dataOperation)) {
-                String contentId = dataOperation.getStreamStructure().getContentId();
-                StreamPayload payload = dataOperation.getStreamPayload();
-                if (payload.hasStreamSharedState()) {
-                    mSharedStateCache.put(contentId, payload.getStreamSharedState());
-                }
-            }
-        }
-    }
-
-    private static boolean shouldAppendToSession(
-            SessionState sessionState, @RequestBehavior int requestBehavior) {
-        switch (requestBehavior) {
-            case RequestBehavior.REQUEST_WITH_CONTENT: // Fall-through
-            case RequestBehavior.REQUEST_WITH_TIMEOUT:
-                return sessionState.hasContent;
-            case RequestBehavior.NO_REQUEST_WITH_CONTENT: // Fall-through
-            case RequestBehavior.NO_REQUEST_WITH_TIMEOUT:
-                return sessionState.hasContent && sessionState.hasOutstandingRequest;
-            default:
-                return false;
-        }
-    }
-
-    private static boolean shouldStartRequest(
-            SessionState sessionState, @RequestBehavior int requestBehavior) {
-        return (requestBehavior == RequestBehavior.REQUEST_WITH_TIMEOUT
-                       || requestBehavior == RequestBehavior.REQUEST_WITH_WAIT
-                       || requestBehavior == RequestBehavior.REQUEST_WITH_CONTENT)
-                && !sessionState.hasOutstandingRequest;
-    }
-
-    private static boolean shouldPopulateWithTimeout(
-            SessionState sessionState, @RequestBehavior int requestBehavior) {
-        return requestBehavior == RequestBehavior.REQUEST_WITH_TIMEOUT
-                || (requestBehavior == RequestBehavior.NO_REQUEST_WITH_TIMEOUT
-                        && sessionState.hasOutstandingRequest);
-    }
-
-    private static String requestBehaviorToString(@RequestBehavior int requestBehavior) {
-        switch (requestBehavior) {
-            case RequestBehavior.NO_REQUEST_WITH_CONTENT:
-                return "NO_REQUEST_WITH_CONTENT";
-            case RequestBehavior.NO_REQUEST_WITH_TIMEOUT:
-                return "NO_REQUEST_WITH_TIMEOUT";
-            case RequestBehavior.NO_REQUEST_WITH_WAIT:
-                return "NO_REQUEST_WITH_WAIT";
-            case RequestBehavior.REQUEST_WITH_CONTENT:
-                return "REQUEST_WITH_CONTENT";
-            case RequestBehavior.REQUEST_WITH_TIMEOUT:
-                return "REQUEST_WITH_TIMEOUT";
-            case RequestBehavior.REQUEST_WITH_WAIT:
-                return "REQUEST_WITH_WAIT";
-            default:
-                return "UNKNOWN";
-        }
-    }
-
-    private static int requestBehaviorToTaskType(@RequestBehavior int requestBehavior) {
-        switch (requestBehavior) {
-            case RequestBehavior.REQUEST_WITH_WAIT: // Fall-through
-            case RequestBehavior.NO_REQUEST_WITH_WAIT:
-                // Wait for the request to complete and then show content.
-                return TaskType.USER_FACING;
-            case RequestBehavior.REQUEST_WITH_CONTENT: // Fall-through
-            case RequestBehavior.NO_REQUEST_WITH_CONTENT:
-                // Show content immediately and append when the request completes.
-                return TaskType.IMMEDIATE;
-            case RequestBehavior.REQUEST_WITH_TIMEOUT: // Fall-through
-            case RequestBehavior.NO_REQUEST_WITH_TIMEOUT:
-                // Wait for the request to complete but show current content if the timeout elapses.
-                return TaskType.USER_FACING;
-            default:
-                return TaskType.USER_FACING;
-        }
-    }
-
-    // Interner that caches the inner PietSharedStateItem from a StreamSharedState, which may
-    // sometimes be identical, only the inner content_id differing (see [INTERNAL LINK]).
-    @VisibleForTesting
-    static class StreamSharedStateInterner implements Interner<StreamSharedState> {
-        private final Interner<PietSharedStateItem> mInterner = new HashPoolInterner<>();
-
-        @SuppressWarnings("ReferenceEquality")
-        // Intentional reference comparison for interned != orig
-        @Override
-        public StreamSharedState intern(StreamSharedState input) {
-            PietSharedStateItem orig = input.getPietSharedStateItem();
-            PietSharedStateItem interned = mInterner.intern(orig);
-            if (interned != orig) {
-                /*
-                 * If interned != orig we have a memoized item and we need to replace the proto with
-                 * the modified version.
-                 */
-                return input.toBuilder().setPietSharedStateItem(interned).build();
-            }
-            return input;
-        }
-
-        @Override
-        public void clear() {
-            mInterner.clear();
-        }
-
-        @Override
-        public int size() {
-            return mInterner.size();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/ContentCache.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/ContentCache.java
deleted file mode 100644
index 0d15840d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/ContentCache.java
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedsessionmanager.internal;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * In order to support optimistic writes, the cache must store the payloads for the full duration of
- * the mutation. The cache supports lifecycle methods to start and finish the mutation. The cache
- * will hold onto payloads during the duration of the mutation, but will clear data when a mutation
- * is started or finished.
- *
- * <p>This cache assumes that we update all ModelProviders within the lifecycle of a mutation. This
- * is the current behavior of FeedModelProvider.
- */
-public final class ContentCache implements Dumpable {
-    private static final String TAG = "ContentCache";
-
-    private final Map<String, StreamPayload> mMutationCache;
-
-    private int mLookupCount;
-    private int mHitCount;
-    private int mMaxMutationCacheSize;
-    private int mMutationsCount;
-
-    public ContentCache() {
-        mMutationCache = Collections.synchronizedMap(new HashMap<>());
-    }
-
-    /**
-     * Called when the {@link
-     * org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager}
-     * commits a new mutation. Everything added to the cache must be retained until {@link
-     * #finishMutation()} is called.
-     */
-    void startMutation() {
-        mMutationsCount++;
-        mMutationCache.clear();
-    }
-
-    /**
-     * Called when the {@link
-     * org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager} has
-     * finished the mutation. At this point it would be safe to clear the cache.
-     */
-    void finishMutation() {
-        if (mMutationCache.size() > mMaxMutationCacheSize) {
-            mMaxMutationCacheSize = mMutationCache.size();
-        }
-        mMutationCache.clear();
-    }
-
-    /** Return the {@link StreamPayload} or {@code null} if it is not found in the cache. */
-    @Nullable
-    public StreamPayload get(String key) {
-        StreamPayload value = mMutationCache.get(key);
-        mLookupCount++;
-        if (value != null) {
-            mHitCount++;
-        } else {
-            // This is expected on startup.
-            Logger.d(TAG, "Mutation Cache didn't contain item %s", key);
-        }
-        return value;
-    }
-
-    /** Add a new value to the cache, returning the previous version or {@code null}. */
-    @Nullable
-    public StreamPayload put(String key, StreamPayload payload) {
-        return mMutationCache.put(key, payload);
-    }
-
-    /** Returns the current number of items in the cache. */
-    public int size() {
-        return mMutationCache.size();
-    }
-
-    public void reset() {
-        mMutationCache.clear();
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        dumper.forKey("mutationCacheSize").value(mMutationCache.size());
-        dumper.forKey("mutationsCount").value(mMutationsCount).compactPrevious();
-        dumper.forKey("maxMutationCacheSize").value(mMaxMutationCacheSize).compactPrevious();
-        dumper.forKey("lookupCount").value(mLookupCount);
-        dumper.forKey("hits").value(mHitCount).compactPrevious();
-        dumper.forKey("misses").value(mLookupCount - mHitCount).compactPrevious();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/HeadAsStructure.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/HeadAsStructure.java
deleted file mode 100644
index 741eea5..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/HeadAsStructure.java
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedsessionmanager.internal;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.Function;
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.Validators;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/**
- * This class will load the current $HEAD to allow for structured access to the defined contents and
- * structure. Currently, the only supported access is filtering the tree in a pre-order traversal of
- * the structure, {@see #filter}.
- */
-public final class HeadAsStructure {
-    private static final String TAG = "HeadFilter";
-
-    private final Store mStore;
-    private final TimingUtils mTimingUtils;
-    private final ThreadUtils mThreadUtils;
-    private final Object mLock = new Object();
-    @VisibleForTesting
-    final Map<String, List<TreeNode>> mTree = new HashMap<>();
-    @VisibleForTesting
-    final Map<String, TreeNode> mContent = new HashMap<>();
-
-    @GuardedBy("mLock")
-    private boolean mInitalized;
-
-    @VisibleForTesting
-    TreeNode mRoot;
-
-    /**
-     * Define a Node within the tree formed by $HEAD. This contains both the structure and content.
-     * Allowing filtering of either the structure or content.
-     */
-    public static final class TreeNode {
-        final StreamStructure mStreamStructure;
-        StreamPayload mStreamPayload;
-
-        TreeNode(StreamStructure streamStructure) {
-            this.mStreamStructure = streamStructure;
-        }
-
-        public StreamStructure getStreamStructure() {
-            return mStreamStructure;
-        }
-
-        public StreamPayload getStreamPayload() {
-            return mStreamPayload;
-        }
-    }
-
-    public HeadAsStructure(Store store, TimingUtils timingUtils, ThreadUtils threadUtils) {
-        this.mStore = store;
-        this.mTimingUtils = timingUtils;
-        this.mThreadUtils = threadUtils;
-    }
-
-    /**
-     * Capture the state of the current $HEAD, returning success or failure through a {@link
-     * Consumer}. The snapshot of head will not be updated if $HEAD is updated. Initialization may
-     * only be called once. This method must be called on a background thread.
-     */
-    public void initialize(Consumer<Result<Void>> consumer) {
-        Logger.i(TAG, "initialize HeadFilter");
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-
-        synchronized (mLock) {
-            if (mInitalized) {
-                consumer.accept(Result.failure());
-                return;
-            }
-            if (!buildTree()) {
-                timeTracker.stop("", "buildTree Failed");
-                consumer.accept(Result.failure());
-                return;
-            }
-            if (!bindChildren()) {
-                timeTracker.stop("", "bindChildren Failed");
-                consumer.accept(Result.failure());
-                return;
-            }
-            mInitalized = true;
-        }
-
-        timeTracker.stop("task", "HeadFilter.initialize", "content", mContent.size());
-        consumer.accept(Result.success(null));
-    }
-
-    /**
-     * Using the current $HEAD, filter and transform the {@link TreeNode} stored at each node to
-     * {@code T}. The {@code filterPredicate} will filter and transform the node. If {@code
-     * filterPredicate} returns null, the value will be skipped.
-     *
-     * <p>This method must be called after {@link #mInitalized}. This method may run on the main
-     * thread.
-     */
-    // The Nullness checker requires specifying the Nullable vs. NonNull state explicitly since it
-    // can't be inferred from T.  This is done here and in the methods called below.
-    public <T> Result<List<T>> filter(Function<TreeNode, T> filterPredicate) {
-        Logger.i(TAG, "filterHead");
-        synchronized (mLock) {
-            if (!mInitalized) {
-                Logger.e(TAG, "HeadFilter has not been initialized");
-                return Result.failure();
-            }
-        }
-
-        ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        List<T> filteredList = new ArrayList<>();
-        traverseHead(filterPredicate, filteredList);
-        Logger.i(TAG, "filterList size %s", filteredList.size());
-        timeTracker.stop("task", "HeadFilter.filterHead");
-        return Result.success(filteredList);
-    }
-
-    private <T> void traverseHead(Function<TreeNode, T> filterPredicate, List<T> results) {
-        TreeNode r = Validators.checkNotNull(mRoot);
-        traverseNode(r, filterPredicate, results);
-    }
-
-    private <T> void traverseNode(
-            TreeNode node, Function<TreeNode, T> filterPredicate, List<T> results) {
-        if (node.mStreamPayload == null) {
-            Logger.w(TAG, "Found unbound node %s", node.mStreamStructure.getContentId());
-            return;
-        }
-        T data = filterPredicate.apply(node);
-        if (data != null) {
-            results.add(data);
-        }
-        List<TreeNode> children = mTree.get(node.mStreamStructure.getContentId());
-        if (children != null) {
-            for (TreeNode child : children) {
-                traverseNode(child, filterPredicate, results);
-            }
-        }
-    }
-
-    private boolean bindChildren() {
-        Result<List<PayloadWithId>> payloadResult =
-                mStore.getPayloads(new ArrayList<>(mContent.keySet()));
-        if (!payloadResult.isSuccessful()) {
-            Logger.e(TAG, "Unable to get payloads");
-            return false;
-        }
-        for (PayloadWithId payloadWithId : payloadResult.getValue()) {
-            TreeNode node = mContent.get(payloadWithId.contentId);
-            if (node == null) {
-                // This shouldn't happen
-                Logger.w(TAG, "Unable to find tree content for %s", payloadWithId.contentId);
-                continue;
-            }
-            node.mStreamPayload = payloadWithId.payload;
-        }
-        return true;
-    }
-
-    private boolean buildTree() {
-        Result<List<StreamStructure>> headResult =
-                mStore.getStreamStructures(Store.HEAD_SESSION_ID);
-        if (!headResult.isSuccessful()) {
-            Logger.e(TAG, "Unable to load $HEAD");
-            return false;
-        }
-        List<StreamStructure> head = headResult.getValue();
-        Logger.i(TAG, "size of $head %s", head.size());
-        for (StreamStructure structure : head) {
-            switch (structure.getOperation()) {
-                case CLEAR_ALL:
-                    continue;
-                case UPDATE_OR_APPEND:
-                    updateOrAppend(structure);
-                    break;
-                case REMOVE:
-                    remove(structure);
-                    break;
-                default:
-                    Logger.w(TAG, "Unsupported Operation %s", structure.getOperation());
-                    break;
-            }
-        }
-        if (mRoot == null) {
-            Logger.e(TAG, "Root was not found");
-            return false;
-        }
-        return true;
-    }
-
-    private void updateOrAppend(StreamStructure structure) {
-        String contentId = structure.getContentId();
-        if (mContent.containsKey(contentId)) {
-            // this is an update, ignore it
-            return;
-        }
-        TreeNode node = new TreeNode(structure);
-        mContent.put(contentId, node);
-        updateTreeStructure(contentId);
-        if (!structure.hasParentContentId()) {
-            // this is the root
-            if (mRoot != null) {
-                Logger.e(TAG, "Found Multiple roots");
-            }
-            mRoot = node;
-            return;
-        }
-
-        // add this as a child of the parent
-        List<TreeNode> parentChildren = updateTreeStructure(structure.getParentContentId());
-        parentChildren.add(node);
-    }
-
-    private void remove(StreamStructure structure) {
-        String contentId = structure.getContentId();
-        String parentId = structure.hasParentContentId() ? structure.getParentContentId() : null;
-        TreeNode node = mContent.get(contentId);
-        if (node == null) {
-            Logger.w(TAG, "Unable to find StreamStructure %s to remove", contentId);
-            return;
-        }
-        if (parentId == null) {
-            // Removing root is not supported, CLEAR_HEAD is intended when the root itself is
-            // cleared.
-            Logger.w(TAG, "Removing Root is not supported, unable to remove %s", contentId);
-            return;
-        }
-        List<TreeNode> parentChildren = mTree.get(parentId);
-        if (parentChildren == null) {
-            Logger.w(TAG, "Parent %s not found, unable to remove", parentId, contentId);
-        } else if (!parentChildren.remove(node)) {
-            Logger.w(TAG, "Removing %s, not found in parent %s", contentId, parentId);
-        }
-        mTree.remove(contentId);
-        mContent.remove(contentId);
-    }
-
-    private List<TreeNode> updateTreeStructure(String contentId) {
-        List<TreeNode> children = mTree.get(contentId);
-        if (children == null) {
-            children = new ArrayList<>();
-            mTree.put(contentId, children);
-        }
-        return children;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/HeadSessionImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/HeadSessionImpl.java
deleted file mode 100644
index 7b0bfa4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/HeadSessionImpl.java
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedsessionmanager.internal;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SessionMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * Implementation of {@link Session} for $HEAD. This class doesn't support a ModelProvider. The
- * $HEAD session does not support optimistic writes because we may create a new session between when
- * the response is received and when task updating the head session runs.
- */
-public class HeadSessionImpl implements Session, Dumpable {
-    private static final String TAG = "HeadSessionImpl";
-
-    private final Store mStore;
-    private final TimingUtils mTimingUtils;
-    private final SessionContentTracker mSessionContentTracker =
-            new SessionContentTracker(/* supportsClearAll= */ true);
-    private final boolean mLimitPageUpdatesInHead;
-
-    private int mSchemaVersion;
-
-    // operation counts for the dumper
-    private int mUpdateCount;
-    private int mStoreMutationFailures;
-
-    HeadSessionImpl(Store store, TimingUtils timingUtils, boolean limitPageUpdatesInHead) {
-        this.mStore = store;
-        this.mTimingUtils = timingUtils;
-        this.mLimitPageUpdatesInHead = limitPageUpdatesInHead;
-    }
-
-    /** Initialize head from the stored stream structures. */
-    void initializeSession(List<StreamStructure> streamStructures, int schemaVersion) {
-        Logger.i(TAG, "Initialize HEAD %s items", streamStructures.size());
-        this.mSchemaVersion = schemaVersion;
-        mSessionContentTracker.update(streamStructures);
-    }
-
-    void reset() {
-        mSessionContentTracker.clear();
-    }
-
-    public int getSchemaVersion() {
-        return mSchemaVersion;
-    }
-
-    @Override
-    public boolean invalidateOnResetHead() {
-        // There won't be a ModelProvider to invalidate
-        return false;
-    }
-
-    @Override
-    public void updateSession(boolean clearHead, List<StreamStructure> streamStructures,
-            int schemaVersion, @Nullable MutationContext mutationContext) {
-        ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        mUpdateCount++;
-
-        if (clearHead) {
-            this.mSchemaVersion = schemaVersion;
-        }
-
-        StreamToken mutationSourceToken =
-                mutationContext != null ? mutationContext.getContinuationToken() : null;
-        if (mutationSourceToken != null) {
-            String contentId = mutationSourceToken.getContentId();
-            if (mutationSourceToken.hasContentId() && !mSessionContentTracker.contains(contentId)) {
-                // Make sure that mutationSourceToken is a token in this session, if not, we don't
-                // update the session.
-                timeTracker.stop(
-                        "updateSessionIgnored", getSessionId(), "Token Not Found", contentId);
-                Logger.i(TAG, "Token %s not found in session, ignoring update", contentId);
-                return;
-            } else if (mLimitPageUpdatesInHead) {
-                timeTracker.stop("updateSessionIgnored", getSessionId());
-                Logger.i(TAG, "Limited paging updates in HEAD");
-                return;
-            }
-        }
-
-        int updateCnt = 0;
-        int addFeatureCnt = 0;
-        int requiredContentCnt = 0;
-        boolean cleared = false;
-        SessionMutation sessionMutation = mStore.editSession(getSessionId());
-        for (StreamStructure streamStructure : streamStructures) {
-            String contentId = streamStructure.getContentId();
-            switch (streamStructure.getOperation()) {
-                case UPDATE_OR_APPEND:
-                    if (mSessionContentTracker.contains(contentId)) {
-                        // this is an update operation so we can ignore it
-                        updateCnt++;
-                    } else {
-                        sessionMutation.add(streamStructure);
-                        addFeatureCnt++;
-                    }
-                    break;
-                case REMOVE:
-                    Logger.i(TAG, "Removing Item %s from $HEAD", contentId);
-                    if (mSessionContentTracker.contains(contentId)) {
-                        sessionMutation.add(streamStructure);
-                    } else {
-                        Logger.w(TAG, "Remove operation content not found in $HEAD");
-                    }
-                    break;
-                case CLEAR_ALL:
-                    cleared = true;
-                    break;
-                case REQUIRED_CONTENT:
-                    if (!mSessionContentTracker.contains(contentId)) {
-                        sessionMutation.add(streamStructure);
-                        requiredContentCnt++;
-                    }
-                    break;
-                default:
-                    Logger.e(
-                            TAG, "Unknown operation, ignoring: %s", streamStructure.getOperation());
-            }
-            mSessionContentTracker.update(streamStructure);
-        }
-        boolean success = sessionMutation.commit();
-        if (success) {
-            timeTracker.stop("updateSession", getSessionId(), "cleared", cleared, "features",
-                    addFeatureCnt, "updates", updateCnt, "requiredContent", requiredContentCnt);
-        } else {
-            timeTracker.stop("updateSessionFailure", getSessionId());
-            mStoreMutationFailures++;
-            Logger.e(TAG, "$HEAD session mutation failed");
-            mStore.switchToEphemeralMode();
-        }
-    }
-
-    @Override
-    public String getSessionId() {
-        return Store.HEAD_SESSION_ID;
-    }
-
-    @Override
-    @Nullable
-    public ModelProvider getModelProvider() {
-        return null;
-    }
-
-    @Override
-    public Set<String> getContentInSession() {
-        return mSessionContentTracker.getContentIds();
-    }
-
-    public boolean isHeadEmpty() {
-        return mSessionContentTracker.isEmpty();
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        dumper.forKey("sessionName").value(getSessionId());
-        dumper.forKey("updateCount").value(mUpdateCount).compactPrevious();
-        dumper.forKey("storeMutationFailures").value(mStoreMutationFailures).compactPrevious();
-        dumper.dump(mSessionContentTracker);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/InitializableSession.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/InitializableSession.java
deleted file mode 100644
index 05f1974..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/InitializableSession.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedsessionmanager.internal;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider.ViewDepthProvider;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-
-import java.util.List;
-
-/** A {@link Session} which supports initialization from $HEAD. */
-public interface InitializableSession extends Session {
-    /**
-     * Bind a ModelProvider to an existing, unbound session. If {@code null} is passed, this will
-     * unbind the Session, removing all references to the ModelProvider.
-     */
-    void bindModelProvider(
-            @Nullable ModelProvider modelProvider, @Nullable ViewDepthProvider viewDepthProvider);
-
-    /** Set the session id. */
-    void setSessionId(String sessionId);
-
-    /** Called to initialize the session from $HEAD */
-    void populateModelProvider(List<StreamStructure> session, boolean cachedBindings,
-            boolean legacyHeadContent, UiContext uiContext);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/Session.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/Session.java
deleted file mode 100644
index aa5ca550..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/Session.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedsessionmanager.internal;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-
-import java.util.List;
-import java.util.Set;
-
-/** A {@code Session} is a instance which supports update and optionally a {@link ModelProvider}. */
-public interface Session {
-    /**
-     * Called to update the Session, this is responsible for updating the Stored session instance.
-     */
-    void updateSession(boolean clearHead, List<StreamStructure> streamStructures, int schemaVersion,
-            @Nullable MutationContext mutationContext);
-
-    boolean invalidateOnResetHead();
-
-    /** The unique identifier created by the storage layer for the session. */
-    String getSessionId();
-
-    /** Returns a ModelProvider for a Session, if one is defined. */
-    @Nullable
-    ModelProvider getModelProvider();
-
-    /** Returns an unmodifiable set of the StreamContentIds used by the session. */
-    Set<String> getContentInSession();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionCache.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionCache.java
deleted file mode 100644
index ac445ea..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionCache.java
+++ /dev/null
@@ -1,612 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedsessionmanager.internal;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.Validators;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue.TaskType;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.logging.StringFormattingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.SessionMetadata;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSession;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSessions;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/**
- * For the FeedSessionManager, this class is a cache of the {@link Session} objects which are
- * currently defined.
- */
-public final class SessionCache implements Dumpable {
-    private static final String TAG = "SessionCache";
-    @VisibleForTesting
-    static final int MIN_SCHEMA_VERSION_FOR_PIET_SHARED_STATE_REQUIRED_CONTENT = 2;
-    @VisibleForTesting
-    static final String STREAM_SESSION_CONTENT_ID = "FSM::Sessions::0";
-
-    /**
-     * Key used to store the consistency token in {@link
-     * org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorage}
-     */
-    public static final String CONSISTENCY_TOKEN_CONTENT_ID = "ct";
-
-    // Used to synchronize the stored data
-    private final Object mLock = new Object();
-
-    // Sessions with ModelProviders (attached).
-    @GuardedBy("mLock")
-    private final Map<String, Session> mAttachedSessions = new HashMap<>();
-
-    @GuardedBy("mLock")
-    private final Map<String, SessionMetadata> mSessionsMetadata = new HashMap<>();
-
-    private final HeadSessionImpl mHead;
-
-    private final Store mStore;
-    private final TaskQueue mTaskQueue;
-    private final SessionFactory mSessionFactory;
-    private final long mLifetimeMs;
-    private final TimingUtils mTimingUtils;
-    private final ThreadUtils mThreadUtils;
-    private final Clock mClock;
-
-    private boolean mInitialized;
-
-    // operation counts for the dumper
-    private int mGetCount;
-    private int mGetAttachedCount;
-    private int mGetAllCount;
-    private int mPutCount;
-    private int mRemoveCount;
-    private int mUnboundSessionCount;
-    private int mDetachedSessionCount;
-    private int mExpiredSessionsCleared;
-
-    public SessionCache(Store store, TaskQueue taskQueue, SessionFactory sessionFactory,
-            long lifetimeMs, TimingUtils timingUtils, ThreadUtils threadUtil, Clock clock) {
-        this.mStore = store;
-        this.mTaskQueue = taskQueue;
-        this.mSessionFactory = sessionFactory;
-        this.mLifetimeMs = lifetimeMs;
-        this.mTimingUtils = timingUtils;
-        this.mThreadUtils = threadUtil;
-        this.mClock = clock;
-
-        this.mHead = sessionFactory.getHeadSession();
-    }
-
-    /**
-     * Return {@link HeadSessionImpl} for head. Returns {@code null} if {@link #initialize()} hasn't
-     * finished running.
-     */
-    public HeadSessionImpl getHead() {
-        return mHead;
-    }
-
-    /** Returns {@code true} if HEAD has been initialize, which happens in {@link #initialize()}. */
-    public boolean isHeadInitialized() {
-        return mInitialized;
-    }
-
-    /**
-     * Returns true if sessionId exists in any of {attached, unbound, head} set, false otherwise.
-     */
-    public boolean hasSession(String sessionId) {
-        synchronized (mLock) {
-            return mSessionsMetadata.containsKey(sessionId);
-        }
-    }
-
-    /** Returns all attached sessions tracked by the SessionCache. This does NOT include head. */
-    public List<Session> getAttachedSessions() {
-        mGetAttachedCount++;
-        synchronized (mLock) {
-            Logger.d(TAG, "getAttachedSessions, size=%d", mAttachedSessions.size());
-            return new ArrayList<>(mAttachedSessions.values());
-        }
-    }
-
-    /**
-     * Returns all sessions tracked by the SessionCache. This includes head and previously thrown
-     * away unbounded sessions, which are re-created.
-     *
-     * <p>NOTE: This method should be called from a background thread, as it reads the persistent
-     * storage in order to populate the unbound sessions.
-     */
-    List<Session> getAllSessions() {
-        mThreadUtils.checkNotMainThread();
-        mGetAllCount++;
-
-        // Re-build the unbound sessions (that were thrown away on detach) and add them.
-        List<Session> allSessions = new ArrayList<>(populateUnboundSessions());
-
-        allSessions.add(mHead);
-        synchronized (mLock) {
-            allSessions.addAll(mAttachedSessions.values());
-        }
-
-        Logger.d(TAG, "getAllSessions, size=%d", allSessions.size());
-        return allSessions;
-    }
-
-    /**
-     * Return an attached {@link Session} for the sessionId, or {@code null} if the sessionCache
-     * doesn't contain the Session or it is no longer attached.
-     */
-    @Nullable
-    public Session getAttached(String sessionId) {
-        mGetCount++;
-        synchronized (mLock) {
-            return mAttachedSessions.get(sessionId);
-        }
-    }
-
-    /** Returns the last time content was added to HEAD. */
-    public long getHeadLastAddedTimeMillis() {
-        synchronized (mLock) {
-            SessionMetadata metadata = mSessionsMetadata.get(mHead.getSessionId());
-            if (metadata == null) {
-                Logger.e(TAG, "SessionMetadata missing for HEAD");
-                return 0L;
-            }
-            return metadata.getLastAddedTimeMillis();
-        }
-    }
-
-    /** Add a {@link Session} to the SessionCache. */
-    public void putAttached(
-            String sessionId, long creationTimeMillis, int schemaVersion, Session session) {
-        Logger.d(TAG, "putAttached, sessionId=%s", sessionId);
-
-        mThreadUtils.checkNotMainThread();
-        mPutCount++;
-        synchronized (mLock) {
-            mAttachedSessions.put(sessionId, session);
-            mSessionsMetadata.put(sessionId,
-                    SessionMetadata.newBuilder()
-                            .setCreationTimeMillis(creationTimeMillis)
-                            .setSchemaVersion(schemaVersion)
-                            .build());
-            Logger.d(TAG, "Sessions size: attached=%d, all=%d", mAttachedSessions.size(),
-                    mSessionsMetadata.size());
-        }
-        updatePersistedSessionsMetadata();
-    }
-
-    /** Add a {@link Session} to the SessionCache and retain the existing metadata. */
-    public void putAttachedAndRetainMetadata(String sessionId, Session session) {
-        Logger.d(TAG, "putAttachedAndRetainMetadata, sessionId=%s", sessionId);
-
-        mThreadUtils.checkNotMainThread();
-        mPutCount++;
-        synchronized (mLock) {
-            mAttachedSessions.put(sessionId, session);
-            Logger.d(TAG, "Sessions size: attached=%d, all=%d", mAttachedSessions.size(),
-                    mSessionsMetadata.size());
-        }
-    }
-
-    /**
-     * Detaches the model provider from the session, which becomes unbound. We throw away unbound
-     * sessions for memory reasons, they are re-created on demand when needed in {@link
-     * #populateUnboundSessions()}.
-     */
-    public void detachModelProvider(String sessionId) {
-        Logger.d(TAG, "detachModelProvider, sessionId=%s", sessionId);
-
-        mThreadUtils.checkNotMainThread();
-        InitializableSession initializableSession;
-        synchronized (mLock) {
-            Session session = mAttachedSessions.get(sessionId);
-            if (!(session instanceof InitializableSession)) {
-                Logger.w(TAG, "Unable to detach session %s", sessionId);
-                return;
-            } else {
-                initializableSession = (InitializableSession) session;
-            }
-            mAttachedSessions.remove(sessionId);
-            Logger.d(TAG, "Sessions size: attached=%d, all=%d", mAttachedSessions.size(),
-                    mSessionsMetadata.size());
-        }
-
-        initializableSession.bindModelProvider(null, null);
-        mDetachedSessionCount++;
-    }
-
-    /** Remove an attached {@link Session} from the SessionCache. */
-    public void removeAttached(String sessionId) {
-        Logger.d(TAG, "removeAttached, sessionId=%s", sessionId);
-
-        mThreadUtils.checkNotMainThread();
-        mRemoveCount++;
-        synchronized (mLock) {
-            mAttachedSessions.remove(sessionId);
-            mSessionsMetadata.remove(sessionId);
-            Logger.d(TAG, "Sessions size: attached=%d, all=%d", mAttachedSessions.size(),
-                    mSessionsMetadata.size());
-        }
-        updatePersistedSessionsMetadata();
-    }
-
-    /** Initialize the SessionCache from Store. */
-    public boolean initialize() {
-        mThreadUtils.checkNotMainThread();
-
-        // create the head session from the data in the Store
-        ElapsedTimeTracker headTimeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        Result<List<StreamStructure>> results = mStore.getStreamStructures(mHead.getSessionId());
-        if (!results.isSuccessful()) {
-            Logger.w(TAG, "unable to get head stream structures");
-            return false;
-        }
-
-        List<StreamSession> sessionList = getPersistedSessions();
-        int headSchemaVersion = getHeadSchemaVersion(sessionList);
-        mHead.initializeSession(results.getValue(), headSchemaVersion);
-        mInitialized = true;
-        headTimeTracker.stop("", "createHead");
-
-        initializePersistedSessions(sessionList);
-
-        // Ensure that SessionMetadata exists for HEAD.
-        synchronized (mLock) {
-            if (!mSessionsMetadata.containsKey(mHead.getSessionId())) {
-                mSessionsMetadata.put(mHead.getSessionId(), SessionMetadata.getDefaultInstance());
-            }
-            Logger.d(TAG, "initialize, size=%d", mSessionsMetadata.size());
-        }
-        return true;
-    }
-
-    public void reset() {
-        List<Session> sessionList;
-        synchronized (mLock) {
-            sessionList = new ArrayList<>(mAttachedSessions.values());
-        }
-        for (Session session : sessionList) {
-            ModelProvider modelProvider = session.getModelProvider();
-            if (modelProvider != null) {
-                modelProvider.invalidate();
-            }
-        }
-        synchronized (mLock) {
-            mAttachedSessions.clear();
-            mSessionsMetadata.clear();
-            mHead.reset();
-            mSessionsMetadata.put(mHead.getSessionId(), SessionMetadata.getDefaultInstance());
-            mInitialized = true;
-        }
-    }
-
-    /** Returns when the specified {@code sessionId} was created. */
-    @VisibleForTesting
-    long getCreationTimeMillis(String sessionId) {
-        synchronized (mLock) {
-            SessionMetadata metadata = mSessionsMetadata.get(sessionId);
-            if (metadata == null) {
-                Logger.e(TAG, "SessionMetadata missing for session %s", sessionId);
-                return 0L;
-            }
-            return metadata.getCreationTimeMillis();
-        }
-    }
-
-    /**
-     * Updates the last time content was added to HEAD and its schema version and writes data to
-     * disk.
-     */
-    void updateHeadMetadata(long lastAddedTimeMillis, int schemaVersion) {
-        mThreadUtils.checkNotMainThread();
-        synchronized (mLock) {
-            SessionMetadata metadata = mSessionsMetadata.get(mHead.getSessionId());
-            SessionMetadata.Builder builder =
-                    metadata == null ? SessionMetadata.newBuilder() : metadata.toBuilder();
-            mSessionsMetadata.put(mHead.getSessionId(),
-                    builder.setLastAddedTimeMillis(lastAddedTimeMillis)
-                            .setSchemaVersion(schemaVersion)
-                            .build());
-        }
-        updatePersistedSessionsMetadata();
-    }
-
-    /**
-     * Creates a list of unbound sessions, which are populated from persisted storage. Unbound
-     * sessions are defined as the set of sessions whose IDs are in the set {sessionsMetadata.keys -
-     * sessions.keys - head.key}, i.e sessions that were detached and thrown away in {@link
-     * #detachModelProvider(String)}.
-     *
-     * <p>NOTE: The head and attached sessions will explicitly not be returned.
-     */
-    private Collection<Session> populateUnboundSessions() {
-        mThreadUtils.checkNotMainThread();
-
-        List<StreamSession> sessionList = getPersistedSessions();
-        HeadSessionImpl headSession = Validators.checkNotNull(mHead);
-        String headSessionId = headSession.getSessionId();
-
-        Map<String, Session> unboundSessions = new HashMap<>();
-        for (StreamSession session : sessionList) {
-            String sessionId = session.getSessionId();
-            synchronized (mLock) {
-                // We need only unbound sessions, i.e. sessions whose IDs are part of
-                // sessionsMetadata but are not attached or head (those are always stored in
-                // attachedSessions/head respectively so do not need to be restored from persistent
-                // storage.
-                if (mAttachedSessions.containsKey(sessionId)
-                        || !mSessionsMetadata.containsKey(sessionId)
-                        || sessionId.equals(headSessionId)) {
-                    continue;
-                }
-            }
-            InitializableSession unboundSession;
-            // Unbound sessions are sessions that are able to be created through restore
-            unboundSession = mSessionFactory.getSession();
-            unboundSession.setSessionId(sessionId);
-            unboundSessions.put(sessionId, unboundSession);
-
-            // Populate the newly created unbound session.
-            Logger.i(TAG, "Populate unbound session %s", sessionId);
-            Result<List<StreamStructure>> streamStructuresResult =
-                    mStore.getStreamStructures(sessionId);
-            if (streamStructuresResult.isSuccessful()) {
-                unboundSession.populateModelProvider(streamStructuresResult.getValue(),
-                        /* cachedBindings= */ false,
-                        /* legacyHeadContent= */ false, UiContext.getDefaultInstance());
-            } else {
-                Logger.e(TAG, "Failed to read unbound session state, ignored");
-            }
-        }
-
-        return unboundSessions.values();
-    }
-
-    private void initializePersistedSessions(List<StreamSession> sessionList) {
-        mThreadUtils.checkNotMainThread();
-
-        HeadSessionImpl headSession = Validators.checkNotNull(mHead);
-        String headSessionId = headSession.getSessionId();
-        boolean cleanupSessions = false;
-        for (StreamSession session : sessionList) {
-            SessionMetadata metadata = getOrCreateSessionMetadata(session);
-            String sessionId = session.getSessionId();
-            if (sessionId.equals(headSessionId)) {
-                // update the information stored for the $HEAD record we created previously
-                Logger.i(TAG, "Updating $HEAD state, lastAdded %s",
-                        StringFormattingUtils.formatLogDate(metadata.getLastAddedTimeMillis()));
-                synchronized (mLock) {
-                    mSessionsMetadata.put(sessionId, metadata);
-                }
-                continue;
-            }
-            if (!isSessionAlive(sessionId, metadata)) {
-                Logger.i(TAG, "Found expired session %s, created %s", session.getSessionId(),
-                        StringFormattingUtils.formatLogDate(metadata.getCreationTimeMillis()));
-                cleanupSessions = true;
-                continue;
-            }
-            synchronized (mLock) {
-                if (mSessionsMetadata.containsKey(session.getSessionId())) {
-                    // Don't replace sessions already found in sessions
-                    continue;
-                }
-                mSessionsMetadata.put(session.getSessionId(), metadata);
-            }
-        }
-
-        if (cleanupSessions) {
-            // Queue up a task to clear the session journals.
-            mTaskQueue.execute(Task.CLEAN_UP_SESSION_JOURNALS, TaskType.BACKGROUND,
-                    this::cleanupSessionJournals);
-        }
-        Set<String> reservedContentIds = new HashSet<>();
-        reservedContentIds.add(STREAM_SESSION_CONTENT_ID);
-        reservedContentIds.add(CONSISTENCY_TOKEN_CONTENT_ID);
-        mTaskQueue.execute(Task.GARBAGE_COLLECT_CONTENT, TaskType.BACKGROUND,
-                mStore.triggerContentGc(reservedContentIds, getAccessibleContentSupplier(),
-                        shouldKeepSharedStates()));
-    }
-
-    private boolean shouldKeepSharedStates() {
-        synchronized (mLock) {
-            for (String sessionId : mSessionsMetadata.keySet()) {
-                SessionMetadata metadata = mSessionsMetadata.get(sessionId);
-                if (metadata.getSchemaVersion()
-                        < MIN_SCHEMA_VERSION_FOR_PIET_SHARED_STATE_REQUIRED_CONTENT) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private Supplier<Set<String>> getAccessibleContentSupplier() {
-        return () -> {
-            mThreadUtils.checkNotMainThread();
-            Logger.i(TAG, "Determining accessible content");
-
-            // SessionIds should be determined at the time GC runs.
-            Set<String> sessionIds;
-            synchronized (mLock) {
-                sessionIds = mSessionsMetadata.keySet();
-            }
-
-            Set<String> accessibleContent = new HashSet<>(mHead.getContentInSession());
-            for (String sessionId : sessionIds) {
-                if (sessionId.equals(mHead.getSessionId())) {
-                    continue;
-                }
-
-                SessionContentTracker sessionContentTracker =
-                        new SessionContentTracker(/* supportsClearAll= */ false);
-                Result<List<StreamStructure>> streamStructuresResult =
-                        mStore.getStreamStructures(sessionId);
-                if (streamStructuresResult.isSuccessful()) {
-                    sessionContentTracker.update(streamStructuresResult.getValue());
-                } else {
-                    Logger.e(TAG, "Failed to read unbound session state, ignored");
-                }
-                accessibleContent.addAll(sessionContentTracker.getContentIds());
-            }
-            return accessibleContent;
-        };
-    }
-
-    @VisibleForTesting
-    List<StreamSession> getPersistedSessions() {
-        List<String> sessionIds = new ArrayList<>();
-        sessionIds.add(STREAM_SESSION_CONTENT_ID);
-        Result<List<PayloadWithId>> sessionPayloadResult = mStore.getPayloads(sessionIds);
-        if (!sessionPayloadResult.isSuccessful()) {
-            // If we cant read the persisted sessions, report the error and return null. No sessions
-            // will be created, this is as if we deleted all existing sessions.  It should be safe
-            // to ignore the error.
-            Logger.e(TAG, "getPayloads failed to read the Persisted sessions");
-            return Collections.emptyList();
-        }
-
-        List<PayloadWithId> sessionPayload = sessionPayloadResult.getValue();
-        if (sessionPayload.isEmpty()) {
-            Logger.w(TAG, "Persisted Sessions were not found");
-            return Collections.emptyList();
-        }
-        StreamPayload payload = sessionPayload.get(0).payload;
-        if (!payload.hasStreamSessions()) {
-            Logger.e(TAG, "Persisted Sessions StreamSessions was not set");
-            return Collections.emptyList();
-        }
-        return payload.getStreamSessions().getStreamSessionList();
-    }
-
-    @VisibleForTesting
-    void updatePersistedSessionsMetadata() {
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        StreamSessions.Builder sessionsBuilder = StreamSessions.newBuilder();
-        int sessionCount;
-        synchronized (mLock) {
-            sessionCount = mSessionsMetadata.size();
-            for (String sessionId : mSessionsMetadata.keySet()) {
-                SessionMetadata sessionMetadata = mSessionsMetadata.get(sessionId);
-                if (sessionMetadata != null) {
-                    sessionsBuilder.addStreamSession(
-                            StreamSession.newBuilder().setSessionId(sessionId).setSessionMetadata(
-                                    sessionMetadata));
-                }
-            }
-        }
-        mStore.editContent()
-                .add(STREAM_SESSION_CONTENT_ID,
-                        StreamPayload.newBuilder().setStreamSessions(sessionsBuilder).build())
-                .commit();
-        timeTracker.stop(
-                "task", "updatePersistedSessionsMetadata(Content)", "sessionCount", sessionCount);
-    }
-
-    /**
-     * Remove all session journals which are not currently found in {@code sessionsMetadata} which
-     * contains all of the known sessions. This is a garbage collection task.
-     */
-    @VisibleForTesting
-    void cleanupSessionJournals() {
-        mThreadUtils.checkNotMainThread();
-        Logger.i(TAG, "Task: cleanupSessionJournals");
-        ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        int sessionCleared = mExpiredSessionsCleared;
-
-        Result<List<String>> storedSessionsResult = mStore.getAllSessions();
-        if (storedSessionsResult.isSuccessful()) {
-            synchronized (mLock) {
-                for (String sessionId : storedSessionsResult.getValue()) {
-                    if (!mSessionsMetadata.containsKey(sessionId)) {
-                        mStore.removeSession(sessionId);
-                        mExpiredSessionsCleared++;
-                    }
-                }
-            }
-        } else {
-            // We were unable to read all the sessions, log an error and then ignore the fact that
-            // cleanup failed.
-            Logger.e(TAG, "Error reading all sessions, Unable to cleanup session journals");
-        }
-        timeTracker.stop("task", "cleanupSessionJournals", "sessionsCleared",
-                mExpiredSessionsCleared - sessionCleared);
-    }
-
-    @VisibleForTesting
-    boolean isSessionAlive(String sessionId, SessionMetadata metadata) {
-        // Today HEAD will does not time out
-        return mHead.getSessionId().equals(sessionId)
-                || (metadata.getCreationTimeMillis() + mLifetimeMs) > mClock.currentTimeMillis();
-    }
-
-    private SessionMetadata getOrCreateSessionMetadata(StreamSession streamSession) {
-        if (streamSession.hasSessionMetadata()) {
-            return streamSession.getSessionMetadata();
-        }
-
-        // TODO: Log to BasicLoggingApi that SessionMetadata is missing.
-        SessionMetadata.Builder metadataBuilder = SessionMetadata.newBuilder();
-        if (streamSession.getSessionId().equals(mHead.getSessionId())) {
-            metadataBuilder.setLastAddedTimeMillis(streamSession.getLegacyTimeMillis());
-        } else {
-            metadataBuilder.setCreationTimeMillis(streamSession.getLegacyTimeMillis());
-        }
-        return metadataBuilder.build();
-    }
-
-    private int getHeadSchemaVersion(List<StreamSession> sessionList) {
-        for (StreamSession streamSession : sessionList) {
-            if (streamSession.getSessionId().equals(mHead.getSessionId())) {
-                return streamSession.getSessionMetadata().getSchemaVersion();
-            }
-        }
-
-        return 0;
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        synchronized (mLock) {
-            dumper.forKey("attached sessions").value(mAttachedSessions.size());
-        }
-        dumper.forKey("expiredSessionsCleared").value(mExpiredSessionsCleared).compactPrevious();
-        dumper.forKey("unboundSessionCount").value(mUnboundSessionCount).compactPrevious();
-        dumper.forKey("detachedSessionCount").value(mDetachedSessionCount).compactPrevious();
-        dumper.forKey("get").value(mGetCount);
-        dumper.forKey("getAttached").value(mGetAttachedCount).compactPrevious();
-        dumper.forKey("getAll").value(mGetAllCount).compactPrevious();
-        dumper.forKey("put").value(mPutCount).compactPrevious();
-        dumper.forKey("remove").value(mRemoveCount).compactPrevious();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionContentTracker.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionContentTracker.java
deleted file mode 100644
index e0b48ce..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionContentTracker.java
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedsessionmanager.internal;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/** Class tracking the content IDs associated to a session. */
-public class SessionContentTracker implements Dumpable {
-    private static final String TAG = "SessionContentTracker";
-
-    private final boolean mSupportsClearAll;
-    private final Set<String> mContentIds = new HashSet<>();
-
-    SessionContentTracker(boolean supportsClearAll) {
-        this.mSupportsClearAll = supportsClearAll;
-    }
-
-    public boolean isEmpty() {
-        return mContentIds.isEmpty();
-    }
-
-    public void clear() {
-        mContentIds.clear();
-    }
-
-    public boolean contains(String contentId) {
-        return mContentIds.contains(contentId);
-    }
-
-    public Set<String> getContentIds() {
-        return new HashSet<>(mContentIds);
-    }
-
-    public void update(StreamStructure streamStructure) {
-        String contentId = streamStructure.getContentId();
-        switch (streamStructure.getOperation()) {
-            case UPDATE_OR_APPEND: // Fall-through
-            case REQUIRED_CONTENT:
-                mContentIds.add(contentId);
-                break;
-            case REMOVE:
-                mContentIds.remove(contentId);
-                break;
-            case CLEAR_ALL:
-                if (mSupportsClearAll) {
-                    mContentIds.clear();
-                } else {
-                    Logger.i(TAG, "CLEAR_ALL not supported.");
-                }
-                break;
-            default:
-                Logger.e(TAG, "unsupported operation: %s", streamStructure.getOperation());
-        }
-    }
-
-    public void update(List<StreamStructure> streamStructures) {
-        for (StreamStructure streamStructure : streamStructures) {
-            update(streamStructure);
-        }
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        dumper.forKey("contentIds").value(mContentIds.size());
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionFactory.java
deleted file mode 100644
index e0d8874..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionFactory.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedsessionmanager.internal;
-
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-
-/**
- * Factory for creating a {@link InitializableSession} instance used in the {@link
- * org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager}.
- */
-public final class SessionFactory {
-    private final Store mStore;
-    private final TaskQueue mTaskQueue;
-    private final TimingUtils mTimingUtils;
-    private final ThreadUtils mThreadUtils;
-    private final boolean mUseTimeScheduler;
-    private final boolean mLimitPagingUpdates;
-    private final boolean mLimitPagingUpdatesInHead;
-
-    public SessionFactory(Store store, TaskQueue taskQueue, TimingUtils timingUtils,
-            ThreadUtils threadUtils, Configuration config) {
-        this.mStore = store;
-        this.mTaskQueue = taskQueue;
-        this.mTimingUtils = timingUtils;
-        this.mThreadUtils = threadUtils;
-        mUseTimeScheduler = config.getValueOrDefault(ConfigKey.USE_TIMEOUT_SCHEDULER, false);
-        mLimitPagingUpdates = config.getValueOrDefault(ConfigKey.LIMIT_PAGE_UPDATES, true);
-        mLimitPagingUpdatesInHead =
-                config.getValueOrDefault(ConfigKey.LIMIT_PAGE_UPDATES_IN_HEAD, false);
-    }
-
-    public InitializableSession getSession() {
-        return mUseTimeScheduler ? new TimeoutSessionImpl(
-                       mStore, mLimitPagingUpdates, mTaskQueue, mTimingUtils, mThreadUtils)
-                                 : new SessionImpl(mStore, mLimitPagingUpdates, mTaskQueue,
-                                         mTimingUtils, mThreadUtils);
-    }
-
-    public HeadSessionImpl getHeadSession() {
-        return new HeadSessionImpl(mStore, mTimingUtils, mLimitPagingUpdatesInHead);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionImpl.java
deleted file mode 100644
index 78e7155..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionImpl.java
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedsessionmanager.internal;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider.ViewDepthProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SessionMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.common.Validators;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue.TaskType;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-
-import java.util.List;
-import java.util.Set;
-
-/** Implementation of a {@link Session}. */
-// TODO: Tiktok doesn't allow HeadSessionImpl to extend SessionImpl
-public class SessionImpl implements InitializableSession, Dumpable {
-    private static final String TAG = "SessionImpl";
-
-    protected final Store mStore;
-    protected final TaskQueue mTaskQueue;
-    protected final ThreadUtils mThreadUtils;
-    protected final TimingUtils mTimingUtils;
-    private final boolean mLimitPagingUpdates;
-    private final SessionContentTracker mSessionContentTracker =
-            new SessionContentTracker(/* supportsClearAll= */ false);
-
-    // Allow creation of the session without a model provider, this becomes an unbound session
-    @Nullable
-    protected ModelProvider mModelProvider;
-    @Nullable
-    protected ViewDepthProvider mViewDepthProvider;
-    protected boolean mLegacyHeadContent;
-
-    protected String mSessionId;
-
-    // operation counts for the dumper
-    int mUpdateCount;
-
-    SessionImpl(Store store, boolean limitPagingUpdates, TaskQueue taskQueue,
-            TimingUtils timingUtils, ThreadUtils threadUtils) {
-        this.mStore = store;
-        this.mTaskQueue = taskQueue;
-        this.mTimingUtils = timingUtils;
-        this.mThreadUtils = threadUtils;
-        this.mLimitPagingUpdates = limitPagingUpdates;
-    }
-
-    @Override
-    public void bindModelProvider(
-            @Nullable ModelProvider modelProvider, @Nullable ViewDepthProvider viewDepthProvider) {
-        this.mModelProvider = modelProvider;
-        this.mViewDepthProvider = viewDepthProvider;
-    }
-
-    @Override
-    public void setSessionId(String sessionId) {
-        this.mSessionId = sessionId;
-    }
-
-    @Override
-    @Nullable
-    public ModelProvider getModelProvider() {
-        return mModelProvider;
-    }
-
-    @Override
-    public void populateModelProvider(List<StreamStructure> head, boolean cachedBindings,
-            boolean legacyHeadContent, UiContext uiContext) {
-        Logger.i(TAG, "PopulateModelProvider %s items", head.size());
-        this.mLegacyHeadContent = legacyHeadContent;
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-
-        if (mModelProvider != null) {
-            ModelMutation modelMutation =
-                    mModelProvider.edit()
-                            .hasCachedBindings(cachedBindings)
-                            .setSessionId(mSessionId)
-                            .setMutationContext(
-                                    new MutationContext.Builder().setUiContext(uiContext).build());
-
-            // Walk through head and add all the DataOperations to the session.
-            for (StreamStructure streamStructure : head) {
-                String contentId = streamStructure.getContentId();
-                switch (streamStructure.getOperation()) {
-                    case UPDATE_OR_APPEND:
-                        if (!mSessionContentTracker.contains(contentId)) {
-                            modelMutation.addChild(streamStructure);
-                        }
-                        break;
-                    case REMOVE:
-                        modelMutation.removeChild(streamStructure);
-                        break;
-                    case REQUIRED_CONTENT:
-                        // No-op, required content should not be passed into modelMutation.
-                        break;
-                    default:
-                        Logger.e(TAG, "unsupported StreamDataOperation: %s",
-                                streamStructure.getOperation());
-                }
-                mSessionContentTracker.update(streamStructure);
-            }
-            modelMutation.commit();
-        } else {
-            mSessionContentTracker.update(head);
-        }
-
-        timeTracker.stop("populateSession", mSessionId, "operations", head.size());
-    }
-
-    @Override
-    public void updateSession(boolean clearHead, List<StreamStructure> streamStructures,
-            int schemaVersion, @Nullable MutationContext mutationContext) {
-        String localSessionId = Validators.checkNotNull(mSessionId);
-        if (clearHead) {
-            if (shouldInvalidateModelProvider(mutationContext, localSessionId)) {
-                if (mModelProvider != null) {
-                    mModelProvider.invalidate();
-                    Logger.i(TAG, "Invalidating Model Provider for session %s due to a clear head",
-                            localSessionId);
-                }
-            } else {
-                Logger.i(TAG, "Session %s not updated due to clearHead", localSessionId);
-            }
-            return;
-        }
-        mUpdateCount++;
-        updateSessionInternal(streamStructures, mutationContext);
-    }
-
-    protected boolean shouldInvalidateModelProvider(
-            @Nullable MutationContext mutationContext, String sessionId) {
-        if (mModelProvider != null && mutationContext != null
-                && mutationContext.getContinuationToken() != null) {
-            return sessionId.equals(mutationContext.getRequestingSessionId());
-        }
-        return false;
-    }
-
-    @Override
-    public boolean invalidateOnResetHead() {
-        return true;
-    }
-
-    void updateSessionInternal(
-            List<StreamStructure> streamStructures, @Nullable MutationContext mutationContext) {
-        ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        StreamToken mutationSourceToken =
-                mutationContext != null ? mutationContext.getContinuationToken() : null;
-        if (mutationSourceToken != null) {
-            String contentId = mutationSourceToken.getContentId();
-            if (!mSessionContentTracker.contains(contentId)) {
-                // Make sure that mutationSourceToken is a token in this session, if not, we don't
-                // update the session.
-                timeTracker.stop("updateSessionIgnored", mSessionId, "Token Not Found", contentId);
-                Logger.i(TAG, "Token %s not found in session, ignoring update", contentId);
-                return;
-            } else if (mLimitPagingUpdates) {
-                String mutationSessionId =
-                        Validators.checkNotNull(mutationContext).getRequestingSessionId();
-                if (mutationSessionId == null) {
-                    Logger.i(TAG, "Request Session was not set, ignoring update");
-                    return;
-                }
-                if (!mSessionId.equals(mutationSessionId)) {
-                    Logger.i(TAG, "Limiting Updates, paging request made on another session");
-                    return;
-                }
-            }
-        }
-
-        ModelMutation modelMutation = (mModelProvider != null) ? mModelProvider.edit() : null;
-        if (modelMutation != null && mutationContext != null) {
-            modelMutation.setMutationContext(mutationContext);
-            if (mutationContext.getContinuationToken() != null) {
-                modelMutation.hasCachedBindings(true);
-            }
-        }
-
-        int updateCnt = 0;
-        int addFeatureCnt = 0;
-        int requiredContentCnt = 0;
-        SessionMutation sessionMutation = mStore.editSession(mSessionId);
-        for (StreamStructure streamStructure : streamStructures) {
-            String contentId = streamStructure.getContentId();
-            switch (streamStructure.getOperation()) {
-                case UPDATE_OR_APPEND:
-                    if (mSessionContentTracker.contains(contentId)) {
-                        // TODO: This could leave an empty feature if contentKey already exists in
-                        // the session with a different parent.
-                        if (modelMutation != null) {
-                            // this is an update operation so we can ignore it
-                            modelMutation.updateChild(streamStructure);
-                            updateCnt++;
-                        }
-                    } else {
-                        sessionMutation.add(streamStructure);
-                        if (modelMutation != null) {
-                            modelMutation.addChild(streamStructure);
-                        }
-                        addFeatureCnt++;
-                    }
-                    break;
-                case REMOVE:
-                    sessionMutation.add(streamStructure);
-                    if (modelMutation != null) {
-                        modelMutation.removeChild(streamStructure);
-                    }
-                    break;
-                case CLEAR_ALL:
-                    Logger.i(TAG, "CLEAR_ALL not support on this session type");
-                    break;
-                case REQUIRED_CONTENT:
-                    if (!mSessionContentTracker.contains(contentId)) {
-                        sessionMutation.add(streamStructure);
-                        requiredContentCnt++;
-                    }
-                    break;
-                default:
-                    Logger.e(
-                            TAG, "Unknown operation, ignoring: %s", streamStructure.getOperation());
-            }
-            mSessionContentTracker.update(streamStructure);
-        }
-
-        // Commit the Model Provider mutation after the store is updated.
-        int taskType = mutationContext != null && mutationContext.isUserInitiated()
-                ? TaskType.IMMEDIATE
-                : TaskType.USER_FACING;
-        mTaskQueue.execute(Task.SESSION_MUTATION, taskType, sessionMutation::commit);
-        if (modelMutation != null) {
-            modelMutation.commit();
-        }
-        timeTracker.stop("updateSession", mSessionId, "features", addFeatureCnt, "updates",
-                updateCnt, "requiredContent", requiredContentCnt);
-    }
-
-    @Override
-    public String getSessionId() {
-        return Validators.checkNotNull(mSessionId);
-    }
-
-    @Override
-    public Set<String> getContentInSession() {
-        return mSessionContentTracker.getContentIds();
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        dumper.forKey("sessionName").value(mSessionId);
-        dumper.forKey("")
-                .value((mModelProvider == null) ? "sessionIsUnbound" : "sessionIsBound")
-                .compactPrevious();
-        dumper.forKey("updateCount").value(mUpdateCount).compactPrevious();
-        dumper.dump(mSessionContentTracker);
-        if (mModelProvider instanceof Dumpable) {
-            dumper.dump((Dumpable) mModelProvider);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionManagerMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionManagerMutation.java
deleted file mode 100644
index f49887bd..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionManagerMutation.java
+++ /dev/null
@@ -1,419 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedsessionmanager.internal;
-
-import android.text.TextUtils;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.KnownContent;
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.InternalFeedError;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.internal.common.Model;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelError;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelError.ErrorType;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider.State;
-import org.chromium.chrome.browser.feed.library.api.internal.store.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SemanticPropertiesMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue.TaskType;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.logging.StringFormattingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure.Operation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Class which implements factory to create the task which commits a mutation to the
- * FeedSessionManager and Sessions. This is created and used by the {@link
- * org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager} to
- * commit a mutation defined as a List of {@link StreamDataOperation}.
- */
-public final class SessionManagerMutation implements Dumpable {
-    private static final String TAG = "SessionManagerMutation";
-
-    private final Store mStore;
-    private final SessionCache mSessionCache;
-    private final ContentCache mContentCache;
-    private final TaskQueue mTaskQueue;
-    private final SchedulerApi mSchedulerApi;
-    private final ThreadUtils mThreadUtils;
-    private final TimingUtils mTimingUtils;
-    private final Clock mClock;
-    private final MainThreadRunner mMainThreadRunner;
-    private final BasicLoggingApi mBasicLoggingApi;
-
-    // operation counts for the dumper
-    private int mCreateCount;
-    private int mCommitCount;
-    private int mErrorCount;
-    private int mContentCommitErrorCount;
-    private int mSemanticPropertiesCommitErrorCount;
-
-    /** Listens for errors which need to be reported to a ModelProvider. */
-    public interface ModelErrorObserver {
-        void onError(@Nullable Session session, ModelError error);
-    }
-
-    public SessionManagerMutation(Store store, SessionCache sessionCache, ContentCache contentCache,
-            TaskQueue taskQueue, SchedulerApi schedulerApi, ThreadUtils threadUtils,
-            TimingUtils timingUtils, Clock clock, MainThreadRunner mainThreadRunner,
-            BasicLoggingApi basicLoggingApi) {
-        this.mStore = store;
-        this.mSessionCache = sessionCache;
-        this.mContentCache = contentCache;
-        this.mTaskQueue = taskQueue;
-        this.mSchedulerApi = schedulerApi;
-        this.mThreadUtils = threadUtils;
-        this.mTimingUtils = timingUtils;
-        this.mClock = clock;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mBasicLoggingApi = basicLoggingApi;
-    }
-
-    /**
-     * Return a Consumer of StreamDataOperations which will update the {@link
-     * org.chromium.chrome.browser.feed.library.api.internal.sessionmanager.FeedSessionManager}.
-     */
-    public Consumer<Result<Model>> createCommitter(String task, MutationContext mutationContext,
-            ModelErrorObserver modelErrorObserver,
-            @Nullable KnownContent.Listener knownContentListener) {
-        mCreateCount++;
-        return new MutationCommitter(task, mutationContext, modelErrorObserver,
-                knownContentListener, mMainThreadRunner, mBasicLoggingApi);
-    }
-
-    public void resetHead() {
-        HeadMutationCommitter mutation = new HeadMutationCommitter();
-        mTaskQueue.execute(
-                Task.INVALIDATE_HEAD, TaskType.HEAD_INVALIDATE, () -> mutation.resetHead(null));
-    }
-
-    public void forceResetHead() {
-        HeadMutationCommitter mutation = new HeadMutationCommitter();
-        mutation.resetHead(null);
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        dumper.forKey("mutationsCreated").value(mCreateCount);
-        dumper.forKey("commitCount").value(mCommitCount).compactPrevious();
-        dumper.forKey("errorCount").value(mErrorCount).compactPrevious();
-        dumper.forKey("contentCommitErrorCount").value(mContentCommitErrorCount).compactPrevious();
-        dumper.forKey("semanticPropertiesCommitErrorCount")
-                .value(mSemanticPropertiesCommitErrorCount)
-                .compactPrevious();
-    }
-
-    public static boolean validDataOperation(StreamDataOperation dataOperation) {
-        if (!dataOperation.hasStreamPayload() || !dataOperation.hasStreamStructure()) {
-            Logger.e(TAG, "Invalid StreamDataOperation - payload or streamStructure not defined");
-            return false;
-        }
-        String contentId = dataOperation.getStreamStructure().getContentId();
-        if (TextUtils.isEmpty(contentId)) {
-            Logger.e(TAG, "Invalid StreamDataOperation - No ID Found");
-            return false;
-        }
-        return true;
-    }
-
-    // TODO: Tiktok doesn't allow MutationCommitter to extend HeadMutationCommitter
-    class HeadMutationCommitter {
-        /**
-         * This runs as a task on the executor thread and also as part of a SessionMutation commit.
-         */
-        @VisibleForTesting
-        void resetHead(@Nullable String mutationSessionId) {
-            mThreadUtils.checkNotMainThread();
-            ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-            Collection<Session> attachedSessions = mSessionCache.getAttachedSessions();
-
-            // If we have old sessions and we received a clear head, let's invalidate the session
-            // that initiated the clear.
-            mStore.clearHead();
-            for (Session session : attachedSessions) {
-                ModelProvider modelProvider = session.getModelProvider();
-                if (modelProvider != null && session.invalidateOnResetHead()
-                        && shouldInvalidateSession(mutationSessionId, modelProvider)) {
-                    invalidateSession(modelProvider, session);
-                }
-            }
-            timeTracker.stop("task", "resetHead");
-        }
-
-        /**
-         * This will determine if the ModelProvider (session) should be invalidated.
-         *
-         * <ol>
-         *   <li>ModelProvider should be READY
-         *   <li>Clearing head was initiated externally, not from an existing session
-         *   <li>Clearing head was initiated by the ModelProvider
-         *   <li>The ModelProvider doesn't yet have a session, so we'll create the session from the
-         * new $HEAD
-         * </ol>
-         */
-        @VisibleForTesting
-        boolean shouldInvalidateSession(
-                @Nullable String mutationSessionId, ModelProvider modelProvider) {
-            // if the model provider isn't READY, don't invalidate the session
-            if (modelProvider.getCurrentState() != State.READY) {
-                return false;
-            }
-            // Clear was done outside of any session.
-            if (mutationSessionId == null) {
-                return true;
-            }
-            // Invalidate if the ModelProvider doesn't yet have a session or if it matches the
-            // session which initiated the request clearing $HEAD.
-            String sessionId = modelProvider.getSessionId();
-            return sessionId == null || sessionId.equals(mutationSessionId);
-        }
-
-        private void invalidateSession(ModelProvider modelProvider, Session session) {
-            mThreadUtils.checkNotMainThread();
-            Logger.i(TAG, "Invalidate session %s", session.getSessionId());
-            modelProvider.invalidate();
-        }
-    }
-
-    @VisibleForTesting
-    class MutationCommitter extends HeadMutationCommitter implements Consumer<Result<Model>> {
-        private final String mTask;
-        private final MutationContext mMutationContext;
-        private final ModelErrorObserver mModelErrorObserver;
-        private final KnownContent.Listener mKnownContentListener;
-
-        private final List<StreamStructure> mStreamStructures = new ArrayList<>();
-        private final MainThreadRunner mMainThreadRunner;
-        private final BasicLoggingApi mBasicLoggingApi;
-
-        @VisibleForTesting
-        boolean mClearedHead;
-        private Model mModel;
-
-        private MutationCommitter(String task, MutationContext mutationContext,
-                ModelErrorObserver modelErrorObserver, KnownContent.Listener knownContentListener,
-                MainThreadRunner mainThreadRunner, BasicLoggingApi basicLoggingApi) {
-            this.mTask = task;
-            this.mMutationContext = mutationContext;
-            this.mModelErrorObserver = modelErrorObserver;
-            this.mKnownContentListener = knownContentListener;
-            this.mMainThreadRunner = mainThreadRunner;
-            this.mBasicLoggingApi = basicLoggingApi;
-        }
-
-        @Override
-        public void accept(Result<Model> updateResults) {
-            if (!updateResults.isSuccessful()) {
-                mErrorCount++;
-                Session session = null;
-                String sessionId = mMutationContext.getRequestingSessionId();
-                if (sessionId != null) {
-                    session = mSessionCache.getAttached(sessionId);
-                }
-                if (mMutationContext.getContinuationToken() != null) {
-                    StreamToken streamToken = mMutationContext.getContinuationToken();
-                    if (session != null && streamToken != null) {
-                        Logger.e(TAG, "Error found with a token request %s",
-                                streamToken.getContentId());
-                        mModelErrorObserver.onError(session,
-                                new ModelError(ErrorType.PAGINATION_ERROR,
-                                        streamToken.getNextPageToken()));
-                    } else {
-                        Logger.e(TAG, "Unable to process PAGINATION_ERROR");
-                    }
-                } else {
-                    Logger.e(TAG, "Update error, the update is being ignored");
-                    mModelErrorObserver.onError(
-                            session, new ModelError(ErrorType.NO_CARDS_ERROR, null));
-                    mTaskQueue.execute(Task.REQUEST_FAILURE, TaskType.HEAD_RESET, () -> {});
-                }
-                return;
-            }
-            mModel = updateResults.getValue();
-            for (StreamDataOperation operation : mModel.streamDataOperations) {
-                if (operation.getStreamStructure().getOperation() == Operation.CLEAR_ALL) {
-                    mClearedHead = true;
-                    break;
-                }
-            }
-            int taskType;
-            if (mMutationContext != null && mMutationContext.isUserInitiated()) {
-                taskType = TaskType.IMMEDIATE;
-            } else {
-                taskType = mClearedHead ? TaskType.HEAD_RESET : TaskType.USER_FACING;
-            }
-            mTaskQueue.execute(Task.COMMIT_TASK, taskType, this::commitTask);
-        }
-
-        private void commitTask() {
-            ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-            commitContent();
-            commitSessionUpdates();
-            mCommitCount++;
-            timeTracker.stop("task", "sessionMutation.commitTask:" + mTask, "mutations",
-                    mStreamStructures.size(), "userInitiated",
-                    mMutationContext != null ? mMutationContext.isUserInitiated()
-                                             : "No MutationContext");
-        }
-
-        private void commitContent() {
-            mThreadUtils.checkNotMainThread();
-            ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-
-            mContentCache.startMutation();
-            ContentMutation contentMutation = mStore.editContent();
-            SemanticPropertiesMutation semanticPropertiesMutation = mStore.editSemanticProperties();
-            for (StreamDataOperation dataOperation : mModel.streamDataOperations) {
-                Operation operation = dataOperation.getStreamStructure().getOperation();
-                if (operation == Operation.CLEAR_ALL) {
-                    mStreamStructures.add(dataOperation.getStreamStructure());
-                    resetHead(mMutationContext.getRequestingSessionId());
-                    continue;
-                }
-
-                if (operation == Operation.UPDATE_OR_APPEND) {
-                    if (!validDataOperation(dataOperation)) {
-                        mErrorCount++;
-                        continue;
-                    }
-                    String contentId = dataOperation.getStreamStructure().getContentId();
-                    StreamPayload payload = dataOperation.getStreamPayload();
-                    if (payload.hasStreamSharedState()) {
-                        // don't add StreamSharedState to the metadata list stored for sessions
-                        contentMutation.add(contentId, payload);
-                    } else if (payload.hasStreamFeature() || payload.hasStreamToken()) {
-                        mContentCache.put(contentId, payload);
-                        contentMutation.add(contentId, payload);
-                        mStreamStructures.add(dataOperation.getStreamStructure());
-                    } else if (dataOperation.getStreamPayload().hasSemanticData()) {
-                        semanticPropertiesMutation.add(
-                                contentId, dataOperation.getStreamPayload().getSemanticData());
-                    } else {
-                        Logger.e(TAG, "Unsupported UPDATE_OR_APPEND payload");
-                    }
-                    continue;
-                }
-
-                if (operation == Operation.REMOVE) {
-                    // We don't update the content for REMOVED items, content will be garbage
-                    // collected.
-                    mStreamStructures.add(dataOperation.getStreamStructure());
-                    continue;
-                }
-
-                if (operation == Operation.REQUIRED_CONTENT) {
-                    mStreamStructures.add(dataOperation.getStreamStructure());
-                    continue;
-                }
-
-                mErrorCount++;
-                Logger.e(TAG, "Unsupported Mutation: %s",
-                        dataOperation.getStreamStructure().getOperation());
-            }
-            mTaskQueue.execute(Task.PERSIST_MUTATION, TaskType.BACKGROUND, () -> {
-                if (contentMutation.commit().getResult() == CommitResult.Result.FAILURE) {
-                    mContentCommitErrorCount++;
-                    Logger.e(TAG, "contentMutation failed");
-                    mMainThreadRunner.execute("CONTENT_MUTATION_FAILED", () -> {
-                        mBasicLoggingApi.onInternalError(InternalFeedError.CONTENT_MUTATION_FAILED);
-                    });
-                }
-                if (semanticPropertiesMutation.commit().getResult()
-                        == CommitResult.Result.FAILURE) {
-                    mSemanticPropertiesCommitErrorCount++;
-                    Logger.e(TAG, "semanticPropertiesMutation failed");
-                }
-                mContentCache.finishMutation();
-            });
-            timeTracker.stop("", "contentUpdate", "items", mModel.streamDataOperations.size());
-        }
-
-        private void commitSessionUpdates() {
-            mThreadUtils.checkNotMainThread();
-            ElapsedTimeTracker timeTracker = mTimingUtils.getElapsedTimeTracker(TAG);
-
-            StreamDataProto.StreamToken mutationSourceToken =
-                    (mMutationContext != null) ? mMutationContext.getContinuationToken() : null;
-            // For sessions we want to add the remove operation if the mutation source was a
-            // continuation token.
-            if (mutationSourceToken != null) {
-                StreamStructure removeOperation = addTokenRemoveOperation(mutationSourceToken);
-                if (removeOperation != null) {
-                    mStreamStructures.add(0, removeOperation);
-                }
-            }
-            Collection<Session> updates = mSessionCache.getAllSessions();
-
-            HeadSessionImpl head = mSessionCache.getHead();
-            for (Session session : updates) {
-                ModelProvider modelProvider = session.getModelProvider();
-                if (modelProvider != null && modelProvider.getCurrentState() == State.INVALIDATED) {
-                    Logger.w(TAG, "Removing an invalidate session");
-                    // Remove all invalidated sessions
-                    mSessionCache.removeAttached(session.getSessionId());
-                    continue;
-                }
-                if (session == head) {
-                    long updateTime = mClock.currentTimeMillis();
-                    if (mClearedHead) {
-                        session.updateSession(mClearedHead, mStreamStructures, mModel.schemaVersion,
-                                mMutationContext);
-                        mSessionCache.updateHeadMetadata(updateTime, mModel.schemaVersion);
-                        mSchedulerApi.onReceiveNewContent(updateTime);
-                        if (mKnownContentListener != null) {
-                            mKnownContentListener.onNewContentReceived(
-                                    /* isNewRefresh */ true, updateTime);
-                        }
-                        Logger.i(TAG, "Cleared Head, new creation time %s",
-                                StringFormattingUtils.formatLogDate(updateTime));
-                        continue;
-                    } else if (mKnownContentListener != null) {
-                        mKnownContentListener.onNewContentReceived(
-                                /* isNewRefresh */ false, updateTime);
-                    }
-                }
-                Logger.i(TAG, "Update Session %s", session.getSessionId());
-                session.updateSession(
-                        mClearedHead, mStreamStructures, mModel.schemaVersion, mMutationContext);
-            }
-            timeTracker.stop("", "sessionUpdate", "sessions", updates.size());
-        }
-
-        @Nullable
-        private StreamStructure addTokenRemoveOperation(StreamToken token) {
-            return StreamStructure.newBuilder()
-                    .setContentId(token.getContentId())
-                    .setParentContentId(token.getParentId())
-                    .setOperation(Operation.REMOVE)
-                    .build();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/TimeoutSessionImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/TimeoutSessionImpl.java
deleted file mode 100644
index af9cd45..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/TimeoutSessionImpl.java
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedsessionmanager.internal;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild.Type;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.common.Validators;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure.Operation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/** SessionImpl which implements the TimeoutScheduler specific behaviors need within the session. */
-public final class TimeoutSessionImpl extends SessionImpl {
-    private static final String TAG = "TimeoutSessionImpl";
-
-    TimeoutSessionImpl(Store store, boolean limitPagingUpdates, TaskQueue taskQueue,
-            TimingUtils timingUtils, ThreadUtils threadUtils) {
-        super(store, limitPagingUpdates, taskQueue, timingUtils, threadUtils);
-        Logger.i(TAG, "Using TimeoutSessionImpl");
-    }
-
-    @Override
-    public void populateModelProvider(List<StreamStructure> head, boolean cachedBindings,
-            boolean legacyHeadContent, UiContext uiContext) {
-        Logger.i(TAG, "TimeoutSession.populateModelProvider, shouldAppend %s", legacyHeadContent);
-        super.populateModelProvider(head, cachedBindings, legacyHeadContent, uiContext);
-    }
-
-    @Override
-    public void updateSession(boolean clearHead, List<StreamStructure> streamStructures,
-            int schemaVersion, @Nullable MutationContext mutationContext) {
-        String localSessionId = Validators.checkNotNull(mSessionId);
-        Logger.i(TAG, "updateSession; clearHead(%b), shouldAppend(%b), sessionId(%s)", clearHead,
-                mLegacyHeadContent, localSessionId);
-        if (clearHead) {
-            if (!mLegacyHeadContent) {
-                if (shouldInvalidateModelProvider(mutationContext, localSessionId)) {
-                    if (mModelProvider != null) {
-                        if (mutationContext == null) {
-                            mModelProvider.invalidate(UiContext.getDefaultInstance());
-                        } else {
-                            mModelProvider.invalidate(mutationContext.getUiContext());
-                        }
-                        Logger.i(TAG,
-                                "Invalidating Model Provider for session %s due to a clear head",
-                                localSessionId);
-                    }
-                } else {
-                    // Without having legacy HEAD content, don't update the session,
-                    Logger.i(TAG, "Not configured to append: %s", localSessionId);
-                }
-                return;
-            }
-
-            if (mViewDepthProvider != null) {
-                // Append the new items to the existing copy of HEAD, removing the existing items
-                // which have not yet been seen by the user.
-                List<ModelChild> rootChildren = captureRootContent();
-                if (!rootChildren.isEmpty()) {
-                    // Calculate the children to remove and append StreamStructure remove operations
-                    String lowestChild =
-                            Validators.checkNotNull(mViewDepthProvider).getChildViewDepth();
-                    List<StreamStructure> removeOperations = removeItems(lowestChild, rootChildren);
-                    Logger.i(TAG, "Removing %d items", removeOperations.size());
-                    if (!removeOperations.isEmpty()) {
-                        removeOperations.addAll(streamStructures);
-                        streamStructures = removeOperations;
-                    }
-                }
-            }
-            // Only do this once
-            mLegacyHeadContent = false;
-        }
-
-        mUpdateCount++;
-        updateSessionInternal(streamStructures, mutationContext);
-    }
-
-    @Override
-    public boolean invalidateOnResetHead() {
-        return false;
-    }
-
-    /**
-     * Remove items found below the specified {@code lowestChild}. If {@code lowestChild} is itself
-     * a token, it will also be removed to avoid multiple "More" buttons. If {@code lowestChild} is
-     * {@literal null}, only tokens will be removed to prevent potentially removing items that the
-     * user can currently see.
-     */
-    private List<StreamStructure> removeItems(
-            @Nullable String lowestChild, List<ModelChild> rootChildren) {
-        boolean remove = false;
-        List<StreamStructure> removeOperations = new ArrayList<>();
-        for (ModelChild child : rootChildren) {
-            if (remove || child.getType() == Type.TOKEN) {
-                removeOperations.add(
-                        createRemoveFeature(child.getContentId(), child.getParentId()));
-            } else if (child.getContentId().equals(lowestChild)) {
-                remove = true;
-            }
-        }
-        return removeOperations;
-    }
-
-    @VisibleForTesting
-    List<ModelChild> captureRootContent() {
-        ModelProvider modelProvider = getModelProvider();
-        if (modelProvider == null) {
-            Logger.w(TAG, "ModelProvider was not found");
-            return Collections.emptyList();
-        }
-        return modelProvider.getAllRootChildren();
-    }
-
-    @VisibleForTesting
-    StreamStructure createRemoveFeature(String contentId, @Nullable String parentId) {
-        StreamStructure.Builder builder =
-                StreamStructure.newBuilder().setOperation(Operation.REMOVE).setContentId(contentId);
-        if (parentId != null) {
-            builder.setParentContentId(parentId);
-        }
-        return builder.build();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/testing/AbstractSessionImplTest.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/testing/AbstractSessionImplTest.java
deleted file mode 100644
index 6cb39a4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/testing/AbstractSessionImplTest.java
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedsessionmanager.internal.testing;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-import static org.mockito.MockitoAnnotations.initMocks;
-
-import static org.chromium.chrome.browser.feed.library.common.testing.RunnableSubject.assertThatRunnable;
-
-import org.junit.Test;
-import org.mockito.Mock;
-
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.internal.common.testing.ContentIdGenerators;
-import org.chromium.chrome.browser.feed.library.api.internal.common.testing.InternalProtocolBuilder;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SessionMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.feedsessionmanager.internal.SessionImpl;
-import org.chromium.chrome.browser.feed.library.testing.modelprovider.FakeModelMutation;
-import org.chromium.chrome.browser.feed.library.testing.modelprovider.FakeModelProvider;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Abstract class implementing many of the core SessionImpl tests. */
-public abstract class AbstractSessionImplTest {
-    protected static final String TEST_SESSION_ID = "TEST$1";
-    protected static final int SCHEMA_VERSION = 1;
-
-    protected final ContentIdGenerators mContentIdGenerators = new ContentIdGenerators();
-
-    @Mock
-    protected Store mStore;
-    protected FakeSessionMutation mFakeSessionMutation;
-    protected FakeModelProvider mFakeModelProvider;
-
-    private Boolean mSessionMutationResults = true;
-
-    protected void setUp() {
-        initMocks(this);
-        mFakeSessionMutation = new FakeSessionMutation();
-        mFakeModelProvider = new FakeModelProvider();
-        when(mStore.editSession(TEST_SESSION_ID)).thenReturn(mFakeSessionMutation);
-    }
-
-    protected abstract SessionImpl getSessionImpl();
-
-    @Test
-    public void testPopulateModelProvider_features() {
-        SessionImpl session = getSessionImpl();
-        int featureCnt = 3;
-        InternalProtocolBuilder protocolBuilder = new InternalProtocolBuilder();
-        addFeatures(protocolBuilder, featureCnt, 1);
-        List<StreamStructure> streamStructures = protocolBuilder.buildAsStreamStructure();
-
-        // 3 features
-        assertThat(streamStructures).hasSize(featureCnt);
-        session.setSessionId(TEST_SESSION_ID);
-        session.populateModelProvider(
-                streamStructures, false, false, UiContext.getDefaultInstance());
-        FakeModelMutation fakeModelMutation = mFakeModelProvider.getLatestModelMutation();
-        assertThat(fakeModelMutation.mAddedChildren).hasSize(featureCnt);
-        assertThat(fakeModelMutation.isCommitted()).isTrue();
-        assertThat(session.getContentInSession()).hasSize(featureCnt);
-        assertThat(session.getContentInSession())
-                .contains(mContentIdGenerators.createFeatureContentId(1));
-    }
-
-    @Test
-    public void testUpdateSession_notFullyInitialized() {
-        SessionImpl session = getSessionImpl();
-        assertThatRunnable(
-                () -> session.updateSession(false, new ArrayList<>(), SCHEMA_VERSION, null))
-                .throwsAnExceptionOfType(NullPointerException.class);
-    }
-
-    @Test
-    public void testUpdateSession_features() {
-        SessionImpl session = getSessionImpl();
-        session.setSessionId(TEST_SESSION_ID);
-        session.populateModelProvider(
-                new ArrayList<>(), false, false, UiContext.getDefaultInstance());
-        int featureCnt = 3;
-        InternalProtocolBuilder protocolBuilder = new InternalProtocolBuilder().addClearOperation();
-        addFeatures(protocolBuilder, featureCnt, 1);
-        List<StreamStructure> streamStructures = protocolBuilder.buildAsStreamStructure();
-
-        // 1 clear, 3 features
-        assertThat(streamStructures).hasSize(4);
-        session.updateSession(false, streamStructures, SCHEMA_VERSION, null);
-        assertThat(mFakeSessionMutation.streamStructures).hasSize(featureCnt);
-        FakeModelMutation fakeModelMutation = mFakeModelProvider.getLatestModelMutation();
-        assertThat(fakeModelMutation.mAddedChildren).hasSize(featureCnt);
-        assertThat(session.getContentInSession()).hasSize(featureCnt);
-        assertThat(session.getContentInSession())
-                .contains(mContentIdGenerators.createFeatureContentId(1));
-    }
-
-    @Test
-    public void testUpdateFromToken() {
-        SessionImpl session = getSessionImpl();
-        session.setSessionId(TEST_SESSION_ID);
-        session.populateModelProvider(
-                new ArrayList<>(), false, false, UiContext.getDefaultInstance());
-        int featureCnt = 3;
-        InternalProtocolBuilder protocolBuilder = new InternalProtocolBuilder();
-        addFeatures(protocolBuilder, featureCnt, 1);
-        List<StreamStructure> streamStructures = protocolBuilder.buildAsStreamStructure();
-
-        StreamToken token = StreamToken.newBuilder()
-                                    .setContentId(mContentIdGenerators.createTokenContentId(2))
-                                    .build();
-        MutationContext context = new MutationContext.Builder().setContinuationToken(token).build();
-
-        // The token needs to be in the session so temporarily detach the session to update its
-        // content IDs with the token.
-        ModelProvider modelProvider = session.getModelProvider();
-        session.bindModelProvider(null, null);
-
-        List<StreamStructure> tokenStructures = new InternalProtocolBuilder()
-                                                        .addToken(token.getContentId())
-                                                        .buildAsStreamStructure();
-        session.updateSession(false, tokenStructures, SCHEMA_VERSION, null);
-
-        session.bindModelProvider(modelProvider, null);
-
-        session.updateSession(false, streamStructures, SCHEMA_VERSION, context);
-        FakeModelMutation fakeModelMutation = mFakeModelProvider.getLatestModelMutation();
-        assertThat(fakeModelMutation.mMutationContext).isEqualTo(context);
-    }
-
-    @Test
-    public void testUpdateFromToken_notInSession() {
-        SessionImpl session = getSessionImpl();
-        session.setSessionId(TEST_SESSION_ID);
-        session.populateModelProvider(
-                new ArrayList<>(), false, false, UiContext.getDefaultInstance());
-        int featureCnt = 3;
-        InternalProtocolBuilder protocolBuilder = new InternalProtocolBuilder();
-        addFeatures(protocolBuilder, featureCnt, 1);
-        List<StreamStructure> streamStructures = protocolBuilder.buildAsStreamStructure();
-
-        // The token is not in the session, so we ignore the update
-        assertThat(session.getContentInSession()).isEmpty();
-        StreamToken token = StreamToken.newBuilder()
-                                    .setContentId(mContentIdGenerators.createTokenContentId(2))
-                                    .build();
-        MutationContext context = new MutationContext.Builder().setContinuationToken(token).build();
-        session.updateSession(false, streamStructures, SCHEMA_VERSION, context);
-        assertThat(session.getContentInSession()).isEmpty();
-    }
-
-    @Test
-    public void testStorageFailure() {
-        SessionImpl session = getSessionImpl();
-        session.setSessionId(TEST_SESSION_ID);
-        session.populateModelProvider(
-                new ArrayList<>(), false, false, UiContext.getDefaultInstance());
-        int featureCnt = 3;
-        InternalProtocolBuilder protocolBuilder = new InternalProtocolBuilder();
-        addFeatures(protocolBuilder, featureCnt, 1);
-        List<StreamStructure> streamStructures = protocolBuilder.buildAsStreamStructure();
-
-        mSessionMutationResults = false;
-        session.updateSession(false, streamStructures, SCHEMA_VERSION, null);
-        FakeModelMutation fakeModelMutation = mFakeModelProvider.getLatestModelMutation();
-        assertThat(fakeModelMutation.isCommitted())
-                .isTrue(); // Optimistic write will still call this
-    }
-
-    @Test
-    public void testRemove() {
-        SessionImpl session = getSessionImpl();
-        session.setSessionId(TEST_SESSION_ID);
-        session.populateModelProvider(
-                new ArrayList<>(), false, false, UiContext.getDefaultInstance());
-        InternalProtocolBuilder protocolBuilder = new InternalProtocolBuilder();
-        int featureCnt = 2;
-        addFeatures(protocolBuilder, featureCnt, 1);
-        protocolBuilder.removeFeature(mContentIdGenerators.createFeatureContentId(1),
-                mContentIdGenerators.createRootContentId(0));
-        List<StreamStructure> streamStructures = protocolBuilder.buildAsStreamStructure();
-        session.updateSession(false, streamStructures, SCHEMA_VERSION, null);
-        FakeModelMutation fakeModelMutation = mFakeModelProvider.getLatestModelMutation();
-        assertThat(fakeModelMutation.mRemovedChildren).hasSize(1);
-        assertThat(session.getContentInSession()).hasSize(1);
-    }
-
-    protected void addFeatures(
-            InternalProtocolBuilder protocolBuilder, int featureCnt, int startId) {
-        for (int i = 0; i < featureCnt; i++) {
-            protocolBuilder.addFeature(mContentIdGenerators.createFeatureContentId(startId++),
-                    mContentIdGenerators.createRootContentId(0));
-        }
-    }
-
-    /** Fake SessionMutation for tests. */
-    protected final class FakeSessionMutation implements SessionMutation {
-        public final List<StreamStructure> streamStructures = new ArrayList<>();
-
-        @Override
-        public SessionMutation add(StreamStructure dataOperation) {
-            streamStructures.add(dataOperation);
-            return this;
-        }
-
-        @Override
-        public Boolean commit() {
-            return mSessionMutationResults;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/ContentStorageDirectImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/ContentStorageDirectImpl.java
deleted file mode 100644
index 7c82679..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/ContentStorageDirectImpl.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorage;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorageDirect;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadCaller;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * An implementation of {@link ContentStorageDirect} which converts {@link ContentStorage} to a
- * synchronized implementation. This acts as a wrapper class over ContentStorage. It will provide a
- * consumer calling on the main thread and waiting on a Future to complete to return the consumer
- * results.
- */
-public final class ContentStorageDirectImpl
-        extends MainThreadCaller implements ContentStorageDirect {
-    private static final String LOCATION = "ContentStorage.";
-    private final ContentStorage mContentStorage;
-
-    public ContentStorageDirectImpl(
-            ContentStorage contentStorage, MainThreadRunner mainThreadRunner) {
-        super(mainThreadRunner);
-        this.mContentStorage = contentStorage;
-    }
-
-    @Override
-    public Result<Map<String, byte[]>> get(List<String> keys) {
-        if (keys.isEmpty()) {
-            return Result.success(Collections.emptyMap());
-        }
-
-        return mainThreadCaller(LOCATION + "get",
-                (consumer) -> mContentStorage.get(keys, consumer), Result.failure());
-    }
-
-    @Override
-    public Result<Map<String, byte[]>> getAll(String prefix) {
-        return mainThreadCaller(LOCATION + "getAll",
-                (consumer) -> mContentStorage.getAll(prefix, consumer), Result.failure());
-    }
-
-    @Override
-    public CommitResult commit(ContentMutation mutation) {
-        return mainThreadCaller(LOCATION + "commit",
-                (consumer) -> mContentStorage.commit(mutation, consumer), CommitResult.FAILURE);
-    }
-
-    @Override
-    public Result<List<String>> getAllKeys() {
-        return mainThreadCaller(
-                LOCATION + "getAllKeys", mContentStorage::getAllKeys, Result.failure());
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/FeedStore.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/FeedStore.java
deleted file mode 100644
index ebfc7c3..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/FeedStore.java
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore;
-
-import com.google.protobuf.ByteString;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.InternalFeedError;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorageDirect;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorageDirect;
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.common.SemanticPropertiesWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.lifecycle.Resettable;
-import org.chromium.chrome.browser.feed.library.api.internal.store.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.LocalActionMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SemanticPropertiesMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SessionMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.api.internal.store.StoreListener;
-import org.chromium.chrome.browser.feed.library.api.internal.store.UploadableActionMutation;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue.TaskType;
-import org.chromium.chrome.browser.feed.library.common.feedobservable.FeedObservable;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.protoextensions.FeedExtensionRegistry;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.chrome.browser.feed.library.feedapplifecyclelistener.FeedLifecycleListener;
-import org.chromium.chrome.browser.feed.library.feedstore.internal.ClearableStore;
-import org.chromium.chrome.browser.feed.library.feedstore.internal.EphemeralFeedStore;
-import org.chromium.chrome.browser.feed.library.feedstore.internal.FeedStoreHelper;
-import org.chromium.chrome.browser.feed.library.feedstore.internal.PersistentFeedStore;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamLocalAction;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-/**
- * {@link Store} implementation that delegates between {@link PersistentFeedStore} and {@link
- * EphemeralFeedStore}.
- *
- * <p>TODO: We need to design the StoreListener support correctly. For the switch to
- * ephemeral mode, the Observers are called from here. If we ever have events which are raised by
- * one of the delegates, we need to make sure the registered observers are called correctly,
- * independent of what delegate is actually running. The delegates currently throw a
- * IllegalStateException if the register/unregister methods are called.
- */
-public class FeedStore
-        extends FeedObservable<StoreListener> implements Store, Resettable, FeedLifecycleListener {
-    private static final String TAG = "FeedStore";
-
-    // Permanent reference to the persistent store (used for setting off cleanup)
-    private final PersistentFeedStore mPersistentStore;
-    private final MainThreadRunner mMainThreadRunner;
-    // The current store
-    private ClearableStore mDelegate;
-
-    private final TaskQueue mTaskQueue;
-
-    // Needed for switching to ephemeral mode
-    private final FeedStoreHelper mStoreHelper = new FeedStoreHelper();
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final Clock mClock;
-    private final TimingUtils mTimingUtils;
-    private final ThreadUtils mThreadUtils;
-
-    private boolean mIsEphemeralMode;
-
-    protected final ContentStorageDirect mContentStorage;
-    protected final JournalStorageDirect mJournalStorage;
-
-    public FeedStore(Configuration configuration, TimingUtils timingUtils,
-            FeedExtensionRegistry extensionRegistry, ContentStorageDirect contentStorage,
-            JournalStorageDirect journalStorage, ThreadUtils threadUtils, TaskQueue taskQueue,
-            Clock clock, BasicLoggingApi basicLoggingApi, MainThreadRunner mainThreadRunner) {
-        this.mTaskQueue = taskQueue;
-        this.mClock = clock;
-        this.mTimingUtils = timingUtils;
-        this.mThreadUtils = threadUtils;
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mContentStorage = contentStorage;
-        this.mJournalStorage = journalStorage;
-
-        this.mPersistentStore = new PersistentFeedStore(configuration, this.mTimingUtils,
-                extensionRegistry, contentStorage, journalStorage, this.mTaskQueue, threadUtils,
-                this.mClock, this.mStoreHelper, basicLoggingApi, mainThreadRunner);
-        mDelegate = mPersistentStore;
-    }
-
-    @Override
-    public Result<List<PayloadWithId>> getPayloads(List<String> contentIds) {
-        return mDelegate.getPayloads(contentIds);
-    }
-
-    @Override
-    public Result<List<StreamSharedState>> getSharedStates() {
-        return mDelegate.getSharedStates();
-    }
-
-    @Override
-    public Result<List<StreamStructure>> getStreamStructures(String sessionId) {
-        return mDelegate.getStreamStructures(sessionId);
-    }
-
-    @Override
-    public Result<List<String>> getAllSessions() {
-        return mDelegate.getAllSessions();
-    }
-
-    @Override
-    public Result<List<SemanticPropertiesWithId>> getSemanticProperties(List<String> contentIds) {
-        return mDelegate.getSemanticProperties(contentIds);
-    }
-
-    @Override
-    public Result<List<StreamLocalAction>> getAllDismissLocalActions() {
-        return mDelegate.getAllDismissLocalActions();
-    }
-
-    @Override
-    public Result<Set<StreamUploadableAction>> getAllUploadableActions() {
-        return mDelegate.getAllUploadableActions();
-    }
-
-    @Override
-    public Result<String> createNewSession() {
-        return mDelegate.createNewSession();
-    }
-
-    @Override
-    public void removeSession(String sessionId) {
-        mDelegate.removeSession(sessionId);
-    }
-
-    @Override
-    public void clearHead() {
-        mDelegate.clearHead();
-    }
-
-    @Override
-    public ContentMutation editContent() {
-        return mDelegate.editContent();
-    }
-
-    @Override
-    public SessionMutation editSession(String sessionId) {
-        return mDelegate.editSession(sessionId);
-    }
-
-    @Override
-    public SemanticPropertiesMutation editSemanticProperties() {
-        return mDelegate.editSemanticProperties();
-    }
-
-    @Override
-    public LocalActionMutation editLocalActions() {
-        return mDelegate.editLocalActions();
-    }
-
-    @Override
-    public UploadableActionMutation editUploadableActions() {
-        return mDelegate.editUploadableActions();
-    }
-
-    @Override
-    public Runnable triggerContentGc(Set<String> reservedContentIds,
-            Supplier<Set<String>> accessibleContent, boolean keepSharedStates) {
-        return mDelegate.triggerContentGc(reservedContentIds, accessibleContent, keepSharedStates);
-    }
-
-    @Override
-    public Runnable triggerLocalActionGc(
-            List<StreamLocalAction> actions, List<String> validContentIds) {
-        return mDelegate.triggerLocalActionGc(actions, validContentIds);
-    }
-
-    @Override
-    public boolean isEphemeralMode() {
-        return mIsEphemeralMode;
-    }
-
-    @Override
-    public void switchToEphemeralMode() {
-        // This should be called on a background thread because it's called during error handling.
-        mThreadUtils.checkNotMainThread();
-        if (!mIsEphemeralMode) {
-            mPersistentStore.switchToEphemeralMode();
-            mDelegate = new EphemeralFeedStore(mClock, mTimingUtils, mStoreHelper);
-
-            mTaskQueue.execute(Task.CLEAR_PERSISTENT_STORE_TASK, TaskType.BACKGROUND, () -> {
-                ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-                // Try to just wipe content + sessions
-                boolean clearSuccess = mPersistentStore.clearNonActionContent();
-                // If that fails, wipe everything.
-                if (!clearSuccess) {
-                    mPersistentStore.clearAll();
-                }
-                tracker.stop("clearPersistentStore", "completed");
-            });
-
-            mIsEphemeralMode = true;
-            synchronized (mObservers) {
-                for (StoreListener listener : mObservers) {
-                    listener.onSwitchToEphemeralMode();
-                }
-            }
-            mMainThreadRunner.execute("log ephemeral switch",
-                    () -> mBasicLoggingApi.onInternalError(InternalFeedError.SWITCH_TO_EPHEMERAL));
-        }
-    }
-
-    @Override
-    public void reset() {
-        mPersistentStore.clearNonActionContent();
-    }
-
-    @Override
-    public void onLifecycleEvent(@LifecycleEvent String event) {
-        if (LifecycleEvent.ENTER_BACKGROUND.equals(event) && mIsEphemeralMode) {
-            mTaskQueue.execute(
-                    Task.DUMP_EPHEMERAL_ACTIONS, TaskType.BACKGROUND, this::dumpEphemeralActions);
-        }
-    }
-
-    private void dumpEphemeralActions() {
-        // Get all action-related content (actions + semantic data)
-        Result<List<StreamLocalAction>> dismissActionsResult =
-                mDelegate.getAllDismissLocalActions();
-        if (!dismissActionsResult.isSuccessful()) {
-            Logger.e(TAG, "Error retrieving actions when trying to dump ephemeral actions.");
-            return;
-        }
-        List<StreamLocalAction> dismissActions = dismissActionsResult.getValue();
-        LocalActionMutation localActionMutation = mPersistentStore.editLocalActions();
-        List<String> dismissActionContentIds = new ArrayList<>(dismissActions.size());
-        for (StreamLocalAction dismiss : dismissActions) {
-            dismissActionContentIds.add(dismiss.getFeatureContentId());
-            localActionMutation.add(dismiss.getAction(), dismiss.getFeatureContentId());
-        }
-        Result<List<SemanticPropertiesWithId>> semanticPropertiesResult =
-                mDelegate.getSemanticProperties(dismissActionContentIds);
-        if (!semanticPropertiesResult.isSuccessful()) {
-            Logger.e(TAG,
-                    "Error retrieving semantic properties when trying to dump ephemeral actions.");
-            return;
-        }
-        SemanticPropertiesMutation semanticPropertiesMutation =
-                mPersistentStore.editSemanticProperties();
-        for (SemanticPropertiesWithId semanticProperties : semanticPropertiesResult.getValue()) {
-            semanticPropertiesMutation.add(semanticProperties.contentId,
-                    ByteString.copyFrom(semanticProperties.semanticData));
-        }
-
-        // Attempt to write action-related content to persistent storage
-        CommitResult commitResult = localActionMutation.commit();
-        if (commitResult != CommitResult.SUCCESS) {
-            Logger.e(TAG,
-                    "Error writing actions to persistent store when dumping ephemeral actions.");
-            return;
-        }
-        commitResult = semanticPropertiesMutation.commit();
-        if (commitResult != CommitResult.SUCCESS) {
-            Logger.e(TAG,
-                    "Error writing semantic properties to persistent store when dumping"
-                            + " ephemeral actions.");
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/JournalStorageDirectImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/JournalStorageDirectImpl.java
deleted file mode 100644
index 34e826b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/JournalStorageDirectImpl.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorage;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorageDirect;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadCaller;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-
-import java.util.List;
-
-/**
- * An implementation of {@link JournalStorageDirect} which converts {@link JournalStorage} to a
- * synchronized implementation. This acts as a wrapper class over JournalStorage. It will provide a
- * consumer calling on the main thread and waiting on a Future to complete to return the consumer
- * results.
- */
-public final class JournalStorageDirectImpl
-        extends MainThreadCaller implements JournalStorageDirect {
-    private static final String LOCATION = "JournalStorage.";
-    private final JournalStorage mJournalStorage;
-
-    public JournalStorageDirectImpl(
-            JournalStorage journalStorage, MainThreadRunner mainThreadRunner) {
-        super(mainThreadRunner);
-        this.mJournalStorage = journalStorage;
-    }
-
-    @Override
-    public Result<List<byte[]>> read(String journalName) {
-        return mainThreadCaller(LOCATION + "read",
-                (consumer) -> mJournalStorage.read(journalName, consumer), Result.failure());
-    }
-
-    @Override
-    public CommitResult commit(JournalMutation mutation) {
-        return mainThreadCaller(LOCATION + "commit",
-                (consumer) -> mJournalStorage.commit(mutation, consumer), CommitResult.FAILURE);
-    }
-
-    @Override
-    public Result<Boolean> exists(String journalName) {
-        return mainThreadCaller(LOCATION + "exists",
-                (consumer) -> mJournalStorage.exists(journalName, consumer), Result.failure());
-    }
-
-    @Override
-    public Result<List<String>> getAllJournals() {
-        return mainThreadCaller(
-                LOCATION + "getAllJournals", mJournalStorage::getAllJournals, Result.failure());
-    }
-
-    @Override
-    public CommitResult deleteAll() {
-        return mainThreadCaller(
-                LOCATION + "deleteAll", mJournalStorage::deleteAll, CommitResult.FAILURE);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/ClearableStore.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/ClearableStore.java
deleted file mode 100644
index fa8567b8..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/ClearableStore.java
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.internal;
-
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-
-public interface ClearableStore extends Store {
-    /** Clear all data stored in the store */
-    boolean clearAll();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/ContentGc.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/ContentGc.java
deleted file mode 100644
index 7a996f0..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/ContentGc.java
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.internal;
-
-import static org.chromium.chrome.browser.feed.library.feedstore.internal.FeedStoreConstants.SEMANTIC_PROPERTIES_PREFIX;
-import static org.chromium.chrome.browser.feed.library.feedstore.internal.FeedStoreConstants.SHARED_STATE_PREFIX;
-import static org.chromium.chrome.browser.feed.library.feedstore.internal.FeedStoreConstants.UPLOADABLE_ACTION_PREFIX;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorageDirect;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue.TaskType;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamLocalAction;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-/** Storage Content Garbage Collector. */
-public final class ContentGc {
-    private static final String TAG = "ContentGc";
-
-    private final Supplier<Set<String>> mAccessibleContentSupplier;
-    private final Set<String> mReservedContentIds;
-    private final Supplier<Set<StreamLocalAction>> mActionsSupplier;
-    private final ContentStorageDirect mContentStorageDirect;
-    private final TimingUtils mTimingUtils;
-    private final TaskQueue mTaskQueue;
-    private final boolean mKeepSharedStates;
-    private final long mMaxAllowedGcAttempts;
-
-    private int mContentGcAttempts;
-
-    ContentGc(Configuration configuration, Supplier<Set<String>> accessibleContentSupplier,
-            Set<String> reservedContentIds, Supplier<Set<StreamLocalAction>> actionsSupplier,
-            ContentStorageDirect contentStorageDirect, TaskQueue taskQueue, TimingUtils timingUtils,
-            boolean keepSharedStates) {
-        this.mAccessibleContentSupplier = accessibleContentSupplier;
-        this.mReservedContentIds = reservedContentIds;
-        this.mActionsSupplier = actionsSupplier;
-        this.mContentStorageDirect = contentStorageDirect;
-        this.mTaskQueue = taskQueue;
-        this.mTimingUtils = timingUtils;
-        this.mKeepSharedStates = keepSharedStates;
-        mMaxAllowedGcAttempts = configuration.getValueOrDefault(ConfigKey.MAXIMUM_GC_ATTEMPTS, 10L);
-    }
-
-    void gc() {
-        if (mTaskQueue.hasBacklog() && mContentGcAttempts < mMaxAllowedGcAttempts) {
-            Logger.i(TAG, "Re-enqueuing triggerContentGc; attempts(%d)", mContentGcAttempts);
-            mContentGcAttempts++;
-            mTaskQueue.execute(Task.GARBAGE_COLLECT_CONTENT, TaskType.BACKGROUND, this::gc);
-            return;
-        }
-
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        Set<String> population = getPopulation();
-        // remove the items in the population that are accessible, reserved, or semantic properties
-        // either accessible or associated with an action
-        Set<String> accessibleContent = getAccessible();
-        population.removeAll(accessibleContent);
-        population.removeAll(mReservedContentIds);
-        population.removeAll(getAccessibleSemanticProperties(accessibleContent));
-        population.removeAll(getLocalActionSemanticProperties(getLocalActions()));
-        filterUploadableActions(population);
-        if (mKeepSharedStates) {
-            filterSharedStates(population);
-        } else {
-            population.removeAll(getAccessibleSharedStates(accessibleContent));
-        }
-
-        // Population now contains only un-accessible items
-        removeUnAccessible(population);
-        tracker.stop("task", "ContentGc", "contentItemsRemoved", population.size());
-    }
-
-    private void removeUnAccessible(Set<String> unAccessible) {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        ContentMutation.Builder mutationBuilder = new ContentMutation.Builder();
-        for (String key : unAccessible) {
-            Logger.i(TAG, "Removing %s", key);
-            mutationBuilder.delete(key);
-        }
-        CommitResult result = mContentStorageDirect.commit(mutationBuilder.build());
-        if (result == CommitResult.FAILURE) {
-            Logger.e(TAG, "Content Modification failed removing unaccessible items.");
-        }
-        tracker.stop("", "removeUnAccessible", "mutations", unAccessible.size());
-    }
-
-    private void filterSharedStates(Set<String> population) {
-        filterPrefix(population, SHARED_STATE_PREFIX);
-    }
-
-    private void filterUploadableActions(Set<String> population) {
-        filterPrefix(population, UPLOADABLE_ACTION_PREFIX);
-    }
-
-    private void filterPrefix(Set<String> population, String prefix) {
-        int size = population.size();
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        Iterator<String> i = population.iterator();
-        while (i.hasNext()) {
-            String key = i.next();
-            if (key.startsWith(prefix)) {
-                i.remove();
-            }
-        }
-        tracker.stop("", "filterPrefix " + prefix, population.size() - size);
-    }
-
-    private Set<String> getAccessible() {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        Set<String> accessibleContent = mAccessibleContentSupplier.get();
-        tracker.stop("", "getAccessible", "accessableContent", accessibleContent.size());
-        return accessibleContent;
-    }
-
-    private Set<StreamLocalAction> getLocalActions() {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        Set<StreamLocalAction> actions = mActionsSupplier.get();
-        tracker.stop("", "getLocalActions", "actionCount", actions.size());
-        return actions;
-    }
-
-    private Set<String> getPopulation() {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        Set<String> population = new HashSet<>();
-        Result<List<String>> result = mContentStorageDirect.getAllKeys();
-        if (result.isSuccessful()) {
-            population.addAll(result.getValue());
-        } else {
-            Logger.e(TAG, "Unable to get all content, getAll failed");
-        }
-        tracker.stop("", "getPopulation", "contentPopulation", population.size());
-        return population;
-    }
-
-    private Set<String> getAccessibleSemanticProperties(Set<String> accessibleContent) {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        Set<String> semanticPropertiesKeys = new HashSet<>();
-        for (String accessibleContentId : accessibleContent) {
-            String semanticPropertyKey = SEMANTIC_PROPERTIES_PREFIX + accessibleContentId;
-            semanticPropertiesKeys.add(semanticPropertyKey);
-        }
-        tracker.stop("", "getAccessibleSemanticProperties", "accessibleSemanticPropertiesSize",
-                semanticPropertiesKeys.size());
-        return semanticPropertiesKeys;
-    }
-
-    private Set<String> getAccessibleSharedStates(Set<String> accessibleContent) {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        Set<String> sharedStateKeys = new HashSet<>();
-        for (String accessibleContentId : accessibleContent) {
-            String sharedStateKey = SHARED_STATE_PREFIX + accessibleContentId;
-            sharedStateKeys.add(sharedStateKey);
-        }
-        tracker.stop("", "getAccessibleSharedStates", "accessibleSharedStatesSize",
-                sharedStateKeys.size());
-        return sharedStateKeys;
-    }
-
-    private Set<String> getLocalActionSemanticProperties(Set<StreamLocalAction> actions) {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        Set<String> semanticPropertiesKeys = new HashSet<>();
-        for (StreamLocalAction action : actions) {
-            String semanticPropertyKey = SEMANTIC_PROPERTIES_PREFIX + action.getFeatureContentId();
-            semanticPropertiesKeys.add(semanticPropertyKey);
-        }
-        tracker.stop("", "getLocalActionSemanticProperties", "actionSemanticPropertiesSize",
-                semanticPropertiesKeys.size());
-        return semanticPropertiesKeys;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/EphemeralFeedStore.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/EphemeralFeedStore.java
deleted file mode 100644
index 7f714ca..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/EphemeralFeedStore.java
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.internal;
-
-import com.google.protobuf.ByteString;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.common.SemanticPropertiesWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.store.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.LocalActionMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.LocalActionMutation.ActionType;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SemanticPropertiesMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SessionMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.StoreListener;
-import org.chromium.chrome.browser.feed.library.api.internal.store.UploadableActionMutation;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamLocalAction;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/** Ephemeral version of Store */
-public final class EphemeralFeedStore implements ClearableStore {
-    private static final String TAG = "EphemeralFeedStore";
-    private static final Runnable EMPTY_RUNNABLE = () -> {};
-
-    private final Clock mClock;
-    private final TimingUtils mTimingUtils;
-    private final FeedStoreHelper mStoreHelper;
-
-    private final Map<String, PayloadWithId> mPayloadWithIdMap = new HashMap<>();
-    private final Map<String, StreamSharedState> mSharedStateMap = new HashMap<>();
-    private final Map<String, ByteString> mSemanticPropertiesMap = new HashMap<>();
-    private final Map<Integer, List<StreamLocalAction>> mActionsMap = new HashMap<>();
-    private final Map<String, Set<StreamUploadableAction>> mUploadableActionsMap = new HashMap<>();
-    private final Map<String, List<StreamStructure>> mSessionsMap = new HashMap<>();
-
-    public EphemeralFeedStore(Clock clock, TimingUtils timingUtils, FeedStoreHelper storeHelper) {
-        this.mClock = clock;
-        this.mTimingUtils = timingUtils;
-        this.mStoreHelper = storeHelper;
-    }
-
-    @Override
-    public Result<List<PayloadWithId>> getPayloads(List<String> contentIds) {
-        List<PayloadWithId> payloads = new ArrayList<>(contentIds.size());
-        for (String contentId : contentIds) {
-            PayloadWithId payload = mPayloadWithIdMap.get(contentId);
-            if (payload != null) {
-                payloads.add(payload);
-            }
-        }
-        return Result.success(payloads);
-    }
-
-    @Override
-    public Result<List<StreamSharedState>> getSharedStates() {
-        return Result.success(
-                Collections.unmodifiableList(new ArrayList<>(mSharedStateMap.values())));
-    }
-
-    @Override
-    public Result<List<StreamStructure>> getStreamStructures(String sessionId) {
-        List<StreamStructure> streamStructures = mSessionsMap.get(sessionId);
-        if (streamStructures == null) {
-            streamStructures = Collections.emptyList();
-        }
-        return Result.success(streamStructures);
-    }
-
-    @Override
-    public Result<List<String>> getAllSessions() {
-        Set<String> sessions = mSessionsMap.keySet();
-        ArrayList<String> returnValues = new ArrayList<>();
-        for (String sessionId : sessions) {
-            if (!HEAD_SESSION_ID.equals(sessionId)) {
-                returnValues.add(sessionId);
-            }
-        }
-        return Result.success(returnValues);
-    }
-
-    @Override
-    public Result<List<SemanticPropertiesWithId>> getSemanticProperties(List<String> contentIds) {
-        List<SemanticPropertiesWithId> semanticPropertiesWithIds =
-                new ArrayList<>(contentIds.size());
-        for (String contentId : contentIds) {
-            ByteString semanticProperties = mSemanticPropertiesMap.get(contentId);
-            if (semanticProperties != null) {
-                // TODO: switch SemanticPropertiesWithId to use byte array directly
-                semanticPropertiesWithIds.add(
-                        new SemanticPropertiesWithId(contentId, semanticProperties.toByteArray()));
-            }
-        }
-        return Result.success(semanticPropertiesWithIds);
-    }
-
-    @Override
-    public Result<List<StreamLocalAction>> getAllDismissLocalActions() {
-        List<StreamLocalAction> dismissActions = mActionsMap.get(ActionType.DISMISS);
-        if (dismissActions == null) {
-            dismissActions = Collections.emptyList();
-        }
-        return Result.success(dismissActions);
-    }
-
-    @Override
-    public Result<Set<StreamUploadableAction>> getAllUploadableActions() {
-        Set<StreamUploadableAction> uploadableActions = new HashSet<>();
-        for (Set<StreamUploadableAction> actions : mUploadableActionsMap.values()) {
-            uploadableActions.addAll(actions);
-        }
-        return Result.success(uploadableActions);
-    }
-
-    @Override
-    public Result<String> createNewSession() {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        String sessionId = mStoreHelper.getNewStreamSessionId();
-        Result<List<StreamStructure>> streamStructuresResult = getStreamStructures(HEAD_SESSION_ID);
-        mSessionsMap.put(sessionId, new ArrayList<>(streamStructuresResult.getValue()));
-        tracker.stop("createNewSession", sessionId);
-        return Result.success(sessionId);
-    }
-
-    @Override
-    public void removeSession(String sessionId) {
-        if (sessionId.equals(HEAD_SESSION_ID)) {
-            throw new IllegalStateException("Unable to delete the $HEAD session");
-        }
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        mSessionsMap.remove(sessionId);
-        tracker.stop("removeSession", sessionId);
-    }
-
-    @Override
-    public void clearHead() {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        mSessionsMap.remove(HEAD_SESSION_ID);
-        tracker.stop("", "clearHead");
-    }
-
-    @Override
-    public ContentMutation editContent() {
-        return new FeedContentMutation(this::commitContentMutation);
-    }
-
-    private CommitResult commitContentMutation(List<PayloadWithId> mutations) {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-
-        for (PayloadWithId mutation : mutations) {
-            String contentId = mutation.contentId;
-            if (mutation.payload.hasStreamSharedState()) {
-                StreamSharedState streamSharedState = mutation.payload.getStreamSharedState();
-                mSharedStateMap.put(contentId, streamSharedState);
-            } else {
-                mPayloadWithIdMap.put(contentId, mutation);
-            }
-        }
-        tracker.stop("task", "commitContentMutation", "mutations", mutations.size());
-        return CommitResult.SUCCESS;
-    }
-
-    @Override
-    public SessionMutation editSession(String sessionId) {
-        return new FeedSessionMutation(
-                feedSessionMutation -> commitSessionMutation(sessionId, feedSessionMutation));
-    }
-
-    private Boolean commitSessionMutation(
-            String sessionId, List<StreamStructure> streamStructures) {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        List<StreamStructure> sessionStructures = mSessionsMap.get(sessionId);
-        if (sessionStructures == null) {
-            sessionStructures = new ArrayList<>();
-            mSessionsMap.put(sessionId, sessionStructures);
-        }
-        sessionStructures.addAll(streamStructures);
-        tracker.stop("", "commitSessionMutation", "mutations", streamStructures.size());
-        return Boolean.TRUE;
-    }
-
-    @Override
-    public SemanticPropertiesMutation editSemanticProperties() {
-        return new FeedSemanticPropertiesMutation(this::commitSemanticPropertiesMutation);
-    }
-
-    private CommitResult commitSemanticPropertiesMutation(
-            Map<String, ByteString> semanticPropertiesMap) {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        this.mSemanticPropertiesMap.putAll(semanticPropertiesMap);
-        tracker.stop(
-                "", "commitSemanticPropertiesMutation", "mutations", semanticPropertiesMap.size());
-        return CommitResult.SUCCESS;
-    }
-
-    @Override
-    public UploadableActionMutation editUploadableActions() {
-        return new FeedUploadableActionMutation(this::commitUploadableActionMutation);
-    }
-
-    private CommitResult commitUploadableActionMutation(
-            Map<String, FeedUploadableActionMutation.FeedUploadableActionChanges> actions) {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        CommitResult commitResult = CommitResult.SUCCESS;
-        for (Map.Entry<String, FeedUploadableActionMutation.FeedUploadableActionChanges> entry :
-                actions.entrySet()) {
-            String contentId = entry.getKey();
-            FeedUploadableActionMutation.FeedUploadableActionChanges changes = entry.getValue();
-            Set<StreamUploadableAction> actionsSet = mUploadableActionsMap.get(contentId);
-            if (actionsSet == null) {
-                actionsSet = new HashSet<>();
-            }
-            actionsSet.removeAll(changes.removeActions());
-            actionsSet.addAll(changes.upsertActions());
-            mUploadableActionsMap.put(contentId, actionsSet);
-        }
-        tracker.stop("task", "commitUploadableActionMutation", "actions", actions.size());
-        return commitResult;
-    }
-
-    @Override
-    public LocalActionMutation editLocalActions() {
-        return new FeedLocalActionMutation(this::commitLocalActionMutation);
-    }
-
-    private CommitResult commitLocalActionMutation(Map<Integer, List<String>> actions) {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        CommitResult commitResult = CommitResult.SUCCESS;
-        for (Map.Entry<Integer, List<String>> entry : actions.entrySet()) {
-            Integer actionType = entry.getKey();
-            List<StreamLocalAction> actionsList = mActionsMap.get(actionType);
-            if (actionsList == null) {
-                actionsList = new ArrayList<>();
-                mActionsMap.put(actionType, actionsList);
-            }
-            for (String contentId : entry.getValue()) {
-                StreamLocalAction action =
-                        StreamLocalAction.newBuilder()
-                                .setAction(actionType)
-                                .setFeatureContentId(contentId)
-                                .setTimestampSeconds(
-                                        TimeUnit.MILLISECONDS.toSeconds(mClock.currentTimeMillis()))
-                                .build();
-                actionsList.add(action);
-            }
-        }
-
-        tracker.stop("task", "commitLocalActionMutation", "actions", actions.size());
-        return commitResult;
-    }
-
-    @Override
-    public Runnable triggerContentGc(Set<String> reservedContentIds,
-            Supplier<Set<String>> accessibleContent, boolean keepSharedStates) {
-        // No garbage collection in ephemeral mode
-        return EMPTY_RUNNABLE;
-    }
-
-    @Override
-    public Runnable triggerLocalActionGc(
-            List<StreamLocalAction> actions, List<String> validContentIds) {
-        // No garbage collection in ephemeral mode
-        return EMPTY_RUNNABLE;
-    }
-
-    @Override
-    public void switchToEphemeralMode() {
-        // Do nothing
-    }
-
-    @Override
-    public boolean isEphemeralMode() {
-        return true;
-    }
-
-    @Override
-    public void registerObserver(StoreListener observer) {
-        throw new UnsupportedOperationException(
-                "PersistentFeedStore does not support observer directly");
-    }
-
-    @Override
-    public void unregisterObserver(StoreListener observer) {
-        throw new UnsupportedOperationException(
-                "PersistentFeedStore does not support observer directly");
-    }
-
-    @Override
-    public boolean clearAll() {
-        mPayloadWithIdMap.clear();
-        mActionsMap.clear();
-        mSemanticPropertiesMap.clear();
-        mSessionsMap.clear();
-        mSharedStateMap.clear();
-        return true;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedContentMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedContentMutation.java
deleted file mode 100644
index 0bf4d50..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedContentMutation.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.internal;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.store.ContentMutation;
-import org.chromium.chrome.browser.feed.library.common.functional.Committer;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** This class will mutate the Content stored in the FeedStore. */
-public final class FeedContentMutation implements ContentMutation {
-    private final List<PayloadWithId> mMutations = new ArrayList<>();
-    private final Committer<CommitResult, List<PayloadWithId>> mCommitter;
-
-    FeedContentMutation(Committer<CommitResult, List<PayloadWithId>> committer) {
-        this.mCommitter = committer;
-    }
-
-    @Override
-    public ContentMutation add(String contentId, StreamPayload payload) {
-        mMutations.add(new PayloadWithId(contentId, payload));
-        return this;
-    }
-
-    @Override
-    public CommitResult commit() {
-        return mCommitter.commit(mMutations);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedLocalActionMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedLocalActionMutation.java
deleted file mode 100644
index 9dc73d5..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedLocalActionMutation.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.internal;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.internal.store.LocalActionMutation;
-import org.chromium.chrome.browser.feed.library.common.functional.Committer;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/** Implementation of {@link LocalActionMutation} */
-public final class FeedLocalActionMutation implements LocalActionMutation {
-    private static final String TAG = "FeedLocalActionMutation";
-
-    private final Map<Integer, List<String>> mActions = new HashMap<>();
-    private final Committer<CommitResult, Map<Integer, List<String>>> mCommitter;
-
-    FeedLocalActionMutation(Committer<CommitResult, Map<Integer, List<String>>> committer) {
-        this.mCommitter = committer;
-    }
-
-    @Override
-    public LocalActionMutation add(int action, String contentId) {
-        @Nullable
-        List<String> actionsForType = mActions.get(action);
-        if (actionsForType == null) {
-            actionsForType = new ArrayList<>();
-        }
-        actionsForType.add(contentId);
-        mActions.put(action, actionsForType);
-        Logger.i(TAG, "Added action %d with content id %s", action, contentId);
-        return this;
-    }
-
-    @Override
-    public CommitResult commit() {
-        return mCommitter.commit(mActions);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedSemanticPropertiesMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedSemanticPropertiesMutation.java
deleted file mode 100644
index ad05f51..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedSemanticPropertiesMutation.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.internal;
-
-import com.google.protobuf.ByteString;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SemanticPropertiesMutation;
-import org.chromium.chrome.browser.feed.library.common.functional.Committer;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/** Implementation of the {@link SemanticPropertiesMutation}. */
-public final class FeedSemanticPropertiesMutation implements SemanticPropertiesMutation {
-    private final Map<String, ByteString> mSemanticPropertiesMap = new HashMap<>();
-    private final Committer<CommitResult, Map<String, ByteString>> mCommitter;
-
-    FeedSemanticPropertiesMutation(Committer<CommitResult, Map<String, ByteString>> committer) {
-        this.mCommitter = committer;
-    }
-
-    @Override
-    public SemanticPropertiesMutation add(String contentId, ByteString semanticData) {
-        mSemanticPropertiesMap.put(contentId, semanticData);
-        return this;
-    }
-
-    @Override
-    public CommitResult commit() {
-        return mCommitter.commit(mSemanticPropertiesMap);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedSessionMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedSessionMutation.java
deleted file mode 100644
index 797c4cf..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedSessionMutation.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.internal;
-
-import org.chromium.chrome.browser.feed.library.api.internal.store.SessionMutation;
-import org.chromium.chrome.browser.feed.library.common.functional.Committer;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Implementation of the {@link SessionMutation}. */
-public final class FeedSessionMutation implements SessionMutation {
-    private final List<StreamStructure> mStreamStructures = new ArrayList<>();
-    private final Committer<Boolean, List<StreamStructure>> mCommitter;
-
-    FeedSessionMutation(Committer<Boolean, List<StreamStructure>> committer) {
-        this.mCommitter = committer;
-    }
-
-    @Override
-    public SessionMutation add(StreamStructure streamStructure) {
-        mStreamStructures.add(streamStructure);
-        return this;
-    }
-
-    @Override
-    public Boolean commit() {
-        return mCommitter.commit(mStreamStructures);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedStoreConstants.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedStoreConstants.java
deleted file mode 100644
index 89ac4626..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedStoreConstants.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.internal;
-
-/** Group of constants for use across the {@link FeedStore} class and its internal classes */
-public final class FeedStoreConstants {
-    /** Can't be instantiated */
-    private FeedStoreConstants() {}
-
-    /** Used to prefix session IDs */
-    public static final String SESSION_NAME_PREFIX = "_session:";
-
-    /** Key used to prefix Feed shared states keys in {@link ContentStorage} */
-    public static final String SHARED_STATE_PREFIX = "ss::";
-
-    /** Key used to prefix Feed semantic properties keys in {@link ContentStorage} */
-    public static final String SEMANTIC_PROPERTIES_PREFIX = "sp::";
-
-    /** Key used to prefix Feed uploadableAction keys in {@link ContentStorage} */
-    public static final String UPLOADABLE_ACTION_PREFIX = "ua::";
-
-    /** The name of the journal used to store dismiss actions */
-    public static final String DISMISS_ACTION_JOURNAL = "action-dismiss";
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedStoreHelper.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedStoreHelper.java
deleted file mode 100644
index 59cdd66a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedStoreHelper.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.internal;
-
-import static org.chromium.chrome.browser.feed.library.feedstore.internal.FeedStoreConstants.SESSION_NAME_PREFIX;
-
-import java.util.UUID;
-
-/** Helper class for shared FeedStore methods */
-public final class FeedStoreHelper {
-    /** Get a new, unique stream session id. */
-    String getNewStreamSessionId() {
-        return SESSION_NAME_PREFIX + UUID.randomUUID();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedUploadableActionMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedUploadableActionMutation.java
deleted file mode 100644
index f92c42d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedUploadableActionMutation.java
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.internal;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.internal.store.UploadableActionMutation;
-import org.chromium.chrome.browser.feed.library.common.functional.Committer;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/** Implementation of {@link UploadableActionMutation} */
-public final class FeedUploadableActionMutation implements UploadableActionMutation {
-    private static final String TAG = "FeedUploadableActionMutation";
-
-    private final Map<String, FeedUploadableActionChanges> mActions = new HashMap<>();
-    private final Committer<CommitResult, Map<String, FeedUploadableActionChanges>> mCommitter;
-
-    FeedUploadableActionMutation(
-            Committer<CommitResult, Map<String, FeedUploadableActionChanges>> committer) {
-        this.mCommitter = committer;
-    }
-
-    @Override
-    public UploadableActionMutation upsert(StreamUploadableAction action, String contentId) {
-        @Nullable
-        FeedUploadableActionChanges actionsForId = mActions.get(contentId);
-        if (actionsForId == null) {
-            actionsForId = new FeedUploadableActionChanges();
-        }
-        actionsForId.upsertAction(action);
-        mActions.put(contentId, actionsForId);
-        Logger.i(TAG, "Adding action %d", action);
-        return this;
-    }
-
-    @Override
-    public UploadableActionMutation remove(StreamUploadableAction action, String contentId) {
-        @Nullable
-        FeedUploadableActionChanges actionsForId = mActions.get(contentId);
-        if (actionsForId == null) {
-            actionsForId = new FeedUploadableActionChanges();
-        }
-        actionsForId.removeAction(action);
-        mActions.put(contentId, actionsForId);
-        Logger.i(TAG, "Removing action %d", action);
-        return this;
-    }
-
-    @Override
-    public CommitResult commit() {
-        return mCommitter.commit(mActions);
-    }
-
-    public static class FeedUploadableActionChanges {
-        private final Set<StreamUploadableAction> mUpsertActions;
-        private final Set<StreamUploadableAction> mRemoveActions;
-
-        FeedUploadableActionChanges() {
-            this.mUpsertActions = new HashSet<>();
-            this.mRemoveActions = new HashSet<>();
-        }
-
-        void upsertAction(StreamUploadableAction action) {
-            mUpsertActions.add(action);
-            mRemoveActions.remove(action);
-        }
-
-        void removeAction(StreamUploadableAction action) {
-            mRemoveActions.add(action);
-            mUpsertActions.remove(action);
-        }
-
-        public Set<StreamUploadableAction> upsertActions() {
-            return mUpsertActions;
-        }
-
-        public Set<StreamUploadableAction> removeActions() {
-            return mRemoveActions;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/LocalActionGc.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/LocalActionGc.java
deleted file mode 100644
index 75a9bb7..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/LocalActionGc.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.internal;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorageDirect;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamLocalAction;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Garbage collector for {@link StreamLocalAction}s stored in a journal */
-public final class LocalActionGc {
-    private static final String TAG = "LocalActionGc";
-
-    private final List<StreamLocalAction> mActions;
-    private final List<String> mValidContentIds;
-    private final JournalStorageDirect mJournalStorageDirect;
-    private final TimingUtils mTimingUtils;
-    private final String mJournalName;
-
-    LocalActionGc(List<StreamLocalAction> actions, List<String> validContentIds,
-            JournalStorageDirect journalStorageDirect, TimingUtils timingUtils,
-            String journalName) {
-        this.mActions = actions;
-        this.mValidContentIds = validContentIds;
-        this.mJournalStorageDirect = journalStorageDirect;
-        this.mTimingUtils = timingUtils;
-        this.mJournalName = journalName;
-    }
-
-    /**
-     * Cleans up the store based on {@link #mActions} and {@link #mValidContentIds}. Any valid
-     * actions will be copied over to a new copy of the action journal.
-     */
-    void gc() {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        List<StreamLocalAction> validActions = new ArrayList<>(mValidContentIds.size());
-
-        for (StreamLocalAction action : mActions) {
-            if (mValidContentIds.contains(action.getFeatureContentId())) {
-                validActions.add(action);
-            }
-        }
-
-        JournalMutation.Builder mutationBuilder = new JournalMutation.Builder(mJournalName);
-        mutationBuilder.delete();
-
-        for (StreamLocalAction action : validActions) {
-            mutationBuilder.append(action.toByteArray());
-        }
-        CommitResult result = mJournalStorageDirect.commit(mutationBuilder.build());
-        if (result == CommitResult.SUCCESS) {
-            tracker.stop("gcMutation", mActions.size() - validActions.size());
-        } else {
-            tracker.stop("gcMutation failed");
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/PersistentFeedStore.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/PersistentFeedStore.java
deleted file mode 100644
index 3ad96e7f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/PersistentFeedStore.java
+++ /dev/null
@@ -1,661 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.internal;
-
-import static org.chromium.chrome.browser.feed.library.feedstore.internal.FeedStoreConstants.DISMISS_ACTION_JOURNAL;
-import static org.chromium.chrome.browser.feed.library.feedstore.internal.FeedStoreConstants.SEMANTIC_PROPERTIES_PREFIX;
-import static org.chromium.chrome.browser.feed.library.feedstore.internal.FeedStoreConstants.SHARED_STATE_PREFIX;
-import static org.chromium.chrome.browser.feed.library.feedstore.internal.FeedStoreConstants.UPLOADABLE_ACTION_PREFIX;
-
-import android.util.Base64;
-
-import com.google.protobuf.ByteString;
-import com.google.protobuf.InvalidProtocolBufferException;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.InternalFeedError;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorage;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorageDirect;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorage;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorageDirect;
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.common.SemanticPropertiesWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.api.internal.store.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.LocalActionMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.LocalActionMutation.ActionType;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SemanticPropertiesMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SessionMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.StoreListener;
-import org.chromium.chrome.browser.feed.library.api.internal.store.UploadableActionMutation;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.intern.Interner;
-import org.chromium.chrome.browser.feed.library.common.intern.InternerWithStats;
-import org.chromium.chrome.browser.feed.library.common.intern.WeakPoolInterner;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.protoextensions.FeedExtensionRegistry;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils.ElapsedTimeTracker;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamLocalAction;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Implementation of the Store. The PersistentFeedStore will call the host APIs {@link
- * ContentStorage} and {@link JournalStorage} to make persistent changes.
- */
-public final class PersistentFeedStore implements ClearableStore, Dumpable {
-    private static final String TAG = "PersistentFeedStore";
-
-    private final Configuration mConfiguration;
-    private final TimingUtils mTimingUtils;
-    private final FeedExtensionRegistry mExtensionRegistry;
-    private final ContentStorageDirect mContentStorageDirect;
-    private final JournalStorageDirect mJournalStorageDirect;
-    private final TaskQueue mTaskQueue;
-    private final ThreadUtils mThreadUtils;
-    private final Clock mClock;
-    private final FeedStoreHelper mStoreHelper;
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final MainThreadRunner mMainThreadRunner;
-
-    // We use a common string interner pool because the same content IDs are reused across different
-    // protos. The actual proto interners below are backed by thisl common pool.
-    private final InternerWithStats<String> mContentIdStringInterner =
-            new InternerWithStats<>(new WeakPoolInterner<>());
-    private final Interner<StreamStructure> mStreamStructureInterner =
-            new StreamStructureInterner(mContentIdStringInterner);
-    private final Interner<StreamPayload> mStreamPayloadInterner =
-            new StreamPayloadInterner(mContentIdStringInterner);
-
-    public PersistentFeedStore(Configuration configuration, TimingUtils timingUtils,
-            FeedExtensionRegistry extensionRegistry, ContentStorageDirect contentStorageDirect,
-            JournalStorageDirect journalStorageDirect, TaskQueue taskQueue, ThreadUtils threadUtils,
-            Clock clock, FeedStoreHelper storeHelper, BasicLoggingApi basicLoggingApi,
-            MainThreadRunner mainThreadRunner) {
-        this.mConfiguration = configuration;
-        this.mTimingUtils = timingUtils;
-        this.mExtensionRegistry = extensionRegistry;
-        this.mContentStorageDirect = contentStorageDirect;
-        this.mJournalStorageDirect = journalStorageDirect;
-        this.mTaskQueue = taskQueue;
-        this.mThreadUtils = threadUtils;
-        this.mClock = clock;
-        this.mStoreHelper = storeHelper;
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mMainThreadRunner = mainThreadRunner;
-    }
-
-    @Override
-    public Result<List<PayloadWithId>> getPayloads(List<String> contentIds) {
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        List<PayloadWithId> payloads = new ArrayList<>(contentIds.size());
-        Result<Map<String, byte[]>> contentResult = mContentStorageDirect.get(contentIds);
-        if (!contentResult.isSuccessful()) {
-            Logger.e(TAG, "Unsuccessful fetching payloads for content ids %s", contentIds);
-            tracker.stop("getPayloads failed", "items", contentIds);
-            return Result.failure();
-        }
-
-        for (Map.Entry<String, byte[]> entry : contentResult.getValue().entrySet()) {
-            try {
-                StreamPayload streamPayload = mStreamPayloadInterner.intern(StreamPayload.parseFrom(
-                        entry.getValue(), mExtensionRegistry.getExtensionRegistry()));
-                payloads.add(new PayloadWithId(entry.getKey(), streamPayload));
-            } catch (InvalidProtocolBufferException e) {
-                Logger.e(TAG, "Couldn't parse content proto for id %s", entry.getKey());
-                mMainThreadRunner.execute("ITEM_NOT_PARSED", () -> {
-                    mBasicLoggingApi.onInternalError(InternalFeedError.ITEM_NOT_PARSED);
-                });
-            }
-        }
-        tracker.stop("", "getPayloads", "items", payloads.size());
-        return Result.success(payloads);
-    }
-
-    @Override
-    public Result<List<StreamSharedState>> getSharedStates() {
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        Result<Map<String, byte[]>> bytesResult = mContentStorageDirect.getAll(SHARED_STATE_PREFIX);
-        if (!bytesResult.isSuccessful()) {
-            Logger.e(TAG, "Error fetching shared states");
-            tracker.stop("getSharedStates", "failed");
-            return Result.failure();
-        }
-        Collection<byte[]> result = bytesResult.getValue().values();
-        List<StreamSharedState> sharedStates = new ArrayList<>(result.size());
-        for (byte[] byteArray : result) {
-            try {
-                sharedStates.add(StreamSharedState.parseFrom(byteArray));
-            } catch (InvalidProtocolBufferException e) {
-                Logger.e(TAG, e, "Error parsing protocol buffer from bytes %s", byteArray);
-                tracker.stop("getSharedStates", "failed");
-                return Result.failure();
-            }
-        }
-        tracker.stop("", "getSharedStates", "items", sharedStates.size());
-        return Result.success(sharedStates);
-    }
-
-    @Override
-    public Result<List<StreamStructure>> getStreamStructures(String sessionId) {
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        List<StreamStructure> streamStructures;
-        Result<List<byte[]>> operationsResult = mJournalStorageDirect.read(sessionId);
-        if (!operationsResult.isSuccessful()) {
-            Logger.e(TAG, "Error fetching stream structures for session %s", sessionId);
-            tracker.stop("getStreamStructures failed", "session", sessionId);
-            return Result.failure();
-        }
-        List<byte[]> results = operationsResult.getValue();
-        streamStructures = new ArrayList<>(results.size());
-        for (byte[] bytes : results) {
-            if (bytes.length == 0) {
-                continue;
-            }
-            try {
-                streamStructures.add(
-                        mStreamStructureInterner.intern(StreamStructure.parseFrom(bytes)));
-            } catch (InvalidProtocolBufferException e) {
-                Logger.e(TAG, e, "Error parsing stream structure.");
-            }
-        }
-        tracker.stop("", "getStreamStructures", "items", streamStructures.size());
-        return Result.success(streamStructures);
-    }
-
-    @Override
-    public Result<List<String>> getAllSessions() {
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        List<String> sessions;
-
-        Result<List<String>> namesResult = mJournalStorageDirect.getAllJournals();
-        if (!namesResult.isSuccessful()) {
-            Logger.e(TAG, "Error fetching all journals");
-            tracker.stop("getAllSessions failed");
-            return Result.failure();
-        }
-
-        List<String> result = namesResult.getValue();
-        sessions = new ArrayList<>(result.size());
-        for (String name : result) {
-            if (HEAD_SESSION_ID.equals(name)) {
-                // Don't add $HEAD to the sessions list
-                continue;
-            }
-            if (DISMISS_ACTION_JOURNAL.equals(name)) {
-                // Don't add Dismiss Actions journal to sessions list
-                continue;
-            }
-            sessions.add(name);
-        }
-        tracker.stop("", "getAllSessions", "items", sessions.size());
-        return Result.success(sessions);
-    }
-
-    @Override
-    public Result<List<SemanticPropertiesWithId>> getSemanticProperties(List<String> contentIds) {
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        List<SemanticPropertiesWithId> semanticPropertiesWithIds =
-                new ArrayList<>(contentIds.size());
-        List<String> contentIdKeys = new ArrayList<>(contentIds.size());
-        for (String contentId : contentIds) {
-            contentIdKeys.add(SEMANTIC_PROPERTIES_PREFIX + contentId);
-        }
-        Result<Map<String, byte[]>> mapResult = mContentStorageDirect.get(contentIdKeys);
-
-        if (mapResult.isSuccessful()) {
-            for (Map.Entry<String, byte[]> entry : mapResult.getValue().entrySet()) {
-                String contentId = entry.getKey().replace(SEMANTIC_PROPERTIES_PREFIX, "");
-                if (contentIds.contains(contentId)) {
-                    semanticPropertiesWithIds.add(
-                            new SemanticPropertiesWithId(contentId, entry.getValue()));
-                }
-            }
-        } else {
-            Logger.e(TAG, "Error fetching semantic properties for content ids %s", contentIds);
-            tracker.stop("getSemanticProperties failed", contentIds);
-        }
-
-        tracker.stop("task", "getSemanticProperties", "size", semanticPropertiesWithIds.size());
-        return Result.success(semanticPropertiesWithIds);
-    }
-
-    @Override
-    public Result<List<StreamLocalAction>> getAllDismissLocalActions() {
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-
-        Result<List<byte[]>> listResult = mJournalStorageDirect.read(DISMISS_ACTION_JOURNAL);
-        if (!listResult.isSuccessful()) {
-            Logger.e(TAG, "Error retrieving dismiss journal");
-            tracker.stop("getAllDismissLocalActions failed");
-            return Result.failure();
-        } else {
-            List<byte[]> actionByteArrays = listResult.getValue();
-            List<StreamLocalAction> actions = new ArrayList<>(actionByteArrays.size());
-            for (byte[] bytes : actionByteArrays) {
-                StreamLocalAction action;
-                try {
-                    action = StreamLocalAction.parseFrom(bytes);
-                    actions.add(action);
-                } catch (InvalidProtocolBufferException e) {
-                    Logger.e(TAG, e, "Error parsing StreamLocalAction for bytes: %s (length %d)",
-                            Base64.encodeToString(bytes, Base64.DEFAULT), bytes.length);
-                }
-            }
-            tracker.stop("task", "getAllDismissLocalActions", "size", actions.size());
-            return Result.success(actions);
-        }
-    }
-
-    @Override
-    public Result<Set<StreamUploadableAction>> getAllUploadableActions() {
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        Result<Map<String, byte[]>> bytesResult =
-                mContentStorageDirect.getAll(UPLOADABLE_ACTION_PREFIX);
-        if (!bytesResult.isSuccessful()) {
-            Logger.e(TAG, "Error fetching shared states");
-            tracker.stop("getAllUploadableActions", "failed");
-            return Result.failure();
-        }
-        Collection<byte[]> result = bytesResult.getValue().values();
-        Set<StreamUploadableAction> uploadableActions = new HashSet<>();
-        for (byte[] byteArray : result) {
-            try {
-                uploadableActions.add(StreamUploadableAction.parseFrom(byteArray));
-            } catch (InvalidProtocolBufferException e) {
-                tracker.stop("getAllUploadableActions", "failed");
-                Logger.e(TAG, e, "Error parsing protocol buffer from bytes %s", byteArray);
-                return Result.failure();
-            }
-        }
-        tracker.stop("", "getAllUploadableActions", "items", uploadableActions.size());
-        return Result.success(uploadableActions);
-    }
-
-    @Override
-    public Result<String> createNewSession() {
-        mThreadUtils.checkNotMainThread();
-
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        String sessionId = mStoreHelper.getNewStreamSessionId();
-        mJournalStorageDirect.commit(
-                new JournalMutation.Builder(HEAD_SESSION_ID).copy(sessionId).build());
-        tracker.stop("createNewSession", sessionId);
-        return Result.success(sessionId);
-    }
-
-    @Override
-    public void removeSession(String sessionId) {
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        if (sessionId.equals(HEAD_SESSION_ID)) {
-            throw new IllegalStateException("Unable to delete the $HEAD session");
-        }
-        mJournalStorageDirect.commit(new JournalMutation.Builder(sessionId).delete().build());
-        tracker.stop("removeSession", sessionId);
-    }
-
-    @Override
-    public void clearHead() {
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        mJournalStorageDirect.commit(
-                new JournalMutation.Builder(HEAD_SESSION_ID).delete().append(new byte[0]).build());
-        tracker.stop("", "clearHead");
-    }
-
-    @Override
-    public ContentMutation editContent() {
-        mThreadUtils.checkNotMainThread();
-        return new FeedContentMutation(this::commitContentMutation);
-    }
-
-    @Override
-    public SessionMutation editSession(String sessionId) {
-        mThreadUtils.checkNotMainThread();
-        return new FeedSessionMutation(
-                feedSessionMutation -> commitSessionMutation(sessionId, feedSessionMutation));
-    }
-
-    @Override
-    public SemanticPropertiesMutation editSemanticProperties() {
-        mThreadUtils.checkNotMainThread();
-        return new FeedSemanticPropertiesMutation(this::commitSemanticPropertiesMutation);
-    }
-
-    @Override
-    public LocalActionMutation editLocalActions() {
-        mThreadUtils.checkNotMainThread();
-        return new FeedLocalActionMutation(this::commitLocalActionMutation);
-    }
-
-    @Override
-    public UploadableActionMutation editUploadableActions() {
-        return new FeedUploadableActionMutation(this::commitUploadableActionMutation);
-    }
-
-    @Override
-    public Runnable triggerContentGc(Set<String> reservedContentIds,
-            Supplier<Set<String>> accessibleContent, boolean keepSharedStates) {
-        Supplier<Set<StreamLocalAction>> dismissActionSupplier = () -> {
-            Result<List<StreamLocalAction>> dismissActionsResult = getAllDismissLocalActions();
-
-            if (!dismissActionsResult.isSuccessful()) {
-                // TODO: clean up error condition
-                Logger.e(TAG, "Error retrieving dismiss actions for content garbage collection");
-                return Collections.emptySet();
-            } else {
-                return new HashSet<>(dismissActionsResult.getValue());
-            }
-        };
-
-        return new ContentGc(mConfiguration, accessibleContent, reservedContentIds,
-                dismissActionSupplier, mContentStorageDirect, mTaskQueue, mTimingUtils,
-                keepSharedStates)::gc;
-    }
-
-    @Override
-    public Runnable triggerLocalActionGc(
-            List<StreamLocalAction> actions, List<String> validContentIds) {
-        return new LocalActionGc(actions, validContentIds, mJournalStorageDirect, mTimingUtils,
-                DISMISS_ACTION_JOURNAL)::gc;
-    }
-
-    @Override
-    public void switchToEphemeralMode() {
-        // TODO: implement cleanup
-    }
-
-    @Override
-    public boolean isEphemeralMode() {
-        return false;
-    }
-
-    @Override
-    public void registerObserver(StoreListener observer) {
-        throw new UnsupportedOperationException(
-                "PersistentFeedStore does not support observer directly");
-    }
-
-    @Override
-    public void unregisterObserver(StoreListener observer) {
-        throw new UnsupportedOperationException(
-                "PersistentFeedStore does not support observer directly");
-    }
-
-    private CommitResult commitSemanticPropertiesMutation(
-            Map<String, ByteString> semanticPropertiesMap) {
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation
-                .Builder mutationBuilder = new org.chromium.chrome.browser.feed.library.api.host
-                                                   .storage.ContentMutation.Builder();
-        for (Map.Entry<String, ByteString> entry : semanticPropertiesMap.entrySet()) {
-            mutationBuilder.upsert(
-                    SEMANTIC_PROPERTIES_PREFIX + entry.getKey(), entry.getValue().toByteArray());
-        }
-        CommitResult commitResult = mContentStorageDirect.commit(mutationBuilder.build());
-        tracker.stop("task", "commitSemanticPropertiesMutation", "mutations",
-                semanticPropertiesMap.size());
-        return commitResult;
-    }
-
-    private Boolean commitSessionMutation(
-            String sessionId, List<StreamStructure> streamStructures) {
-        mThreadUtils.checkNotMainThread();
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-        JournalMutation.Builder mutation = new JournalMutation.Builder(sessionId);
-        if (streamStructures.isEmpty()) {
-            // allow an empty journal to be created
-            mutation.append(new byte[0]);
-        }
-        for (StreamStructure streamStructure : streamStructures) {
-            mutation.append(streamStructure.toByteArray());
-        }
-        CommitResult mutationResult = mJournalStorageDirect.commit(mutation.build());
-        boolean result = CommitResult.SUCCESS.equals(mutationResult);
-        tracker.stop("", "commitSessionMutation", "mutations", streamStructures.size());
-        Logger.i(TAG, "commitSessionMutation - Success %s, Update Session %s, stream structures %s",
-                result, sessionId, streamStructures.size());
-        return result;
-    }
-
-    private CommitResult commitContentMutation(List<PayloadWithId> mutations) {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-
-        org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation
-                .Builder contentMutationBuilder = new org.chromium.chrome.browser.feed.library.api
-                                                          .host.storage.ContentMutation.Builder();
-        for (PayloadWithId mutation : mutations) {
-            String payloadId = mutation.contentId;
-            StreamPayload payload = mutation.payload;
-            if (mutation.payload.hasStreamSharedState()) {
-                StreamSharedState streamSharedState = mutation.payload.getStreamSharedState();
-                contentMutationBuilder.upsert(
-                        SHARED_STATE_PREFIX + streamSharedState.getContentId(),
-                        streamSharedState.toByteArray());
-            } else {
-                contentMutationBuilder.upsert(payloadId, payload.toByteArray());
-            }
-        }
-
-        // Block waiting for the response from storage, to make this method synchronous.
-        // TODO: handle errors
-        CommitResult commitResult = mContentStorageDirect.commit(contentMutationBuilder.build());
-        tracker.stop("task", "commitContentMutation", "mutations", mutations.size());
-        return commitResult;
-    }
-
-    private CommitResult commitLocalActionMutation(Map<Integer, List<String>> actions) {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-
-        CommitResult commitResult = CommitResult.SUCCESS;
-        for (Map.Entry<Integer, List<String>> entry : actions.entrySet()) {
-            Integer actionType = entry.getKey();
-            String journalName;
-            if (ActionType.DISMISS == entry.getKey()) {
-                journalName = DISMISS_ACTION_JOURNAL;
-            } else {
-                Logger.e(TAG, "Unknown journal name for action type %s", actionType);
-                continue;
-            }
-            JournalMutation.Builder builder = new JournalMutation.Builder(journalName);
-            for (String contentId : entry.getValue()) {
-                StreamLocalAction action =
-                        StreamLocalAction.newBuilder()
-                                .setAction(actionType)
-                                .setFeatureContentId(contentId)
-                                .setTimestampSeconds(
-                                        TimeUnit.MILLISECONDS.toSeconds(mClock.currentTimeMillis()))
-                                .build();
-                byte[] actionBytes = action.toByteArray();
-                Logger.i(TAG, "Adding StreamLocalAction bytes %s (length %d) to journal %s",
-                        Base64.encodeToString(actionBytes, Base64.DEFAULT), actionBytes.length,
-                        journalName);
-                builder.append(actionBytes);
-            }
-            commitResult = mJournalStorageDirect.commit(builder.build());
-            if (commitResult == CommitResult.FAILURE) {
-                Logger.e(TAG, "Error committing action for type %s", actionType);
-                break;
-            }
-        }
-
-        tracker.stop("task", "commitLocalActionMutation", "actions", actions.size());
-        return commitResult;
-    }
-
-    private CommitResult commitUploadableActionMutation(
-            Map<String, FeedUploadableActionMutation.FeedUploadableActionChanges> actions) {
-        ElapsedTimeTracker tracker = mTimingUtils.getElapsedTimeTracker(TAG);
-
-        org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation
-                .Builder contentMutationBuilder = new org.chromium.chrome.browser.feed.library.api
-                                                          .host.storage.ContentMutation.Builder();
-        for (Map.Entry<String, FeedUploadableActionMutation.FeedUploadableActionChanges> entry :
-                actions.entrySet()) {
-            String contentId = entry.getKey();
-            for (StreamUploadableAction removeAction : entry.getValue().removeActions()) {
-                contentMutationBuilder.delete(UPLOADABLE_ACTION_PREFIX + contentId
-                        + removeAction.getPayload().hashCode());
-            }
-            for (StreamUploadableAction upsertAction : entry.getValue().upsertActions()) {
-                contentMutationBuilder.upsert(
-                        UPLOADABLE_ACTION_PREFIX + contentId + upsertAction.getPayload().hashCode(),
-                        upsertAction.toByteArray());
-            }
-        }
-
-        CommitResult commitResult = mContentStorageDirect.commit(contentMutationBuilder.build());
-        tracker.stop("task", "commitUploadableActionMutation", "actions", actions.size());
-        return commitResult;
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        if (mContentStorageDirect instanceof Dumpable) {
-            dumper.dump((Dumpable) mContentStorageDirect);
-        } else {
-            dumper.forKey("contentStorageDirect").value("not dumpable");
-        }
-        if (mJournalStorageDirect instanceof Dumpable) {
-            dumper.dump((Dumpable) mJournalStorageDirect);
-        } else {
-            dumper.forKey("journalStorage").value("not dumpable");
-        }
-        dumper.forKey("contentIdStringInternerSize")
-                .value(mContentIdStringInterner.size())
-                .compactPrevious();
-        dumper.forKey("contentIdStringInternerStats")
-                .value(mContentIdStringInterner.getStats())
-                .compactPrevious();
-    }
-
-    /**
-     * Clears contents and journals relating to the stream. Leaves actions and semantic properties
-     * intact.
-     *
-     * @return {@code true} when the clear succeeded
-     */
-    public boolean clearNonActionContent() {
-        return clearContentStorage() && clearJournalStorage();
-    }
-
-    /**
-     * Cleans out journal storage (excluding dismiss actions journal)
-     *
-     * @return whether the clear succeeded
-     */
-    private boolean clearJournalStorage() {
-        Result<List<String>> allJournalsResult = mJournalStorageDirect.getAllJournals();
-        if (!allJournalsResult.isSuccessful()) {
-            Logger.e(TAG, "Error clearing all contents. Could not fetch all journals.");
-            return false;
-        }
-
-        for (String journal : allJournalsResult.getValue()) {
-            if (DISMISS_ACTION_JOURNAL.equals(journal)) {
-                continue;
-            }
-            CommitResult result = mJournalStorageDirect.commit(
-                    new JournalMutation.Builder(journal).delete().build());
-            if (result != CommitResult.SUCCESS) {
-                Logger.e(TAG, "Error clearing all contents. Could not delete journal %s", journal);
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Cleans out content storage (excluding semantic properties)
-     *
-     * @return whether the clear succeeded
-     */
-    private boolean clearContentStorage() {
-        Result<List<String>> results = mContentStorageDirect.getAllKeys();
-        if (!results.isSuccessful()) {
-            Logger.e(TAG, "Error clearing all contents. Could not fetch all content.");
-            return false;
-        }
-        org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation
-                .Builder contentMutationBuilder = new org.chromium.chrome.browser.feed.library.api
-                                                          .host.storage.ContentMutation.Builder();
-        for (String key : results.getValue()) {
-            if (key.contains(SEMANTIC_PROPERTIES_PREFIX)) {
-                continue;
-            }
-            contentMutationBuilder.delete(key);
-        }
-        CommitResult result = mContentStorageDirect.commit(contentMutationBuilder.build());
-        if (result != CommitResult.SUCCESS) {
-            Logger.e(TAG, "Error clearing all contents. Could not commit content deletions.");
-            return false;
-        }
-        return true;
-    }
-
-    /** Wipes all content and journals */
-    @Override
-    public boolean clearAll() {
-        mThreadUtils.checkNotMainThread();
-
-        boolean success = true;
-        // Run clear on both content and journal
-        CommitResult result = mContentStorageDirect.commit(
-                new org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation
-                        .Builder()
-                        .deleteAll()
-                        .build());
-        CommitResult journalResult = mJournalStorageDirect.deleteAll();
-
-        // Confirm results were successful
-        if (result != CommitResult.SUCCESS) {
-            Logger.e(TAG, "Error clearing all. Could not delete all content from content storage.");
-            success = false;
-        }
-
-        if (journalResult != CommitResult.SUCCESS) {
-            Logger.e(
-                    TAG, "Error clearing all. Could not delete all journals from journal storage.");
-            success = false;
-        }
-
-        // Try to recreate $HEAD (it needs to exist in order to create new sessions)
-        // #clearHead() also will create it if it does not exist
-        clearHead();
-
-        return success;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/StreamPayloadInterner.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/StreamPayloadInterner.java
deleted file mode 100644
index b2f037cf..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/StreamPayloadInterner.java
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.internal;
-
-import org.chromium.chrome.browser.feed.library.common.intern.Interner;
-import org.chromium.chrome.browser.feed.library.common.intern.ProtoStringInternerBase;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamFeature;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-
-/** Interner that interns content ID related strings from StreamPayload protos. */
-public class StreamPayloadInterner extends ProtoStringInternerBase<StreamPayload> {
-    StreamPayloadInterner(Interner<String> interner) {
-        super(interner);
-    }
-
-    @Override
-    public StreamPayload intern(StreamPayload input) {
-        if (input.hasStreamFeature()) {
-            StreamFeature.Builder builder = internStreamFeature(input.getStreamFeature());
-            // If builder is not null we memoized something and  we need to replace the proto with
-            // the modified proto.
-            if (builder != null) {
-                return input.toBuilder().setStreamFeature(builder).build();
-            }
-        } else if (input.hasStreamSharedState()) {
-            StreamSharedState.Builder builder =
-                    internStreamSharedState(input.getStreamSharedState());
-            // If builder is not null we memoized something and  we need to replace the proto with
-            // the modified proto.
-            if (builder != null) {
-                return input.toBuilder().setStreamSharedState(builder).build();
-            }
-        } else if (input.hasStreamToken()) {
-            StreamToken.Builder builder = internStreamToken(input.getStreamToken());
-            // If builder is not null we memoized something and  we need to replace the proto with
-            // the modified proto.
-            if (builder != null) {
-                return input.toBuilder().setStreamToken(builder).build();
-            }
-        }
-
-        // If we got here we did not memoized anything.
-        return input;
-    }
-
-    private StreamFeature.Builder internStreamFeature(StreamFeature input) {
-        StreamFeature.Builder builder = null;
-        builder = internSingleStringField(
-                input, builder, StreamFeature::getContentId, StreamFeature.Builder::setContentId);
-        builder = internSingleStringField(
-                input, builder, StreamFeature::getParentId, StreamFeature.Builder::setParentId);
-        return builder;
-    }
-
-    private StreamSharedState.Builder internStreamSharedState(StreamSharedState input) {
-        StreamSharedState.Builder builder = null;
-        builder = internSingleStringField(input, builder, StreamSharedState::getContentId,
-                StreamSharedState.Builder::setContentId);
-        return builder;
-    }
-
-    private StreamToken.Builder internStreamToken(StreamToken input) {
-        StreamToken.Builder builder = null;
-        builder = internSingleStringField(
-                input, builder, StreamToken::getContentId, StreamToken.Builder::setContentId);
-        builder = internSingleStringField(
-                input, builder, StreamToken::getParentId, StreamToken.Builder::setParentId);
-        return builder;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/StreamStructureInterner.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/StreamStructureInterner.java
deleted file mode 100644
index 52b28e7..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/StreamStructureInterner.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.internal;
-
-import org.chromium.chrome.browser.feed.library.common.intern.Interner;
-import org.chromium.chrome.browser.feed.library.common.intern.ProtoStringInternerBase;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-
-/**
- * Interner that interns content ID related strings from StreamStructure protos. The reason is that
- * there is a great potential to reuse there, many content IDs are identical.
- */
-public class StreamStructureInterner extends ProtoStringInternerBase<StreamStructure> {
-    StreamStructureInterner(Interner<String> interner) {
-        super(interner);
-    }
-
-    @Override
-    public StreamStructure intern(StreamStructure input) {
-        StreamStructure.Builder builder = null;
-        builder = internSingleStringField(input, builder, StreamStructure::getContentId,
-                StreamStructure.Builder::setContentId);
-        builder = internSingleStringField(input, builder, StreamStructure::getParentContentId,
-                StreamStructure.Builder::setParentContentId);
-
-        // If builder is not null we memoized something and  we need to replace the proto with the
-        // modified proto.
-        return (builder != null) ? builder.build() : input;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/AbstractClearableFeedStoreTest.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/AbstractClearableFeedStoreTest.java
deleted file mode 100644
index 2b64dd0..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/AbstractClearableFeedStoreTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.testing;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.protobuf.ByteString;
-
-import org.junit.Test;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.common.SemanticPropertiesWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.store.LocalActionMutation.ActionType;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.testing.FakeMainThreadRunner;
-import org.chromium.chrome.browser.feed.library.feedstore.internal.ClearableStore;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamFeature;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamLocalAction;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/** Tests of the {@link ClearableStore} classes. */
-public abstract class AbstractClearableFeedStoreTest extends AbstractFeedStoreTest {
-    protected static final String CONTENT_ID = "CONTENT_ID";
-    protected static final String CONTENT_ID_2 = "CONTENT_ID_2";
-    protected static final String SESSION_ID = "SESSION";
-    protected static final String SESSION_ID_2 = "SESSION_2";
-    protected static final StreamPayload STREAM_PAYLOAD =
-            StreamPayload.newBuilder()
-                    .setStreamFeature(StreamFeature.newBuilder().setContentId(CONTENT_ID))
-                    .build();
-    protected static final StreamPayload STREAM_PAYLOAD_2 =
-            StreamPayload.newBuilder()
-                    .setStreamFeature(StreamFeature.newBuilder().setContentId(CONTENT_ID_2))
-                    .build();
-    protected static final StreamPayload STREAM_PAYLOAD_SHARED_STATE =
-            StreamPayload.newBuilder()
-                    .setStreamSharedState(StreamSharedState.newBuilder().setContentId(CONTENT_ID))
-                    .build();
-    protected static final StreamPayload STREAM_PAYLOAD_SHARED_STATE_2 =
-            StreamPayload.newBuilder()
-                    .setStreamSharedState(StreamSharedState.newBuilder().setContentId(CONTENT_ID_2))
-                    .build();
-    protected static final byte[] SEMANTIC_PROPERTIES = new byte[] {14, 23, 54, 7};
-    protected static final byte[] SEMANTIC_PROPERTIES_2 = new byte[] {12, 24, 18, 9};
-
-    @Test
-    public void clearAll() {
-        ClearableStore store =
-                (ClearableStore) getStore(FakeMainThreadRunner.runTasksImmediately());
-
-        /*
-        SETUP
-        */
-
-        // Payload
-        CommitResult commitResult = store.editContent()
-                                            .add(CONTENT_ID, STREAM_PAYLOAD)
-                                            .add(CONTENT_ID_2, STREAM_PAYLOAD_2)
-                                            .commit();
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        Result<List<PayloadWithId>> payloadsResult =
-                store.getPayloads(Arrays.asList(CONTENT_ID, CONTENT_ID_2));
-        assertThat(payloadsResult.isSuccessful()).isTrue();
-        assertThat(payloadsResult.getValue()).hasSize(2);
-
-        // Semantic properties
-        commitResult = store.editSemanticProperties()
-                               .add(CONTENT_ID, ByteString.copyFrom(SEMANTIC_PROPERTIES))
-                               .add(CONTENT_ID_2, ByteString.copyFrom(SEMANTIC_PROPERTIES_2))
-                               .commit();
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        Result<List<SemanticPropertiesWithId>> semanticPropertiesResult =
-                store.getSemanticProperties(Arrays.asList(CONTENT_ID, CONTENT_ID_2));
-        assertThat(semanticPropertiesResult.isSuccessful()).isTrue();
-        assertThat(semanticPropertiesResult.getValue()).hasSize(2);
-
-        // Shared State
-        commitResult = store.editContent()
-                               .add(CONTENT_ID, STREAM_PAYLOAD_SHARED_STATE)
-                               .add(CONTENT_ID_2, STREAM_PAYLOAD_SHARED_STATE_2)
-                               .commit();
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        Result<List<StreamSharedState>> sharedStatesResult = store.getSharedStates();
-        assertThat(sharedStatesResult.isSuccessful()).isTrue();
-        assertThat(sharedStatesResult.getValue()).hasSize(2);
-
-        // Journal
-        boolean boolCommitResult =
-                store.editSession(SESSION_ID)
-                        .add(StreamStructure.newBuilder().setContentId(CONTENT_ID).build())
-                        .commit();
-        assertThat(boolCommitResult).isTrue();
-        boolCommitResult =
-                store.editSession(SESSION_ID_2)
-                        .add(StreamStructure.newBuilder().setContentId(CONTENT_ID_2).build())
-                        .commit();
-        assertThat(boolCommitResult).isTrue();
-
-        Result<List<String>> sessionsResult = store.getAllSessions();
-        assertThat(sessionsResult.isSuccessful()).isTrue();
-        assertThat(sessionsResult.getValue()).hasSize(2);
-
-        // Actions
-        commitResult = store.editLocalActions()
-                               .add(ActionType.DISMISS, CONTENT_ID)
-                               .add(ActionType.DISMISS, CONTENT_ID_2)
-                               .commit();
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        Result<List<StreamLocalAction>> dismissActionsResult = store.getAllDismissLocalActions();
-        assertThat(dismissActionsResult.isSuccessful()).isTrue();
-        assertThat(dismissActionsResult.getValue()).hasSize(2);
-
-        /*
-        CLEAR
-        */
-
-        assertThat(store.clearAll()).isTrue();
-
-        /*
-        VERIFICATION
-        */
-
-        // Payload
-        payloadsResult = store.getPayloads(Collections.singletonList(CONTENT_ID));
-        assertThat(payloadsResult.isSuccessful()).isTrue();
-        assertThat(payloadsResult.getValue()).hasSize(0);
-
-        // Semantic properties (should not be cleared)
-        semanticPropertiesResult =
-                store.getSemanticProperties(Arrays.asList(CONTENT_ID, CONTENT_ID_2));
-        assertThat(semanticPropertiesResult.isSuccessful()).isTrue();
-        assertThat(semanticPropertiesResult.getValue()).hasSize(0);
-
-        // Shared state
-        sharedStatesResult = store.getSharedStates();
-        assertThat(sharedStatesResult.isSuccessful()).isTrue();
-        assertThat(sharedStatesResult.getValue()).hasSize(0);
-
-        // Journal
-        sessionsResult = store.getAllSessions();
-        assertThat(sessionsResult.isSuccessful()).isTrue();
-        assertThat(sessionsResult.getValue()).hasSize(0);
-
-        // Actions (should not be cleared)
-        dismissActionsResult = store.getAllDismissLocalActions();
-        assertThat(dismissActionsResult.isSuccessful()).isTrue();
-        assertThat(dismissActionsResult.getValue()).hasSize(0);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/AbstractFeedStoreTest.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/AbstractFeedStoreTest.java
deleted file mode 100644
index 448c826b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/AbstractFeedStoreTest.java
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.testing;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.protobuf.ByteString;
-
-import org.junit.Test;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.common.SemanticPropertiesWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.common.testing.ContentIdGenerators;
-import org.chromium.chrome.browser.feed.library.api.internal.store.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.LocalActionMutation.ActionType;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SessionMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.testing.FakeMainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.testing.RunnableSubject;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.common.time.testing.FakeClock;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamFeature;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamLocalAction;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure.Operation;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/** Tests of the {@link FeedStore} classes. */
-public abstract class AbstractFeedStoreTest {
-    protected final FakeClock mFakeClock = new FakeClock();
-    protected final TimingUtils mTimingUtils = new TimingUtils();
-
-    private static final long START_TIME = 50;
-    private static final long START_TIME_MILLIS = TimeUnit.SECONDS.toMillis(START_TIME);
-    private static final long THREE_DAYS_AFTER_START_TIME = START_TIME + TimeUnit.DAYS.toSeconds(3);
-    private static final long THREE_DAYS_AFTER_START_TIME_MILLIS =
-            TimeUnit.SECONDS.toMillis(THREE_DAYS_AFTER_START_TIME);
-
-    private static final ContentIdGenerators sIdGenerators = new ContentIdGenerators();
-    private static final int PAYLOAD_ID = 12345;
-    private static final int OPERATION_ID = 67890;
-    private static final String PAYLOAD_CONTENT_ID =
-            sIdGenerators.createFeatureContentId(PAYLOAD_ID);
-    private static final String OPERATION_CONTENT_ID =
-            sIdGenerators.createFeatureContentId(OPERATION_ID);
-    private static final StreamPayload.Builder STREAM_PAYLOAD =
-            StreamPayload.newBuilder().setStreamFeature(
-                    StreamFeature.newBuilder()
-                            .setContentId(PAYLOAD_CONTENT_ID)
-                            .setParentId(sIdGenerators.createRootContentId(0)));
-    private static final StreamStructure STREAM_STRUCTURE =
-            StreamStructure.newBuilder()
-                    .setContentId(OPERATION_CONTENT_ID)
-                    .setParentContentId(sIdGenerators.createRootContentId(0))
-                    .setOperation(Operation.UPDATE_OR_APPEND)
-                    .build();
-    private static final StreamDataOperation STREAM_DATA_OPERATION =
-            StreamDataOperation.newBuilder()
-                    .setStreamStructure(STREAM_STRUCTURE)
-                    .setStreamPayload(STREAM_PAYLOAD)
-                    .build();
-    private final MainThreadRunner mMainThreadRunner = FakeMainThreadRunner.runTasksImmediately();
-
-    /**
-     * Provides an instance of the store
-     *
-     * @param mainThreadRunner
-     */
-    protected abstract Store getStore(MainThreadRunner mainThreadRunner);
-
-    @Test
-    public void testMinimalStore() {
-        Store store = getStore(mMainThreadRunner);
-        Result<List<String>> result = store.getAllSessions();
-        assertThat(result.isSuccessful()).isTrue();
-        assertThat(result.getValue()).isEmpty();
-    }
-
-    @Test
-    public void testContentMutation() {
-        Store store = getStore(mMainThreadRunner);
-        ContentMutation contentMutation = store.editContent();
-        assertThat(contentMutation).isNotNull();
-    }
-
-    @Test
-    public void addStructureOperationToSession() {
-        Store store = getStore(mMainThreadRunner);
-        SessionMutation mutation = store.editSession(Store.HEAD_SESSION_ID);
-        mutation.add(STREAM_DATA_OPERATION.getStreamStructure());
-        mutation.commit();
-
-        Result<List<StreamStructure>> streamStructuresResult =
-                store.getStreamStructures(Store.HEAD_SESSION_ID);
-
-        assertThat(streamStructuresResult.isSuccessful()).isTrue();
-        List<StreamStructure> streamStructures = streamStructuresResult.getValue();
-        assertThat(streamStructures).hasSize(1);
-        assertThat(streamStructures.get(0).getContentId()).isEqualTo(OPERATION_CONTENT_ID);
-    }
-
-    @Test
-    public void addContentOperationToSession() {
-        Store store = getStore(mMainThreadRunner);
-        ContentMutation mutation = store.editContent();
-        mutation.add(PAYLOAD_CONTENT_ID, STREAM_DATA_OPERATION.getStreamPayload());
-        CommitResult result = mutation.commit();
-
-        assertThat(result).isEqualTo(CommitResult.SUCCESS);
-    }
-
-    @Test
-    public void createNewSession() {
-        Store store = getStore(mMainThreadRunner);
-        SessionMutation mutation = store.editSession(Store.HEAD_SESSION_ID);
-        mutation.add(STREAM_STRUCTURE);
-        mutation.commit();
-
-        Result<String> sessionResult = store.createNewSession();
-        assertThat(sessionResult.isSuccessful()).isTrue();
-        String sessionId = sessionResult.getValue();
-
-        Result<List<StreamStructure>> streamStructuresResult = store.getStreamStructures(sessionId);
-
-        assertThat(streamStructuresResult.isSuccessful()).isTrue();
-        List<StreamStructure> streamStructures = streamStructuresResult.getValue();
-        assertThat(streamStructures).hasSize(1);
-        StreamStructure streamStructure = streamStructures.get(0);
-        assertThat(streamStructure.getContentId()).contains(Integer.toString(OPERATION_ID));
-    }
-
-    @Test
-    public void removeSession() {
-        Store store = getStore(mMainThreadRunner);
-        SessionMutation mutation = store.editSession(Store.HEAD_SESSION_ID);
-        mutation.add(STREAM_STRUCTURE);
-        mutation.commit();
-
-        Result<String> sessionResult = store.createNewSession();
-        assertThat(sessionResult.isSuccessful()).isTrue();
-        String sessionId = sessionResult.getValue();
-
-        store.removeSession(sessionId);
-
-        Result<List<StreamStructure>> streamStructuresResult = store.getStreamStructures(sessionId);
-
-        assertThat(streamStructuresResult.isSuccessful()).isTrue();
-        assertThat(streamStructuresResult.getValue()).isEmpty();
-    }
-
-    @Test
-    public void clearHead() {
-        Store store = getStore(mMainThreadRunner);
-        SessionMutation mutation = store.editSession(Store.HEAD_SESSION_ID);
-        mutation.add(STREAM_STRUCTURE);
-        mutation.commit();
-
-        store.clearHead();
-
-        Result<List<StreamStructure>> streamStructuresResult =
-                store.getStreamStructures(Store.HEAD_SESSION_ID);
-
-        assertThat(streamStructuresResult.isSuccessful()).isTrue();
-        assertThat(streamStructuresResult.getValue()).isEmpty();
-    }
-
-    @Test
-    public void getSessions() {
-        Store store = getStore(mMainThreadRunner);
-        SessionMutation mutation = store.editSession(Store.HEAD_SESSION_ID);
-        mutation.add(STREAM_STRUCTURE);
-        mutation.commit();
-
-        Result<List<String>> sessionsResult = store.getAllSessions();
-        assertThat(sessionsResult.isSuccessful()).isTrue();
-        List<String> sessions = sessionsResult.getValue();
-        assertThat(sessions).isEmpty();
-
-        Result<String> sessionResult = store.createNewSession();
-        assertThat(sessionResult.isSuccessful()).isTrue();
-        String sessionId = sessionResult.getValue();
-
-        sessionsResult = store.getAllSessions();
-        assertThat(sessionsResult.isSuccessful()).isTrue();
-        sessions = sessionsResult.getValue();
-        assertThat(sessions).hasSize(1);
-        assertThat(sessions.get(0)).isEqualTo(sessionId);
-
-        sessionResult = store.createNewSession();
-        assertThat(sessionResult.isSuccessful()).isTrue();
-
-        sessionsResult = store.getAllSessions();
-        assertThat(sessionsResult.isSuccessful()).isTrue();
-        sessions = sessionsResult.getValue();
-        assertThat(sessions).hasSize(2);
-    }
-
-    @Test
-    public void editContent() {
-        StreamPayload streamPayload =
-                StreamPayload.newBuilder()
-                        .setStreamFeature(
-                                StreamFeature.newBuilder().setContentId(PAYLOAD_CONTENT_ID))
-                        .build();
-        Store store = getStore(mMainThreadRunner);
-
-        CommitResult commitResult =
-                store.editContent().add(PAYLOAD_CONTENT_ID, streamPayload).commit();
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        Result<List<PayloadWithId>> payloadsResult =
-                store.getPayloads(Collections.singletonList(PAYLOAD_CONTENT_ID));
-        assertThat(payloadsResult.isSuccessful()).isTrue();
-        assertThat(payloadsResult.getValue()).hasSize(1);
-        assertThat(payloadsResult.getValue().get(0).contentId).isEqualTo(PAYLOAD_CONTENT_ID);
-        assertThat(payloadsResult.getValue().get(0).payload).isEqualTo(streamPayload);
-    }
-
-    @Test
-    public void getSharedStates() {
-        StreamSharedState streamSharedState =
-                StreamSharedState.newBuilder().setContentId(PAYLOAD_CONTENT_ID).build();
-        Store store = getStore(mMainThreadRunner);
-        store.editContent()
-                .add(String.valueOf(PAYLOAD_ID),
-                        StreamPayload.newBuilder().setStreamSharedState(streamSharedState).build())
-                .commit();
-        Result<List<StreamSharedState>> sharedStatesResult = store.getSharedStates();
-        assertThat(sharedStatesResult.isSuccessful()).isTrue();
-        List<StreamSharedState> sharedStates = sharedStatesResult.getValue();
-        assertThat(sharedStates).hasSize(1);
-        assertThat(sharedStates.get(0)).isEqualTo(streamSharedState);
-    }
-
-    @Test
-    public void getPayloads_noPayload() {
-        List<String> contentIds = new ArrayList<>();
-        contentIds.add(PAYLOAD_CONTENT_ID);
-
-        Store store = getStore(mMainThreadRunner);
-        Result<List<PayloadWithId>> payloadsResult = store.getPayloads(contentIds);
-        assertThat(payloadsResult.isSuccessful()).isTrue();
-        List<PayloadWithId> payloads = payloadsResult.getValue();
-        assertThat(payloads).isEmpty();
-    }
-
-    @Test
-    public void deleteHead_notAllowed() {
-        RunnableSubject
-                .assertThatRunnable(() -> {
-                    Store store = getStore(mMainThreadRunner);
-                    store.removeSession(Store.HEAD_SESSION_ID);
-                })
-                .throwsAnExceptionOfType(IllegalStateException.class);
-    }
-
-    @Test
-    public void editSemanticProperties() {
-        Store store = getStore(mMainThreadRunner);
-        assertThat(store.editSemanticProperties()).isNotNull();
-    }
-
-    @Test
-    public void getSemanticProperties() {
-        ByteString semanticData = ByteString.copyFromUtf8("helloWorld");
-        Store store = getStore(mMainThreadRunner);
-        store.editSemanticProperties().add(PAYLOAD_CONTENT_ID, semanticData).commit();
-        Result<List<SemanticPropertiesWithId>> semanticPropertiesResult =
-                store.getSemanticProperties(Collections.singletonList(PAYLOAD_CONTENT_ID));
-        assertThat(semanticPropertiesResult.isSuccessful()).isTrue();
-        List<SemanticPropertiesWithId> semanticProperties = semanticPropertiesResult.getValue();
-        assertThat(semanticProperties).hasSize(1);
-        assertThat(semanticProperties.get(0).contentId).isEqualTo(PAYLOAD_CONTENT_ID);
-        assertThat(semanticProperties.get(0).semanticData).isEqualTo(semanticData.toByteArray());
-    }
-
-    @Test
-    public void getSemanticProperties_requestDifferentKey() {
-        ByteString semanticData = ByteString.copyFromUtf8("helloWorld");
-        Store store = getStore(mMainThreadRunner);
-        store.editSemanticProperties().add(PAYLOAD_CONTENT_ID, semanticData).commit();
-        Result<List<SemanticPropertiesWithId>> semanticPropertiesResult =
-                store.getSemanticProperties(Collections.singletonList(OPERATION_CONTENT_ID));
-        assertThat(semanticPropertiesResult.isSuccessful()).isTrue();
-        List<SemanticPropertiesWithId> semanticProperties = semanticPropertiesResult.getValue();
-        assertThat(semanticProperties).isEmpty();
-    }
-
-    @Test
-    public void getSemanticProperties_doesNotExist() {
-        Store store = getStore(mMainThreadRunner);
-        Result<List<SemanticPropertiesWithId>> semanticPropertiesResult =
-                store.getSemanticProperties(Collections.singletonList(PAYLOAD_CONTENT_ID));
-        assertThat(semanticPropertiesResult.isSuccessful()).isTrue();
-        List<SemanticPropertiesWithId> semanticProperties = semanticPropertiesResult.getValue();
-        assertThat(semanticProperties).isEmpty();
-    }
-
-    @Test
-    public void getDismissActions() {
-        mFakeClock.set(START_TIME_MILLIS);
-        Store store = getStore(mMainThreadRunner);
-        store.editLocalActions().add(ActionType.DISMISS, OPERATION_CONTENT_ID).commit();
-        Result<List<StreamLocalAction>> dismissActionsResult = store.getAllDismissLocalActions();
-        assertThat(dismissActionsResult.isSuccessful()).isTrue();
-        List<StreamLocalAction> dismissActions = dismissActionsResult.getValue();
-        assertThat(dismissActions).isNotEmpty();
-        assertThat(dismissActions.get(0).getAction()).isEqualTo(ActionType.DISMISS);
-        assertThat(dismissActions.get(0).getFeatureContentId()).isEqualTo(OPERATION_CONTENT_ID);
-        assertThat(dismissActions.get(0).getTimestampSeconds()).isEqualTo(START_TIME);
-    }
-
-    @Test
-    public void getDismissActions_notIncludedInSessions() {
-        mFakeClock.set(START_TIME_MILLIS);
-        Store store = getStore(mMainThreadRunner);
-        store.editLocalActions().add(ActionType.DISMISS, OPERATION_CONTENT_ID).commit();
-        Result<List<String>> allSessionsResult = store.getAllSessions();
-        assertThat(allSessionsResult.isSuccessful()).isTrue();
-        List<String> allSessions = allSessionsResult.getValue();
-        assertThat(allSessions).isEmpty();
-    }
-
-    @Test
-    public void getDismissActions_multipleDismisses() {
-        mFakeClock.set(START_TIME_MILLIS);
-        Store store = getStore(mMainThreadRunner);
-        store.editLocalActions()
-                .add(ActionType.DISMISS, OPERATION_CONTENT_ID)
-                .add(ActionType.DISMISS, PAYLOAD_CONTENT_ID)
-                .commit();
-        Result<List<StreamLocalAction>> dismissActionsResult = store.getAllDismissLocalActions();
-        assertThat(dismissActionsResult.isSuccessful()).isTrue();
-        List<StreamLocalAction> dismissActions = dismissActionsResult.getValue();
-        assertThat(dismissActions).isNotEmpty();
-        assertThat(dismissActions.get(0).getAction()).isEqualTo(ActionType.DISMISS);
-        assertThat(dismissActions.get(0).getFeatureContentId()).isEqualTo(OPERATION_CONTENT_ID);
-        assertThat(dismissActions.get(0).getTimestampSeconds()).isEqualTo(START_TIME);
-        assertThat(dismissActions.get(1).getAction()).isEqualTo(ActionType.DISMISS);
-        assertThat(dismissActions.get(1).getFeatureContentId()).isEqualTo(PAYLOAD_CONTENT_ID);
-        assertThat(dismissActions.get(1).getTimestampSeconds()).isEqualTo(START_TIME);
-    }
-
-    @Test
-    public void getDismissActions_expired() {
-        mFakeClock.set(START_TIME_MILLIS);
-        Store store = getStore(mMainThreadRunner);
-        store.editLocalActions().add(ActionType.DISMISS, OPERATION_CONTENT_ID).commit();
-        mFakeClock.set(THREE_DAYS_AFTER_START_TIME_MILLIS);
-        Result<List<StreamLocalAction>> dismissActionsResult = store.getAllDismissLocalActions();
-        assertThat(dismissActionsResult.isSuccessful()).isTrue();
-        List<StreamLocalAction> dismissActions = dismissActionsResult.getValue();
-
-        // Should still return expired actions.
-        assertThat(dismissActions).isNotEmpty();
-        assertThat(dismissActions.get(0).getAction()).isEqualTo(ActionType.DISMISS);
-        assertThat(dismissActions.get(0).getFeatureContentId()).isEqualTo(OPERATION_CONTENT_ID);
-        assertThat(dismissActions.get(0).getTimestampSeconds()).isEqualTo(START_TIME);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/DelegatingContentStorage.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/DelegatingContentStorage.java
deleted file mode 100644
index e6485b0f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/DelegatingContentStorage.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.testing;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorage;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorageDirect;
-import org.chromium.chrome.browser.feed.library.common.Result;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Delegate class allowing spying on ContentStorageDirect delegates implementing both of the storage
- * interfaces.
- */
-public class DelegatingContentStorage implements ContentStorage, ContentStorageDirect {
-    private final ContentStorageDirect mDelegate;
-
-    public DelegatingContentStorage(ContentStorageDirect delegate) {
-        this.mDelegate = delegate;
-    }
-
-    @Override
-    public void get(List<String> keys, Consumer<Result<Map<String, byte[]>>> consumer) {
-        consumer.accept(mDelegate.get(keys));
-    }
-
-    @Override
-    public Result<Map<String, byte[]>> get(List<String> keys) {
-        return mDelegate.get(keys);
-    }
-
-    @Override
-    public void getAll(String prefix, Consumer<Result<Map<String, byte[]>>> consumer) {
-        consumer.accept(mDelegate.getAll(prefix));
-    }
-
-    @Override
-    public Result<Map<String, byte[]>> getAll(String prefix) {
-        return mDelegate.getAll(prefix);
-    }
-
-    @Override
-    public void getAllKeys(Consumer<Result<List<String>>> consumer) {
-        consumer.accept(mDelegate.getAllKeys());
-    }
-
-    @Override
-    public Result<List<String>> getAllKeys() {
-        return mDelegate.getAllKeys();
-    }
-
-    @Override
-    public void commit(ContentMutation mutation, Consumer<CommitResult> consumer) {
-        consumer.accept(mDelegate.commit(mutation));
-    }
-
-    @Override
-    public CommitResult commit(ContentMutation mutation) {
-        return mDelegate.commit(mutation);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/DelegatingJournalStorage.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/DelegatingJournalStorage.java
deleted file mode 100644
index 2a2ed72..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/DelegatingJournalStorage.java
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.testing;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorage;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorageDirect;
-import org.chromium.chrome.browser.feed.library.common.Result;
-
-import java.util.List;
-
-/**
- * Delegate class allowing spying on JournalStorageDirect delegates implementing both of the storage
- * interfaces.
- */
-public class DelegatingJournalStorage implements JournalStorage, JournalStorageDirect {
-    private final JournalStorageDirect mDelegate;
-
-    public DelegatingJournalStorage(JournalStorageDirect delegate) {
-        this.mDelegate = delegate;
-    }
-
-    @Override
-    public void read(String journalName, Consumer<Result<List<byte[]>>> consumer) {
-        consumer.accept(mDelegate.read(journalName));
-    }
-
-    @Override
-    public Result<List<byte[]>> read(String journalName) {
-        return mDelegate.read(journalName);
-    }
-
-    @Override
-    public void commit(JournalMutation mutation, Consumer<CommitResult> consumer) {
-        consumer.accept(mDelegate.commit(mutation));
-    }
-
-    @Override
-    public CommitResult commit(JournalMutation mutation) {
-        return mDelegate.commit(mutation);
-    }
-
-    @Override
-    public void exists(String journalName, Consumer<Result<Boolean>> consumer) {
-        consumer.accept(mDelegate.exists(journalName));
-    }
-
-    @Override
-    public Result<Boolean> exists(String journalName) {
-        return mDelegate.exists(journalName);
-    }
-
-    @Override
-    public void getAllJournals(Consumer<Result<List<String>>> consumer) {
-        consumer.accept(mDelegate.getAllJournals());
-    }
-
-    @Override
-    public Result<List<String>> getAllJournals() {
-        return mDelegate.getAllJournals();
-    }
-
-    @Override
-    public void deleteAll(Consumer<CommitResult> consumer) {
-        consumer.accept(mDelegate.deleteAll());
-    }
-
-    @Override
-    public CommitResult deleteAll() {
-        return mDelegate.deleteAll();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/DelegatingStore.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/DelegatingStore.java
deleted file mode 100644
index 9d79ac8e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/DelegatingStore.java
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.feedstore.testing;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.common.SemanticPropertiesWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.store.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.LocalActionMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SemanticPropertiesMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SessionMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.api.internal.store.StoreListener;
-import org.chromium.chrome.browser.feed.library.api.internal.store.UploadableActionMutation;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamLocalAction;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-
-import java.util.List;
-import java.util.Set;
-
-/** Class which allows spying on a Store implementation */
-public class DelegatingStore implements Store {
-    private final Store mStore;
-
-    public DelegatingStore(Store store) {
-        this.mStore = store;
-    }
-
-    @Override
-    public Result<List<PayloadWithId>> getPayloads(List<String> contentIds) {
-        return mStore.getPayloads(contentIds);
-    }
-
-    @Override
-    public Result<List<StreamSharedState>> getSharedStates() {
-        return mStore.getSharedStates();
-    }
-
-    @Override
-    public Result<List<StreamStructure>> getStreamStructures(String sessionId) {
-        return mStore.getStreamStructures(sessionId);
-    }
-
-    @Override
-    public Result<List<String>> getAllSessions() {
-        return mStore.getAllSessions();
-    }
-
-    @Override
-    public Result<List<SemanticPropertiesWithId>> getSemanticProperties(List<String> contentIds) {
-        return mStore.getSemanticProperties(contentIds);
-    }
-
-    @Override
-    public Result<List<StreamLocalAction>> getAllDismissLocalActions() {
-        return mStore.getAllDismissLocalActions();
-    }
-
-    @Override
-    public Result<Set<StreamUploadableAction>> getAllUploadableActions() {
-        return mStore.getAllUploadableActions();
-    }
-
-    @Override
-    public Result<String> createNewSession() {
-        return mStore.createNewSession();
-    }
-
-    @Override
-    public void removeSession(String sessionId) {
-        mStore.removeSession(sessionId);
-    }
-
-    @Override
-    public void clearHead() {
-        mStore.clearHead();
-    }
-
-    @Override
-    public ContentMutation editContent() {
-        return mStore.editContent();
-    }
-
-    @Override
-    public SessionMutation editSession(String sessionId) {
-        return mStore.editSession(sessionId);
-    }
-
-    @Override
-    public SemanticPropertiesMutation editSemanticProperties() {
-        return mStore.editSemanticProperties();
-    }
-
-    @Override
-    public LocalActionMutation editLocalActions() {
-        return mStore.editLocalActions();
-    }
-
-    @Override
-    public UploadableActionMutation editUploadableActions() {
-        return mStore.editUploadableActions();
-    }
-
-    @Override
-    public Runnable triggerContentGc(Set<String> reservedContentIds,
-            Supplier<Set<String>> accessibleContent, boolean keepSharedStates) {
-        return mStore.triggerContentGc(reservedContentIds, accessibleContent, keepSharedStates);
-    }
-
-    @Override
-    public Runnable triggerLocalActionGc(
-            List<StreamLocalAction> actions, List<String> validContentIds) {
-        return mStore.triggerLocalActionGc(actions, validContentIds);
-    }
-
-    @Override
-    public void switchToEphemeralMode() {
-        mStore.switchToEphemeralMode();
-    }
-
-    @Override
-    public boolean isEphemeralMode() {
-        return mStore.isEphemeralMode();
-    }
-
-    @Override
-    public void registerObserver(StoreListener observer) {
-        mStore.registerObserver(observer);
-    }
-
-    @Override
-    public void unregisterObserver(StoreListener observer) {
-        mStore.unregisterObserver(observer);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/logging/NoOpBasicLoggingApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/logging/NoOpBasicLoggingApi.java
deleted file mode 100644
index 1dd2be5..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/logging/NoOpBasicLoggingApi.java
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-package org.chromium.chrome.browser.feed.library.hostimpl.logging;
-
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ContentLoggingData;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ElementLoggingData;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-
-import java.util.List;
-
-/** {@link BasicLoggingApi} implementation that no-ops for all methods. */
-public final class NoOpBasicLoggingApi implements BasicLoggingApi {
-    @Override
-    public void onContentViewed(ContentLoggingData data) {}
-
-    @Override
-    public void onContentDismissed(ContentLoggingData data, boolean wasCommitted) {}
-
-    @Override
-    public void onContentSwiped(ContentLoggingData data) {}
-
-    @Override
-    public void onContentClicked(ContentLoggingData data) {}
-
-    @Override
-    public void onClientAction(ContentLoggingData data, int actionType) {}
-
-    @Override
-    public void onContentContextMenuOpened(ContentLoggingData data) {}
-
-    @Override
-    public void onMoreButtonViewed(int position) {}
-
-    @Override
-    public void onMoreButtonClicked(int position) {}
-
-    @Override
-    public void onNotInterestedIn(int interestType, ContentLoggingData data, boolean wasCommitted) {
-    }
-
-    @Override
-    public void onOpenedWithContent(int timeToPopulateMs, int contentCount) {}
-
-    @Override
-    public void onOpenedWithNoImmediateContent() {}
-
-    @Override
-    public void onOpenedWithNoContent() {}
-
-    @Override
-    public void onSpinnerStarted(int spinnerType) {}
-
-    @Override
-    public void onSpinnerFinished(int timeShownMs, int spinnerType) {}
-
-    @Override
-    public void onSpinnerDestroyedWithoutCompleting(int timeShownMs, int spinnerType) {}
-
-    @Override
-    public void onPietFrameRenderingEvent(List<Integer> pietErrorCodes) {}
-
-    @Override
-    public void onVisualElementClicked(ElementLoggingData data, int elementType) {}
-
-    @Override
-    public void onVisualElementViewed(ElementLoggingData data, int elementType) {}
-
-    @Override
-    public void onInternalError(int internalError) {}
-
-    @Override
-    public void onTokenCompleted(boolean wasSynthetic, int contentCount, int tokenCount) {}
-
-    @Override
-    public void onTokenFailedToComplete(boolean wasSynthetic, int failureCount) {}
-
-    @Override
-    public void onServerRequest(int requestReason) {}
-
-    @Override
-    public void onZeroStateShown(int zeroStateShowReason) {}
-
-    @Override
-    public void onZeroStateRefreshCompleted(int newContentCount, int newTokenCount) {}
-
-    @Override
-    public void onInitialSessionEvent(
-            int sessionEvent, int timeFromRegisteringMs, int sessionCount) {}
-
-    @Override
-    public void onScroll(int scrollType, int distanceScrolled) {}
-
-    @Override
-    public void onTaskFinished(@Task int task, int delayTime, int taskTime) {}
-
-    @Override
-    public void reportScrollActivity(int scrollAmount) {}
-
-    @Override
-    public void reportFeedInteraction() {}
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/network/NetworkClientWrapper.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/network/NetworkClientWrapper.java
deleted file mode 100644
index 9f13f58..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/network/NetworkClientWrapper.java
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.hostimpl.network;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpResponse;
-import org.chromium.chrome.browser.feed.library.api.host.network.NetworkClient;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-
-/** A {@link NetworkClient} which wraps a NetworkClient to make calls on the Main thread. */
-public final class NetworkClientWrapper implements NetworkClient {
-    private static final String TAG = "NetworkClientWrapper";
-
-    private final NetworkClient mDirectNetworkClient;
-    private final ThreadUtils mThreadUtils;
-    private final MainThreadRunner mMainThreadRunner;
-
-    public NetworkClientWrapper(NetworkClient directNetworkClient, ThreadUtils threadUtils,
-            MainThreadRunner mainThreadRunner) {
-        this.mDirectNetworkClient = directNetworkClient;
-        this.mThreadUtils = threadUtils;
-        this.mMainThreadRunner = mainThreadRunner;
-    }
-
-    @Override
-    public void send(HttpRequest request, Consumer<HttpResponse> responseConsumer) {
-        if (mThreadUtils.isMainThread()) {
-            mDirectNetworkClient.send(request, responseConsumer);
-            return;
-        }
-        mMainThreadRunner.execute(
-                TAG + " send", () -> mDirectNetworkClient.send(request, responseConsumer));
-    }
-
-    @Override
-    public void close() throws Exception {
-        mDirectNetworkClient.close();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/scheduler/SchedulerApiWrapper.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/scheduler/SchedulerApiWrapper.java
deleted file mode 100644
index 6c35728..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/scheduler/SchedulerApiWrapper.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.hostimpl.scheduler;
-
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.SimpleSettableFuture;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-import java.util.concurrent.ExecutionException;
-
-/** Wrapper class which will call the {@link SchedulerApi} on the main thread. */
-public final class SchedulerApiWrapper implements SchedulerApi {
-    private static final String TAG = "SchedulerApiWrapper";
-    private final SchedulerApi mDirectSchedulerApi;
-    private final ThreadUtils mThreadUtils;
-    private final MainThreadRunner mMainThreadRunner;
-
-    public SchedulerApiWrapper(SchedulerApi directSchedulerApi, ThreadUtils threadUtils,
-            MainThreadRunner mainThreadRunner) {
-        Logger.i(TAG, "Create SchedulerApiMainThreadWrapper");
-        this.mDirectSchedulerApi = directSchedulerApi;
-        this.mThreadUtils = threadUtils;
-        this.mMainThreadRunner = mainThreadRunner;
-    }
-
-    @RequestBehavior
-    @Override
-    public int shouldSessionRequestData(SessionState sessionState) {
-        if (mThreadUtils.isMainThread()) {
-            return mDirectSchedulerApi.shouldSessionRequestData(sessionState);
-        }
-        SimpleSettableFuture<Integer> future = new SimpleSettableFuture<>();
-        mMainThreadRunner.execute(TAG + " shouldSessionRequestData",
-                () -> future.put(mDirectSchedulerApi.shouldSessionRequestData(sessionState)));
-        try {
-            return future.get();
-        } catch (InterruptedException | ExecutionException e) {
-            Logger.e(TAG, e, null);
-        }
-        return RequestBehavior.NO_REQUEST_WITH_WAIT;
-    }
-
-    @Override
-    public void onReceiveNewContent(long contentCreationDateTimeMs) {
-        if (mThreadUtils.isMainThread()) {
-            mDirectSchedulerApi.onReceiveNewContent(contentCreationDateTimeMs);
-            return;
-        }
-        mMainThreadRunner.execute(TAG + " onReceiveNewContent",
-                () -> { mDirectSchedulerApi.onReceiveNewContent(contentCreationDateTimeMs); });
-    }
-
-    @Override
-    public void onRequestError(int networkResponseCode) {
-        if (mThreadUtils.isMainThread()) {
-            mDirectSchedulerApi.onRequestError(networkResponseCode);
-            return;
-        }
-        mMainThreadRunner.execute(TAG + " onRequestError",
-                () -> { mDirectSchedulerApi.onRequestError(networkResponseCode); });
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/PersistentContentStorage.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/PersistentContentStorage.java
deleted file mode 100644
index 75ef6563..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/PersistentContentStorage.java
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.hostimpl.storage;
-
-import static org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Type.DELETE;
-import static org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Type.DELETE_ALL;
-import static org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Type.DELETE_BY_PREFIX;
-import static org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Type.UPSERT;
-
-import android.content.Context;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Delete;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.DeleteByPrefix;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Upsert;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorage;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorageDirect;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/** Implementation of {@link ContentStorage} that persists data to disk. */
-public final class PersistentContentStorage implements ContentStorage, ContentStorageDirect {
-    private static final String TAG = "PersistentContent";
-    private static final String CONTENT_DIR = "content";
-
-    private final Context mContext;
-    private final ThreadUtils mThreadUtils;
-    private final Executor mExecutor;
-
-    private File mContentDir;
-
-    public PersistentContentStorage(Context context, Executor executor, ThreadUtils threadUtils) {
-        this.mContext = context;
-        this.mExecutor = executor;
-        this.mThreadUtils = threadUtils;
-    }
-
-    @Override
-    public void get(List<String> keys, Consumer<Result<Map<String, byte[]>>> consumer) {
-        mThreadUtils.checkMainThread();
-        mExecutor.execute(() -> consumer.accept(get(keys)));
-    }
-
-    @Override
-    public Result<Map<String, byte[]>> get(List<String> keys) {
-        initializeContentDir();
-
-        Map<String, byte[]> valueMap = new HashMap<>(keys.size());
-        for (String key : keys) {
-            File keyFile = new File(mContentDir, key);
-            if (keyFile.exists()) {
-                try {
-                    valueMap.put(key, getFileContents(keyFile));
-                } catch (IOException e) {
-                    Logger.e(TAG, e, "Error getting file contents");
-                    return Result.failure();
-                }
-            }
-        }
-        return Result.success(valueMap);
-    }
-
-    @Override
-    public void getAll(String prefix, Consumer<Result<Map<String, byte[]>>> consumer) {
-        mThreadUtils.checkMainThread();
-        mExecutor.execute(() -> consumer.accept(getAll(prefix)));
-    }
-
-    @Override
-    public Result<Map<String, byte[]>> getAll(String prefix) {
-        initializeContentDir();
-
-        File[] files = mContentDir.listFiles();
-
-        Map<String, byte[]> allFilesMap = new HashMap<>();
-
-        try {
-            if (files != null) {
-                for (File file : files) {
-                    if (file.getName().startsWith(prefix)) {
-                        allFilesMap.put(file.getName(), getFileContents(file));
-                    }
-                }
-            }
-
-            return Result.success(allFilesMap);
-        } catch (IOException e) {
-            Logger.e(TAG, e, "Error getting file contents");
-            return Result.failure();
-        }
-    }
-
-    private byte[] getFileContents(File keyFile) throws IOException {
-        mThreadUtils.checkNotMainThread();
-
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-
-        if (keyFile.exists()) {
-            try (FileInputStream fileInputStream = new FileInputStream(keyFile)) {
-                while (fileInputStream.available() > 0) {
-                    outputStream.write(fileInputStream.read());
-                }
-                return outputStream.toByteArray();
-            } catch (IOException e) {
-                Logger.e(TAG, "Error reading file", e);
-                throw new IOException("Error reading file", e);
-            }
-        }
-        return new byte[0];
-    }
-
-    @Override
-    public void commit(ContentMutation mutation, Consumer<CommitResult> consumer) {
-        mThreadUtils.checkMainThread();
-        mExecutor.execute(() -> consumer.accept(commit(mutation)));
-    }
-
-    @Override
-    public CommitResult commit(ContentMutation mutation) {
-        initializeContentDir();
-
-        for (ContentOperation operation : mutation.getOperations()) {
-            if (operation.getType() == UPSERT) {
-                if (!upsert((Upsert) operation)) {
-                    return CommitResult.FAILURE;
-                }
-            } else if (operation.getType() == DELETE) {
-                if (!delete((Delete) operation)) {
-                    return CommitResult.FAILURE;
-                }
-            } else if (operation.getType() == DELETE_BY_PREFIX) {
-                if (!deleteByPrefix((DeleteByPrefix) operation)) {
-                    return CommitResult.FAILURE;
-                }
-            } else if (operation.getType() == DELETE_ALL) {
-                if (!deleteAll()) {
-                    return CommitResult.FAILURE;
-                }
-            } else {
-                Logger.e(TAG, "Unrecognized ContentOperation type: %s", operation.getType());
-            }
-        }
-
-        return CommitResult.SUCCESS;
-    }
-
-    @Override
-    public void getAllKeys(Consumer<Result<List<String>>> consumer) {
-        mThreadUtils.checkMainThread();
-        consumer.accept(getAllKeys());
-    }
-
-    @Override
-    public Result<List<String>> getAllKeys() {
-        String[] filenames = mContentDir.list();
-        if (filenames != null) {
-            return Result.success(Arrays.asList(filenames));
-        } else {
-            return Result.failure();
-        }
-    }
-
-    private boolean deleteAll() {
-        mThreadUtils.checkNotMainThread();
-
-        boolean success = true;
-
-        File[] files = mContentDir.listFiles();
-        if (files != null) {
-            // Delete all files in the content directory
-            for (File file : files) {
-                if (!file.delete()) {
-                    Logger.e(TAG, "Error deleting file when deleting all for file %s",
-                            file.getName());
-                    success = false;
-                }
-            }
-        }
-        return mContentDir.delete() && success;
-    }
-
-    private boolean deleteByPrefix(DeleteByPrefix operation) {
-        mThreadUtils.checkNotMainThread();
-
-        File[] files = mContentDir.listFiles();
-
-        if (files != null) {
-            for (File file : files) {
-                if (file.getName().startsWith(operation.getPrefix())) {
-                    // Try to delete
-                    if (!file.delete()) {
-                        Logger.e(TAG, "Error deleting by prefix %s", operation.getPrefix());
-                        return false;
-                    }
-                }
-            }
-            return true;
-        }
-
-        return false;
-    }
-
-    private boolean delete(Delete operation) {
-        mThreadUtils.checkNotMainThread();
-
-        File file = new File(mContentDir, operation.getKey());
-        boolean result = file.delete();
-        if (!result) {
-            Logger.e(TAG, "Error deleting key %s", operation.getKey());
-        }
-        return result;
-    }
-
-    private boolean upsert(Upsert operation) {
-        mThreadUtils.checkNotMainThread();
-
-        File file = new File(mContentDir, operation.getKey());
-        try (FileOutputStream fos = new FileOutputStream(file)) {
-            fos.write(operation.getValue());
-            return true;
-        } catch (IOException e) {
-            Logger.e(TAG, "Error upserting key %s with value %s", operation.getKey(),
-                    operation.getValue());
-            return false;
-        }
-    }
-
-    private void initializeContentDir() {
-        mThreadUtils.checkNotMainThread();
-
-        if (mContentDir == null) {
-            mContentDir = mContext.getDir(CONTENT_DIR, Context.MODE_PRIVATE);
-        }
-        if (!mContentDir.exists()) {
-            mContentDir.mkdir();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/PersistentJournalStorage.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/PersistentJournalStorage.java
deleted file mode 100644
index 2216f68..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/PersistentJournalStorage.java
+++ /dev/null
@@ -1,419 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.hostimpl.storage;
-
-import static org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Type.APPEND;
-import static org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Type.COPY;
-import static org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Type.DELETE;
-
-import android.content.Context;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Append;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Copy;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorage;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorageDirect;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.concurrent.Executor;
-
-/**
- * Implementation of {@link JournalStorage} that persists data to disk.
- *
- * <p>Data is stored in files, with each append consisting of first the size of the bytes to write,
- * followed by the bytes themselves. For example, for a byte array of size 4, a total of 8 bytes
- * will be written: the 4 bytes representing the integer 4 (size), followed by the 4 bytes for the
- * append.
- */
-public final class PersistentJournalStorage implements JournalStorage, JournalStorageDirect {
-    private static final String TAG = "PersistentJournal";
-    /** The schema version currently in use. */
-    private static final int SCHEMA_VERSION = 1;
-
-    private static final String SHARED_PREFERENCES = "JOURNAL_SP";
-    private static final String SCHEMA_KEY = "JOURNAL_SCHEMA";
-
-    // Optional Content directory - By default this is not used
-    private static final String JOURNAL_DIR = "journal";
-    private static final String ENCODING = "UTF-8";
-    private static final int INTEGER_BYTE_SIZE = 4;
-    private static final String ASTERISK = "_ATK_";
-    private static final int MAX_BYTE_SIZE = 1000000;
-
-    private final Context mContext;
-    private final ThreadUtils mThreadUtils;
-    private final Executor mExecutor;
-    @Nullable
-    private final String mPersistenceDir;
-    private File mJournalDir;
-
-    /**
-     * The schema of existing content. If this does not match {@code SCHEMA_VERSION}, all existing
-     * content will be wiped so there are no version mismatches where data cannot be read / written
-     * correctly.
-     */
-    private int mExistingSchema;
-
-    public PersistentJournalStorage(Context context, Executor executorService,
-            ThreadUtils threadUtils, @Nullable String persistenceDir) {
-        this.mContext = context;
-        this.mExecutor = executorService;
-        this.mThreadUtils = threadUtils;
-        // TODO: See https://goto.google.com/tiktok-conformance-violations/SHARED_PREFS
-        this.mExistingSchema =
-                context.getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE)
-                        .getInt(SCHEMA_KEY, 0);
-        this.mPersistenceDir = persistenceDir;
-    }
-
-    @Override
-    public void read(String journalName, Consumer<Result<List<byte[]>>> consumer) {
-        mThreadUtils.checkMainThread();
-        mExecutor.execute(() -> consumer.accept(read(journalName)));
-    }
-
-    @Override
-    public Result<List<byte[]>> read(String journalName) {
-        initializeJournalDir();
-
-        String sanitizedJournalName = sanitize(journalName);
-        if (!sanitizedJournalName.isEmpty()) {
-            File journal = new File(mJournalDir, sanitizedJournalName);
-            try {
-                return Result.success(getJournalContents(journal));
-            } catch (IOException e) {
-                Logger.e(TAG, "Error occured reading journal %s", journalName);
-                return Result.failure();
-            }
-        }
-        return Result.failure();
-    }
-
-    private List<byte[]> getJournalContents(File journal) throws IOException {
-        mThreadUtils.checkNotMainThread();
-
-        List<byte[]> journalContents = new ArrayList<>();
-        if (journal.exists()) {
-            // Read byte size & bytes for each entry in the journal. See class comment for more info
-            // on format.
-            try (FileInputStream inputStream = new FileInputStream(journal)) {
-                byte[] lengthBytes = new byte[INTEGER_BYTE_SIZE];
-                while (inputStream.available() > 0) {
-                    readBytes(inputStream, lengthBytes, INTEGER_BYTE_SIZE);
-                    int size = ByteBuffer.wrap(lengthBytes).getInt();
-                    if (size > MAX_BYTE_SIZE || size < 0) {
-                        throw new IOException(
-                                String.format(Locale.US, "Unexpected byte size %d", size));
-                    }
-
-                    byte[] contentBytes = new byte[size];
-                    readBytes(inputStream, contentBytes, size);
-                    journalContents.add(contentBytes);
-                }
-            } catch (IOException e) {
-                Logger.e(TAG, "Error reading file", e);
-                throw new IOException("Error reading journal file", e);
-            }
-        }
-        return journalContents;
-    }
-
-    private void readBytes(FileInputStream inputStream, byte[] dest, int size) throws IOException {
-        int bytesRead = inputStream.read(dest, 0, size);
-        if (bytesRead != size) {
-            throw new IOException(String.format(
-                    Locale.US, "Expected to read %d bytes, but read %d bytes", size, bytesRead));
-        }
-    }
-
-    @Override
-    public void commit(JournalMutation mutation, Consumer<CommitResult> consumer) {
-        mThreadUtils.checkMainThread();
-        mExecutor.execute(() -> consumer.accept(commit(mutation)));
-    }
-
-    @Override
-    public CommitResult commit(JournalMutation mutation) {
-        initializeJournalDir();
-
-        String sanitizedJournalName = sanitize(mutation.getJournalName());
-        if (!sanitizedJournalName.isEmpty()) {
-            File journal = new File(mJournalDir, sanitizedJournalName);
-
-            for (JournalOperation operation : mutation.getOperations()) {
-                if (operation.getType() == APPEND) {
-                    if (!append((Append) operation, journal)) {
-                        return CommitResult.FAILURE;
-                    }
-                } else if (operation.getType() == COPY) {
-                    if (!copy((Copy) operation, journal)) {
-                        return CommitResult.FAILURE;
-                    }
-                } else if (operation.getType() == DELETE) {
-                    if (!delete(journal)) {
-                        return CommitResult.FAILURE;
-                    }
-                } else {
-                    Logger.e(TAG, "Unrecognized journal operation type %s", operation.getType());
-                }
-            }
-
-            return CommitResult.SUCCESS;
-        }
-        return CommitResult.FAILURE;
-    }
-
-    @Override
-    public void deleteAll(Consumer<CommitResult> consumer) {
-        mThreadUtils.checkMainThread();
-
-        mExecutor.execute(() -> consumer.accept(deleteAllInitialized()));
-    }
-
-    @Override
-    public CommitResult deleteAll() {
-        initializeJournalDir();
-        return deleteAllInitialized();
-    }
-
-    private CommitResult deleteAllInitialized() {
-        boolean success = true;
-
-        File[] files = mJournalDir.listFiles();
-        if (files != null) {
-            // Delete all files in the journal directory
-            for (File file : files) {
-                if (!file.delete()) {
-                    Logger.e(TAG, "Error deleting file when deleting all journals for file %s",
-                            file.getName());
-                    success = false;
-                }
-            }
-        }
-        success &= mJournalDir.delete();
-        return success ? CommitResult.SUCCESS : CommitResult.FAILURE;
-    }
-
-    private boolean delete(File journal) {
-        mThreadUtils.checkNotMainThread();
-
-        if (!journal.exists()) {
-            // If the file doesn't exist, let's call it deleted.
-            return true;
-        }
-        boolean result = journal.delete();
-        if (!result) {
-            Logger.e(TAG, "Error deleting journal %s", journal.getName());
-        }
-        return result;
-    }
-
-    private boolean copy(Copy operation, File journal) {
-        mThreadUtils.checkNotMainThread();
-
-        try {
-            if (!journal.exists()) {
-                Logger.w(TAG, "Journal file %s does not exist, creating empty version",
-                        journal.getName());
-                if (!journal.createNewFile()) {
-                    Logger.e(TAG, "Journal file %s exists while trying to create it",
-                            journal.getName());
-                }
-            }
-            String sanitizedDestJournalName = sanitize(operation.getToJournalName());
-            if (!sanitizedDestJournalName.isEmpty()) {
-                copyFile(journal, sanitizedDestJournalName);
-                return true;
-            }
-        } catch (IOException e) {
-            Logger.e(TAG, e, "Error copying journal %s to %s", journal.getName(),
-                    operation.getToJournalName());
-        }
-        return false;
-    }
-
-    private void copyFile(File journal, String destinationFileName) throws IOException {
-        InputStream inputStream = null;
-        OutputStream outputStream = null;
-        try {
-            File destination = new File(mJournalDir, destinationFileName);
-            inputStream = new FileInputStream(journal);
-            outputStream = new FileOutputStream(destination);
-            byte[] bytes = new byte[512];
-            int length;
-            while ((length = inputStream.read(bytes)) > 0) {
-                outputStream.write(bytes, 0, length);
-            }
-        } finally {
-            if (inputStream != null) {
-                inputStream.close();
-            }
-            if (outputStream != null) {
-                outputStream.close();
-            }
-        }
-    }
-
-    private boolean append(Append operation, File journal) {
-        mThreadUtils.checkNotMainThread();
-
-        if (!journal.exists()) {
-            try {
-                journal.createNewFile();
-            } catch (IOException e) {
-                Logger.e(TAG, "Could not create file to append to for journal %s.",
-                        journal.getName());
-                return false;
-            }
-        }
-
-        byte[] journalBytes = operation.getValue();
-        byte[] sizeBytes =
-                ByteBuffer.allocate(INTEGER_BYTE_SIZE).putInt(journalBytes.length).array();
-        return writeBytes(journal, sizeBytes, journalBytes);
-    }
-
-    /** Write byte size & bytes into the journal. See class comment for more info on format. */
-    private boolean writeBytes(File journal, byte[] sizeBytes, byte[] journalBytes) {
-        try (FileOutputStream out = new FileOutputStream(journal, /* append= */ true)) {
-            out.write(sizeBytes);
-            out.write(journalBytes);
-            return true;
-        } catch (IOException e) {
-            Logger.e(TAG, "Error appending byte[] %s (size byte[] %s) for journal %s", journalBytes,
-                    sizeBytes, journal.getName());
-            return false;
-        }
-    }
-
-    @Override
-    public void exists(String journalName, Consumer<Result<Boolean>> consumer) {
-        mThreadUtils.checkMainThread();
-        mExecutor.execute(() -> consumer.accept(exists(journalName)));
-    }
-
-    @Override
-    public Result<Boolean> exists(String journalName) {
-        initializeJournalDir();
-
-        String sanitizedJournalName = sanitize(journalName);
-        if (!sanitizedJournalName.isEmpty()) {
-            File journal = new File(mJournalDir, sanitizedJournalName);
-            return Result.success(journal.exists());
-        }
-        return Result.failure();
-    }
-
-    @Override
-    public void getAllJournals(Consumer<Result<List<String>>> consumer) {
-        mThreadUtils.checkMainThread();
-        mExecutor.execute(() -> consumer.accept(getAllJournals()));
-    }
-
-    @Override
-    public Result<List<String>> getAllJournals() {
-        initializeJournalDir();
-
-        File[] files = mJournalDir.listFiles();
-        List<String> journals = new ArrayList<>();
-        if (files != null) {
-            for (File file : files) {
-                String desanitizedFileName = desanitize(file.getName());
-                if (!desanitizedFileName.isEmpty()) {
-                    journals.add(desanitizedFileName);
-                }
-            }
-        }
-        return Result.success(journals);
-    }
-
-    private void initializeJournalDir() {
-        // if we've set the journalDir then just verify that it exists
-        if (mJournalDir != null) {
-            if (!mJournalDir.exists()) {
-                if (!mJournalDir.mkdir()) {
-                    Logger.w(TAG, "Jardin journal directory already exists");
-                }
-            }
-            return;
-        }
-
-        // Create the root directory persistent files
-        if (mPersistenceDir != null) {
-            File persistenceRoot = mContext.getDir(mPersistenceDir, Context.MODE_PRIVATE);
-            if (!persistenceRoot.exists()) {
-                if (!persistenceRoot.mkdir()) {
-                    Logger.w(TAG, "persistenceDir directory already exists");
-                }
-            }
-            mJournalDir = new File(persistenceRoot, JOURNAL_DIR);
-        } else {
-            mJournalDir = mContext.getDir(JOURNAL_DIR, Context.MODE_PRIVATE);
-        }
-        if (mExistingSchema != SCHEMA_VERSION) {
-            // For schema mismatch, delete everything.
-            CommitResult result = deleteAllInitialized();
-            if (result == CommitResult.SUCCESS
-                    && mContext.getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE)
-                               .edit()
-                               .putInt(SCHEMA_KEY, SCHEMA_VERSION)
-                               .commit()) {
-                mExistingSchema = SCHEMA_VERSION;
-            }
-        }
-        if (!mJournalDir.exists()) {
-            if (!mJournalDir.mkdir()) {
-                Logger.w(TAG, "journal directory already exists");
-            }
-        }
-    }
-
-    @VisibleForTesting
-    String sanitize(String journalName) {
-        try {
-            // * is not replaced by URL encoder
-            String sanitized = URLEncoder.encode(journalName, ENCODING);
-            return sanitized.replace("*", ASTERISK);
-        } catch (UnsupportedEncodingException e) {
-            // Should not happen
-            Logger.e(TAG, "Error sanitizing journal name %s", journalName);
-            return "";
-        }
-    }
-
-    @VisibleForTesting
-    String desanitize(String sanitizedJournalName) {
-        try {
-            // * is not replaced by URL encoder
-            String desanitized = URLDecoder.decode(sanitizedJournalName, ENCODING);
-            return desanitized.replace(ASTERISK, "*");
-        } catch (UnsupportedEncodingException e) {
-            // Should not happen
-            Logger.e(TAG, "Error desanitizing journal name %s", sanitizedJournalName);
-            return "";
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/testing/InMemoryContentStorage.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/testing/InMemoryContentStorage.java
deleted file mode 100644
index ded3f7d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/testing/InMemoryContentStorage.java
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.hostimpl.storage.testing;
-
-import static org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Type.DELETE;
-import static org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Type.DELETE_BY_PREFIX;
-import static org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Type.UPSERT;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Delete;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.DeleteByPrefix;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Type;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Upsert;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorage;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorageDirect;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/** A {@link ContentStorage} that holds data in memory. */
-public final class InMemoryContentStorage implements ContentStorageDirect, Dumpable {
-    private static final String TAG = "InMemoryContentStorage";
-
-    private final Map<String, byte[]> mStore = new HashMap<>();
-
-    private int mGetCount;
-    private int mGetAllCount;
-    private int mInsertCount;
-    private int mUpdateCount;
-
-    @Override
-    public Result<Map<String, byte[]>> get(List<String> keys) {
-        mGetCount++;
-
-        Map<String, byte[]> valueMap = new HashMap<>(keys.size());
-        for (String key : keys) {
-            byte[] value = mStore.get(key);
-            if (value == null || value.length == 0) {
-                Logger.w(TAG, "Didn't find value for %s, not adding to map", key);
-            } else {
-                valueMap.put(key, value);
-            }
-        }
-        return Result.success(valueMap);
-    }
-
-    @Override
-    public Result<Map<String, byte[]>> getAll(String prefix) {
-        mGetAllCount++;
-        Map<String, byte[]> results = new HashMap<>();
-        for (Entry<String, byte[]> entry : mStore.entrySet()) {
-            if (entry.getKey().startsWith(prefix)) {
-                results.put(entry.getKey(), entry.getValue());
-            }
-        }
-        return Result.success(results);
-    }
-
-    @Override
-    public CommitResult commit(ContentMutation mutation) {
-        for (ContentOperation operation : mutation.getOperations()) {
-            if (operation.getType() == UPSERT) {
-                if (!upsert((Upsert) operation)) {
-                    return CommitResult.FAILURE;
-                }
-            } else if (operation.getType() == DELETE) {
-                if (!delete((Delete) operation)) {
-                    return CommitResult.FAILURE;
-                }
-            } else if (operation.getType() == DELETE_BY_PREFIX) {
-                if (!deleteByPrefix((DeleteByPrefix) operation)) {
-                    return CommitResult.FAILURE;
-                }
-            } else if (operation.getType() == Type.DELETE_ALL) {
-                if (!deleteAll()) {
-                    return CommitResult.FAILURE;
-                }
-            } else {
-                Logger.e(TAG, "Invalid ContentMutation: unexpected operation: %s",
-                        operation.getType());
-                return CommitResult.FAILURE;
-            }
-        }
-
-        return CommitResult.SUCCESS;
-    }
-
-    @Override
-    public Result<List<String>> getAllKeys() {
-        return Result.success(new ArrayList<>(mStore.keySet()));
-    }
-
-    private boolean deleteAll() {
-        mStore.clear();
-        return true;
-    }
-
-    private boolean deleteByPrefix(DeleteByPrefix operation) {
-        List<String> keysToRemove = new ArrayList<>();
-        for (String key : mStore.keySet()) {
-            if (key.startsWith(operation.getPrefix())) {
-                keysToRemove.add(key);
-            }
-        }
-        mStore.keySet().removeAll(keysToRemove);
-        return true;
-    }
-
-    private boolean delete(Delete operation) {
-        mStore.remove(operation.getKey());
-        return true;
-    }
-
-    private boolean upsert(Upsert operation) {
-        String key = operation.getKey();
-        // TODO: remove unneeded null checks.
-        if (key == null) {
-            Logger.e(TAG, "Invalid ContentMutation: null key");
-            return false;
-        }
-        byte[] value = operation.getValue();
-        if (value == null) {
-            Logger.e(TAG, "Invalid ContentMutation: null value");
-            return false;
-        }
-        if (value.length == 0) {
-            Logger.e(TAG, "Invalid ContentMutation: empty value");
-            return false;
-        }
-        byte[] currentValue = mStore.put(key, value);
-        if (currentValue == null) {
-            mInsertCount++;
-        } else {
-            mUpdateCount++;
-        }
-        return true;
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        dumper.forKey("contentItems").value(mStore.size());
-        dumper.forKey("getCount").value(mGetCount);
-        dumper.forKey("getAllCount").value(mGetAllCount).compactPrevious();
-        dumper.forKey("insertCount").value(mInsertCount).compactPrevious();
-        dumper.forKey("updateCount").value(mUpdateCount).compactPrevious();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/testing/InMemoryJournalStorage.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/testing/InMemoryJournalStorage.java
deleted file mode 100644
index e565be8a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/testing/InMemoryJournalStorage.java
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.hostimpl.storage.testing;
-
-import static org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Type.APPEND;
-import static org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Type.COPY;
-import static org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Type.DELETE;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Append;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Copy;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorage;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorageDirect;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumpable;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/** A {@link JournalStorage} implementation that holds the data in memory. */
-public final class InMemoryJournalStorage implements JournalStorageDirect, Dumpable {
-    private static final String TAG = "InMemoryJournalStorage";
-
-    private final Map<String, List<byte[]>> mJournals;
-    private int mReadCount;
-    private int mAppendCount;
-    private int mCopyCount;
-    private int mDeleteCount;
-
-    public InMemoryJournalStorage() {
-        mJournals = new HashMap<>();
-    }
-
-    @Override
-    public Result<List<byte[]>> read(String journalName) {
-        mReadCount++;
-        List<byte[]> journal = mJournals.get(journalName);
-        if (journal == null) {
-            journal = new ArrayList<>();
-        }
-        return Result.success(journal);
-    }
-
-    @Override
-    public CommitResult commit(JournalMutation mutation) {
-        String journalName = mutation.getJournalName();
-
-        for (JournalOperation operation : mutation.getOperations()) {
-            if (operation.getType() == APPEND) {
-                if (!append(((Append) operation).getValue(), journalName)) {
-                    return CommitResult.FAILURE;
-                }
-            } else if (operation.getType() == COPY) {
-                if (!copy(journalName, ((Copy) operation).getToJournalName())) {
-                    return CommitResult.FAILURE;
-                }
-            } else if (operation.getType() == DELETE) {
-                if (!delete(journalName)) {
-                    return CommitResult.FAILURE;
-                }
-            } else {
-                Logger.w(TAG, "Unexpected JournalOperation type: %s", operation.getType());
-                return CommitResult.FAILURE;
-            }
-        }
-        return CommitResult.SUCCESS;
-    }
-
-    @Override
-    public Result<Boolean> exists(String journalName) {
-        return Result.success(mJournals.containsKey(journalName));
-    }
-
-    @Override
-    public Result<List<String>> getAllJournals() {
-        return Result.success(new ArrayList<>(mJournals.keySet()));
-    }
-
-    @Override
-    public CommitResult deleteAll() {
-        mJournals.clear();
-        return CommitResult.SUCCESS;
-    }
-
-    private boolean append(byte[] value, String journalName) {
-        List<byte[]> journal = mJournals.get(journalName);
-        if (value == null) {
-            Logger.e(TAG, "Journal not found: %s", journalName);
-            return false;
-        }
-        if (journal == null) {
-            journal = new ArrayList<>();
-            mJournals.put(journalName, journal);
-        }
-        mAppendCount++;
-        journal.add(value);
-        return true;
-    }
-
-    private boolean copy(String fromJournalName, String toJournalName) {
-        mCopyCount++;
-        List<byte[]> toJournal = mJournals.get(toJournalName);
-        if (toJournal != null) {
-            Logger.e(TAG, "Copy destination journal already present: %s", toJournalName);
-            return false;
-        }
-        List<byte[]> journal = mJournals.get(fromJournalName);
-        if (journal != null) {
-            // TODO: Compact before copying?
-            mJournals.put(toJournalName, new ArrayList<>(journal));
-        }
-        return true;
-    }
-
-    private boolean delete(String journalName) {
-        mDeleteCount++;
-        mJournals.remove(journalName);
-        return true;
-    }
-
-    @Override
-    public void dump(Dumper dumper) {
-        dumper.title(TAG);
-        dumper.forKey("readCount").value(mReadCount);
-        dumper.forKey("appendCount").value(mAppendCount).compactPrevious();
-        dumper.forKey("copyCount").value(mCopyCount).compactPrevious();
-        dumper.forKey("deleteCount").value(mDeleteCount).compactPrevious();
-        dumper.forKey("sessions").value(mJournals.size());
-        for (Entry<String, List<byte[]>> entry : mJournals.entrySet()) {
-            Dumper childDumper = dumper.getChildDumper();
-            childDumper.title("Session");
-            childDumper.forKey("name").value(entry.getKey());
-            childDumper.forKey("operations").value(entry.getValue().size()).compactPrevious();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/mocknetworkclient/MockServerNetworkClient.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/mocknetworkclient/MockServerNetworkClient.java
deleted file mode 100644
index 280d21f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/mocknetworkclient/MockServerNetworkClient.java
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.mocknetworkclient;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.Settings;
-import android.provider.Settings.Global;
-import android.util.Base64;
-
-import com.google.protobuf.ByteString;
-import com.google.protobuf.CodedOutputStream;
-import com.google.protobuf.ExtensionRegistryLite;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest.HttpMethod;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpResponse;
-import org.chromium.chrome.browser.feed.library.api.host.network.NetworkClient;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.feedrequestmanager.RequestHelper;
-import org.chromium.components.feed.core.proto.wire.FeedRequestProto.FeedRequest;
-import org.chromium.components.feed.core.proto.wire.RequestProto.Request;
-import org.chromium.components.feed.core.proto.wire.ResponseProto.Response;
-import org.chromium.components.feed.core.proto.wire.mockserver.MockServerProto.ConditionalResponse;
-import org.chromium.components.feed.core.proto.wire.mockserver.MockServerProto.MockServer;
-
-import java.io.IOException;
-import java.util.List;
-
-/** A network client that returns mock responses provided via a config proto */
-public final class MockServerNetworkClient implements NetworkClient {
-    private static final String TAG = "MockServerNetworkClient";
-
-    private final Context mContext;
-    private final Response mInitialResponse;
-    private final List<ConditionalResponse> mConditionalResponses;
-    private final ExtensionRegistryLite mExtensionRegistry;
-    private final long mResponseDelay;
-
-    public MockServerNetworkClient(
-            Context context, MockServer mockServer, long responseDelayMillis) {
-        this.mContext = context;
-        mInitialResponse = mockServer.getInitialResponse();
-        mConditionalResponses = mockServer.getConditionalResponsesList();
-
-        mExtensionRegistry = ExtensionRegistryLite.newInstance();
-        mExtensionRegistry.add(FeedRequest.feedRequest);
-        mResponseDelay = responseDelayMillis;
-    }
-
-    @Override
-    public void send(HttpRequest httpRequest, Consumer<HttpResponse> responseConsumer) {
-        try {
-            if (isAirplaneModeOn()) {
-                delayedAccept(new HttpResponse(400, new byte[] {}, false), responseConsumer);
-                return;
-            }
-            Request request = getRequest(httpRequest);
-            ByteString requestToken =
-                    (request.getExtension(FeedRequest.feedRequest).getFeedQuery().hasPageToken())
-                    ? request.getExtension(FeedRequest.feedRequest).getFeedQuery().getPageToken()
-                    : null;
-            if (requestToken != null) {
-                for (ConditionalResponse response : mConditionalResponses) {
-                    if (!response.hasContinuationToken()) {
-                        Logger.w(TAG, "Conditional response without a token");
-                        continue;
-                    }
-                    if (requestToken.equals(response.getContinuationToken())) {
-                        delayedAccept(createHttpResponse(response.getResponse()), responseConsumer);
-                        return;
-                    }
-                }
-            }
-            delayedAccept(createHttpResponse(mInitialResponse), responseConsumer);
-        } catch (IOException e) {
-            // TODO : handle errors here
-            Logger.e(TAG, e.getMessage());
-            delayedAccept(new HttpResponse(400, new byte[] {}, false), responseConsumer);
-        }
-    }
-
-    private boolean isAirplaneModeOn() {
-        return Settings.System.getInt(mContext.getContentResolver(), Global.AIRPLANE_MODE_ON, 0)
-                != 0;
-    }
-
-    private void delayedAccept(HttpResponse httpResponse, Consumer<HttpResponse> responseConsumer) {
-        if (mResponseDelay <= 0) {
-            responseConsumer.accept(httpResponse);
-            return;
-        }
-
-        new Handler(Looper.getMainLooper())
-                .postDelayed(() -> responseConsumer.accept(httpResponse), mResponseDelay);
-    }
-
-    // TODO Fix nullness violation: incompatible types in argument.
-    @SuppressWarnings("nullness:argument.type.incompatible")
-    private Request getRequest(HttpRequest httpRequest) throws IOException {
-        byte[] rawRequest = new byte[0];
-        if (httpRequest.getMethod().equals(HttpMethod.GET)) {
-            if (httpRequest.getUri().getQueryParameter(RequestHelper.MOTHERSHIP_PARAM_PAYLOAD)
-                    != null) {
-                rawRequest = Base64.decode(httpRequest.getUri().getQueryParameter(
-                                                   RequestHelper.MOTHERSHIP_PARAM_PAYLOAD),
-                        Base64.URL_SAFE);
-            }
-        } else {
-            rawRequest = httpRequest.getBody();
-        }
-        return Request.parseFrom(rawRequest, mExtensionRegistry);
-    }
-
-    @Override
-    public void close() {}
-
-    private HttpResponse createHttpResponse(Response response) {
-        if (response == null) {
-            return new HttpResponse(500, new byte[] {}, false);
-        }
-
-        try {
-            byte[] rawResponse = response.toByteArray();
-            byte[] newResponse = new byte[rawResponse.length + (Integer.SIZE / 8)];
-            CodedOutputStream codedOutputStream = CodedOutputStream.newInstance(newResponse);
-            codedOutputStream.writeUInt32NoTag(rawResponse.length);
-            codedOutputStream.writeRawBytes(rawResponse);
-            codedOutputStream.flush();
-            return new HttpResponse(200, newResponse, false);
-        } catch (IOException e) {
-            Logger.e(TAG, "Error creating response", e);
-            return new HttpResponse(500, new byte[] {}, false);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/AdapterFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/AdapterFactory.java
deleted file mode 100644
index df99d07..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/AdapterFactory.java
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.content.Context;
-
-/**
- * An AdapterFactory manages binding a model to an Adapter and releasing it once we are done with
- * the view. This provides the basic support for Recycling Adapters and Views. The {@link
- * AdapterKeySupplier} is provided by the {@link ElementAdapter} to supply all the information
- * needed needed by this class.
- *
- * @param <A> A subclass of {@link ElementAdapter} which this factory is managing.
- * @param <M> The model. This is the model type which is bound to the view by the adapter.
- */
-class AdapterFactory<A extends ElementAdapter<?, M>, M> {
-    private static final String TAG = "AdapterFactory";
-
-    // TODO: Make these configurable instead of constants.
-    private static final int DEFAULT_POOL_SIZE = 100;
-    private static final int DEFAULT_NUM_POOLS = 10;
-
-    private final Context mContext;
-    private final AdapterParameters mParameters;
-    private final AdapterKeySupplier<A, M> mKeySupplier;
-    private final Statistics mStatistics;
-    private final RecyclerPool<A> mRecyclingPool;
-
-    /** Provides Adapter class level details to the factory. */
-    interface AdapterKeySupplier<A extends ElementAdapter<?, M>, M> {
-        /**
-         * Returns a String tag for the Adapter. This will be used in messages and developer
-         * logging
-         */
-        String getAdapterTag();
-
-        /** Returns a new Adapter. */
-        A getAdapter(Context context, AdapterParameters parameters);
-
-        /** Returns the Key based upon the model. */
-        RecyclerKey getKey(FrameContext frameContext, M model);
-    }
-
-    /** Key supplier with a singleton key. */
-    abstract static class SingletonKeySupplier<A extends ElementAdapter<?, M>, M>
-            implements AdapterKeySupplier<A, M> {
-        public static final RecyclerKey SINGLETON_KEY = new RecyclerKey();
-
-        @Override
-        public RecyclerKey getKey(FrameContext frameContext, M model) {
-            return SINGLETON_KEY;
-        }
-    }
-
-    // SuppressWarnings for various errors. We don't want to have to import checker framework and
-    // checker doesn't like generic assignments.
-    @SuppressWarnings("nullness")
-    AdapterFactory(
-            Context context, AdapterParameters parameters, AdapterKeySupplier<A, M> keySupplier) {
-        this.mContext = context;
-        this.mParameters = parameters;
-        this.mKeySupplier = keySupplier;
-        this.mStatistics = new Statistics(keySupplier.getAdapterTag());
-        if (keySupplier instanceof SingletonKeySupplier) {
-            mRecyclingPool = new SingleKeyRecyclerPool<>(
-                    SingletonKeySupplier.SINGLETON_KEY, DEFAULT_POOL_SIZE);
-        } else {
-            mRecyclingPool = new KeyedRecyclerPool<>(DEFAULT_NUM_POOLS, DEFAULT_POOL_SIZE);
-        }
-    }
-
-    /** Returns an adapter suitable for binding the given model. */
-    public A get(M model, FrameContext frameContext) {
-        mStatistics.mGetCalls++;
-        A a = mRecyclingPool.get(mKeySupplier.getKey(frameContext, model));
-        if (a == null) {
-            a = mKeySupplier.getAdapter(mContext, mParameters);
-            mStatistics.mAdapterCreation++;
-        } else {
-            mStatistics.mPoolHit++;
-        }
-        return a;
-    }
-
-    /** Release the Adapter, releases the model and will recycle the Adapter */
-    public void release(A a) {
-        mStatistics.mReleaseCalls++;
-        a.releaseAdapter();
-        RecyclerKey key = a.getKey();
-        if (key != null) {
-            mRecyclingPool.put(key, a);
-        }
-    }
-
-    public void purgeRecyclerPool() {
-        mRecyclingPool.clear();
-    }
-
-    /**
-     * Basic statistics about hits, creations, etc. used to track how get/release are being used.
-     */
-    static class Statistics {
-        final String mFactoryName;
-        int mAdapterCreation;
-        int mPoolHit;
-        int mReleaseCalls;
-        int mGetCalls;
-
-        public Statistics(String factoryName) {
-            this.mFactoryName = factoryName;
-        }
-
-        @Override
-        public String toString() {
-            // String used to show statistics during debugging in Android Studio.
-            return "Stats: " + mFactoryName + ", Hits:" + mPoolHit + ", creations "
-                    + mAdapterCreation + ", Release: " + mReleaseCalls;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/AdapterParameters.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/AdapterParameters.java
deleted file mode 100644
index d7effb3..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/AdapterParameters.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.content.Context;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.piet.PietStylesHelper.PietStylesHelperFactory;
-import org.chromium.chrome.browser.feed.library.piet.ui.RoundedCornerMaskCache;
-
-/**
- * A state shared by instances of Cards and Slices. The state is accessed directly from the instance
- * instead of going through getX methods.
- *
- * <p>This is basically the Dagger state for Piet. If we can use Dagger, replace this with Dagger.
- */
-class AdapterParameters {
-    // TODO: Make these configurable instead of constants.
-    private static final int DEFAULT_TEMPLATE_POOL_SIZE = 100;
-    private static final int DEFAULT_NUM_TEMPLATE_POOLS = 30;
-
-    final Context mContext;
-    final Supplier<ViewGroup> mParentViewSupplier;
-    final HostProviders mHostProviders;
-    final ParameterizedTextEvaluator mTemplatedStringEvaluator;
-    final ElementAdapterFactory mElementAdapterFactory;
-    final TemplateBinder mTemplateBinder;
-    final StyleProvider mDefaultStyleProvider;
-    final Clock mClock;
-    final PietStylesHelperFactory mPietStylesHelperFactory;
-    final RoundedCornerMaskCache mRoundedCornerMaskCache;
-    final boolean mAllowLegacyRoundedCornerImpl;
-    final boolean mAllowOutlineRoundedCornerImpl;
-
-    // Doesn't like passing "this" to the new ElementAdapterFactory; however, nothing in the
-    // factory's construction will reference the elementAdapterFactory member of this, so should be
-    // safe.
-    @SuppressWarnings("nullness")
-    public AdapterParameters(Context context, Supplier<ViewGroup> parentViewSupplier,
-            HostProviders hostProviders, Clock clock, boolean allowLegacyRoundedCornerImpl,
-            boolean allowOutlineRoundedCornerImpl) {
-        this.mContext = context;
-        this.mParentViewSupplier = parentViewSupplier;
-        this.mHostProviders = hostProviders;
-        this.mClock = clock;
-
-        mTemplatedStringEvaluator = new ParameterizedTextEvaluator(clock);
-
-        KeyedRecyclerPool<ElementAdapter<? extends View, ?>> templateRecyclerPool =
-                new KeyedRecyclerPool<>(DEFAULT_NUM_TEMPLATE_POOLS, DEFAULT_TEMPLATE_POOL_SIZE);
-        mElementAdapterFactory = new ElementAdapterFactory(context, this, templateRecyclerPool);
-        mTemplateBinder = new TemplateBinder(templateRecyclerPool, mElementAdapterFactory);
-
-        this.mDefaultStyleProvider = new StyleProvider(hostProviders.getAssetProvider());
-
-        this.mPietStylesHelperFactory = new PietStylesHelperFactory();
-        this.mRoundedCornerMaskCache = new RoundedCornerMaskCache();
-
-        this.mAllowLegacyRoundedCornerImpl = allowLegacyRoundedCornerImpl;
-        this.mAllowOutlineRoundedCornerImpl = allowOutlineRoundedCornerImpl;
-    }
-
-    /** Testing-only constructor for mocking the internally-constructed objects. */
-    @VisibleForTesting
-    AdapterParameters(Context context, Supplier<ViewGroup> parentViewSupplier,
-            HostProviders hostProviders, ParameterizedTextEvaluator templatedStringEvaluator,
-            ElementAdapterFactory elementAdapterFactory, TemplateBinder templateBinder,
-            Clock clock) {
-        this(context, parentViewSupplier, hostProviders, templatedStringEvaluator,
-                elementAdapterFactory, templateBinder, clock, new PietStylesHelperFactory(),
-                new RoundedCornerMaskCache(), true, true);
-    }
-
-    /** Testing-only constructor for mocking the internally-constructed objects. */
-    @VisibleForTesting
-    AdapterParameters(Context context, Supplier<ViewGroup> parentViewSupplier,
-            HostProviders hostProviders, ParameterizedTextEvaluator templatedStringEvaluator,
-            ElementAdapterFactory elementAdapterFactory, TemplateBinder templateBinder, Clock clock,
-            PietStylesHelperFactory pietStylesHelperFactory, RoundedCornerMaskCache maskCache,
-            boolean allowLegacyRoundedCornerImpl, boolean allowOutlineRoundedCornerImpl) {
-        this.mContext = context;
-        this.mParentViewSupplier = parentViewSupplier;
-        this.mHostProviders = hostProviders;
-
-        this.mTemplatedStringEvaluator = templatedStringEvaluator;
-        this.mElementAdapterFactory = elementAdapterFactory;
-        this.mTemplateBinder = templateBinder;
-        this.mDefaultStyleProvider = new StyleProvider(hostProviders.getAssetProvider());
-        this.mClock = clock;
-        this.mPietStylesHelperFactory = pietStylesHelperFactory;
-        this.mRoundedCornerMaskCache = maskCache;
-        this.mAllowLegacyRoundedCornerImpl = allowLegacyRoundedCornerImpl;
-        this.mAllowOutlineRoundedCornerImpl = allowOutlineRoundedCornerImpl;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ChunkedTextElementAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ChunkedTextElementAdapter.java
deleted file mode 100644
index d07d669c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ChunkedTextElementAdapter.java
+++ /dev/null
@@ -1,461 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import static org.chromium.chrome.browser.feed.library.api.host.imageloader.ImageLoaderApi.DIMENSION_UNKNOWN;
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-import static org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode.ERR_MISSING_BINDING_VALUE;
-import static org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.Typeface;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
-import android.text.Layout;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
-import android.text.TextPaint;
-import android.text.style.AbsoluteSizeSpan;
-import android.text.style.ClickableSpan;
-import android.text.style.ForegroundColorSpan;
-import android.text.style.ImageSpan;
-import android.text.style.StyleSpan;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.TextView;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.ui.LayoutUtils;
-import org.chromium.chrome.browser.feed.library.piet.DebugLogger.MessageType;
-import org.chromium.chrome.browser.feed.library.piet.host.ActionHandler;
-import org.chromium.chrome.browser.feed.library.piet.host.ActionHandler.ActionType;
-import org.chromium.components.feed.core.proto.ui.piet.ActionsProto.Action;
-import org.chromium.components.feed.core.proto.ui.piet.ActionsProto.Actions;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.ImageBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.BindingValue;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.TextElement;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Visibility;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-import org.chromium.components.feed.core.proto.ui.piet.ImagesProto.Image;
-import org.chromium.components.feed.core.proto.ui.piet.LogDataProto.LogData;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Frame;
-import org.chromium.components.feed.core.proto.ui.piet.TextProto.Chunk;
-import org.chromium.components.feed.core.proto.ui.piet.TextProto.ChunkedText;
-import org.chromium.components.feed.core.proto.ui.piet.TextProto.ParameterizedText;
-import org.chromium.components.feed.core.proto.ui.piet.TextProto.StyledImageChunk;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/** An {@link ElementAdapter} which manages {@code ChunkedText} elements. */
-class ChunkedTextElementAdapter extends TextElementAdapter {
-    private static final String TAG = "ChunkedTextElementAdapter";
-
-    // We only use a LayerDrawable so we can switch out the Drawable; we only want one layer.
-    @VisibleForTesting
-    static final int SINGLE_LAYER_ID = 0;
-
-    private final Set<ImageSpanDrawableCallback> mLoadingImages = new HashSet<>();
-
-    ChunkedTextElementAdapter(Context context, AdapterParameters parameters) {
-        super(context, parameters);
-    }
-
-    @Override
-    void setTextOnView(FrameContext frameContext, TextElement textLine) {
-        ChunkedText chunkedText;
-        switch (textLine.getContentCase()) {
-            case CHUNKED_TEXT:
-                chunkedText = textLine.getChunkedText();
-                break;
-            case CHUNKED_TEXT_BINDING:
-                BindingValue binding =
-                        frameContext.getChunkedTextBindingValue(textLine.getChunkedTextBinding());
-                if (!binding.hasChunkedText()) {
-                    if (textLine.getChunkedTextBinding().getIsOptional()) {
-                        setVisibilityOnView(Visibility.GONE);
-                        return;
-                    } else {
-                        throw new PietFatalException(ERR_MISSING_BINDING_VALUE,
-                                frameContext.reportMessage(MessageType.ERROR,
-                                        ERR_MISSING_BINDING_VALUE,
-                                        String.format("Chunked text binding %s had no content",
-                                                binding.getBindingId())));
-                    }
-                }
-                chunkedText = binding.getChunkedText();
-                break;
-            default:
-                throw new PietFatalException(ERR_MISSING_OR_UNHANDLED_CONTENT,
-                        frameContext.reportMessage(MessageType.ERROR,
-                                ERR_MISSING_OR_UNHANDLED_CONTENT,
-                                String.format("Unhandled type of TextElement; had content %s",
-                                        textLine.getContentCase())));
-        }
-        bindChunkedText(chunkedText, frameContext);
-    }
-
-    private void bindChunkedText(ChunkedText chunkedText, FrameContext frameContext) {
-        TextView textView = getBaseView();
-        SpannableStringBuilder spannable = new SpannableStringBuilder();
-        boolean hasTouchListener = false;
-        for (Chunk chunk : chunkedText.getChunksList()) {
-            int chunkStart = spannable.length();
-            switch (chunk.getContentCase()) {
-                case TEXT_CHUNK:
-                    addTextChunk(frameContext, spannable, chunk);
-                    break;
-                case IMAGE_CHUNK:
-                    addImageChunk(frameContext, textView, spannable, chunk);
-                    break;
-
-                default:
-                    throw new PietFatalException(ERR_MISSING_OR_UNHANDLED_CONTENT,
-                            String.format("Unhandled type of ChunkedText Chunk; had content %s",
-                                    chunk.getContentCase()));
-            }
-            int chunkEnd = spannable.length();
-            switch (chunk.getActionsDataCase()) {
-                case ACTIONS:
-                    setChunkActions(chunk.getActions(), spannable, textView, frameContext,
-                            chunkStart, chunkEnd, hasTouchListener);
-                    hasTouchListener = true;
-                    break;
-                case ACTIONS_BINDING:
-                    Actions boundActions =
-                            frameContext.getActionsFromBinding(chunk.getActionsBinding());
-                    if (boundActions == null) {
-                        break;
-                    }
-                    setChunkActions(boundActions, spannable, textView, frameContext, chunkStart,
-                            chunkEnd, hasTouchListener);
-                    hasTouchListener = true;
-                    break;
-                default:
-                    // No actions
-            }
-        }
-        textView.setText(spannable);
-    }
-
-    private void setChunkActions(Actions actions, SpannableStringBuilder spannable,
-            TextView textView, FrameContext frameContext, int chunkStart, int chunkEnd,
-            boolean hasTouchListener) {
-        // TODO: Also support long click actions.
-        if (actions.hasOnClickAction()) {
-            spannable.setSpan(new ActionsClickableSpan(actions.getOnClickAction(),
-                                      frameContext.getActionHandler(), frameContext.getFrame()),
-                    chunkStart, chunkEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-            if (!hasTouchListener) {
-                textView.setOnTouchListener(new ChunkedTextTouchListener(spannable));
-            }
-        }
-    }
-
-    @VisibleForTesting
-    void addTextChunk(FrameContext frameContext, SpannableStringBuilder spannable, Chunk chunk) {
-        int start = spannable.length();
-        ParameterizedText parameterizedText;
-        switch (chunk.getTextChunk().getContentCase()) {
-            case PARAMETERIZED_TEXT:
-                parameterizedText = chunk.getTextChunk().getParameterizedText();
-                break;
-            case PARAMETERIZED_TEXT_BINDING:
-                BindingValue textBindingValue = frameContext.getParameterizedTextBindingValue(
-                        chunk.getTextChunk().getParameterizedTextBinding());
-                parameterizedText = textBindingValue.getParameterizedText();
-                break;
-            default:
-                frameContext.reportMessage(MessageType.ERROR, ERR_MISSING_OR_UNHANDLED_CONTENT,
-                        String.format("StyledTextChunk missing ParameterizedText content; has %s",
-                                chunk.getTextChunk().getContentCase()));
-                parameterizedText = ParameterizedText.getDefaultInstance();
-        }
-        StyleProvider chunkStyle =
-                frameContext.makeStyleFor(chunk.getTextChunk().getStyleReferences());
-        if (chunkStyle.getMargins().hasStart()) {
-            addMargin(spannable, chunkStyle.getMargins().getStart());
-        }
-
-        CharSequence evaluatedText = getParameters().mTemplatedStringEvaluator.evaluate(
-                getParameters().mHostProviders.getAssetProvider(), parameterizedText);
-        spannable.append(evaluatedText);
-        if (chunkStyle.hasColor()) {
-            spannable.setSpan(new ForegroundColorSpan(chunkStyle.getColor()), start,
-                    spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-        }
-        if (chunkStyle.getFont().getItalic()) {
-            spannable.setSpan(new StyleSpan(Typeface.ITALIC), start, spannable.length(),
-                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-        }
-        if (chunkStyle.getFont().hasSize()) {
-            spannable.setSpan(new AbsoluteSizeSpan((int) LayoutUtils.spToPx(
-                                      chunkStyle.getFont().getSize(), getContext())),
-                    start, spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-        }
-        if (chunkStyle.getMaxLines() > 0) {
-            Logger.e(TAG,
-                    frameContext.reportMessage(MessageType.WARNING,
-                            ErrorCode.ERR_UNSUPPORTED_FEATURE,
-                            String.format("Ignoring max lines parameter set to '%s';"
-                                            + " not supported on chunks.",
-                                    chunkStyle.getMaxLines())));
-        }
-
-        if (chunkStyle.getMargins().hasEnd()) {
-            addMargin(spannable, chunkStyle.getMargins().getEnd());
-        }
-    }
-
-    @VisibleForTesting
-    void addImageChunk(FrameContext frameContext, TextView textView,
-            SpannableStringBuilder spannable, Chunk chunk) {
-        StyledImageChunk imageChunk = chunk.getImageChunk();
-        Image image;
-        switch (imageChunk.getContentCase()) {
-            case IMAGE:
-                image = imageChunk.getImage();
-                break;
-            case IMAGE_BINDING:
-                ImageBindingRef imageBinding = imageChunk.getImageBinding();
-                BindingValue imageBindingValue = frameContext.getImageBindingValue(imageBinding);
-                if (!imageBindingValue.hasImage()) {
-                    if (!imageBinding.getIsOptional()) {
-                        frameContext.reportMessage(MessageType.ERROR, ERR_MISSING_BINDING_VALUE,
-                                String.format("No image found for binding id: %s",
-                                        imageBinding.getBindingId()));
-                    }
-                    return;
-                }
-                image = imageBindingValue.getImage();
-                break;
-            default:
-                frameContext.reportMessage(MessageType.ERROR, ERR_MISSING_OR_UNHANDLED_CONTENT,
-                        String.format("StyledImageChunk missing Image content; has %s",
-                                imageChunk.getContentCase()));
-                return;
-        }
-
-        image = frameContext.filterImageSourcesByMediaQueryCondition(image);
-
-        StyleProvider chunkStyle = frameContext.makeStyleFor(imageChunk.getStyleReferences());
-
-        // Set a placeholder empty image
-        Drawable placeholder = null;
-        if (chunkStyle.hasPreLoadFill()) {
-            placeholder = chunkStyle.createPreLoadFill();
-        }
-        if (placeholder == null) {
-            placeholder = new ColorDrawable(Color.TRANSPARENT);
-        }
-        LayerDrawable wrapper = new LayerDrawable(new Drawable[] {placeholder});
-        wrapper.setId(0, SINGLE_LAYER_ID);
-        setBounds(wrapper, chunkStyle, textView);
-        ImageSpan imageSpan = new ImageSpan(wrapper, ImageSpan.ALIGN_BASELINE);
-
-        if (chunkStyle.getMargins().hasStart()) {
-            addMargin(spannable, chunkStyle.getMargins().getStart());
-        }
-
-        spannable.append(" "); // dummy space to overwrite
-        spannable.setSpan(imageSpan, spannable.length() - 1, spannable.length(),
-                Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
-
-        if (chunkStyle.getMargins().hasEnd()) {
-            addMargin(spannable, chunkStyle.getMargins().getEnd());
-        }
-
-        // Start asynchronously loading the real image.
-        Integer overlayColor = chunkStyle.hasColor() ? chunkStyle.getColor() : null;
-        ImageSpanDrawableCallback imageSpanLoader =
-                new ImageSpanDrawableCallback(wrapper, chunkStyle, overlayColor, textView);
-        mLoadingImages.add(imageSpanLoader);
-        int styleWidth = styleToImageDim(chunkStyle.getWidthSpecPx(getContext()));
-        int styleHeight = styleToImageDim(chunkStyle.getHeightSpecPx(getContext()));
-        getParameters().mHostProviders.getAssetProvider().getImage(
-                image, styleWidth, styleHeight, imageSpanLoader);
-    }
-
-    @Override
-    void onUnbindModel() {
-        for (ImageSpanDrawableCallback imageLoader : mLoadingImages) {
-            imageLoader.cancelCallback();
-        }
-        mLoadingImages.clear();
-        super.onUnbindModel();
-    }
-
-    private void addMargin(SpannableStringBuilder spannable, int marginDp) {
-        ColorDrawable spacer = new ColorDrawable(Color.TRANSPARENT);
-        int width = (int) LayoutUtils.dpToPx(marginDp, getContext());
-        spacer.setBounds(0, 0, width, 1);
-        ImageSpan margin = new ImageSpan(spacer);
-        spannable.append(" ");
-        spannable.setSpan(margin, spannable.length() - 1, spannable.length(),
-                Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
-    }
-
-    /**
-     * Sets the width and height of the drawable based on the {@code imageStyle}, preserving aspect
-     * ratio. If no dimensions are set in the style, defaults to matching the line height of the
-     * {@code textView}.
-     */
-    @VisibleForTesting
-    void setBounds(Drawable imageDrawable, StyleProvider imageStyle, TextView textView) {
-        int lineHeight = textView.getLineHeight();
-
-        int styleHeight = styleToImageDim(imageStyle.getHeightSpecPx(getContext()));
-        int styleWidth = styleToImageDim(imageStyle.getWidthSpecPx(getContext()));
-
-        int height;
-        int width;
-        if (styleHeight >= 0 && styleWidth >= 0) {
-            // Scale the image to exactly this size.
-            height = styleHeight;
-            width = styleWidth;
-        } else if (styleWidth >= 0) {
-            // Set the width, and preserve aspect ratio.
-            width = styleWidth;
-            height = (int) (imageDrawable.getIntrinsicHeight()
-                    * ((float) width / imageDrawable.getIntrinsicWidth()));
-        } else {
-            // Default to making the image the same height as the text, preserving aspect ratio.
-            height = styleHeight >= 0 ? styleHeight : lineHeight;
-            width = (int) (imageDrawable.getIntrinsicWidth()
-                    * ((float) height / imageDrawable.getIntrinsicHeight()));
-        }
-
-        imageDrawable.setBounds(0, 0, width, height);
-    }
-
-    private int styleToImageDim(int styleDimensionInPx) {
-        return styleDimensionInPx < 0 ? DIMENSION_UNKNOWN : styleDimensionInPx;
-    }
-
-    static class ActionsClickableSpan extends ClickableSpan {
-        private final Action mAction;
-        private final ActionHandler mHandler;
-        private final Frame mFrame;
-
-        ActionsClickableSpan(Action action, ActionHandler handler, Frame frame) {
-            this.mAction = action;
-            this.mHandler = handler;
-            this.mFrame = frame;
-        }
-
-        @Override
-        public void onClick(View widget) {
-            // TODO: Pass VE information with the action.
-            mHandler.handleAction(
-                    mAction, ActionType.CLICK, mFrame, widget, LogData.getDefaultInstance());
-        }
-
-        @Override
-        public void updateDrawState(TextPaint textPaint) {
-            textPaint.setUnderlineText(false);
-        }
-    }
-
-    /**
-     * Triggers click handlers when text is touched; copied from LinkMovementMethod.onTouchEvent.
-     *
-     * <p>We can't use LinkMovementMethod because that makes the TextView scrollable (relevant when
-     * max_lines is set). We could extend TextView and override onScroll to no-op, but ellipsizing
-     * will still be broken in that case.
-     */
-    static class ChunkedTextTouchListener implements View.OnTouchListener {
-        private final SpannableStringBuilder mSpannable;
-
-        ChunkedTextTouchListener(SpannableStringBuilder spannable) {
-            this.mSpannable = spannable;
-        }
-
-        @Override
-        public boolean onTouch(View widget, MotionEvent event) {
-            int action = event.getAction();
-
-            if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
-                TextView textView = (TextView) widget;
-                int x = (int) event.getX();
-                int y = (int) event.getY();
-
-                x -= textView.getTotalPaddingLeft();
-                y -= textView.getTotalPaddingTop();
-
-                x += textView.getScrollX();
-                y += textView.getScrollY();
-
-                Layout layout = textView.getLayout();
-                int line = layout.getLineForVertical(y);
-                int off = layout.getOffsetForHorizontal(line, x);
-
-                ClickableSpan[] links = mSpannable.getSpans(off, off, ClickableSpan.class);
-
-                if (links.length != 0) {
-                    if (action == MotionEvent.ACTION_UP) {
-                        links[0].onClick(textView);
-                    }
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
-    @VisibleForTesting
-    class ImageSpanDrawableCallback implements Consumer<Drawable> {
-        private final LayerDrawable mWrapper;
-        private final StyleProvider mImageStyle;
-        @Nullable
-        private final Integer mOverlayColor;
-        private final TextView mTextView;
-        private boolean mCancelled;
-
-        ImageSpanDrawableCallback(LayerDrawable wrapper, StyleProvider imageStyle,
-                @Nullable Integer overlayColor, TextView textView) {
-            this.mWrapper = wrapper;
-            this.mImageStyle = imageStyle;
-            this.mOverlayColor = overlayColor;
-            this.mTextView = textView;
-        }
-
-        @Override
-        public void accept(@Nullable Drawable imageDrawable) {
-            if (mCancelled || imageDrawable == null) {
-                return;
-            }
-            Drawable finalDrawable = ViewUtils.applyOverlayColor(imageDrawable, mOverlayColor);
-            checkState(mWrapper.setDrawableByLayerId(SINGLE_LAYER_ID, finalDrawable),
-                    "Failed to set drawable on chunked text");
-            setBounds(finalDrawable, mImageStyle, mTextView);
-            setBounds(mWrapper, mImageStyle, mTextView);
-            mTextView.invalidate();
-            mLoadingImages.remove(this);
-        }
-
-        void cancelCallback() {
-            mCancelled = true;
-        }
-    }
-
-    static class KeySupplier extends TextElementKeySupplier<ChunkedTextElementAdapter> {
-        @Override
-        public String getAdapterTag() {
-            return TAG;
-        }
-
-        @Override
-        public ChunkedTextElementAdapter getAdapter(Context context, AdapterParameters parameters) {
-            return new ChunkedTextElementAdapter(context, parameters);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/CustomElementAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/CustomElementAdapter.java
deleted file mode 100644
index 93497c4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/CustomElementAdapter.java
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.content.Context;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.piet.AdapterFactory.SingletonKeySupplier;
-import org.chromium.chrome.browser.feed.library.piet.DebugLogger.MessageType;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.BindingValue;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.CustomElement;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.CustomElementData;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Element;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Visibility;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-
-/** Adapter that manages a custom view created by the host. */
-class CustomElementAdapter extends ElementAdapter<FrameLayout, CustomElement> {
-    private static final String TAG = "CustomElementAdapter";
-    CustomElementData mBoundCustomElementData = CustomElementData.getDefaultInstance();
-
-    CustomElementAdapter(Context context, AdapterParameters parameters) {
-        super(context, parameters, new FrameLayout(context), KeySupplier.SINGLETON_KEY);
-    }
-
-    @Override
-    protected CustomElement getModelFromElement(Element baseElement) {
-        if (!baseElement.hasCustomElement()) {
-            throw new PietFatalException(ErrorCode.ERR_MISSING_ELEMENT_CONTENTS,
-                    String.format("Missing CustomElement; has %s", baseElement.getElementsCase()));
-        }
-        return baseElement.getCustomElement();
-    }
-
-    @Override
-    void onBindModel(CustomElement customElement, Element baseElement, FrameContext frameContext) {
-        switch (customElement.getContentCase()) {
-            case CUSTOM_ELEMENT_DATA:
-                mBoundCustomElementData = customElement.getCustomElementData();
-                break;
-            case CUSTOM_BINDING:
-                BindingValue binding =
-                        frameContext.getCustomElementBindingValue(customElement.getCustomBinding());
-                if (!binding.hasCustomElementData()) {
-                    if (customElement.getCustomBinding().getIsOptional()) {
-                        setVisibilityOnView(Visibility.GONE);
-                        return;
-                    } else {
-                        throw new PietFatalException(ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                                frameContext.reportMessage(MessageType.ERROR,
-                                        ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                                        String.format("Custom element binding %s had no content",
-                                                binding.getBindingId())));
-                    }
-                }
-                mBoundCustomElementData = binding.getCustomElementData();
-                break;
-            default:
-                Logger.e(TAG,
-                        frameContext.reportMessage(MessageType.ERROR,
-                                ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                                "Missing payload in CustomElement"));
-                return;
-        }
-
-        View v = getParameters().mHostProviders.getCustomElementProvider().createCustomElement(
-                mBoundCustomElementData);
-        getBaseView().addView(v);
-    }
-
-    @Override
-    void onUnbindModel() {
-        FrameLayout baseView = getBaseView();
-        // There should be a maximum of one child that was bound, so using the CustomElementData
-        // that was saved during the last bind should be fine.
-        if (baseView != null && baseView.getChildCount() > 0) {
-            for (int i = 0; i < baseView.getChildCount(); i++) {
-                getParameters().mHostProviders.getCustomElementProvider().releaseCustomView(
-                        baseView.getChildAt(i), mBoundCustomElementData);
-            }
-            baseView.removeAllViews();
-        }
-    }
-
-    static class KeySupplier extends SingletonKeySupplier<CustomElementAdapter, CustomElement> {
-        @Override
-        public String getAdapterTag() {
-            return TAG;
-        }
-
-        @Override
-        public CustomElementAdapter getAdapter(Context context, AdapterParameters parameters) {
-            return new CustomElementAdapter(context, parameters);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/DebugLogger.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/DebugLogger.java
deleted file mode 100644
index 7372a41d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/DebugLogger.java
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.content.Context;
-import android.util.SparseArray;
-import android.util.SparseIntArray;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.core.widget.TextViewCompat;
-
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.library.common.ui.LayoutUtils;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/** Utility class for collecting and displaying debug information. */
-class DebugLogger {
-    // Formatting parameters for report views:
-    private static final int PADDING = 4;
-    private static final int SIDE_PADDING = 16;
-    private static final int DIVIDER_COLOR = 0x65000000;
-
-    private static final int ERROR_BACKGROUND_COLOR = 0xFFEF9A9A;
-    private static final int WARNING_BACKGROUND_COLOR = 0xFFFFFF66;
-
-    @VisibleForTesting
-    static final int ERROR_DIVIDER_WIDTH_DP = 1;
-
-    /** What kind of error are we reporting when calling {@link #recordMessage(int, String)}. */
-    @IntDef({MessageType.ERROR, MessageType.WARNING})
-    @interface MessageType {
-        int ERROR = 1;
-        int WARNING = 2;
-    }
-
-    private final SparseArray<List<ErrorCodeAndMessage>> mMessages;
-    private final SparseIntArray mBackgroundColors;
-
-    DebugLogger() {
-        mMessages = new SparseArray<>();
-        mMessages.put(MessageType.ERROR, new ArrayList<>());
-        mMessages.put(MessageType.WARNING, new ArrayList<>());
-
-        mBackgroundColors = new SparseIntArray();
-        mBackgroundColors.put(MessageType.ERROR, ERROR_BACKGROUND_COLOR);
-        mBackgroundColors.put(MessageType.WARNING, WARNING_BACKGROUND_COLOR);
-    }
-
-    // TODO: Deprecate this version to reduce the use of ERR_UNSPECIFIED.
-    void recordMessage(@MessageType int messageType, String error) {
-        recordMessage(messageType, ErrorCode.ERR_UNSPECIFIED, error);
-    }
-
-    void recordMessage(@MessageType int messageType, ErrorCode errorCode, String error) {
-        mMessages.get(messageType).add(new ErrorCodeAndMessage(errorCode, error));
-    }
-
-    /**
-     * Create a {@code View} containing all the messages of a certain type; null for no messages.
-     */
-    @Nullable
-    View getReportView(@MessageType int messageType, Context context) {
-        List<ErrorCodeAndMessage> errors = this.mMessages.get(messageType);
-        if (errors.isEmpty()) {
-            return null;
-        }
-        LinearLayout view = new LinearLayout(context);
-        view.setOrientation(LinearLayout.VERTICAL);
-        LayoutParams layoutParams =
-                new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
-        view.setLayoutParams(layoutParams);
-        view.setBackgroundColor(mBackgroundColors.get(messageType));
-        view.addView(getDivider(context));
-        for (ErrorCodeAndMessage error : errors) {
-            view.addView(getMessageTextView(error.mMessage, context));
-        }
-        return view;
-    }
-
-    @VisibleForTesting
-    List<ErrorCodeAndMessage> getMessages(@MessageType int messageType) {
-        return mMessages.get(messageType);
-    }
-
-    List<ErrorCode> getErrorCodes() {
-        ArrayList<ErrorCode> errorCodes = new ArrayList<>();
-        for (int i = 0; i < mMessages.size(); i++) {
-            for (ErrorCodeAndMessage errorCodeAndMessage : mMessages.valueAt(i)) {
-                errorCodes.add(errorCodeAndMessage.mErrorCode);
-            }
-        }
-        errorCodes.trimToSize();
-        return Collections.unmodifiableList(errorCodes);
-    }
-
-    private View getDivider(Context context) {
-        View v = new View(context);
-        LayoutParams layoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
-                (int) LayoutUtils.dpToPx(ERROR_DIVIDER_WIDTH_DP, context));
-        v.setLayoutParams(layoutParams);
-        v.setBackgroundColor(DIVIDER_COLOR);
-        return v;
-    }
-
-    private TextView getMessageTextView(String message, Context context) {
-        TextView textView = new TextView(context);
-        TextViewCompat.setTextAppearance(textView, R.style.gm_font_weight_regular);
-        textView.setPadding((int) LayoutUtils.dpToPx(SIDE_PADDING, context),
-                (int) LayoutUtils.dpToPx(PADDING, context),
-                (int) LayoutUtils.dpToPx(SIDE_PADDING, context),
-                (int) LayoutUtils.dpToPx(PADDING, context));
-        textView.setText(message);
-        return textView;
-    }
-
-    /** Simple class to hold an error code and message pair. */
-    static class ErrorCodeAndMessage {
-        final ErrorCode mErrorCode;
-        final String mMessage;
-
-        ErrorCodeAndMessage(ErrorCode errorCode, String message) {
-            this.mErrorCode = errorCode;
-            this.mMessage = message;
-        }
-
-        @Override
-        public boolean equals(@Nullable Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (!(o instanceof ErrorCodeAndMessage)) {
-                return false;
-            }
-
-            ErrorCodeAndMessage that = (ErrorCodeAndMessage) o;
-
-            if (mErrorCode != that.mErrorCode) {
-                return false;
-            }
-            return mMessage.equals(that.mMessage);
-        }
-
-        @Override
-        public int hashCode() {
-            int result = mErrorCode.hashCode();
-            result = 31 * result + mMessage.hashCode();
-            return result;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementAdapter.java
deleted file mode 100644
index 723def2..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementAdapter.java
+++ /dev/null
@@ -1,580 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-import static org.chromium.chrome.browser.feed.library.piet.StyleProvider.DIMENSION_NOT_SET;
-
-import android.content.Context;
-import android.os.Build;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.widget.FrameLayout;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.piet.DebugLogger.MessageType;
-import org.chromium.chrome.browser.feed.library.piet.host.LogDataCallback;
-import org.chromium.chrome.browser.feed.library.piet.ui.RoundedCornerWrapperView;
-import org.chromium.components.feed.core.proto.ui.piet.AccessibilityProto.Accessibility;
-import org.chromium.components.feed.core.proto.ui.piet.AccessibilityProto.AccessibilityRole;
-import org.chromium.components.feed.core.proto.ui.piet.ActionsProto.Actions;
-import org.chromium.components.feed.core.proto.ui.piet.ActionsProto.VisibilityAction;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.BindingValue;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Element;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Visibility;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.VisibilityState;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-import org.chromium.components.feed.core.proto.ui.piet.LogDataProto.LogData;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.StyleIdsStack;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * ElementAdapter provides a base class for the various adapters created by UiElement, and provides
- * handling for overlays and any other general UiElement features. This class enforces the life
- * cycle of the BoundViewAdapter.
- *
- * @param <V> A subclass of an Android View. This is the root level view the adapter is responsible
- *     for creating. Once created, it should have the same lifetime as the adapter.
- * @param <M> The model. This is the model type which is bound to the view by the adapter.
- */
-abstract class ElementAdapter<V extends View, M> {
-    private static final String TAG = "ElementAdapter";
-    private final Context mContext;
-    private final AdapterParameters mParameters;
-    private final V mView;
-    @Nullable
-    private M mModel;
-    private Element mBaseElement = Element.getDefaultInstance();
-    @Nullable
-    private RecyclerKey mKey;
-    private StyleProvider mElementStyle;
-    @Nullable
-    private LogData mLogData;
-
-    /**
-     * Set to {@code true} when {@link #createAdapter} has completed successfully; unset at the end
-     * of
-     * {@link #releaseAdapter}.
-     */
-    private boolean mCreated;
-
-    /**
-     * We only check the bound visibility when we're in the process of binding, not in {@link
-     * #createAdapter}.
-     */
-    private boolean mCheckBoundVisibility;
-
-    @Nullable
-    private FrameLayout mWrapperView;
-
-    Actions mActions = Actions.getDefaultInstance();
-    /** Set of actions that are currently active / triggered so they only get called once. */
-    private final Set<VisibilityAction> mActiveVisibilityActions = new HashSet<>();
-
-    /**
-     * Desired width of this element. {@link StyleProvider#DIMENSION_NOT_SET} indicates no explicit
-     * width; let the parent view decide.
-     */
-    int mWidthPx = DIMENSION_NOT_SET;
-    /**
-     * Desired height of this element. {@link StyleProvider#DIMENSION_NOT_SET} indicates no explicit
-     * height; let the parent view decide.
-     */
-    int mHeightPx = DIMENSION_NOT_SET;
-
-    ElementAdapter(Context context, AdapterParameters parameters, V view) {
-        this.mContext = context;
-        this.mParameters = parameters;
-        this.mView = view;
-        mElementStyle = parameters.mDefaultStyleProvider;
-    }
-
-    ElementAdapter(Context context, AdapterParameters parameters, V view, RecyclerKey key) {
-        this(context, parameters, view);
-        this.mKey = key;
-    }
-
-    /**
-     * Returns the View bound to the Adapter, for external use, such as adding to a layout. This is
-     * not a valid call until the first Model has been bound to the Adapter.
-     */
-    public View getView() {
-        return mWrapperView != null ? mWrapperView : mView;
-    }
-
-    /**
-     * Returns the base view of the adapter; the view typed to the subclass's content. This returns
-     * a different result than getView when there is a wrapper FrameLayout to support overlays.
-     */
-    protected V getBaseView() {
-        return mView;
-    }
-
-    /**
-     * Sets up an adapter, but does not bind data. After this, the {@link #getView()} and {@link
-     * #getKey()} can be called. This method must not be called if a Model is currently bound to the
-     * Adapter; call {@link #releaseAdapter()} first. Do not override; override {@link
-     * #onCreateAdapter} instead.
-     */
-    public void createAdapter(Element baseElement, FrameContext frameContext) {
-        M model = getModelFromElement(baseElement);
-        createAdapter(model, baseElement, frameContext);
-    }
-
-    /**
-     * Sets up an adapter, but does not bind data. After this, the {@link #getView()} and {@link
-     * #getKey()} can be called. This method must not be called if a Model is currently bound to the
-     * Adapter; call {@link #releaseAdapter()} first. Do not override; override {@link
-     * #onCreateAdapter} instead.
-     */
-    public void createAdapter(M model, Element baseElement, FrameContext frameContext) {
-        this.mModel = model;
-        this.mBaseElement = baseElement;
-
-        // Initialize the wrapper view before checking visibility - we need to have it in place
-        // before the parent adds our outermost view to the hierarchy.
-        mElementStyle = frameContext.makeStyleFor(getElementStyleIdsStack());
-        initializeWrapperViewDependentFeatures();
-
-        Visibility visibility = getVisibilityForElement(baseElement, frameContext);
-        setVisibilityOnView(visibility);
-        if (visibility == Visibility.GONE) {
-            return;
-        }
-
-        setDesiredDimensions();
-
-        onCreateAdapter(model, baseElement, frameContext);
-
-        initializeOverflow(baseElement);
-
-        mElementStyle.applyElementStyles(this);
-        mCreated = true;
-    }
-
-    private void initializeWrapperViewDependentFeatures() {
-        if (mWrapperView != null) {
-            // We have already initialized the wrapper view.
-            return;
-        }
-        if (!mElementStyle.hasRoundedCorners() && !mElementStyle.hasBorders()) {
-            // We do not need a wrapper view.
-            return;
-        }
-
-        FrameLayout wrapper = mElementStyle.createWrapperView(mContext,
-                mParameters.mRoundedCornerMaskCache, mParameters.mAllowLegacyRoundedCornerImpl,
-                mParameters.mAllowOutlineRoundedCornerImpl);
-        wrapper.addView(getBaseView());
-
-        if (!(wrapper instanceof RoundedCornerWrapperView)) {
-            mElementStyle.addBordersWithoutRoundedCorners(wrapper, getContext());
-        }
-
-        mWrapperView = wrapper;
-    }
-
-    /** Performs child-class-specific adapter creation; to be overridden. */
-    void onCreateAdapter(M model, Element baseElement, FrameContext frameContext) {}
-
-    /**
-     * Binds data from a Model to the Adapter, without changing child views or styles. Do not
-     * override; override {@link #onBindModel} instead. Binds to an Element, allowing the subclass
-     * to pick out the relevant model from the oneof.
-     */
-    public void bindModel(Element baseElement, FrameContext frameContext) {
-        bindModel(getModelFromElement(baseElement), baseElement, frameContext);
-    }
-
-    /** Bind the model and initialize overlays. Calls child {@link #onBindModel} methods. */
-    void bindModel(M model, Element baseElement, FrameContext frameContext) {
-        this.mModel = model;
-        this.mBaseElement = baseElement;
-        mCheckBoundVisibility = true;
-        if (getElementStyleIdsStack().hasStyleBinding()) {
-            mElementStyle = frameContext.makeStyleFor(getElementStyleIdsStack());
-        }
-
-        Visibility visibility = getVisibilityForElement(baseElement, frameContext);
-        setVisibilityOnView(visibility);
-        if (visibility == Visibility.GONE) {
-            return;
-        }
-        if (!mCreated) {
-            createAdapter(model, baseElement, frameContext);
-        }
-        if (!mCreated) {
-            // This should not happen; indicates a problem in the logic if createAdapter here runs
-            // without successfully creating the adapter.
-            throw new PietFatalException(ErrorCode.ERR_UNSPECIFIED,
-                    frameContext.reportMessage(MessageType.ERROR, "Binding uncreated adapter"));
-        }
-
-        onBindModel(model, baseElement, frameContext);
-        // Sometimes, onBindModel will short-circuit and set the visibility to GONE (ex. when an
-        // optional binding is not found). In that case, we don't want to continue binding.
-        if (getView().getVisibility() == View.GONE) {
-            return;
-        }
-
-        bindActions(frameContext);
-
-        // Reapply styles if we have style bindings
-        if (getElementStyleIdsStack().hasStyleBinding()) {
-            mElementStyle.applyElementStyles(this);
-        }
-        for (AccessibilityRole role : baseElement.getAccessibility().getRolesList()) {
-            switch (role) {
-                case HEADER:
-                    getBaseView().setImportantForAccessibility(
-                            View.IMPORTANT_FOR_ACCESSIBILITY_YES);
-                    getBaseView().setFocusable(true);
-                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
-                        getBaseView().setAccessibilityDelegate(new View.AccessibilityDelegate() {
-                            @Override
-                            public void onInitializeAccessibilityNodeInfo(
-                                    View host, AccessibilityNodeInfo info) {
-                                super.onInitializeAccessibilityNodeInfo(host, info);
-                                info.setHeading(true);
-                            }
-                        });
-                    } else {
-                        getBaseView().setAccessibilityDelegate(new View.AccessibilityDelegate() {
-                            @Override
-                            public void onInitializeAccessibilityNodeInfo(
-                                    View host, AccessibilityNodeInfo info) {
-                                super.onInitializeAccessibilityNodeInfo(host, info);
-                                info.setCollectionItemInfo(
-                                        AccessibilityNodeInfo.CollectionItemInfo.obtain(
-                                                -1, 0, 0, 0, true));
-                            }
-                        });
-                    }
-                    break;
-                default:
-                    // Do nothing
-            }
-        }
-
-        CharSequence contentDescription =
-                getAccessibilityString(baseElement.getAccessibility(), frameContext);
-        if (contentDescription.length() > 0) {
-            getBaseView().setContentDescription(contentDescription);
-        } else {
-            getBaseView().setContentDescription(null);
-        }
-        LogDataCallback callback = mParameters.mHostProviders.getLogDataCallback();
-        if (callback != null) {
-            switch (baseElement.getLogDataValueCase()) {
-                case LOG_DATA:
-                    mLogData = baseElement.getLogData();
-                    break;
-                case LOG_DATA_REF:
-                    // Get the logData from the binding in the template
-                    mLogData = frameContext.getLogDataFromBinding(baseElement.getLogDataRef());
-                    break;
-                default: // No log Data
-            }
-            if (mLogData != null) {
-                callback.onBind(mLogData, getView());
-            }
-        }
-    }
-
-    private CharSequence getAccessibilityString(
-            Accessibility accessibility, FrameContext frameContext) {
-        switch (accessibility.getDescriptionDataCase()) {
-            case DESCRIPTION:
-                return getTemplatedStringEvaluator().evaluate(
-                        mParameters.mHostProviders.getAssetProvider(),
-                        accessibility.getDescription());
-            case DESCRIPTION_BINDING:
-                BindingValue bindingValue = frameContext.getParameterizedTextBindingValue(
-                        accessibility.getDescriptionBinding());
-                if (bindingValue.hasParameterizedText()) {
-                    return getTemplatedStringEvaluator().evaluate(
-                            mParameters.mHostProviders.getAssetProvider(),
-                            bindingValue.getParameterizedText());
-                }
-                // fall through
-            default:
-                return "";
-        }
-    }
-
-    /** Extracts the relevant model from the Element oneof. Throws IllegalArgument if not found. */
-    abstract M getModelFromElement(Element baseElement);
-
-    /** Performs child-adapter-specific binding logic; to be overridden. */
-    void onBindModel(M model, Element baseElement, FrameContext frameContext) {}
-
-    void bindActions(FrameContext frameContext) {
-        // Set up actions. On the server, they are defined either as the actual action, or an
-        // "actions_binding". That actions_binding is defined in a template, and the binding value
-        // is then looked up in the template invocation.
-        switch (mBaseElement.getActionsDataCase()) {
-            case ACTIONS:
-                mActions = mBaseElement.getActions();
-                ViewUtils.setOnClickActions(
-                        mActions, getBaseView(), frameContext, mBaseElement.getLogData());
-                break;
-            case ACTIONS_BINDING:
-                // Get the actions from the actions_binding in the template
-                mActions = frameContext.getActionsFromBinding(mBaseElement.getActionsBinding());
-                ViewUtils.setOnClickActions(
-                        mActions, getBaseView(), frameContext, mBaseElement.getLogData());
-                break;
-            default: // No actions defined.
-                mActions = Actions.getDefaultInstance();
-                ViewUtils.clearOnClickActions(getBaseView());
-                ViewUtils.clearOnLongClickActions(getBaseView());
-        }
-        setHideActionsActive();
-    }
-
-    /** Intended to be called in onCreate when view is offscreen; sets hide actions to active. */
-    void setHideActionsActive() {
-        mActiveVisibilityActions.clear();
-        // Set all "hide" actions as active, since the view is currently off screen.
-        mActiveVisibilityActions.addAll(mActions.getOnHideActionsList());
-    }
-
-    private static void initializeOverflow(Element baseElement) {
-        switch (baseElement.getHorizontalOverflow()) {
-            case OVERFLOW_HIDDEN:
-            case OVERFLOW_UNSPECIFIED:
-                // These are the default behavior
-                break;
-            default:
-                // TODO: Use the standard Piet error codes: ERR_UNSUPPORTED_FEATURE
-                Logger.w(TAG, "Unsupported overflow behavior: %s",
-                        baseElement.getHorizontalOverflow());
-        }
-    }
-
-    /**
-     * Gets the style of the Element's content (ex. TextElement). Only valid after model has been
-     * bound.
-     */
-    StyleProvider getElementStyle() {
-        if (mModel == null) {
-            Logger.wtf(TAG, "getElementStyle called when adapter is not bound");
-        }
-        return mElementStyle;
-    }
-
-    /** Returns any styles associated with the bound Element. */
-    StyleIdsStack getElementStyleIdsStack() {
-        return mBaseElement.getStyleReferences();
-    }
-
-    /**
-     * Unbinds the current Model from the Adapter. The Adapter will unbind all contained Adapters
-     * recursively. Do not override; override {@link #onUnbindModel} instead.
-     */
-    public void unbindModel() {
-        // If the visibility was GONE, we may not have ever called onBindModel.
-        if (mCreated) {
-            onUnbindModel();
-        }
-        LogDataCallback callback = mParameters.mHostProviders.getLogDataCallback();
-        if (callback != null && mLogData != null) {
-            callback.onUnbind(mLogData, getView());
-            mLogData = null;
-        }
-        mModel = null;
-        mBaseElement = Element.getDefaultInstance();
-        mCheckBoundVisibility = false;
-
-        // Unset actions
-        ViewUtils.clearOnLongClickActions(getBaseView());
-        ViewUtils.clearOnClickActions(getBaseView());
-    }
-
-    /** Performs child-adapter-specific unbind logic; to be overridden. */
-    void onUnbindModel() {}
-
-    /**
-     * Releases all child adapters to recycler pools. Do not override; override {@link
-     * #onReleaseAdapter} instead.
-     */
-    public void releaseAdapter() {
-        if (!mCreated) {
-            return;
-        }
-
-        onReleaseAdapter();
-
-        // Destroy overlays
-        if (mWrapperView != null) {
-            mWrapperView.removeAllViews();
-            mWrapperView = null;
-        }
-
-        setVisibilityOnView(Visibility.VISIBLE);
-
-        mWidthPx = DIMENSION_NOT_SET;
-        mHeightPx = DIMENSION_NOT_SET;
-
-        mCreated = false;
-    }
-
-    /** Performs child-adapter-specific release logic; to be overridden. */
-    void onReleaseAdapter() {}
-
-    /**
-     * Subclasses will call this method when they are first bound to a Model to set the Key based
-     * upon the Model type.
-     */
-    void setKey(RecyclerKey key) {
-        this.mKey = key;
-    }
-
-    /** Returns a {@link RecyclerKey} which represents an instance of a Model based upon a type. */
-    @Nullable
-    public RecyclerKey getKey() {
-        // There are Adapters which don't hold on to their views.  How do we want to mark them?
-        return mKey;
-    }
-
-    /**
-     * Returns the desired width of the adapter, computed from the model at bind time, or {@link
-     * StyleProvider#DIMENSION_NOT_SET} which implies that the parent can choose the width.
-     */
-    int getComputedWidthPx() {
-        return mWidthPx;
-    }
-
-    /**
-     * Returns the desired height of the adapter, computed from the model at bind time, or {@link
-     * StyleProvider#DIMENSION_NOT_SET} which implies that the parent can choose the height.
-     */
-    int getComputedHeightPx() {
-        return mHeightPx;
-    }
-
-    /** Sets the adapter's desired dimensions based on the style. */
-    private void setDesiredDimensions() {
-        mWidthPx = mElementStyle.getWidthSpecPx(mContext);
-        mHeightPx = mElementStyle.getHeightSpecPx(mContext);
-    }
-
-    /** Sets the layout parameters on this adapter's view. */
-    public void setLayoutParams(LayoutParams layoutParams) {
-        View view = getView();
-        if (view == null) {
-            return;
-        }
-        view.setLayoutParams(layoutParams);
-        View baseView = getBaseView();
-        if (baseView != null && baseView != view) {
-            int height = layoutParams.height == LayoutParams.WRAP_CONTENT
-                    ? LayoutParams.WRAP_CONTENT
-                    : LayoutParams.MATCH_PARENT;
-            int width = layoutParams.width == LayoutParams.WRAP_CONTENT ? LayoutParams.WRAP_CONTENT
-                                                                        : LayoutParams.MATCH_PARENT;
-            baseView.setLayoutParams(new FrameLayout.LayoutParams(width, height));
-        }
-    }
-
-    AdapterParameters getParameters() {
-        return mParameters;
-    }
-
-    Context getContext() {
-        return mContext;
-    }
-
-    /** Returns the {@code model}, but is only legal to call when the Adapter is bound to a model */
-    M getModel() {
-        return checkNotNull(mModel);
-    }
-
-    /** Returns the {@code model}, or null if the adapter is not bound. */
-    @Nullable
-    M getRawModel() {
-        return mModel;
-    }
-
-    /** Return the Element's desired vertical placement within its container. */
-    int getVerticalGravity(int defaultGravity) {
-        if (mModel == null) {
-            return defaultGravity;
-        }
-        return getElementStyle().getGravityVertical(defaultGravity);
-    }
-
-    /** Return the Element's desired horizontal placement within its container. */
-    int getHorizontalGravity(int defaultGravity) {
-        if (mModel == null) {
-            return defaultGravity;
-        }
-        return getElementStyle().getGravityHorizontal(defaultGravity);
-    }
-
-    /** Return the Element's desired horizontal and vertical placement within its container. */
-    int getGravity(int defaultGravity) {
-        if (mModel == null) {
-            return defaultGravity;
-        }
-        return getElementStyle().getGravity(defaultGravity);
-    }
-
-    ParameterizedTextEvaluator getTemplatedStringEvaluator() {
-        return mParameters.mTemplatedStringEvaluator;
-    }
-
-    @VisibleForTesting
-    Visibility getVisibilityForElement(Element element, FrameContext frameContext) {
-        VisibilityState visibilityState = element.getVisibilityState();
-        if (mCheckBoundVisibility && visibilityState.hasOverridingBoundVisibility()) {
-            @Nullable
-            Visibility overridingVisibility = frameContext.getVisibilityFromBinding(
-                    visibilityState.getOverridingBoundVisibility());
-            if (overridingVisibility != null) {
-                return overridingVisibility;
-            }
-        }
-        return visibilityState.getDefaultVisibility();
-    }
-
-    void setVisibilityOnView(Visibility visibility) {
-        setVisibilityOnView(visibility, getView());
-        if (getView() != getBaseView()) {
-            setVisibilityOnView(visibility, getBaseView());
-        }
-    }
-
-    private static void setVisibilityOnView(Visibility visibility, View view) {
-        switch (visibility) {
-            case INVISIBLE:
-                view.setVisibility(View.INVISIBLE);
-                break;
-            case GONE:
-                view.setVisibility(View.GONE);
-                break;
-            case VISIBILITY_UNSPECIFIED:
-            case VISIBLE:
-                view.setVisibility(View.VISIBLE);
-                break;
-        }
-    }
-
-    void triggerHideActions(FrameContext frameContext) {
-        ViewUtils.triggerHideActions(getView(), mActions, frameContext.getActionHandler(),
-                frameContext.getFrame(), mActiveVisibilityActions);
-    }
-
-    void triggerViewActions(View viewport, FrameContext frameContext) {
-        ViewUtils.maybeTriggerViewActions(getView(), viewport, mActions,
-                frameContext.getActionHandler(), frameContext.getFrame(), mActiveVisibilityActions);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementAdapterFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementAdapterFactory.java
deleted file mode 100644
index 5f074acc..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementAdapterFactory.java
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.content.Context;
-import android.view.View;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.piet.DebugLogger.MessageType;
-import org.chromium.chrome.browser.feed.library.piet.TemplateBinder.TemplateKey;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.CustomElement;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Element;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.ElementList;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.ElementStack;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.GridRow;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.ImageElement;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/** Provides methods to create various adapter types based on bindings. */
-class ElementAdapterFactory {
-    private final AdapterFactory<CustomElementAdapter, CustomElement> mCustomElementFactory;
-    private final AdapterFactory<ChunkedTextElementAdapter, Element> mChunkedTextElementFactory;
-    private final AdapterFactory<ParameterizedTextElementAdapter, Element>
-            mParameterizedTextElementFactory;
-    private final AdapterFactory<ImageElementAdapter, ImageElement> mImageElementFactory;
-    private final AdapterFactory<GridRowAdapter, GridRow> mGridRowFactory;
-    private final AdapterFactory<ElementListAdapter, ElementList> mElementListFactory;
-    private final AdapterFactory<ElementStackAdapter, ElementStack> mElementStackFactory;
-    private final List<AdapterFactory<?, ?>> mFactories;
-
-    private final KeyedRecyclerPool<ElementAdapter<? extends View, ?>> mTemplateRecyclerPool;
-
-    ElementAdapterFactory(Context context, AdapterParameters parameters,
-            KeyedRecyclerPool<ElementAdapter<? extends View, ?>> templateRecyclerPool) {
-        this(new AdapterFactory<>(context, parameters, new CustomElementAdapter.KeySupplier()),
-                new AdapterFactory<>(
-                        context, parameters, new ChunkedTextElementAdapter.KeySupplier()),
-                new AdapterFactory<>(
-                        context, parameters, new ParameterizedTextElementAdapter.KeySupplier()),
-                new AdapterFactory<>(context, parameters, new ImageElementAdapter.KeySupplier()),
-                new AdapterFactory<>(context, parameters, new GridRowAdapter.KeySupplier()),
-                new AdapterFactory<>(context, parameters, new ElementListAdapter.KeySupplier()),
-                new AdapterFactory<>(context, parameters, new ElementStackAdapter.KeySupplier()),
-                templateRecyclerPool);
-    }
-
-    /** Testing-only constructor for mocking the factories. */
-    @VisibleForTesting
-    ElementAdapterFactory(AdapterFactory<CustomElementAdapter, CustomElement> customElementFactory,
-            AdapterFactory<ChunkedTextElementAdapter, Element> chunkedTextElementFactory,
-            AdapterFactory<ParameterizedTextElementAdapter, Element>
-                    parameterizedTextElementFactory,
-            AdapterFactory<ImageElementAdapter, ImageElement> imageElementFactory,
-            AdapterFactory<GridRowAdapter, GridRow> gridRowFactory,
-            AdapterFactory<ElementListAdapter, ElementList> elementListFactory,
-            AdapterFactory<ElementStackAdapter, ElementStack> elementStackFactory,
-            KeyedRecyclerPool<ElementAdapter<? extends View, ?>> templateRecyclerPool) {
-        this.mCustomElementFactory = customElementFactory;
-        this.mChunkedTextElementFactory = chunkedTextElementFactory;
-        this.mParameterizedTextElementFactory = parameterizedTextElementFactory;
-        this.mImageElementFactory = imageElementFactory;
-        this.mGridRowFactory = gridRowFactory;
-        this.mElementListFactory = elementListFactory;
-        this.mElementStackFactory = elementStackFactory;
-        mFactories = Collections.unmodifiableList(Arrays.asList(customElementFactory,
-                chunkedTextElementFactory, parameterizedTextElementFactory, imageElementFactory,
-                gridRowFactory, elementListFactory, elementStackFactory));
-        this.mTemplateRecyclerPool = templateRecyclerPool;
-    }
-
-    ElementAdapter<? extends View, ?> createAdapterForElement(
-            Element element, FrameContext frameContext) {
-        ElementAdapter<? extends View, ?> returnAdapter;
-        switch (element.getElementsCase()) {
-            case CUSTOM_ELEMENT:
-                returnAdapter = mCustomElementFactory.get(element.getCustomElement(), frameContext);
-                break;
-            case TEXT_ELEMENT:
-                switch (element.getTextElement().getContentCase()) {
-                    case CHUNKED_TEXT:
-                    case CHUNKED_TEXT_BINDING:
-                        returnAdapter = mChunkedTextElementFactory.get(element, frameContext);
-                        break;
-                    case PARAMETERIZED_TEXT:
-                    case PARAMETERIZED_TEXT_BINDING:
-                        returnAdapter = mParameterizedTextElementFactory.get(element, frameContext);
-                        break;
-                    default:
-                        throw new PietFatalException(ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                                frameContext.reportMessage(MessageType.ERROR,
-                                        ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                                        String.format("Unsupported TextElement type: %s",
-                                                element.getTextElement().getContentCase())));
-                }
-                break;
-            case IMAGE_ELEMENT:
-                returnAdapter = mImageElementFactory.get(element.getImageElement(), frameContext);
-                break;
-            case GRID_ROW:
-                returnAdapter = mGridRowFactory.get(element.getGridRow(), frameContext);
-                break;
-            case ELEMENT_LIST:
-                returnAdapter = mElementListFactory.get(element.getElementList(), frameContext);
-                break;
-            case ELEMENT_STACK:
-                returnAdapter = mElementStackFactory.get(element.getElementStack(), frameContext);
-                break;
-            case ELEMENTS_NOT_SET:
-            default:
-                throw new PietFatalException(ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                        frameContext.reportMessage(MessageType.ERROR,
-                                ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                                String.format("Unsupported Element type: %s",
-                                        element.getElementsCase())));
-        }
-        returnAdapter.createAdapter(element, frameContext);
-        return returnAdapter;
-    }
-
-    void releaseAdapter(ElementAdapter<? extends View, ?> adapter) {
-        adapter.unbindModel();
-
-        if (adapter.getKey() instanceof TemplateKey) {
-            // Don't release template adapters; just return them to the pool after unbinding.
-            TemplateKey key = (TemplateKey) adapter.getKey();
-            if (key != null) {
-                mTemplateRecyclerPool.put(key, adapter);
-            }
-        } else if (adapter instanceof CustomElementAdapter) {
-            mCustomElementFactory.release((CustomElementAdapter) adapter);
-        } else if (adapter instanceof ChunkedTextElementAdapter) {
-            mChunkedTextElementFactory.release((ChunkedTextElementAdapter) adapter);
-        } else if (adapter instanceof ParameterizedTextElementAdapter) {
-            mParameterizedTextElementFactory.release((ParameterizedTextElementAdapter) adapter);
-        } else if (adapter instanceof ImageElementAdapter) {
-            mImageElementFactory.release((ImageElementAdapter) adapter);
-        } else if (adapter instanceof GridRowAdapter) {
-            mGridRowFactory.release((GridRowAdapter) adapter);
-        } else if (adapter instanceof ElementListAdapter) {
-            mElementListFactory.release((ElementListAdapter) adapter);
-        } else if (adapter instanceof ElementStackAdapter) {
-            mElementStackFactory.release((ElementStackAdapter) adapter);
-        }
-    }
-
-    void purgeRecyclerPools() {
-        for (AdapterFactory<?, ?> factory : mFactories) {
-            factory.purgeRecyclerPool();
-        }
-        mTemplateRecyclerPool.clear();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementContainerAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementContainerAdapter.java
deleted file mode 100644
index ec02ace..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementContainerAdapter.java
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import android.content.Context;
-import android.view.View;
-import android.view.ViewGroup;
-
-import org.chromium.chrome.browser.feed.library.piet.DebugLogger.MessageType;
-import org.chromium.chrome.browser.feed.library.piet.TemplateBinder.TemplateAdapterModel;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.BindingValue;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Content;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Element;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.TemplateInvocation;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Template;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Base class for adapters that act as containers for other adapters, such as ElementList and
- * GridRow. Ensures that lifecycle methods are called on child adapters when the parent class binds,
- * unbinds, or releases.
- */
-abstract class ElementContainerAdapter<V extends ViewGroup, M> extends ElementAdapter<V, M> {
-    final List<ElementAdapter<? extends View, ?>> mChildAdapters;
-    int[] mAdaptersPerContent = new int[0];
-
-    /** Cached reference to the factory for convenience. */
-    private final ElementAdapterFactory mFactory;
-
-    ElementContainerAdapter(
-            Context context, AdapterParameters parameters, V view, RecyclerKey key) {
-        super(context, parameters, view, key);
-        mChildAdapters = new ArrayList<>();
-        mFactory = parameters.mElementAdapterFactory;
-    }
-
-    ElementContainerAdapter(Context context, AdapterParameters parameters, V view) {
-        super(context, parameters, view);
-        mChildAdapters = new ArrayList<>();
-        mFactory = parameters.mElementAdapterFactory;
-    }
-
-    @Override
-    void onCreateAdapter(M model, Element baseElement, FrameContext frameContext) {
-        createInlineChildAdapters(getContentsFromModel(model), frameContext);
-    }
-
-    abstract List<Content> getContentsFromModel(M model);
-
-    @Override
-    void onBindModel(M model, Element baseElement, FrameContext frameContext) {
-        bindChildAdapters(getContentsFromModel(model), frameContext);
-    }
-
-    /** Unbind the model and release child adapters. Be sure to call this in any overrides. */
-    @Override
-    void onUnbindModel() {
-        if (getRawModel() != null && !mChildAdapters.isEmpty()) {
-            unbindChildAdapters(getContentsFromModel(getModel()));
-        }
-
-        super.onUnbindModel();
-    }
-
-    @Override
-    void onReleaseAdapter() {
-        V containerView = getBaseView();
-        if (containerView != null) {
-            containerView.removeAllViews();
-        }
-        for (ElementAdapter<?, ?> childAdapter : mChildAdapters) {
-            mFactory.releaseAdapter(childAdapter);
-        }
-        mChildAdapters.clear();
-    }
-
-    /** Creates and adds adapters for all inline Content items. */
-    private void createInlineChildAdapters(List<Content> contents, FrameContext frameContext) {
-        mAdaptersPerContent = new int[contents.size()];
-
-        checkState(mChildAdapters.isEmpty(),
-                "Child adapters is not empty (has %s elements); release adapter before creating.",
-                mChildAdapters.size());
-        // Could also check that getBaseView has no children, but it may have children due to
-        // alignment padding elements.
-
-        for (int contentIndex = 0; contentIndex < contents.size(); contentIndex++) {
-            Content content = contents.get(contentIndex);
-            switch (content.getContentTypeCase()) {
-                case ELEMENT:
-                    mAdaptersPerContent[contentIndex] =
-                            createAndAddElementAdapter(content.getElement(), frameContext);
-                    break;
-                case TEMPLATE_INVOCATION:
-                    mAdaptersPerContent[contentIndex] = createAndAddTemplateAdapters(
-                            content.getTemplateInvocation(), frameContext);
-                    break;
-                case BOUND_ELEMENT:
-                case TEMPLATE_BINDING:
-                    // Do nothing; create these adapters in the bindModel call.
-                    mAdaptersPerContent[contentIndex] = 0;
-                    continue;
-                default:
-                    throw new PietFatalException(ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                            frameContext.reportMessage(MessageType.ERROR,
-                                    ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                                    String.format("Unhandled Content type: %s",
-                                            content.getContentTypeCase())));
-            }
-        }
-    }
-
-    /**
-     * Create an adapter for the element and add it to this container's layout.
-     *
-     * @return number of adapters created
-     */
-    private int createAndAddElementAdapter(Element element, FrameContext frameContext) {
-        ElementAdapter<? extends View, ?> adapter =
-                mFactory.createAdapterForElement(element, frameContext);
-        addChildAdapter(adapter);
-        getBaseView().addView(adapter.getView());
-        return 1;
-    }
-
-    /**
-     * Create adapters for the template invocation and add them to this container's layout.
-     *
-     * @return number of adapters created
-     */
-    private int createAndAddTemplateAdapters(
-            TemplateInvocation templateInvocation, FrameContext frameContext) {
-        Template template = frameContext.getTemplate(templateInvocation.getTemplateId());
-        if (template == null) {
-            return 0;
-        }
-        for (int templateIndex = 0; templateIndex < templateInvocation.getBindingContextsCount();
-                templateIndex++) {
-            TemplateAdapterModel templateModel = new TemplateAdapterModel(
-                    template, templateInvocation.getBindingContexts(templateIndex));
-            ElementAdapter<? extends View, ?> templateAdapter =
-                    getParameters().mTemplateBinder.createTemplateAdapter(
-                            templateModel, frameContext);
-            addChildAdapter(templateAdapter);
-            getBaseView().addView(templateAdapter.getView());
-        }
-        return templateInvocation.getBindingContextsCount();
-    }
-
-    /**
-     * Binds all static adapters, and creates+binds+adds adapters for Content bindings.
-     *
-     * <p>There are a few inefficient O(N^2) mid-list inserts in this method, but since we're
-     * dealing with views here, N should always be small (probably less than ~10).
-     */
-    private void bindChildAdapters(List<Content> contents, FrameContext frameContext) {
-        checkState(mAdaptersPerContent.length == contents.size(),
-                "Internal error in adapters per content (%s != %s). Adapter has not been created?",
-                mAdaptersPerContent.length, contents.size());
-        int adapterIndex = 0;
-        int viewIndex = 0;
-        for (int contentIndex = 0; contentIndex < contents.size(); contentIndex++) {
-            Content content = contents.get(contentIndex);
-            switch (content.getContentTypeCase()) {
-                case ELEMENT:
-                    // An Element generates exactly one adapter+view; bind it here.
-                    mChildAdapters.get(adapterIndex).bindModel(content.getElement(), frameContext);
-                    adapterIndex++;
-                    viewIndex++;
-                    break;
-                case TEMPLATE_INVOCATION:
-                    // Bind one TemplateInstanceAdapter for each BindingContext.
-                    TemplateInvocation templateInvocation = content.getTemplateInvocation();
-                    Template template =
-                            frameContext.getTemplate(templateInvocation.getTemplateId());
-                    if (template == null) {
-                        continue;
-                    }
-                    for (int templateIndex = 0; templateIndex < mAdaptersPerContent[contentIndex];
-                            templateIndex++) {
-                        ElementAdapter<? extends View, ?> templateAdapter =
-                                mChildAdapters.get(adapterIndex);
-                        getParameters().mTemplateBinder.bindTemplateAdapter(templateAdapter,
-                                new TemplateAdapterModel(template,
-                                        templateInvocation.getBindingContexts(templateIndex)),
-                                frameContext);
-                        adapterIndex++;
-                        viewIndex++;
-                    }
-                    break;
-                case BOUND_ELEMENT:
-                    // Look up the binding, then create, bind, and add a single adapter.
-                    BindingValue elementBinding =
-                            frameContext.getElementBindingValue(content.getBoundElement());
-                    if (!elementBinding.hasElement()) {
-                        continue;
-                    }
-                    Element element = elementBinding.getElement();
-                    ElementAdapter<? extends View, ?> adapter =
-                            mFactory.createAdapterForElement(element, frameContext);
-                    adapter.bindModel(element, frameContext);
-                    mChildAdapters.add(adapterIndex++, adapter);
-                    getBaseView().addView(adapter.getView(), viewIndex++);
-                    mAdaptersPerContent[contentIndex] = 1;
-                    break;
-                case TEMPLATE_BINDING:
-                    // Look up the binding, then create, bind, and add template adapters.
-                    BindingValue templateBindingValue =
-                            frameContext.getTemplateInvocationBindingValue(
-                                    content.getTemplateBinding());
-                    if (!templateBindingValue.hasTemplateInvocation()) {
-                        continue;
-                    }
-                    TemplateInvocation boundTemplateInvocation =
-                            templateBindingValue.getTemplateInvocation();
-                    Template boundTemplate =
-                            frameContext.getTemplate(boundTemplateInvocation.getTemplateId());
-                    if (boundTemplate == null) {
-                        continue;
-                    }
-                    mAdaptersPerContent[contentIndex] =
-                            boundTemplateInvocation.getBindingContextsCount();
-                    for (int templateIndex = 0;
-                            templateIndex < boundTemplateInvocation.getBindingContextsCount();
-                            templateIndex++) {
-                        TemplateAdapterModel templateModel = new TemplateAdapterModel(boundTemplate,
-                                boundTemplateInvocation.getBindingContexts(templateIndex));
-                        ElementAdapter<? extends View, ?> boundTemplateAdapter =
-                                getParameters().mTemplateBinder.createAndBindTemplateAdapter(
-                                        templateModel, frameContext);
-                        mChildAdapters.add(adapterIndex++, boundTemplateAdapter);
-                        getBaseView().addView(boundTemplateAdapter.getView(), viewIndex++);
-                    }
-                    break;
-                default:
-                    throw new PietFatalException(ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                            frameContext.reportMessage(MessageType.ERROR,
-                                    ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                                    String.format("Unhandled Content type: %s",
-                                            content.getContentTypeCase())));
-            }
-        }
-    }
-
-    /** Unbind all inline adapters, and destroy all bound adapters. */
-    private void unbindChildAdapters(List<Content> contents) {
-        int adapterIndex = 0;
-        int viewIndex = 0;
-        for (int contentIndex = 0; contentIndex < contents.size(); contentIndex++) {
-            Content content = contents.get(contentIndex);
-            switch (content.getContentTypeCase()) {
-                case ELEMENT:
-                case TEMPLATE_INVOCATION:
-                    // For inline content, just unbind to allow re-binding in the future.
-                    for (int i = 0; i < mAdaptersPerContent[contentIndex]; i++) {
-                        mChildAdapters.get(adapterIndex).unbindModel();
-                        adapterIndex++;
-                        viewIndex++;
-                    }
-                    break;
-                case BOUND_ELEMENT:
-                case TEMPLATE_BINDING:
-                    // For bound content, release, recycle, and remove adapters.
-                    for (int i = 0; i < mAdaptersPerContent[contentIndex]; i++) {
-                        mFactory.releaseAdapter(mChildAdapters.get(adapterIndex));
-                        mChildAdapters.remove(adapterIndex);
-                        getBaseView().removeViewAt(viewIndex);
-                        // Don't increment adapterIndex or viewIndex because we removed this
-                        // adapter/view.
-                    }
-                    mAdaptersPerContent[contentIndex] = 0;
-                    break;
-                default:
-                    throw new PietFatalException(ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                            String.format(
-                                    "Unhandled Content type: %s", content.getContentTypeCase()));
-            }
-        }
-    }
-
-    void addChildAdapter(ElementAdapter<? extends View, ?> adapter) {
-        mChildAdapters.add(adapter);
-    }
-
-    @Override
-    public void triggerViewActions(View viewport, FrameContext frameContext) {
-        super.triggerViewActions(viewport, frameContext);
-        for (ElementAdapter<?, ?> childAdapter : mChildAdapters) {
-            childAdapter.triggerViewActions(viewport, frameContext);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementListAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementListAdapter.java
deleted file mode 100644
index 0cf408d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementListAdapter.java
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import static org.chromium.chrome.browser.feed.library.piet.StyleProvider.DIMENSION_NOT_SET;
-
-import android.content.Context;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.LinearLayout.LayoutParams;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.piet.AdapterFactory.SingletonKeySupplier;
-import org.chromium.chrome.browser.feed.library.piet.DebugLogger.MessageType;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Content;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Element;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.ElementList;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-
-import java.util.List;
-
-/** An {@link ElementContainerAdapter} which manages vertical lists of elements. */
-class ElementListAdapter extends ElementContainerAdapter<LinearLayout, ElementList> {
-    private static final String TAG = "ElementListAdapter";
-
-    // Only needed for reporting errors during updateChildLayoutParams.
-    @Nullable
-    private FrameContext mFrameContextForDebugLogsFromCreate;
-    @Nullable
-    private FrameContext mFrameContextForDebugLogsFromBind;
-
-    private ElementListAdapter(Context context, AdapterParameters parameters) {
-        super(context, parameters, createView(context), KeySupplier.SINGLETON_KEY);
-    }
-
-    @Override
-    ElementList getModelFromElement(Element baseElement) {
-        if (!baseElement.hasElementList()) {
-            throw new PietFatalException(ErrorCode.ERR_MISSING_ELEMENT_CONTENTS,
-                    String.format("Missing ElementList; has %s", baseElement.getElementsCase()));
-        }
-        return baseElement.getElementList();
-    }
-
-    @Override
-    void onCreateAdapter(ElementList model, Element baseElement, FrameContext frameContext) {
-        this.mFrameContextForDebugLogsFromCreate = frameContext;
-        super.onCreateAdapter(model, baseElement, frameContext);
-    }
-
-    @Override
-    void onBindModel(ElementList model, Element baseElement, FrameContext frameContext) {
-        this.mFrameContextForDebugLogsFromBind = frameContext;
-        super.onBindModel(model, baseElement, frameContext);
-        for (ElementAdapter<? extends View, ?> adapter : mChildAdapters) {
-            updateChildLayoutParams(adapter);
-        }
-    }
-
-    @Override
-    List<Content> getContentsFromModel(ElementList model) {
-        return model.getContentsList();
-    }
-
-    @Override
-    void onUnbindModel() {
-        super.onUnbindModel();
-        this.mFrameContextForDebugLogsFromBind = null;
-    }
-
-    @Override
-    void onReleaseAdapter() {
-        super.onReleaseAdapter();
-        this.mFrameContextForDebugLogsFromCreate = null;
-    }
-
-    @Override
-    public void setLayoutParams(ViewGroup.LayoutParams layoutParams) {
-        super.setLayoutParams(layoutParams);
-        for (ElementAdapter<? extends View, ?> adapter : mChildAdapters) {
-            updateChildLayoutParams(adapter);
-        }
-    }
-
-    @Nullable
-    private FrameContext getLoggingFrameContext() {
-        return mFrameContextForDebugLogsFromBind != null ? mFrameContextForDebugLogsFromBind
-                                                         : mFrameContextForDebugLogsFromCreate;
-    }
-
-    private void updateChildLayoutParams(ElementAdapter<? extends View, ?> adapter) {
-        LayoutParams childParams = new LayoutParams(0, 0);
-
-        int childHeight = adapter.getComputedHeightPx();
-        if (childHeight == DIMENSION_NOT_SET) {
-            childHeight = LayoutParams.WRAP_CONTENT;
-        } else if (childHeight == LayoutParams.MATCH_PARENT) {
-            FrameContext loggingFrameContext = getLoggingFrameContext();
-            if (loggingFrameContext != null) {
-                loggingFrameContext.reportMessage(MessageType.WARNING,
-                        ErrorCode.ERR_UNSUPPORTED_FEATURE,
-                        "FILL_PARENT not supported for height on ElementList contents.");
-            }
-            childHeight = LayoutParams.WRAP_CONTENT;
-        }
-
-        childParams.width = adapter.getComputedWidthPx() == DIMENSION_NOT_SET
-                ? LayoutParams.MATCH_PARENT
-                : adapter.getComputedWidthPx();
-        childParams.height = childHeight;
-
-        adapter.getElementStyle().applyMargins(getContext(), childParams);
-
-        childParams.gravity = adapter.getHorizontalGravity(Gravity.START);
-
-        adapter.setLayoutParams(childParams);
-    }
-
-    @VisibleForTesting
-    static LinearLayout createView(Context context) {
-        LinearLayout viewGroup = new LinearLayout(context);
-        viewGroup.setOrientation(LinearLayout.VERTICAL);
-        viewGroup.setLayoutParams(
-                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
-        viewGroup.setClipToPadding(false);
-        return viewGroup;
-    }
-
-    static class KeySupplier extends SingletonKeySupplier<ElementListAdapter, ElementList> {
-        @Override
-        public String getAdapterTag() {
-            return TAG;
-        }
-
-        @Override
-        public ElementListAdapter getAdapter(Context context, AdapterParameters parameters) {
-            return new ElementListAdapter(context, parameters);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementStackAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementStackAdapter.java
deleted file mode 100644
index e8358e8e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementStackAdapter.java
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import static org.chromium.chrome.browser.feed.library.piet.StyleProvider.DIMENSION_NOT_SET;
-
-import android.content.Context;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.FrameLayout;
-
-import org.chromium.chrome.browser.feed.library.piet.AdapterFactory.SingletonKeySupplier;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Content;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Element;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.ElementStack;
-
-import java.util.List;
-
-/** Container adapter that stacks its children in a FrameLayout. */
-class ElementStackAdapter extends ElementContainerAdapter<FrameLayout, ElementStack> {
-    private static final String TAG = "ElementStackAdapter";
-
-    private ElementStackAdapter(Context context, AdapterParameters parameters) {
-        super(context, parameters, createView(context));
-    }
-
-    @Override
-    public void onBindModel(ElementStack stack, Element baseElement, FrameContext frameContext) {
-        super.onBindModel(stack, baseElement, frameContext);
-        for (ElementAdapter<?, ?> childAdapter : mChildAdapters) {
-            updateChildLayoutParams(childAdapter);
-        }
-    }
-
-    private void updateChildLayoutParams(ElementAdapter<? extends View, ?> adapter) {
-        FrameLayout.LayoutParams childParams = new FrameLayout.LayoutParams(0, 0);
-
-        childParams.width = adapter.getComputedWidthPx() == DIMENSION_NOT_SET
-                ? LayoutParams.WRAP_CONTENT
-                : adapter.getComputedWidthPx();
-        childParams.height = adapter.getComputedHeightPx() == DIMENSION_NOT_SET
-                ? LayoutParams.WRAP_CONTENT
-                : adapter.getComputedHeightPx();
-
-        adapter.getElementStyle().applyMargins(getContext(), childParams);
-
-        childParams.gravity = adapter.getGravity(Gravity.CENTER);
-
-        adapter.setLayoutParams(childParams);
-    }
-
-    @Override
-    List<Content> getContentsFromModel(ElementStack model) {
-        return model.getContentsList();
-    }
-
-    @Override
-    ElementStack getModelFromElement(Element baseElement) {
-        return baseElement.getElementStack();
-    }
-
-    private static FrameLayout createView(Context context) {
-        FrameLayout view = new FrameLayout(context);
-        view.setLayoutParams(
-                new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
-        return view;
-    }
-
-    static class KeySupplier extends SingletonKeySupplier<ElementStackAdapter, ElementStack> {
-        @Override
-        public String getAdapterTag() {
-            return TAG;
-        }
-
-        @Override
-        public ElementStackAdapter getAdapter(Context context, AdapterParameters parameters) {
-            return new ElementStackAdapter(context, parameters);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/FrameAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/FrameAdapter.java
deleted file mode 100644
index 0145d5db..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/FrameAdapter.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.view.View;
-import android.widget.LinearLayout;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.components.feed.core.proto.ui.piet.PietAndroidSupport.ShardingControl;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Frame;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.PietSharedState;
-
-import java.util.List;
-
-/**
- * An adapter which manages {@link Frame} instances. Frames will contain one or more slices. This
- * class has additional public methods to support host access to the primary view of the frame
- * before the model is bound to the frame. A frame is basically a vertical LinearLayout of slice
- * Views which are created by {@link ElementAdapter}. This Adapter is not created through a Factory
- * and is managed by the host.
- */
-public interface FrameAdapter {
-    /**
-     * This version of bind will support the {@link ShardingControl}. Sharding allows only part of
-     * the frame to be rendered. When sharding is used, a frame is one or more LinearLayout
-     * containing a subset of the full set of slices defined for the frame.
-     */
-    void bindModel(Frame frame, int frameWidthPx, @Nullable ShardingControl shardingControl,
-            List<PietSharedState> pietSharedStates);
-
-    void unbindModel();
-
-    /**
-     * Return the LinearLayout managed by this FrameAdapter. This method can be used to gain access
-     * to this view before {@code bindModel} is called.
-     */
-    LinearLayout getFrameContainer();
-
-    /**
-     * Trigger any actions that occur on the view being hidden. This is also called by unbind(); it
-     * only needs to be called independently in cases where the view goes offscreen but stays bound.
-     * Piet hide/show action handling is idempotent, so calling this multiple times in a row will
-     * only trigger each action once.
-     */
-    void triggerHideActions();
-
-    /** Trigger all visibility-related actions, filtered on the actual visibility of the view. */
-    void triggerViewActions(View viewport);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/FrameAdapterImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/FrameAdapterImpl.java
deleted file mode 100644
index c7b26c1..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/FrameAdapterImpl.java
+++ /dev/null
@@ -1,296 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-import static org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT;
-import static org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode.ERR_POOR_FRAME_RATE;
-
-import android.content.Context;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.LinearLayout;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.api.host.config.DebugBehavior;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.piet.DebugLogger.MessageType;
-import org.chromium.chrome.browser.feed.library.piet.TemplateBinder.TemplateAdapterModel;
-import org.chromium.chrome.browser.feed.library.piet.host.ActionHandler;
-import org.chromium.chrome.browser.feed.library.piet.host.EventLogger;
-import org.chromium.chrome.browser.feed.library.piet.host.LogDataCallback;
-import org.chromium.components.feed.core.proto.ui.piet.ActionsProto.VisibilityAction;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.BindingContext;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Content;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Element;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.TemplateInvocation;
-import org.chromium.components.feed.core.proto.ui.piet.PietAndroidSupport.ShardingControl;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Frame;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.PietSharedState;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * An adapter which manages {@link Frame} instances. Frames will contain one or more slices. This
- * class has additional public methods to support host access to the primary view of the frame
- * before the model is bound to the frame. A frame is basically a vertical LinearLayout of slice
- * Views which are created by {@link ElementAdapter}. This Adapter is not created through a Factory
- * and is managed by the host.
- */
-public class FrameAdapterImpl implements FrameAdapter {
-    private static final String TAG = "FrameAdapter";
-
-    private static final String GENERIC_EXCEPTION = "Top Level Exception was caught - see logcat";
-
-    private final Set<ElementAdapter<?, ?>> mChildAdapters;
-
-    private final Context mContext;
-    private final AdapterParameters mParameters;
-    private final ActionHandler mActionHandler;
-    private final EventLogger mEventLogger;
-    private final DebugBehavior mDebugBehavior;
-    private final Set<VisibilityAction> mActiveActions = new HashSet<>();
-    @Nullable
-    private LinearLayout mView;
-    @Nullable
-    private FrameContext mFrameContext;
-
-    FrameAdapterImpl(Context context, AdapterParameters parameters, ActionHandler actionHandler,
-            EventLogger eventLogger, DebugBehavior debugBehavior) {
-        this.mContext = context;
-        this.mParameters = parameters;
-        this.mActionHandler = actionHandler;
-        this.mEventLogger = eventLogger;
-        this.mDebugBehavior = debugBehavior;
-        mChildAdapters = new HashSet<>();
-    }
-
-    // TODO: Need to implement support for sharding
-    @Override
-    public void bindModel(Frame frame, int frameWidthPx, @Nullable ShardingControl shardingControl,
-            List<PietSharedState> pietSharedStates) {
-        long startTime = System.nanoTime();
-        initialBind(mParameters.mParentViewSupplier.get());
-        FrameContext localFrameContext =
-                createFrameContext(frame, frameWidthPx, pietSharedStates, checkNotNull(mView));
-        mFrameContext = localFrameContext;
-        mActiveActions.clear();
-        mActiveActions.addAll(frame.getActions().getOnHideActionsList());
-        LinearLayout frameView = checkNotNull(mView);
-
-        try {
-            for (Content content : frame.getContentsList()) {
-                // For Slice we will create the lower level slice instead to remove the extra
-                // level.
-                List<ElementAdapter<?, ?>> adapters =
-                        getBoundAdaptersForContent(content, localFrameContext);
-                for (ElementAdapter<?, ?> adapter : adapters) {
-                    mChildAdapters.add(adapter);
-                    setLayoutParamsOnChild(adapter);
-                    frameView.addView(adapter.getView());
-                }
-            }
-
-            StyleProvider style = localFrameContext.makeStyleFor(frame.getStyleReferences());
-            frameView.setBackground(style.createBackground());
-        } catch (RuntimeException e) {
-            // TODO: Remove this once error reporting is fully implemented.
-            Logger.e(TAG, e, "Catch top level exception");
-            String message = e.getMessage() != null ? e.getMessage() : GENERIC_EXCEPTION;
-            if (e instanceof PietFatalException) {
-                localFrameContext.reportMessage(
-                        MessageType.ERROR, ((PietFatalException) e).getErrorCode(), message);
-            } else {
-                localFrameContext.reportMessage(MessageType.ERROR, message);
-            }
-        }
-        startTime = System.nanoTime() - startTime;
-        // TODO: We should be targeting < 15ms and warn at 10ms?
-        //   Until we get a chance to do the performance tuning, leave this at 30ms to prevent
-        //   warnings on large GridRows based frames.
-        if (startTime / 1000000 > 30) {
-            Logger.w(TAG,
-                    localFrameContext.reportMessage(MessageType.WARNING, ERR_POOR_FRAME_RATE,
-                            String.format("Slow Bind (%s) time: %s ps", frame.getTag(),
-                                    startTime / 1000)));
-        }
-        // If there were errors add an error slice to the frame
-        if (localFrameContext.getDebugBehavior().getShowDebugViews()) {
-            View errorView =
-                    localFrameContext.getDebugLogger().getReportView(MessageType.ERROR, mContext);
-            if (errorView != null) {
-                frameView.addView(errorView);
-            }
-            View warningView =
-                    localFrameContext.getDebugLogger().getReportView(MessageType.WARNING, mContext);
-            if (warningView != null) {
-                frameView.addView(warningView);
-            }
-        }
-        mEventLogger.logEvents(localFrameContext.getDebugLogger().getErrorCodes());
-        LogDataCallback callback = mParameters.mHostProviders.getLogDataCallback();
-        Frame localFrame = localFrameContext.getFrame();
-        if (callback != null && localFrame != null && localFrame.hasLogData()) {
-            callback.onBind(localFrame.getLogData(), frameView);
-        }
-    }
-
-    @Override
-    public void unbindModel() {
-        triggerHideActions();
-
-        LinearLayout view = checkNotNull(this.mView);
-        LogDataCallback callback = mParameters.mHostProviders.getLogDataCallback();
-        if (mFrameContext != null) {
-            Frame frame = mFrameContext.getFrame();
-            if (callback != null && frame != null && frame.hasLogData()) {
-                callback.onUnbind(frame.getLogData(), view);
-            }
-        }
-        for (ElementAdapter<?, ?> child : mChildAdapters) {
-            mParameters.mElementAdapterFactory.releaseAdapter(child);
-        }
-        mChildAdapters.clear();
-        view.removeAllViews();
-        mFrameContext = null;
-    }
-
-    private void setLayoutParamsOnChild(ElementAdapter<?, ?> childAdapter) {
-        int width = childAdapter.getComputedWidthPx();
-        width = width == StyleProvider.DIMENSION_NOT_SET ? LayoutParams.MATCH_PARENT : width;
-        int height = childAdapter.getComputedHeightPx();
-        height = height == StyleProvider.DIMENSION_NOT_SET ? LayoutParams.WRAP_CONTENT : height;
-
-        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, height);
-
-        childAdapter.getElementStyle().applyMargins(mContext, params);
-
-        params.gravity = childAdapter.getGravity(Gravity.TOP | Gravity.START);
-
-        childAdapter.setLayoutParams(params);
-    }
-
-    @Override
-    public LinearLayout getFrameContainer() {
-        initialBind(mParameters.mParentViewSupplier.get());
-        return checkNotNull(mView);
-    }
-
-    @VisibleForTesting
-    FrameContext createFrameContext(
-            Frame frame, int frameWidthPx, List<PietSharedState> pietSharedStates, View frameView) {
-        MediaQueryHelper mediaQueryHelper = new MediaQueryHelper(
-                frameWidthPx, mParameters.mHostProviders.getAssetProvider(), mContext);
-        PietStylesHelper pietStylesHelper = checkNotNull(
-                mParameters.mPietStylesHelperFactory.get(pietSharedStates, mediaQueryHelper));
-        return FrameContext.createFrameContext(frame, pietSharedStates, pietStylesHelper,
-                mDebugBehavior, new DebugLogger(), mActionHandler, mParameters.mHostProviders,
-                frameView);
-    }
-
-    @Override
-    public void triggerHideActions() {
-        if (mFrameContext == null || mView == null) {
-            return;
-        }
-        FrameContext localFrameContext = mFrameContext;
-        ViewUtils.triggerHideActions(mView, localFrameContext.getFrame().getActions(),
-                localFrameContext.getActionHandler(), localFrameContext.getFrame(), mActiveActions);
-
-        for (ElementAdapter<?, ?> adapter : mChildAdapters) {
-            adapter.triggerHideActions(localFrameContext);
-        }
-    }
-
-    @Override
-    public void triggerViewActions(View viewport) {
-        if (mFrameContext == null || mView == null) {
-            return;
-        }
-        FrameContext localFrameContext = mFrameContext;
-        ViewUtils.maybeTriggerViewActions(mView, viewport,
-                localFrameContext.getFrame().getActions(), localFrameContext.getActionHandler(),
-                localFrameContext.getFrame(), mActiveActions);
-
-        for (ElementAdapter<?, ?> adapter : mChildAdapters) {
-            adapter.triggerViewActions(viewport, localFrameContext);
-        }
-    }
-
-    @VisibleForTesting
-    List<ElementAdapter<?, ?>> getBoundAdaptersForContent(
-            Content content, FrameContext frameContext) {
-        switch (content.getContentTypeCase()) {
-            case ELEMENT:
-                Element element = content.getElement();
-                ElementAdapter<?, ?> inlineSliceAdapter =
-                        mParameters.mElementAdapterFactory.createAdapterForElement(
-                                element, frameContext);
-                inlineSliceAdapter.bindModel(element, frameContext);
-                return Collections.singletonList(inlineSliceAdapter);
-            case TEMPLATE_INVOCATION:
-                TemplateInvocation templateInvocation = content.getTemplateInvocation();
-                ArrayList<ElementAdapter<?, ?>> returnList = new ArrayList<>();
-                for (BindingContext bindingContext : templateInvocation.getBindingContextsList()) {
-                    TemplateAdapterModel model = new TemplateAdapterModel(
-                            templateInvocation.getTemplateId(), frameContext, bindingContext);
-                    ElementAdapter<? extends View, ?> templateAdapter =
-                            mParameters.mTemplateBinder.createAndBindTemplateAdapter(
-                                    model, frameContext);
-                    returnList.add(templateAdapter);
-                }
-                returnList.trimToSize();
-                return Collections.unmodifiableList(returnList);
-            default:
-                Logger.wtf(TAG,
-                        frameContext.reportMessage(MessageType.ERROR,
-                                ERR_MISSING_OR_UNHANDLED_CONTENT,
-                                String.format("Unsupported Content type for frame: %s",
-                                        content.getContentTypeCase())));
-                return Collections.emptyList();
-        }
-    }
-
-    @VisibleForTesting
-    AdapterParameters getParameters() {
-        return this.mParameters;
-    }
-
-    @VisibleForTesting
-    @Nullable
-    LinearLayout getView() {
-        return this.mView;
-    }
-
-    private void initialBind(@Nullable ViewGroup parent) {
-        if (mView != null) {
-            return;
-        }
-        this.mView = createView(parent);
-    }
-
-    private LinearLayout createView(@Nullable ViewGroup parent) {
-        LinearLayout linearLayout = new LinearLayout(mContext);
-        linearLayout.setOrientation(LinearLayout.VERTICAL);
-        ViewGroup.LayoutParams layoutParams;
-        if (parent != null && parent.getLayoutParams() != null) {
-            layoutParams = new LinearLayout.LayoutParams(parent.getLayoutParams());
-            layoutParams.width = LayoutParams.MATCH_PARENT;
-            layoutParams.height = LayoutParams.WRAP_CONTENT;
-        } else {
-            layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
-        }
-        linearLayout.setLayoutParams(layoutParams);
-        return linearLayout;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/FrameContext.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/FrameContext.java
deleted file mode 100644
index ab5fee7..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/FrameContext.java
+++ /dev/null
@@ -1,532 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import static org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode.ERR_BINDING_VALUE_TYPE_MISMATCH;
-import static org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode.ERR_DUPLICATE_BINDING_VALUE;
-import static org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode.ERR_DUPLICATE_STYLE;
-import static org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode.ERR_DUPLICATE_TEMPLATE;
-import static org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode.ERR_MISSING_BINDING_VALUE;
-import static org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode.ERR_MISSING_TEMPLATE;
-
-import android.view.View;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.api.host.config.DebugBehavior;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.piet.DebugLogger.MessageType;
-import org.chromium.chrome.browser.feed.library.piet.host.ActionHandler;
-import org.chromium.chrome.browser.feed.library.piet.host.HostBindingProvider;
-import org.chromium.components.feed.core.proto.ui.piet.ActionsProto.Actions;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.ActionsBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.ChunkedTextBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.CustomBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.ElementBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.GridCellWidthBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.ImageBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.LogDataBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.ParameterizedTextBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.StyleBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.TemplateBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.VisibilityBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.BindingContext;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.BindingValue;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.GridCellWidth;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Visibility;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-import org.chromium.components.feed.core.proto.ui.piet.ImagesProto.Image;
-import org.chromium.components.feed.core.proto.ui.piet.ImagesProto.ImageSource;
-import org.chromium.components.feed.core.proto.ui.piet.LogDataProto.LogData;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Frame;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.PietSharedState;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Stylesheet;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Template;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.BoundStyle;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.Style;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.StyleIdsStack;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This is a {@link FrameContext} that is bound. Binding means we have a {@code Frame}, an optional
- * map of {@code BindingValues} and a {@code StyleProvider}.
- */
-class FrameContext {
-    private static final String TAG = "FrameContext";
-
-    @VisibleForTesting
-    final PietStylesHelper mStyleshelper;
-    private final List<PietSharedState> mPietSharedStates;
-    private final DebugBehavior mDebugBehavior;
-    private final DebugLogger mDebugLogger;
-    private final ActionHandler mActionHandler;
-    private final HostProviders mHostProviders;
-    private final HostBindingProvider mHostBindingProvider;
-    private final Map<String, Template> mTemplates;
-
-    // List of stylesheets for each Template that could be affected by media queries.
-    private final Map<Template, List<Stylesheet>> mTemplateMediaQueryStylesheets;
-
-    // This is the Frame which contains all the slices being processed.
-    private final Frame mCurrentFrame;
-
-    // The Current Stylesheet as a map from style_id to Style.
-    private final Map<String, Style> mStylesheet;
-
-    // The in-scope bindings as a map from state_id to binding value
-    private final Map<String, BindingValue> mBindingValues;
-
-    // The base / default style; set to default instance for Frame or childDefaultStyleId for
-    // Template
-    private final Style mBaseStyle;
-
-    // The root view of this frame.
-    private final View mFrameView;
-
-    /** Initialize a FrameContext for the first time from a top-level Frame. */
-    @VisibleForTesting
-    FrameContext(Frame frame, Map<String, Style> stylesheet, List<PietSharedState> pietSharedStates,
-            PietStylesHelper pietStylesHelper, DebugBehavior debugBehavior, DebugLogger debugLogger,
-            ActionHandler actionHandler, HostProviders hostProviders, View frameView) {
-        this(frame, stylesheet, new ThrowingEmptyMap(), pietSharedStates, pietStylesHelper,
-                debugBehavior, debugLogger, actionHandler, hostProviders,
-                new NoKeyOverwriteHashMap<>("Template", ERR_DUPLICATE_TEMPLATE), frameView);
-
-        mStyleshelper.addSharedStateTemplatesToFrame(mTemplates);
-        if (frame.getTemplatesCount() > 0) {
-            for (Template template : frame.getTemplatesList()) {
-                if (pietStylesHelper.areMediaQueriesMet(template.getConditionsList())) {
-                    mTemplates.put(template.getTemplateId(), template);
-                }
-            }
-        }
-    }
-
-    /** Set up a new FrameContext; typically called to copy an existing FrameContext. */
-    FrameContext(Frame frame, Map<String, Style> stylesheet,
-            Map<String, BindingValue> bindingValues, List<PietSharedState> pietSharedStates,
-            PietStylesHelper pietStylesHelper, DebugBehavior debugBehavior, DebugLogger debugLogger,
-            ActionHandler actionHandler, HostProviders hostProviders,
-            Map<String, Template> templates, View frameView) {
-        mCurrentFrame = frame;
-        this.mStylesheet = stylesheet;
-        this.mBindingValues = bindingValues;
-        this.mBaseStyle = Style.getDefaultInstance();
-        this.mStyleshelper = pietStylesHelper;
-        this.mPietSharedStates = pietSharedStates;
-        this.mDebugBehavior = debugBehavior;
-        this.mDebugLogger = debugLogger;
-        this.mActionHandler = actionHandler;
-        this.mHostProviders = hostProviders;
-        this.mHostBindingProvider = hostProviders.getHostBindingProvider();
-        this.mTemplates = templates;
-        this.mFrameView = frameView;
-        this.mTemplateMediaQueryStylesheets = new HashMap<>();
-    }
-
-    /**
-     * Creates a {@link FrameContext} and constructs the stylesheets from the frame and the list of
-     * {@link PietSharedState}. Any errors found with the styling will be reported.
-     */
-    public static FrameContext createFrameContext(Frame frame,
-            List<PietSharedState> pietSharedStates, PietStylesHelper pietStylesHelper,
-            DebugBehavior debugBehavior, DebugLogger debugLogger, ActionHandler actionHandler,
-            HostProviders hostProviders, View frameView) {
-        NoKeyOverwriteHashMap<String, Style> styleMap = null;
-        if (frame.hasStylesheets()) {
-            styleMap = pietStylesHelper.getStylesheetMap(frame.getStylesheets(), debugLogger);
-        }
-
-        if (styleMap == null) {
-            styleMap = new NoKeyOverwriteHashMap<>("Style", ERR_DUPLICATE_STYLE);
-        }
-        return new FrameContext(frame, styleMap, pietSharedStates, pietStylesHelper, debugBehavior,
-                debugLogger, actionHandler, hostProviders, frameView);
-    }
-
-    /** Return any of the template's stylesheets that could be affected by a MediaQuery. */
-    List<Stylesheet> getMediaQueryStylesheets(Template template) {
-        if (mTemplateMediaQueryStylesheets.containsKey(template)) {
-            return mTemplateMediaQueryStylesheets.get(template);
-        }
-
-        ArrayList<Stylesheet> mediaQueryStylesheets = new ArrayList<>();
-
-        for (Stylesheet stylesheet : template.getStylesheets().getStylesheetsList()) {
-            if (stylesheet.getConditionsCount() > 0) {
-                mediaQueryStylesheets.add(stylesheet);
-            }
-        }
-        for (String stylesheetId : template.getStylesheets().getStylesheetIdsList()) {
-            Stylesheet stylesheet = mStyleshelper.getStylesheet(stylesheetId);
-            if (stylesheet != null && stylesheet.getConditionsCount() > 0) {
-                mediaQueryStylesheets.add(stylesheet);
-            }
-        }
-
-        mediaQueryStylesheets.trimToSize();
-        List<Stylesheet> mediaQueryStylesheetsImmutable =
-                Collections.unmodifiableList(mediaQueryStylesheets);
-
-        mTemplateMediaQueryStylesheets.put(template, mediaQueryStylesheetsImmutable);
-
-        return mediaQueryStylesheetsImmutable;
-    }
-
-    /**
-     * Creates a new FrameContext which is scoped properly for the Template. The Frame's stylesheet
-     * is discarded and replaced by the Template's stylesheet. In addition, a Template can define a
-     * root level style which applies to all child elements.
-     */
-    FrameContext createTemplateContext(Template template, BindingContext bindingContext) {
-        Map<String, BindingValue> bindingValues = createBindingValueMap(bindingContext);
-        Map<String, Style> localStylesheet =
-                mStyleshelper.getStylesheetMap(template.getStylesheets(), getDebugLogger());
-
-        return new FrameContext(mCurrentFrame, localStylesheet, bindingValues, mPietSharedStates,
-                mStyleshelper, mDebugBehavior, mDebugLogger, mActionHandler, mHostProviders,
-                mTemplates, mFrameView);
-    }
-
-    public DebugBehavior getDebugBehavior() {
-        return mDebugBehavior;
-    }
-
-    public DebugLogger getDebugLogger() {
-        return mDebugLogger;
-    }
-
-    public Frame getFrame() {
-        return mCurrentFrame;
-    }
-
-    public ActionHandler getActionHandler() {
-        return mActionHandler;
-    }
-
-    public Template getTemplate(String templateId) {
-        Template template = mTemplates.get(templateId);
-        if (template == null) {
-            throw new PietFatalException(ERR_MISSING_TEMPLATE,
-                    reportMessage(MessageType.ERROR, ERR_MISSING_TEMPLATE,
-                            String.format("Template '%s' not found", templateId)));
-        }
-        return template;
-    }
-
-    public List<PietSharedState> getPietSharedStates() {
-        return mPietSharedStates;
-    }
-
-    /** Return a {@link StyleProvider} for the style. */
-    public StyleProvider makeStyleFor(StyleIdsStack styles) {
-        return new StyleProvider(
-                PietStylesHelper.mergeStyleIdsStack(mBaseStyle, styles, mStylesheet, this),
-                mHostProviders.getAssetProvider());
-    }
-
-    /**
-     * Return a {@link GridCellWidth} for the binding if there is one defined; otherwise returns
-     * {@code null}.
-     */
-    @Nullable
-    GridCellWidth getGridCellWidthFromBinding(GridCellWidthBindingRef binding) {
-        BindingValue bindingValue = mBindingValues.get(binding.getBindingId());
-        // Purposefully check for host binding and overwrite here as we want to perform the
-        // hasCellWidth checks on host binding.   This allows the host to act more like the server.
-        if (bindingValue != null && bindingValue.hasHostBindingData()) {
-            bindingValue = mHostBindingProvider.getGridCellWidthBindingForValue(bindingValue);
-        }
-        return bindingValue == null || !bindingValue.hasCellWidth() ? null
-                                                                    : bindingValue.getCellWidth();
-    }
-
-    /**
-     * Return an {@link Actions} for the binding if there is one defined; otherwise returns the
-     * default instance.
-     */
-    Actions getActionsFromBinding(ActionsBindingRef binding) {
-        BindingValue bindingValue = mBindingValues.get(binding.getBindingId());
-        if (bindingValue != null && bindingValue.hasHostBindingData()) {
-            bindingValue = mHostBindingProvider.getActionsBindingForValue(bindingValue);
-        }
-        if (bindingValue == null) {
-            return Actions.getDefaultInstance();
-        }
-        if (!bindingValue.hasActions()) {
-            Logger.w(TAG,
-                    reportMessage(MessageType.WARNING, ERR_BINDING_VALUE_TYPE_MISMATCH,
-                            String.format(
-                                    "No actions found for binding %s", binding.getBindingId())));
-        }
-        return bindingValue.getActions();
-    }
-
-    /**
-     * Return a {@link BoundStyle} for the binding if there is one defined; otherwise returns the
-     * default instance.
-     */
-    BoundStyle getStyleFromBinding(StyleBindingRef binding) {
-        return getStyleFromBinding(binding, mBindingValues);
-    }
-
-    /**
-     * Return a {@link BoundStyle} for the binding if there is one defined; otherwise returns the
-     * default instance.
-     */
-    BoundStyle getStyleFromBinding(
-            StyleBindingRef binding, Map<String, BindingValue> bindingValues) {
-        BindingValue bindingValue = bindingValues.get(binding.getBindingId());
-        if (bindingValue != null && bindingValue.hasHostBindingData()) {
-            bindingValue = mHostBindingProvider.getStyleBindingForValue(bindingValue);
-        }
-        if (bindingValue == null) {
-            return BoundStyle.getDefaultInstance();
-        }
-        if (!bindingValue.hasBoundStyle()) {
-            Logger.w(TAG,
-                    reportMessage(MessageType.WARNING, ERR_BINDING_VALUE_TYPE_MISMATCH,
-                            String.format(
-                                    "No style found for binding %s", binding.getBindingId())));
-        }
-        return bindingValue.getBoundStyle();
-    }
-
-    /** Returns the {@link BindingValue} for the BindingRef; otherwise returns null. */
-    @Nullable
-    Visibility getVisibilityFromBinding(VisibilityBindingRef binding) {
-        BindingValue bindingValue = mBindingValues.get(binding.getBindingId());
-        if (bindingValue != null && bindingValue.hasHostBindingData()) {
-            bindingValue = mHostBindingProvider.getVisibilityBindingForValue(bindingValue);
-        }
-        if (bindingValue == null) {
-            return null;
-        } else if (!bindingValue.hasVisibility()) {
-            Logger.w(TAG,
-                    reportMessage(MessageType.WARNING, ERR_BINDING_VALUE_TYPE_MISMATCH,
-                            String.format(
-                                    "No visibility found for binding %s", binding.getBindingId())));
-            return null;
-        } else {
-            return bindingValue.getVisibility();
-        }
-    }
-
-    Image filterImageSourcesByMediaQueryCondition(Image image) {
-        Image.Builder imageBuilder = image.toBuilder().clearSources();
-        for (ImageSource source : image.getSourcesList()) {
-            if (mStyleshelper.areMediaQueriesMet(source.getConditionsList())) {
-                imageBuilder.addSources(source);
-            }
-        }
-        return imageBuilder.build();
-    }
-
-    /**
-     * Returns the {@link BindingValue} for the BindingRef; throws IllegalStateException if binding
-     * id does not point to a template resource.
-     */
-    BindingValue getTemplateInvocationBindingValue(TemplateBindingRef binding) {
-        BindingValue bindingValue = getBindingValue(binding.getBindingId());
-        if (bindingValue.hasHostBindingData()) {
-            bindingValue = mHostBindingProvider.getTemplateBindingForValue(bindingValue);
-        }
-        if (!bindingValue.hasTemplateInvocation() && !binding.getIsOptional()) {
-            throw new PietFatalException(ERR_MISSING_BINDING_VALUE,
-                    reportMessage(MessageType.ERROR, ERR_MISSING_BINDING_VALUE,
-                            String.format(
-                                    "Template binding not found for %s", binding.getBindingId())));
-        } else {
-            return bindingValue;
-        }
-    }
-
-    /**
-     * Returns the {@link BindingValue} for the BindingRef; throws IllegalStateException if binding
-     * id does not point to a custom element resource.
-     */
-    BindingValue getCustomElementBindingValue(CustomBindingRef binding) {
-        BindingValue bindingValue = getBindingValue(binding.getBindingId());
-        if (bindingValue.hasHostBindingData()) {
-            bindingValue = mHostBindingProvider.getCustomElementDataBindingForValue(bindingValue);
-        }
-        if (!bindingValue.hasCustomElementData() && !binding.getIsOptional()) {
-            throw new PietFatalException(ERR_MISSING_BINDING_VALUE,
-                    reportMessage(MessageType.ERROR, ERR_MISSING_BINDING_VALUE,
-                            String.format("Custom element binding not found for %s",
-                                    binding.getBindingId())));
-        } else {
-            return bindingValue;
-        }
-    }
-
-    /**
-     * Returns the {@link BindingValue} for the BindingRef; throws IllegalStateException if binding
-     * id does not point to a chunked text resource.
-     */
-    BindingValue getChunkedTextBindingValue(ChunkedTextBindingRef binding) {
-        BindingValue bindingValue = getBindingValue(binding.getBindingId());
-        if (bindingValue.hasHostBindingData()) {
-            bindingValue = mHostBindingProvider.getChunkedTextBindingForValue(bindingValue);
-        }
-        if (!bindingValue.hasChunkedText() && !binding.getIsOptional()) {
-            throw new PietFatalException(ERR_MISSING_BINDING_VALUE,
-                    reportMessage(MessageType.ERROR, ERR_MISSING_BINDING_VALUE,
-                            String.format("Chunked text binding not found for %s",
-                                    binding.getBindingId())));
-        } else {
-            return bindingValue;
-        }
-    }
-
-    /**
-     * Returns the {@link BindingValue} for the BindingRef; throws IllegalStateException if binding
-     * id does not point to a parameterized text resource.
-     */
-    BindingValue getParameterizedTextBindingValue(ParameterizedTextBindingRef binding) {
-        BindingValue bindingValue = getBindingValue(binding.getBindingId());
-        if (bindingValue.hasHostBindingData()) {
-            bindingValue = mHostBindingProvider.getParameterizedTextBindingForValue(bindingValue);
-        }
-        if (!bindingValue.hasParameterizedText() && !binding.getIsOptional()) {
-            throw new PietFatalException(ERR_MISSING_BINDING_VALUE,
-                    reportMessage(MessageType.ERROR, ERR_MISSING_BINDING_VALUE,
-                            String.format("Parameterized text binding not found for %s",
-                                    binding.getBindingId())));
-        } else {
-            return bindingValue;
-        }
-    }
-
-    /**
-     * Returns the {@link BindingValue} for the BindingRef; throws IllegalStateException if binding
-     * id does not point to a image resource.
-     */
-    BindingValue getImageBindingValue(ImageBindingRef binding) {
-        BindingValue bindingValue = getBindingValue(binding.getBindingId());
-        if (bindingValue.hasHostBindingData()) {
-            bindingValue = mHostBindingProvider.getImageBindingForValue(bindingValue);
-        }
-        if (!bindingValue.hasImage() && !binding.getIsOptional()) {
-            throw new PietFatalException(ERR_MISSING_BINDING_VALUE,
-                    reportMessage(MessageType.ERROR, ERR_MISSING_BINDING_VALUE,
-                            String.format(
-                                    "Image binding not found for %s", binding.getBindingId())));
-        } else {
-            return bindingValue;
-        }
-    }
-
-    /**
-     * Returns the {@link BindingValue} for the BindingRef; throws IllegalStateException if binding
-     * id does not point to an Element.
-     */
-    BindingValue getElementBindingValue(ElementBindingRef binding) {
-        BindingValue bindingValue = getBindingValue(binding.getBindingId());
-        if (bindingValue.hasHostBindingData()) {
-            bindingValue = mHostBindingProvider.getElementBindingForValue(bindingValue);
-        }
-        if (!bindingValue.hasElement() && !binding.getIsOptional()) {
-            throw new PietFatalException(ERR_MISSING_BINDING_VALUE,
-                    reportMessage(MessageType.ERROR, ERR_MISSING_BINDING_VALUE,
-                            String.format(
-                                    "Element binding not found for %s", binding.getBindingId())));
-        } else {
-            return bindingValue;
-        }
-    }
-
-    /**
-     * Return an {@link LogData} for the binding if there is one defined; otherwise returns the
-     * default instance.
-     */
-    @Nullable
-    LogData getLogDataFromBinding(LogDataBindingRef binding) {
-        BindingValue bindingValue = mBindingValues.get(binding.getBindingId());
-        if (bindingValue != null && bindingValue.hasHostBindingData()) {
-            bindingValue = mHostBindingProvider.getLogDataBindingForValue(bindingValue);
-        }
-        if (bindingValue == null) {
-            return null;
-        }
-        if (!bindingValue.hasLogData()) {
-            Logger.w(TAG,
-                    reportMessage(MessageType.WARNING, ERR_BINDING_VALUE_TYPE_MISMATCH,
-                            String.format(
-                                    "No logData found for binding %s", binding.getBindingId())));
-            return null;
-        }
-        return bindingValue.getLogData();
-    }
-
-    /** Returns the root view of this Frame. */
-    View getFrameView() {
-        return mFrameView;
-    }
-
-    private BindingValue getBindingValue(String bindingId) {
-        BindingValue returnValue = mBindingValues.get(bindingId);
-        if (returnValue == null) {
-            return BindingValue.getDefaultInstance();
-        }
-        return returnValue;
-    }
-
-    /**
-     * Report user errors in frames. This will return the fully formed error so it can be logged at
-     * the site of the error.
-     */
-    public String reportMessage(@MessageType int messageType, String message) {
-        String e = String.format("[%s] %s", mCurrentFrame.getTag(), message);
-        mDebugLogger.recordMessage(messageType, e);
-        return e;
-    }
-
-    /**
-     * Report user errors in frames. This will return the fully formed error so it can be logged at
-     * the site of the error.
-     */
-    public String reportMessage(@MessageType int messageType, ErrorCode errorCode, String message) {
-        String e = String.format("[%s] %s", mCurrentFrame.getTag(), message);
-        mDebugLogger.recordMessage(messageType, errorCode, e);
-        return e;
-    }
-
-    private Map<String, BindingValue> createBindingValueMap(BindingContext bindingContext) {
-        Map<String, BindingValue> bindingValueMap =
-                new NoKeyOverwriteHashMap<>("BindingValue", ERR_DUPLICATE_BINDING_VALUE);
-        for (BindingValue bindingValue : bindingContext.getBindingValuesList()) {
-            if (bindingValue.hasBindingIdFromTranscludingTemplate()) {
-                BindingValue parentBindingValue =
-                        mBindingValues.get(bindingValue.getBindingIdFromTranscludingTemplate());
-                if (parentBindingValue != null) {
-                    BindingValue bindingValueForChild =
-                            parentBindingValue.toBuilder()
-                                    .setBindingId(bindingValue.getBindingId())
-                                    .build();
-                    bindingValueMap.put(bindingValue.getBindingId(), bindingValueForChild);
-                }
-            } else {
-                bindingValueMap.put(bindingValue.getBindingId(), bindingValue);
-            }
-        }
-        return bindingValueMap;
-    }
-
-    /** Map that throws whenever you try to look anything up in it. */
-    private static class ThrowingEmptyMap extends HashMap<String, BindingValue> {
-        @Override
-        public BindingValue get(@Nullable Object key) {
-            throw new PietFatalException(ErrorCode.ERR_MISSING_BINDING_VALUE,
-                    "Looking up bindings not supported in this context; no BindingValues defined.");
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/GridRowAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/GridRowAdapter.java
deleted file mode 100644
index 4bd0fb8b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/GridRowAdapter.java
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-import static org.chromium.chrome.browser.feed.library.piet.StyleProvider.DIMENSION_NOT_SET;
-import static org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode.ERR_GRID_CELL_WIDTH_WITHOUT_CONTENTS;
-import static org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode.ERR_MISSING_ELEMENT_CONTENTS;
-import static org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode.ERR_UNSUPPORTED_FEATURE;
-
-import android.content.Context;
-import android.view.Gravity;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.common.ui.LayoutUtils;
-import org.chromium.chrome.browser.feed.library.piet.AdapterFactory.AdapterKeySupplier;
-import org.chromium.chrome.browser.feed.library.piet.AdapterFactory.SingletonKeySupplier;
-import org.chromium.chrome.browser.feed.library.piet.DebugLogger.MessageType;
-import org.chromium.chrome.browser.feed.library.piet.ui.GridRowView;
-import org.chromium.chrome.browser.feed.library.piet.ui.GridRowView.LayoutParams;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Content;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Element;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.GridCell;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.GridCellWidth;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.GridCellWidth.WidthSpecCase;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.GridRow;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/** An {@link ElementContainerAdapter} which manages {@code GridRow} slices. */
-class GridRowAdapter extends ElementContainerAdapter<GridRowView, GridRow> {
-    private static final String TAG = "GridRowAdapter";
-
-    private GridRowAdapter(Context context, AdapterParameters parameters) {
-        super(context, parameters,
-                createView(context, parameters.mHostProviders.getAssetProvider().isRtLSupplier()),
-                KeySupplier.SINGLETON_KEY);
-    }
-
-    @Override
-    GridRow getModelFromElement(Element baseElement) {
-        if (!baseElement.hasGridRow()) {
-            throw new PietFatalException(ERR_MISSING_ELEMENT_CONTENTS,
-                    String.format("Missing GridRow; has %s", baseElement.getElementsCase()));
-        }
-        return baseElement.getGridRow();
-    }
-
-    @Override
-    List<Content> getContentsFromModel(GridRow model) {
-        ArrayList<Content> contents = new ArrayList<>();
-        for (GridCell cell : model.getCellsList()) {
-            contents.add(cell.getContent());
-        }
-        contents.trimToSize();
-        return Collections.unmodifiableList(contents);
-    }
-
-    @Override
-    void onBindModel(GridRow gridRow, Element baseElement, FrameContext frameContext) {
-        super.onBindModel(gridRow, baseElement, frameContext);
-
-        int adapterIndex = 0;
-        checkState(gridRow.getCellsCount() == mAdaptersPerContent.length,
-                "Mismatch between number of cells (%s) and adaptersPerContent (%s);"
-                        + " problem in creation?",
-                gridRow.getCellsCount(), mAdaptersPerContent.length);
-        for (int contentIndex = 0; contentIndex < gridRow.getCellsCount(); contentIndex++) {
-            GridCell cell = gridRow.getCells(contentIndex);
-            for (int i = 0; i < mAdaptersPerContent[contentIndex]; i++) {
-                setLayoutParamsOnCell(mChildAdapters.get(adapterIndex), cell, frameContext);
-                adapterIndex++;
-            }
-        }
-    }
-
-    @SuppressWarnings("UnnecessaryDefaultInEnumSwitch")
-    private void setLayoutParamsOnCell(ElementAdapter<? extends View, ?> cellAdapter, GridCell cell,
-            FrameContext frameContext) {
-        // TODO: Support full-cell backgrounds and horizontal/vertical gravity for all
-        // types of ElementAdapter in GridCell.
-
-        GridCellWidth gridCellWidth = null;
-        if (cell.hasWidth()) {
-            gridCellWidth = cell.getWidth();
-        } else if (cell.hasWidthBinding()) {
-            gridCellWidth = frameContext.getGridCellWidthFromBinding(cell.getWidthBinding());
-        }
-
-        // Default cell is weight = 1 and height = WRAP_CONTENT.
-        boolean isCollapsible = gridCellWidth != null
-                && gridCellWidth.getWidthSpecCase() != WidthSpecCase.WEIGHT
-                && gridCellWidth.getIsCollapsible();
-        LayoutParams params;
-        if (isCollapsible) {
-            params = new LayoutParams(
-                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0.0f, true);
-        } else {
-            params = new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1.0f, false);
-        }
-
-        // If a width is specified on the proto, we expect it to be populated so we can use it.
-        if (gridCellWidth != null) {
-            switch (gridCellWidth.getWidthSpecCase()) {
-                case CONTENT_WIDTH:
-                    params.weight = 0;
-                    params.width = LayoutParams.WRAP_CONTENT;
-                    switch (gridCellWidth.getContentWidth()) {
-                        case CONTENT_WIDTH:
-                            if (cellAdapter.getComputedWidthPx() == LayoutParams.MATCH_PARENT) {
-                                frameContext.reportMessage(MessageType.WARNING,
-                                        ERR_UNSUPPORTED_FEATURE,
-                                        "FIT_PARENT width is invalid for CONTENT_WIDTH"
-                                                + " cell contents.");
-                            } else if (cellAdapter.getComputedWidthPx() != DIMENSION_NOT_SET) {
-                                params.width = cellAdapter.getComputedWidthPx();
-                            }
-                            break;
-                        case INVALID_CONTENT_WIDTH:
-                        default:
-                            frameContext.reportMessage(MessageType.WARNING,
-                                    ERR_GRID_CELL_WIDTH_WITHOUT_CONTENTS,
-                                    String.format("Invalid content width: %s",
-                                            gridCellWidth.getContentWidth().name()));
-                    }
-                    break;
-                case DP:
-                    params.weight = 0;
-                    params.width = (int) LayoutUtils.dpToPx(gridCellWidth.getDp(), getContext());
-                    break;
-                case WEIGHT:
-                    params.weight = gridCellWidth.getWeight();
-                    params.width = 0;
-                    break;
-                case WIDTHSPEC_NOT_SET:
-                default:
-                    frameContext.reportMessage(MessageType.WARNING,
-                            ERR_GRID_CELL_WIDTH_WITHOUT_CONTENTS,
-                            String.format("Invalid content width: %s",
-                                    gridCellWidth.getContentWidth().name()));
-            }
-        }
-
-        params.height = cellAdapter.getComputedHeightPx() == DIMENSION_NOT_SET
-                ? LayoutParams.MATCH_PARENT
-                : cellAdapter.getComputedHeightPx();
-
-        cellAdapter.getElementStyle().applyMargins(getContext(), params);
-
-        params.gravity = cellAdapter.getVerticalGravity(Gravity.TOP);
-
-        cellAdapter.setLayoutParams(params);
-    }
-
-    @VisibleForTesting
-    static GridRowView createView(Context context, Supplier<Boolean> isRtL) {
-        GridRowView viewGroup = new GridRowView(context, isRtL);
-        viewGroup.setOrientation(LinearLayout.HORIZONTAL);
-        viewGroup.setLayoutParams(new LinearLayout.LayoutParams(
-                LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
-        viewGroup.setBaselineAligned(false);
-        viewGroup.setClipToPadding(false);
-        return viewGroup;
-    }
-
-    /** A {@link AdapterKeySupplier} for the {@link GridRowAdapter}. */
-    static class KeySupplier extends SingletonKeySupplier<GridRowAdapter, GridRow> {
-        @Override
-        public String getAdapterTag() {
-            return TAG;
-        }
-
-        @Override
-        public GridRowAdapter getAdapter(Context context, AdapterParameters parameters) {
-            return new GridRowAdapter(context, parameters);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/HostProviders.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/HostProviders.java
deleted file mode 100644
index 65fd653e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/HostProviders.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.piet.host.AssetProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.CustomElementProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.HostBindingProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.LogDataCallback;
-
-/** Wrapper class to hold all host-related objects. */
-public class HostProviders {
-    private final AssetProvider mAssetProvider;
-    private final CustomElementProvider mCustomElementProvider;
-    private final HostBindingProvider mHostBindingProvider;
-    @Nullable
-    private final LogDataCallback mLogDataCallback;
-
-    public HostProviders(AssetProvider assetProvider, CustomElementProvider customElementProvider,
-            HostBindingProvider hostBindingProvider, @Nullable LogDataCallback logDataCallback) {
-        this.mAssetProvider = assetProvider;
-        this.mCustomElementProvider = customElementProvider;
-        this.mHostBindingProvider = hostBindingProvider;
-        this.mLogDataCallback = logDataCallback;
-    }
-
-    public AssetProvider getAssetProvider() {
-        return mAssetProvider;
-    }
-
-    public CustomElementProvider getCustomElementProvider() {
-        return mCustomElementProvider;
-    }
-
-    public HostBindingProvider getHostBindingProvider() {
-        return mHostBindingProvider;
-    }
-
-    @Nullable
-    public LogDataCallback getLogDataCallback() {
-        return mLogDataCallback;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ImageElementAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ImageElementAdapter.java
deleted file mode 100644
index ce2c369..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ImageElementAdapter.java
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import static org.chromium.chrome.browser.feed.library.api.host.imageloader.ImageLoaderApi.DIMENSION_UNKNOWN;
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import android.content.Context;
-import android.widget.ImageView;
-import android.widget.ImageView.ScaleType;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.piet.AdapterFactory.SingletonKeySupplier;
-import org.chromium.chrome.browser.feed.library.piet.ui.AspectRatioScalingImageView;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.BindingValue;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Element;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.ImageElement;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Visibility;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-import org.chromium.components.feed.core.proto.ui.piet.ImagesProto.Image;
-import org.chromium.components.feed.core.proto.ui.piet.ImagesProto.ImageSource;
-
-/** An {@link ElementAdapter} for {@code ImageElement} elements. */
-class ImageElementAdapter extends ElementAdapter<AspectRatioScalingImageView, ImageElement> {
-    private static final String TAG = "ImageElementAdapter";
-
-    @Nullable
-    private LoadImageCallback mCurrentlyLoadingImage;
-
-    @VisibleForTesting
-    ImageElementAdapter(Context context, AdapterParameters parameters) {
-        super(context, parameters, createView(context), KeySupplier.SINGLETON_KEY);
-    }
-
-    @Override
-    ImageElement getModelFromElement(Element baseElement) {
-        if (!baseElement.hasImageElement()) {
-            throw new PietFatalException(ErrorCode.ERR_MISSING_ELEMENT_CONTENTS,
-                    String.format("Missing ImageElement; has %s", baseElement.getElementsCase()));
-        }
-        return baseElement.getImageElement();
-    }
-
-    @Override
-    void onCreateAdapter(ImageElement model, Element baseElement, FrameContext frameContext) {
-        StyleProvider style = getElementStyle();
-        Context context = getContext();
-
-        mWidthPx = style.getWidthSpecPx(context);
-
-        if (style.hasHeight()) {
-            mHeightPx = style.getHeightSpecPx(context);
-        } else {
-            // Defaults to a square when only the width is defined.
-            // TODO: This is not cross-platform standard; should probably get rid of this.
-            mHeightPx = mWidthPx > 0 ? mWidthPx : StyleProvider.DIMENSION_NOT_SET;
-        }
-    }
-
-    @Override
-    void onBindModel(ImageElement model, Element baseElement, FrameContext frameContext) {
-        Image image;
-        switch (model.getContentCase()) {
-            case IMAGE:
-                image = model.getImage();
-                break;
-            case IMAGE_BINDING:
-                BindingValue binding = frameContext.getImageBindingValue(model.getImageBinding());
-                if (!binding.hasImage()) {
-                    if (model.getImageBinding().getIsOptional()) {
-                        setVisibilityOnView(Visibility.GONE);
-                        return;
-                    } else {
-                        throw new PietFatalException(ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                                String.format(
-                                        "Image binding %s had no content", binding.getBindingId()));
-                    }
-                }
-                image = binding.getImage();
-                break;
-            default:
-                throw new PietFatalException(ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                        String.format("Unsupported or missing content in ImageElement: %s",
-                                model.getContentCase()));
-        }
-
-        if (getElementStyle().hasPreLoadFill()) {
-            getBaseView().setImageDrawable(getElementStyle().createPreLoadFill());
-        }
-
-        image = frameContext.filterImageSourcesByMediaQueryCondition(image);
-
-        getBaseView().setDefaultAspectRatio(getAspectRatio(image));
-
-        checkState(
-                mCurrentlyLoadingImage == null, "An image loading callback exists; unbind first");
-        Integer overlayColor = getElementStyle().hasColor() ? getElementStyle().getColor() : null;
-        LoadImageCallback loadImageCallback = createLoadImageCallback(
-                getElementStyle().getScaleType(), overlayColor, frameContext);
-        mCurrentlyLoadingImage = loadImageCallback;
-        getParameters().mHostProviders.getAssetProvider().getImage(image,
-                convertDimensionForImageLoader(mWidthPx), convertDimensionForImageLoader(mHeightPx),
-                loadImageCallback);
-    }
-
-    private int convertDimensionForImageLoader(int dimension) {
-        return dimension < 0 ? DIMENSION_UNKNOWN : dimension;
-    }
-
-    @VisibleForTesting
-    static float getAspectRatio(Image image) {
-        for (ImageSource source : image.getSourcesList()) {
-            if (source.getHeightPx() > 0 && source.getWidthPx() > 0) {
-                return ((float) source.getWidthPx()) / source.getHeightPx();
-            }
-        }
-        return 0.0f;
-    }
-
-    @Override
-    void onUnbindModel() {
-        if (mCurrentlyLoadingImage != null) {
-            mCurrentlyLoadingImage.cancel();
-            mCurrentlyLoadingImage = null;
-        }
-        ImageView imageView = getBaseView();
-        if (imageView != null) {
-            imageView.setImageDrawable(null);
-        }
-    }
-
-    @VisibleForTesting
-    LoadImageCallback createLoadImageCallback(
-            ScaleType scaleType, @Nullable Integer overlayColor, FrameContext frameContext) {
-        return new LoadImageCallback(getBaseView(), scaleType, overlayColor,
-                getElementStyle().getFadeInImageOnLoad(), getParameters(), frameContext);
-    }
-
-    private static AspectRatioScalingImageView createView(Context context) {
-        AspectRatioScalingImageView imageView = new AspectRatioScalingImageView(context);
-        imageView.setCropToPadding(true);
-        return imageView;
-    }
-
-    static class KeySupplier extends SingletonKeySupplier<ImageElementAdapter, ImageElement> {
-        @Override
-        public String getAdapterTag() {
-            return TAG;
-        }
-
-        @Override
-        public ImageElementAdapter getAdapter(Context context, AdapterParameters parameters) {
-            return new ImageElementAdapter(context, parameters);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/KeyedRecyclerPool.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/KeyedRecyclerPool.java
deleted file mode 100644
index b222ec0..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/KeyedRecyclerPool.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-
-import android.util.LruCache;
-
-import androidx.annotation.Nullable;
-
-/**
- * This is a simple implementation of a recycling pool for Adapters.
- *
- * <p>TODO: This should be made real so it supports control of the pool size
- */
-class KeyedRecyclerPool<A extends ElementAdapter<?, ?>> implements RecyclerPool<A> {
-    private final LruCache<RecyclerKey, SingleKeyRecyclerPool<A>> mPoolMap;
-    private final int mCapacityPerPool;
-
-    KeyedRecyclerPool(int maxKeys, int capacityPerPool) {
-        mPoolMap = new LruCache<>(maxKeys);
-        this.mCapacityPerPool = capacityPerPool;
-    }
-
-    @Override
-    @Nullable
-    public A get(RecyclerKey key) {
-        if (key == null) {
-            return null;
-        }
-        SingleKeyRecyclerPool<A> pool = mPoolMap.get(key);
-        if (pool == null) {
-            return null;
-        } else {
-            return pool.get(key);
-        }
-    }
-
-    @Override
-    public void put(RecyclerKey key, A adapter) {
-        checkNotNull(key, "null key for %s", adapter);
-        SingleKeyRecyclerPool<A> pool = mPoolMap.get(key);
-        if (pool == null) {
-            pool = new SingleKeyRecyclerPool<>(key, mCapacityPerPool);
-            mPoolMap.put(key, pool);
-        }
-        pool.put(key, adapter);
-    }
-
-    @Override
-    public void clear() {
-        mPoolMap.evictAll();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/LoadImageCallback.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/LoadImageCallback.java
deleted file mode 100644
index 9bae984..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/LoadImageCallback.java
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.TransitionDrawable;
-import android.widget.ImageView;
-import android.widget.ImageView.ScaleType;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.base.Consumer;
-
-/**
- * Handles loading images from the host. In particular, handles the resizing of images as well as
- * the fading animation.
- */
-public class LoadImageCallback implements Consumer<Drawable> {
-    static final int FADE_IN_ANIMATION_TIME_MS = 300;
-
-    private final ImageView mImageView;
-    private final ScaleType mScaleType;
-    private final long mInitialTime;
-    @Nullable
-    private final Integer mOverlayColor;
-    private final boolean mFadeImage;
-    private final AdapterParameters mParameters;
-
-    private boolean mCancelled;
-
-    @Nullable
-    private Drawable mFinalDrawable;
-
-    LoadImageCallback(ImageView imageView, ScaleType scaleType, @Nullable Integer overlayColor,
-            boolean fadeImage, AdapterParameters parameters, FrameContext frameContext) {
-        this.mImageView = imageView;
-        this.mScaleType = scaleType;
-        this.mOverlayColor = overlayColor;
-        this.mFadeImage = fadeImage;
-        this.mParameters = parameters;
-        this.mInitialTime = parameters.mClock.elapsedRealtime();
-    }
-
-    @Override
-    public void accept(@Nullable Drawable drawable) {
-        if (mCancelled || drawable == null) {
-            return;
-        }
-
-        mImageView.setScaleType(mScaleType);
-
-        final Drawable localDrawable = ViewUtils.applyOverlayColor(drawable, mOverlayColor);
-        this.mFinalDrawable = localDrawable;
-
-        // If we are in the process of binding when we get the image, we should not fade in the
-        // image as the image was cached.
-        if (!shouldFadeInImage()) {
-            mImageView.setImageDrawable(localDrawable);
-            // Invalidating the view as the view doesn't update if not manually updated here.
-            mImageView.invalidate();
-            return;
-        }
-
-        Drawable initialDrawable = mImageView.getDrawable() != null
-                ? mImageView.getDrawable()
-                : new ColorDrawable(Color.TRANSPARENT);
-
-        TransitionDrawable transitionDrawable =
-                new TransitionDrawable(new Drawable[] {initialDrawable, localDrawable});
-        mImageView.setImageDrawable(transitionDrawable);
-        transitionDrawable.setCrossFadeEnabled(true);
-        transitionDrawable.startTransition(FADE_IN_ANIMATION_TIME_MS);
-
-        mImageView.postDelayed(() -> {
-            if (mCancelled) {
-                return;
-            }
-            // Allows GC of the initial drawable and the transition drawable. Additionally
-            // fixes the issue where the transition sometimes doesn't occur, which would
-            // result in blank images.
-            mImageView.setImageDrawable(this.mFinalDrawable);
-        }, FADE_IN_ANIMATION_TIME_MS);
-    }
-
-    private boolean shouldFadeInImage() {
-        return mFadeImage
-                && (mParameters.mClock.elapsedRealtime() - mInitialTime)
-                > mParameters.mHostProviders.getAssetProvider().getFadeImageThresholdMs();
-    }
-
-    void cancel() {
-        this.mCancelled = true;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/MediaQueryHelper.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/MediaQueryHelper.java
deleted file mode 100644
index 379a79e4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/MediaQueryHelper.java
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.content.Context;
-import android.content.res.Configuration;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.ui.LayoutUtils;
-import org.chromium.chrome.browser.feed.library.piet.host.AssetProvider;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-import org.chromium.components.feed.core.proto.ui.piet.MediaQueriesProto.MediaQueryCondition;
-
-import java.util.List;
-
-/** Provides methods for filtering by MediaQueryConditions, based on a static status. */
-public class MediaQueryHelper {
-    private static final String TAG = "MediaQueryHelper";
-
-    private final int mFrameWidthPx;
-    private final int mDeviceOrientation;
-    private final boolean mIsDarkTheme;
-    private final Context mContext;
-
-    MediaQueryHelper(int frameWidthPx, AssetProvider assetProvider, Context context) {
-        this.mFrameWidthPx = frameWidthPx;
-        this.mDeviceOrientation = context.getResources().getConfiguration().orientation;
-        this.mIsDarkTheme = assetProvider.isDarkTheme();
-        this.mContext = context;
-    }
-
-    @VisibleForTesting
-    MediaQueryHelper(
-            int frameWidthPx, int deviceOrientation, boolean isDarkTheme, Context context) {
-        this.mFrameWidthPx = frameWidthPx;
-        this.mDeviceOrientation = deviceOrientation;
-        this.mIsDarkTheme = isDarkTheme;
-        this.mContext = context;
-    }
-
-    boolean areMediaQueriesMet(List<MediaQueryCondition> conditions) {
-        for (MediaQueryCondition condition : conditions) {
-            if (!isMediaQueryMet(condition)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @SuppressWarnings("UnnecessaryDefaultInEnumSwitch")
-    @VisibleForTesting
-    boolean isMediaQueryMet(MediaQueryCondition condition) {
-        switch (condition.getConditionCase()) {
-            case FRAME_WIDTH:
-                int targetWidth =
-                        (int) LayoutUtils.dpToPx(condition.getFrameWidth().getWidth(), mContext);
-                switch (condition.getFrameWidth().getCondition()) {
-                    case EQUALS:
-                        return mFrameWidthPx == targetWidth;
-                    case GREATER_THAN:
-                        return mFrameWidthPx > targetWidth;
-                    case LESS_THAN:
-                        return mFrameWidthPx < targetWidth;
-                    case NOT_EQUALS:
-                        return mFrameWidthPx != targetWidth;
-                    default:
-                }
-                throw new PietFatalException(ErrorCode.ERR_INVALID_MEDIA_QUERY_CONDITION,
-                        String.format("Unhandled ComparisonCondition: %s",
-                                condition.getFrameWidth().getCondition().name()));
-            case ORIENTATION:
-                switch (condition.getOrientation().getOrientation()) {
-                    case LANDSCAPE:
-                        return mDeviceOrientation == Configuration.ORIENTATION_LANDSCAPE;
-                    case UNSPECIFIED:
-                        Logger.w(TAG, "Got UNSPECIFIED orientation; defaulting to PORTRAIT");
-                        // fall through
-                    case PORTRAIT:
-                        return mDeviceOrientation == Configuration.ORIENTATION_PORTRAIT
-                                || mDeviceOrientation == Configuration.ORIENTATION_SQUARE;
-                }
-                throw new PietFatalException(ErrorCode.ERR_INVALID_MEDIA_QUERY_CONDITION,
-                        String.format("Unhandled Orientation: %s",
-                                condition.getOrientation().getOrientation()));
-            case DARK_LIGHT:
-                switch (condition.getDarkLight().getMode()) {
-                    case DARK:
-                        return mIsDarkTheme;
-                    case UNSPECIFIED:
-                        Logger.w(TAG, "Got UNSPECIFIED DarkLightMode; defaulting to LIGHT");
-                        // fall through
-                    case LIGHT:
-                        return !mIsDarkTheme;
-                }
-                throw new PietFatalException(ErrorCode.ERR_INVALID_MEDIA_QUERY_CONDITION,
-                        String.format(
-                                "Unhandled DarkLightMode: %s", condition.getDarkLight().getMode()));
-            default:
-                throw new PietFatalException(ErrorCode.ERR_INVALID_MEDIA_QUERY_CONDITION,
-                        String.format(
-                                "Unhandled MediaQueryCondition: %s", condition.getConditionCase()));
-        }
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof MediaQueryHelper)) {
-            return false;
-        }
-        MediaQueryHelper that = (MediaQueryHelper) o;
-        return mFrameWidthPx == that.mFrameWidthPx && mDeviceOrientation == that.mDeviceOrientation
-                && mIsDarkTheme == that.mIsDarkTheme && mContext.equals(that.mContext);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = mFrameWidthPx;
-        result = 31 * result + mDeviceOrientation;
-        result = 31 * result + (mIsDarkTheme ? 1 : 0);
-        result = 31 * result + mContext.hashCode();
-        return result;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/NoKeyOverwriteHashMap.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/NoKeyOverwriteHashMap.java
deleted file mode 100644
index d2ba4de..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/NoKeyOverwriteHashMap.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-
-import java.util.HashMap;
-
-/** Map that throws if you try to insert a second key with the same value. */
-public class NoKeyOverwriteHashMap<K, V> extends HashMap<K, V> {
-    /** A term for the items this map contains (ex. "Style" or "Template"); used in debug logs. */
-    private final String mTermForContentValue;
-
-    private final ErrorCode mErrorCodeForDuplicate;
-
-    NoKeyOverwriteHashMap(String termForContentValue, ErrorCode errorCodeForDuplicate) {
-        this.mTermForContentValue = termForContentValue;
-        this.mErrorCodeForDuplicate = errorCodeForDuplicate;
-    }
-
-    @Override
-    @Nullable
-    public V put(K key, V value) {
-        if (containsKey(key)) {
-            throw new PietFatalException(mErrorCodeForDuplicate,
-                    String.format("%s key '%s' already defined", mTermForContentValue, key));
-        }
-        return super.put(key, value);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ParameterizedTextElementAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ParameterizedTextElementAdapter.java
deleted file mode 100644
index 56d3064..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ParameterizedTextElementAdapter.java
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.content.Context;
-import android.widget.TextView;
-
-import org.chromium.chrome.browser.feed.library.piet.DebugLogger.MessageType;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.BindingValue;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.TextElement;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-import org.chromium.components.feed.core.proto.ui.piet.TextProto.ParameterizedText;
-
-/** An {@link ElementAdapter} which manages {@code ParameterizedText} elements. */
-class ParameterizedTextElementAdapter extends TextElementAdapter {
-    private static final String TAG = "ParameterizedTextElementAdapter";
-
-    ParameterizedTextElementAdapter(Context context, AdapterParameters parameters) {
-        super(context, parameters);
-    }
-
-    @Override
-    void setTextOnView(FrameContext frameContext, TextElement textLine) {
-        switch (textLine.getContentCase()) {
-            case PARAMETERIZED_TEXT:
-                // No bindings found, so use the inlined value (or empty if not set)
-                setTextOnView(getBaseView(), textLine.getParameterizedText());
-                break;
-            case PARAMETERIZED_TEXT_BINDING:
-                BindingValue bindingValue = frameContext.getParameterizedTextBindingValue(
-                        textLine.getParameterizedTextBinding());
-
-                if (!bindingValue.hasParameterizedText()
-                        && !textLine.getParameterizedTextBinding().getIsOptional()) {
-                    throw new PietFatalException(ErrorCode.ERR_MISSING_BINDING_VALUE,
-                            String.format("Parameterized text binding %s had no content",
-                                    bindingValue.getBindingId()));
-                }
-
-                setTextOnView(getBaseView(), bindingValue.getParameterizedText());
-                break;
-            default:
-                frameContext.reportMessage(MessageType.ERROR,
-                        ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                        String.format("TextElement missing ParameterizedText content; has %s",
-                                textLine.getContentCase()));
-                setTextOnView(getBaseView(), ParameterizedText.getDefaultInstance());
-        }
-    }
-
-    private void setTextOnView(TextView textView, ParameterizedText parameterizedText) {
-        if (!parameterizedText.hasText()) {
-            textView.setText("");
-            return;
-        }
-
-        textView.setText(getTemplatedStringEvaluator().evaluate(
-                getParameters().mHostProviders.getAssetProvider(), parameterizedText));
-    }
-
-    static class KeySupplier extends TextElementKeySupplier<ParameterizedTextElementAdapter> {
-        @Override
-        public String getAdapterTag() {
-            return TAG;
-        }
-
-        @Override
-        public ParameterizedTextElementAdapter getAdapter(
-                Context context, AdapterParameters parameters) {
-            return new ParameterizedTextElementAdapter(context, parameters);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ParameterizedTextEvaluator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ParameterizedTextEvaluator.java
deleted file mode 100644
index 8ef184e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ParameterizedTextEvaluator.java
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.os.Build;
-import android.os.Build.VERSION_CODES;
-import android.text.Html;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.piet.host.AssetProvider;
-import org.chromium.components.feed.core.proto.ui.piet.TextProto.ParameterizedText;
-
-import java.util.ArrayList;
-import java.util.IllegalFormatException;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/** Helper class to format templated strings when rendering cards. */
-public class ParameterizedTextEvaluator {
-    private static final String TAG = "ParameterizedTextEvalua";
-    private final Clock mClock;
-
-    ParameterizedTextEvaluator(Clock clock) {
-        this.mClock = clock;
-    }
-
-    /** Evaluates the given parameterized string, respecting the HTML setting */
-    public CharSequence evaluate(AssetProvider assetProvider, ParameterizedText templatedString) {
-        if (!templatedString.hasText()) {
-            Logger.w(TAG, "Got templated string with no display string");
-            return templatedString.getText();
-        }
-
-        String evaluated = evaluateText(assetProvider, templatedString);
-
-        if (templatedString.getIsHtml()) {
-            if (Build.VERSION.SDK_INT < VERSION_CODES.N) {
-                return Html.fromHtml(evaluated);
-            } else {
-                return Html.fromHtml(evaluated, Html.FROM_HTML_MODE_LEGACY);
-            }
-        } else {
-            return evaluated;
-        }
-    }
-
-    /**
-     * Evaluates the given ParameterizedText, and returns the raw evaluated value, without any Html
-     * wrapping.
-     */
-    private String evaluateText(AssetProvider assetProvider, ParameterizedText templatedString) {
-        if (!templatedString.hasText()) {
-            Logger.w(TAG, "Got templated string with no display string");
-            return templatedString.getText();
-        }
-
-        if (templatedString.getParametersCount() == 0) {
-            return templatedString.getText();
-        }
-
-        List<String> params = new ArrayList<>();
-        for (ParameterizedText.Parameter param : templatedString.getParametersList()) {
-            String value = evaluateParam(assetProvider, param);
-            // Add a placeholder for any invalid parameters so that it will be obvious which one
-            // failed.
-            if (value == null) {
-                value = "(invalid param)";
-            }
-            params.add(value);
-        }
-
-        String displayString = templatedString.getText();
-        try {
-            return String.format(
-                    displayString, (Object[]) params.toArray(new String[params.size()]));
-        } catch (IllegalFormatException e) {
-            // Don't crash if we get invalid data - just log the display string and the error.
-            Logger.e(TAG, e, "Error formatting display string \"%s\"", displayString);
-            return displayString;
-        }
-    }
-
-    @Nullable
-    private String evaluateParam(AssetProvider assetProvider, ParameterizedText.Parameter param) {
-        if (param.hasTimestampSeconds()) {
-            long elapsedTimeMillis = mClock.currentTimeMillis()
-                    - TimeUnit.SECONDS.toMillis(param.getTimestampSeconds());
-            return assetProvider.getRelativeElapsedString(elapsedTimeMillis);
-        }
-        return null;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietFatalException.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietFatalException.java
deleted file mode 100644
index 2b8281f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietFatalException.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-
-/** Exception that carries a Piet error code */
-class PietFatalException extends IllegalArgumentException {
-    private final ErrorCode mErrorCode;
-
-    PietFatalException(ErrorCode errorCode, String message) {
-        super(message);
-        this.mErrorCode = errorCode;
-    }
-
-    ErrorCode getErrorCode() {
-        return mErrorCode;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietManager.java
deleted file mode 100644
index 0b96c37a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietManager.java
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.content.Context;
-import android.view.ViewGroup;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.api.host.config.DebugBehavior;
-import org.chromium.chrome.browser.feed.library.common.functional.Suppliers;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.common.time.SystemClockImpl;
-import org.chromium.chrome.browser.feed.library.common.ui.LayoutUtils;
-import org.chromium.chrome.browser.feed.library.piet.host.ActionHandler;
-import org.chromium.chrome.browser.feed.library.piet.host.AssetProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.CustomElementProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.EmptyStringFormatter;
-import org.chromium.chrome.browser.feed.library.piet.host.EventLogger;
-import org.chromium.chrome.browser.feed.library.piet.host.HostBindingProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.ImageLoader;
-import org.chromium.chrome.browser.feed.library.piet.host.LogDataCallback;
-import org.chromium.chrome.browser.feed.library.piet.host.NullImageLoader;
-import org.chromium.chrome.browser.feed.library.piet.host.NullTypefaceProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.StringFormatter;
-import org.chromium.chrome.browser.feed.library.piet.host.ThrowingCustomElementProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.TypefaceProvider;
-
-/** Manages a top-level session of Piet. */
-public interface PietManager {
-    static Builder builder() {
-        return new Builder();
-    }
-
-    FrameAdapter createPietFrameAdapter(Supplier<ViewGroup> cardViewProducer,
-            ActionHandler actionHandler, EventLogger eventLogger, Context context);
-
-    FrameAdapter createPietFrameAdapter(Supplier<ViewGroup> cardViewProducer,
-            ActionHandler actionHandler, EventLogger eventLogger, Context context,
-            @Nullable LogDataCallback logDataCallback);
-
-    void purgeRecyclerPools();
-
-    /**
-     * Builder for PietManager that provides defaults wherever possible
-     * TODO(crbug.com/1029183): Builder and its ctor were made public as a work-around for a method
-     * not found exception in PietManagerImplTest.
-     */
-    public class Builder {
-        private static final NullImageLoader BLANK_IMAGE_LOADER = new NullImageLoader();
-        private static final StringFormatter EMPTY_STRING_FORMATTER = new EmptyStringFormatter();
-        private static final Supplier<Integer> CORNER_RADIUS_DEFAULT = Suppliers.of(0);
-        private static final Supplier<Boolean> DARK_THEME_DEFAULT = Suppliers.of(false);
-        private static final Supplier<Long> FADE_IMAGE_THRESHOLD_DEFAULT =
-                Suppliers.of(Long.MAX_VALUE);
-        private static final TypefaceProvider NULL_TYPEFACE_PROVIDER = new NullTypefaceProvider();
-
-        private ImageLoader mImageLoader = BLANK_IMAGE_LOADER;
-        private StringFormatter mStringFormatter = EMPTY_STRING_FORMATTER;
-        private Supplier<Integer> mDefaultCornerRadiusSupplier = CORNER_RADIUS_DEFAULT;
-        private Supplier<Boolean> mIsDarkThemeSupplier = DARK_THEME_DEFAULT;
-        private Supplier<Long> mFadeImageThresholdMsSupplier = FADE_IMAGE_THRESHOLD_DEFAULT;
-        private TypefaceProvider mTypefaceProvider = NULL_TYPEFACE_PROVIDER;
-        private Supplier<Boolean> mIsRtLSupplier = LayoutUtils::isDefaultLocaleRtl;
-
-        private DebugBehavior mDebugBehavior = DebugBehavior.SILENT;
-        private CustomElementProvider mCustomElementProvider;
-        private HostBindingProvider mHostBindingProvider;
-        private Clock mClock;
-        private boolean mAllowLegacyRoundedCornerImpl;
-        private boolean mAllowOutlineRoundedCornerImpl;
-
-        public Builder() {}
-
-        public Builder setDebugBehavior(DebugBehavior debugBehavior) {
-            this.mDebugBehavior = debugBehavior;
-            return this;
-        }
-
-        public Builder setCustomElementProvider(CustomElementProvider customElementProvider) {
-            this.mCustomElementProvider = customElementProvider;
-            return this;
-        }
-
-        public Builder setHostBindingProvider(HostBindingProvider hostBindingProvider) {
-            this.mHostBindingProvider = hostBindingProvider;
-            return this;
-        }
-
-        public Builder setClock(Clock clock) {
-            this.mClock = clock;
-            return this;
-        }
-
-        /**
-         * Use the rounded corner optimizations on JB/KK for better performance at the expense of
-         * antialiasing.
-         */
-        public Builder setAllowLegacyRoundedCornerImpl(boolean allowLegacyRoundedCornerImpl) {
-            this.mAllowLegacyRoundedCornerImpl = allowLegacyRoundedCornerImpl;
-            return this;
-        }
-
-        /**
-         * Use the clipToOutline rounded corner optimizations on L+ when all four corners are
-         * rounded for better performance.
-         */
-        public Builder setAllowOutlineRoundedCornerImpl(boolean allowOutlineRoundedCornerImpl) {
-            this.mAllowOutlineRoundedCornerImpl = allowOutlineRoundedCornerImpl;
-            return this;
-        }
-
-        // AssetProvider-related setters
-        public Builder setImageLoader(ImageLoader imageLoader) {
-            this.mImageLoader = imageLoader;
-            return this;
-        }
-
-        public Builder setStringFormatter(StringFormatter stringFormatter) {
-            this.mStringFormatter = stringFormatter;
-            return this;
-        }
-
-        public Builder setDefaultCornerRadius(Supplier<Integer> defaultCornerRadiusSupplier) {
-            this.mDefaultCornerRadiusSupplier = defaultCornerRadiusSupplier;
-            return this;
-        }
-
-        public Builder setFadeImageThresholdMs(Supplier<Long> fadeImageThresholdMsSupplier) {
-            this.mFadeImageThresholdMsSupplier = fadeImageThresholdMsSupplier;
-            return this;
-        }
-
-        public Builder setIsDarkTheme(Supplier<Boolean> isDarkThemeSupplier) {
-            this.mIsDarkThemeSupplier = isDarkThemeSupplier;
-            return this;
-        }
-
-        public Builder setIsRtL(Supplier<Boolean> isRtLSupplier) {
-            this.mIsRtLSupplier = isRtLSupplier;
-            return this;
-        }
-
-        public Builder setTypefaceProvider(TypefaceProvider typefaceProvider) {
-            this.mTypefaceProvider = typefaceProvider;
-            return this;
-        }
-        // End AssetProvider-related setters
-
-        public PietManager build() {
-            mCustomElementProvider = mCustomElementProvider == null
-                    ? new ThrowingCustomElementProvider()
-                    : mCustomElementProvider;
-            mHostBindingProvider =
-                    mHostBindingProvider == null ? new HostBindingProvider() : mHostBindingProvider;
-            mClock = mClock == null ? new SystemClockImpl() : mClock;
-
-            AssetProvider assetProvider = new AssetProvider(mImageLoader, mStringFormatter,
-                    mDefaultCornerRadiusSupplier, mFadeImageThresholdMsSupplier,
-                    mIsDarkThemeSupplier, mIsRtLSupplier, mTypefaceProvider);
-
-            return new PietManagerImpl(mDebugBehavior, assetProvider, mCustomElementProvider,
-                    mHostBindingProvider, mClock, mAllowLegacyRoundedCornerImpl,
-                    mAllowOutlineRoundedCornerImpl);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietManagerImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietManagerImpl.java
deleted file mode 100644
index 75b2f21..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietManagerImpl.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.content.Context;
-import android.view.ViewGroup;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.api.host.config.DebugBehavior;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.piet.host.ActionHandler;
-import org.chromium.chrome.browser.feed.library.piet.host.AssetProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.CustomElementProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.EventLogger;
-import org.chromium.chrome.browser.feed.library.piet.host.HostBindingProvider;
-import org.chromium.chrome.browser.feed.library.piet.host.LogDataCallback;
-
-/** Implementation of {@link PietManager}. */
-class PietManagerImpl implements PietManager {
-    @VisibleForTesting
-    final AssetProvider mAssetProvider;
-    private final DebugBehavior mDebugBehavior;
-    private final CustomElementProvider mCustomElementProvider;
-    private final HostBindingProvider mHostBindingProvider;
-    private final Clock mClock;
-    private final boolean mAllowLegacyRoundedCornerImpl;
-    private final boolean mAllowOutlineRoundedCornerImpl;
-    @VisibleForTesting
-    @Nullable
-    AdapterParameters mAdapterParameters;
-
-    PietManagerImpl(DebugBehavior debugBehavior, AssetProvider assetProvider,
-            CustomElementProvider customElementProvider, HostBindingProvider hostBindingProvider,
-            Clock clock, boolean allowLegacyRoundedCornerImpl,
-            boolean allowOutlineRoundedCornerImpl) {
-        this.mDebugBehavior = debugBehavior;
-        this.mAssetProvider = assetProvider;
-        this.mCustomElementProvider = customElementProvider;
-        this.mHostBindingProvider = hostBindingProvider;
-        this.mClock = clock;
-        this.mAllowLegacyRoundedCornerImpl = allowLegacyRoundedCornerImpl;
-        this.mAllowOutlineRoundedCornerImpl = allowOutlineRoundedCornerImpl;
-    }
-
-    @Override
-    public FrameAdapter createPietFrameAdapter(Supplier<ViewGroup> cardViewProducer,
-            ActionHandler actionHandler, EventLogger eventLogger, Context context) {
-        return createPietFrameAdapter(cardViewProducer, actionHandler, eventLogger, context, null);
-    }
-
-    @Override
-    public FrameAdapter createPietFrameAdapter(Supplier<ViewGroup> cardViewProducer,
-            ActionHandler actionHandler, EventLogger eventLogger, Context context,
-            @Nullable LogDataCallback logDataCallback) {
-        AdapterParameters parameters =
-                getAdapterParameters(context, cardViewProducer, logDataCallback);
-
-        return new FrameAdapterImpl(
-                context, parameters, actionHandler, eventLogger, mDebugBehavior);
-    }
-
-    /**
-     * Return the {@link AdapterParameters}. If one doesn't exist this will create a new instance.
-     * The
-     * {@code AdapterParameters} is scoped to the {@code Context}.
-     */
-    @VisibleForTesting
-    AdapterParameters getAdapterParameters(Context context, Supplier<ViewGroup> cardViewProducer,
-            @Nullable LogDataCallback logDataCallback) {
-        if (mAdapterParameters == null || mAdapterParameters.mContext != context) {
-            mAdapterParameters = new AdapterParameters(context, cardViewProducer,
-                    new HostProviders(mAssetProvider, mCustomElementProvider, mHostBindingProvider,
-                            logDataCallback),
-                    mClock, mAllowLegacyRoundedCornerImpl, mAllowOutlineRoundedCornerImpl);
-        }
-        return mAdapterParameters;
-    }
-
-    @Override
-    public void purgeRecyclerPools() {
-        if (mAdapterParameters != null) {
-            AdapterParameters adapterParametersNonNull = mAdapterParameters;
-            adapterParametersNonNull.mElementAdapterFactory.purgeRecyclerPools();
-            adapterParametersNonNull.mPietStylesHelperFactory.purge();
-            adapterParametersNonNull.mRoundedCornerMaskCache.purge();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietStylesHelper.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietStylesHelper.java
deleted file mode 100644
index 05785c85..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietStylesHelper.java
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-
-import android.util.LruCache;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.piet.DebugLogger.MessageType;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-import org.chromium.components.feed.core.proto.ui.piet.MediaQueriesProto.MediaQueryCondition;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.PietSharedState;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Stylesheet;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Stylesheets;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Template;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.BoundStyle;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.Style;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.StyleIdsStack;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/** This class provides support helpers methods for managing styles in Piet. */
-public class PietStylesHelper {
-    private static final String TAG = "PietStylesHelper";
-
-    private final Map<Stylesheets, NoKeyOverwriteHashMap<String, Style>> mMultiStylesheetScopes =
-            new NoKeyOverwriteHashMap<>("Style", ErrorCode.ERR_DUPLICATE_STYLESHEET);
-    private final Map<String, Stylesheet> mStylesheet =
-            new NoKeyOverwriteHashMap<>("Stylesheet", ErrorCode.ERR_DUPLICATE_STYLESHEET);
-    private final Map<String, Template> mTemplates =
-            new NoKeyOverwriteHashMap<>("Template", ErrorCode.ERR_DUPLICATE_TEMPLATE);
-
-    private final MediaQueryHelper mMediaQueryHelper;
-
-    private PietStylesHelper(
-            List<PietSharedState> pietSharedStates, MediaQueryHelper mediaQueryHelper) {
-        this.mMediaQueryHelper = mediaQueryHelper;
-        for (PietSharedState sharedState : pietSharedStates) {
-            if (sharedState.getStylesheetsCount() > 0) {
-                for (Stylesheet stylesheet : sharedState.getStylesheetsList()) {
-                    if (mediaQueryHelper.areMediaQueriesMet(stylesheet.getConditionsList())) {
-                        mStylesheet.put(stylesheet.getStylesheetId(), stylesheet);
-                    }
-                }
-            }
-
-            for (Template template : sharedState.getTemplatesList()) {
-                if (mediaQueryHelper.areMediaQueriesMet(template.getConditionsList())) {
-                    mTemplates.put(template.getTemplateId(), template);
-                }
-            }
-        }
-    }
-
-    boolean areMediaQueriesMet(List<MediaQueryCondition> conditions) {
-        return mMediaQueryHelper.areMediaQueriesMet(conditions);
-    }
-
-    @Nullable
-    Stylesheet getStylesheet(String stylesheetId) {
-        return mStylesheet.get(stylesheetId);
-    }
-
-    /** Returns a Map of style_id to Style. This represents the Stylesheet. */
-    NoKeyOverwriteHashMap<String, Style> getStylesheetMap(
-            Stylesheets stylesheetRefs, DebugLogger debugLogger) {
-        if (mMultiStylesheetScopes.containsKey(stylesheetRefs)) {
-            return mMultiStylesheetScopes.get(stylesheetRefs);
-        }
-
-        NoKeyOverwriteHashMap<String, Style> styleMap =
-                new NoKeyOverwriteHashMap<>("Style", ErrorCode.ERR_DUPLICATE_STYLE);
-
-        // Add inline stylesheets.
-        for (Stylesheet stylesheet : stylesheetRefs.getStylesheetsList()) {
-            addStylesToMapIfMediaQueryConditionsMet(stylesheet, styleMap);
-        }
-
-        // Add stylesheets referenced from PietSharedState.
-        for (String stylesheetId : stylesheetRefs.getStylesheetIdsList()) {
-            Stylesheet stylesheet = mStylesheet.get(stylesheetId);
-            if (stylesheet == null) {
-                String message = String.format(
-                        "Stylesheet [%s] was not found in the PietSharedState", stylesheetId);
-                debugLogger.recordMessage(
-                        MessageType.WARNING, ErrorCode.ERR_MISSING_STYLESHEET, message);
-                Logger.w(TAG, message);
-                continue;
-            }
-            addStylesToMapIfMediaQueryConditionsMet(stylesheet, styleMap);
-        }
-
-        mMultiStylesheetScopes.put(stylesheetRefs, styleMap);
-
-        return styleMap;
-    }
-
-    /** Adds all styles from the Stylesheet to the Map, subject to MediaQueryCondition filtering. */
-    private void addStylesToMapIfMediaQueryConditionsMet(
-            Stylesheet stylesheet, NoKeyOverwriteHashMap<String, Style> styleMap) {
-        if (!areMediaQueriesMet(stylesheet.getConditionsList())) {
-            return;
-        }
-        for (Style style : stylesheet.getStylesList()) {
-            if (!areMediaQueriesMet(style.getConditionsList())) {
-                continue;
-            }
-            styleMap.put(style.getStyleId(), style);
-        }
-    }
-
-    /** Returns a {@link Template} for the template */
-    @Nullable
-    public Template getTemplate(String templateId) {
-        return mTemplates.get(templateId);
-    }
-
-    void addSharedStateTemplatesToFrame(Map<String, Template> frameTemplates) {
-        frameTemplates.putAll(mTemplates);
-    }
-
-    static Style mergeStyleIdsStack(
-            StyleIdsStack stack, Map<String, Style> styleMap, @Nullable FrameContext frameContext) {
-        return mergeStyleIdsStack(Style.getDefaultInstance(), stack, styleMap, frameContext);
-    }
-
-    /**
-     * Given a StyleIdsStack, a base style, and a styleMap that contains the styles definition,
-     * returns a Style that is the proto-merge of all the styles in the stack, starting with the
-     * base.
-     */
-    static Style mergeStyleIdsStack(Style baseStyle, StyleIdsStack stack,
-            Map<String, Style> styleMap, @Nullable FrameContext frameContext) {
-        Style.Builder mergedStyle = baseStyle.toBuilder();
-        for (String style : stack.getStyleIdsList()) {
-            if (styleMap.containsKey(style)) {
-                mergedStyle.mergeFrom(styleMap.get(style)).build();
-            } else {
-                String error = String.format(
-                        "Unable to bind style [%s], style not found in Stylesheet", style);
-                if (frameContext != null) {
-                    frameContext.reportMessage(
-                            MessageType.ERROR, ErrorCode.ERR_MISSING_STYLE, error);
-                }
-                Logger.w(TAG, error);
-            }
-        }
-        if (stack.hasStyleBinding()) {
-            // LINT.IfChange
-            FrameContext localFrameContext = checkNotNull(
-                    frameContext, "Binding styles not supported when frameContext is null");
-            BoundStyle boundStyle = localFrameContext.getStyleFromBinding(stack.getStyleBinding());
-            if (boundStyle.hasBackground()) {
-                mergedStyle.setBackground(mergedStyle.getBackground().toBuilder().mergeFrom(
-                        boundStyle.getBackground()));
-            }
-            if (boundStyle.hasColor()) {
-                mergedStyle.setColor(boundStyle.getColor());
-            }
-            if (boundStyle.hasImageLoadingSettings()) {
-                mergedStyle.setImageLoadingSettings(
-                        mergedStyle.getImageLoadingSettings().toBuilder().mergeFrom(
-                                boundStyle.getImageLoadingSettings()));
-            }
-            if (boundStyle.hasScaleType()) {
-                mergedStyle.setScaleType(boundStyle.getScaleType());
-            }
-            // LINT.ThenChange
-        }
-        return mergedStyle.build();
-    }
-
-    @VisibleForTesting
-    static class PietStylesHelperKey {
-        private final List<PietSharedState> mPietSharedStates;
-        private final MediaQueryHelper mMediaQueryHelper;
-
-        PietStylesHelperKey(
-                List<PietSharedState> pietSharedStates, MediaQueryHelper mediaQueryHelper) {
-            this.mPietSharedStates = pietSharedStates;
-            this.mMediaQueryHelper = mediaQueryHelper;
-        }
-
-        PietStylesHelper newPietStylesHelper() {
-            return new PietStylesHelper(mPietSharedStates, mMediaQueryHelper);
-        }
-
-        @SuppressWarnings({"ReferenceEquality", "EqualsUsingHashCode"})
-        @Override
-        public boolean equals(@Nullable Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (!(o instanceof PietStylesHelperKey)) {
-                return false;
-            }
-            PietStylesHelperKey that = (PietStylesHelperKey) o;
-
-            if (!mMediaQueryHelper.equals(that.mMediaQueryHelper)
-                    || mPietSharedStates.size() != that.mPietSharedStates.size()) {
-                return false;
-            }
-            // Compare the two lists of PietSharedState in an container-independent way.
-            // Add everything from "this" list to a list, then remove everything from "that" list,
-            // and ensure the list is empty. O(N^2) will become a problem with large numbers of
-            // shared states, but we expect this to usually be less than ~10. Comparing .equals() on
-            // PietSharedState protos is very expensive - shortcut with hashcode.
-            ArrayList<Integer> sharedStateHashCodes = new ArrayList<>();
-            for (PietSharedState sharedState : mPietSharedStates) {
-                sharedStateHashCodes.add(sharedState.hashCode());
-            }
-            for (PietSharedState sharedState : that.mPietSharedStates) {
-                if (!sharedStateHashCodes.remove((Integer) sharedState.hashCode())) {
-                    return false;
-                }
-            }
-            return sharedStateHashCodes.isEmpty();
-        }
-
-        @Override
-        public int hashCode() {
-            int result = mPietSharedStates.hashCode();
-            result = 31 * result + mMediaQueryHelper.hashCode();
-            return result;
-        }
-    }
-
-    /** Class that creates and caches PietStylesHelpers. */
-    static class PietStylesHelperFactory {
-        // TODO: Make this size configurable.
-        private static final int DEFAULT_STYLES_HELPER_POOL_SIZE = 8;
-
-        final LruCache<PietStylesHelperKey, PietStylesHelper> mStylesHelpers;
-
-        PietStylesHelperFactory() {
-            this.mStylesHelpers = new LruCache<PietStylesHelperKey, PietStylesHelper>(
-                    DEFAULT_STYLES_HELPER_POOL_SIZE) {
-                @Override
-                protected PietStylesHelper create(PietStylesHelperKey key) {
-                    return key.newPietStylesHelper();
-                }
-            };
-        }
-
-        PietStylesHelper get(
-                List<PietSharedState> pietSharedStates, MediaQueryHelper mediaQueryHelper) {
-            return checkNotNull(mStylesHelpers.get(
-                    new PietStylesHelperKey(pietSharedStates, mediaQueryHelper)));
-        }
-
-        void purge() {
-            mStylesHelpers.evictAll();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/RecyclerKey.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/RecyclerKey.java
deleted file mode 100644
index b97a54a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/RecyclerKey.java
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-/**
- * Key for a {@link RecyclerPool}; objects that can be bound to the same model have an equal key.
- * Extend and override hashCode and equals for more granular specification of which objects are
- * compatible for recycling. (ex. {@link TextElementAdapter} is only compatible with other adapters
- * that have the same size, font weight, and italic)
- */
-class RecyclerKey {}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/RecyclerPool.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/RecyclerPool.java
deleted file mode 100644
index b05bf8f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/RecyclerPool.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import androidx.annotation.Nullable;
-
-/**
- * Interface defining a simple Pool of Adapters.
- *
- * @param <A> The adapter being managed by the {@link RecyclerPool}
- */
-interface RecyclerPool<A extends ElementAdapter<?, ?>> {
-    /**
-     * Return an {@link ElementAdapter} matching the {@link RecyclerKey} or null if one isn't found.
-     */
-    @Nullable
-    A get(RecyclerKey key);
-
-    /** Put a {@link ElementAdapter} with a {@link RecyclerKey} into the pool. */
-    void put(RecyclerKey key, A adapter);
-
-    /** Clear everything out of the recycler pool. */
-    void clear();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/SingleKeyRecyclerPool.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/SingleKeyRecyclerPool.java
deleted file mode 100644
index a39bf140..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/SingleKeyRecyclerPool.java
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import androidx.annotation.Nullable;
-import androidx.core.util.Pools.SimplePool;
-
-/** A very simple, single pool version of a {@link RecyclerPool} */
-class SingleKeyRecyclerPool<A extends ElementAdapter<?, ?>> implements RecyclerPool<A> {
-    private static final String KEY_ERROR_MESSAGE = "Given key %s does not match singleton key %s";
-
-    private final RecyclerKey mSingletonKey;
-    private final int mCapacity;
-
-    private SimplePool<A> mPool;
-
-    SingleKeyRecyclerPool(RecyclerKey key, int capacity) {
-        mSingletonKey = key;
-        this.mCapacity = capacity;
-        mPool = new SimplePool<>(capacity);
-    }
-
-    @Nullable
-    @Override
-    public A get(RecyclerKey key) {
-        if (!mSingletonKey.equals(key)) {
-            throw new IllegalArgumentException(
-                    String.format(KEY_ERROR_MESSAGE, key, mSingletonKey));
-        }
-        return mPool.acquire();
-    }
-
-    @Override
-    public void put(RecyclerKey key, A adapter) {
-        if (key == null) {
-            throw new NullPointerException(String.format("null key for %s", adapter));
-        }
-        if (!mSingletonKey.equals(key)) {
-            throw new IllegalArgumentException(
-                    String.format(KEY_ERROR_MESSAGE, key, mSingletonKey));
-        }
-        mPool.release(adapter);
-    }
-
-    @Override
-    public void clear() {
-        mPool = new SimplePool<>(mCapacity);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/StyleProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/StyleProvider.java
deleted file mode 100644
index 9bd4331b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/StyleProvider.java
+++ /dev/null
@@ -1,462 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.content.Context;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.view.ViewGroup.MarginLayoutParams;
-import android.view.ViewOutlineProvider;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.ImageView.ScaleType;
-
-import androidx.annotation.Nullable;
-import androidx.core.view.ViewCompat;
-
-import org.chromium.chrome.browser.feed.library.common.ui.LayoutUtils;
-import org.chromium.chrome.browser.feed.library.piet.host.AssetProvider;
-import org.chromium.chrome.browser.feed.library.piet.ui.BorderDrawable;
-import org.chromium.chrome.browser.feed.library.piet.ui.GradientDrawable;
-import org.chromium.chrome.browser.feed.library.piet.ui.RoundedCornerMaskCache;
-import org.chromium.chrome.browser.feed.library.piet.ui.RoundedCornerViewHelper;
-import org.chromium.chrome.browser.feed.library.piet.ui.RoundedCornerWrapperView;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-import org.chromium.components.feed.core.proto.ui.piet.GradientsProto.Fill;
-import org.chromium.components.feed.core.proto.ui.piet.RoundedCornersProto.RoundedCorners;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.Borders;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.Borders.Edges;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.EdgeWidths;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.Font;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.Style;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.Style.HeightSpecCase;
-
-/**
- * Class which understands how to create the current styles, converting from Piet to Android values
- * as desired (ex. Piet gravity to Android gravity).
- *
- * <p>Feel free to add "has..." methods for any of the fields if needed.
- */
-class StyleProvider {
-    /**
-     * Value returned by get(Height|Width)SpecPx when an explicit value for the dimension has not
-     * been computed, and it should be set by the parent instead.
-     */
-    public static final int DIMENSION_NOT_SET = -3;
-
-    // For borders with no rounded corners.
-    private static final float[] ZERO_RADIUS = new float[] {0, 0, 0, 0, 0, 0, 0, 0};
-
-    private final Style mStyle;
-    private final AssetProvider mAssetProvider;
-
-    StyleProvider(AssetProvider assetProvider) {
-        this.mStyle = Style.getDefaultInstance();
-        this.mAssetProvider = assetProvider;
-    }
-
-    StyleProvider(Style style, AssetProvider assetProvider) {
-        this.mStyle = style;
-        this.mAssetProvider = assetProvider;
-    }
-
-    /** Default font or foreground color */
-    public int getColor() {
-        return mStyle.getColor();
-    }
-
-    /** Whether a color is explicitly specified */
-    public boolean hasColor() {
-        return mStyle.hasColor();
-    }
-
-    /** This style's background */
-    public Fill getBackground() {
-        return mStyle.getBackground();
-    }
-
-    /** The pre-load fill for this style */
-    public Fill getPreLoadFill() {
-        return mStyle.getImageLoadingSettings().getPreLoadFill();
-    }
-
-    /** Whether the style has a pre-load fill */
-    public boolean hasPreLoadFill() {
-        return mStyle.getImageLoadingSettings().hasPreLoadFill();
-    }
-
-    /** Whether to fade in the image after it's loaded */
-    public boolean getFadeInImageOnLoad() {
-        return mStyle.getImageLoadingSettings().getFadeInImageOnLoad();
-    }
-
-    /** Image scale type on this style */
-    public ImageView.ScaleType getScaleType() {
-        switch (mStyle.getScaleType()) {
-            case CENTER_CROP:
-                return ScaleType.CENTER_CROP;
-            case CENTER_INSIDE:
-            case SCALE_TYPE_UNSPECIFIED:
-                return ScaleType.FIT_CENTER;
-        }
-        throw new PietFatalException(ErrorCode.ERR_MISSING_OR_UNHANDLED_CONTENT,
-                String.format("Unsupported ScaleType: %s", mStyle.getScaleType()));
-    }
-
-    /** The {@link RoundedCorners} to be used with the background color. */
-    public RoundedCorners getRoundedCorners() {
-        return mStyle.getRoundedCorners();
-    }
-
-    /** Whether rounded corners are explicitly specified */
-    public boolean hasRoundedCorners() {
-        if (!mStyle.hasRoundedCorners()) {
-            return false;
-        }
-        RoundedCorners roundedCorners = mStyle.getRoundedCorners();
-        int radiusOverride = roundedCorners.getUseHostRadiusOverride()
-                ? mAssetProvider.getDefaultCornerRadius()
-                : 0;
-        return RoundedCornerViewHelper.hasValidRoundedCorners(roundedCorners, radiusOverride);
-    }
-
-    /** The font for this style */
-    public Font getFont() {
-        return mStyle.getFont();
-    }
-
-    /** This style's padding */
-    public EdgeWidths getPadding() {
-        return mStyle.getPadding();
-    }
-
-    /** This style's margins */
-    public EdgeWidths getMargins() {
-        return mStyle.getMargins();
-    }
-
-    /** Whether this style has borders */
-    public boolean hasBorders() {
-        return mStyle.getBorders().getWidth() > 0;
-    }
-
-    /** This style's borders */
-    public Borders getBorders() {
-        return mStyle.getBorders();
-    }
-
-    /** The max_lines for a TextView */
-    public int getMaxLines() {
-        return mStyle.getMaxLines();
-    }
-
-    /** The min_height for a view */
-    public int getMinHeight() {
-        return mStyle.getMinHeight();
-    }
-
-    /**
-     * Height of a view in px, or {@link LayoutParams#WRAP_CONTENT} or {@link
-     * LayoutParams#MATCH_PARENT}, or {@link StyleProvider#DIMENSION_NOT_SET} when not defined.
-     */
-    public int getHeightSpecPx(Context context) {
-        switch (mStyle.getHeightSpecCase()) {
-            case HEIGHT:
-                return (int) LayoutUtils.dpToPx(mStyle.getHeight(), context);
-            case RELATIVE_HEIGHT:
-                switch (mStyle.getRelativeHeight()) {
-                    case FILL_PARENT:
-                        return LayoutParams.MATCH_PARENT;
-                    case FIT_CONTENT:
-                        return LayoutParams.WRAP_CONTENT;
-                    case RELATIVE_SIZE_UNDEFINED:
-                        // fall through
-                }
-                // fall through
-            case HEIGHTSPEC_NOT_SET:
-                // fall out
-        }
-        return DIMENSION_NOT_SET;
-    }
-
-    /**
-     * Width of a view in px, or {@link LayoutParams#WRAP_CONTENT} or {@link
-     * LayoutParams#MATCH_PARENT}, or {@link StyleProvider#DIMENSION_NOT_SET} when not defined.
-     */
-    public int getWidthSpecPx(Context context) {
-        switch (mStyle.getWidthSpecCase()) {
-            case WIDTH:
-                return (int) LayoutUtils.dpToPx(mStyle.getWidth(), context);
-            case RELATIVE_WIDTH:
-                switch (mStyle.getRelativeWidth()) {
-                    case FILL_PARENT:
-                        return LayoutParams.MATCH_PARENT;
-                    case FIT_CONTENT:
-                        return LayoutParams.WRAP_CONTENT;
-                    case RELATIVE_SIZE_UNDEFINED:
-                        // fall through
-                }
-                // fall through
-            case WIDTHSPEC_NOT_SET:
-                // fall out
-        }
-        return DIMENSION_NOT_SET;
-    }
-
-    /** Whether a height is explicitly specified */
-    public boolean hasHeight() {
-        return mStyle.getHeightSpecCase() != HeightSpecCase.HEIGHTSPEC_NOT_SET;
-    }
-
-    /** Whether a width is explicitly specified */
-    public boolean hasWidth() {
-        return mStyle.getHeightSpecCase() != HeightSpecCase.HEIGHTSPEC_NOT_SET;
-    }
-
-    /** Whether the style has a horizontal gravity specified */
-    public boolean hasGravityHorizontal() {
-        return mStyle.hasGravityHorizontal();
-    }
-
-    /** Horizontal gravity specified on the style */
-    public int getGravityHorizontal(int defaultGravity) {
-        switch (mStyle.getGravityHorizontal()) {
-            case GRAVITY_START:
-                return Gravity.START;
-            case GRAVITY_CENTER:
-                return Gravity.CENTER_HORIZONTAL;
-            case GRAVITY_END:
-                return Gravity.END;
-            case GRAVITY_HORIZONTAL_UNSPECIFIED:
-                // fall out
-        }
-        return defaultGravity;
-    }
-
-    /** Whether the style has a vertical gravity specified */
-    public boolean hasGravityVertical() {
-        return mStyle.hasGravityVertical();
-    }
-
-    /** Vertical gravity specified on the style */
-    public int getGravityVertical(int defaultGravity) {
-        switch (mStyle.getGravityVertical()) {
-            case GRAVITY_TOP:
-                return Gravity.TOP;
-            case GRAVITY_MIDDLE:
-                return Gravity.CENTER_VERTICAL;
-            case GRAVITY_BOTTOM:
-                return Gravity.BOTTOM;
-            case GRAVITY_VERTICAL_UNSPECIFIED:
-                // fall out
-        }
-        return defaultGravity;
-    }
-
-    /** Gravity (horizontal and vertical) as specified on the style */
-    public int getGravity(int defaultGravity) {
-        return getGravityHorizontal(defaultGravity) | getGravityVertical(defaultGravity);
-    }
-
-    /** Horizontal and vertical alignment of text, as an Android view Gravity */
-    public int getTextAlignment() {
-        int horizontalGravity;
-        int verticalGravity;
-
-        switch (mStyle.getTextAlignmentHorizontal()) {
-            case TEXT_ALIGNMENT_CENTER:
-                horizontalGravity = Gravity.CENTER_HORIZONTAL;
-                break;
-            case TEXT_ALIGNMENT_END:
-                horizontalGravity = Gravity.END;
-                break;
-            case TEXT_ALIGNMENT_START:
-            default:
-                horizontalGravity = Gravity.START;
-        }
-
-        switch (mStyle.getTextAlignmentVertical()) {
-            case TEXT_ALIGNMENT_MIDDLE:
-                verticalGravity = Gravity.CENTER_VERTICAL;
-                break;
-            case TEXT_ALIGNMENT_BOTTOM:
-                verticalGravity = Gravity.BOTTOM;
-                break;
-            case TEXT_ALIGNMENT_TOP:
-            default:
-                verticalGravity = Gravity.TOP;
-        }
-
-        return horizontalGravity | verticalGravity;
-    }
-
-    /** Sets the Padding and Background Color on the view. */
-    void applyElementStyles(ElementAdapter<?, ?> adapter) {
-        Context context = adapter.getContext();
-        View view = adapter.getView();
-        View baseView = adapter.getBaseView();
-
-        // Apply layout styles
-        EdgeWidths padding = getPadding();
-
-        // If this is a TextElementAdapter with line height set, extra padding needs to be added to
-        // the top and bottom to match the css line height behavior.
-        TextElementAdapter.ExtraLineHeight extraLineHeight =
-                TextElementAdapter.ExtraLineHeight.builder().build();
-        if (adapter instanceof TextElementAdapter) {
-            extraLineHeight = ((TextElementAdapter) adapter).getExtraLineHeight();
-        }
-
-        applyPadding(context, baseView, padding, extraLineHeight);
-
-        if (getMinHeight() > 0) {
-            baseView.setMinimumHeight((int) LayoutUtils.dpToPx(getMinHeight(), context));
-        } else {
-            baseView.setMinimumHeight(0);
-        }
-
-        // Apply appearance styles
-        baseView.setBackground(createBackground());
-        if (mStyle.getShadow().hasElevationShadow()) {
-            ViewCompat.setElevation(view, mStyle.getShadow().getElevationShadow().getElevation());
-        } else {
-            ViewCompat.setElevation(view, 0.0f);
-        }
-        if (view != baseView) {
-            ViewCompat.setElevation(baseView, 0.0f);
-        }
-
-        baseView.setAlpha(mStyle.getOpacity());
-    }
-
-    /**
-     * Set the padding on a view. This includes adding extra padding for line spacing on TextView
-     * and extra padding for borders.
-     */
-    void applyPadding(Context context, View view, EdgeWidths padding,
-            TextElementAdapter.ExtraLineHeight extraLineHeight) {
-        int startPadding =
-                (int) LayoutUtils.dpToPx(padding.getStart() + getBorderWidth(Edges.START), context);
-        int endPadding =
-                (int) LayoutUtils.dpToPx(padding.getEnd() + getBorderWidth(Edges.END), context);
-        int topPadding =
-                (int) LayoutUtils.dpToPx(padding.getTop() + getBorderWidth(Edges.TOP), context)
-                + extraLineHeight.topPaddingPx();
-        int bottomPadding = (int) LayoutUtils.dpToPx(
-                                    padding.getBottom() + getBorderWidth(Edges.BOTTOM), context)
-                + extraLineHeight.bottomPaddingPx();
-
-        view.setPadding(mAssetProvider.isRtL() ? endPadding : startPadding, topPadding,
-                mAssetProvider.isRtL() ? startPadding : endPadding, bottomPadding);
-    }
-
-    private int getBorderWidth(Borders.Edges edge) {
-        if (!hasBorders()) {
-            return 0;
-        }
-        if (getBorders().getBitmask() == 0
-                || ((getBorders().getBitmask() & edge.getNumber()) != 0)) {
-            return getBorders().getWidth();
-        }
-        return 0;
-    }
-
-    void addBordersWithoutRoundedCorners(FrameLayout view, Context context) {
-        if (!hasBorders()) {
-            return;
-        }
-
-        // Create a drawable to stroke the border
-        BorderDrawable borderDrawable =
-                new BorderDrawable(context, getBorders(), ZERO_RADIUS, mAssetProvider.isRtL());
-        view.setForeground(borderDrawable);
-    }
-
-    /** Sets appropriate margins on a {@link MarginLayoutParams} instance. */
-    void applyMargins(Context context, MarginLayoutParams marginLayoutParams) {
-        EdgeWidths margins = getMargins();
-        int startMargin = (int) LayoutUtils.dpToPx(margins.getStart(), context);
-        int endMargin = (int) LayoutUtils.dpToPx(margins.getEnd(), context);
-        marginLayoutParams.setMargins(startMargin,
-                (int) LayoutUtils.dpToPx(margins.getTop(), context), endMargin,
-                (int) LayoutUtils.dpToPx(margins.getBottom(), context));
-        marginLayoutParams.setMarginStart(startMargin);
-        marginLayoutParams.setMarginEnd(endMargin);
-    }
-
-    FrameLayout createWrapperView(Context context, RoundedCornerMaskCache maskCache,
-            boolean allowClipPathRounding, boolean allowOutlineRounding) {
-        if (!hasRoundedCorners()) {
-            FrameLayout view = new FrameLayout(context);
-            // The wrapper view gets elevation; set an outline so it can cast a shadow.
-            view.setOutlineProvider(ViewOutlineProvider.BOUNDS);
-            return view;
-        }
-        int radiusOverride = getRoundedCorners().getUseHostRadiusOverride()
-                ? mAssetProvider.getDefaultCornerRadius()
-                : 0;
-
-        return new RoundedCornerWrapperView(context, getRoundedCorners(), maskCache,
-                mAssetProvider.isRtLSupplier(), radiusOverride, getBorders(), allowClipPathRounding,
-                allowOutlineRounding);
-    }
-
-    /**
-     * Return a {@link Drawable} with the fill and rounded corners defined on the style; returns
-     * {@code null} if the background has no color defined.
-     */
-    @Nullable
-    Drawable createBackground() {
-        return createBackgroundForFill(getBackground());
-    }
-
-    /**
-     * Return a {@link Drawable} with the fill and rounded corners defined on the style; returns
-     * {@code null} if the pre load fill has no color defined.
-     */
-    @Nullable
-    Drawable createPreLoadFill() {
-        return createBackgroundForFill(getPreLoadFill());
-    }
-
-    /**
-     * Return a {@link Drawable} with a given Fill and the rounded corners defined on the style;
-     * returns {@code null} if the background has no color defined.
-     */
-    @Nullable
-    private Drawable createBackgroundForFill(Fill background) {
-        switch (background.getFillTypeCase()) {
-            case COLOR:
-                return new ColorDrawable(background.getColor());
-            case LINEAR_GRADIENT:
-                return new GradientDrawable(
-                        background.getLinearGradient(), mAssetProvider.isRtLSupplier());
-            default:
-                return null;
-        }
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof StyleProvider)) {
-            return false;
-        }
-
-        StyleProvider that = (StyleProvider) o;
-
-        return mStyle.equals(that.mStyle) && mAssetProvider.equals(that.mAssetProvider);
-    }
-
-    @Override
-    public int hashCode() {
-        return mStyle.hashCode();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/TemplateBinder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/TemplateBinder.java
deleted file mode 100644
index 540db1f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/TemplateBinder.java
+++ /dev/null
@@ -1,234 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.BindingContext;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.PietSharedState;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Stylesheet;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Template;
-
-import java.util.List;
-
-/**
- * Methods to enable creation and binding of Templates.
- *
- * <p>This class creates and binds adapters for templates allowing for reuse of full template
- * layouts as a unit. Release and recycling is handled by the ElementAdapterFactory.
- */
-class TemplateBinder {
-    private final KeyedRecyclerPool<ElementAdapter<? extends View, ?>> mTemplateRecyclerPool;
-    private final ElementAdapterFactory mAdapterFactory;
-
-    TemplateBinder(KeyedRecyclerPool<ElementAdapter<? extends View, ?>> mTemplateRecyclerPool,
-            ElementAdapterFactory adapterFactory) {
-        this.mTemplateRecyclerPool = mTemplateRecyclerPool;
-        this.mAdapterFactory = adapterFactory;
-    }
-
-    /** Higher-performance method that creates and binds an adapter for a template all at once. */
-    ElementAdapter<? extends View, ?> createAndBindTemplateAdapter(
-            TemplateAdapterModel model, FrameContext frameContext) {
-        // Create the template context for use in both create and bind
-        // This is a modestly expensive operation, and calling createTemplateAdapter followed by
-        // bindTemplateAdapter would do it twice.
-        FrameContext templateContext =
-                frameContext.createTemplateContext(model.getTemplate(), model.getBindingContext());
-
-        TemplateKey templateKey = makeTemplateKey(model, frameContext);
-        ElementAdapter<? extends View, ?> adapter = mTemplateRecyclerPool.get(templateKey);
-
-        if (adapter == null) {
-            // Create new adapter
-            adapter = mAdapterFactory.createAdapterForElement(
-                    model.getTemplate().getElement(), templateContext);
-
-            adapter.setKey(templateKey);
-        }
-
-        adapter.bindModel(model.getTemplate().getElement(), templateContext);
-
-        return adapter;
-    }
-
-    ElementAdapter<? extends View, ?> createTemplateAdapter(
-            TemplateAdapterModel model, FrameContext frameContext) {
-        TemplateKey templateKey = makeTemplateKey(model, frameContext);
-        ElementAdapter<? extends View, ?> adapter = mTemplateRecyclerPool.get(templateKey);
-
-        if (adapter == null) {
-            // Make new FrameContext here
-            FrameContext templateContext = frameContext.createTemplateContext(
-                    model.getTemplate(), model.getBindingContext());
-
-            // Create new adapter
-            adapter = mAdapterFactory.createAdapterForElement(
-                    model.getTemplate().getElement(), templateContext);
-
-            adapter.setKey(templateKey);
-        }
-
-        return adapter;
-    }
-
-    void bindTemplateAdapter(ElementAdapter<? extends View, ?> adapter, TemplateAdapterModel model,
-            FrameContext frameContext) {
-        TemplateKey templateKey = makeTemplateKey(model, frameContext);
-
-        checkNotNull(adapter.getKey(), "Adapter key was null; not initialized correctly?");
-        checkState(adapter.getKey() instanceof TemplateKey,
-                "bindTemplateAdapter only applicable for template adapters");
-        checkState(templateKey.equals(adapter.getKey()), "Template keys did not match");
-
-        FrameContext templateContext =
-                frameContext.createTemplateContext(model.getTemplate(), model.getBindingContext());
-
-        adapter.bindModel(model.getTemplate().getElement(), templateContext);
-    }
-
-    private static TemplateKey makeTemplateKey(
-            TemplateAdapterModel model, FrameContext frameContext) {
-        return new TemplateKey(model.getTemplate(), frameContext.getPietSharedStates(),
-                frameContext.getMediaQueryStylesheets(model.getTemplate()));
-    }
-
-    /**
-     * Determines whether two templates are compatible for recycling. We're going to call the hash
-     * code good enough for performance reasons (.equals() is expensive), and hope we don't get a
-     * lot of collisions.
-     */
-    @SuppressWarnings({"ReferenceEquality", "EqualsUsingHashCode"})
-    static boolean templateEquals(@Nullable Template template1, @Nullable Template template2) {
-        if (template1 == template2) {
-            return true;
-        } else if (template1 == null || template2 == null) {
-            return false;
-        }
-        return template1.hashCode() == template2.hashCode();
-    }
-
-    /** Wrap the Template proto object as the recycler key. */
-    static class TemplateKey extends RecyclerKey {
-        private final Template mTemplate;
-        @Nullable
-        private final List<PietSharedState> mPietSharedStates;
-
-        // If the Template references Stylesheets that have MediaQueryConditions on them, they need
-        // to be part of the key.
-        private final List<Stylesheet> mMediaQueryBasedStylesheets;
-
-        TemplateKey(Template template, @Nullable List<PietSharedState> pietSharedStates,
-                List<Stylesheet> mediaQueryBasedStylesheets) {
-            this.mTemplate = template;
-            this.mPietSharedStates = pietSharedStates;
-            this.mMediaQueryBasedStylesheets = mediaQueryBasedStylesheets;
-        }
-
-        /** Equals checks the hashCode of the component fields to avoid expensive proto equals. */
-        @SuppressWarnings({"ReferenceEquality", "EqualsUsingHashCode"})
-        @Override
-        public boolean equals(@Nullable Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (!(o instanceof TemplateKey)) {
-                return false;
-            }
-
-            TemplateKey that = (TemplateKey) o;
-
-            // Check that Templates are equal
-            if (!templateEquals(mTemplate, that.mTemplate)) {
-                return false;
-            }
-            // Check that PietSharedStates are equal or both null
-            if (that.mPietSharedStates == null ^ this.mPietSharedStates == null) {
-                return false;
-            }
-            if (this.mPietSharedStates != null && that.mPietSharedStates != null
-                    && (this.mPietSharedStates.size() != that.mPietSharedStates.size()
-                            || this.mPietSharedStates.hashCode()
-                                    != that.mPietSharedStates.hashCode())) {
-                return false;
-            }
-            // Check that stylesheets are equal or both empty
-            if (that.mMediaQueryBasedStylesheets.isEmpty()
-                    ^ this.mMediaQueryBasedStylesheets.isEmpty()) {
-                return false;
-            }
-            return this.mMediaQueryBasedStylesheets == that.mMediaQueryBasedStylesheets
-                    || this.mMediaQueryBasedStylesheets.hashCode()
-                    == that.mMediaQueryBasedStylesheets.hashCode();
-        }
-
-        @Override
-        public int hashCode() {
-            int result = mTemplate.hashCode();
-            result = 31 * result + (mPietSharedStates != null ? mPietSharedStates.hashCode() : 0);
-            result = 31 * result
-                    + (mMediaQueryBasedStylesheets != null ? mMediaQueryBasedStylesheets.hashCode()
-                                                           : 0);
-            return result;
-        }
-    }
-
-    static class TemplateAdapterModel {
-        private final Template mTemplate;
-        private final BindingContext mBindingContext;
-
-        TemplateAdapterModel(Template template, BindingContext bindingContext) {
-            this.mTemplate = template;
-            this.mBindingContext = bindingContext;
-        }
-
-        TemplateAdapterModel(
-                String templateId, FrameContext frameContext, BindingContext bindingContext) {
-            this.mTemplate = checkNotNull(
-                    frameContext.getTemplate(templateId), "Template was not found: %s", templateId);
-            this.mBindingContext = bindingContext;
-        }
-
-        public Template getTemplate() {
-            return mTemplate;
-        }
-
-        BindingContext getBindingContext() {
-            return mBindingContext;
-        }
-
-        @SuppressWarnings({"ReferenceEquality", "EqualsUsingHashCode"})
-        @Override
-        public boolean equals(@Nullable Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (!(o instanceof TemplateAdapterModel)) {
-                return false;
-            }
-
-            TemplateAdapterModel that = (TemplateAdapterModel) o;
-
-            return templateEquals(mTemplate, that.mTemplate)
-                    && (mBindingContext == that.mBindingContext
-                            || (mBindingContext.getBindingValuesCount()
-                                            == that.mBindingContext.getBindingValuesCount()
-                                    && mBindingContext.hashCode()
-                                            == that.mBindingContext.hashCode()));
-        }
-
-        @Override
-        public int hashCode() {
-            int result = mTemplate.hashCode();
-            result = 31 * result + mBindingContext.hashCode();
-            return result;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/TextElementAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/TextElementAdapter.java
deleted file mode 100644
index f6ede42..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/TextElementAdapter.java
+++ /dev/null
@@ -1,486 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.content.Context;
-import android.graphics.Typeface;
-import android.os.Build;
-import android.text.Layout;
-import android.text.TextUtils;
-import android.view.View;
-import android.widget.TextView;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.core.widget.TextViewCompat;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.library.common.ui.LayoutUtils;
-import org.chromium.chrome.browser.feed.library.piet.AdapterFactory.AdapterKeySupplier;
-import org.chromium.chrome.browser.feed.library.piet.DebugLogger.MessageType;
-import org.chromium.chrome.browser.feed.library.piet.host.TypefaceProvider.GoogleSansTypeface;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.Element;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.TextElement;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.Font;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.Typeface.CommonTypeface;
-
-import java.util.List;
-
-/**
- * Base {@link ElementAdapter} to extend to manage {@code ChunkedText} and {@code ParameterizedText}
- * elements.
- */
-abstract class TextElementAdapter extends ElementAdapter<TextView, Element> {
-    private ExtraLineHeight mExtraLineHeight = ExtraLineHeight.builder().build();
-
-    TextElementAdapter(Context context, AdapterParameters parameters) {
-        super(context, parameters, createView(context));
-    }
-
-    @Override
-    protected Element getModelFromElement(Element baseElement) {
-        if (!baseElement.hasTextElement()) {
-            throw new PietFatalException(ErrorCode.ERR_MISSING_ELEMENT_CONTENTS,
-                    String.format("Missing TextElement; has %s", baseElement.getElementsCase()));
-        }
-        return baseElement;
-    }
-
-    @Override
-    void onCreateAdapter(Element textLine, Element baseElement, FrameContext frameContext) {
-        if (getKey() == null) {
-            TextElementKey key = createKey(getElementStyle().getFont());
-            setKey(key);
-            setValuesUsedInRecyclerKey(key, frameContext);
-        }
-
-        // Setup the layout of the text lines, including all properties not in the recycler key.
-        updateTextStyle();
-    }
-
-    private void updateTextStyle() {
-        TextView textView = getBaseView();
-        StyleProvider textStyle = getElementStyle();
-        textView.setTextColor(textStyle.getColor());
-
-        if (textStyle.getFont().hasLineHeight()) {
-            textView.setIncludeFontPadding(false);
-            ExtraLineHeight extraLineHeight = getExtraLineHeight();
-            textView.setLineSpacing(
-                    /* add= */ extraLineHeight.betweenLinesExtraPx(), /* mult= */ 1.0f);
-        }
-        setLetterSpacing(textView, textStyle);
-        if (textStyle.getMaxLines() > 0) {
-            textView.setMaxLines(textStyle.getMaxLines());
-            textView.setEllipsize(TextUtils.TruncateAt.END);
-        } else {
-            // MAX_VALUE is the value used in the Android implementation for the default
-            textView.setMaxLines(Integer.MAX_VALUE);
-        }
-
-        getBaseView().setGravity(textStyle.getTextAlignment());
-    }
-
-    private void setLetterSpacing(TextView textView, StyleProvider textStyle) {
-        if (!textStyle.getFont().hasLetterSpacingDp()) {
-            return;
-        }
-        float textSize;
-        if (textStyle.getFont().hasSize()) {
-            textSize = textStyle.getFont().getSize();
-        } else {
-            textSize = LayoutUtils.pxToSp(textView.getTextSize(), textView.getContext());
-        }
-        float letterSpacingDp = textStyle.getFont().getLetterSpacingDp();
-        float letterSpacingEm = letterSpacingDp / textSize;
-        textView.setLetterSpacing(letterSpacingEm);
-    }
-
-    @Override
-    void onBindModel(Element textLine, Element baseElement, FrameContext frameContext) {
-        // Set the initial state for the TextView
-        // No bindings found, so use the inlined value (or empty if not set)
-        setTextOnView(frameContext, textLine.getTextElement());
-
-        if (getElementStyleIdsStack().hasStyleBinding()) {
-            updateTextStyle();
-        } else if (baseFontHeightChanged()) {
-            updateTextStyle();
-            getElementStyle().applyElementStyles(this);
-        }
-    }
-
-    abstract void setTextOnView(FrameContext frameContext, TextElement textElement);
-
-    @Override
-    void onUnbindModel() {
-        TextView textView = getBaseView();
-        textView.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
-        textView.setText("");
-    }
-
-    private float calculateCurrentAndExpectedLineHeightDifference() {
-        TextView textView = getBaseView();
-        StyleProvider textStyle = getElementStyle();
-
-        float lineHeightGoalSp = textStyle.getFont().getLineHeight();
-        float lineHeightGoalPx = LayoutUtils.spToPx(lineHeightGoalSp, textView.getContext());
-        float currentHeight = textView.getLineHeight();
-
-        return (lineHeightGoalPx - currentHeight);
-    }
-
-    /**
-     * Returns a line height object which contains the number of pixels that need to be added
-     * between each line, as well as the number of pixels that need to be added to the top and
-     * bottom padding of the element in order to match css line height behavior.
-     */
-    ExtraLineHeight getExtraLineHeight() {
-        Font font = getElementStyle().getFont();
-
-        if (!font.hasLineHeight()) {
-            return mExtraLineHeight;
-        }
-
-        int totalExtraPadding = 0;
-        int extraLineHeightBetweenLines = 0;
-        if (font.hasLineHeight()) {
-            float changeInLineHeight = calculateCurrentAndExpectedLineHeightDifference();
-            if (changeInLineHeight == 0) {
-                return mExtraLineHeight;
-            }
-
-            float extraLineHeightBetweenLinesFloat =
-                    mExtraLineHeight.betweenLinesExtraPx() + changeInLineHeight;
-            extraLineHeightBetweenLines = Math.round(extraLineHeightBetweenLinesFloat);
-
-            // Adjust the rounding for the extra top and bottom padding, to make the total height of
-            // the text element a little more exact.
-            totalExtraPadding = adjustRounding(extraLineHeightBetweenLinesFloat);
-        }
-        int extraPaddingForLineHeightTop = totalExtraPadding / 2;
-        int extraPaddingForLineHeightBottom = totalExtraPadding - extraPaddingForLineHeightTop;
-
-        mExtraLineHeight = ExtraLineHeight.builder()
-                                   .setTopPaddingPx(extraPaddingForLineHeightTop)
-                                   .setBottomPaddingPx(extraPaddingForLineHeightBottom)
-                                   .setBetweenLinesExtraPx(extraLineHeightBetweenLines)
-                                   .build();
-
-        return mExtraLineHeight;
-    }
-
-    private boolean baseFontHeightChanged() {
-        // Check if we've already calculated the extra line height and there is a significant
-        // difference between the current and expected line heights.
-        if (mExtraLineHeight.betweenLinesExtraPx() == 0) {
-            return false;
-        }
-        float lineHeightDifference = calculateCurrentAndExpectedLineHeightDifference();
-        if (Math.round(lineHeightDifference) == 0) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Rounds the float value away from the nearest integer, i.e. 4.75 rounds to 4, and 7.2 rounds
-     * to 8.
-     */
-    private int adjustRounding(float floatValueToRound) {
-        int intWithRegularRounding = Math.round(floatValueToRound);
-        // If the regular rounding rounded up, round down with adjusted rounding.
-        if (floatValueToRound - (float) intWithRegularRounding < 0) {
-            return intWithRegularRounding - 1;
-        }
-        // If the regular rounding rounded down, round up with adjusted rounding.
-        if (floatValueToRound - (float) intWithRegularRounding > 0) {
-            return intWithRegularRounding + 1;
-        }
-        return intWithRegularRounding;
-    }
-
-    @VisibleForTesting
-    // LINT.IfChange
-    void setValuesUsedInRecyclerKey(TextElementKey fontKey, FrameContext frameContext) {
-        TextView textView = getBaseView();
-        textView.setTextSize(fontKey.getSize());
-        if (!fontKey.mTypefaces.isEmpty()) {
-            FontDetails fontDetails =
-                    new FontDetails(fontKey.mTypefaces, fontKey.isItalic(), frameContext);
-            loadFont(textView, fontDetails);
-        } else {
-            makeFontItalic(textView, fontKey.isItalic());
-        }
-    }
-
-    private void loadFont(TextView textView, FontDetails fontDetails) {
-        StylesProto.Typeface typeface = fontDetails.getTypefaceToLoad();
-        if (typeface == null) {
-            fontDetails.getFrameContext().reportMessage(MessageType.WARNING,
-                    ErrorCode.ERR_MISSING_FONTS, "Could not load specified typefaces.");
-            // We didn't load a typeface, but we can at least respect italicization.
-            makeFontItalic(textView, fontDetails.isItalic());
-            return;
-        }
-        switch (typeface.getTypefaceSpecifierCase()) {
-            case COMMON_TYPEFACE:
-                loadCommonTypeface(typeface.getCommonTypeface(), fontDetails, textView);
-                break;
-            case CUSTOM_TYPEFACE:
-                loadCustomTypeface(typeface.getCustomTypeface(), fontDetails, textView);
-                break;
-            default:
-                // do nothing
-        }
-    }
-
-    /** Load one of the typefaces from the {@link CommonTypeface} enum. */
-    private void loadCommonTypeface(
-            CommonTypeface commonTypeface, FontDetails fontDetails, TextView textView) {
-        switch (commonTypeface) {
-            case PLATFORM_DEFAULT_LIGHT:
-                TextViewCompat.setTextAppearance(textView, R.style.gm_font_weight_light);
-                break;
-            case PLATFORM_DEFAULT_REGULAR:
-                TextViewCompat.setTextAppearance(textView, R.style.gm_font_weight_regular);
-                break;
-            case PLATFORM_DEFAULT_MEDIUM:
-                TextViewCompat.setTextAppearance(textView, R.style.gm_font_weight_medium);
-                break;
-            case GOOGLE_SANS_MEDIUM:
-            case GOOGLE_SANS_REGULAR:
-                loadCustomTypeface(
-                        googleSansEnumToStringDef(commonTypeface), fontDetails, textView);
-                // The host should take care of italicization for custom fonts, so return here.
-                return;
-            default:
-                // Unrecognized common typeface. Try to load the next typeface from fontDetails.
-                // This should never happen.
-                fontDetails.currentTypefaceFailedToLoad();
-                loadFont(textView, fontDetails);
-                return;
-        }
-        makeFontItalic(textView, fontDetails.isItalic());
-    }
-
-    /** Ask the host to load a typeface by string identifier. */
-    private void loadCustomTypeface(
-            String customTypefaceName, FontDetails fontDetails, TextView textView) {
-        TypefaceCallback typefaceCallback = new TypefaceCallback(textView, fontDetails);
-        getParameters().mHostProviders.getAssetProvider().getTypeface(
-                customTypefaceName, fontDetails.isItalic(), typefaceCallback);
-    }
-
-    /**
-     * Conversion method to avoid version skew issues if we would ever change the enum names in the
-     * CommonTypeface proto, so we don't need to change all the hosts or old clients.
-     */
-    @VisibleForTesting
-    @GoogleSansTypeface
-    static String googleSansEnumToStringDef(CommonTypeface googleSansType) {
-        switch (googleSansType) {
-            case GOOGLE_SANS_MEDIUM:
-                return GoogleSansTypeface.GOOGLE_SANS_MEDIUM;
-            case GOOGLE_SANS_REGULAR:
-                return GoogleSansTypeface.GOOGLE_SANS_REGULAR;
-            default:
-                return GoogleSansTypeface.UNDEFINED;
-        }
-    }
-
-    private static void makeFontItalic(TextView textView, boolean isItalic) {
-        if (isItalic) {
-            textView.setTypeface(textView.getTypeface(), Typeface.ITALIC);
-        } else {
-            textView.setTypeface(Typeface.create(textView.getTypeface(), Typeface.NORMAL));
-        }
-    }
-
-    private static TextView createView(Context context) {
-        TextView view = new TextView(context);
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
-            view.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
-        }
-        return view;
-    }
-
-    TextElementKey createKey(Font font) {
-        return new TextElementKey(font);
-    }
-
-    abstract static class TextElementKeySupplier<A extends TextElementAdapter>
-            implements AdapterKeySupplier<A, Element> {
-        @Override
-        public TextElementKey getKey(FrameContext frameContext, Element model) {
-            StyleProvider styleProvider = frameContext.makeStyleFor(model.getStyleReferences());
-            return new TextElementKey(styleProvider.getFont());
-        }
-    }
-
-    /** We will Key TextViews off of Font Size, Typefaces and Italics. */
-    // LINT.IfChange
-    static class TextElementKey extends RecyclerKey {
-        private final int mSize;
-        private final boolean mItalic;
-        private final List<StylesProto.Typeface> mTypefaces;
-
-        TextElementKey(Font font) {
-            mSize = font.getSize();
-            mItalic = font.getItalic();
-            mTypefaces = font.getTypefaceList();
-        }
-
-        public int getSize() {
-            return mSize;
-        }
-
-        public boolean isItalic() {
-            return mItalic;
-        }
-
-        @Override
-        public int hashCode() {
-            // Can't use Objects.hash() as it is only available in KK+ and can't use Guava's impl
-            // either.
-            int result = mSize;
-            result = 31 * result + (mItalic ? 1 : 0);
-            result = 31 * result + mTypefaces.hashCode();
-            return result;
-        }
-
-        @Override
-        public boolean equals(@Nullable Object obj) {
-            if (obj == this) {
-                return true;
-            }
-
-            if (obj == null) {
-                return false;
-            }
-
-            if (!(obj instanceof TextElementKey)) {
-                return false;
-            }
-
-            TextElementKey key = (TextElementKey) obj;
-            return key.mSize == mSize && key.mItalic == mItalic
-                    && mTypefaces.equals(key.mTypefaces);
-        }
-    }
-    // LINT.ThenChange
-
-    static class ExtraLineHeight {
-        private final int mTopPaddingPx;
-        private final int mBottomPaddingPx;
-        private final int mBetweenLinesExtraPx;
-
-        int topPaddingPx() {
-            return mTopPaddingPx;
-        }
-
-        int bottomPaddingPx() {
-            return mBottomPaddingPx;
-        }
-
-        int betweenLinesExtraPx() {
-            return mBetweenLinesExtraPx;
-        }
-
-        private ExtraLineHeight(Builder builder) {
-            this.mTopPaddingPx = builder.mTopPaddingPx;
-            this.mBottomPaddingPx = builder.mBottomPaddingPx;
-            this.mBetweenLinesExtraPx = builder.mBetweenLinesExtraPx;
-        }
-
-        static Builder builder() {
-            return new ExtraLineHeight.Builder();
-        }
-
-        static class Builder {
-            private int mTopPaddingPx;
-            private int mBottomPaddingPx;
-            private int mBetweenLinesExtraPx;
-
-            Builder setTopPaddingPx(int value) {
-                mTopPaddingPx = value;
-                return this;
-            }
-
-            Builder setBottomPaddingPx(int value) {
-                mBottomPaddingPx = value;
-                return this;
-            }
-
-            Builder setBetweenLinesExtraPx(int value) {
-                mBetweenLinesExtraPx = value;
-                return this;
-            }
-
-            ExtraLineHeight build() {
-                return new ExtraLineHeight(this);
-            }
-        }
-    }
-
-    static class FontDetails {
-        private int mFontIndexToLoad;
-        private final List<StylesProto.Typeface> mTypefaceList;
-        private final boolean mIsItalic;
-        private final FrameContext mFrameContextForErrors;
-
-        FontDetails(List<StylesProto.Typeface> typefaceList, boolean isItalic,
-                FrameContext frameContext) {
-            this.mTypefaceList = typefaceList;
-            this.mIsItalic = isItalic;
-            this.mFrameContextForErrors = frameContext;
-        }
-
-        FrameContext getFrameContext() {
-            return mFrameContextForErrors;
-        }
-
-        @Nullable
-        StylesProto.Typeface getTypefaceToLoad() {
-            if (mTypefaceList.size() <= mFontIndexToLoad) {
-                return null;
-            }
-            return mTypefaceList.get(mFontIndexToLoad);
-        }
-
-        void currentTypefaceFailedToLoad() {
-            mFontIndexToLoad++;
-        }
-
-        boolean isItalic() {
-            return mIsItalic;
-        }
-    }
-
-    class TypefaceCallback implements Consumer<Typeface> {
-        private final TextView mTextView;
-        private final FontDetails mFontDetails;
-
-        TypefaceCallback(TextView textView, FontDetails fontDetails) {
-            this.mTextView = textView;
-            this.mFontDetails = fontDetails;
-        }
-
-        @Override
-        public void accept(@Nullable Typeface typeface) {
-            if (typeface == null) {
-                mFontDetails.currentTypefaceFailedToLoad();
-                loadFont(mTextView, mFontDetails);
-                return;
-            }
-            if (mTextView.getTypeface() == null || !mTextView.getTypeface().equals(typeface)) {
-                mTextView.setTypeface(typeface);
-            }
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ViewUtils.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ViewUtils.java
deleted file mode 100644
index 27358e6..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ViewUtils.java
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet;
-
-import android.graphics.PorterDuff.Mode;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.os.Build.VERSION_CODES;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-import androidx.core.view.ViewCompat;
-
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.library.piet.host.ActionHandler;
-import org.chromium.chrome.browser.feed.library.piet.host.ActionHandler.ActionType;
-import org.chromium.components.feed.core.proto.ui.piet.ActionsProto.Actions;
-import org.chromium.components.feed.core.proto.ui.piet.ActionsProto.VisibilityAction;
-import org.chromium.components.feed.core.proto.ui.piet.LogDataProto.LogData;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Frame;
-
-import java.util.Set;
-
-/** Utility class, providing useful methods to interact with Views. */
-public class ViewUtils {
-    private static final String TAG = "ViewUtils";
-
-    /**
-     * Attaches the onClick action from actions to the view, executed by the handler. In Android M+,
-     * a RippleDrawable is added to the foreground of the view, so that a ripple animation happens
-     * on each click.
-     */
-    static void setOnClickActions(
-            Actions actions, View view, FrameContext frameContext, LogData logData) {
-        ActionHandler handler = frameContext.getActionHandler();
-        if (actions.hasOnLongClickAction()) {
-            view.setOnLongClickListener(v -> {
-                handler.handleAction(actions.getOnLongClickAction(), ActionType.LONG_CLICK,
-                        frameContext.getFrame(), view, logData);
-                return true;
-            });
-        } else {
-            clearOnLongClickActions(view);
-        }
-        if (actions.hasOnClickAction()) {
-            view.setOnClickListener(v -> {
-                handler.handleAction(actions.getOnClickAction(), ActionType.CLICK,
-                        frameContext.getFrame(), view, logData);
-            });
-        } else {
-            clearOnClickActions(view);
-        }
-        // TODO: Implement alternative support for older versions
-        if (Build.VERSION.SDK_INT >= VERSION_CODES.M) {
-            if (actions.hasOnClickAction() || actions.hasOnLongClickAction()) {
-                // CAUTION: View.setForeground() is only available in L+
-                view.setForeground(view.getContext().getDrawable(R.drawable.piet_clickable_ripple));
-            } else {
-                view.setForeground(null);
-            }
-        }
-    }
-
-    static void clearOnLongClickActions(View view) {
-        view.setOnLongClickListener(null);
-        view.setLongClickable(false);
-    }
-
-    /** Sets clickability to false. */
-    static void clearOnClickActions(View view) {
-        if (view.hasOnClickListeners()) {
-            view.setOnClickListener(null);
-        }
-
-        view.setClickable(false);
-    }
-
-    /**
-     * Check if this view is visible, trigger actions accordingly, and update set of active actions.
-     *
-     * <p>Actions are added to activeActions when they trigger, and removed when the condition that
-     * caused them to trigger is no longer true. (Ex. a view action will be removed when the view
-     * goes off screen)
-     *
-     * @param view this adapter's view
-     * @param viewport the visible viewport
-     * @param actions this element's actions, which might be triggered
-     * @param actionHandler host-provided handler to execute actions
-     * @param frame the parent frame
-     * @param activeActions mutable set of currently-triggered actions; this will get updated by
-     *         this
-     *     method as new actions are triggered and old actions are reset.
-     */
-    static void maybeTriggerViewActions(View view, View viewport, Actions actions,
-            ActionHandler actionHandler, Frame frame, Set<VisibilityAction> activeActions) {
-        if (actions.getOnViewActionsCount() == 0 && actions.getOnHideActionsCount() == 0) {
-            return;
-        }
-        // For invisible views, short-cut triggering of hide/show actions.
-        if (view.getVisibility() != View.VISIBLE || !ViewCompat.isAttachedToWindow(view)) {
-            triggerHideActions(view, actions, actionHandler, frame, activeActions);
-            return;
-        }
-
-        // Figure out overlap of viewport and view, and trigger based on proportion overlap.
-        Rect viewRect = getViewRectOnScreen(view);
-        Rect viewportRect = getViewRectOnScreen(viewport);
-
-        if (viewportRect.intersect(viewRect)) {
-            int viewArea = viewRect.height() * viewRect.width();
-            int visibleArea = viewportRect.height() * viewportRect.width();
-            float proportionVisible = ((float) visibleArea) / viewArea;
-
-            for (VisibilityAction visibilityAction : actions.getOnViewActionsList()) {
-                if (proportionVisible >= visibilityAction.getProportionVisible()) {
-                    if (activeActions.add(visibilityAction)) {
-                        actionHandler.handleAction(visibilityAction.getAction(), ActionType.VIEW,
-                                frame, view, LogData.getDefaultInstance());
-                    }
-                } else {
-                    activeActions.remove(visibilityAction);
-                }
-            }
-
-            for (VisibilityAction visibilityAction : actions.getOnHideActionsList()) {
-                if (proportionVisible < visibilityAction.getProportionVisible()) {
-                    if (activeActions.add(visibilityAction)) {
-                        actionHandler.handleAction(visibilityAction.getAction(), ActionType.VIEW,
-                                frame, view, LogData.getDefaultInstance());
-                    }
-                } else {
-                    activeActions.remove(visibilityAction);
-                }
-            }
-        }
-    }
-
-    static void triggerHideActions(View view, Actions actions, ActionHandler actionHandler,
-            Frame frame, Set<VisibilityAction> activeActions) {
-        activeActions.removeAll(actions.getOnViewActionsList());
-        for (VisibilityAction visibilityAction : actions.getOnHideActionsList()) {
-            if (activeActions.add(visibilityAction)) {
-                actionHandler.handleAction(visibilityAction.getAction(), ActionType.VIEW, frame,
-                        view, LogData.getDefaultInstance());
-            }
-        }
-    }
-
-    /**
-     * Replaces all non-transparent pixels of a {@link Drawable} with overlayColor and returns the
-     * new
-     * {@link Drawable}; If overlayColor is null, returns the original {@link Drawable}.
-     */
-    static Drawable applyOverlayColor(Drawable drawable, @Nullable Integer overlayColor) {
-        if (overlayColor == null) {
-            return drawable;
-        }
-        Drawable drawableWithOverlay = drawable.mutate();
-        drawableWithOverlay.setColorFilter(overlayColor, Mode.SRC_IN);
-        return drawableWithOverlay;
-    }
-
-    private static Rect getViewRectOnScreen(View view) {
-        int[] viewLocation = new int[2];
-        view.getLocationOnScreen(viewLocation);
-
-        return new Rect(viewLocation[0], viewLocation[1], viewLocation[0] + view.getWidth(),
-                viewLocation[1] + view.getHeight());
-    }
-
-    /** Private constructor to prevent instantiation. */
-    private ViewUtils() {}
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/ActionHandler.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/ActionHandler.java
deleted file mode 100644
index aae73df..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/ActionHandler.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.host;
-
-import android.view.View;
-
-import androidx.annotation.IntDef;
-
-import org.chromium.components.feed.core.proto.ui.piet.ActionsProto.Action;
-import org.chromium.components.feed.core.proto.ui.piet.LogDataProto.LogData;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Frame;
-
-/**
- * Interface from the Piet host which provides handling of {@link Action} from the UI. An instance
- * of this is provided by the host. When an action is raised by the client {@link
- * #handleAction(Action, int, Frame, View, String)} will be called.
- */
-public interface ActionHandler {
-    /** Called on a event, such as a click of a view, on a UI element */
-    // TODO: Do we need the veLoggingToken, one is defined in the Action
-    void handleAction(
-            Action action, @ActionType int actionType, Frame frame, View view, LogData logData);
-
-    /** Possible action types. */
-    @IntDef({ActionType.VIEW, ActionType.CLICK, ActionType.LONG_CLICK})
-    @interface ActionType {
-        /** View action type */
-        int VIEW = 0;
-
-        /** Click action */
-        int CLICK = 1;
-
-        /** Long click action */
-        int LONG_CLICK = 2;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/AssetProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/AssetProvider.java
deleted file mode 100644
index a1cb9b8e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/AssetProvider.java
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.host;
-
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.piet.host.TypefaceProvider.GoogleSansTypeface;
-import org.chromium.components.feed.core.proto.ui.piet.ImagesProto.Image;
-
-/** Provide Assets from the host */
-public class AssetProvider {
-    @VisibleForTesting
-    final ImageLoader mImageLoader;
-    @VisibleForTesting
-    final StringFormatter mStringFormatter;
-    private final Supplier<Integer> mDefaultCornerRadiusSupplier;
-    private final Supplier<Boolean> mIsDarkThemeSupplier;
-    private final Supplier<Long> mFadeImageThresholdMsSupplier;
-    private final Supplier<Boolean> mIsRtLSupplier;
-    @VisibleForTesting
-    final TypefaceProvider mTypefaceProvider;
-
-    public AssetProvider(ImageLoader imageLoader, StringFormatter stringFormatter,
-            Supplier<Integer> defaultCornerRadiusSupplier,
-            Supplier<Long> fadeImageThresholdMsSupplier, Supplier<Boolean> isDarkThemeSupplier,
-            Supplier<Boolean> isRtLSupplier, TypefaceProvider typefaceProvider) {
-        this.mImageLoader = imageLoader;
-        this.mStringFormatter = stringFormatter;
-        this.mDefaultCornerRadiusSupplier = defaultCornerRadiusSupplier;
-        this.mIsDarkThemeSupplier = isDarkThemeSupplier;
-        this.mFadeImageThresholdMsSupplier = fadeImageThresholdMsSupplier;
-        this.mIsRtLSupplier = isRtLSupplier;
-        this.mTypefaceProvider = typefaceProvider;
-    }
-
-    /**
-     * Given an {@link Image}, asynchronously load the {@link Drawable} and return via a {@link
-     * Consumer}.
-     *
-     * <p>The width and the height of the image can be provided preemptively, however it is not
-     * guaranteed that both dimensions will be known. In the case that only one dimension is known,
-     * the host should be careful to preserve the aspect ratio.
-     *
-     * @param image The image to load.
-     * @param widthPx The width of the {@link Image} in pixels. Will be {@link #DIMENSION_NOT_SET}
-     *         if
-     *     unknown.
-     * @param heightPx The height of the {@link Image} in pixels. Will be {@link #DIMENSION_NOT_SET}
-     *     if unknown.
-     * @param consumer Callback to return the {@link Drawable} from an {@link Image} if the load
-     *     succeeds. {@literal null} should be passed to this if no source succeeds in loading the
-     *     image
-     */
-    public void getImage(Image image, int widthPx, int heightPx, Consumer<Drawable> consumer) {
-        mImageLoader.getImage(image, widthPx, heightPx, consumer);
-    }
-
-    /** Return a relative elapsed time string such as "8 minutes ago" or "1 day ago". */
-    public String getRelativeElapsedString(long elapsedTimeMillis) {
-        return mStringFormatter.getRelativeElapsedString(elapsedTimeMillis);
-    }
-
-    /** Returns the default corner rounding radius in pixels. */
-    public int getDefaultCornerRadius() {
-        return mDefaultCornerRadiusSupplier.get();
-    }
-
-    /** Returns whether the theme for the Piet rendering context is a "dark theme". */
-    public boolean isDarkTheme() {
-        return mIsDarkThemeSupplier.get();
-    }
-
-    /**
-     * Fade-in animation will only occur if image loading time takes more than this amount of time.
-     */
-    public long getFadeImageThresholdMs() {
-        return mFadeImageThresholdMsSupplier.get();
-    }
-
-    /**
-     * Allows the host to return a typeface Piet would otherwise not be able to access (ex. from
-     * assets). Piet will call this when the typeface is not one Piet recognizes (as a default
-     * Android typeface). If host does not specially handle the specified typeface, host can return
-     * {@code null}, and Piet will proceed through its fallback typefaces.
-     *
-     * <p>Piet also expects the host to provide the Google Sans typeface, and will request it using
-     * the {@link GoogleSansTypeface} StringDef. Piet will report errors if Google Sans is requested
-     * and not found.
-     */
-    public void getTypeface(String typeface, boolean isItalic, Consumer<Typeface> consumer) {
-        mTypefaceProvider.getTypeface(typeface, isItalic, consumer);
-    }
-
-    /** Returns whether Piet should render layouts using a right-to-left orientation. */
-    public boolean isRtL() {
-        return mIsRtLSupplier.get();
-    }
-
-    /** Returns whether Piet should render layouts using a right-to-left orientation. */
-    public Supplier<Boolean> isRtLSupplier() {
-        return mIsRtLSupplier;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/CustomElementProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/CustomElementProvider.java
deleted file mode 100644
index 48064598..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/CustomElementProvider.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.host;
-
-import android.view.View;
-
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.CustomElementData;
-
-/**
- * Provides custom elements from the host. Host must handle filtering for supported extensions and
- * returning a view.
- */
-public interface CustomElementProvider {
-    /** Requests that the host create a view based on an extension on CustomElementData. */
-    View createCustomElement(CustomElementData customElementData);
-
-    /** Notify the host that Piet is done with and will no longer use this custom element View. */
-    void releaseCustomView(View customElementView, CustomElementData customElementData);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/EmptyStringFormatter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/EmptyStringFormatter.java
deleted file mode 100644
index 76a6323..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/EmptyStringFormatter.java
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.host;
-
-/** {@link StringFormatter} that returns empty string, for hosts that do not use this capability. */
-public class EmptyStringFormatter implements StringFormatter {
-    @Override
-    public String getRelativeElapsedString(long elapsedTimeMillis) {
-        return "";
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/EventLogger.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/EventLogger.java
deleted file mode 100644
index 8fbe712..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/EventLogger.java
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.host;
-
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-
-import java.util.List;
-
-/** Allows Piet to report events to the host. */
-public interface EventLogger {
-    /**
-     * Tells the host each {@link ErrorCode} that was raised during the binding of a Frame. This
-     * list can contain duplicates.
-     */
-    void logEvents(List<ErrorCode> errorCodes);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/HostBindingProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/HostBindingProvider.java
deleted file mode 100644
index 2b64907e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/HostBindingProvider.java
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.host;
-
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.ActionsBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.ChunkedTextBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.CustomBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.ElementBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.GridCellWidthBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.ImageBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.LogDataBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.ParameterizedTextBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.StyleBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.TemplateBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.VisibilityBindingRef;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.BindingValue;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.HostBindingData;
-
-/**
- * Interface which allows a host to provide bindings to Piet directly. This specifically allows
- * changing bindings based on on-device information.
- *
- * <p>Methods are called by Piet during the binding process when their associated *BindingRef is
- * found and the server has specified a {@link BindingValue} which includes a {@link
- * HostBindingData} set.
- *
- * <p>Methods returns should include the associated binding filled in with no {@link
- * HostBindingData}. If a {@link HostBindingData} is set on the returned {@link BindingValue}
- * instances then it will be ignored.
- *
- * <p>This class provides a default implementation which just removes {@link HostBindingData} from
- * any server specified {@link HostBindingData}.
- *
- * <p>See [INTERNAL LINK].
- */
-public class HostBindingProvider {
-    /**
-     * Called by Piet during the binding process for a {@link CustomBindingRef} if the server has
-     * specified a BindingValue which includes {@link HostBindingData} set.
-     */
-    public BindingValue getCustomElementDataBindingForValue(BindingValue bindingValue) {
-        return clearHostBindingData(bindingValue);
-    }
-
-    /**
-     * Called by Piet during the binding process for a {@link ParameterizedTextBindingRef} if the
-     * server has specified a BindingValue which includes {@link HostBindingData} set.
-     */
-    public BindingValue getParameterizedTextBindingForValue(BindingValue bindingValue) {
-        return clearHostBindingData(bindingValue);
-    }
-
-    /**
-     * Called by Piet during the binding process for a {@link ChunkedTextBindingRef} if the server
-     * has specified a BindingValue which includes {@link HostBindingData} set.
-     */
-    public BindingValue getChunkedTextBindingForValue(BindingValue bindingValue) {
-        return clearHostBindingData(bindingValue);
-    }
-
-    /**
-     * Called by Piet during the binding process for a {@link ImageBindingRef} if the server has
-     * specified a BindingValue which includes {@link HostBindingData} set.
-     */
-    public BindingValue getImageBindingForValue(BindingValue bindingValue) {
-        return clearHostBindingData(bindingValue);
-    }
-
-    /**
-     * Called by Piet during the binding process for a {@link ActionsBindingRef} if the server has
-     * specified a BindingValue which includes {@link HostBindingData} set.
-     */
-    public BindingValue getActionsBindingForValue(BindingValue bindingValue) {
-        return clearHostBindingData(bindingValue);
-    }
-
-    /**
-     * Called by Piet during the binding process for a {@link GridCellWidthBindingRef} if the server
-     * has specified a BindingValue which includes {@link HostBindingData} set.
-     */
-    public BindingValue getGridCellWidthBindingForValue(BindingValue bindingValue) {
-        return clearHostBindingData(bindingValue);
-    }
-
-    /**
-     * Called by Piet during the binding process for a {@link ElementBindingRef} if the server has
-     * specified a BindingValue which includes {@link HostBindingData} set.
-     */
-    public BindingValue getElementBindingForValue(BindingValue bindingValue) {
-        return clearHostBindingData(bindingValue);
-    }
-
-    /**
-     * Called by Piet during the binding process for a {@link LogDataBindingRef} if the server has
-     * specified a BindingValue which includes {@link HostBindingData} set.
-     */
-    public BindingValue getLogDataBindingForValue(BindingValue bindingValue) {
-        return clearHostBindingData(bindingValue);
-    }
-
-    /**
-     * Called by Piet during the binding process for a {@link TemplateBindingRef} if the server has
-     * specified a BindingValue which includes {@link HostBindingData} set.
-     */
-    public BindingValue getTemplateBindingForValue(BindingValue bindingValue) {
-        return clearHostBindingData(bindingValue);
-    }
-
-    /**
-     * Called by Piet during the binding process for a {@link StyleBindingRef} if the server has
-     * specified a BindingValue which includes {@link HostBindingData} set.
-     */
-    public BindingValue getStyleBindingForValue(BindingValue bindingValue) {
-        return clearHostBindingData(bindingValue);
-    }
-
-    /**
-     * Called by Piet during the binding process for a {@link VisibilityBindingRef} if the server
-     * has specified a BindingValue which includes {@link HostBindingData} set.
-     */
-    public BindingValue getVisibilityBindingForValue(BindingValue bindingValue) {
-        return clearHostBindingData(bindingValue);
-    }
-
-    private BindingValue clearHostBindingData(BindingValue bindingValue) {
-        return bindingValue.toBuilder().clearHostBindingData().build();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/ImageLoader.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/ImageLoader.java
deleted file mode 100644
index 1c5c4dfe..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/ImageLoader.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.host;
-
-import android.graphics.drawable.Drawable;
-
-import org.chromium.base.Consumer;
-import org.chromium.components.feed.core.proto.ui.piet.ImagesProto.Image;
-
-/** Class that allows Piet to ask the host to load an image. */
-public interface ImageLoader {
-    /**
-     * Given an {@link Image}, asynchronously load the {@link Drawable} and return via a {@link
-     * Consumer}.
-     *
-     * <p>The width and the height of the image can be provided preemptively, however it is not
-     * guaranteed that both dimensions will be known. In the case that only one dimension is known,
-     * the host should be careful to preserve the aspect ratio.
-     *
-     * @param image The image to load.
-     * @param widthPx The width of the {@link Image} in pixels. Will be {@link #DIMENSION_UNKNOWN}
-     *         if
-     *     unknown.
-     * @param heightPx The height of the {@link Image} in pixels. Will be {@link #DIMENSION_UNKNOWN}
-     *     if unknown.
-     * @param consumer Callback to return the {@link Drawable} from an {@link Image} if the load
-     *     succeeds. {@literal null} should be passed to this if no source succeeds in loading the
-     *     image
-     */
-    void getImage(Image image, int widthPx, int heightPx, Consumer<Drawable> consumer);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/LogDataCallback.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/LogDataCallback.java
deleted file mode 100644
index 14217c1..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/LogDataCallback.java
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.host;
-
-import android.view.View;
-
-import org.chromium.components.feed.core.proto.ui.piet.LogDataProto.LogData;
-
-public interface LogDataCallback {
-    void onBind(LogData logData, View view);
-
-    void onUnbind(LogData logData, View view);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/NullImageLoader.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/NullImageLoader.java
deleted file mode 100644
index dab002d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/NullImageLoader.java
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.host;
-
-import android.graphics.drawable.Drawable;
-
-import org.chromium.base.Consumer;
-import org.chromium.components.feed.core.proto.ui.piet.ImagesProto.Image;
-
-/** {@link ImageLoader} that always returns {@link null}. For image-less clients. */
-public class NullImageLoader implements ImageLoader {
-    @Override
-    public void getImage(Image image, int widthPx, int heightPx, Consumer<Drawable> consumer) {
-        consumer.accept(null);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/NullTypefaceProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/NullTypefaceProvider.java
deleted file mode 100644
index 25e4ae3..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/NullTypefaceProvider.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.host;
-
-import android.graphics.Typeface;
-
-import org.chromium.base.Consumer;
-
-/** Typeface provider that does not provide any typefaces; for use as a default implementation. */
-public class NullTypefaceProvider implements TypefaceProvider {
-    @Override
-    public void getTypeface(String typeface, boolean isItalic, Consumer<Typeface> consumer) {
-        consumer.accept(null);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/StringFormatter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/StringFormatter.java
deleted file mode 100644
index 27c6b86..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/StringFormatter.java
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.host;
-
-/** Lets Piet ask the host to format strings. */
-public interface StringFormatter {
-    /** Return a relative elapsed time string such as "8 minutes ago" or "1 day ago". */
-    String getRelativeElapsedString(long elapsedTimeMillis);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/ThrowingCustomElementProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/ThrowingCustomElementProvider.java
deleted file mode 100644
index 4e62c08..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/ThrowingCustomElementProvider.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.host;
-
-import android.view.View;
-
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.CustomElement;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.CustomElementData;
-
-/**
- * {@link CustomElementProvider} for implementations of Piet that do not use {@link CustomElement}.
- */
-public class ThrowingCustomElementProvider implements CustomElementProvider {
-    public ThrowingCustomElementProvider() {}
-
-    @Override
-    public View createCustomElement(CustomElementData customElementData) {
-        throw new UnsupportedOperationException(
-                "CustomElements are not supported by this implementation!");
-    }
-
-    @Override
-    public void releaseCustomView(View customElementView, CustomElementData customElementData) {
-        throw new UnsupportedOperationException(
-                "CustomElements are not supported by this implementation!");
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/TypefaceProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/TypefaceProvider.java
deleted file mode 100644
index 7eda5c23..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/TypefaceProvider.java
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.host;
-
-import android.graphics.Typeface;
-
-import androidx.annotation.StringDef;
-
-import org.chromium.base.Consumer;
-
-/** Allows the host to provide Typefaces to Piet. */
-public interface TypefaceProvider {
-    /**
-     * Allows the host to load a typeface Piet would otherwise not be able to access (ex. from
-     * assets), and return it via the consumer. Piet will call this when the typeface is not one
-     * Piet recognizes (as a default Android typeface). If host does not specially handle the
-     * specified typeface, host can accept {@code null} through the consumer, and Piet will proceed
-     * through its fallback typefaces.
-     *
-     * <p>Piet also expects the host to provide the Google Sans typeface, and will request it using
-     * the {@link GoogleSansTypeface} StringDef. Piet will report errors if Google Sans is requested
-     * and not found.
-     *
-     * @param typeface the String that the host uses to identify which typeface to load.
-     * @param isItalic specifies whether the font should be italic. This is passed to the host
-     *         instead
-     *     of being handled by Piet so that the host can decide whether to just set the italic bits
-     *     for the typeface or, if they want, return an entirely different font for the italic
-     *     version.
-     * @param consumer accepts the typeface once it's loaded, via consumer.accept(Typeface). If the
-     *     host does not recognize the typeface name or fails to load the typeface, it should accept
-     *     {@code null}. If the host does NOT call consumer.accept(null), Piet will not load the
-     *     fallback font, and will just use the platform default.
-     */
-    void getTypeface(String typeface, boolean isItalic, Consumer<Typeface> consumer);
-
-    /**
-     * Strings the host can expect to receive to request Google Sans fonts. These are intentionally
-     * decoupled from the Piet CommonTypeface enum so we can change the proto enum names without
-     * breaking older hosts.
-     */
-    @StringDef({GoogleSansTypeface.UNDEFINED, GoogleSansTypeface.GOOGLE_SANS_REGULAR,
-            GoogleSansTypeface.GOOGLE_SANS_MEDIUM})
-    @interface GoogleSansTypeface {
-        String UNDEFINED = "UNDEFINED";
-        String GOOGLE_SANS_REGULAR = "GOOGLE_SANS_REGULAR";
-        String GOOGLE_SANS_MEDIUM = "GOOGLE_SANS_MEDIUM";
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/res/drawable-v21/piet_clickable_ripple.xml b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/res/drawable-v21/piet_clickable_ripple.xml
deleted file mode 100644
index dfa447f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/res/drawable-v21/piet_clickable_ripple.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright 2019 The Chromium Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
--->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="?android:attr/colorControlHighlight">
-  <!-- Mask drawable, not actually rendered. This just keeps the ripple inside the module. -->
-  <item android:id="@android:id/mask" android:drawable="@android:color/white"/>
-</ripple>
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/res/values/styles.xml b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/res/values/styles.xml
deleted file mode 100644
index 8e77b8d0..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/res/values/styles.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright 2019 The Chromium Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-  <style name="gm_font_weight_regular">
-    <item name="android:fontFamily">sans-serif</item>
-    <item name="android:textAlignment">viewStart</item>
-  </style>
-
-  <style name="gm_font_weight_light">
-    <item name="android:fontFamily">sans-serif-light</item>
-    <item name="android:textAlignment">viewStart</item>
-  </style>
-
-  <style name="gm_font_weight_medium">
-    <item name="android:fontFamily">sans-serif-medium</item>
-    <item name="android:textAlignment">viewStart</item>
-  </style>
-</resources>
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/testing/FakeFrameAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/testing/FakeFrameAdapter.java
deleted file mode 100644
index 41456da..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/testing/FakeFrameAdapter.java
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.testing;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import android.content.Context;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.piet.FrameAdapter;
-import org.chromium.chrome.browser.feed.library.piet.host.ActionHandler;
-import org.chromium.chrome.browser.feed.library.piet.host.ActionHandler.ActionType;
-import org.chromium.components.feed.core.proto.ui.piet.ActionsProto.Action;
-import org.chromium.components.feed.core.proto.ui.piet.LogDataProto.LogData;
-import org.chromium.components.feed.core.proto.ui.piet.PietAndroidSupport;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.Frame;
-import org.chromium.components.feed.core.proto.ui.piet.PietProto.PietSharedState;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Fake for {@link FrameAdapter}. */
-public class FakeFrameAdapter implements FrameAdapter {
-    private final List<Action> mViewActions;
-    private final List<Action> mHideActions;
-    private final LinearLayout mFrameContainer;
-    private final ActionHandler mActionHandler;
-
-    public boolean mIsBound;
-    private boolean mViewActionsTriggered;
-    @Nullable
-    private Frame mFrame;
-
-    private FakeFrameAdapter(Context context, List<Action> viewActions, List<Action> hideActions,
-            ActionHandler actionHandler) {
-        this.mViewActions = viewActions;
-        this.mFrameContainer = new LinearLayout(context);
-        this.mActionHandler = actionHandler;
-        this.mHideActions = hideActions;
-    }
-
-    @Override
-    public void bindModel(Frame frame, int frameWidthPx,
-            @Nullable PietAndroidSupport.ShardingControl shardingControl,
-            List<PietSharedState> pietSharedStates) {
-        checkState(!mIsBound);
-        this.mFrame = frame;
-        mIsBound = true;
-    }
-
-    @Override
-    public void unbindModel() {
-        checkState(mIsBound);
-        triggerHideActions();
-        mFrame = null;
-        mIsBound = false;
-        mViewActionsTriggered = false;
-    }
-
-    @Override
-    public LinearLayout getFrameContainer() {
-        return mFrameContainer;
-    }
-
-    @Override
-    public void triggerHideActions() {
-        if (!mViewActionsTriggered) {
-            return;
-        }
-
-        if (!mIsBound) {
-            return;
-        }
-
-        for (Action action : mHideActions) {
-            mActionHandler.handleAction(action, ActionType.VIEW, checkNotNull(mFrame),
-                    mFrameContainer, LogData.getDefaultInstance());
-        }
-
-        mViewActionsTriggered = false;
-    }
-
-    @Override
-    public void triggerViewActions(View viewport) {
-        if (mViewActionsTriggered) {
-            return;
-        }
-
-        if (!mIsBound) {
-            return;
-        }
-
-        // Assume all view actions are fired when triggerViewActions is called.
-        for (Action action : mViewActions) {
-            mActionHandler.handleAction(action, ActionType.VIEW, checkNotNull(mFrame),
-                    mFrameContainer,
-                    /* logData= */ LogData.getDefaultInstance());
-        }
-
-        mViewActionsTriggered = true;
-    }
-
-    /** Returns whether the {@link FrameAdapter} is bound. */
-    public boolean isBound() {
-        return mIsBound;
-    }
-
-    /** Returns a new builder for a {@link FakeFrameAdapter} */
-    public static Builder builder(Context context) {
-        return new Builder(context);
-    }
-
-    /** Builder for {@link FakeFrameAdapter}. */
-    public static final class Builder {
-        private final Context mContext;
-        private final List<Action> mViewActions;
-        private final List<Action> mHideActions;
-
-        private ActionHandler mActionHandler;
-
-        private Builder(Context context) {
-            this.mContext = context;
-            mViewActions = new ArrayList<>();
-            mHideActions = new ArrayList<>();
-            mActionHandler = new NoOpActionHandler();
-        }
-
-        public Builder addViewAction(Action viewAction) {
-            mViewActions.add(viewAction);
-            return this;
-        }
-
-        public Builder addHideAction(Action hideAction) {
-            mHideActions.add(hideAction);
-            return this;
-        }
-
-        /**
-         * Sets the {@link ActionHandler} to be used when triggering actions. If not set, actions
-         * will no-op.
-         */
-        public Builder setActionHandler(ActionHandler actionHandler) {
-            this.mActionHandler = actionHandler;
-            return this;
-        }
-
-        public FakeFrameAdapter build() {
-            return new FakeFrameAdapter(mContext, mViewActions, mHideActions, mActionHandler);
-        }
-    }
-
-    private static final class NoOpActionHandler implements ActionHandler {
-        @Override
-        public void handleAction(Action action, @ActionType int actionType, Frame frame, View view,
-                LogData logData) {}
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/AspectRatioScalingImageView.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/AspectRatioScalingImageView.java
deleted file mode 100644
index 2aeca46..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/AspectRatioScalingImageView.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.ui;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.widget.ImageView;
-
-/** {@link ImageView} which always aspect-ratio scales the image to fit its container. */
-public class AspectRatioScalingImageView extends ImageView {
-    /** Default aspect ratio for the view when the drawable is not set. Set to zero to ignore. */
-    private float mDefaultAspectRatio;
-
-    public AspectRatioScalingImageView(Context context) {
-        super(context);
-    }
-
-    public void setDefaultAspectRatio(float aspectRatio) {
-        mDefaultAspectRatio = aspectRatio;
-        invalidate();
-    }
-
-    /**
-     * This custom onMeasure scales the image to fill the container. If the container has only one
-     * constrained dimension, the image is aspect ratio scaled to its max possible size given the
-     * constraining dimension.
-     *
-     * <p>This is overridden because adjustViewBounds does not scale up small images in API 17-, and
-     * because we want the image to scale independent of the dimensions of the Drawable - the image
-     * should not change size based on the resolution of the Drawable, only the aspect ratio.
-     */
-    @Override
-    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        Drawable drawable = getDrawable();
-
-        // Try to get the aspect ratio; if we can't, fall back to super.
-        // width / height
-        float aspectRatio;
-        if (drawable != null && drawable.getIntrinsicHeight() > 0
-                && drawable.getIntrinsicWidth() > 0) {
-            aspectRatio = ((float) drawable.getIntrinsicWidth()) / drawable.getIntrinsicHeight();
-        } else if (mDefaultAspectRatio > 0) {
-            aspectRatio = mDefaultAspectRatio;
-        } else {
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-            return;
-        }
-        // height / width
-        float inverseAspectRatio = 1 / aspectRatio;
-
-        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
-        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
-
-        int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
-        int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
-
-        if (widthSpecMode == MeasureSpec.UNSPECIFIED && heightSpecMode != MeasureSpec.UNSPECIFIED) {
-            // Aspect ratio scale the width
-            measuredWidth = aspectRatioScaleWidth(measuredHeight, aspectRatio);
-        } else if (heightSpecMode == MeasureSpec.UNSPECIFIED
-                && widthSpecMode != MeasureSpec.UNSPECIFIED) {
-            // Aspect ratio scale the height
-            measuredHeight = aspectRatioScaleHeight(measuredWidth, inverseAspectRatio);
-        } else if (heightSpecMode == MeasureSpec.UNSPECIFIED
-                && widthSpecMode == MeasureSpec.UNSPECIFIED) {
-            // If both are UNSPECIFIED, take up as much room as possible.
-            measuredWidth = Integer.MAX_VALUE;
-            measuredHeight = Integer.MAX_VALUE;
-        } else if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.EXACTLY) {
-            measuredWidth =
-                    Math.min(aspectRatioScaleWidth(measuredHeight, aspectRatio), measuredWidth);
-        } else if (heightSpecMode == MeasureSpec.AT_MOST && widthSpecMode == MeasureSpec.EXACTLY) {
-            measuredHeight = Math.min(
-                    aspectRatioScaleHeight(measuredWidth, inverseAspectRatio), measuredHeight);
-        } else if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
-            int desiredWidth = aspectRatioScaleWidth(measuredHeight, aspectRatio);
-            int desiredHeight = aspectRatioScaleHeight(measuredWidth, inverseAspectRatio);
-            if (desiredWidth < measuredWidth) {
-                measuredWidth = desiredWidth;
-            } else if (desiredHeight < measuredHeight) {
-                measuredHeight = desiredHeight;
-            }
-        }
-        // else keep values from the MeasureSpec because both modes are EXACTLY.
-
-        setMeasuredDimension(measuredWidth, measuredHeight);
-    }
-
-    private int aspectRatioScaleWidth(int constrainingHeight, float aspectRatio) {
-        int imageHeight = constrainingHeight - getPaddingTop() - getPaddingBottom();
-        int imageWidth = (int) (imageHeight * aspectRatio);
-        return imageWidth + getPaddingRight() + getPaddingLeft();
-    }
-
-    private int aspectRatioScaleHeight(int constrainingWidth, float inverseAspectRatio) {
-        int imageWidth = constrainingWidth - getPaddingRight() - getPaddingLeft();
-        int imageHeight = (int) (imageWidth * inverseAspectRatio);
-        return imageHeight + getPaddingTop() + getPaddingBottom();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/BitmapMaskingRoundedCornerDelegate.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/BitmapMaskingRoundedCornerDelegate.java
deleted file mode 100644
index c5632e2..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/BitmapMaskingRoundedCornerDelegate.java
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.ui;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.os.Build;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.piet.ui.RoundedCornerMaskCache.Corner;
-import org.chromium.chrome.browser.feed.library.piet.ui.RoundedCornerMaskCache.RoundedCornerBitmaps;
-import org.chromium.components.feed.core.proto.ui.piet.RoundedCornersProto.RoundedCorners.Corners;
-
-/**
- * Rounding delegate for the bitmap masking strategy.
- *
- * <p>Handles creation of corner mask bitmaps. Since creating bitmaps is expensive, this class also
- * saves them and makes sure they are not re-created unless necessary. {@link
- * RoundedCornerWrapperView} decides which rounding strategy to use and sets the appropriate
- * delegate.
- */
-class BitmapMaskingRoundedCornerDelegate extends RoundedCornerDelegate {
-    private final Paint mPaint;
-    private final Paint mMaskPaint;
-    private final RoundedCornerMaskCache mMaskCache;
-    private final int mBitmask;
-    private final Canvas mOffscreenCanvas;
-
-    // Masks for each of the corners of the view; null if that corner is not rounded.
-    @Nullable
-    private Bitmap mCornerTL;
-    @Nullable
-    private Bitmap mCornerTR;
-    @Nullable
-    private Bitmap mCornerBL;
-    @Nullable
-    private Bitmap mCornerBR;
-
-    // Keep track of current mask configuration so we can use cached values if nothing has changed.
-    private int mLastRadius = -1;
-    private boolean mLastRtL;
-
-    BitmapMaskingRoundedCornerDelegate(
-            RoundedCornerMaskCache maskCache, int bitmask, boolean isRtL) {
-        this(maskCache, bitmask, isRtL, new Canvas());
-    }
-
-    BitmapMaskingRoundedCornerDelegate(
-            RoundedCornerMaskCache maskCache, int bitmask, boolean isRtL, Canvas canvas) {
-        this.mMaskCache = maskCache;
-        mOffscreenCanvas = canvas;
-        this.mLastRtL = !isRtL; // Flip this so we must update the layout on the first time.
-        this.mBitmask = bitmask;
-        this.mPaint = maskCache.getPaint();
-        this.mMaskPaint = maskCache.getMaskPaint();
-    }
-
-    /**
-     * Defensively make sure outline clipping is turned off, although that should be the default.
-     */
-    @Override
-    public void initializeForView(ViewGroup view) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            view.setClipToOutline(false);
-            view.setClipChildren(false);
-        }
-    }
-
-    private void initCornerMasks(int radius, boolean isRtL) {
-        if (radius < 1) {
-            return;
-        }
-        RoundedCornerBitmaps masks = mMaskCache.getMasks(radius);
-
-        if ((RoundedCornerViewHelper.shouldRoundCorner(Corners.TOP_START, mBitmask) && !isRtL)
-                || (RoundedCornerViewHelper.shouldRoundCorner(Corners.TOP_END, mBitmask)
-                        && isRtL)) {
-            mCornerTL = masks.get(Corner.TOP_LEFT);
-        } else {
-            mCornerTL = null;
-        }
-
-        if ((RoundedCornerViewHelper.shouldRoundCorner(Corners.TOP_END, mBitmask) && !isRtL)
-                || (RoundedCornerViewHelper.shouldRoundCorner(Corners.TOP_START, mBitmask)
-                        && isRtL)) {
-            mCornerTR = masks.get(Corner.TOP_RIGHT);
-        } else {
-            mCornerTR = null;
-        }
-
-        if ((RoundedCornerViewHelper.shouldRoundCorner(Corners.BOTTOM_START, mBitmask) && !isRtL)
-                || (RoundedCornerViewHelper.shouldRoundCorner(Corners.BOTTOM_END, mBitmask)
-                        && isRtL)) {
-            mCornerBL = masks.get(Corner.BOTTOM_LEFT);
-        } else {
-            mCornerBL = null;
-        }
-
-        if ((RoundedCornerViewHelper.shouldRoundCorner(Corners.BOTTOM_END, mBitmask) && !isRtL)
-                || (RoundedCornerViewHelper.shouldRoundCorner(Corners.BOTTOM_START, mBitmask)
-                        && isRtL)) {
-            mCornerBR = masks.get(Corner.BOTTOM_RIGHT);
-        } else {
-            mCornerBR = null;
-        }
-    }
-
-    /**
-     * Creates corner masks (which cover the parts of the corners that should not be shown).
-     *
-     * <p>Masks must be created after the radius is known. However, if the size of the view and the
-     * LtR remain the same, it will only create the masks once.
-     */
-    @Override
-    public void onLayout(int radius, boolean isRtL, int width, int height) {
-        if (radius == 0) {
-            return;
-        }
-        if (radius == mLastRadius && isRtL == mLastRtL) {
-            return;
-        }
-
-        initCornerMasks(radius, isRtL);
-
-        mLastRadius = radius;
-        mLastRtL = isRtL;
-    }
-
-    /**
-     * Ensures that the wrapper view is invalidated when child views are invalidated.
-     *
-     * <p>This method only exists in Android O+.
-     */
-    @Override
-    public void onDescendantInvalidated(View roundedCornerView, View invalidatedDescendant) {
-        Rect targetRect = new Rect();
-        invalidatedDescendant.getDrawingRect(targetRect);
-        roundedCornerView.invalidate(targetRect);
-    }
-
-    /**
-     * Ensures that the wrapper view is invalidated when the child view is.
-     *
-     * <p>This is only used in Android N- and is deprecated, but we must use it because
-     * onDescendantInvalidated only exists in O+.
-     */
-    @Override
-    public void invalidateChildInParent(View view, final Rect dirty) {
-        view.invalidate(dirty);
-    }
-
-    /**
-     * Creates a local bitmap and draws the content and corner masks on top of that.
-     *
-     * <p>The bitmap is drawn directly to the {@link Canvas} that is passed into this method.
-     */
-    @Override
-    public void draw(RoundedCornerWrapperView view, Canvas canvas) {
-        int width = view.getWidth();
-        int height = view.getHeight();
-        if (width == 0 || height == 0) {
-            // The view is not visible, and offscreenBitmap creation will fail. Stop here. Call the
-            // super method to make sure the lifecycle is handled properly.
-            view.drawSuper(canvas);
-            return;
-        }
-        int radius = view.getRadius(width, height);
-        Bitmap localOffscreenBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-        mOffscreenCanvas.setBitmap(localOffscreenBitmap);
-        view.drawSuper(mOffscreenCanvas);
-        drawWithCornerMasks(canvas, radius, width, height, localOffscreenBitmap);
-    }
-
-    private void drawWithCornerMasks(
-            Canvas canvas, int radius, int width, int height, Bitmap offscreenBitmap) {
-        // Crop the corners off using masks
-        maskCorners(mOffscreenCanvas, width, height, radius);
-
-        // Draw the offscreen bitmap (view with rounded corners) to the target canvas.
-        canvas.drawBitmap(offscreenBitmap, 0f, 0f, mPaint);
-    }
-
-    /** Draws a mask on each corner that is rounded. */
-    private void maskCorners(Canvas canvas, int width, int height, int radius) {
-        if (mCornerTL != null) {
-            canvas.drawBitmap(mCornerTL, 0, 0, mMaskPaint);
-        }
-        if (mCornerTR != null) {
-            canvas.drawBitmap(mCornerTR, width - radius, 0, mMaskPaint);
-        }
-        if (mCornerBL != null) {
-            canvas.drawBitmap(mCornerBL, 0, height - radius, mMaskPaint);
-        }
-        if (mCornerBR != null) {
-            canvas.drawBitmap(mCornerBR, width - radius, height - radius, mMaskPaint);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/BorderDrawable.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/BorderDrawable.java
deleted file mode 100644
index 9f62c65..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/BorderDrawable.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.ui;
-
-import android.content.Context;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.RoundRectShape;
-
-import org.chromium.chrome.browser.feed.library.common.ui.LayoutUtils;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.Borders;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.Borders.Edges;
-
-/**
- * Shape used to draw borders. Uses offsets to push the border out of the drawing bounds if it is
- * not specified.
- */
-public class BorderDrawable extends ShapeDrawable {
-    private final boolean mHasLeftBorder;
-    private final boolean mHasRightBorder;
-    private final boolean mHasTopBorder;
-    private final boolean mHasBottomBorder;
-    private final int mOffsetToHideLeft;
-    private final int mOffsetToHideRight;
-    private final int mOffsetToHideTop;
-    private final int mOffsetToHideBottom;
-    private final int mBorderWidth;
-
-    public BorderDrawable(Context context, Borders borders, float[] cornerRadii, boolean isRtL) {
-        this(context, borders, cornerRadii, isRtL, /* width= */ 0, /* height= */ 0);
-    }
-
-    // Doesn't like calls to getPaint()
-    @SuppressWarnings("nullness")
-    public BorderDrawable(Context context, Borders borders, float[] cornerRadii, boolean isRtL,
-            int width, int height) {
-        super(new RoundRectShape(cornerRadii, null, null));
-
-        mBorderWidth = (int) LayoutUtils.dpToPx(borders.getWidth(), context);
-
-        // Calculate the offsets which push the border outside the view, making it invisible
-        int bitmask = borders.getBitmask();
-        if (bitmask == 0 || bitmask == 15) {
-            // All borders are visible
-            mHasLeftBorder = true;
-            mHasRightBorder = true;
-            mHasTopBorder = true;
-            mHasBottomBorder = true;
-            mOffsetToHideLeft = 0;
-            mOffsetToHideRight = 0;
-            mOffsetToHideTop = 0;
-            mOffsetToHideBottom = 0;
-        } else {
-            int leftEdge = isRtL ? Edges.END.getNumber() : Edges.START.getNumber();
-            int rightEdge = isRtL ? Edges.START.getNumber() : Edges.END.getNumber();
-            mHasLeftBorder = (bitmask & leftEdge) != 0;
-            mHasRightBorder = (bitmask & rightEdge) != 0;
-            mHasTopBorder = (bitmask & Edges.TOP.getNumber()) != 0;
-            mHasBottomBorder = (bitmask & Edges.BOTTOM.getNumber()) != 0;
-            mOffsetToHideLeft = mHasLeftBorder ? 0 : -mBorderWidth;
-            mOffsetToHideRight = mHasRightBorder ? 0 : mBorderWidth;
-            mOffsetToHideTop = mHasTopBorder ? 0 : -mBorderWidth;
-            mOffsetToHideBottom = mHasBottomBorder ? 0 : mBorderWidth;
-        }
-        getPaint().setStyle(Paint.Style.STROKE);
-        // Multiply the width by two - the centerline of the stroke will be the edge of the view, so
-        // half of the stroke will be outside the view. In order for the visible portion to have the
-        // correct width, the full stroke needs to be twice as wide.
-        // For rounded corners, this relies on the containing FrameLayout to crop the outside half
-        // of the rounded border; otherwise, the border would get thicker on the corners.
-        getPaint().setStrokeWidth(mBorderWidth * 2);
-        getPaint().setColor(borders.getColor());
-    }
-
-    @Override
-    public void setBounds(int left, int top, int right, int bottom) {
-        super.setBounds(left + mOffsetToHideLeft, top + mOffsetToHideTop,
-                right + mOffsetToHideRight, bottom + mOffsetToHideBottom);
-    }
-
-    @Override
-    public void setBounds(Rect bounds) {
-        setBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/ClipPathRoundedCornerDelegate.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/ClipPathRoundedCornerDelegate.java
deleted file mode 100644
index 268ef5a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/ClipPathRoundedCornerDelegate.java
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.ui;
-
-import android.graphics.Canvas;
-import android.graphics.Path;
-import android.graphics.RectF;
-import android.os.Build;
-import android.view.ViewGroup;
-
-/**
- * Rounding delegate for the clip path strategy.
- *
- * <p>Adds logic to create a path along the edge of the view and clip to it. {@link
- * RoundedCornerWrapperView} decides which rounding strategy to use and sets the appropriate
- * delegate.
- */
-class ClipPathRoundedCornerDelegate extends RoundedCornerDelegate {
-    private final Path mClipPath = new Path();
-
-    /**
-     * Turns off clipping to the outline.
-     *
-     * <p>This rounding strategy should not be doing outline clipping. This defensively makes sure
-     * it's turned off, although that should be the default.
-     */
-    @Override
-    public void initializeForView(ViewGroup view) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            view.setClipToOutline(false);
-            view.setClipChildren(false);
-        }
-    }
-
-    /** Updates the path every time the size changes. */
-    @Override
-    public void onSizeChanged(int radius, int width, int height, int bitmask, boolean isRtL) {
-        float[] radii = RoundedCornerViewHelper.createRoundedCornerBitMask(radius, bitmask, isRtL);
-        mClipPath.addRoundRect(new RectF(0, 0, width, height), radii, Path.Direction.CW);
-    }
-
-    /** Clips the path that was created in onSizeChanged(). */
-    @Override
-    public void dispatchDraw(Canvas canvas) {
-        if (mClipPath != null) {
-            canvas.clipPath(mClipPath);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/GradientDrawable.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/GradientDrawable.java
deleted file mode 100644
index c9d4cef4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/GradientDrawable.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.ui;
-
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.RectShape;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.components.feed.core.proto.ui.piet.GradientsProto.LinearGradient;
-
-/** Class to display gradients according to the Piet spec (angle + color stops at %ages) */
-public class GradientDrawable extends ShapeDrawable {
-    // Doesn't like the call to setShape and setShaderFactory
-    @SuppressWarnings("nullness")
-    public GradientDrawable(LinearGradient gradient, Supplier<Boolean> rtlSupplier) {
-        super();
-
-        int[] colors = new int[gradient.getStopsCount()];
-        float[] stops = new float[gradient.getStopsCount()];
-        for (int i = 0; i < gradient.getStopsCount(); i++) {
-            colors[i] = gradient.getStops(i).getColor();
-            stops[i] = gradient.getStops(i).getPositionPercent() / 100.0f;
-        }
-        setShape(new RectShape());
-        setShaderFactory(new GradientShader(colors, stops, gradient.getDirectionDeg(),
-                gradient.getReverseForRtl() ? rtlSupplier : null));
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/GradientShader.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/GradientShader.java
deleted file mode 100644
index 145d7e6..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/GradientShader.java
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.ui;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import android.graphics.RectF;
-import android.graphics.Shader;
-import android.graphics.Shader.TileMode;
-import android.graphics.drawable.ShapeDrawable;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.supplier.Supplier;
-
-/** Generates a linear gradient according to CSS behavior */
-class GradientShader extends ShapeDrawable.ShaderFactory {
-    private final int[] mColors;
-    private final float[] mStops;
-    @VisibleForTesting
-    final double mAngleRadians;
-    @VisibleForTesting
-    final double mAngleRadiansSmall;
-    @VisibleForTesting
-    @Nullable
-    final Supplier<Boolean> mRtLSupplier;
-
-    GradientShader(
-            int[] colors, float[] stops, int angle, @Nullable Supplier<Boolean> rtLSupplier) {
-        checkState(colors.length == stops.length, "Mismatch: got %s colors and %s stops",
-                colors.length, stops.length);
-        this.mColors = colors;
-        this.mStops = stops;
-        this.mAngleRadians = Math.toRadians(angle % 360);
-        this.mAngleRadiansSmall = Math.toRadians(angle % 90);
-        this.mRtLSupplier = rtLSupplier;
-    }
-
-    @Override
-    public Shader resize(int width, int height) {
-        RectF line =
-                calculateGradientLine(width, height, mAngleRadians, mAngleRadiansSmall, isRtL());
-
-        return new android.graphics.LinearGradient(
-                line.left, line.top, line.right, line.bottom, mColors, mStops, TileMode.CLAMP);
-    }
-
-    private boolean isRtL() {
-        return mRtLSupplier != null && mRtLSupplier.get();
-    }
-
-    /** Returns a RectF as a shorthand for two points - start coords and end coords */
-    @VisibleForTesting
-    static RectF calculateGradientLine(
-            int width, int height, double angleRadians, double angleRadiansSmall, boolean isRtL) {
-        // See documentation on how CSS gradients work at:
-        // https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient
-
-        // This is Math. It's kind of like Magic.
-        // You put numbers in, and the right gradients come out.
-        // Note that on Android, the Y axis starts at the top and increases to the bottom, so some
-        // of the math is backward.
-        double length = Math.hypot(width / 2.0d, height / 2.0d)
-                * Math.cos((Math.PI / 2) - Math.atan2(height, width) - angleRadiansSmall);
-        float rtLmultiplier = isRtL ? -1 : 1;
-        float startX = (float) ((width / 2.0f) - length * rtLmultiplier * Math.sin(angleRadians));
-        float endX = (float) ((width / 2.0f) + length * rtLmultiplier * Math.sin(angleRadians));
-        float startY = (float) ((height / 2.0f) + length * Math.cos(angleRadians));
-        float endY = (float) ((height / 2.0f) - length * Math.cos(angleRadians));
-
-        return new RectF(startX, startY, endX, endY);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/GridRowView.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/GridRowView.java
deleted file mode 100644
index 7af9b7e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/GridRowView.java
+++ /dev/null
@@ -1,523 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.ui;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-
-import androidx.annotation.VisibleForTesting;
-import androidx.core.view.MarginLayoutParamsCompat;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-/** LinearLayout with special measuring code for GridRow */
-public class GridRowView extends LinearLayout {
-    private static final String TAG = "GridRowView";
-    private final Supplier<Boolean> mIsRtlSupplier;
-
-    // Total width of the GridRowView's internal padding, child widths, and child margins.
-    // This will not equal getMeasuredWidth() when the GridRowView is MATCH_PARENT width and the
-    // parent is wider than the space required by the GridRowView.
-    // This is the analogue of LinearLayout.mTotalLength
-    @VisibleForTesting
-    int mTotalContentWidth;
-
-    // Copied from LinearLayout.
-    private int mViewGravity = Gravity.START | Gravity.TOP;
-
-    // TODO: call to setOrientation(int) not allowed on the given receiver.
-    @SuppressWarnings("nullness:method.invocation.invalid")
-    public GridRowView(Context context, Supplier<Boolean> isRtlSupplier) {
-        super(context);
-        this.mIsRtlSupplier = isRtlSupplier;
-        super.setOrientation(HORIZONTAL);
-    }
-
-    @Override
-    public void setOrientation(int orientation) {
-        if (orientation != HORIZONTAL) {
-            throw new IllegalArgumentException("GridRowView can only be horizontal");
-        }
-    }
-
-    @Override
-    protected LayoutParams generateDefaultLayoutParams() {
-        return new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1.0f, false);
-    }
-
-    @Override
-    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
-        if (lp instanceof LayoutParams) {
-            return new LayoutParams((LayoutParams) lp);
-        } else if (lp instanceof LinearLayout.LayoutParams) {
-            return new LayoutParams((LinearLayout.LayoutParams) lp);
-        }
-        return new LayoutParams(lp);
-    }
-
-    @Override
-    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
-        return p instanceof LayoutParams;
-    }
-
-    @Override
-    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.UNSPECIFIED
-                || MeasureSpec.getSize(widthMeasureSpec) == 0) {
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-            return;
-        }
-
-        // Here's how much space we actually have; the GridRowView will fill it.
-        // (This will not be 0/UNSPECIFIED because that is handled above)
-        int maxWidth = MeasureSpec.getSize(widthMeasureSpec);
-
-        int gridRowVerticalPadding = getPaddingTop() + getPaddingBottom();
-        int gridRowHorizontalPadding = getPaddingLeft() + getPaddingRight();
-
-        // Max height for child cells; either AT_MOST or UNSPECIFIED
-        int maxHeightSpec;
-        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
-        if (heightMode == MeasureSpec.UNSPECIFIED) {
-            maxHeightSpec = heightMeasureSpec;
-        } else {
-            maxHeightSpec = MeasureSpec.makeMeasureSpec(
-                    heightSize - gridRowVerticalPadding, MeasureSpec.AT_MOST);
-        }
-
-        int unlimitedSpace = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-
-        // See how much space the fixed-size (WRAP_CONTENT and width) cells take.
-        // Ask how much space they would fill if there were no constraints.
-        // Also add up the total weight for distribution among the weight cells later.
-        int totalReservedWidth = 0;
-        float totalWeight = 0;
-        for (int i = 0; i < getChildCount(); i++) {
-            View view = getChildAt(i);
-            if (view.getVisibility() == View.GONE) {
-                continue;
-            }
-            LayoutParams params = ((LayoutParams) view.getLayoutParams());
-            if (params.weight == 0
-                    && (params.width > 0 || params.width == LayoutParams.WRAP_CONTENT)
-                    && !params.mIsCollapsible) {
-                if (params.width == LayoutParams.WRAP_CONTENT) {
-                    view.measure(unlimitedSpace, getMaxHeightSpecForView(params, maxHeightSpec));
-                } else {
-                    view.measure(MeasureSpec.makeMeasureSpec(params.width, MeasureSpec.EXACTLY),
-                            getMaxHeightSpecForView(params, maxHeightSpec));
-                }
-                totalReservedWidth += view.getMeasuredWidth();
-            } else if (params.weight > 0) {
-                totalWeight += params.weight;
-            }
-            totalReservedWidth += MarginLayoutParamsCompat.getMarginStart(params)
-                    + MarginLayoutParamsCompat.getMarginEnd(params);
-        }
-        totalReservedWidth += gridRowHorizontalPadding;
-
-        // Calculate width remaining to the collapsible cell(s)
-        int availableWidth = Math.max(maxWidth - totalReservedWidth, 0);
-
-        // Find collapsible cells and assign them the available width.
-        // The first cell will get as much width as it needs (or as much as is available), and
-        // future cells will get whatever's left.
-        for (int i = 0; i < getChildCount(); i++) {
-            View view = getChildAt(i);
-            if (view.getVisibility() == View.GONE) {
-                continue;
-            }
-
-            LayoutParams params = ((LayoutParams) view.getLayoutParams());
-            if (!params.mIsCollapsible) {
-                continue;
-            }
-            int viewMaxHeight = getMaxHeightSpecForView(params, maxHeightSpec);
-            // TODO: Handle margins on collapsible cells
-            int desiredWidth;
-            if (availableWidth == 0) {
-                // Shortcut for when we run out of room.
-                desiredWidth = 0;
-            } else if (params.width == LayoutParams.WRAP_CONTENT) {
-                view.measure(unlimitedSpace, viewMaxHeight);
-                desiredWidth = view.getMeasuredWidth();
-            } else {
-                desiredWidth = params.width;
-            }
-            view.measure(MeasureSpec.makeMeasureSpec(
-                                 Math.min(availableWidth, desiredWidth), MeasureSpec.EXACTLY),
-                    viewMaxHeight);
-
-            totalReservedWidth += view.getMeasuredWidth();
-            availableWidth = Math.max(0, availableWidth - view.getMeasuredWidth());
-        }
-
-        // Distribute remaining width among the weight cells.
-        if (totalWeight > 0) {
-            for (int i = 0; i < getChildCount(); i++) {
-                View view = getChildAt(i);
-                if (view.getVisibility() == View.GONE) {
-                    continue;
-                }
-                LayoutParams params = ((LayoutParams) view.getLayoutParams());
-                if (params.weight > 0) {
-                    view.measure(MeasureSpec.makeMeasureSpec(
-                                         (int) (availableWidth * params.weight / totalWeight),
-                                         MeasureSpec.EXACTLY),
-                            getMaxHeightSpecForView(params, maxHeightSpec));
-                }
-            }
-        }
-
-        // Truncate remaining cells if we ran out of room.
-        availableWidth = maxWidth - gridRowHorizontalPadding;
-        for (int i = 0; i < getChildCount(); i++) {
-            View view = getChildAt(i);
-            if (view.getVisibility() == View.GONE) {
-                continue;
-            }
-            LayoutParams params = ((LayoutParams) view.getLayoutParams());
-            availableWidth -= MarginLayoutParamsCompat.getMarginStart(params);
-            if (view.getMeasuredWidth() > availableWidth) {
-                view.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY),
-                        maxHeightSpec);
-            }
-            availableWidth = Math.max(0,
-                    availableWidth - view.getMeasuredWidth()
-                            - MarginLayoutParamsCompat.getMarginEnd(params));
-        }
-
-        // Set height of the GridRowView based on the max cell height
-        // Divided by 2 so we can create a MeasureSpec out of it (needs some free bits).
-        int rowHeight = Integer.MAX_VALUE / 2;
-        if (heightMode == MeasureSpec.EXACTLY) {
-            rowHeight = heightSize;
-        } else {
-            if (heightMode == MeasureSpec.AT_MOST) {
-                rowHeight = MeasureSpec.getSize(heightMeasureSpec);
-            }
-            int maxCellHeight = 0;
-            for (int i = 0; i < getChildCount(); i++) {
-                View view = getChildAt(i);
-                if (view.getVisibility() == View.GONE) {
-                    continue;
-                }
-                LayoutParams params = ((LayoutParams) view.getLayoutParams());
-                int cellHeight = view.getMeasuredHeight() + params.topMargin + params.bottomMargin;
-                maxCellHeight = Math.max(cellHeight, maxCellHeight);
-            }
-            // We should not need to resize the cells because they were all already smaller than
-            // this.
-            rowHeight = Math.min(rowHeight,
-                    Math.max(maxCellHeight + gridRowVerticalPadding, getMinimumHeight()));
-        }
-
-        // Resize any cells that are MATCH_PARENT or have a min height on them.
-        for (int i = 0; i < getChildCount(); i++) {
-            View view = getChildAt(i);
-            if (view.getVisibility() == View.GONE) {
-                continue;
-            }
-            LayoutParams params = ((LayoutParams) view.getLayoutParams());
-            if (params.height == LayoutParams.MATCH_PARENT) {
-                view.measure(
-                        MeasureSpec.makeMeasureSpec(view.getMeasuredWidth(), MeasureSpec.EXACTLY),
-                        MeasureSpec.makeMeasureSpec(rowHeight, MeasureSpec.EXACTLY));
-            } else if (params.height == LayoutParams.WRAP_CONTENT
-                    && view.getMinimumHeight() > view.getMeasuredHeight()
-                    && view.getMinimumHeight() < rowHeight) {
-                view.measure(
-                        MeasureSpec.makeMeasureSpec(view.getMeasuredWidth(), MeasureSpec.EXACTLY),
-                        MeasureSpec.makeMeasureSpec(view.getMinimumHeight(), MeasureSpec.EXACTLY));
-            }
-        }
-
-        // Handle WRAP_CONTENT on the GridRowView - width of the row is the sum of the cell widths.
-        // This does not make sense when there are weight cells, since they take up all available
-        // space.
-        if (getLayoutParams() != null && getLayoutParams().width == LayoutParams.WRAP_CONTENT
-                && totalWeight == 0) {
-            maxWidth = Math.min(maxWidth, totalReservedWidth);
-        }
-
-        // Calculate totalContentWidth
-        mTotalContentWidth = gridRowHorizontalPadding;
-        for (int i = 0; i < getChildCount(); i++) {
-            View view = getChildAt(i);
-            if (view.getVisibility() == View.GONE) {
-                continue;
-            }
-            mTotalContentWidth += view.getMeasuredWidth();
-            LayoutParams params = ((LayoutParams) view.getLayoutParams());
-            mTotalContentWidth += MarginLayoutParamsCompat.getMarginStart(params)
-                    + MarginLayoutParamsCompat.getMarginEnd(params);
-        }
-
-        setMeasuredDimension(maxWidth, rowHeight);
-    }
-
-    /**
-     * Find either the height specified by LayoutParams, or the height constrained by the parent.
-     */
-    private int getMaxHeightSpecForView(LayoutParams viewLayoutParams, int parentMaxHeightSpec) {
-        int marginHeight = viewLayoutParams.topMargin + viewLayoutParams.bottomMargin;
-        if (MeasureSpec.getMode(parentMaxHeightSpec) != MeasureSpec.UNSPECIFIED) {
-            int maxHeight = Math.max(0, MeasureSpec.getSize(parentMaxHeightSpec) - marginHeight);
-            parentMaxHeightSpec = MeasureSpec.makeMeasureSpec(
-                    maxHeight, MeasureSpec.getMode(parentMaxHeightSpec));
-        }
-        if (viewLayoutParams.height > 0) {
-            if (MeasureSpec.getMode(parentMaxHeightSpec) == MeasureSpec.UNSPECIFIED
-                    || MeasureSpec.getSize(parentMaxHeightSpec)
-                            > (viewLayoutParams.height + marginHeight)) {
-                return MeasureSpec.makeMeasureSpec(viewLayoutParams.height, MeasureSpec.EXACTLY);
-            }
-            return parentMaxHeightSpec;
-        } else {
-            return parentMaxHeightSpec;
-        }
-    }
-
-    // (Copied from LinearLayout.java API 27, removed references to private members, and simplified
-    // slightly (ex. remove divider width))
-    // THIS METHOD IS UNTESTED: PROCEED WITH CAUTION!
-    @Override
-    @SuppressLint("RtlHardcoded")
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        final boolean isLayoutRtl = mIsRtlSupplier.get();
-        final int paddingTop = getPaddingTop();
-
-        int childTop;
-        int childLeft;
-
-        // Where bottom of child should go
-        final int height = bottom - top;
-        int childBottom = height - getPaddingBottom();
-
-        // Space available for child
-        int childSpace = height - paddingTop - getPaddingBottom();
-
-        final int count = getChildCount();
-
-        final int majorGravity = getGravity() & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
-        final int minorGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
-
-        final int layoutDirection = getLayoutDirection();
-        switch (Gravity.getAbsoluteGravity(majorGravity, layoutDirection)) {
-            case Gravity.RIGHT:
-                // totalContentWidth contains the padding already
-                childLeft = getPaddingLeft() + right - left - mTotalContentWidth;
-                break;
-
-            case Gravity.CENTER_HORIZONTAL:
-                // totalContentWidth contains the padding already
-                childLeft = getPaddingLeft() + (right - left - mTotalContentWidth) / 2;
-                break;
-
-            case Gravity.LEFT:
-            default:
-                childLeft = getPaddingLeft();
-                break;
-        }
-
-        int start = 0;
-        int dir = 1;
-
-        // In case of RTL, start drawing from the last child.
-        if (isLayoutRtl) {
-            start = count - 1;
-            dir = -1;
-        }
-
-        for (int i = 0; i < count; i++) {
-            final int childIndex = start + dir * i;
-            final View child = getChildAt(childIndex);
-            if (child.getVisibility() != GONE) {
-                final int childWidth = child.getMeasuredWidth();
-                final int childHeight = child.getMeasuredHeight();
-
-                final LinearLayout.LayoutParams lp =
-                        (LinearLayout.LayoutParams) child.getLayoutParams();
-
-                int gravity = lp.gravity;
-                if (gravity < 0) {
-                    gravity = minorGravity;
-                }
-
-                switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
-                    case Gravity.TOP:
-                        childTop = paddingTop + lp.topMargin;
-                        break;
-
-                    case Gravity.CENTER_VERTICAL:
-                        childTop = paddingTop + ((childSpace - childHeight) / 2) + lp.topMargin
-                                - lp.bottomMargin;
-                        break;
-
-                    case Gravity.BOTTOM:
-                        childTop = childBottom - childHeight - lp.bottomMargin;
-                        break;
-                    default:
-                        childTop = paddingTop;
-                        break;
-                }
-
-                childLeft += lp.leftMargin;
-                setChildFrame(child, childLeft, childTop, childWidth, childHeight);
-                childLeft += childWidth + lp.rightMargin;
-            }
-        }
-    }
-
-    // (Copied from LinearLayout.java API 27)
-    private void setChildFrame(View child, int left, int top, int width, int height) {
-        child.layout(left, top, left + width, top + height);
-    }
-
-    /**
-     * (Copied from LinearLayout.java API 27) Describes how the child views are positioned. Defaults
-     * to GRAVITY_TOP. If this layout has a HORIZONTAL orientation, this controls the alignment of
-     * the children.
-     *
-     * @param gravity See {@link android.view.Gravity}
-     * @attr ref android.R.styleable#LinearLayout_gravity
-     */
-    @Override
-    public void setGravity(int gravity) {
-        if (mViewGravity != gravity) {
-            if ((gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
-                gravity |= Gravity.START;
-            }
-
-            if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
-                gravity |= Gravity.TOP;
-            }
-
-            mViewGravity = gravity;
-            requestLayout();
-        }
-    }
-
-    /**
-     * (Copied from LinearLayout.java API 27) Returns the current gravity. See {@link
-     * android.view.Gravity}
-     *
-     * @return the current gravity.
-     * @see #setGravity
-     */
-    @Override
-    public int getGravity() {
-        return mViewGravity;
-    }
-
-    // (Copied from LinearLayout.java API 27)
-    @Override
-    public void setHorizontalGravity(int horizontalGravity) {
-        final int gravity = horizontalGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
-        if ((mViewGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) != gravity) {
-            mViewGravity = (mViewGravity & ~Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) | gravity;
-            requestLayout();
-        }
-    }
-
-    // (Copied from LinearLayout.java API 27)
-    @Override
-    public void setVerticalGravity(int verticalGravity) {
-        final int gravity = verticalGravity & Gravity.VERTICAL_GRAVITY_MASK;
-        if ((mViewGravity & Gravity.VERTICAL_GRAVITY_MASK) != gravity) {
-            mViewGravity = (mViewGravity & ~Gravity.VERTICAL_GRAVITY_MASK) | gravity;
-            requestLayout();
-        }
-    }
-
-    @VisibleForTesting
-    public boolean hasCollapsibleCells() {
-        for (int i = 0; i < getChildCount(); i++) {
-            View view = getChildAt(i);
-            if (((LayoutParams) view.getLayoutParams()).mIsCollapsible) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * LayoutParams for GridRowViews. Essentially just LinearLayout.LayoutParams with a boolean to
-     * keep track of whether this cell isCollapsible. Collapsible cells behave as WRAP_CONTENT when
-     * they have sufficient room, but shrink when there is not enough room for them. Collapsible
-     * cells take priority over weight cells; a weight cell will shrink to zero before the
-     * collapsible cell starts to shrink.
-     */
-    public static class LayoutParams extends LinearLayout.LayoutParams {
-        private final boolean mIsCollapsible;
-
-        public LayoutParams(LayoutParams source) {
-            super(source);
-            mIsCollapsible = source.getIsCollapsible();
-        }
-
-        public LayoutParams(int width, int height, boolean isCollapsible) {
-            this(width, height, 0.0f, isCollapsible);
-        }
-
-        /**
-         * If a cell is collapsible, it doesn't make sense for it to also have weight (since all
-         * weight cells are by definition collapsible, and have no intrinsic width).
-         */
-        public LayoutParams(int width, int height, float weight, boolean isCollapsible) {
-            super(width, height, weight);
-            if (isCollapsible && weight > 0) {
-                isCollapsible = false;
-            }
-            if (width == MATCH_PARENT) {
-                Logger.wtf(TAG, "GridRowView cells cannot have width MATCH_PARENT.");
-            }
-            this.mIsCollapsible = isCollapsible;
-        }
-
-        public LayoutParams(Context c, AttributeSet attrs) {
-            super(c, attrs);
-            mIsCollapsible = false;
-        }
-
-        public LayoutParams(int width, int height) {
-            super(width, height);
-            mIsCollapsible = false;
-        }
-
-        public LayoutParams(int width, int height, float weight) {
-            super(width, height, weight);
-            mIsCollapsible = false;
-        }
-
-        public LayoutParams(ViewGroup.LayoutParams p) {
-            super(p);
-            mIsCollapsible = false;
-        }
-
-        public LayoutParams(MarginLayoutParams source) {
-            super(source);
-            mIsCollapsible = false;
-        }
-
-        public LayoutParams(LinearLayout.LayoutParams source) {
-            super((MarginLayoutParams) source);
-            weight = source.weight;
-            gravity = source.gravity;
-            mIsCollapsible = false;
-        }
-
-        public boolean getIsCollapsible() {
-            return mIsCollapsible;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/OutlineProviderRoundedCornerDelegate.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/OutlineProviderRoundedCornerDelegate.java
deleted file mode 100644
index 794d4c1..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/OutlineProviderRoundedCornerDelegate.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.ui;
-
-import android.annotation.TargetApi;
-import android.os.Build;
-import android.view.ViewGroup;
-
-/**
- * Rounding delegate for the outline provider strategy.
- *
- * <p>Adds logic to clip rounded corner views to their outline. {@link RoundedCornerWrapperView}
- * decides which rounding strategy to use and sets the appropriate delegate.
- */
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
-class OutlineProviderRoundedCornerDelegate extends RoundedCornerDelegate {
-    /**
-     * Sets clipToOutline to true.
-     *
-     * <p>Setting it in an initializer rather than a constructor means a new instance of this
-     * delegate doesn't need to be created every time an outline provider is needed.
-     */
-    @Override
-    public void initializeForView(ViewGroup view) {
-        view.setClipToOutline(true);
-        view.setClipChildren(true);
-    }
-
-    /** Reset clipToOutline to false (the default) when this strategy stops being used. */
-    @Override
-    public void destroy(ViewGroup view) {
-        view.setClipToOutline(false);
-        view.setClipChildren(false);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerDelegate.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerDelegate.java
deleted file mode 100644
index a4fa1e2..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerDelegate.java
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.ui;
-
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-
-/**
- * Abstract delegate that allows its children to add logic to round the corners of a {@link View}.
- *
- * <p>This class is abstract as it is not meant to be directly instantiated. Multiple delegates with
- * different rounding strategies subclass this delegate. Each delegate can add logic to different
- * {@link View} lifecycle methods, as well as initialize and destroy logic. Since {@link
- * RoundedCornerWrapperView} actually inherits from {@link View}, it takes care of calling the super
- * methods of these lifecycle events, in addition to calling these delegate methods.
- *
- * <p>Since not all rounding strategies need to override all of these methods, and {@link
- * RoundedCornerWrapperView} calls the default 'super' implementation, they are left as empty
- * methods by default. Having empty methods here simplifies the logic in {@link
- * RoundedCornerWrapperView}, because that view doesn't need to know which strategies require extra
- * logic in specific methods.
- */
-abstract class RoundedCornerDelegate {
-    /**
-     * Initializes anything that needs to be changed on the view that is being rounded.
-     *
-     * <p>This should be the opposite of what is torn down in destroy().
-     */
-    void initializeForView(ViewGroup view) {}
-
-    /** Allows a rounded corner delegate to add logic when child views are drawn. */
-    void dispatchDraw(Canvas canvas) {}
-
-    /** Allows a rounded corner delegate to add logic during layout. */
-    void onLayout(int radius, boolean isRtL, int width, int height) {}
-
-    /**
-     * Allows a rounded corner delegate to add logic during {@link
-     * ViewParent#onDescendantInvalidated}.
-     */
-    void onDescendantInvalidated(View roundedCornerView, View invalidatedDescendant) {}
-
-    /**
-     * Allows a rounded corner delegate to add logic during {@link
-     * ViewParent#invalidateChildInParent}.
-     */
-    void invalidateChildInParent(View view, final Rect dirty) {}
-
-    /** Allows a rounded corner delegate to add logic when the size changes. */
-    void onSizeChanged(int radius, int width, int height, int bitmask, boolean isRtL) {}
-
-    /**
-     * Renders the view to this canvas.
-     *
-     * <p>The default call to the super method is here, rather than in {@link
-     * RoundedCornerWrapperView}, because an implementation may override this and set a bitmap
-     * directly to the canvas.
-     *
-     * <p>If this is overridden, view.drawSuper() must be called, even if it is with a different
-     * {@link Canvas}.
-     */
-    void draw(RoundedCornerWrapperView view, Canvas canvas) {
-        view.drawSuper(canvas);
-    }
-
-    /**
-     * Removes any modifications the delegate has made to the view that is being rounded.
-     *
-     * <p>This should be called on the current {@link RoundedCornerDelegate} when switching from one
-     * delegate to another.
-     */
-    void destroy(ViewGroup view) {}
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerDelegateFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerDelegateFactory.java
deleted file mode 100644
index aff0c87..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerDelegateFactory.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.ui;
-
-/**
- * Factory of {@link RoundedCornerDelegate}.
- *
- * <p>This factory creates the delegate that corresponds with the {@link RoundingStrategy} that is
- * passed in.
- */
-class RoundedCornerDelegateFactory {
-    // The outline provider delegate has no state, so optimize by making a single static instance.
-    private static final OutlineProviderRoundedCornerDelegate OUTLINE_DELEGATE =
-            new OutlineProviderRoundedCornerDelegate();
-
-    /** Strategies that correspond with different {@link RoundedCornerDelegate}s. */
-    enum RoundingStrategy { UNKNOWN, CLIP_PATH, OUTLINE_PROVIDER, BITMAP_MASKING }
-
-    static RoundedCornerDelegate getDelegate(RoundingStrategy strategy,
-            RoundedCornerMaskCache maskCache, int bitmask, boolean isRtL) {
-        // This switch omits the default statement to force a compile failure if a new strategy is
-        // added but not handled.
-        switch (strategy) {
-            case CLIP_PATH:
-                return new ClipPathRoundedCornerDelegate();
-            case OUTLINE_PROVIDER:
-                return OUTLINE_DELEGATE;
-            case BITMAP_MASKING:
-                return new BitmapMaskingRoundedCornerDelegate(maskCache, bitmask, isRtL);
-            case UNKNOWN:
-                // This should never happen, but if it does, bitmap masking works for everything.
-                return new BitmapMaskingRoundedCornerDelegate(maskCache, bitmask, isRtL);
-        }
-        throw new AssertionError(String.format(
-                "RoundedCornerDelegateFactory doesn't handle %s rounding strategy", strategy));
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerMaskCache.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerMaskCache.java
deleted file mode 100644
index 0598bf5..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerMaskCache.java
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.ui;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffXfermode;
-import android.util.LruCache;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.VisibleForTesting;
-
-/** Caches rounded corner masks to save memory and time spent creating them */
-public class RoundedCornerMaskCache {
-    // TODO: Make cache size configurable.
-    private static final int CACHE_SIZE = 8;
-
-    @IntDef({Corner.TOP_LEFT, Corner.TOP_RIGHT, Corner.BOTTOM_LEFT, Corner.BOTTOM_RIGHT})
-    @interface Corner {
-        int TOP_LEFT = 0;
-        int TOP_RIGHT = 1;
-        int BOTTOM_LEFT = 2;
-        int BOTTOM_RIGHT = 3;
-    }
-
-    private final Canvas mCanvas;
-    private final Paint mPaint;
-    private final Paint mMaskPaint;
-    private final LruCache<Integer, RoundedCornerBitmaps> mCache;
-
-    public RoundedCornerMaskCache() {
-        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        mMaskPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-        mMaskPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
-
-        mCanvas = new Canvas();
-        mCache = new LruCache<Integer, RoundedCornerBitmaps>(CACHE_SIZE) {
-            @Override
-            protected RoundedCornerBitmaps create(Integer key) {
-                return new RoundedCornerBitmaps(key, mCanvas, mMaskPaint);
-            }
-        };
-    }
-
-    Paint getPaint() {
-        return mPaint;
-    }
-
-    Paint getMaskPaint() {
-        return mMaskPaint;
-    }
-
-    RoundedCornerBitmaps getMasks(int radius) {
-        RoundedCornerBitmaps masks = mCache.get(radius);
-        if (masks == null) {
-            masks = new RoundedCornerBitmaps(radius, mCanvas, mMaskPaint);
-            mCache.put(radius, masks);
-        }
-        return masks;
-    }
-
-    public void purge() {
-        mCache.evictAll();
-    }
-
-    static class RoundedCornerBitmaps {
-        @VisibleForTesting
-        final Bitmap[] mMasks;
-        private final Canvas mCanvas;
-        private final int mRadius;
-        private final Paint mMaskPaint;
-
-        RoundedCornerBitmaps(int radius, Canvas canvas, Paint maskPaint) {
-            mMasks = new Bitmap[4];
-            this.mCanvas = canvas;
-            this.mRadius = radius;
-            this.mMaskPaint = maskPaint;
-        }
-
-        Bitmap get(@Corner int corner) {
-            switch (corner) {
-                case Corner.TOP_LEFT:
-                    if (mMasks[Corner.TOP_LEFT] == null) {
-                        mMasks[Corner.TOP_LEFT] =
-                                Bitmap.createBitmap(mRadius, mRadius, Config.ALPHA_8);
-                        mCanvas.setBitmap(mMasks[Corner.TOP_LEFT]);
-                        mCanvas.drawColor(Color.BLACK);
-                        mCanvas.drawCircle(mRadius, mRadius, mRadius, mMaskPaint);
-                    }
-                    return mMasks[Corner.TOP_LEFT];
-
-                case Corner.TOP_RIGHT:
-                    if (mMasks[Corner.TOP_RIGHT] == null) {
-                        mMasks[Corner.TOP_RIGHT] =
-                                Bitmap.createBitmap(mRadius, mRadius, Config.ALPHA_8);
-                        mCanvas.setBitmap(mMasks[Corner.TOP_RIGHT]);
-                        mCanvas.drawColor(Color.BLACK);
-                        mCanvas.drawCircle(0, mRadius, mRadius, mMaskPaint);
-                    }
-                    return mMasks[Corner.TOP_RIGHT];
-
-                case Corner.BOTTOM_LEFT:
-                    if (mMasks[Corner.BOTTOM_LEFT] == null) {
-                        mMasks[Corner.BOTTOM_LEFT] =
-                                Bitmap.createBitmap(mRadius, mRadius, Config.ALPHA_8);
-                        mCanvas.setBitmap(mMasks[Corner.BOTTOM_LEFT]);
-                        mCanvas.drawColor(Color.BLACK);
-                        mCanvas.drawCircle(mRadius, 0, mRadius, mMaskPaint);
-                    }
-                    return mMasks[Corner.BOTTOM_LEFT];
-
-                case Corner.BOTTOM_RIGHT:
-                    if (mMasks[Corner.BOTTOM_RIGHT] == null) {
-                        mMasks[Corner.BOTTOM_RIGHT] =
-                                Bitmap.createBitmap(mRadius, mRadius, Config.ALPHA_8);
-                        mCanvas.setBitmap(mMasks[Corner.BOTTOM_RIGHT]);
-                        mCanvas.drawColor(Color.BLACK);
-                        mCanvas.drawCircle(0, 0, mRadius, mMaskPaint);
-                    }
-                    return mMasks[Corner.BOTTOM_RIGHT];
-
-                default:
-                    throw new IllegalArgumentException(
-                            String.format("Unrecognized corner: %s", corner));
-            }
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerViewHelper.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerViewHelper.java
deleted file mode 100644
index 04ae7f0..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerViewHelper.java
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.ui;
-
-import android.view.View;
-
-import org.chromium.components.feed.core.proto.ui.piet.RoundedCornersProto.RoundedCorners;
-import org.chromium.components.feed.core.proto.ui.piet.RoundedCornersProto.RoundedCorners.Corners;
-
-import java.util.Arrays;
-
-/** Helper class to help work with rounded corner views. */
-public class RoundedCornerViewHelper {
-    /**
-     * Returns a float[] representing the mask for which corners should be rounded with the radius.
-     */
-    static float[] createRoundedCornerBitMask(float radius, int cornerField, boolean isRtL) {
-        final int layoutDirection = isRtL ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;
-        return createRoundedCornerBitMask(radius, cornerField, layoutDirection);
-    }
-
-    /**
-     * Returns a float[] representing the mask for which corners should be rounded with the radius.
-     *
-     * @param layoutDirection either 0 for {@link android.view.View#LAYOUT_DIRECTION_LTR} or 1 for
-     *     {@link android.view.View#LAYOUT_DIRECTION_RTL}. If an invalid value is passed in, default
-     *     to LTR.
-     */
-    private static float[] createRoundedCornerBitMask(
-            float radius, int cornerField, int layoutDirection) {
-        float[] radii = new float[8];
-        // If we don't have any radius, don't bother creating the mask.
-        if (radius > 0) {
-            if (cornerField == Corners.CORNERS_UNSPECIFIED_VALUE) {
-                Arrays.fill(radii, 0, 8, radius);
-                return radii;
-            }
-
-            if (layoutDirection == View.LAYOUT_DIRECTION_RTL) {
-                if ((cornerField & Corners.TOP_START_VALUE) != 0) {
-                    radii[2] = radius;
-                    radii[3] = radius;
-                }
-                if ((cornerField & Corners.TOP_END_VALUE) != 0) {
-                    radii[0] = radius;
-                    radii[1] = radius;
-                }
-                if ((cornerField & Corners.BOTTOM_END_VALUE) != 0) {
-                    radii[6] = radius;
-                    radii[7] = radius;
-                }
-                if ((cornerField & Corners.BOTTOM_START_VALUE) != 0) {
-                    radii[4] = radius;
-                    radii[5] = radius;
-                }
-            } else {
-                if ((cornerField & Corners.TOP_START_VALUE) != 0) {
-                    radii[0] = radius;
-                    radii[1] = radius;
-                }
-                if ((cornerField & Corners.TOP_END_VALUE) != 0) {
-                    radii[2] = radius;
-                    radii[3] = radius;
-                }
-                if ((cornerField & Corners.BOTTOM_END_VALUE) != 0) {
-                    radii[4] = radius;
-                    radii[5] = radius;
-                }
-                if ((cornerField & Corners.BOTTOM_START_VALUE) != 0) {
-                    radii[6] = radius;
-                    radii[7] = radius;
-                }
-            }
-        }
-
-        return radii;
-    }
-
-    /**
-     * Evaluates whether the rounded corners are valid--meaning one of the radius values is set, and
-     * is greater than zero.
-     */
-    public static boolean hasValidRoundedCorners(
-            RoundedCorners roundedCorners, int radiusOverride) {
-        return ((roundedCorners.hasRadiusPercentageOfWidth()
-                        && (roundedCorners.getRadiusPercentageOfWidth() > 0))
-                || (roundedCorners.hasRadiusPercentageOfHeight()
-                        && (roundedCorners.getRadiusPercentageOfHeight() > 0))
-                || (roundedCorners.hasRadiusDp() && (roundedCorners.getRadiusDp() > 0))
-                || (radiusOverride > 0));
-    }
-
-    /**
-     * Returns the radius that was passed in, or a smaller radius if necessary.
-     *
-     * <p>If the current radius is bigger than the width or height, or if it has adjacent rounded
-     * corners and the radius is more than half of the width or height, the radius is made smaller.
-     * It shrinks on all sides, even if only one corner needs to shrink--Piet does not allow
-     * different corners to have different radii.
-     */
-    static int adjustRadiusIfTooBig(
-            int width, int height, int currentRadius, RoundedCorners roundedCorners) {
-        int smallerSide = Math.min(height, width);
-        currentRadius = Math.min(currentRadius, smallerSide);
-
-        // This is expected to be by far the most common case, so check this first and return fast.
-        if (allFourCornersRounded(roundedCorners.getBitmask())) {
-            return Math.min(currentRadius, smallerSide / 2);
-        }
-
-        // If not all corners are rounded, it may not be necessary to truncate to half the smaller
-        // side. If there are only horizontally-adjacent or only vertically-adjacent corners,
-        // truncate the radius to half of that side of the view. Both need to be checked in case
-        // there are 3 corners rounded, which ends up being equivalent to truncating to half the
-        // smaller side.
-        if (hasVerticallyAdjacentRoundedCorners(roundedCorners.getBitmask())) {
-            currentRadius = Math.min(currentRadius, height / 2);
-        }
-        if (hasHorizontallyAdjacentRoundedCorners(roundedCorners.getBitmask())) {
-            currentRadius = Math.min(currentRadius, width / 2);
-        }
-        return currentRadius;
-    }
-
-    static boolean allFourCornersRounded(int bitmask) {
-        return bitmask == 0 || bitmask == 15;
-    }
-
-    private static boolean hasVerticallyAdjacentRoundedCorners(int bitmask) {
-        return (shouldRoundCorner(Corners.TOP_START, bitmask)
-                       && shouldRoundCorner(Corners.BOTTOM_START, bitmask))
-                || (shouldRoundCorner(Corners.TOP_END, bitmask)
-                        && shouldRoundCorner(Corners.BOTTOM_END, bitmask));
-    }
-
-    private static boolean hasHorizontallyAdjacentRoundedCorners(int bitmask) {
-        return (shouldRoundCorner(Corners.TOP_START, bitmask)
-                       && shouldRoundCorner(Corners.TOP_END, bitmask))
-                || (shouldRoundCorner(Corners.BOTTOM_START, bitmask)
-                        && shouldRoundCorner(Corners.BOTTOM_END, bitmask));
-    }
-
-    /**
-     * Returns whether the corner should be rounded, based on the bitmask.
-     *
-     * <p>A bitmask of 0 implies that all corners should be rounded. The binary bitmask digits
-     * correspond to the {@link Corners} value.
-     */
-    static boolean shouldRoundCorner(Corners corner, int bitmask) {
-        return (bitmask == 0) || (bitmask & corner.getNumber()) != 0;
-    }
-
-    // Prevent instantiation
-    private RoundedCornerViewHelper() {}
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerWrapperView.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerWrapperView.java
deleted file mode 100644
index 69048fe21..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerWrapperView.java
+++ /dev/null
@@ -1,325 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.piet.ui;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Outline;
-import android.graphics.Rect;
-import android.graphics.drawable.shapes.RoundRectShape;
-import android.view.View;
-import android.view.ViewOutlineProvider;
-import android.view.ViewParent;
-import android.widget.FrameLayout;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.feed.library.common.ui.LayoutUtils;
-import org.chromium.chrome.browser.feed.library.piet.ui.RoundedCornerDelegateFactory.RoundingStrategy;
-import org.chromium.components.feed.core.proto.ui.piet.RoundedCornersProto.RoundedCorners;
-import org.chromium.components.feed.core.proto.ui.piet.RoundedCornersProto.RoundedCorners.RadiusOptionsCase;
-import org.chromium.components.feed.core.proto.ui.piet.StylesProto.Borders;
-
-/**
- * Wrapper for {@link View} instances in Piet that require rounded corners.
- *
- * <p>There are three strategies used to round corners in different situations. This class decides
- * which to use based on the following rules:
- *
- * <p>OUTLINE_PROVIDER: This is always used when possible (unless disallowed by the host). It
- * requires hardware acceleration, does not work if 1-3 corners are rounded, and does not work on
- * K-.
- *
- * <p>CLIP_PATH: This works in all situations, but does not support anti-aliasing. Used when the
- * device does not support hardware acceleration, and in K- where outline provider is not supported.
- * Although BITMAP_MASKING would work for those cases, this strategy is much more performant. Older
- * SDKs or no hw acceleration support typically are signs of less-performant phones. The lack of
- * anti-aliasing does not negatively effect metrics for these users. This strategy can be disallowed
- * by the host, in which case BITMAP_MASKING will be used where OUTLINE_PROVIDER is not possible.
- *
- * <p>BITMAP_MASKING: This implementation should work in all cases for all SDKs, but has the worst
- * performance in CPU and memory usage. It is only used when 1-3 corners are rounded in L+, or if
- * the other strategies are disallowed by the host or not possible.
- *
- * <p>A {@link RoundedCornerDelegate} is called in places where special logic is needed for
- * different rounding strategies. Each strategy has its own delegate, which is created when the
- * strategy is selected. This class doesn't know about the implementation details of the rounding
- * strategies.
- */
-public class RoundedCornerWrapperView extends FrameLayout {
-    private final int mRadiusOverride;
-    private final RoundedCorners mRoundedCorners;
-    private final Supplier<Boolean> mIsRtLSupplier;
-    private final Context mContext;
-    private final Borders mBorders;
-    private final boolean mAllowClipPath;
-    private final boolean mAllowOutlineRounding;
-    private final boolean mHasRoundedCorners;
-    private final boolean mAllFourCornersRounded;
-    private final RoundedCornerMaskCache mMaskCache;
-
-    private RoundedCornerDelegate mRoundingDelegate;
-    private boolean mDrawSuperCalled;
-
-    // Keep track of current mask configuration so we can use cached values if nothing has changed.
-    int mLastWidth = -1;
-    int mLastHeight = -1;
-
-    private int mRoundedCornerRadius;
-
-    // Doesn't like the call to setOutlineProvider
-    @SuppressWarnings("nullness")
-    public RoundedCornerWrapperView(Context context, RoundedCorners roundedCorners,
-            RoundedCornerMaskCache maskCache, Supplier<Boolean> isRtLSupplier, int radiusOverride,
-            Borders borders, boolean allowClipPath, boolean allowOutlineRounding) {
-        super(context);
-
-        this.mRadiusOverride = radiusOverride;
-        this.mRoundedCorners = roundedCorners;
-        this.mIsRtLSupplier = isRtLSupplier;
-        this.mAllowClipPath = allowClipPath;
-        this.mAllowOutlineRounding = allowOutlineRounding;
-        this.mContext = context;
-        this.mBorders = borders;
-        this.mMaskCache = maskCache;
-        this.mHasRoundedCorners =
-                RoundedCornerViewHelper.hasValidRoundedCorners(roundedCorners, radiusOverride);
-        this.mAllFourCornersRounded =
-                RoundedCornerViewHelper.allFourCornersRounded(roundedCorners.getBitmask());
-
-        setRoundingStrategy();
-
-        // Even when not using the outline provider strategy, the outline needs to be set for
-        // shadows to render properly.
-        setupOutlineProvider();
-        setWillNotDraw(false);
-    }
-
-    private void setRoundingStrategy() {
-        if (mAllFourCornersRounded && mAllowOutlineRounding) {
-            setRoundingDelegate(RoundingStrategy.OUTLINE_PROVIDER);
-        } else {
-            setRoundingDelegate(RoundingStrategy.BITMAP_MASKING);
-        }
-    }
-
-    private void updateRoundingStrategy() {
-        if (mRoundingDelegate instanceof OutlineProviderRoundedCornerDelegate
-                && this.isAttachedToWindow() && !this.isHardwareAccelerated()) {
-            if (mAllowClipPath) {
-                setRoundingDelegate(RoundingStrategy.CLIP_PATH);
-            } else {
-                setRoundingDelegate(RoundingStrategy.BITMAP_MASKING);
-            }
-        }
-    }
-
-    void setRoundingDelegate(RoundingStrategy strategy) {
-        if (mRoundingDelegate != null) {
-            mRoundingDelegate.destroy(this);
-        }
-        mRoundingDelegate = RoundedCornerDelegateFactory.getDelegate(
-                strategy, mMaskCache, mRoundedCorners.getBitmask(), mIsRtLSupplier.get());
-        mRoundingDelegate.initializeForView(this);
-    }
-
-    private void setupOutlineProvider() {
-        if (mHasRoundedCorners) {
-            super.setOutlineProvider(new ViewOutlineProvider() {
-                @Override
-                public void getOutline(View view, Outline outline) {
-                    int radius = getRadius(view.getWidth(), view.getHeight());
-                    if (mAllFourCornersRounded) {
-                        outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), radius);
-                        return;
-                    }
-                    float[] radii = RoundedCornerViewHelper.createRoundedCornerBitMask(
-                            radius, mRoundedCorners.getBitmask(), mIsRtLSupplier.get());
-                    RoundRectShape outlineShape = new RoundRectShape(radii, null, null);
-                    outlineShape.resize(view.getWidth(), view.getHeight());
-                    // This actually sets the outline to use this shape
-                    outlineShape.getOutline(outline);
-                }
-            });
-        } else {
-            super.setOutlineProvider(ViewOutlineProvider.BOUNDS);
-        }
-    }
-
-    /**
-     * Calls the rounding delegate to perform any additional work specific to a certain rounding
-     * strategy during dispatchDraw().
-     */
-    @Override
-    protected void dispatchDraw(Canvas canvas) {
-        mRoundingDelegate.dispatchDraw(canvas);
-        super.dispatchDraw(canvas);
-    }
-
-    /**
-     * Allows the {@link RoundedCornerDelegate} to add logic during onDescendantInvalidated().
-     *
-     * <p>The bitmap masking rounded corner strategy requires this hook, to make sure the wrapper
-     * view is invalidated when there are animations. The delegate handles that logic.
-     */
-    @Override
-    public void onDescendantInvalidated(View child, View target) {
-        super.onDescendantInvalidated(child, target);
-        mRoundingDelegate.onDescendantInvalidated(this, target);
-    }
-
-    /**
-     * Allows the {@link RoundedCornerDelegate} to add logic during invalidateChildInParent().
-     *
-     * <p>The bitmap masking rounded corner strategy requires this hook, to make sure the wrapper
-     * view is invalidated when there are animations. The delegate handles that logic.
-     */
-    @Override
-    public ViewParent invalidateChildInParent(final int[] location, final Rect dirty) {
-        mRoundingDelegate.invalidateChildInParent(this, dirty);
-        return super.invalidateChildInParent(location, dirty);
-    }
-
-    /**
-     * Calls the {@link RoundedCornerDelegate} to draw to the {@link Canvas}, in case extra logic is
-     * needed to round the corners.
-     *
-     * <p>Draws as normal for everything except the bitmap masking strategy. The bitmap masking
-     * strategy requires manipulating the {@link Canvas}, which the delegate handles.
-     */
-    @Override
-    @SuppressWarnings("MissingSuperCall")
-    public void draw(Canvas canvas) {
-        mDrawSuperCalled = false;
-        mRoundingDelegate.draw(this, canvas);
-        checkState(mDrawSuperCalled, "View.draw() never called in RoundedCornerWrapperView.draw()");
-    }
-
-    public void drawSuper(Canvas canvas) {
-        mDrawSuperCalled = true;
-        super.draw(canvas);
-    }
-
-    /**
-     * Updates rounded corner information when the size changes.
-     *
-     * <p>At this point, the view will actually be attached to the window, meaning we can detect
-     * whether it is hardware accelerated. The outline provider strategy doesn't work without
-     * hardware acceleration, so the rounding strategy may need to be updated. The size always
-     * changes at least once--from 0 to final dimensions--so it is safe to assume that this will
-     * catch devices without hw acceleration.
-     *
-     * <p>Call the rounding delegate to perform any additional work specific to a certain rounding
-     * strategy.
-     */
-    @Override
-    protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
-        super.onSizeChanged(width, height, oldWidth, oldHeight);
-        updateRoundingStrategy();
-        mRoundingDelegate.onSizeChanged(getRadius(width, height), width, height,
-                mRoundedCorners.getBitmask(), mIsRtLSupplier.get());
-    }
-
-    /**
-     * Lays out the view, calling the rounding delegate to perform any additional work specific to a
-     * certain rounding strategy.
-     *
-     * <p>Borders must be created after the radius is known, so they are added from onLayout().
-     */
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        if (!changed || !mHasRoundedCorners) {
-            return;
-        }
-
-        int width = getWidth();
-        int height = getHeight();
-        if (width == 0 || height == 0) {
-            // The view is not visible; no further processing is needed.
-            return;
-        }
-
-        int radius = getRadius(width, height);
-        addBorders(radius);
-
-        mRoundingDelegate.onLayout(radius, mIsRtLSupplier.get(), width, height);
-    }
-
-    /**
-     * Creates a border drawable and adds it to this view's foreground.
-     *
-     * <p>This is called from {@link RoundedCornerWrapperView} because when the corners are rounded,
-     * the borders also need to be rounded, and the radius can't properly be calculated until the
-     * view has been laid out and the height and width are known. From this class, it is easy to
-     * make sure the border is created after layout happens, since we are overriding draw. Draw is
-     * guaranteed to happen after layout, so we can make sure that the borders are drawn with the
-     * appropriate measurements.
-     */
-    void addBorders(int radius) {
-        if (mBorders.getWidth() <= 0) {
-            return;
-        }
-        boolean isRtL = mIsRtLSupplier.get();
-        // Set up outline of borders
-        float[] outerRadii = RoundedCornerViewHelper.createRoundedCornerBitMask(
-                radius, mRoundedCorners.getBitmask(), isRtL);
-
-        // Create a drawable to stroke the border
-        BorderDrawable borderDrawable =
-                new BorderDrawable(mContext, mBorders, outerRadii, isRtL, mLastWidth, mLastHeight);
-        this.setForeground(borderDrawable);
-    }
-
-    /**
-     * Returns the radius, which is only calculated if necessary.
-     *
-     * <p>If the width and height are the same as the previous width and height, there's no need to
-     * re-calculate, and the previous radius is returned. The width and height are needed for radii
-     * calculated as a percentage of width or height, and to make sure that the radius isn't too big
-     * for the size of the view.
-     */
-    public int getRadius(int width, int height) {
-        if (!mHasRoundedCorners || width == 0 || height == 0) {
-            return 0;
-        }
-        if (mRadiusOverride > 0) {
-            mRoundedCornerRadius = mRadiusOverride;
-            return mRoundedCornerRadius;
-        }
-        if (width == mLastWidth && height == mLastHeight) {
-            return mRoundedCornerRadius;
-        }
-        int radius = makeRadius(width, height);
-        mLastWidth = width;
-        mLastHeight = height;
-        return radius;
-    }
-
-    /** Calculates the corner radius, clipping to width or height when necessary. */
-    private int makeRadius(int width, int height) {
-        int radius;
-        RadiusOptionsCase radiusOptions = mRoundedCorners.getRadiusOptionsCase();
-
-        switch (radiusOptions) {
-            case RADIUS_DP:
-                radius = (int) LayoutUtils.dpToPx(mRoundedCorners.getRadiusDp(), mContext);
-                break;
-            case RADIUS_PERCENTAGE_OF_HEIGHT:
-                radius = mRoundedCorners.getRadiusPercentageOfHeight() * height / 100;
-                break;
-            case RADIUS_PERCENTAGE_OF_WIDTH:
-                radius = mRoundedCorners.getRadiusPercentageOfWidth() * width / 100;
-                break;
-            default:
-                radius = 0;
-        }
-
-        mRoundedCornerRadius = RoundedCornerViewHelper.adjustRadiusIfTooBig(
-                width, height, radius, mRoundedCorners);
-        return mRoundedCornerRadius;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/constants/Constants.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/constants/Constants.java
deleted file mode 100644
index a7bf09e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/constants/Constants.java
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-package org.chromium.chrome.browser.feed.library.sharedstream.constants;
-
-/** A set of constants to be used in sharedStream */
-public final class Constants {
-    // Default minimum time for a view to be onscreen and not scrolling before it is counted as a
-    // view
-    public static final long VIEW_MIN_TIME_MS_DEFAULT = 500L;
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contentchanged/StreamContentChangedListener.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contentchanged/StreamContentChangedListener.java
deleted file mode 100644
index 209dacf..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contentchanged/StreamContentChangedListener.java
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.contentchanged;
-
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ContentChangedListener;
-
-import java.util.HashSet;
-
-/**
- * {@link ContentChangedListener} used to notify any number of listeners when content is changed.
- */
-public class StreamContentChangedListener implements ContentChangedListener {
-    private final HashSet<ContentChangedListener> mListeners = new HashSet<>();
-
-    public void addContentChangedListener(ContentChangedListener listener) {
-        mListeners.add(listener);
-    }
-
-    public void removeContentChangedListener(ContentChangedListener listener) {
-        mListeners.remove(listener);
-    }
-
-    @Override
-    public void onContentChanged() {
-        for (ContentChangedListener listener : mListeners) {
-            listener.onContentChanged();
-        }
-    }
-
-    @Override
-    public void onAddFinished() {
-        for (ContentChangedListener listener : mListeners) {
-            listener.onAddFinished();
-        }
-    }
-
-    @Override
-    public void onAddStarting() {
-        for (ContentChangedListener listener : mListeners) {
-            listener.onAddStarting();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contextmenumanager/ContextMenuManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contextmenumanager/ContextMenuManager.java
deleted file mode 100644
index dfe74460..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contextmenumanager/ContextMenuManager.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.contextmenumanager;
-
-import android.view.View;
-
-import java.util.List;
-
-/** Allow for display of context menus. */
-public interface ContextMenuManager {
-    /**
-     * Opens a context menu if there is currently no open context menu. Returns whether a menu was
-     * opened.
-     *
-     * @param anchorView The {@link View} to position the menu by.
-     * @param items The contents to display.
-     * @param handler The {@link ContextMenuClickHandler} that handles the user clicking on an
-     *         option.
-     */
-    boolean openContextMenu(View anchorView, List<String> items, ContextMenuClickHandler handler);
-
-    /** Dismiss a popup if one is showing. */
-    void dismissPopup();
-
-    /**
-     * Sets the root view of the window that the context menu is opening in. This, as well as the
-     * anchor view that the click happens on, determines where the context menu opens if the context
-     * menu is anchored.
-     *
-     * <p>Note: this is being changed to be settable after the fact for a future version of this
-     * library that will use dependency injection.
-     */
-    void setView(View view);
-
-    /** Notifies creator of the menu that a click has occurred. */
-    interface ContextMenuClickHandler {
-        void handleClick(int position);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contextmenumanager/ContextMenuManagerImpl.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contextmenumanager/ContextMenuManagerImpl.java
deleted file mode 100644
index 00f8c31..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contextmenumanager/ContextMenuManagerImpl.java
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.contextmenumanager;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.view.ContextThemeWrapper;
-import android.view.View;
-import android.view.ViewParent;
-import android.view.WindowManager.LayoutParams;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.PopupWindow;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.ui.LayoutUtils;
-import org.chromium.chrome.browser.feed.library.sharedstream.publicapi.menumeasurer.MenuMeasurer;
-import org.chromium.chrome.browser.feed.library.sharedstream.publicapi.menumeasurer.Size;
-
-import java.util.List;
-
-/**
- * Implementation of {@link ContextMenuManager} that shows the context menu anchored by a view. This
- * is only supported for N+
- */
-@TargetApi(Build.VERSION_CODES.N)
-public class ContextMenuManagerImpl implements ContextMenuManager {
-    private static final String TAG = "ContextMenuManager";
-
-    // Indicates how deep into the card the menu should be set if the menu is showing below a card.
-    // IE 4 indicates that the menu should be placed 1/4 of the way from the edge of the card.
-    private static final int FRACTION_FROM_EDGE = 4;
-
-    // Indicates how far from the bottom of the card the menu should be set if the menu is showing
-    // above a card.
-    private static final int FRACTION_FROM_BOTTOM_EDGE = FRACTION_FROM_EDGE - 1;
-
-    private final MenuMeasurer mMenuMeasurer;
-    private final Context mContext;
-    @Nullable
-    private View mView;
-
-    @Nullable
-    private PopupWindow mPopupWindow;
-
-    public ContextMenuManagerImpl(MenuMeasurer menuMeasurer, Context context) {
-        this.mMenuMeasurer = menuMeasurer;
-        this.mContext = context;
-    }
-
-    @Override
-    public void setView(View view) {
-        this.mView = view;
-    }
-
-    /**
-     * Opens a context menu if there is currently no open context menu. Returns whether a menu was
-     * opened.
-     *
-     * @param anchorView The {@link View} to position the menu by.
-     * @param items The contents to display.
-     * @param handler The {@link ContextMenuClickHandler} that handles the user clicking on an
-     *         option.
-     */
-    @Override
-    public boolean openContextMenu(
-            View anchorView, List<String> items, ContextMenuClickHandler handler) {
-        if (menuShowing()) {
-            return false;
-        }
-
-        ArrayAdapter<String> adapter =
-                new ArrayAdapter<>(mContext, R.layout.feed_simple_list_item, items);
-
-        ListView listView = createListView(adapter, mContext);
-
-        Size measurements = mMenuMeasurer.measureAdapterContent(
-                listView, adapter, /* windowPadding= */ 0, getStreamWidth(), getStreamHeight());
-
-        PopupWindowWithDimensions popupWindowWithDimensions =
-                createPopupWindow(listView, measurements, mContext);
-
-        listView.setOnItemClickListener((parent, view, position, id) -> {
-            handler.handleClick(position);
-            popupWindowWithDimensions.getPopupWindow().dismiss();
-        });
-
-        int yOffset = getYOffsetForContextMenu(
-                anchorView, popupWindowWithDimensions.getDimensions().getHeight());
-
-        int xOffset = anchorView.getWidth() / FRACTION_FROM_EDGE;
-
-        // In RtL locals, we want to show the menu 1 / FRACTION_FROM_EDGE from the right of the
-        // anchor view. showAsDropDown in RtL aligns the right edge of the menu with the right edge
-        // of the anchor view, so we want to shift to the left.
-        if (LayoutUtils.isDefaultLocaleRtl()) {
-            xOffset *= -1;
-        }
-
-        // Note: PopupWindow#showAsDropDown is bugged for android versions below N and should not be
-        // used in that context. Instead, showAtLocation should be used, and the menu should be set
-        // at an absolute location. However, to get enter animations to properly work,
-        // showAsDropDown needs to be used so that Android knows whether the menu is opening above
-        // or below the anchor view. This is possible as this class is only used for N+.
-        popupWindowWithDimensions.getPopupWindow().showAsDropDown(anchorView, xOffset, yOffset);
-
-        // We want to prevent any more touch events from be used (if a user has yet to end their
-        // current touch session). This prevents the possibility of scrolling after the context menu
-        // opens.
-        ViewParent parent = anchorView.getParent();
-        if (parent != null) {
-            parent.requestDisallowInterceptTouchEvent(true);
-        }
-
-        this.mPopupWindow = popupWindowWithDimensions.getPopupWindow();
-        return true;
-    }
-
-    /**
-     * Gets the offset in pixels from the bottom of the anchorview to place the menu.
-     *
-     * <p>First, we attempt to place the top of the menu {@code 1/FRACTION_FROM_EDGE} down from the
-     * top of the anchor view. If the menu cannot fit there, we attempt to put the bottom of the
-     * menu
-     * {@code 1/FRACTION_FROM_EDGE} up from the bottom of the anchor view. If the menu can fit in
-     * neither position it instead is centered in the stream.
-     */
-    // TODO: Add tests for each case here.
-    private int getYOffsetForContextMenu(
-            int menuHeight, int anchorViewYInWindow, int anchorViewHeight, int windowHeight) {
-        Logger.i(TAG,
-                "Getting Y offset for context menu. menuHeight: %s, anchorViewYInWindow: %s, "
-                        + "anchorViewHeight: %s, windowHeight: %s",
-                menuHeight, anchorViewYInWindow, anchorViewHeight, windowHeight);
-
-        // Check if the menu can fit below the card.
-        if (menuHeight + anchorViewYInWindow + anchorViewHeight / FRACTION_FROM_EDGE
-                < windowHeight) {
-            // Check if 1/FRACTION_FROM_EDGE of the way down the card is visible.
-            if (-FRACTION_FROM_EDGE * anchorViewYInWindow < anchorViewHeight) {
-                // 1/FRACTION_FROM_EDGE of the way down the card is visible stream, so offset to
-                // that point, from the bottom of the anchor view.
-                return -FRACTION_FROM_BOTTOM_EDGE * anchorViewHeight / FRACTION_FROM_EDGE;
-            } else {
-                // 1/FRACTION_FROM_EDGE down from the top of the anchor view is not visible, offset
-                // the menu to the top of the stream.
-                return -1 * (anchorViewHeight + anchorViewYInWindow);
-            }
-            // Check if the menu can have the bottom 1/FRACTION_FROM_EDGE off from the bottom of the
-            // anchor.
-        } else if (anchorViewYInWindow - menuHeight + anchorViewHeight / FRACTION_FROM_EDGE >= 0) {
-            // Check if 1/FRACTION_FROM_EDGE from the bottom of the anchor is visible.
-            if (anchorViewYInWindow
-                            + FRACTION_FROM_BOTTOM_EDGE * anchorViewHeight / FRACTION_FROM_EDGE
-                    < windowHeight) {
-                // FRACTION_FROM_BOTTOM_EDGE/FRACTION_FROM_EDGE of the way down the card is visible,
-                // so position the bottom there.
-                return -(menuHeight + anchorViewHeight / FRACTION_FROM_EDGE);
-            } else {
-                // Less than the top 1/FRACTION_FROM_EDGE of the card is on the screen. Offset so
-                // the menu is at the bottom of the screen
-                return -(menuHeight + anchorViewHeight - (windowHeight - anchorViewYInWindow));
-            }
-        } else {
-            // The menu will fit neither above, nor below the content. Center it in the middle of
-            // the screen.
-
-            // First, get an offset so that the top of the menu will be at the top of the screen.
-            int offset = -(anchorViewHeight + anchorViewYInWindow);
-
-            // Then, shift so that the middle of the menu is at the top of the screen.
-            offset -= menuHeight / 2;
-
-            // Then, shift so that the center of the menu is at the center of the screen.
-            offset += windowHeight / 2;
-
-            return offset;
-        }
-    }
-
-    private int getYOffsetForContextMenu(View anchorView, int menuHeight) {
-        int anchorViewY = getYPosition(anchorView);
-        int anchorViewYInWindow = anchorViewY - getStreamYPosition();
-
-        return getYOffsetForContextMenu(
-                menuHeight, anchorViewYInWindow, anchorView.getHeight(), getStreamHeight());
-    }
-
-    private PopupWindowWithDimensions createPopupWindow(
-            ListView listView, Size measurements, Context context) {
-        // While using elevation to create shadows should work in lollipop+, the shadow was not
-        // appearing in versions below Android N, so we are using ninepatch below N.
-        return createPopupWindowWithElevation(listView, measurements, context);
-    }
-
-    // TODO: Remove the nullness suppression.
-    @SuppressWarnings("nullness:argument.type.incompatible")
-    private PopupWindowWithDimensions createPopupWindowWithElevation(
-            ListView listView, Size measurements, Context context) {
-        // Note: We are intentionally using contextPopupMenuStyle, which allows hosts to modify the
-        // style of context menus. This should not be changed without speaking with host teams.
-        PopupWindow popupWindow = new PopupWindow(
-                getBaseContext(context), null, android.R.attr.contextPopupMenuStyle);
-        Drawable background = popupWindow.getBackground();
-        Rect backgroundPadding = new Rect();
-        background.getPadding(backgroundPadding);
-        popupWindow.setContentView(listView);
-
-        // We want the menu to wrap content.
-        popupWindow.setHeight(LayoutParams.WRAP_CONTENT);
-
-        // Material design specifies the width of a menu, so we set it specifically, instead of
-        // wrapping content.
-        popupWindow.setWidth(measurements.getWidth() + backgroundPadding.width());
-
-        popupWindow.setFocusable(true);
-
-        // So this is weird. In our situation, the menu does overlap with the anchor. Setting this
-        // to false doesn't actually make it impossible to overlap with the anchor, it just changes
-        // the default behavior of PopupWindow#showAsDropDown. All of the positioning logic written
-        // to this point has assumed that the default position of a drop down menu is with the top
-        // left of the menu touching the bottom right of the anchor view. Setting overlap anchor to
-        // true changes the default behavior so that the top left corner of the menu is over the top
-        // left corner of the anchor view. As the logic has been written assuming overlap anchor is
-        // false, we set it false.
-        popupWindow.setOverlapAnchor(false);
-
-        // Our positioning code uses this sizing to properly position the menus. The measurement we
-        // need here is from the top of the menu, to the bottom of where the shadow ends (and
-        // similarly for width). So we divide the width and height of the shadows by two to now
-        // include the shadows on both sides.
-        Size popupAndBackgroundSize = new Size(measurements.getWidth()
-                        + (backgroundPadding.width() + background.getMinimumWidth()) / 2,
-                measurements.getHeight()
-                        + (backgroundPadding.height() + background.getMinimumHeight()) / 2);
-
-        return new PopupWindowWithDimensions(popupWindow, popupAndBackgroundSize);
-    }
-
-    private Context getBaseContext(Context context) {
-        if (context instanceof ContextThemeWrapper) {
-            return ((ContextThemeWrapper) context).getBaseContext();
-        }
-        return context;
-    }
-
-    private ListView createListView(ArrayAdapter<String> adapter, Context context) {
-        ListView listView = new ListView(context);
-        listView.setAdapter(adapter);
-        listView.setDivider(null);
-        listView.setDividerHeight(0);
-        return listView;
-    }
-
-    /**
-     * Gets the height of the Stream. This is specifically the height visible on screen, not
-     * including anything below the screen.
-     */
-    int getStreamHeight() {
-        return checkNotNull(mView).getHeight();
-    }
-
-    /** Gets the width of the Stream. */
-    private int getStreamWidth() {
-        return checkNotNull(mView).getWidth();
-    }
-
-    /** Gets the Y coordinate of the position of the Stream. */
-    private int getStreamYPosition() {
-        return getYPosition(checkNotNull(mView));
-    }
-
-    private boolean menuShowing() {
-        return mPopupWindow != null && mPopupWindow.isShowing();
-    }
-
-    @Override
-    public void dismissPopup() {
-        if (mPopupWindow == null) {
-            return;
-        }
-
-        mPopupWindow.dismiss();
-        mPopupWindow = null;
-    }
-
-    private int getYPosition(View view) {
-        int[] viewLocation = new int[2];
-        view.getLocationInWindow(viewLocation);
-
-        return viewLocation[1];
-    }
-
-    /** Represents a {@link PopupWindow} that accounts for padding caused by shadows. */
-    private static class PopupWindowWithDimensions {
-        private final PopupWindow mPopupWindow;
-        private final Size mSize;
-
-        PopupWindowWithDimensions(PopupWindow popupWindow, Size size) {
-            this.mPopupWindow = popupWindow;
-            this.mSize = size;
-        }
-
-        PopupWindow getPopupWindow() {
-            return mPopupWindow;
-        }
-
-        Size getDimensions() {
-            return mSize;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contextmenumanager/FloatingContextMenuManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contextmenumanager/FloatingContextMenuManager.java
deleted file mode 100644
index 4685792..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contextmenumanager/FloatingContextMenuManager.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.contextmenumanager;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.view.View;
-import android.view.ViewParent;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.R;
-
-import java.util.List;
-
-/**
- * {@link ContextMenuManager} implementation to show a floating context menu that is positioned
- * without regard to the anchor view.
- */
-public class FloatingContextMenuManager implements ContextMenuManager {
-    private final Context mContext;
-    @Nullable
-    private AlertDialog mAlertDialog;
-
-    public FloatingContextMenuManager(Context context) {
-        this.mContext = context;
-    }
-
-    @Override
-    public boolean openContextMenu(
-            View anchorView, List<String> items, ContextMenuClickHandler handler) {
-        if (menuShowing()) {
-            return false;
-        }
-
-        ArrayAdapter<String> adapter =
-                new ArrayAdapter<>(mContext, R.layout.feed_simple_list_item, items);
-
-        ListView listView = createListView(adapter, mContext);
-        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(mContext);
-
-        dialogBuilder.setView(listView);
-        AlertDialog alertDialog = dialogBuilder.create();
-        listView.setOnItemClickListener((parent, view, position, id) -> {
-            handler.handleClick(position);
-            dismissPopup();
-        });
-
-        ViewParent parent = anchorView.getParent();
-        if (parent != null) {
-            parent.requestDisallowInterceptTouchEvent(true);
-        }
-        alertDialog.show();
-
-        this.mAlertDialog = alertDialog;
-        return true;
-    }
-
-    private ListView createListView(ArrayAdapter<String> adapter, Context context) {
-        ListView listView = new ListView(context);
-        listView.setAdapter(adapter);
-        listView.setDivider(null);
-        listView.setDividerHeight(0);
-
-        return listView;
-    }
-
-    @Override
-    public void dismissPopup() {
-        if (mAlertDialog != null) {
-            mAlertDialog.dismiss();
-            mAlertDialog = null;
-        }
-    }
-
-    @Override
-    public void setView(View view) {
-        // No-op.
-    }
-
-    private boolean menuShowing() {
-        return mAlertDialog != null && mAlertDialog.isShowing();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/deepestcontenttracker/DeepestContentTracker.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/deepestcontenttracker/DeepestContentTracker.java
deleted file mode 100644
index 259dfcb..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/deepestcontenttracker/DeepestContentTracker.java
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.deepestcontenttracker;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider.ViewDepthProvider;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Tracks the {@code contentId} of the deepest viewed content. */
-public class DeepestContentTracker implements ViewDepthProvider {
-    private static final String TAG = "DeepestContentTracker";
-
-    private final List<String> mContentIds = new ArrayList<>();
-
-    public void updateDeepestContentTracker(int contentPosition, @Nullable String contentId) {
-        // Fill content ids to size of content position. This is needed in-case we programmatically
-        // set scroll position of the recycler view. Add one to contentPosition size in order to
-        // more easily perform a set below.
-        while (mContentIds.size() < contentPosition + 1) {
-            mContentIds.add(null);
-        }
-
-        // Just update the content id of the item in the list.
-        mContentIds.set(contentPosition, contentId);
-    }
-
-    public void removeContentId(int contentPosition) {
-        if (contentPosition >= mContentIds.size()) {
-            return;
-        }
-
-        mContentIds.remove(contentPosition);
-    }
-
-    @VisibleForTesting
-    @Nullable
-    String getContentItAtPosition(int position) {
-        if (position >= mContentIds.size() || position < 0) {
-            return null;
-        }
-
-        return mContentIds.get(position);
-    }
-
-    public void reset() {
-        mContentIds.clear();
-    }
-
-    @Override
-    @Nullable
-    public String getChildViewDepth() {
-        if (mContentIds.isEmpty()) {
-            return null;
-        }
-
-        int i = mContentIds.size() - 1;
-        while (mContentIds.get(i) == null && i > 0) {
-            i--;
-        }
-
-        return mContentIds.get(i);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/LoggingListener.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/LoggingListener.java
deleted file mode 100644
index 5559112..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/LoggingListener.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.logging;
-
-/**
- * Interface that extends {@link VisibilityListener} and provides additional callbacks for logging
- * events.
- */
-public interface LoggingListener extends VisibilityListener {
-    void onContentClicked();
-
-    void onContentSwiped();
-
-    /**
-     * Called when the scroll state changes.
-     *
-     * @param newScrollState: the new {@link ScrollState} that is occurring (e.g. dragging, idle).
-     */
-    void onScrollStateChanged(int newScrollState);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/OneShotVisibilityLoggingListener.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/OneShotVisibilityLoggingListener.java
deleted file mode 100644
index 756760f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/OneShotVisibilityLoggingListener.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.logging;
-
-/** Implementation of a {@link LoggingListener} that only notifies a listener of the first view. */
-public class OneShotVisibilityLoggingListener implements LoggingListener {
-    private final LoggingListener mLoggingListener;
-    protected boolean mViewLogged;
-
-    public OneShotVisibilityLoggingListener(LoggingListener loggingListener) {
-        this.mLoggingListener = loggingListener;
-    }
-
-    @Override
-    public void onViewVisible() {
-        if (mViewLogged) {
-            return;
-        }
-
-        mLoggingListener.onViewVisible();
-        mViewLogged = true;
-    }
-
-    @Override
-    public void onContentClicked() {
-        mLoggingListener.onContentClicked();
-    }
-
-    @Override
-    public void onContentSwiped() {
-        mLoggingListener.onContentSwiped();
-    }
-
-    @Override
-    public void onScrollStateChanged(int newScrollState) {
-        mLoggingListener.onScrollStateChanged(newScrollState);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/SpinnerLogger.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/SpinnerLogger.java
deleted file mode 100644
index b21423b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/SpinnerLogger.java
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.logging;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.SpinnerType;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-
-/** Logs events for displaying spinner in the Stream. */
-public class SpinnerLogger {
-    private static final String TAG = "SpinnerLogger";
-    private static final int SPINNER_INACTIVE = -1;
-    private final BasicLoggingApi mBasicLoggingApi;
-    private final Clock mClock;
-
-    private long mSpinnerStartTime = SPINNER_INACTIVE;
-    @SpinnerType
-    private int mSpinnerType;
-
-    public SpinnerLogger(BasicLoggingApi basicLoggingApi, Clock clock) {
-        this.mBasicLoggingApi = basicLoggingApi;
-        this.mClock = clock;
-    }
-
-    public void spinnerStarted(@SpinnerType int spinnerType) {
-        if (isSpinnerActive()) {
-            Logger.wtf(TAG,
-                    "spinnerStarted should not be called if another spinner is "
-                            + "currently being tracked.");
-            return;
-        }
-
-        mBasicLoggingApi.onSpinnerStarted(spinnerType);
-        mSpinnerStartTime = mClock.currentTimeMillis();
-        this.mSpinnerType = spinnerType;
-    }
-
-    public void spinnerFinished() {
-        if (!isSpinnerActive()) {
-            Logger.wtf(TAG, "spinnerFinished should only be called after spinnerStarted.");
-            return;
-        }
-
-        long spinnerDuration = mClock.currentTimeMillis() - mSpinnerStartTime;
-        mBasicLoggingApi.onSpinnerFinished((int) spinnerDuration, mSpinnerType);
-        mSpinnerStartTime = SPINNER_INACTIVE;
-    }
-
-    public void spinnerDestroyedWithoutCompleting() {
-        if (!isSpinnerActive()) {
-            Logger.wtf(TAG,
-                    "spinnerDestroyedWithoutCompleting should only be called after"
-                            + " spinnerStarted.");
-            return;
-        }
-
-        long spinnerDuration = mClock.currentTimeMillis() - mSpinnerStartTime;
-        mBasicLoggingApi.onSpinnerDestroyedWithoutCompleting((int) spinnerDuration, mSpinnerType);
-        mSpinnerStartTime = SPINNER_INACTIVE;
-    }
-
-    @VisibleForTesting
-    @SpinnerType
-    public int getSpinnerType() {
-        return mSpinnerType;
-    }
-
-    public boolean isSpinnerActive() {
-        return mSpinnerStartTime != SPINNER_INACTIVE;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/StreamContentLoggingData.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/StreamContentLoggingData.java
deleted file mode 100644
index 07d7aa30..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/StreamContentLoggingData.java
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.logging;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.host.logging.ContentLoggingData;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.ClientBasicLoggingMetadata;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.BasicLoggingMetadata;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.RepresentationData;
-
-import java.util.Objects;
-
-/** Implementation of {@link ContentLoggingData} to capture content data when logging events. */
-public class StreamContentLoggingData implements ContentLoggingData {
-    private final int mPositionInStream;
-    private final long mPublishedTimeSeconds;
-    private final long mTimeContentBecameAvailable;
-    private final float mScore;
-    private final String mRepresentationUri;
-    private final boolean mIsAvailableOffline;
-
-    public StreamContentLoggingData(int positionInStream, BasicLoggingMetadata basicLoggingMetadata,
-            RepresentationData representationData, boolean availableOffline) {
-        this(positionInStream, representationData.getPublishedTimeSeconds(),
-                basicLoggingMetadata
-                        .getExtension(ClientBasicLoggingMetadata.clientBasicLoggingMetadata)
-                        .getAvailabilityTimeSeconds(),
-                basicLoggingMetadata.getScore(), representationData.getUri(), availableOffline);
-    }
-
-    private StreamContentLoggingData(int positionInStream, long publishedTimeSeconds,
-            long timeContentBecameAvailable, float score, String representationUri,
-            boolean isAvailableOffline) {
-        this.mPositionInStream = positionInStream;
-        this.mPublishedTimeSeconds = publishedTimeSeconds;
-        this.mTimeContentBecameAvailable = timeContentBecameAvailable;
-        this.mScore = score;
-        this.mRepresentationUri = representationUri;
-        this.mIsAvailableOffline = isAvailableOffline;
-    }
-
-    @Override
-    public int getPositionInStream() {
-        return mPositionInStream;
-    }
-
-    @Override
-    public long getPublishedTimeSeconds() {
-        return mPublishedTimeSeconds;
-    }
-
-    @Override
-    public long getTimeContentBecameAvailable() {
-        return mTimeContentBecameAvailable;
-    }
-
-    @Override
-    public float getScore() {
-        return mScore;
-    }
-
-    @Override
-    public String getRepresentationUri() {
-        return mRepresentationUri;
-    }
-
-    @Override
-    public boolean isAvailableOffline() {
-        return mIsAvailableOffline;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mPositionInStream, mPublishedTimeSeconds, mTimeContentBecameAvailable,
-                mScore, mRepresentationUri, mIsAvailableOffline);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof StreamContentLoggingData)) {
-            return false;
-        }
-
-        StreamContentLoggingData that = (StreamContentLoggingData) o;
-
-        if (mPositionInStream != that.mPositionInStream) {
-            return false;
-        }
-        if (mPublishedTimeSeconds != that.mPublishedTimeSeconds) {
-            return false;
-        }
-        if (mTimeContentBecameAvailable != that.mTimeContentBecameAvailable) {
-            return false;
-        }
-        if (Float.compare(that.mScore, mScore) != 0) {
-            return false;
-        }
-        if (mIsAvailableOffline != that.mIsAvailableOffline) {
-            return false;
-        }
-
-        return Objects.equals(mRepresentationUri, that.mRepresentationUri);
-    }
-
-    @Override
-    public String toString() {
-        return "StreamContentLoggingData{"
-                + "positionInStream=" + mPositionInStream
-                + ", publishedTimeSeconds=" + mPublishedTimeSeconds
-                + ", timeContentBecameAvailable=" + mTimeContentBecameAvailable
-                + ", score=" + mScore + ", representationUri='" + mRepresentationUri + '\'' + '}';
-    }
-
-    /**
-     * Returns a {@link StreamContentLoggingData} instance with {@code this} as a basis, but with
-     * the given offline status.
-     *
-     * <p>Will not create a new instance if unneeded.
-     */
-    public StreamContentLoggingData createWithOfflineStatus(boolean offlineStatus) {
-        if (offlineStatus == this.mIsAvailableOffline) {
-            return this;
-        }
-
-        return new StreamContentLoggingData(mPositionInStream, mPublishedTimeSeconds,
-                mTimeContentBecameAvailable, mScore, mRepresentationUri, offlineStatus);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/UiSessionRequestLogger.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/UiSessionRequestLogger.java
deleted file mode 100644
index 14f3c0c7..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/UiSessionRequestLogger.java
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.logging;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.SessionEvent;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelError;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProviderObserver;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-
-/** Logs the initial event after sessions have been requested by the UI. */
-public class UiSessionRequestLogger implements ModelProviderObserver {
-    private static final String TAG = "UiSessionRequestLogger";
-    private final Clock mClock;
-    private final BasicLoggingApi mBasicLoggingApi;
-    private int mSessionCount;
-    @Nullable
-    private SessionRequestState mSessionRequestState;
-
-    public UiSessionRequestLogger(Clock clock, BasicLoggingApi basicLoggingApi) {
-        this.mClock = clock;
-        this.mBasicLoggingApi = basicLoggingApi;
-    }
-
-    /** Should be called whenever the UI requests a new session from the {@link ModelProvider}. */
-    public void onSessionRequested(ModelProvider modelProvider) {
-        if (mSessionRequestState != null) {
-            mSessionRequestState.mModelProvider.unregisterObserver(this);
-        }
-
-        this.mSessionRequestState = new SessionRequestState(modelProvider, mClock);
-        modelProvider.registerObserver(this);
-    }
-
-    @Override
-    public void onSessionStart(UiContext uiContext) {
-        if (mSessionRequestState == null) {
-            Logger.wtf(TAG, "onSessionStart() called without SessionRequestState.");
-            return;
-        }
-
-        SessionRequestState localSessionRequestState = mSessionRequestState;
-
-        mBasicLoggingApi.onInitialSessionEvent(
-                SessionEvent.STARTED, localSessionRequestState.getElapsedTime(), ++mSessionCount);
-
-        localSessionRequestState.getModelProvider().unregisterObserver(this);
-        mSessionRequestState = null;
-    }
-
-    @Override
-    public void onSessionFinished(UiContext uiContext) {
-        if (mSessionRequestState == null) {
-            Logger.wtf(TAG, "onSessionFinished() called without SessionRequestState.");
-            return;
-        }
-
-        SessionRequestState localSessionRequestState = mSessionRequestState;
-
-        mBasicLoggingApi.onInitialSessionEvent(SessionEvent.FINISHED_IMMEDIATELY,
-                localSessionRequestState.getElapsedTime(), ++mSessionCount);
-
-        localSessionRequestState.getModelProvider().unregisterObserver(this);
-        mSessionRequestState = null;
-    }
-
-    @Override
-    public void onError(ModelError modelError) {
-        if (mSessionRequestState == null) {
-            Logger.wtf(TAG, "onError() called without SessionRequestState.");
-            return;
-        }
-
-        SessionRequestState localSessionRequestState = mSessionRequestState;
-
-        mBasicLoggingApi.onInitialSessionEvent(
-                SessionEvent.ERROR, localSessionRequestState.getElapsedTime(), ++mSessionCount);
-
-        localSessionRequestState.getModelProvider().unregisterObserver(this);
-        mSessionRequestState = null;
-    }
-
-    /** Should be called whenever the UI is destroyed, and will log the event if necessary. */
-    public void onDestroy() {
-        if (mSessionRequestState == null) {
-            // We don't wtf here as to allow onDestroy() to be called regardless of the internal
-            // state.
-            return;
-        }
-
-        SessionRequestState localSessionRequestState = mSessionRequestState;
-
-        mBasicLoggingApi.onInitialSessionEvent(SessionEvent.USER_ABANDONED,
-                localSessionRequestState.getElapsedTime(), ++mSessionCount);
-
-        localSessionRequestState.getModelProvider().unregisterObserver(this);
-        mSessionRequestState = null;
-    }
-
-    /** Encapsulates the state of whether a session has been requested and when it was requested. */
-    private static class SessionRequestState {
-        private final long mSessionRequestTime;
-        private final ModelProvider mModelProvider;
-        private final Clock mClock;
-
-        private SessionRequestState(ModelProvider modelProvider, Clock clock) {
-            this.mSessionRequestTime = clock.elapsedRealtime();
-            this.mModelProvider = modelProvider;
-            this.mClock = clock;
-        }
-
-        int getElapsedTime() {
-            return (int) (mClock.elapsedRealtime() - mSessionRequestTime);
-        }
-
-        ModelProvider getModelProvider() {
-            return mModelProvider;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/VisibilityListener.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/VisibilityListener.java
deleted file mode 100644
index 83139ab..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/VisibilityListener.java
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.logging;
-
-/** Interface that can be implemented to listen to view visibility events. */
-public interface VisibilityListener { void onViewVisible(); }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/VisibilityMonitor.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/VisibilityMonitor.java
deleted file mode 100644
index 64a8855..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/VisibilityMonitor.java
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.logging;
-
-import android.graphics.Rect;
-import android.view.View;
-import android.view.ViewParent;
-import android.view.ViewTreeObserver;
-
-import androidx.annotation.Nullable;
-import androidx.core.view.ViewCompat;
-
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-
-/** Utility class to monitor the visibility of a view. */
-public class VisibilityMonitor
-        implements ViewTreeObserver.OnPreDrawListener, View.OnAttachStateChangeListener {
-    public static final double DEFAULT_VIEW_LOG_THRESHOLD = .66;
-    private static final String TAG = "VisibilityMonitor";
-
-    private final View mView;
-    private final double mViewLogThreshold;
-    private boolean mVisible;
-    @Nullable
-    private VisibilityListener mVisibilityListener;
-
-    public VisibilityMonitor(View view, Configuration configuration) {
-        this.mView = view;
-        this.mViewLogThreshold = configuration.getValueOrDefault(
-                ConfigKey.VIEW_LOG_THRESHOLD, DEFAULT_VIEW_LOG_THRESHOLD);
-    }
-
-    public VisibilityMonitor(View view, double viewLogThreshold) {
-        this.mView = view;
-        this.mViewLogThreshold = viewLogThreshold;
-    }
-
-    @Override
-    public boolean onPreDraw() {
-        ViewParent parent = mView.getParent();
-        if (parent != null) {
-            Rect rect = new Rect(0, 0, mView.getWidth(), mView.getHeight());
-
-            @SuppressWarnings("argument.type.incompatible")
-            boolean childVisibleRectNotEmpty = parent.getChildVisibleRect(mView, rect, null);
-            if (childVisibleRectNotEmpty
-                    && rect.height() >= mViewLogThreshold * mView.getHeight()) {
-                if (!mVisible) {
-                    notifyListenerOnVisible();
-                    mVisible = true;
-                }
-            } else {
-                mVisible = false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public void onViewAttachedToWindow(View v) {
-        mView.getViewTreeObserver().addOnPreDrawListener(this);
-    }
-
-    @Override
-    public void onViewDetachedFromWindow(View v) {
-        mVisible = false;
-        mView.getViewTreeObserver().removeOnPreDrawListener(this);
-    }
-
-    public void setListener(@Nullable VisibilityListener visibilityListener) {
-        if (visibilityListener != null) {
-            detach();
-        }
-
-        this.mVisibilityListener = visibilityListener;
-
-        if (visibilityListener != null) {
-            attach();
-        }
-    }
-
-    private void attach() {
-        mView.addOnAttachStateChangeListener(this);
-        if (ViewCompat.isAttachedToWindow(mView)) {
-            mView.getViewTreeObserver().addOnPreDrawListener(this);
-        }
-    }
-
-    private void detach() {
-        mView.removeOnAttachStateChangeListener(this);
-        if (ViewCompat.isAttachedToWindow(mView)) {
-            mView.getViewTreeObserver().removeOnPreDrawListener(this);
-        }
-    }
-
-    private void notifyListenerOnVisible() {
-        if (mVisibilityListener != null) {
-            mVisibilityListener.onViewVisible();
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/offlinemonitor/StreamOfflineMonitor.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/offlinemonitor/StreamOfflineMonitor.java
deleted file mode 100644
index ccc9e73..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/offlinemonitor/StreamOfflineMonitor.java
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.offlinemonitor;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.offlineindicator.OfflineIndicatorApi;
-import org.chromium.chrome.browser.feed.library.api.host.offlineindicator.OfflineIndicatorApi.OfflineStatusListener;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/** Monitors and notifies consumers as to when the offline status of given urls change. */
-public class StreamOfflineMonitor implements OfflineStatusListener {
-    private static final String TAG = "StreamOfflineMonitor";
-
-    private final Set<String> mContentToRequestStatus = new HashSet<>();
-    private final Set<String> mOfflineContent = new HashSet<>();
-    private final OfflineIndicatorApi mOfflineIndicatorApi;
-
-    @VisibleForTesting
-    protected final Map<String, List<Consumer<Boolean>>> mOfflineStatusConsumersMap =
-            new HashMap<>();
-
-    @SuppressWarnings("nullness:argument.type.incompatible")
-    public StreamOfflineMonitor(OfflineIndicatorApi offlineIndicatorApi) {
-        offlineIndicatorApi.addOfflineStatusListener(this);
-        this.mOfflineIndicatorApi = offlineIndicatorApi;
-    }
-
-    /**
-     * Returns whether the given url is known to be available offline.
-     *
-     * <p>Note: As this monitor does not have complete knowledge as to what is available offline,
-     * this may return {@code false} for content that is available offline. Once the host has been
-     * informed that such articles are on the feed, it will eventually inform the feed of any
-     * additional offline stories. At that point, any relevant listeners will be notified.
-     */
-    public boolean isAvailableOffline(String url) {
-        if (mOfflineContent.contains(url)) {
-            return true;
-        }
-        mContentToRequestStatus.add(url);
-        return false;
-    }
-
-    /**
-     * Adds consumer for any changes in the status of the offline availability of the given story.
-     * Only triggered on change, not immediately upon registering.
-     */
-    public void addOfflineStatusConsumer(String url, Consumer<Boolean> isOfflineConsumer) {
-        if (!mOfflineStatusConsumersMap.containsKey(url)) {
-            // Initializing size of lists to 1 as it is unlikely that we would have more than one
-            // listener per URL.
-            mOfflineStatusConsumersMap.put(url, new ArrayList<>(1));
-        }
-
-        mOfflineStatusConsumersMap.get(url).add(isOfflineConsumer);
-    }
-
-    /**
-     * Removes consumer for any changes in the status of the offline availability of the given
-     * story.
-     */
-    public void removeOfflineStatusConsumer(String url, Consumer<Boolean> isOfflineConsumer) {
-        if (!mOfflineStatusConsumersMap.containsKey(url)) {
-            Logger.w(TAG, "Removing consumer for url %s with no list of consumers", url);
-            return;
-        }
-
-        if (!mOfflineStatusConsumersMap.get(url).remove(isOfflineConsumer)) {
-            Logger.w(TAG, "Removing consumer for url %s that isn't on list of consumers", url);
-        }
-
-        if (mOfflineStatusConsumersMap.get(url).isEmpty()) {
-            mOfflineStatusConsumersMap.remove(url);
-        }
-    }
-
-    private void notifyConsumers(String url, boolean availableOffline) {
-        List<Consumer<Boolean>> offlineStatusConsumers = mOfflineStatusConsumersMap.get(url);
-        if (offlineStatusConsumers == null) {
-            return;
-        }
-
-        for (Consumer<Boolean> statusConsumer : offlineStatusConsumers) {
-            statusConsumer.accept(availableOffline);
-        }
-    }
-
-    public void requestOfflineStatusForNewContent() {
-        if (mContentToRequestStatus.isEmpty()) {
-            return;
-        }
-
-        mOfflineIndicatorApi.getOfflineStatus(
-                new ArrayList<>(mContentToRequestStatus), offlineUrls -> {
-                    for (String offlineUrl : offlineUrls) {
-                        updateOfflineStatus(offlineUrl, true);
-                    }
-                });
-        mContentToRequestStatus.clear();
-    }
-
-    @Override
-    public void updateOfflineStatus(String url, boolean availableOffline) {
-        // If the new offline status is the same as our knowledge of it, no-op.
-        if (mOfflineContent.contains(url) == availableOffline) {
-            return;
-        }
-
-        if (availableOffline) {
-            mOfflineContent.add(url);
-        } else {
-            mOfflineContent.remove(url);
-        }
-
-        notifyConsumers(url, availableOffline);
-    }
-
-    public void onDestroy() {
-        mOfflineStatusConsumersMap.clear();
-        mOfflineIndicatorApi.removeOfflineStatusListener(this);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/pendingdismiss/PendingDismissCallback.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/pendingdismiss/PendingDismissCallback.java
deleted file mode 100644
index 0630541..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/pendingdismiss/PendingDismissCallback.java
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.pendingdismiss;
-
-/** An interface for a callbacks related to dismisses so proper logging can occur. */
-public interface PendingDismissCallback {
-    /* Called when the dismiss has been reverted and the dismissed content has come back. */
-    void onDismissReverted();
-
-    /* Called when the dismiss has been committed and can no longer be reversed. */
-    void onDismissCommitted();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietCustomElementProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietCustomElementProvider.java
deleted file mode 100644
index 04a7c05f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietCustomElementProvider.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.piet;
-
-import android.content.Context;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.piet.host.CustomElementProvider;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.CustomElementData;
-
-/**
- * A Stream implementation of a {@link CustomElementProvider} which handles Stream custom elements
- * and can delegate to a host custom element adapter if needed.
- */
-public class PietCustomElementProvider implements CustomElementProvider {
-    private static final String TAG = "PietCustomElementPro";
-
-    private final Context mContext;
-    @Nullable
-    private final CustomElementProvider mHostCustomElementProvider;
-
-    public PietCustomElementProvider(
-            Context context, @Nullable CustomElementProvider hostCustomElementProvider) {
-        this.mContext = context;
-        this.mHostCustomElementProvider = hostCustomElementProvider;
-    }
-
-    @Override
-    public View createCustomElement(CustomElementData customElementData) {
-        // We don't currently implement any custom elements yet.  Delegate to host if there is one.
-        if (mHostCustomElementProvider != null) {
-            return mHostCustomElementProvider.createCustomElement(customElementData);
-        }
-
-        // Just return an empty view if there is not host.
-        Logger.w(TAG, "Received request for unknown custom element");
-        return new View(mContext);
-    }
-
-    @Override
-    public void releaseCustomView(View customElementView, CustomElementData customElementData) {
-        if (mHostCustomElementProvider != null) {
-            mHostCustomElementProvider.releaseCustomView(customElementView, customElementData);
-            return;
-        }
-
-        Logger.w(TAG, "Received release for unknown custom element");
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietEventLogger.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietEventLogger.java
deleted file mode 100644
index 25909fdb..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietEventLogger.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.piet;
-
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.components.feed.core.proto.ui.piet.ErrorsProto.ErrorCode;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Logger that logs to the {@link BasicLoggingApi} any Piet errors. */
-public class PietEventLogger {
-    private final BasicLoggingApi mBasicLoggingApi;
-
-    public PietEventLogger(BasicLoggingApi basicLoggingApi) {
-        this.mBasicLoggingApi = basicLoggingApi;
-    }
-
-    public void logEvents(List<ErrorCode> pietErrors) {
-        mBasicLoggingApi.onPietFrameRenderingEvent(convertErrorCodes(pietErrors));
-    }
-
-    private List<Integer> convertErrorCodes(List<ErrorCode> errorCodes) {
-        List<Integer> errorCodeValues = new ArrayList<>(errorCodes.size());
-        for (ErrorCode errorCode : errorCodes) {
-            errorCodeValues.add(errorCode.getNumber());
-        }
-        return errorCodeValues;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietHostBindingProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietHostBindingProvider.java
deleted file mode 100644
index 8d8ab1fe..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietHostBindingProvider.java
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.piet;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.piet.host.HostBindingProvider;
-import org.chromium.chrome.browser.feed.library.sharedstream.offlinemonitor.StreamOfflineMonitor;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.BindingValue;
-import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.HostBindingData;
-import org.chromium.components.feed.core.proto.ui.stream.StreamOfflineExtensionProto.OfflineExtension;
-
-/**
- * A Stream implementation of a {@link HostBindingProvider} which handles Stream host bindings and
- * can delegate to a host host binding provider if needed.
- */
-public class PietHostBindingProvider extends HostBindingProvider {
-    private static final String TAG = "PietHostBindingProvider";
-
-    private final StreamOfflineMonitor mOfflineMonitor;
-    @Nullable
-    private final HostBindingProvider mHostBindingProvider;
-
-    public PietHostBindingProvider(@Nullable HostBindingProvider hostHostBindingProvider,
-            StreamOfflineMonitor offlineMonitor) {
-        this.mHostBindingProvider = hostHostBindingProvider;
-        this.mOfflineMonitor = offlineMonitor;
-    }
-
-    @Override
-    public BindingValue getCustomElementDataBindingForValue(BindingValue bindingValue) {
-        BindingValue genericBindingResult = getGenericBindingForValue(bindingValue);
-
-        if (genericBindingResult != null) {
-            return genericBindingResult;
-        }
-
-        if (mHostBindingProvider != null) {
-            return mHostBindingProvider.getCustomElementDataBindingForValue(bindingValue);
-        }
-        return super.getCustomElementDataBindingForValue(bindingValue);
-    }
-
-    @Override
-    public BindingValue getParameterizedTextBindingForValue(BindingValue bindingValue) {
-        BindingValue genericBindingResult = getGenericBindingForValue(bindingValue);
-
-        if (genericBindingResult != null) {
-            return genericBindingResult;
-        }
-
-        if (mHostBindingProvider != null) {
-            return mHostBindingProvider.getParameterizedTextBindingForValue(bindingValue);
-        }
-        return super.getParameterizedTextBindingForValue(bindingValue);
-    }
-
-    @Override
-    public BindingValue getChunkedTextBindingForValue(BindingValue bindingValue) {
-        BindingValue genericBindingResult = getGenericBindingForValue(bindingValue);
-
-        if (genericBindingResult != null) {
-            return genericBindingResult;
-        }
-
-        if (mHostBindingProvider != null) {
-            return mHostBindingProvider.getChunkedTextBindingForValue(bindingValue);
-        }
-        return super.getChunkedTextBindingForValue(bindingValue);
-    }
-
-    @Override
-    public BindingValue getImageBindingForValue(BindingValue bindingValue) {
-        BindingValue genericBindingResult = getGenericBindingForValue(bindingValue);
-
-        if (genericBindingResult != null) {
-            return genericBindingResult;
-        }
-
-        if (mHostBindingProvider != null) {
-            return mHostBindingProvider.getImageBindingForValue(bindingValue);
-        }
-        return super.getImageBindingForValue(bindingValue);
-    }
-
-    @Override
-    public BindingValue getActionsBindingForValue(BindingValue bindingValue) {
-        BindingValue genericBindingResult = getGenericBindingForValue(bindingValue);
-
-        if (genericBindingResult != null) {
-            return genericBindingResult;
-        }
-
-        if (mHostBindingProvider != null) {
-            return mHostBindingProvider.getActionsBindingForValue(bindingValue);
-        }
-        return super.getActionsBindingForValue(bindingValue);
-    }
-
-    @Override
-    public BindingValue getGridCellWidthBindingForValue(BindingValue bindingValue) {
-        BindingValue genericBindingResult = getGenericBindingForValue(bindingValue);
-
-        if (genericBindingResult != null) {
-            return genericBindingResult;
-        }
-
-        if (mHostBindingProvider != null) {
-            return mHostBindingProvider.getGridCellWidthBindingForValue(bindingValue);
-        }
-        return super.getGridCellWidthBindingForValue(bindingValue);
-    }
-
-    @Override
-    public BindingValue getLogDataBindingForValue(BindingValue bindingValue) {
-        BindingValue genericBindingResult = getGenericBindingForValue(bindingValue);
-
-        if (genericBindingResult != null) {
-            return genericBindingResult;
-        }
-
-        if (mHostBindingProvider != null) {
-            return mHostBindingProvider.getLogDataBindingForValue(bindingValue);
-        }
-        return super.getLogDataBindingForValue(bindingValue);
-    }
-
-    @Override
-    public BindingValue getTemplateBindingForValue(BindingValue bindingValue) {
-        BindingValue genericBindingResult = getGenericBindingForValue(bindingValue);
-
-        if (genericBindingResult != null) {
-            return genericBindingResult;
-        }
-
-        if (mHostBindingProvider != null) {
-            return mHostBindingProvider.getTemplateBindingForValue(bindingValue);
-        }
-        return super.getTemplateBindingForValue(bindingValue);
-    }
-
-    @Override
-    public BindingValue getStyleBindingForValue(BindingValue bindingValue) {
-        BindingValue genericBindingResult = getGenericBindingForValue(bindingValue);
-
-        if (genericBindingResult != null) {
-            return genericBindingResult;
-        }
-
-        if (mHostBindingProvider != null) {
-            return mHostBindingProvider.getStyleBindingForValue(bindingValue);
-        }
-        return super.getStyleBindingForValue(bindingValue);
-    }
-
-    @Override
-    public BindingValue getVisibilityBindingForValue(BindingValue bindingValue) {
-        BindingValue genericBindingResult = getGenericBindingForValue(bindingValue);
-
-        if (genericBindingResult != null) {
-            return genericBindingResult;
-        }
-
-        if (mHostBindingProvider != null) {
-            return mHostBindingProvider.getVisibilityBindingForValue(bindingValue);
-        }
-
-        return super.getVisibilityBindingForValue(bindingValue);
-    }
-
-    /**
-     * Gets a {@link BindingValue} that supports multiple separate types. IE, Visibility or Style
-     * bindings. Returns {@literal null} if no generic binding can be found.
-     */
-    @Nullable
-    private BindingValue getGenericBindingForValue(BindingValue bindingValue) {
-        HostBindingData hostBindingData = bindingValue.getHostBindingData();
-
-        if (hostBindingData.hasExtension(OfflineExtension.offlineExtension)) {
-            BindingValue result = getBindingForOfflineExtension(
-                    hostBindingData.getExtension(OfflineExtension.offlineExtension));
-            if (result != null) {
-                return result;
-            }
-        }
-
-        return null;
-    }
-
-    @Nullable
-    private BindingValue getBindingForOfflineExtension(OfflineExtension offlineExtension) {
-        if (!offlineExtension.hasUrl()) {
-            Logger.e(TAG, "No URL for OfflineExtension, return clear.");
-            return null;
-        }
-
-        return mOfflineMonitor.isAvailableOffline(offlineExtension.getUrl())
-                ? offlineExtension.getOfflineBinding()
-                : offlineExtension.getNotOfflineBinding();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietImageLoader.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietImageLoader.java
deleted file mode 100644
index c49755aa..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietImageLoader.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.piet;
-
-import android.graphics.drawable.Drawable;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.imageloader.ImageLoaderApi;
-import org.chromium.chrome.browser.feed.library.piet.host.ImageLoader;
-import org.chromium.components.feed.core.proto.ui.piet.ImagesProto.Image;
-import org.chromium.components.feed.core.proto.ui.piet.ImagesProto.ImageSource;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
-
-/** A Piet {@link ImageLoader} which uses {@link ImageLoaderApi} to load images. */
-public class PietImageLoader implements ImageLoader {
-    private final ImageLoaderApi mImageLoaderApi;
-
-    @Inject
-    public PietImageLoader(ImageLoaderApi imageLoaderApi) {
-        this.mImageLoaderApi = imageLoaderApi;
-    }
-
-    @Override
-    public void getImage(Image image, int widthPx, int heightPx, Consumer<Drawable> consumer) {
-        List<String> urls = new ArrayList<>(image.getSourcesList().size());
-        for (ImageSource source : image.getSourcesList()) {
-            urls.add(source.getUrl());
-        }
-
-        mImageLoaderApi.loadDrawable(urls, widthPx, heightPx, consumer);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietRequiredContentAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietRequiredContentAdapter.java
deleted file mode 100644
index 34eba40..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietRequiredContentAdapter.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.piet;
-
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.RequiredContentAdapter;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.Content;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.PietContent;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-import org.chromium.components.feed.core.proto.wire.DataOperationProto.DataOperation;
-import org.chromium.components.feed.core.proto.wire.DataOperationProto.DataOperation.Operation;
-
-import java.util.Collections;
-import java.util.List;
-
-/** Implementation of {@link RequiredContentAdapter} that identifies dependent PietSharedStates. */
-public final class PietRequiredContentAdapter implements RequiredContentAdapter {
-    @Override
-    public List<ContentId> determineRequiredContentIds(DataOperation dataOperation) {
-        if (dataOperation.getOperation() != Operation.UPDATE_OR_APPEND) {
-            return Collections.emptyList();
-        }
-
-        return dataOperation.getFeature()
-                .getExtension(Content.contentExtension)
-                .getExtension(PietContent.pietContentExtension)
-                .getPietSharedStatesList();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietStringFormatter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietStringFormatter.java
deleted file mode 100644
index e37c8cf..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietStringFormatter.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.piet;
-
-import android.text.format.DateUtils;
-
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.piet.host.StringFormatter;
-
-import javax.inject.Inject;
-
-/** Formats strings for Piet. */
-public class PietStringFormatter implements StringFormatter {
-    private final Clock mClock;
-
-    @Inject
-    public PietStringFormatter(Clock clock) {
-        this.mClock = clock;
-    }
-
-    @Override
-    public String getRelativeElapsedString(long elapsedTimeMillis) {
-        return DateUtils
-                .getRelativeTimeSpanString(mClock.currentTimeMillis() - elapsedTimeMillis,
-                        mClock.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS)
-                .toString();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/menumeasurer/MenuMeasurer.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/menumeasurer/MenuMeasurer.java
deleted file mode 100644
index c974ac0..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/menumeasurer/MenuMeasurer.java
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.publicapi.menumeasurer;
-
-import android.content.Context;
-import android.view.View;
-import android.view.View.MeasureSpec;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ListAdapter;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Makes measurements for a Menu based on an {@link ArrayAdapter}. */
-public class MenuMeasurer {
-    public static final int NO_MAX_HEIGHT = Integer.MAX_VALUE;
-    public static final int NO_MAX_WIDTH = Integer.MAX_VALUE;
-    private static final String TAG = "MenuMeasurer";
-
-    private final Context mContext;
-
-    public MenuMeasurer(Context context) {
-        this.mContext = context;
-    }
-
-    // TODO: Test measureAdapterContent fully instead of just calculateSize.
-    public Size measureAdapterContent(
-            ViewGroup parent, ListAdapter adapter, int windowPadding, int maxWidth, int maxHeight) {
-        return calculateSize(getMeasurements(parent, adapter), windowPadding, maxWidth, maxHeight);
-    }
-
-    private List<Size> getMeasurements(ViewGroup parent, ListAdapter adapter) {
-        ArrayList<Size> measurements = new ArrayList<>(adapter.getCount());
-        int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        View view = null;
-        for (int i = 0; i < adapter.getCount(); i++) {
-            view = getViewFromAdapter(adapter, i, view, parent);
-            view.measure(widthMeasureSpec, heightMeasureSpec);
-            measurements.add(new Size(view.getMeasuredWidth(), view.getMeasuredHeight()));
-        }
-        return measurements;
-    }
-
-    @VisibleForTesting
-    Size calculateSize(List<Size> measuredSizes, int windowPadding, int maxWidth, int maxHeight) {
-        int largestWidth = 0;
-        int totalHeight = 0;
-        for (Size size : measuredSizes) {
-            int itemWidth = size.getWidth();
-            totalHeight += size.getHeight();
-
-            if (itemWidth > largestWidth) {
-                largestWidth = itemWidth;
-            }
-        }
-
-        int widthUnit = mContext.getResources().getDimensionPixelSize(R.dimen.menu_width_multiple);
-
-        int width = Math.min(roundLargestPopupContentWidth(largestWidth, widthUnit),
-                maxWidth - windowPadding - windowPadding);
-        return new Size(width, Math.min(totalHeight + windowPadding + windowPadding, maxHeight));
-    }
-
-    /**
-     * Given the {@code largestWidth} of members of popup content and the {@code widthUnit}, returns
-     * the smallest multiple of {@code widthUnit} that is at least as large as {@code largestWidth}.
-     */
-    private int roundLargestPopupContentWidth(int largestWidth, int widthUnit) {
-        return Math.round((((float) largestWidth / (float) widthUnit) + 0.5f)) * widthUnit;
-    }
-
-    /** Minimal method to suppress an incorrect nullness error. */
-    @SuppressWarnings("nullness:argument.type.incompatible")
-    private View getViewFromAdapter(
-            ListAdapter arrayAdapter, int index, @Nullable View convertView, ViewGroup parentView) {
-        return arrayAdapter.getView(index, convertView, parentView);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/menumeasurer/Size.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/menumeasurer/Size.java
deleted file mode 100644
index 4faeb68f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/menumeasurer/Size.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.publicapi.menumeasurer;
-
-import androidx.annotation.Nullable;
-
-/**
- * Class to represent the width and height of a view in pixels. This is a minimal version of {@link
- * android.util.Size} which is only available in API 21.
- */
-public class Size {
-    private final int mWidth;
-    private final int mHeight;
-
-    public Size(int width, int height) {
-        this.mWidth = width;
-        this.mHeight = height;
-    }
-
-    /** Gets the width of the size in pixels. */
-    public int getWidth() {
-        return mWidth;
-    }
-
-    /** Gets the height of the size in pixels. */
-    public int getHeight() {
-        return mHeight;
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof Size)) {
-            return false;
-        }
-
-        Size size = (Size) o;
-
-        return mWidth == size.mWidth && mHeight == size.mHeight;
-    }
-
-    @Override
-    public int hashCode() {
-        return 31 * mWidth + mHeight;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/scroll/ScrollObservable.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/scroll/ScrollObservable.java
deleted file mode 100644
index a1b5f21..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/scroll/ScrollObservable.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll;
-
-/** Interface to register for scroll events. */
-public interface ScrollObservable {
-    /** Adds an observer for listening to future scroll events. */
-    void addScrollObserver(ScrollObserver observer);
-
-    /** Removes the specified observer from listening to scroll events. */
-    void removeScrollObserver(ScrollObserver observer);
-
-    /** Provides the current scroll state of the monitor. */
-    int getCurrentScrollState();
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/scroll/ScrollObserver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/scroll/ScrollObserver.java
deleted file mode 100644
index b55e84b3..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/scroll/ScrollObserver.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll;
-
-import android.view.View;
-
-/** Observer which gets notified about scroll events. */
-public interface ScrollObserver {
-    /**
-     * Callback with the new state of the scrollable container.
-     *
-     * @param view the view being scrolled.
-     * @param featureId the id of the view where the scroll originated from; optional.
-     * @param newState one of the RecyclerView SCROLLING_STATE_fields.
-     * @param timestamp the time in ms when the scroll state change occurred.
-     */
-    default void onScrollStateChanged(View view, String featureId, int newState, long timestamp) {}
-
-    /**
-     * Callback with the change in x/y from the most recent scroll events.
-     *
-     * @param view the view being scrolled.
-     * @param featureId the id of the view where the scroll originated from; optional.
-     * @param dx the amount scrolled in the x direction.
-     * @param dy the amount scrolled in the y direction.
-     */
-    void onScroll(View view, String featureId, int dx, int dy);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/removetrackingfactory/StreamRemoveTrackingFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/removetrackingfactory/StreamRemoveTrackingFactory.java
deleted file mode 100644
index 203600c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/removetrackingfactory/StreamRemoveTrackingFactory.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.removetrackingfactory;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.ContentRemoval;
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.internal.knowncontent.FeedKnownContent;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider.RemoveTrackingFactory;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.RemoveTracking;
-
-/** {@link RemoveTrackingFactory} to notify host of removed content. */
-public class StreamRemoveTrackingFactory implements RemoveTrackingFactory<ContentRemoval> {
-    private final ModelProvider mModelProvider;
-    private final FeedKnownContent mFeedKnownContent;
-
-    public StreamRemoveTrackingFactory(
-            ModelProvider modelProvider, FeedKnownContent feedKnownContent) {
-        this.mModelProvider = modelProvider;
-        this.mFeedKnownContent = feedKnownContent;
-    }
-
-    @Nullable
-    @Override
-    public RemoveTracking<ContentRemoval> create(MutationContext mutationContext) {
-        String requestingSessionId = mutationContext.getRequestingSessionId();
-        if (requestingSessionId == null) {
-            return null;
-        }
-
-        // Only notify host on the StreamScope that requested the dismiss.
-        if (!requestingSessionId.equals(mModelProvider.getSessionId())) {
-            return null;
-        }
-
-        return new RemoveTracking<>(
-                streamFeature
-                -> {
-                    if (!streamFeature.getContent().getRepresentationData().hasUri()) {
-                        return null;
-                    }
-
-                    return new ContentRemoval(
-                            streamFeature.getContent().getRepresentationData().getUri(),
-                            mutationContext.isUserInitiated());
-                },
-                removedContent
-                -> mFeedKnownContent.getKnownContentHostNotifier().onContentRemoved(
-                        removedContent));
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/PietScrollObserver.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/PietScrollObserver.java
deleted file mode 100644
index e9d10d6..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/PietScrollObserver.java
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.scroll;
-
-import android.view.View;
-import android.view.View.OnAttachStateChangeListener;
-import android.view.ViewTreeObserver.OnGlobalLayoutListener;
-
-import androidx.recyclerview.widget.RecyclerView;
-
-import org.chromium.chrome.browser.feed.library.piet.FrameAdapter;
-import org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll.ScrollObservable;
-import org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll.ScrollObserver;
-
-/** Scroll observer that triggers Piet scroll actions. */
-public class PietScrollObserver implements ScrollObserver {
-    private final FrameAdapter mFrameAdapter;
-    private final View mViewport;
-    private final ScrollObservable mScrollObservable;
-    private final FirstDrawTrigger mFirstDrawTrigger;
-
-    /**
-     * Construct a PietScrollObserver.
-     *
-     * @param frameAdapter Piet FrameAdapter which will have view actions triggered by this scroll
-     *     observer
-     * @param viewport the view containing the frameAdapter, the bounds of which determine whether
-     *         the
-     *     frame is visible
-     * @param scrollObservable used to get the scroll state to ensure scrolling is idle before
-     *     triggering
-     */
-    @SuppressWarnings("initialization") // Doesn't like the OnAttachStateChangeListener.
-    public PietScrollObserver(
-            FrameAdapter frameAdapter, View viewport, ScrollObservable scrollObservable) {
-        this.mFrameAdapter = frameAdapter;
-        this.mViewport = viewport;
-        this.mScrollObservable = scrollObservable;
-
-        mFirstDrawTrigger = new FirstDrawTrigger();
-
-        frameAdapter.getFrameContainer().addOnAttachStateChangeListener(
-                new OnAttachStateChangeListener() {
-                    @Override
-                    public void onViewAttachedToWindow(View view) {
-                        installFirstDrawTrigger();
-                    }
-
-                    @Override
-                    public void onViewDetachedFromWindow(View view) {
-                        uninstallFirstDrawTrigger();
-                    }
-                });
-    }
-
-    @Override
-    public void onScrollStateChanged(View view, String featureId, int newState, long timestamp) {
-        // There was logic in here previously ensuring that the state had changed; however, you can
-        // have a case where the feed is idle and you fling the feed, and it goes to idle again
-        // without triggering the observer during scrolling. Just triggering this every time the
-        // feed comes to rest appears to have the desired behavior. We can think about also
-        // triggering while the feed is scrolling; not sure how frequently the observer triggers
-        // during scroll.
-        if (newState == RecyclerView.SCROLL_STATE_IDLE) {
-            mFrameAdapter.triggerViewActions(mViewport);
-        }
-    }
-
-    @Override
-    public void onScroll(View view, String featureId, int dx, int dy) {
-        // no-op
-    }
-
-    /** Install the first-draw triggering observer. */
-    public void installFirstDrawTrigger() {
-        mFrameAdapter.getFrameContainer().getViewTreeObserver().addOnGlobalLayoutListener(
-                mFirstDrawTrigger);
-    }
-
-    /** Uninstall the first-draw triggering observer. */
-    public void uninstallFirstDrawTrigger() {
-        mFrameAdapter.getFrameContainer().getViewTreeObserver().removeOnGlobalLayoutListener(
-                mFirstDrawTrigger);
-    }
-
-    class FirstDrawTrigger implements OnGlobalLayoutListener {
-        @Override
-        public void onGlobalLayout() {
-            uninstallFirstDrawTrigger();
-
-            if (mScrollObservable.getCurrentScrollState() == RecyclerView.SCROLL_STATE_IDLE) {
-                mFrameAdapter.triggerViewActions(mViewport);
-            }
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollEvents.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollEvents.java
deleted file mode 100644
index d0a183735..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollEvents.java
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-package org.chromium.chrome.browser.feed.library.sharedstream.scroll;
-
-/** Events for scrolling. */
-public interface ScrollEvents {
-    /**
-     * Notifies of the delta change of the scroll action and the ms timestamp of when the action
-     * finished.
-     */
-    void onScrollEvent(int scrollAmount, long scrollEndTimestampMs);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollListenerNotifier.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollListenerNotifier.java
deleted file mode 100644
index 33572e18..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollListenerNotifier.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.scroll;
-
-import static org.chromium.chrome.browser.feed.shared.stream.Stream.ScrollListener.UNKNOWN_SCROLL_DELTA;
-
-import android.view.View;
-
-import androidx.recyclerview.widget.RecyclerView;
-
-import org.chromium.base.ObserverList;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll.ScrollObservable;
-import org.chromium.chrome.browser.feed.library.sharedstream.publicapi.scroll.ScrollObserver;
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ContentChangedListener;
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ScrollListener;
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ScrollListener.ScrollState;
-
-/** Class which monitors scrolls and notifies listeners on changes. */
-public class ScrollListenerNotifier implements ScrollObserver {
-    private static final String TAG = "StreamScrollMonitor";
-
-    private final MainThreadRunner mMainThreadRunner;
-    private final ObserverList<ScrollListener> mScrollListeners;
-    private final ContentChangedListener mContentChangedListener;
-
-    // Doesn't like adding itself to the scrollobservable
-    @SuppressWarnings("initialization")
-    public ScrollListenerNotifier(ContentChangedListener childChangeListener,
-            ScrollObservable scrollObservable, MainThreadRunner mainThreadRunner) {
-        this.mContentChangedListener = childChangeListener;
-        this.mMainThreadRunner = mainThreadRunner;
-
-        mScrollListeners = new ObserverList<ScrollListener>();
-
-        scrollObservable.addScrollObserver(this);
-    }
-
-    public void addScrollListener(ScrollListener listener) {
-        mScrollListeners.addObserver(listener);
-    }
-
-    public void removeScrollListener(ScrollListener listener) {
-        mScrollListeners.removeObserver(listener);
-    }
-
-    /**
-     * Should be called if a programmatic scroll of the RecyclerView is done. Will notify host with
-     * appropriate deltas.
-     */
-    public void onProgrammaticScroll(RecyclerView recyclerView) {
-        mMainThreadRunner.execute(TAG + " onProgrammaticScroll", () -> {
-            // Post scroll as this allows users of scroll to retrieve new heights/widths of change.
-            onScroll(recyclerView, "", UNKNOWN_SCROLL_DELTA, UNKNOWN_SCROLL_DELTA);
-        });
-    }
-
-    @ScrollState
-    public static int convertRecyclerViewScrollStateToListenerState(int state) {
-        switch (state) {
-            case RecyclerView.SCROLL_STATE_DRAGGING:
-                return ScrollState.DRAGGING;
-            case RecyclerView.SCROLL_STATE_SETTLING:
-                return ScrollState.SETTLING;
-            case RecyclerView.SCROLL_STATE_IDLE:
-                return ScrollState.IDLE;
-            default:
-                Logger.wtf(TAG, "Invalid recycler view scroll state: %d", state);
-                return ScrollState.IDLE;
-        }
-    }
-
-    @Override
-    public void onScrollStateChanged(View view, String featureId, int newState, long timestamp) {
-        if (newState == RecyclerView.SCROLL_STATE_IDLE) {
-            mContentChangedListener.onContentChanged();
-        }
-
-        int scrollState = convertRecyclerViewScrollStateToListenerState(newState);
-        for (ScrollListener scrollListener : mScrollListeners) {
-            scrollListener.onScrollStateChanged(scrollState);
-        }
-    }
-
-    @Override
-    public void onScroll(View view, String featureId, int dx, int dy) {
-        for (ScrollListener scrollListener : mScrollListeners) {
-            scrollListener.onScrolled(dx, dy);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollLogger.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollLogger.java
deleted file mode 100644
index 3441019c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollLogger.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-package org.chromium.chrome.browser.feed.library.sharedstream.scroll;
-
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ScrollType;
-
-/** */
-public class ScrollLogger {
-    private final BasicLoggingApi mApi;
-    // We don't want to log scrolls that are tiny since the user probably didn't mean to actually
-    // scroll.
-    private static final int SCROLL_TOLERANCE = 10;
-
-    public ScrollLogger(BasicLoggingApi api) {
-        this.mApi = api;
-    }
-    /** Handles logging of scrolling. */
-    public void handleScroll(@ScrollType int scrollType, int scrollAmount) {
-        if (Math.abs(scrollAmount) <= SCROLL_TOLERANCE) {
-            return;
-        }
-        mApi.onScroll(scrollType, scrollAmount);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollRestoreHelper.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollRestoreHelper.java
deleted file mode 100644
index a8b8ec8..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollRestoreHelper.java
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.sharedstream.scroll;
-
-import android.view.View;
-
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.feed.library.common.logging.Logger;
-import org.chromium.components.feed.core.proto.libraries.sharedstream.ScrollStateProto.ScrollState;
-
-/** Helper for restoring scroll positions. */
-public class ScrollRestoreHelper {
-    private static final String TAG = "ScrollUtils";
-    private static final boolean ABANDON_RESTORE_BELOW_FOLD_DEFAULT = true;
-    private static final long ABANDON_RESTORE_BELOW_FOLD_THRESHOLD_DEFAULT = 10L;
-
-    /** Private constructor to prevent instantiation. */
-    private ScrollRestoreHelper() {}
-
-    /**
-     * Returns a {@link ScrollState} for scroll position restore, or {@literal null} if the scroll
-     * position can't or shouldn't be restored.
-     *
-     * @param currentHeaderCount The amount of headers which appear before Stream content.
-     */
-    @Nullable
-    public static ScrollState getScrollStateForScrollRestore(LinearLayoutManager layoutManager,
-            Configuration configuration, int currentHeaderCount) {
-        int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
-        View firstVisibleView = layoutManager.findViewByPosition(firstVisibleItemPosition);
-        int firstVisibleTop =
-                firstVisibleView == null ? RecyclerView.NO_POSITION : firstVisibleView.getTop();
-        int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();
-
-        return getScrollStateForScrollRestore(firstVisibleItemPosition, firstVisibleTop,
-                lastVisibleItemPosition, configuration, currentHeaderCount);
-    }
-
-    @Nullable
-    public static ScrollState getScrollStateForScrollRestore(int firstVisibleItemPosition,
-            int firstVisibleTop, int lastVisibleItemPosition, Configuration configuration,
-            int currentHeaderCount) {
-        // If either of the firstVisibleItemPosition or firstVisibleTop are unknown, we shouldn't
-        // restore scroll, so return null.
-        if (firstVisibleItemPosition == RecyclerView.NO_POSITION
-                || firstVisibleTop == RecyclerView.NO_POSITION) {
-            return null;
-        }
-
-        // Determine if we can restore past the fold.
-        if (configuration.getValueOrDefault(
-                    ConfigKey.ABANDON_RESTORE_BELOW_FOLD, ABANDON_RESTORE_BELOW_FOLD_DEFAULT)) {
-            long threshold =
-                    configuration.getValueOrDefault(ConfigKey.ABANDON_RESTORE_BELOW_FOLD_THRESHOLD,
-                            ABANDON_RESTORE_BELOW_FOLD_THRESHOLD_DEFAULT);
-
-            if (lastVisibleItemPosition == RecyclerView.NO_POSITION
-                    || lastVisibleItemPosition - currentHeaderCount > threshold) {
-                Logger.w(TAG,
-                        "Abandoning scroll due to fold threshold.  Bottom scroll index: %d, Header "
-                                + "count: %d, Configured Threshold: %d",
-                        lastVisibleItemPosition, currentHeaderCount, threshold);
-                return null;
-            }
-        }
-
-        return ScrollState.newBuilder()
-                .setPosition(firstVisibleItemPosition)
-                .setOffset(firstVisibleTop)
-                .build();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/actionmanager/FakeActionReader.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/actionmanager/FakeActionReader.java
deleted file mode 100644
index e8340f4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/actionmanager/FakeActionReader.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.actionmanager;
-
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ActionReader;
-import org.chromium.chrome.browser.feed.library.api.internal.common.DismissActionWithSemanticProperties;
-import org.chromium.chrome.browser.feed.library.common.Result;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/** Fake implementation of {@link ActionReader}. */
-public final class FakeActionReader implements ActionReader {
-    private final ArrayList<DismissActionWithSemanticProperties> mDismissActions =
-            new ArrayList<>();
-
-    @Override
-    public Result<List<DismissActionWithSemanticProperties>>
-    getDismissActionsWithSemanticProperties() {
-        return Result.success(mDismissActions);
-    }
-
-    /** Adds a dismiss action with semantic properties. */
-    public FakeActionReader addDismissActionsWithSemanticProperties(
-            DismissActionWithSemanticProperties... dismissActionsToAdd) {
-        Collections.addAll(mDismissActions, dismissActionsToAdd);
-        return this;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/actionmanager/FakeViewActionManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/actionmanager/FakeViewActionManager.java
deleted file mode 100644
index 2dae7bef..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/actionmanager/FakeViewActionManager.java
+++ /dev/null
@@ -1,72 +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.
-
-package org.chromium.chrome.browser.feed.library.testing.actionmanager;
-
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ViewActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.api.internal.store.UploadableActionMutation;
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ScrollListener;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-import org.chromium.components.feed.core.proto.wire.ActionPayloadProto.ActionPayload;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/** Fake implementation of {@link ViewActionManager}. */
-public final class FakeViewActionManager implements ViewActionManager {
-    private final Store mStore;
-    public final Set<StreamUploadableAction> mViewActions = new HashSet<>();
-
-    public FakeViewActionManager(Store store) {
-        mStore = store;
-    }
-
-    @Override
-    public void setViewport(@Nullable View viewport) {}
-
-    @Override
-    public void onViewVisible(View view, String contentId, ActionPayload actionPayload) {}
-
-    @Override
-    public void onViewHidden(View view, String contentId) {}
-
-    @Override
-    public ScrollListener getScrollListener() {
-        return new ScrollListener() {
-            @Override
-            public void onScrollStateChanged(int state) {}
-
-            @Override
-            public void onScrolled(int dx, int dy) {}
-        };
-    }
-
-    @Override
-    public void onAnimationFinished() {}
-
-    @Override
-    public void onLayoutChange() {}
-
-    @Override
-    public void onShow() {}
-
-    @Override
-    public void onHide() {}
-
-    @Override
-    public void storeViewActions(Runnable runnable) {
-        UploadableActionMutation actionMutation = mStore.editUploadableActions();
-        for (StreamUploadableAction action : mViewActions) {
-            actionMutation.upsert(action, action.getFeatureContentId());
-        }
-        CommitResult commitResult = actionMutation.commit();
-        runnable.run();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/android/LinearLayoutManagerForTest.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/android/LinearLayoutManagerForTest.java
deleted file mode 100644
index 8976563..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/android/LinearLayoutManagerForTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.android;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-
-import android.content.Context;
-import android.view.View;
-
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/** A {@link LinearLayoutManager} used for testing. */
-public final class LinearLayoutManagerForTest extends LinearLayoutManager {
-    private final Map<Integer, View> mChildMap;
-
-    public int firstVisibleItemPosition = RecyclerView.NO_POSITION;
-    public int firstVisibleViewOffset;
-
-    public int lastVisibleItemPosition = RecyclerView.NO_POSITION;
-
-    public int scrolledPosition;
-    public int scrolledOffset;
-
-    public LinearLayoutManagerForTest(Context context) {
-        super(context);
-        this.mChildMap = new HashMap<>();
-    }
-
-    @Override
-    public int findFirstVisibleItemPosition() {
-        return firstVisibleItemPosition;
-    }
-
-    @Override
-    public int findLastVisibleItemPosition() {
-        return lastVisibleItemPosition;
-    }
-
-    @Override
-    public View findViewByPosition(int position) {
-        if (mChildMap.containsKey(position)) {
-            return checkNotNull(mChildMap.get(position),
-                    "addChildToPosition(int position, View child) should be called prior to "
-                            + "findViewByPosition(int position).");
-        }
-        return super.findViewByPosition(position);
-    }
-
-    @Override
-    public void scrollToPositionWithOffset(int scrollPosition, int scrollOffset) {
-        scrolledPosition = scrollPosition;
-        scrolledOffset = scrollOffset;
-    }
-
-    public void addChildToPosition(int position, View child) {
-        mChildMap.put(position, child);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/network/NetworkClientConformanceTest.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/network/NetworkClientConformanceTest.java
deleted file mode 100644
index 2100a65..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/network/NetworkClientConformanceTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.conformance.network;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.net.Uri;
-
-import org.junit.Test;
-
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest.HttpMethod;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpResponse;
-import org.chromium.chrome.browser.feed.library.api.host.network.NetworkClient;
-import org.chromium.chrome.browser.feed.library.common.testing.RequiredConsumer;
-
-import java.util.Collections;
-
-public abstract class NetworkClientConformanceTest {
-    protected NetworkClient mNetworkClient;
-
-    /** Defines a valid URI for the provided method. */
-    protected Uri getValidUri(@HttpMethod String httpMethod) {
-        return new Uri.Builder().path("http://www.google.com/").build();
-    }
-
-    /** Allows conformance tests to delay assertions until after the request completes. */
-    protected void waitForRequest() {}
-
-    @Test
-    public void send_get() {
-        @HttpMethod
-        String method = HttpMethod.GET;
-        HttpRequest request = new HttpRequest(
-                getValidUri(method), method, Collections.emptyList(), new byte[] {});
-        RequiredConsumer<HttpResponse> responseConsumer = new RequiredConsumer<>(response -> {
-            assertThat(response.getResponseBody()).isNotNull();
-            assertThat(response.getResponseCode()).isNotNull();
-        });
-
-        mNetworkClient.send(request, responseConsumer);
-        waitForRequest();
-        assertThat(responseConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void send_post() {
-        @HttpMethod
-        String method = HttpMethod.POST;
-        HttpRequest request = new HttpRequest(
-                getValidUri(method), method, Collections.emptyList(), "helloWorld".getBytes());
-        RequiredConsumer<HttpResponse> responseConsumer = new RequiredConsumer<>(response -> {
-            assertThat(response.getResponseBody()).isNotNull();
-            assertThat(response.getResponseCode()).isNotNull();
-        });
-
-        mNetworkClient.send(request, responseConsumer);
-        waitForRequest();
-        assertThat(responseConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void send_put() {
-        @HttpMethod
-        String method = HttpMethod.PUT;
-        HttpRequest request = new HttpRequest(
-                getValidUri(method), method, Collections.emptyList(), "helloWorld".getBytes());
-        RequiredConsumer<HttpResponse> responseConsumer = new RequiredConsumer<>(response -> {
-            assertThat(response.getResponseBody()).isNotNull();
-            assertThat(response.getResponseCode()).isNotNull();
-        });
-
-        mNetworkClient.send(request, responseConsumer);
-        waitForRequest();
-        assertThat(responseConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void send_delete() {
-        @HttpMethod
-        String method = HttpMethod.DELETE;
-        HttpRequest request = new HttpRequest(
-                getValidUri(method), method, Collections.emptyList(), new byte[] {});
-        RequiredConsumer<HttpResponse> responseConsumer = new RequiredConsumer<>(response -> {
-            assertThat(response.getResponseBody()).isNotNull();
-            assertThat(response.getResponseCode()).isNotNull();
-        });
-
-        mNetworkClient.send(request, responseConsumer);
-        waitForRequest();
-        assertThat(responseConsumer.isCalled()).isTrue();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/scheduler/SchedulerConformanceTest.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/scheduler/SchedulerConformanceTest.java
deleted file mode 100644
index 615884b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/scheduler/SchedulerConformanceTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.conformance.scheduler;
-
-import org.junit.Test;
-
-import org.chromium.base.test.UiThreadTest;
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi;
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi.SessionState;
-
-public abstract class SchedulerConformanceTest {
-    private static final int NOT_FOUND = 404;
-    private static final int SERVER_ERROR = 500;
-
-    protected SchedulerApi mScheduler;
-
-    @Test
-    @UiThreadTest
-    public void shouldSessionRequestData() {
-        // Should not throw error
-        mScheduler.shouldSessionRequestData(new SessionState(false, 0, false));
-    }
-
-    @Test
-    @UiThreadTest
-    public void onReceiveNewContent() {
-        // Should not throw error
-        mScheduler.onReceiveNewContent(System.currentTimeMillis());
-    }
-
-    @Test
-    @UiThreadTest
-    public void onRequestError_notFound() {
-        // Should not throw error
-        mScheduler.onRequestError(NOT_FOUND);
-    }
-
-    @Test
-    @UiThreadTest
-    public void onRequestError_serverError() {
-        // Should not throw error
-        mScheduler.onRequestError(SERVER_ERROR);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/ContentStorageConformanceTest.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/ContentStorageConformanceTest.java
deleted file mode 100644
index 5401664..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/ContentStorageConformanceTest.java
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.conformance.storage;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Build;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.test.util.DisableIf;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorage;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.testing.RequiredConsumer;
-
-import java.nio.charset.Charset;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Conformance test for {@link ContentStorage}. Hosts who wish to test against this should extend
- * this class and set {@code storage} to the Host implementation.
- */
-// clang-format off
-@DisableIf.Build(sdk_is_greater_than = Build.VERSION_CODES.N_MR1,
-    sdk_is_less_than = Build.VERSION_CODES.P, message = "https://crbug.com/1091301")
-public abstract class ContentStorageConformanceTest {
-    //clang-format on
-    private static final String KEY = "key";
-    private static final String KEY_0 = KEY + " 0";
-    private static final String KEY_1 = KEY + " 1";
-    private static final String OTHER_KEY = "other";
-    private static final byte[] DATA_0 = "data 0".getBytes(Charset.forName("UTF-8"));
-    private static final byte[] DATA_1 = "data 1".getBytes(Charset.forName("UTF-8"));
-    private static final byte[] OTHER_DATA = "other data".getBytes(Charset.forName("UTF-8"));
-
-    // Helper consumers to make tests cleaner
-    private final Consumer<Result<Map<String, byte[]>>> mIsKey0Data0 = input -> {
-        assertThat(input.isSuccessful()).isTrue();
-        Map<String, byte[]> valueMap = input.getValue();
-        assertThat(valueMap.get(KEY_0)).isEqualTo(DATA_0);
-    };
-    private final Consumer<Result<Map<String, byte[]>>> mIsKey0EmptyData = input -> {
-        assertThat(input.isSuccessful()).isTrue();
-        Map<String, byte[]> valueMap = input.getValue();
-        assertThat(valueMap.get(KEY_0)).isNull();
-    };
-    private final Consumer<Result<Map<String, byte[]>>> mIsKey0Data1 = input -> {
-        assertThat(input.isSuccessful()).isTrue();
-        Map<String, byte[]> valueMap = input.getValue();
-        assertThat(valueMap.get(KEY_0)).isEqualTo(DATA_1);
-    };
-
-    private final Consumer<Result<Map<String, byte[]>>> mIsKey0Data0Key1Data1 = result -> {
-        assertThat(result.isSuccessful()).isTrue();
-        Map<String, byte[]> input = result.getValue();
-        assertThat(input.get(KEY_0)).isEqualTo(DATA_0);
-        assertThat(input.get(KEY_1)).isEqualTo(DATA_1);
-    };
-    private final Consumer<Result<Map<String, byte[]>>> mIsKey0EmptyDataKey1EmptyData = input -> {
-        assertThat(input.isSuccessful()).isTrue();
-        Map<String, byte[]> valueMap = input.getValue();
-        assertThat(valueMap.get(KEY_0)).isNull();
-        assertThat(valueMap.get(KEY_1)).isNull();
-    };
-    private final Consumer<Result<Map<String, byte[]>>>
-            mIsKey0EmptyDataKey1EmptyDataOtherKeyEmptyData = input -> {
-        assertThat(input.isSuccessful()).isTrue();
-        Map<String, byte[]> valueMap = input.getValue();
-        assertThat(valueMap.get(KEY_0)).isNull();
-        assertThat(valueMap.get(KEY_1)).isNull();
-        assertThat(valueMap.get(OTHER_KEY)).isNull();
-    };
-
-    private final Consumer<Result<Map<String, byte[]>>> mIsKey0Data0Key1Data1OtherKeyOtherData =
-            result -> {
-        assertThat(result.isSuccessful()).isTrue();
-        Map<String, byte[]> input = result.getValue();
-        assertThat(input.get(KEY_0)).isEqualTo(DATA_0);
-        assertThat(input.get(KEY_1)).isEqualTo(DATA_1);
-        assertThat(input.get(OTHER_KEY)).isEqualTo(OTHER_DATA);
-    };
-    private final Consumer<Result<Map<String, byte[]>>>
-            mIsKey0EmptyDataKey1EmptyDataOtherKeyOtherData = result -> {
-        assertThat(result.isSuccessful()).isTrue();
-        Map<String, byte[]> input = result.getValue();
-        assertThat(input.get(KEY_0)).isNull();
-        assertThat(input.get(KEY_1)).isNull();
-        assertThat(input.get(OTHER_KEY)).isEqualTo(OTHER_DATA);
-    };
-
-    private final Consumer<CommitResult> mIsSuccess =
-            input -> assertThat(input).isEqualTo(CommitResult.SUCCESS);
-
-    private final Consumer<Result<List<String>>> mIsKey0Key1 = result -> {
-        assertThat(result.isSuccessful()).isTrue();
-        assertThat(result.getValue()).containsExactly(KEY_0, KEY_1);
-    };
-
-    protected ContentStorage mStorage;
-
-    private RequiredConsumer<CommitResult> mAssertSuccessConsumer;
-
-    @Before
-    public final void testSetup() {
-        mAssertSuccessConsumer = new RequiredConsumer<>(mIsSuccess);
-    }
-
-    @Test
-    public void missingKey() {
-        RequiredConsumer<Result<Map<String, byte[]>>> consumer =
-                new RequiredConsumer<>(mIsKey0EmptyData);
-        mStorage.get(Collections.singletonList(KEY_0), consumer);
-        assertThat(consumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void missingKey_multipleKeys() {
-        RequiredConsumer<Result<Map<String, byte[]>>> consumer =
-                new RequiredConsumer<>(mIsKey0EmptyDataKey1EmptyData);
-        mStorage.get(Arrays.asList(KEY_0, KEY_1), consumer);
-        assertThat(consumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void storeAndRetrieve() {
-        mStorage.commit(new ContentMutation.Builder().upsert(KEY_0, DATA_0).build(),
-                mAssertSuccessConsumer);
-        assertThat(mAssertSuccessConsumer.isCalled()).isTrue();
-        RequiredConsumer<Result<Map<String, byte[]>>> byteConsumer =
-                new RequiredConsumer<>(mIsKey0Data0);
-        mStorage.get(Collections.singletonList(KEY_0), byteConsumer);
-        assertThat(byteConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void storeAndRetrieve_multipleKeys() {
-        mStorage.commit(
-                new ContentMutation.Builder().upsert(KEY_0, DATA_0).upsert(KEY_1, DATA_1).build(),
-                mAssertSuccessConsumer);
-        assertThat(mAssertSuccessConsumer.isCalled()).isTrue();
-        RequiredConsumer<Result<Map<String, byte[]>>> byteConsumer =
-                new RequiredConsumer<>(mIsKey0Data0Key1Data1);
-        mStorage.get(Arrays.asList(KEY_0, KEY_1), byteConsumer);
-        assertThat(byteConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void storeAndOverwrite_chained() {
-        mStorage.commit(
-                new ContentMutation.Builder().upsert(KEY_0, DATA_0).upsert(KEY_0, DATA_1).build(),
-                mAssertSuccessConsumer);
-        assertThat(mAssertSuccessConsumer.isCalled()).isTrue();
-        RequiredConsumer<Result<Map<String, byte[]>>> byteConsumer =
-                new RequiredConsumer<>(mIsKey0Data1);
-        mStorage.get(Collections.singletonList(KEY_0), byteConsumer);
-        assertThat(byteConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void storeAndOverwrite_separate() {
-        mStorage.commit(new ContentMutation.Builder().upsert(KEY_0, DATA_0).build(),
-                mAssertSuccessConsumer);
-        assertThat(mAssertSuccessConsumer.isCalled()).isTrue();
-
-        RequiredConsumer<Result<Map<String, byte[]>>> byteConsumer =
-                new RequiredConsumer<>(mIsKey0Data0);
-        mStorage.get(Collections.singletonList(KEY_0), byteConsumer);
-        assertThat(byteConsumer.isCalled()).isTrue();
-
-        // Reset assertSuccessConsumer
-        mAssertSuccessConsumer = new RequiredConsumer<>(
-                input -> { assertThat(input).isEqualTo(CommitResult.SUCCESS); });
-        mStorage.commit(new ContentMutation.Builder().upsert(KEY_0, DATA_1).build(),
-                mAssertSuccessConsumer);
-        assertThat(mAssertSuccessConsumer.isCalled()).isTrue();
-
-        RequiredConsumer<Result<Map<String, byte[]>>> byteConsumer2 =
-                new RequiredConsumer<>(mIsKey0Data1);
-        mStorage.get(Collections.singletonList(KEY_0), byteConsumer2);
-        assertThat(byteConsumer2.isCalled()).isTrue();
-    }
-
-    @Test
-    public void storeAndDelete() {
-        mStorage.commit(
-                new ContentMutation.Builder().upsert(KEY_0, DATA_0).upsert(KEY_1, DATA_1).build(),
-                mAssertSuccessConsumer);
-        assertThat(mAssertSuccessConsumer.isCalled()).isTrue();
-
-        // Confirm Key 0 and 1 are present
-        RequiredConsumer<Result<Map<String, byte[]>>> byteConsumer =
-                new RequiredConsumer<>(mIsKey0Data0Key1Data1);
-        mStorage.get(Arrays.asList(KEY_0, KEY_1), byteConsumer);
-        assertThat(byteConsumer.isCalled()).isTrue();
-
-        // Delete Key 0
-        RequiredConsumer<CommitResult> deleteConsumer = new RequiredConsumer<>(mIsSuccess);
-        mStorage.commit(new ContentMutation.Builder().delete(KEY_0).build(), deleteConsumer);
-        assertThat(deleteConsumer.isCalled()).isTrue();
-
-        // Confirm that Key 0 is deleted and Key 1 is present
-        byteConsumer = new RequiredConsumer<>(mIsKey0EmptyData);
-        mStorage.get(Arrays.asList(KEY_0, KEY_1), byteConsumer);
-        assertThat(byteConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void storeAndDeleteByPrefix() {
-        mStorage.commit(new ContentMutation.Builder()
-                                .upsert(KEY_0, DATA_0)
-                                .upsert(KEY_1, DATA_1)
-                                .upsert(OTHER_KEY, OTHER_DATA)
-                                .build(),
-                mAssertSuccessConsumer);
-        assertThat(mAssertSuccessConsumer.isCalled()).isTrue();
-
-        // Confirm Key 0, Key 1, and Other are present
-        RequiredConsumer<Result<Map<String, byte[]>>> byteConsumer =
-                new RequiredConsumer<>(mIsKey0Data0Key1Data1OtherKeyOtherData);
-        mStorage.get(Arrays.asList(KEY_0, KEY_1, OTHER_KEY), byteConsumer);
-        assertThat(byteConsumer.isCalled()).isTrue();
-
-        // Delete by prefix Key
-        RequiredConsumer<CommitResult> deleteConsumer = new RequiredConsumer<>(mIsSuccess);
-        mStorage.commit(new ContentMutation.Builder().deleteByPrefix(KEY).build(), deleteConsumer);
-
-        // Confirm Key 0 and Key 1 are deleted, and Other is present
-        byteConsumer = new RequiredConsumer<>(mIsKey0EmptyDataKey1EmptyDataOtherKeyOtherData);
-        mStorage.get(Arrays.asList(KEY_0, KEY_1, OTHER_KEY), byteConsumer);
-        assertThat(byteConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void storeAndDeleteAll() {
-        mStorage.commit(new ContentMutation.Builder()
-                                .upsert(KEY_0, DATA_0)
-                                .upsert(KEY_1, DATA_1)
-                                .upsert(OTHER_KEY, OTHER_DATA)
-                                .build(),
-                mAssertSuccessConsumer);
-        assertThat(mAssertSuccessConsumer.isCalled()).isTrue();
-
-        // Confirm Key 0, Key 1, and Other are present
-        RequiredConsumer<Result<Map<String, byte[]>>> byteConsumer =
-                new RequiredConsumer<>(mIsKey0Data0Key1Data1OtherKeyOtherData);
-        mStorage.get(Arrays.asList(KEY_0, KEY_1, OTHER_KEY), byteConsumer);
-        assertThat(byteConsumer.isCalled()).isTrue();
-
-        // Delete all
-        RequiredConsumer<CommitResult> deleteConsumer = new RequiredConsumer<>(mIsSuccess);
-        mStorage.commit(new ContentMutation.Builder().deleteAll().build(), deleteConsumer);
-
-        // Confirm all keys are deleted
-        byteConsumer = new RequiredConsumer<>(mIsKey0EmptyDataKey1EmptyDataOtherKeyEmptyData);
-        mStorage.get(Arrays.asList(KEY_0, KEY_1, OTHER_KEY), byteConsumer);
-        assertThat(byteConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void multipleValues_getAll() {
-        mStorage.commit(
-                new ContentMutation.Builder().upsert(KEY_0, DATA_0).upsert(KEY_1, DATA_1).build(),
-                mAssertSuccessConsumer);
-        assertThat(mAssertSuccessConsumer.isCalled()).isTrue();
-
-        RequiredConsumer<Result<Map<String, byte[]>>> mapConsumer =
-                new RequiredConsumer<>(mIsKey0Data0Key1Data1);
-        mStorage.getAll(KEY, mapConsumer);
-        assertThat(mapConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void multipleValues_getAllKeys() {
-        mStorage.commit(
-                new ContentMutation.Builder().upsert(KEY_0, DATA_0).upsert(KEY_1, DATA_1).build(),
-                mAssertSuccessConsumer);
-        assertThat(mAssertSuccessConsumer.isCalled()).isTrue();
-
-        RequiredConsumer<Result<List<String>>> listConsumer = new RequiredConsumer<>(mIsKey0Key1);
-        mStorage.getAllKeys(listConsumer);
-        assertThat(listConsumer.isCalled()).isTrue();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/ContentStorageDirectConformanceTest.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/ContentStorageDirectConformanceTest.java
deleted file mode 100644
index 690ad782..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/ContentStorageDirectConformanceTest.java
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.conformance.storage;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorageDirect;
-import org.chromium.chrome.browser.feed.library.common.Result;
-
-import java.nio.charset.Charset;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Conformance test for {@link ContentStorage}. Hosts who wish to test against this should extend
- * this class and set {@code storage} to the Host implementation.
- */
-public abstract class ContentStorageDirectConformanceTest {
-    private static final String KEY = "key";
-    private static final String KEY_0 = KEY + " 0";
-    private static final String KEY_1 = KEY + " 1";
-    private static final String OTHER_KEY = "other";
-    private static final byte[] DATA_0 = "data 0".getBytes(Charset.forName("UTF-8"));
-    private static final byte[] DATA_1 = "data 1".getBytes(Charset.forName("UTF-8"));
-    private static final byte[] OTHER_DATA = "other data".getBytes(Charset.forName("UTF-8"));
-
-    protected ContentStorageDirect mStorage;
-
-    @Test
-    public void missingKey() {
-        Result<Map<String, byte[]>> result = mStorage.get(Collections.singletonList(KEY_0));
-        Map<String, byte[]> valueMap = result.getValue();
-        assertThat(valueMap.get(KEY_0)).isNull();
-    }
-
-    @Test
-    public void missingKey_multipleKeys() {
-        Result<Map<String, byte[]>> result = mStorage.get(Arrays.asList(KEY_0, KEY_1));
-        Map<String, byte[]> valueMap = result.getValue();
-        assertThat(valueMap.get(KEY_0)).isNull();
-        assertThat(valueMap.get(KEY_1)).isNull();
-    }
-
-    @Test
-    public void storeAndRetrieve() {
-        CommitResult commitResult =
-                mStorage.commit(new ContentMutation.Builder().upsert(KEY_0, DATA_0).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        Result<Map<String, byte[]>> result = mStorage.get(Collections.singletonList(KEY_0));
-        Map<String, byte[]> input = result.getValue();
-        assertThat(input.get(KEY_0)).isEqualTo(DATA_0);
-    }
-
-    @Test
-    public void storeAndRetrieve_multipleKeys() {
-        CommitResult commitResult = mStorage.commit(
-                new ContentMutation.Builder().upsert(KEY_0, DATA_0).upsert(KEY_1, DATA_1).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        Result<Map<String, byte[]>> result = mStorage.get(Arrays.asList(KEY_0, KEY_1));
-        Map<String, byte[]> input = result.getValue();
-        assertThat(input.get(KEY_0)).isEqualTo(DATA_0);
-        assertThat(input.get(KEY_1)).isEqualTo(DATA_1);
-    }
-
-    @Test
-    public void storeAndOverwrite_chained() {
-        CommitResult commitResult = mStorage.commit(
-                new ContentMutation.Builder().upsert(KEY_0, DATA_0).upsert(KEY_0, DATA_1).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        Result<Map<String, byte[]>> result = mStorage.get(Collections.singletonList(KEY_0));
-        Map<String, byte[]> valueMap = result.getValue();
-        assertThat(valueMap.get(KEY_0)).isEqualTo(DATA_1);
-    }
-
-    @Test
-    public void storeAndOverwrite_separate() {
-        CommitResult commitResult =
-                mStorage.commit(new ContentMutation.Builder().upsert(KEY_0, DATA_0).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        Result<Map<String, byte[]>> result = mStorage.get(Collections.singletonList(KEY_0));
-        Map<String, byte[]> valueMap = result.getValue();
-        assertThat(valueMap.get(KEY_0)).isEqualTo(DATA_0);
-
-        commitResult = mStorage.commit(new ContentMutation.Builder().upsert(KEY_0, DATA_1).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        result = mStorage.get(Collections.singletonList(KEY_0));
-        valueMap = result.getValue();
-        assertThat(valueMap.get(KEY_0)).isEqualTo(DATA_1);
-    }
-
-    @Test
-    public void storeAndDelete() {
-        CommitResult commitResult = mStorage.commit(
-                new ContentMutation.Builder().upsert(KEY_0, DATA_0).upsert(KEY_1, DATA_1).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        // Confirm Key 0 and 1 are present
-        Result<Map<String, byte[]>> result = mStorage.get(Arrays.asList(KEY_0, KEY_1));
-        Map<String, byte[]> input = result.getValue();
-        assertThat(input.get(KEY_0)).isEqualTo(DATA_0);
-        assertThat(input.get(KEY_1)).isEqualTo(DATA_1);
-
-        // Delete Key 0
-        commitResult = mStorage.commit(new ContentMutation.Builder().delete(KEY_0).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        // Confirm that Key 0 is deleted and Key 1 is present
-        Result<Map<String, byte[]>> result2 = mStorage.get(Arrays.asList(KEY_0, KEY_1));
-        Map<String, byte[]> valueMap = result2.getValue();
-        assertThat(valueMap.get(KEY_0)).isNull();
-    }
-
-    @Test
-    public void storeAndDeleteByPrefix() {
-        CommitResult commitResult = mStorage.commit(new ContentMutation.Builder()
-                                                            .upsert(KEY_0, DATA_0)
-                                                            .upsert(KEY_1, DATA_1)
-                                                            .upsert(OTHER_KEY, OTHER_DATA)
-                                                            .build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        // Confirm Key 0, Key 1, and Other are present
-        Result<Map<String, byte[]>> result = mStorage.get(Arrays.asList(KEY_0, KEY_1, OTHER_KEY));
-        Map<String, byte[]> valueMap = result.getValue();
-        assertThat(valueMap.get(KEY_0)).isEqualTo(DATA_0);
-        assertThat(valueMap.get(KEY_1)).isEqualTo(DATA_1);
-        assertThat(valueMap.get(OTHER_KEY)).isEqualTo(OTHER_DATA);
-
-        // Delete by prefix Key
-        commitResult = mStorage.commit(new ContentMutation.Builder().deleteByPrefix(KEY).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        // Confirm Key 0 and Key 1 are deleted, and Other is present
-        result = mStorage.get(Arrays.asList(KEY_0, KEY_1, OTHER_KEY));
-        valueMap = result.getValue();
-        assertThat(valueMap.get(KEY_0)).isNull();
-        assertThat(valueMap.get(KEY_1)).isNull();
-        assertThat(valueMap.get(OTHER_KEY)).isEqualTo(OTHER_DATA);
-    }
-
-    @Test
-    public void storeAndDeleteAll() {
-        CommitResult commitResult = mStorage.commit(new ContentMutation.Builder()
-                                                            .upsert(KEY_0, DATA_0)
-                                                            .upsert(KEY_1, DATA_1)
-                                                            .upsert(OTHER_KEY, OTHER_DATA)
-                                                            .build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        // Confirm Key 0, Key 1, and Other are present
-        Result<Map<String, byte[]>> result = mStorage.get(Arrays.asList(KEY_0, KEY_1, OTHER_KEY));
-        Map<String, byte[]> valueMap = result.getValue();
-        assertThat(valueMap.get(KEY_0)).isEqualTo(DATA_0);
-        assertThat(valueMap.get(KEY_1)).isEqualTo(DATA_1);
-        assertThat(valueMap.get(OTHER_KEY)).isEqualTo(OTHER_DATA);
-
-        // Delete all
-        commitResult = mStorage.commit(new ContentMutation.Builder().deleteAll().build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        // Confirm all keys are deleted
-        result = mStorage.get(Arrays.asList(KEY_0, KEY_1, OTHER_KEY));
-        valueMap = result.getValue();
-        assertThat(valueMap.get(KEY_0)).isNull();
-        assertThat(valueMap.get(KEY_1)).isNull();
-        assertThat(valueMap.get(OTHER_KEY)).isNull();
-    }
-
-    @Test
-    public void multipleValues_getAll() {
-        CommitResult commitResult = mStorage.commit(
-                new ContentMutation.Builder().upsert(KEY_0, DATA_0).upsert(KEY_1, DATA_1).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        Result<Map<String, byte[]>> result = mStorage.getAll(KEY);
-        Map<String, byte[]> input = result.getValue();
-        assertThat(input.get(KEY_0)).isEqualTo(DATA_0);
-        assertThat(input.get(KEY_1)).isEqualTo(DATA_1);
-    }
-
-    @Test
-    public void multipleValues_getAllKeys() {
-        CommitResult commitResult = mStorage.commit(
-                new ContentMutation.Builder().upsert(KEY_0, DATA_0).upsert(KEY_1, DATA_1).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        Result<List<String>> result = mStorage.getAllKeys();
-        assertThat(result.getValue()).containsExactly(KEY_0, KEY_1);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/JournalStorageConformanceTest.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/JournalStorageConformanceTest.java
deleted file mode 100644
index 41bd5f7..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/JournalStorageConformanceTest.java
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.conformance.storage;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Build;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-
-import org.junit.Test;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.test.util.DisableIf;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorage;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.testing.RequiredConsumer;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamLocalAction;
-
-import java.nio.charset.Charset;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Conformance test for {@link JournalStorage}. Hosts who wish to test against this should extend
- * this class and set {@code storage} to the Host implementation.
- */
-// clang-format off
-@DisableIf.Build(sdk_is_greater_than = Build.VERSION_CODES.N_MR1,
-    sdk_is_less_than = Build.VERSION_CODES.P, message = "https://crbug.com/1091301")
-public abstract class JournalStorageConformanceTest {
-    //clank-format on
-    private static final String JOURNAL_NAME = "journal name";
-    private static final String JOURNAL_COPY_NAME = "journal copy name";
-    private static final byte[] DATA_0 = "data 0".getBytes(Charset.forName("UTF-8"));
-    private static final byte[] DATA_1 = "data 1".getBytes(Charset.forName("UTF-8"));
-
-    private final Consumer<Result<List<String>>> mIsJournal1 = result -> {
-        assertThat(result.isSuccessful()).isTrue();
-        List<String> input = result.getValue();
-        assertThat(input).hasSize(1);
-        assertThat(input).contains(JOURNAL_NAME);
-    };
-    private final Consumer<Result<List<String>>> mIsJournal1AndJournal2 = result -> {
-        assertThat(result.isSuccessful()).isTrue();
-        List<String> input = result.getValue();
-        assertThat(input).hasSize(2);
-        assertThat(input).contains(JOURNAL_NAME);
-        assertThat(input).contains(JOURNAL_COPY_NAME);
-    };
-
-    private final Consumer<Result<List<byte[]>>> mIsData0AndData1 = result -> {
-        assertThat(result.isSuccessful()).isTrue();
-        List<byte[]> input = result.getValue();
-        // We should get back one byte array, containing the bytes of DATA_0 and DATA_1.
-        assertThat(input).isNotNull();
-        assertThat(input).hasSize(2);
-        assertThat(Arrays.equals(input.get(0), DATA_0)).isTrue();
-        assertThat(Arrays.equals(input.get(1), DATA_1)).isTrue();
-    };
-    private final Consumer<Result<List<byte[]>>> mIsEmptyList = result -> {
-        assertThat(result.isSuccessful()).isTrue();
-        List<byte[]> input = result.getValue();
-
-        // The result should be an empty List.
-        assertThat(input).isNotNull();
-        assertThat(input).isEmpty();
-    };
-    private final Consumer<CommitResult> mIsSuccess =
-            input -> assertThat(input).isEqualTo(CommitResult.SUCCESS);
-    private final Consumer<Result<Boolean>> mIsFalse = result -> {
-        assertThat(result.isSuccessful()).isTrue();
-        Boolean input = result.getValue();
-        assertThat(input).isFalse();
-    };
-    private final Consumer<Result<Boolean>> mIsTrue = result -> {
-        assertThat(result.isSuccessful()).isTrue();
-        Boolean input = result.getValue();
-        assertThat(input).isTrue();
-    };
-
-    protected JournalStorage mJournalStorage;
-
-    @Test
-    public void readOfEmptyJournalReturnsEmptyData() {
-        // Try to read some blobs from an empty journal store.
-        RequiredConsumer<Result<List<byte[]>>> readConsumer = new RequiredConsumer<>(mIsEmptyList);
-        mJournalStorage.read(JOURNAL_NAME, readConsumer);
-        assertThat(readConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void appendToJournal() {
-        // Write some data and put the result from the callback into commitResult.
-        RequiredConsumer<CommitResult> commitConsumer = new RequiredConsumer<>(mIsSuccess);
-        mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).append(DATA_0).append(DATA_1).build(),
-                commitConsumer);
-        assertThat(commitConsumer.isCalled()).isTrue();
-
-        // Read the data back into blobs.
-        RequiredConsumer<Result<List<byte[]>>> readConsumer =
-                new RequiredConsumer<>(mIsData0AndData1);
-        mJournalStorage.read(JOURNAL_NAME, readConsumer);
-        assertThat(readConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void copyJournal() {
-        // Write some data.
-        RequiredConsumer<CommitResult> commitConsumer = new RequiredConsumer<>(mIsSuccess);
-        mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).append(DATA_0).append(DATA_1).build(),
-                commitConsumer);
-        assertThat(commitConsumer.isCalled()).isTrue();
-
-        // Copy the data into a new journal and put the result from the callback into commitResult.
-        commitConsumer = new RequiredConsumer<>(mIsSuccess);
-        mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).copy(JOURNAL_COPY_NAME).build(),
-                commitConsumer);
-        assertThat(commitConsumer.isCalled()).isTrue();
-
-        // Read the data back into blobs.
-        RequiredConsumer<Result<List<byte[]>>> readConsumer =
-                new RequiredConsumer<>(mIsData0AndData1);
-        mJournalStorage.read(JOURNAL_COPY_NAME, readConsumer);
-        assertThat(readConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void deleteJournal() {
-        // Write some data.
-        RequiredConsumer<CommitResult> commitConsumer = new RequiredConsumer<>(mIsSuccess);
-        mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).append(DATA_0).append(DATA_1).build(),
-                commitConsumer);
-        assertThat(commitConsumer.isCalled()).isTrue();
-
-        // Delete the journal and put the result from the callback into commitResult.
-        commitConsumer = new RequiredConsumer<>(mIsSuccess);
-        mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).delete().build(), commitConsumer);
-        assertThat(commitConsumer.isCalled()).isTrue();
-
-        // Try to read the deleted journal.
-        RequiredConsumer<Result<List<byte[]>>> readConsumer = new RequiredConsumer<>(mIsEmptyList);
-        mJournalStorage.read(JOURNAL_NAME, readConsumer);
-        assertThat(readConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void deleteAllJournals() {
-        // Write some data, then copy into two journals.
-        RequiredConsumer<CommitResult> commitConsumer = new RequiredConsumer<>(mIsSuccess);
-        mJournalStorage.commit(new JournalMutation.Builder(JOURNAL_NAME)
-                                       .append(DATA_0)
-                                       .append(DATA_1)
-                                       .copy(JOURNAL_COPY_NAME)
-                                       .build(),
-                commitConsumer);
-        assertThat(commitConsumer.isCalled()).isTrue();
-
-        // Delete all journals
-        commitConsumer = new RequiredConsumer<>(mIsSuccess);
-        mJournalStorage.deleteAll(commitConsumer);
-        assertThat(commitConsumer.isCalled()).isTrue();
-
-        // Try to read the deleted journals
-        RequiredConsumer<Result<Boolean>> existsConsumer = new RequiredConsumer<>(mIsFalse);
-        mJournalStorage.exists(JOURNAL_NAME, existsConsumer);
-        assertThat(existsConsumer.isCalled()).isTrue();
-        existsConsumer = new RequiredConsumer<>(mIsFalse);
-        mJournalStorage.exists(JOURNAL_COPY_NAME, existsConsumer);
-        assertThat(existsConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void exists() {
-        // Write some data.
-        RequiredConsumer<CommitResult> commitConsumer = new RequiredConsumer<>(mIsSuccess);
-        mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).append(DATA_0).append(DATA_1).build(),
-                commitConsumer);
-        assertThat(commitConsumer.isCalled()).isTrue();
-
-        RequiredConsumer<Result<Boolean>> existsConsumer = new RequiredConsumer<>(mIsTrue);
-        mJournalStorage.exists(JOURNAL_NAME, existsConsumer);
-        assertThat(existsConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void exists_doesNotExist() {
-        RequiredConsumer<Result<Boolean>> existsConsumer = new RequiredConsumer<>(mIsFalse);
-        mJournalStorage.exists(JOURNAL_NAME, existsConsumer);
-        assertThat(existsConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void getAllJournals_singleJournal() {
-        // Write some data.
-        RequiredConsumer<CommitResult> commitConsumer = new RequiredConsumer<>(mIsSuccess);
-        mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).append(DATA_0).append(DATA_1).build(),
-                commitConsumer);
-        assertThat(commitConsumer.isCalled()).isTrue();
-
-        RequiredConsumer<Result<List<String>>> getAllJournalsConsumer =
-                new RequiredConsumer<>(mIsJournal1);
-        mJournalStorage.getAllJournals(getAllJournalsConsumer);
-        assertThat(getAllJournalsConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void getAllJournals_multipleJournals() {
-        // Write some data.
-        RequiredConsumer<CommitResult> commitConsumer = new RequiredConsumer<>(mIsSuccess);
-        mJournalStorage.commit(new JournalMutation.Builder(JOURNAL_NAME)
-                                       .append(DATA_0)
-                                       .append(DATA_1)
-                                       .copy(JOURNAL_COPY_NAME)
-                                       .build(),
-                commitConsumer);
-        assertThat(commitConsumer.isCalled()).isTrue();
-
-        RequiredConsumer<Result<List<String>>> getAllJournalsConsumer =
-                new RequiredConsumer<>(mIsJournal1AndJournal2);
-        mJournalStorage.getAllJournals(getAllJournalsConsumer);
-        assertThat(getAllJournalsConsumer.isCalled()).isTrue();
-    }
-
-    @Test
-    public void streamLocalAction_roundTrip() {
-        // Write a Stream action with known breaking data ([INTERNAL LINK])
-        StreamLocalAction action =
-                StreamLocalAction.newBuilder()
-                        .setTimestampSeconds(1532979950)
-                        .setAction(1)
-                        .setFeatureContentId("FEATURE::stories.f::5726498306727238903")
-                        .build();
-        RequiredConsumer<CommitResult> commitConsumer = new RequiredConsumer<>(mIsSuccess);
-        mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).append(action.toByteArray()).build(),
-                commitConsumer);
-        assertThat(commitConsumer.isCalled()).isTrue();
-
-        // Ensure that it can be parsed back correctly
-        RequiredConsumer<Result<List<byte[]>>> readConsumer = new RequiredConsumer<>(result -> {
-            List<byte[]> bytes = result.getValue();
-            assertThat(bytes).hasSize(1);
-            StreamLocalAction parsedAction = null;
-            try {
-                parsedAction = StreamLocalAction.parseFrom(bytes.get(0));
-            } catch (InvalidProtocolBufferException e) {
-                throw new AssertionError(
-                        "Should be able to parse StreamLocalAction bytes correctly", e);
-            }
-            assertThat(parsedAction).isEqualTo(action);
-        });
-        mJournalStorage.read(JOURNAL_NAME, readConsumer);
-        assertThat(readConsumer.isCalled()).isTrue();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/JournalStorageDirectConformanceTest.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/JournalStorageDirectConformanceTest.java
deleted file mode 100644
index c3aead19..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/JournalStorageDirectConformanceTest.java
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.conformance.storage;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-
-import org.junit.Test;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorageDirect;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamLocalAction;
-
-import java.nio.charset.Charset;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Conformance test for {@link JournalStorage}. Hosts who wish to test against this should extend
- * this class and set {@code storage} to the Host implementation.
- */
-public abstract class JournalStorageDirectConformanceTest {
-    private static final String JOURNAL_NAME = "journal name";
-    private static final String JOURNAL_COPY_NAME = "journal copy name";
-    private static final byte[] DATA_0 = "data 0".getBytes(Charset.forName("UTF-8"));
-    private static final byte[] DATA_1 = "data 1".getBytes(Charset.forName("UTF-8"));
-
-    protected JournalStorageDirect mJournalStorage;
-
-    @Test
-    public void readOfEmptyJournalReturnsEmptyData() {
-        // Try to read some blobs from an empty journal store.
-        Result<List<byte[]>> result = mJournalStorage.read(JOURNAL_NAME);
-        List<byte[]> input = result.getValue();
-
-        // The result should be an empty List.
-        assertThat(input).isNotNull();
-        assertThat(input).isEmpty();
-    }
-
-    @Test
-    public void appendToJournal() {
-        // Write some data
-        CommitResult commitResult = mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).append(DATA_0).append(DATA_1).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        // Read the data back into blobs.
-        Result<List<byte[]>> result = mJournalStorage.read(JOURNAL_NAME);
-        List<byte[]> input = result.getValue();
-        // We should get back one byte array, containing the bytes of DATA_0 and DATA_1.
-        assertThat(input).isNotNull();
-        assertThat(input).hasSize(2);
-        assertThat(Arrays.equals(input.get(0), DATA_0)).isTrue();
-        assertThat(Arrays.equals(input.get(1), DATA_1)).isTrue();
-    }
-
-    @Test
-    public void copyJournal() {
-        // Write some data.
-        CommitResult commitResult = mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).append(DATA_0).append(DATA_1).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        // Copy the data into a new journal
-        commitResult = mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).copy(JOURNAL_COPY_NAME).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        // Read the data back into blobs.
-        Result<List<byte[]>> result = mJournalStorage.read(JOURNAL_COPY_NAME);
-        List<byte[]> input = result.getValue();
-        // We should get back one byte array, containing the bytes of DATA_0 and DATA_1.
-        assertThat(input).isNotNull();
-        assertThat(input).hasSize(2);
-        assertThat(Arrays.equals(input.get(0), DATA_0)).isTrue();
-        assertThat(Arrays.equals(input.get(1), DATA_1)).isTrue();
-    }
-
-    @Test
-    public void deleteJournal() {
-        // Write some data.
-        CommitResult commitResult = mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).append(DATA_0).append(DATA_1).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        // Delete the journal
-        commitResult =
-                mJournalStorage.commit(new JournalMutation.Builder(JOURNAL_NAME).delete().build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        // Try to read the deleted journal.
-        Result<List<byte[]>> result = mJournalStorage.read(JOURNAL_NAME);
-        List<byte[]> input = result.getValue();
-
-        // The result should be an empty List.
-        assertThat(input).isNotNull();
-        assertThat(input).isEmpty();
-    }
-
-    @Test
-    public void deleteAllJournals() {
-        // Write some data, then copy into two journals.
-        CommitResult commitResult = mJournalStorage.commit(new JournalMutation.Builder(JOURNAL_NAME)
-                                                                   .append(DATA_0)
-                                                                   .append(DATA_1)
-                                                                   .copy(JOURNAL_COPY_NAME)
-                                                                   .build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        // Delete all journals
-        commitResult = mJournalStorage.deleteAll();
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        // Try to read the deleted journals
-        Result<Boolean> result = mJournalStorage.exists(JOURNAL_NAME);
-        Boolean input = result.getValue();
-        assertThat(input).isFalse();
-
-        result = mJournalStorage.exists(JOURNAL_COPY_NAME);
-        input = result.getValue();
-        assertThat(input).isFalse();
-    }
-
-    @Test
-    public void exists() {
-        // Write some data.
-        CommitResult commitResult = mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).append(DATA_0).append(DATA_1).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        Result<Boolean> result = mJournalStorage.exists(JOURNAL_NAME);
-        Boolean input = result.getValue();
-        assertThat(input).isTrue();
-    }
-
-    @Test
-    public void exists_doesNotExist() {
-        Result<Boolean> result = mJournalStorage.exists(JOURNAL_NAME);
-        Boolean input = result.getValue();
-        assertThat(input).isFalse();
-    }
-
-    @Test
-    public void getAllJournals_singleJournal() {
-        // Write some data.
-        CommitResult commitResult = mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).append(DATA_0).append(DATA_1).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        Result<List<String>> result = mJournalStorage.getAllJournals();
-        List<String> input = result.getValue();
-        assertThat(input).hasSize(1);
-        assertThat(input).contains(JOURNAL_NAME);
-    }
-
-    @Test
-    public void getAllJournals_multipleJournals() {
-        // Write some data.
-        CommitResult commitResult = mJournalStorage.commit(new JournalMutation.Builder(JOURNAL_NAME)
-                                                                   .append(DATA_0)
-                                                                   .append(DATA_1)
-                                                                   .copy(JOURNAL_COPY_NAME)
-                                                                   .build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        Result<List<String>> result = mJournalStorage.getAllJournals();
-        List<String> input = result.getValue();
-        assertThat(input).hasSize(2);
-        assertThat(input).contains(JOURNAL_NAME);
-        assertThat(input).contains(JOURNAL_COPY_NAME);
-    }
-
-    @Test
-    public void streamLocalAction_roundTrip() {
-        // Write a Stream action with known breaking data ([INTERNAL LINK])
-        StreamLocalAction action =
-                StreamLocalAction.newBuilder()
-                        .setTimestampSeconds(1532979950)
-                        .setAction(1)
-                        .setFeatureContentId("FEATURE::stories.f::5726498306727238903")
-                        .build();
-        CommitResult commitResult = mJournalStorage.commit(
-                new JournalMutation.Builder(JOURNAL_NAME).append(action.toByteArray()).build());
-        assertThat(commitResult).isEqualTo(CommitResult.SUCCESS);
-
-        // Ensure that it can be parsed back correctly
-        Result<List<byte[]>> result = mJournalStorage.read(JOURNAL_NAME);
-        List<byte[]> bytes = result.getValue();
-        assertThat(bytes).hasSize(1);
-        StreamLocalAction parsedAction = null;
-        try {
-            parsedAction = StreamLocalAction.parseFrom(bytes.get(0));
-        } catch (InvalidProtocolBufferException e) {
-            throw new AssertionError(
-                    "Should be able to parse StreamLocalAction bytes correctly", e);
-        }
-        assertThat(parsedAction).isEqualTo(action);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/logging/FakeBasicLoggingApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/logging/FakeBasicLoggingApi.java
deleted file mode 100644
index fa133067..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/logging/FakeBasicLoggingApi.java
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.host.logging;
-
-import org.chromium.chrome.browser.feed.library.api.host.logging.ActionType;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ContentLoggingData;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ElementLoggingData;
-import org.chromium.chrome.browser.feed.library.api.host.logging.InternalFeedError;
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ScrollType;
-import org.chromium.chrome.browser.feed.library.api.host.logging.SessionEvent;
-import org.chromium.chrome.browser.feed.library.api.host.logging.SpinnerType;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ZeroStateShowReason;
-
-import java.util.List;
-
-/** Fake implementation of {@link BasicLoggingApi}. */
-public class FakeBasicLoggingApi implements BasicLoggingApi {
-    @InternalFeedError
-    public int lastInternalError = InternalFeedError.NEXT_VALUE;
-    @RequestReason
-    public int serverRequestReason = RequestReason.UNKNOWN;
-    @Task
-    public int lastTaskLogged;
-    public int lastTaskDelay;
-    public int lastTaskTime;
-
-    public FakeBasicLoggingApi() {}
-
-    @Override
-    public void onContentViewed(ContentLoggingData data) {}
-
-    @Override
-    public void onContentDismissed(ContentLoggingData data, boolean wasCommitted) {}
-
-    @Override
-    public void onContentSwiped(ContentLoggingData data) {}
-
-    @Override
-    public void onContentClicked(ContentLoggingData data) {}
-
-    @Override
-    public void onClientAction(ContentLoggingData data, @ActionType int actionType) {}
-
-    @Override
-    public void onContentContextMenuOpened(ContentLoggingData data) {}
-
-    @Override
-    public void onInitialSessionEvent(
-            @SessionEvent int sessionEvent, int timeFromRegisteringMs, int sessionCount) {}
-
-    @Override
-    public void onMoreButtonViewed(int position) {}
-
-    @Override
-    public void onMoreButtonClicked(int position) {}
-
-    @Override
-    public void onNotInterestedIn(int type, ContentLoggingData data, boolean wasCommitted) {}
-
-    @Override
-    public void onOpenedWithContent(int timeToPopulateMs, int contentCount) {}
-
-    @Override
-    public void onOpenedWithNoImmediateContent() {}
-
-    @Override
-    public void onOpenedWithNoContent() {}
-
-    @Override
-    public void onServerRequest(@RequestReason int requestReason) {
-        serverRequestReason = requestReason;
-    }
-
-    @Override
-    public void onSpinnerDestroyedWithoutCompleting(int timeShownMs, @SpinnerType int spinnerType) {
-    }
-
-    @Override
-    public void onSpinnerFinished(int timeShownMs, @SpinnerType int spinnerType) {}
-
-    @Override
-    public void onSpinnerStarted(@SpinnerType int spinnerType) {}
-
-    @Override
-    public void onTokenCompleted(boolean wasSynthetic, int contentCount, int tokenCount) {}
-
-    @Override
-    public void onTokenFailedToComplete(boolean wasSynthetic, int failureCount) {}
-
-    @Override
-    public void onPietFrameRenderingEvent(List<Integer> pietErrorCodes) {}
-
-    @Override
-    public void onVisualElementClicked(ElementLoggingData data, int elementType) {}
-
-    @Override
-    public void onVisualElementViewed(ElementLoggingData data, int elementType) {}
-
-    @Override
-    public void onInternalError(@InternalFeedError int internalError) {
-        lastInternalError = internalError;
-    }
-
-    @Override
-    public void onZeroStateRefreshCompleted(int newContentCount, int newTokenCount) {}
-
-    @Override
-    public void onZeroStateShown(@ZeroStateShowReason int zeroStateShowReason) {}
-
-    @Override
-    public void onScroll(@ScrollType int scrollType, int distanceScrolled) {}
-
-    @Override
-    public void onTaskFinished(@Task int task, int delayTime, int taskTime) {
-        lastTaskDelay = delayTime;
-        lastTaskTime = taskTime;
-        lastTaskLogged = task;
-    }
-
-    @Override
-    public void reportScrollActivity(int scrollAmount) {}
-
-    @Override
-    public void reportFeedInteraction() {}
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/offlineindicator/FakeOfflineIndicatorApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/offlineindicator/FakeOfflineIndicatorApi.java
deleted file mode 100644
index 87c846c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/offlineindicator/FakeOfflineIndicatorApi.java
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.host.offlineindicator;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.offlineindicator.OfflineIndicatorApi;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/** Fake used for tests using the {@link OfflineIndicatorApi}. */
-public class FakeOfflineIndicatorApi implements OfflineIndicatorApi {
-    private final Set<String> mOfflineUrls;
-    private final Set<OfflineStatusListener> mListeners;
-
-    private FakeOfflineIndicatorApi(String[] urls) {
-        mOfflineUrls = new HashSet<>(Arrays.asList(urls));
-        mListeners = new HashSet<>();
-    }
-
-    public static FakeOfflineIndicatorApi createWithOfflineUrls(String... urls) {
-        return new FakeOfflineIndicatorApi(urls);
-    }
-
-    public static FakeOfflineIndicatorApi createWithNoOfflineUrls() {
-        return createWithOfflineUrls();
-    }
-
-    @Override
-    public void getOfflineStatus(
-            List<String> urlsToRetrieve, Consumer<List<String>> urlListConsumer) {
-        HashSet<String> copiedHashSet = new HashSet<>(mOfflineUrls);
-        copiedHashSet.retainAll(urlsToRetrieve);
-
-        urlListConsumer.accept(new ArrayList<>(copiedHashSet));
-    }
-
-    @Override
-    public void addOfflineStatusListener(OfflineStatusListener offlineStatusListener) {
-        mListeners.add(offlineStatusListener);
-    }
-
-    @Override
-    public void removeOfflineStatusListener(OfflineStatusListener offlineStatusListener) {
-        mListeners.remove(offlineStatusListener);
-    }
-
-    /**
-     * Sets the offline status of the given {@code url} to the given value and notifies any
-     * observers.
-     */
-    public void setOfflineStatus(String url, boolean isAvailable) {
-        boolean statusChanged = isAvailable ? mOfflineUrls.add(url) : mOfflineUrls.remove(url);
-
-        if (!statusChanged) {
-            return;
-        }
-
-        for (OfflineStatusListener listener : mListeners) {
-            listener.updateOfflineStatus(url, isAvailable);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/scheduler/FakeSchedulerApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/scheduler/FakeSchedulerApi.java
deleted file mode 100644
index b639aefd..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/scheduler/FakeSchedulerApi.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.host.scheduler;
-
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-
-/** Fake implementation of {@link SchedulerApi}. */
-public final class FakeSchedulerApi implements SchedulerApi {
-    private final ThreadUtils mThreadUtils;
-    @RequestBehavior
-    private int mRequestBehavior = RequestBehavior.NO_REQUEST_WITH_CONTENT;
-
-    public FakeSchedulerApi(ThreadUtils threadUtils) {
-        this.mThreadUtils = threadUtils;
-    }
-
-    @Override
-    public void onReceiveNewContent(long contentCreationDateTimeMs) {}
-
-    @Override
-    public void onRequestError(int networkResponseCode) {}
-
-    @Override
-    @RequestBehavior
-    public int shouldSessionRequestData(SessionState sessionState) {
-        mThreadUtils.checkMainThread();
-        return mRequestBehavior;
-    }
-
-    /** Sets the result returned from {@link shouldSessionRequestData( SessionState )}. */
-    public FakeSchedulerApi setRequestBehavior(@RequestBehavior int requestBehavior) {
-        this.mRequestBehavior = requestBehavior;
-        return this;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/stream/FakeCardConfiguration.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/stream/FakeCardConfiguration.java
deleted file mode 100644
index 229528f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/stream/FakeCardConfiguration.java
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.host.stream;
-
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-
-import org.chromium.chrome.browser.feed.library.api.host.stream.CardConfiguration;
-
-/** Fake for {@link CardConfiguration}. */
-public class FakeCardConfiguration implements CardConfiguration {
-    private static ColorDrawable sColorDrawable;
-
-    private int mBottomMargin = 1;
-    private int mStartMargin = 2;
-    private int mEndMargin = 3;
-
-    @Override
-    public int getDefaultCornerRadius() {
-        return 0;
-    }
-
-    @Override
-    public Drawable getCardBackground() {
-        if (sColorDrawable == null) {
-            sColorDrawable = new ColorDrawable(Color.RED);
-        }
-        return sColorDrawable;
-    }
-
-    @Override
-    public int getCardBottomMargin() {
-        return mBottomMargin;
-    }
-
-    @Override
-    public int getCardStartMargin() {
-        return mStartMargin;
-    }
-
-    @Override
-    public int getCardEndMargin() {
-        return mEndMargin;
-    }
-
-    public void setCardStartMargin(int cardStartMargin) {
-        this.mStartMargin = cardStartMargin;
-    }
-
-    public void setCardEndMargin(int cardEndMargin) {
-        this.mEndMargin = cardEndMargin;
-    }
-
-    public void setCardBottomMargin(int cardBottomMargin) {
-        this.mBottomMargin = cardBottomMargin;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/stream/FakeTooltipSupportedApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/stream/FakeTooltipSupportedApi.java
deleted file mode 100644
index 387c0f3..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/stream/FakeTooltipSupportedApi.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.host.stream;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipInfo.FeatureName;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipSupportedApi;
-import org.chromium.chrome.browser.feed.library.api.internal.common.ThreadUtils;
-
-import java.util.ArrayList;
-
-/** Fake implementation of {@link TooltipSupportedApi}. */
-public final class FakeTooltipSupportedApi implements TooltipSupportedApi {
-    private final ArrayList<String> mUnsupportedFeatures = new ArrayList<>();
-    private final ThreadUtils mThreadUtils;
-    @Nullable
-    private String mLastFeatureName;
-
-    public FakeTooltipSupportedApi(ThreadUtils threadUtils) {
-        this.mThreadUtils = threadUtils;
-    }
-
-    @Override
-    public void wouldTriggerHelpUi(@FeatureName String featureName, Consumer<Boolean> consumer) {
-        mThreadUtils.checkMainThread();
-        mLastFeatureName = featureName;
-        consumer.accept(!mUnsupportedFeatures.contains(featureName));
-    }
-
-    /** Adds an unsupported feature. */
-    public FakeTooltipSupportedApi addUnsupportedFeature(String featureName) {
-        mUnsupportedFeatures.add(featureName);
-        return this;
-    }
-
-    /**
-     * Gets the last feature name that was passed in to {@link wouldTriggerHelpUi(String,
-     * Consumer)}.
-     */
-    @Nullable
-    public String getLatestFeatureName() {
-        return mLastFeatureName;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelChild.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelChild.java
deleted file mode 100644
index a82388561..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelChild.java
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.modelprovider;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkState;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelToken;
-
-/**
- * Fake for {@link org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild}.
- */
-public class FakeModelChild implements ModelChild {
-    private final String mContentId;
-
-    private final @Nullable ModelFeature mModelFeature;
-    private final @Nullable ModelToken mModelToken;
-    private final @Nullable String mParentId;
-
-    public static Builder newBuilder() {
-        return new Builder();
-    }
-
-    private FakeModelChild(String contentId, @Nullable ModelFeature modelFeature,
-            @Nullable ModelToken modelToken, @Nullable String parentId) {
-        // A ModelChild can't represent both a ModelFeature and a ModelToken.
-        checkState(modelFeature == null || modelToken == null);
-        this.mContentId = contentId;
-        this.mModelFeature = modelFeature;
-        this.mModelToken = modelToken;
-        this.mParentId = parentId;
-    }
-
-    @Override
-    public @Type int getType() {
-        if (mModelFeature != null) {
-            return Type.FEATURE;
-        }
-
-        if (mModelToken != null) {
-            return Type.TOKEN;
-        }
-
-        return Type.UNBOUND;
-    }
-
-    @Override
-    public String getContentId() {
-        return mContentId;
-    }
-
-    @Override
-    public boolean hasParentId() {
-        return mParentId != null;
-    }
-
-    @Override
-    public @Nullable String getParentId() {
-        return mParentId;
-    }
-
-    @Override
-    public ModelFeature getModelFeature() {
-        checkState(mModelFeature != null,
-                "Must call setModelFeature on builder to have a ModelFeature");
-
-        // checkNotNull for nullness checker, if modelFeature is null, the checkState above will
-        // fail.
-        return checkNotNull(mModelFeature);
-    }
-
-    @Override
-    public ModelToken getModelToken() {
-        checkState(mModelToken != null, "Must call setModelToken on builder to have a ModelToken");
-
-        // checkNotNull for nullness checker, if modelToken is null, the checkState above will fail.
-        return checkNotNull(mModelToken);
-    }
-
-    public static class Builder {
-        private String mContentId = "";
-        private @Nullable ModelFeature mModelFeature;
-        private @Nullable ModelToken mModelToken;
-        private @Nullable String mParentId;
-
-        private Builder() {}
-
-        public Builder setContentId(String contentId) {
-            this.mContentId = contentId;
-            return this;
-        }
-
-        public Builder setParentId(@Nullable String parentId) {
-            this.mParentId = parentId;
-            return this;
-        }
-
-        public Builder setModelFeature(ModelFeature modelFeature) {
-            checkState(mModelToken == null);
-            this.mModelFeature = modelFeature;
-            return this;
-        }
-
-        public Builder setModelToken(ModelToken modelToken) {
-            checkState(mModelFeature == null);
-            this.mModelToken = modelToken;
-            return this;
-        }
-
-        public FakeModelChild build() {
-            return new FakeModelChild(mContentId, mModelFeature, mModelToken, mParentId);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelCursor.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelCursor.java
deleted file mode 100644
index a7c760e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelCursor.java
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.modelprovider;
-
-import androidx.annotation.Nullable;
-
-import com.google.common.collect.ImmutableList;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelCursor;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelToken;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamFeature;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.Card;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.Cluster;
-import org.chromium.components.feed.core.proto.ui.stream.StreamStructureProto.Content;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** A fake {@link ModelCursor} for testing. */
-public class FakeModelCursor implements ModelCursor {
-    private List<ModelChild> mModelChildren;
-    private int mCurrentIndex;
-
-    public FakeModelCursor(List<ModelChild> modelChildren) {
-        mCurrentIndex = 0;
-        this.mModelChildren = modelChildren;
-    }
-
-    public static FakeModelCursor emptyCursor() {
-        return FakeModelCursor.newBuilder().build();
-    }
-
-    public static Builder newBuilder() {
-        return new Builder();
-    }
-
-    public void setModelChildren(List<ModelChild> modelChildren) {
-        this.mModelChildren = modelChildren;
-    }
-
-    @Override
-    @Nullable
-    public ModelChild getNextItem() {
-        if (isAtEnd()) {
-            return null;
-        }
-        return mModelChildren.get(mCurrentIndex++);
-    }
-
-    @Override
-    public boolean isAtEnd() {
-        return mCurrentIndex >= mModelChildren.size();
-    }
-
-    public ModelChild getChildAt(int i) {
-        return mModelChildren.get(i);
-    }
-
-    public List<ModelChild> getModelChildren() {
-        return ImmutableList.copyOf(mModelChildren);
-    }
-
-    public static class Builder {
-        final List<ModelChild> mCursorChildren = new ArrayList<>();
-
-        private Builder() {}
-
-        public Builder addCard() {
-            final FakeModelCursor build = emptyCursor();
-            return addChildWithModelFeature(getCardModelFeatureWithCursor(build));
-        }
-
-        public Builder addCard(String contentId) {
-            return addChildWithModelFeatureAndContentId(
-                    getCardModelFeatureWithCursor(emptyCursor()), contentId);
-        }
-
-        public Builder addChild(ModelFeature feature) {
-            return addChild(FakeModelChild.newBuilder().setModelFeature(feature).build());
-        }
-
-        public Builder addChild(ModelChild child) {
-            mCursorChildren.add(child);
-            return this;
-        }
-
-        public Builder addChildren(List<ModelChild> children) {
-            for (ModelChild child : children) {
-                addChild(child);
-            }
-            return this;
-        }
-
-        public Builder addCluster() {
-            final FakeModelCursor cursor = new FakeModelCursor(new ArrayList<>());
-            return addChildWithModelFeature(getClusterModelFeatureWithCursor(cursor));
-        }
-
-        public Builder addCluster(String contentId) {
-            return addChildWithModelFeature(getClusterModelFeatureWithContentId(contentId));
-        }
-
-        public Builder addClusters(int count) {
-            for (int i = 0; i < count; i++) {
-                addCluster();
-            }
-
-            return this;
-        }
-
-        public Builder addUnboundChild() {
-            addChild(FakeModelChild.newBuilder().build());
-            return this;
-        }
-
-        public Builder addChildWithModelFeature(FakeModelFeature modelFeature) {
-            ModelChild cardChild =
-                    FakeModelChild.newBuilder().setModelFeature(modelFeature).build();
-            mCursorChildren.add(cardChild);
-            return this;
-        }
-
-        public Builder addChildWithModelFeatureAndContentId(
-                FakeModelFeature modelFeature, String contentId) {
-            ModelChild cardChild = FakeModelChild.newBuilder()
-                                           .setModelFeature(modelFeature)
-                                           .setContentId(contentId)
-                                           .build();
-            mCursorChildren.add(cardChild);
-            return this;
-        }
-
-        public Builder addContent(Content content) {
-            final FakeModelCursor cursor = new FakeModelCursor(new ArrayList<>());
-            return addChildWithModelFeature(getContentModelFeatureWithCursor(content, cursor));
-        }
-
-        public Builder addContent(Content content, String contentId) {
-            final FakeModelCursor cursor = new FakeModelCursor(new ArrayList<>());
-            return addChildWithModelFeatureAndContentId(
-                    getContentModelFeatureWithCursor(content, cursor), contentId);
-        }
-
-        public Builder addToken(boolean isSynthetic) {
-            return addToken(FakeModelToken.newBuilder().setIsSynthetic(isSynthetic).build());
-        }
-
-        public Builder addToken() {
-            return addToken(/* isSynthetic= */ false);
-        }
-
-        public Builder addToken(ModelToken token) {
-            ModelChild tokenChild = FakeModelChild.newBuilder().setModelToken(token).build();
-
-            mCursorChildren.add(tokenChild);
-
-            return this;
-        }
-
-        public Builder addToken(String contentId) {
-            ModelChild tokenChild =
-                    FakeModelChild.newBuilder()
-                            .setModelToken(FakeModelToken.newBuilder()
-                                                   .setStreamToken(StreamToken.getDefaultInstance())
-                                                   .build())
-                            .setContentId(contentId)
-                            .build();
-            mCursorChildren.add(tokenChild);
-            return this;
-        }
-
-        public Builder addSyntheticToken() {
-            return addToken(/* isSynthetic= */ true);
-        }
-
-        public FakeModelCursor build() {
-            return new FakeModelCursor(mCursorChildren);
-        }
-    }
-
-    public static FakeModelFeature getCardModelFeatureWithCursor(ModelCursor modelCursor) {
-        return FakeModelFeature.newBuilder()
-                .setStreamFeature(
-                        StreamFeature.newBuilder().setCard(Card.getDefaultInstance()).build())
-                .setModelCursor(modelCursor)
-                .build();
-    }
-
-    public static FakeModelFeature getCardModelFeatureWithContentId(String contentId) {
-        return FakeModelFeature.newBuilder()
-                .setStreamFeature(StreamFeature.newBuilder()
-                                          .setCard(Card.getDefaultInstance())
-                                          .setContentId(contentId)
-                                          .build())
-                .setModelCursor(FakeModelCursor.newBuilder().build())
-                .build();
-    }
-
-    public static FakeModelFeature getClusterModelFeatureWithCursor(ModelCursor cursor) {
-        return FakeModelFeature.newBuilder()
-                .setStreamFeature(
-                        StreamFeature.newBuilder().setCluster(Cluster.getDefaultInstance()).build())
-                .setModelCursor(cursor)
-                .build();
-    }
-
-    public static FakeModelFeature getClusterModelFeatureWithContentId(String contentId) {
-        return FakeModelFeature.newBuilder()
-                .setStreamFeature(StreamFeature.newBuilder()
-                                          .setCluster(Cluster.getDefaultInstance())
-                                          .setContentId(contentId)
-                                          .build())
-                .setModelCursor(FakeModelCursor.newBuilder().build())
-                .build();
-    }
-
-    public static FakeModelFeature getContentModelFeatureWithCursor(
-            Content content, ModelCursor cursor) {
-        return FakeModelFeature.newBuilder()
-                .setStreamFeature(StreamFeature.newBuilder().setContent(content).build())
-                .setModelCursor(cursor)
-                .build();
-    }
-
-    public static FakeModelFeature getModelFeatureWithEmptyCursor() {
-        return FakeModelFeature.newBuilder().setModelCursor(newBuilder().build()).build();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelFeature.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelFeature.java
deleted file mode 100644
index 81f2ed0..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelFeature.java
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.modelprovider;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.FeatureChange;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.FeatureChangeObserver;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelCursor;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamFeature;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-
-/** Fake for {@link ModelFeature}. */
-public class FakeModelFeature implements ModelFeature {
-    private final StreamFeature mStreamFeature;
-    private final ModelCursor mModelCursor;
-    private final HashSet<FeatureChangeObserver> mObservers = new HashSet<>();
-
-    private FakeModelFeature(ModelCursor modelCursor, StreamFeature streamFeature) {
-        this.mModelCursor = modelCursor;
-        this.mStreamFeature = streamFeature;
-    }
-
-    public static Builder newBuilder() {
-        return new Builder();
-    }
-
-    public HashSet<FeatureChangeObserver> getObservers() {
-        return mObservers;
-    }
-
-    public void triggerOnChange(FeatureChange change) {
-        for (FeatureChangeObserver observer : mObservers) {
-            observer.onChange(change);
-        }
-    }
-
-    @Override
-    public StreamFeature getStreamFeature() {
-        return mStreamFeature;
-    }
-
-    @Override
-    public ModelCursor getCursor() {
-        return mModelCursor;
-    }
-
-    @Override
-    public @Nullable ModelCursor getDirectionalCursor(
-            boolean forward, @Nullable String startingChild) {
-        return null;
-    }
-
-    @Override
-    public void registerObserver(FeatureChangeObserver observer) {
-        this.mObservers.add(observer);
-    }
-
-    @Override
-    public void unregisterObserver(FeatureChangeObserver observer) {
-        this.mObservers.remove(observer);
-    }
-
-    public static class Builder {
-        private ModelCursor mModelCursor = new FakeModelCursor(new ArrayList<>());
-        private StreamFeature mStreamFeature = StreamFeature.getDefaultInstance();
-
-        private Builder() {}
-
-        public Builder setModelCursor(ModelCursor modelCursor) {
-            this.mModelCursor = modelCursor;
-            return this;
-        }
-
-        public Builder setStreamFeature(StreamFeature streamFeature) {
-            this.mStreamFeature = streamFeature;
-            return this;
-        }
-
-        public FakeModelFeature build() {
-            return new FakeModelFeature(mModelCursor, mStreamFeature);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelMutation.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelMutation.java
deleted file mode 100644
index b3113b7..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelMutation.java
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.modelprovider;
-
-import org.chromium.chrome.browser.feed.library.api.common.MutationContext;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelMutation;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Fake ModelMutation for tests. */
-public final class FakeModelMutation implements ModelMutation {
-    public final List<StreamStructure> mAddedChildren = new ArrayList<>();
-    public final List<StreamStructure> mRemovedChildren = new ArrayList<>();
-    public final List<StreamStructure> mUpdateChildren = new ArrayList<>();
-    public MutationContext mMutationContext;
-    boolean mCommitCalled;
-
-    @Override
-    public ModelMutation addChild(StreamStructure streamStructure) {
-        mAddedChildren.add(streamStructure);
-        return this;
-    }
-
-    @Override
-    public ModelMutation removeChild(StreamStructure streamStructure) {
-        mRemovedChildren.add(streamStructure);
-        return this;
-    }
-
-    @Override
-    public ModelMutation updateChild(StreamStructure streamStructure) {
-        mUpdateChildren.add(streamStructure);
-        return this;
-    }
-
-    @Override
-    public ModelMutation setMutationContext(MutationContext mutationContext) {
-        this.mMutationContext = mutationContext;
-        return this;
-    }
-
-    @Override
-    public ModelMutation setSessionId(String sessionId) {
-        return this;
-    }
-
-    @Override
-    public ModelMutation hasCachedBindings(boolean cachedBindings) {
-        return this;
-    }
-
-    @Override
-    public void commit() {
-        mCommitCalled = true;
-    }
-
-    /** Clears the commit. */
-    public FakeModelMutation clearCommit() {
-        mCommitCalled = false;
-        mAddedChildren.clear();
-        mRemovedChildren.clear();
-        mUpdateChildren.clear();
-        return this;
-    }
-
-    /** Returns whether this mutation was committed. */
-    public boolean isCommitted() {
-        return mCommitCalled;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelProvider.java
deleted file mode 100644
index cac96a8..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelProvider.java
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.modelprovider;
-
-import androidx.annotation.Nullable;
-
-import com.google.common.collect.ImmutableList;
-
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelCursor;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelError;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProviderObserver;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelToken;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Fake for tests using {@link ModelProvider}. Functionality should be added to this class as
- * needed.
- */
-public class FakeModelProvider implements ModelProvider {
-    private final Set<ModelProviderObserver> mObservers = new HashSet<>();
-    private ModelFeature mRootFeature;
-    private boolean mWasRefreshTriggered;
-    private boolean mTokensEnabled = true;
-    @Nullable
-    private String mSessionId;
-    @RequestReason
-    private int mLastRequestReason = RequestReason.UNKNOWN;
-    @Nullable
-    private ModelFeature mImmediateSessionStartModel;
-    @Nullable
-    private UiContext mUnusedTriggerRefreshUiContext;
-    private FakeModelMutation mLatestModelMutation = new FakeModelMutation();
-    private boolean mIsInvalidated;
-
-    @Override
-    public ModelMutation edit() {
-        mLatestModelMutation = new FakeModelMutation();
-        return mLatestModelMutation;
-    }
-
-    @Override
-    public void invalidate() {
-        mIsInvalidated = true;
-    }
-
-    @Override
-    public void invalidate(UiContext uiContext) {
-        mIsInvalidated = true;
-    }
-
-    @Override
-    public void detachModelProvider() {}
-
-    @Override
-    public void raiseError(ModelError error) {}
-
-    @Override
-    @Nullable
-    public ModelFeature getRootFeature() {
-        return mRootFeature;
-    }
-
-    @Override
-    @Nullable
-    public ModelChild getModelChild(String contentId) {
-        return null;
-    }
-
-    @Override
-    @Nullable
-    public StreamSharedState getSharedState(ContentId contentId) {
-        return null;
-    }
-
-    @Override
-    public boolean handleToken(ModelToken modelToken) {
-        return mTokensEnabled;
-    }
-
-    @Override
-    public void triggerRefresh(@RequestReason int requestReason) {
-        triggerRefresh(requestReason, UiContext.getDefaultInstance());
-    }
-
-    @Override
-    public void triggerRefresh(@RequestReason int requestReason, UiContext uiContext) {
-        mWasRefreshTriggered = true;
-        mLastRequestReason = requestReason;
-        mUnusedTriggerRefreshUiContext = uiContext;
-    }
-
-    @Override
-    public int getCurrentState() {
-        return State.INITIALIZING;
-    }
-
-    @Override
-    @Nullable
-    public String getSessionId() {
-        return mSessionId;
-    }
-
-    @Override
-    public List<ModelChild> getAllRootChildren() {
-        ImmutableList.Builder<ModelChild> listBuilder = ImmutableList.builder();
-        if (mRootFeature == null) {
-            return listBuilder.build();
-        }
-
-        ModelCursor cursor = mRootFeature.getCursor();
-        ModelChild child;
-        while ((child = cursor.getNextItem()) != null) {
-            listBuilder.add(child);
-        }
-        return listBuilder.build();
-    }
-
-    @Override
-    public void enableRemoveTracking(RemoveTrackingFactory<?> removeTrackingFactory) {}
-
-    @Override
-    public void registerObserver(ModelProviderObserver observer) {
-        if (mImmediateSessionStartModel != null) {
-            this.mRootFeature = mImmediateSessionStartModel;
-            observer.onSessionStart(UiContext.getDefaultInstance());
-        }
-
-        mObservers.add(observer);
-    }
-
-    @Override
-    public void unregisterObserver(ModelProviderObserver observer) {
-        mObservers.remove(observer);
-    }
-
-    public void triggerOnSessionStart(ModelFeature rootFeature) {
-        triggerOnSessionStart(rootFeature, UiContext.getDefaultInstance());
-    }
-
-    public void triggerOnSessionStart(ModelFeature rootFeature, UiContext uiContext) {
-        this.mRootFeature = rootFeature;
-        for (ModelProviderObserver observer : mObservers) {
-            observer.onSessionStart(uiContext);
-        }
-    }
-
-    public void triggerOnSessionFinished() {
-        triggerOnSessionFinished(UiContext.getDefaultInstance());
-    }
-
-    public void triggerOnSessionFinished(UiContext uiContext) {
-        for (ModelProviderObserver observer : mObservers) {
-            observer.onSessionFinished(uiContext);
-        }
-    }
-
-    public void triggerOnError(ModelError modelError) {
-        for (ModelProviderObserver observer : mObservers) {
-            observer.onError(modelError);
-        }
-    }
-
-    public boolean wasRefreshTriggered() {
-        return mWasRefreshTriggered;
-    }
-
-    public Set<ModelProviderObserver> getObservers() {
-        return mObservers;
-    }
-
-    public void setSessionId(String sessionId) {
-        this.mSessionId = sessionId;
-    }
-
-    @RequestReason
-    public int getLastRequestReason() {
-        return mLastRequestReason;
-    }
-
-    public void triggerOnSessionStartImmediately(ModelFeature modelFeature) {
-        mImmediateSessionStartModel = modelFeature;
-    }
-
-    public void setTokensEnabled(boolean value) {
-        mTokensEnabled = value;
-    }
-
-    /** Returns the last {@link FakeModelMutation} returned from the {@link edit()} method. */
-    public FakeModelMutation getLatestModelMutation() {
-        return mLatestModelMutation;
-    }
-
-    /** Returns whether this {@link ModelProvider} has been invalidated. */
-    public boolean isInvalidated() {
-        return mIsInvalidated;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelProviderFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelProviderFactory.java
deleted file mode 100644
index 2b1b484..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelProviderFactory.java
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.modelprovider;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider.ViewDepthProvider;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProviderFactory;
-import org.chromium.chrome.browser.feed.library.common.functional.Predicate;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.UiContext;
-
-/**
- * Fake for tests using {@link ModelProviderFactory}. Functionality should be added to this class as
- * needed.
- */
-public class FakeModelProviderFactory implements ModelProviderFactory {
-    private FakeModelProvider mModelProvider;
-    private String mCreateSessionId;
-    @Nullable
-    private ViewDepthProvider mViewDepthProvider;
-
-    @Override
-    public ModelProvider create(String sessionId, UiContext uiContext) {
-        this.mModelProvider = new FakeModelProvider();
-        this.mCreateSessionId = sessionId;
-        return mModelProvider;
-    }
-
-    @Override
-    public ModelProvider createNew(
-            @Nullable ViewDepthProvider viewDepthProvider, UiContext uiContext) {
-        this.mViewDepthProvider = viewDepthProvider;
-        this.mModelProvider = new FakeModelProvider();
-        return mModelProvider;
-    }
-
-    @Override
-    public ModelProvider createNew(@Nullable ViewDepthProvider viewDepthProvider,
-            @Nullable Predicate<StreamStructure> filterPredicate, UiContext uiContext) {
-        this.mViewDepthProvider = viewDepthProvider;
-        this.mModelProvider = new FakeModelProvider();
-        return mModelProvider;
-    }
-
-    public FakeModelProvider getLatestModelProvider() {
-        return mModelProvider;
-    }
-
-    public String getLatestCreateSessionId() {
-        return mCreateSessionId;
-    }
-
-    @Nullable
-    public ViewDepthProvider getViewDepthProvider() {
-        return mViewDepthProvider;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelToken.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelToken.java
deleted file mode 100644
index 34246270..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelToken.java
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.modelprovider;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelToken;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.TokenCompletedObserver;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-
-import java.util.HashSet;
-
-/** Fake for {@link ModelToken}. */
-public class FakeModelToken implements ModelToken {
-    private final StreamToken mStreamToken;
-    private final boolean mIsSynthetic;
-    private final HashSet<TokenCompletedObserver> mObservers = new HashSet<>();
-
-    private FakeModelToken(StreamToken streamToken, boolean isSynthetic) {
-        this.mStreamToken = streamToken;
-        this.mIsSynthetic = isSynthetic;
-    }
-
-    public static Builder newBuilder() {
-        return new Builder();
-    }
-
-    public HashSet<TokenCompletedObserver> getObservers() {
-        return mObservers;
-    }
-
-    @Override
-    public StreamToken getStreamToken() {
-        return mStreamToken;
-    }
-
-    @Override
-    public void registerObserver(TokenCompletedObserver observer) {
-        mObservers.add(observer);
-    }
-
-    @Override
-    public void unregisterObserver(TokenCompletedObserver observer) {
-        mObservers.remove(observer);
-    }
-
-    @Override
-    public boolean isSynthetic() {
-        return mIsSynthetic;
-    }
-
-    public static class Builder {
-        private StreamToken mStreamToken = StreamToken.getDefaultInstance();
-        private boolean mIsSynthetic;
-
-        private Builder() {}
-
-        public Builder setStreamToken(StreamToken streamToken) {
-            this.mStreamToken = streamToken;
-            return this;
-        }
-
-        public Builder setIsSynthetic(boolean isSynthetic) {
-            this.mIsSynthetic = isSynthetic;
-            return this;
-        }
-
-        public FakeModelToken build() {
-            return new FakeModelToken(mStreamToken, mIsSynthetic);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeViewDepthProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeViewDepthProvider.java
deleted file mode 100644
index dfc6618..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeViewDepthProvider.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.modelprovider;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelProvider.ViewDepthProvider;
-
-/** Fake implementation of {@link ViewDepthProvider}. */
-public final class FakeViewDepthProvider implements ViewDepthProvider {
-    @Nullable
-    private String mChildViewDepth;
-
-    public FakeViewDepthProvider() {}
-
-    @Override
-    @Nullable
-    public String getChildViewDepth() {
-        return mChildViewDepth;
-    }
-
-    public FakeViewDepthProvider setChildViewDepth(String childViewDepth) {
-        this.mChildViewDepth = childViewDepth;
-        return this;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FeatureChangeBuilder.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FeatureChangeBuilder.java
deleted file mode 100644
index b5cc766..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FeatureChangeBuilder.java
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.modelprovider;
-
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.FeatureChange;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelChild;
-import org.chromium.chrome.browser.feed.library.api.internal.modelprovider.ModelFeature;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Builds a {@link FeatureChange} representing the addition or removal of given {@link ModelChild}
- * instances.
- */
-public class FeatureChangeBuilder {
-    private final List<ModelChild> mRemovedChildren = new ArrayList<>();
-    private final List<ModelChild> mAppendedChildren = new ArrayList<>();
-
-    public FeatureChangeBuilder addChildForRemoval(ModelChild modelChild) {
-        mRemovedChildren.add(modelChild);
-        return this;
-    }
-
-    public FeatureChangeBuilder addChildForAppending(ModelChild modelChild) {
-        mAppendedChildren.add(modelChild);
-        return this;
-    }
-
-    public FeatureChange build() {
-        return new FeatureChange() {
-            @Override
-            public String getContentId() {
-                return "";
-            }
-
-            @Override
-            public boolean isFeatureChanged() {
-                return false;
-            }
-
-            @Override
-            public ModelFeature getModelFeature() {
-                return FakeModelFeature.newBuilder().build();
-            }
-
-            @Override
-            public ChildChanges getChildChanges() {
-                return new ChildChanges() {
-                    @Override
-                    public List<ModelChild> getAppendedChildren() {
-                        return mAppendedChildren;
-                    }
-
-                    @Override
-                    public List<ModelChild> getRemovedChildren() {
-                        return mRemovedChildren;
-                    }
-                };
-            }
-        };
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/network/FakeNetworkClient.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/network/FakeNetworkClient.java
deleted file mode 100644
index b6e73931..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/network/FakeNetworkClient.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.network;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpResponse;
-import org.chromium.chrome.browser.feed.library.api.host.network.NetworkClient;
-import org.chromium.chrome.browser.feed.library.common.concurrent.testing.FakeThreadUtils;
-
-import java.util.ArrayList;
-
-/** Fake implementation of {@link NetworkClient}. */
-public final class FakeNetworkClient implements NetworkClient {
-    private final FakeThreadUtils mFakeThreadUtils;
-    private final ArrayList<HttpResponse> mResponses = new ArrayList<>();
-    @Nullable
-    private HttpRequest mRequest;
-    @Nullable
-    private HttpResponse mDefaultResponse;
-
-    public FakeNetworkClient(FakeThreadUtils fakeThreadUtils) {
-        this.mFakeThreadUtils = fakeThreadUtils;
-    }
-
-    @Override
-    public void send(HttpRequest request, Consumer<HttpResponse> responseConsumer) {
-        this.mRequest = request;
-        boolean policy = mFakeThreadUtils.enforceMainThread(true);
-        try {
-            if (mResponses.isEmpty() && mDefaultResponse != null) {
-                responseConsumer.accept(mDefaultResponse);
-                return;
-            }
-
-            responseConsumer.accept(mResponses.remove(0));
-        } finally {
-            mFakeThreadUtils.enforceMainThread(policy);
-        }
-    }
-
-    @Override
-    public void close() {}
-
-    /** Adds a response to the {@link FakeNetworkClient} to be returned in order. */
-    public FakeNetworkClient addResponse(HttpResponse response) {
-        mResponses.add(response);
-        return this;
-    }
-
-    /** Sets a default response to use if no other response is available. */
-    public FakeNetworkClient setDefaultResponse(HttpResponse response) {
-        mDefaultResponse = response;
-        return this;
-    }
-
-    /** Returns the last {@link HttpRequest} sent. */
-    @Nullable
-    public HttpRequest getLatestRequest() {
-        return mRequest;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/protocoladapter/FakeProtocolAdapter.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/protocoladapter/FakeProtocolAdapter.java
deleted file mode 100644
index 98c013b..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/protocoladapter/FakeProtocolAdapter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.protocoladapter;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.internal.common.Model;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamDataOperation;
-import org.chromium.components.feed.core.proto.wire.ContentIdProto.ContentId;
-import org.chromium.components.feed.core.proto.wire.DataOperationProto.DataOperation;
-import org.chromium.components.feed.core.proto.wire.ResponseProto.Response;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/** Converts the wire protocol (protos sent from the server) into an internal representation. */
-public final class FakeProtocolAdapter implements ProtocolAdapter {
-    private static final String UNMAPPED_CONTENT_ID = "unmapped_content_id";
-
-    private final Map<String, ContentId> mContentIds = new HashMap<>();
-    @Nullable
-    private Response mLastResponse;
-
-    @Override
-    public Result<Model> createModel(Response response) {
-        mLastResponse = response;
-        return Result.success(Model.empty());
-    }
-
-    @Override
-    public List<StreamDataOperation> createOperations(List<DataOperation> dataOperations) {
-        return new ArrayList<>();
-    }
-
-    @Override
-    public String getStreamContentId(ContentId wireContentId) {
-        for (String contentId : mContentIds.keySet()) {
-            if (wireContentId.equals(mContentIds.get(contentId))) {
-                return contentId;
-            }
-        }
-
-        return UNMAPPED_CONTENT_ID;
-    }
-
-    @Override
-    public Result<ContentId> getWireContentId(String contentId) {
-        ContentId wireContentId = mContentIds.get(contentId);
-        if (wireContentId != null) {
-            return Result.success(wireContentId);
-        } else {
-            return Result.success(ContentId.getDefaultInstance());
-        }
-    }
-
-    /** Adds a content id mapping to the {@link FakeProtocolAdapter}. */
-    public FakeProtocolAdapter addContentId(String contentId, ContentId wireContentId) {
-        mContentIds.put(contentId, wireContentId);
-        return this;
-    }
-
-    /** Returns the last response sent into {@link #createModel(Response)}. */
-    @Nullable
-    public Response getLastResponse() {
-        return mLastResponse;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/requestmanager/FakeActionUploadRequestManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/requestmanager/FakeActionUploadRequestManager.java
deleted file mode 100644
index 6cce9d2..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/requestmanager/FakeActionUploadRequestManager.java
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.requestmanager;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.internal.actionmanager.ViewActionManager;
-import org.chromium.chrome.browser.feed.library.api.internal.requestmanager.ActionUploadRequestManager;
-import org.chromium.chrome.browser.feed.library.api.internal.store.Store;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.testing.FakeThreadUtils;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-import org.chromium.components.feed.core.proto.wire.ConsistencyTokenProto.ConsistencyToken;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/** Fake implements of {@link ActionUploadRequestManager}. */
-public final class FakeActionUploadRequestManager implements ActionUploadRequestManager {
-    private final Store mStore;
-    private final ViewActionManager mViewActionManager;
-    private final FakeThreadUtils mFakeThreadUtils;
-    private Result<ConsistencyToken> mResult =
-            Result.success(ConsistencyToken.getDefaultInstance());
-    @Nullable
-    private Set<StreamUploadableAction> mActions;
-
-    public FakeActionUploadRequestManager(
-            Store store, ViewActionManager viewActionManager, FakeThreadUtils fakeThreadUtils) {
-        this.mStore = store;
-        this.mViewActionManager = viewActionManager;
-        this.mFakeThreadUtils = fakeThreadUtils;
-    }
-
-    @Override
-    public void triggerUploadActions(Set<StreamUploadableAction> actions, ConsistencyToken token,
-            Consumer<Result<ConsistencyToken>> consumer) {
-        this.mActions = actions;
-        boolean policy = mFakeThreadUtils.enforceMainThread(false);
-        try {
-            consumer.accept(mResult);
-        } finally {
-            mFakeThreadUtils.enforceMainThread(policy);
-        }
-    }
-
-    @Override
-    public void triggerUploadAllActions(
-            ConsistencyToken token, Consumer<Result<ConsistencyToken>> consumer) {
-        mViewActionManager.storeViewActions(() -> {
-            Result<Set<StreamUploadableAction>> actionsResult = mStore.getAllUploadableActions();
-            if (actionsResult.isSuccessful()) {
-                triggerUploadActions(actionsResult.getValue(), token, consumer);
-            }
-        });
-    }
-
-    /**
-     * Sets the result to return from triggerUploadActions. If unset will use {@code
-     * Result.success(ConsistencyToken.getDefaultInstance())}.
-     */
-    public FakeActionUploadRequestManager setResult(Result<ConsistencyToken> result) {
-        this.mResult = result;
-        return this;
-    }
-
-    /** Returns the last set of actions sent to triggerUploadActions. */
-    public Set<StreamUploadableAction> getLatestActions() {
-        if (mActions == null) {
-            return new HashSet<>();
-        }
-
-        return mActions;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/requestmanager/FakeFeedRequestManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/requestmanager/FakeFeedRequestManager.java
deleted file mode 100644
index 76dffd30..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/requestmanager/FakeFeedRequestManager.java
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.requestmanager;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.internal.common.Model;
-import org.chromium.chrome.browser.feed.library.api.internal.protocoladapter.ProtocolAdapter;
-import org.chromium.chrome.browser.feed.library.api.internal.requestmanager.FeedRequestManager;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.MainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue.TaskType;
-import org.chromium.chrome.browser.feed.library.common.concurrent.testing.FakeThreadUtils;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamToken;
-import org.chromium.components.feed.core.proto.wire.ConsistencyTokenProto.ConsistencyToken;
-import org.chromium.components.feed.core.proto.wire.ResponseProto.Response;
-
-import java.util.ArrayDeque;
-import java.util.Queue;
-
-/**
- * Fake implementation of a {@link FeedRequestManager}. This acts a Queue of responses which will be
- * sent through the {@link ProtocolAdapter} to create the {@code List<StreamDataOperation>} which is
- * then returned as a {@link Result} to the {@link Consumer}.
- */
-public class FakeFeedRequestManager implements FeedRequestManager {
-    private final FakeThreadUtils mFakeThreadUtils;
-    private final MainThreadRunner mMainThreadRunner;
-    private final ProtocolAdapter mProtocolAdapter;
-    private final Queue<ResponseWithDelay> mResponses = new ArrayDeque<>();
-    private final TaskQueue mTaskQueue;
-    @Nullable
-    private StreamToken mLatestStreamToken;
-    @RequestReason
-    private int mLatestRequestReason = RequestReason.UNKNOWN;
-
-    public FakeFeedRequestManager(FakeThreadUtils fakeThreadUtils,
-            MainThreadRunner mainThreadRunner, ProtocolAdapter protocolAdapter,
-            TaskQueue taskQueue) {
-        this.mFakeThreadUtils = fakeThreadUtils;
-        this.mMainThreadRunner = mainThreadRunner;
-        this.mProtocolAdapter = protocolAdapter;
-        this.mTaskQueue = taskQueue;
-    }
-
-    // TODO: queue responses for action uploads
-    /** Adds a Response to the queue. */
-    public FakeFeedRequestManager queueResponse(Response response) {
-        return queueResponse(response, /* delayMs= */ 0);
-    }
-
-    /** Adds a Response to the queue with a delay. */
-    public FakeFeedRequestManager queueResponse(Response response, long delayMs) {
-        mResponses.add(new ResponseWithDelay(response, delayMs));
-        return this;
-    }
-
-    /** Adds an error to the queue. */
-    public FakeFeedRequestManager queueError() {
-        return queueError(/* delayMs= */ 0);
-    }
-
-    /** Adds an error to the queue with a delay. */
-    public FakeFeedRequestManager queueError(long delayMs) {
-        mResponses.add(new ResponseWithDelay(delayMs));
-        return this;
-    }
-
-    @Override
-    public void loadMore(
-            StreamToken streamToken, ConsistencyToken token, Consumer<Result<Model>> consumer) {
-        mFakeThreadUtils.checkNotMainThread();
-        mLatestStreamToken = streamToken;
-        handleResponseWithDelay(mResponses.remove(), consumer);
-    }
-
-    @Override
-    public void triggerRefresh(@RequestReason int reason, Consumer<Result<Model>> consumer) {
-        triggerRefresh(reason, ConsistencyToken.getDefaultInstance(), consumer);
-    }
-
-    @Override
-    public void triggerRefresh(
-            @RequestReason int reason, ConsistencyToken token, Consumer<Result<Model>> consumer) {
-        mLatestRequestReason = reason;
-        ResponseWithDelay responseWithDelay = mResponses.remove();
-        mTaskQueue.execute(Task.UNKNOWN, TaskType.HEAD_INVALIDATE,
-                () -> { handleResponseWithDelay(responseWithDelay, consumer); });
-    }
-
-    private void handleResponseWithDelay(
-            ResponseWithDelay responseWithDelay, Consumer<Result<Model>> consumer) {
-        if (responseWithDelay.mDelayMs > 0) {
-            mMainThreadRunner.executeWithDelay("FakeFeedRequestManager#consumer", () -> {
-                invokeConsumer(responseWithDelay, consumer);
-            }, responseWithDelay.mDelayMs);
-        } else {
-            invokeConsumer(responseWithDelay, consumer);
-        }
-    }
-
-    private void invokeConsumer(
-            ResponseWithDelay responseWithDelay, Consumer<Result<Model>> consumer) {
-        boolean policy = mFakeThreadUtils.enforceMainThread(true);
-        if (responseWithDelay.mIsError) {
-            consumer.accept(Result.failure());
-        } else {
-            consumer.accept(mProtocolAdapter.createModel(responseWithDelay.mResponse));
-        }
-        mFakeThreadUtils.enforceMainThread(policy);
-    }
-
-    /** Returns the latest {@link StreamToken} passed in to the {@link FeedRequestManager}. */
-    @Nullable
-    public StreamToken getLatestStreamToken() {
-        return mLatestStreamToken;
-    }
-
-    /**
-     * Returns the latest {@link RequestReason} passed in to the {@link FeedRequestManager}. Returns
-     * {@literal RequestReason.UNKNOWN} if the request manager has not been invoked.
-     */
-    @RequestReason
-    public int getLatestRequestReason() {
-        return mLatestRequestReason;
-    }
-
-    private static final class ResponseWithDelay {
-        private final Response mResponse;
-        private final boolean mIsError;
-        private final long mDelayMs;
-
-        private ResponseWithDelay(Response response, long delayMs) {
-            this.mResponse = response;
-            this.mDelayMs = delayMs;
-            mIsError = false;
-        }
-
-        private ResponseWithDelay(long delayMs) {
-            this.mResponse = Response.getDefaultInstance();
-            this.mDelayMs = delayMs;
-            mIsError = true;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/shadows/ExtendedShadowLinearLayout.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/shadows/ExtendedShadowLinearLayout.java
deleted file mode 100644
index 181a191..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/shadows/ExtendedShadowLinearLayout.java
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.shadows;
-
-import android.widget.LinearLayout;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.shadows.ShadowLinearLayout;
-
-/**
- * Robolectric Shadow for {@link LinearLayout}.
- *
- * <p>Provides functionality to test view position.
- */
-@Implements(LinearLayout.class)
-public class ExtendedShadowLinearLayout extends ShadowLinearLayout {
-    private int mXLocation;
-    private int mYLocation;
-    private int mHeight;
-    private int mWidth;
-    private boolean mAttached;
-
-    @Implementation
-    public void getLocationOnScreen(int[] pos) {
-        pos[0] = mXLocation;
-        pos[1] = mYLocation;
-    }
-
-    public void setLocationOnScreen(int x, int y) {
-        mXLocation = x;
-        mYLocation = y;
-    }
-
-    @Implementation
-    public void getLocationInWindow(int[] pos) {
-        pos[0] = mXLocation;
-        pos[1] = mYLocation;
-    }
-
-    public void setLocationInWindow(int x, int y) {
-        mXLocation = x;
-        mYLocation = y;
-    }
-
-    @Override
-    @Implementation
-    public boolean isAttachedToWindow() {
-        return mAttached;
-    }
-
-    public void setAttachedToWindow(boolean attached) {
-        this.mAttached = attached;
-    }
-
-    @Implementation
-    public int getHeight() {
-        return mHeight;
-    }
-
-    public void setHeight(int height) {
-        this.mHeight = height;
-    }
-
-    @Implementation
-    public int getWidth() {
-        return mWidth;
-    }
-
-    public void setWidth(int width) {
-        this.mWidth = width;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/shadows/ExtendedShadowView.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/shadows/ExtendedShadowView.java
deleted file mode 100644
index 023a7ad..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/shadows/ExtendedShadowView.java
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.shadows;
-
-import android.view.View;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.shadows.ShadowView;
-
-/**
- * Robolectric Shadow for {@link View}.
- *
- * <p>Provides functionality to test view position.
- */
-@Implements(View.class)
-public class ExtendedShadowView extends ShadowView {
-    private int mXLocation;
-    private int mYLocation;
-    private int mHeight;
-    private int mWidth;
-    private boolean mAttached;
-
-    @Implementation
-    public void getLocationOnScreen(int[] pos) {
-        pos[0] = mXLocation;
-        pos[1] = mYLocation;
-    }
-
-    public void setLocationOnScreen(int x, int y) {
-        mXLocation = x;
-        mYLocation = y;
-    }
-
-    @Implementation
-    public void getLocationInWindow(int[] pos) {
-        pos[0] = mXLocation;
-        pos[1] = mYLocation;
-    }
-
-    public void setLocationInWindow(int x, int y) {
-        mXLocation = x;
-        mYLocation = y;
-    }
-
-    @Override
-    @Implementation
-    public boolean isAttachedToWindow() {
-        return mAttached;
-    }
-
-    public void setAttachedToWindow(boolean attached) {
-        this.mAttached = attached;
-    }
-
-    @Implementation
-    public int getHeight() {
-        return mHeight;
-    }
-
-    public void setHeight(int height) {
-        this.mHeight = height;
-    }
-
-    @Implementation
-    public int getWidth() {
-        return mWidth;
-    }
-
-    public void setWidth(int width) {
-        this.mWidth = width;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/shadows/ShadowRecycledViewPool.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/shadows/ShadowRecycledViewPool.java
deleted file mode 100644
index c84db41..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/shadows/ShadowRecycledViewPool.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.shadows;
-
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-
-/**
- * Shadow for {@link RecyclerView.RecycledViewPool} which is able to give information on when the
- * pool has been cleared.
- *
- * <p>{@link ViewHolder#getItemViewType()} is used as the keys for pools; however, this field is
- * final. That means a special adapters needs to be created in order to handle all this. This shadow
- * helps so all this infrastructure isn't needed.
- */
-@Implements(RecyclerView.RecycledViewPool.class)
-public class ShadowRecycledViewPool {
-    private int mClearCount;
-
-    @Implementation
-    public void clear() {
-        mClearCount++;
-    }
-
-    public int getClearCallCount() {
-        return mClearCount;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/sharedstream/contextmenumanager/FakeContextMenuManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/sharedstream/contextmenumanager/FakeContextMenuManager.java
deleted file mode 100644
index 956aa06f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/sharedstream/contextmenumanager/FakeContextMenuManager.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.sharedstream.contextmenumanager;
-
-import static org.chromium.chrome.browser.feed.library.common.Validators.checkNotNull;
-
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.sharedstream.contextmenumanager.ContextMenuManager;
-
-import java.util.List;
-
-/** Fake to be used to test {@link ContextMenuManager}. */
-public class FakeContextMenuManager implements ContextMenuManager {
-    private boolean mIsMenuOpened;
-    @Nullable
-    private List<String> mItems;
-    @Nullable
-    private ContextMenuClickHandler mHandler;
-
-    @Override
-    public boolean openContextMenu(
-            View anchorView, List<String> items, ContextMenuClickHandler handler) {
-        if (mIsMenuOpened) {
-            return false;
-        }
-
-        mIsMenuOpened = true;
-        this.mItems = items;
-        this.mHandler = handler;
-
-        return true;
-    }
-
-    @Override
-    public void dismissPopup() {
-        mIsMenuOpened = false;
-        mItems = null;
-        mHandler = null;
-    }
-
-    @Override
-    public void setView(View view) {}
-
-    public void performClick(int position) {
-        if (!mIsMenuOpened) {
-            throw new IllegalStateException("Cannot perform click with no menu opened.");
-        }
-
-        checkNotNull(mHandler).handleClick(position);
-    }
-
-    public List<String> getMenuOptions() {
-        if (!mIsMenuOpened) {
-            throw new IllegalStateException("No menu open.");
-        }
-
-        return checkNotNull(mItems);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/sharedstream/offlinemonitor/FakeStreamOfflineMonitor.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/sharedstream/offlinemonitor/FakeStreamOfflineMonitor.java
deleted file mode 100644
index ab566719..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/sharedstream/offlinemonitor/FakeStreamOfflineMonitor.java
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.sharedstream.offlinemonitor;
-
-import org.chromium.chrome.browser.feed.library.sharedstream.offlinemonitor.StreamOfflineMonitor;
-import org.chromium.chrome.browser.feed.library.testing.host.offlineindicator.FakeOfflineIndicatorApi;
-
-/** Fake used for tests using the {@link StreamOfflineMonitor}. */
-public class FakeStreamOfflineMonitor extends StreamOfflineMonitor {
-    private final FakeOfflineIndicatorApi mFakeIndicatorApi;
-    private boolean mOfflineStatusRequested;
-
-    /**
-     * Creates a {@link FakeStreamOfflineMonitor} with the given {@link FakeOfflineIndicatorApi}.
-     */
-    public static FakeStreamOfflineMonitor createWithOfflineIndicatorApi(
-            FakeOfflineIndicatorApi offlineIndicatorApi) {
-        return new FakeStreamOfflineMonitor(offlineIndicatorApi);
-    }
-
-    /**
-     * Creates a {@link FakeStreamOfflineMonitor} with a default {@link FakeOfflineIndicatorApi}.
-     */
-    public static FakeStreamOfflineMonitor create() {
-        return new FakeStreamOfflineMonitor(FakeOfflineIndicatorApi.createWithNoOfflineUrls());
-    }
-
-    private FakeStreamOfflineMonitor(FakeOfflineIndicatorApi offlineIndicatorApi) {
-        super(offlineIndicatorApi);
-        this.mFakeIndicatorApi = offlineIndicatorApi;
-    }
-
-    /** Sets the offline status for the given {@code url}. */
-    public void setOfflineStatus(String url, boolean isAvailable) {
-        // Check if the url is available to marks the url as something to request from the
-        // OfflineIndicatorApi.
-        isAvailableOffline(url);
-
-        // Sets the status of the url with the api, which is the source of truth.
-        mFakeIndicatorApi.setOfflineStatus(url, isAvailable);
-
-        // Triggers notification to any current listeners, namely the superclass of this fake.
-        requestOfflineStatusForNewContent();
-    }
-
-    /** Returns the count of how many observers there are for offline status. */
-    public int getOfflineStatusConsumerCount() {
-        return mOfflineStatusConsumersMap.size();
-    }
-
-    @Override
-    public void requestOfflineStatusForNewContent() {
-        mOfflineStatusRequested = true;
-        super.requestOfflineStatusForNewContent();
-    }
-
-    public boolean isOfflineStatusRequested() {
-        return mOfflineStatusRequested;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/store/FakeStore.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/store/FakeStore.java
deleted file mode 100644
index fd4e769..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/store/FakeStore.java
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.library.testing.store;
-
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.internal.common.PayloadWithId;
-import org.chromium.chrome.browser.feed.library.api.internal.store.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SemanticPropertiesMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.SessionMutation;
-import org.chromium.chrome.browser.feed.library.api.internal.store.UploadableActionMutation;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.common.concurrent.TaskQueue;
-import org.chromium.chrome.browser.feed.library.common.concurrent.testing.FakeMainThreadRunner;
-import org.chromium.chrome.browser.feed.library.common.concurrent.testing.FakeThreadUtils;
-import org.chromium.chrome.browser.feed.library.common.protoextensions.FeedExtensionRegistry;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.library.common.time.TimingUtils;
-import org.chromium.chrome.browser.feed.library.feedstore.FeedStore;
-import org.chromium.chrome.browser.feed.library.hostimpl.storage.testing.InMemoryContentStorage;
-import org.chromium.chrome.browser.feed.library.hostimpl.storage.testing.InMemoryJournalStorage;
-import org.chromium.chrome.browser.feed.library.testing.host.logging.FakeBasicLoggingApi;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamPayload;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamSharedState;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamStructure;
-import org.chromium.components.feed.core.proto.libraries.api.internal.StreamDataProto.StreamUploadableAction;
-import org.chromium.components.feed.core.proto.wire.SemanticPropertiesProto.SemanticProperties;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Fake implementation of {@link
- * org.chromium.chrome.browser.feed.library.api.internal.store.Store}.
- */
-public final class FakeStore extends FeedStore {
-    private final FakeThreadUtils mFakeThreadUtils;
-    private boolean mAllowCreateNewSession = true;
-    private boolean mAllowEditContent = true;
-    private boolean mAllowGetPayloads = true;
-    private boolean mAllowGetStreamStructures = true;
-    private boolean mAllowGetSharedStates = true;
-    private boolean mClearHeadCalled;
-
-    public FakeStore(Configuration configuration, FakeThreadUtils fakeThreadUtils,
-            TaskQueue taskQueue, Clock clock) {
-        super(configuration, new TimingUtils(), new FeedExtensionRegistry(ArrayList::new),
-                new InMemoryContentStorage(), new InMemoryJournalStorage(), fakeThreadUtils,
-                taskQueue, clock, new FakeBasicLoggingApi(),
-                FakeMainThreadRunner.runTasksImmediately());
-        this.mFakeThreadUtils = fakeThreadUtils;
-    }
-
-    @Override
-    public Result<List<PayloadWithId>> getPayloads(List<String> contentIds) {
-        if (!mAllowGetPayloads) {
-            return Result.failure();
-        }
-
-        return super.getPayloads(contentIds);
-    }
-
-    @Override
-    public Result<List<StreamStructure>> getStreamStructures(String sessionId) {
-        if (!mAllowGetStreamStructures) {
-            return Result.failure();
-        }
-
-        return super.getStreamStructures(sessionId);
-    }
-
-    @Override
-    public void clearHead() {
-        mClearHeadCalled = true;
-        super.clearHead();
-    }
-
-    @Override
-    public Result<String> createNewSession() {
-        if (!mAllowCreateNewSession) {
-            return Result.failure();
-        }
-
-        return super.createNewSession();
-    }
-
-    @Override
-    public Result<List<StreamSharedState>> getSharedStates() {
-        if (!mAllowGetSharedStates) {
-            return Result.failure();
-        }
-
-        return super.getSharedStates();
-    }
-
-    @Override
-    public ContentMutation editContent() {
-        if (!mAllowEditContent) {
-            return new ContentMutation() {
-                @Override
-                public ContentMutation add(String contentId, StreamPayload payload) {
-                    return this;
-                }
-
-                @Override
-                public CommitResult commit() {
-                    return CommitResult.FAILURE;
-                }
-            };
-        }
-
-        return super.editContent();
-    }
-
-    /** Returns if {@link FeedStore#clearAll()} was called. */
-    public boolean getClearHeadCalled() {
-        return mClearHeadCalled;
-    }
-
-    /** Clears all content storage. */
-    public FakeStore clearContent() {
-        mContentStorage.commit(
-                new org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation
-                        .Builder()
-                        .deleteAll()
-                        .build());
-        return this;
-    }
-
-    /** Sets whether to fail on calls to {@link getStreamStructures(String)}. */
-    public FakeStore setAllowGetStreamStructures(boolean value) {
-        mAllowGetStreamStructures = value;
-        return this;
-    }
-
-    /** Sets whether to fail on calls to {@link editContent()}. */
-    public FakeStore setAllowEditContent(boolean value) {
-        mAllowEditContent = value;
-        return this;
-    }
-
-    /** Sets whether to fail on calls to {@link createNewSession()}. */
-    public FakeStore setAllowCreateNewSession(boolean value) {
-        mAllowCreateNewSession = value;
-        return this;
-    }
-
-    /** Sets whether to fail on calls to {@link getPayloads(List)}. */
-    public FakeStore setAllowGetPayloads(boolean value) {
-        mAllowGetPayloads = value;
-        return this;
-    }
-
-    /** Sets whether to fail on calls to {@link getSharedStates()}. */
-    public FakeStore setAllowGetSharedStates(boolean value) {
-        mAllowGetSharedStates = value;
-        return this;
-    }
-
-    /** Adds the {@code payload} to the store. */
-    public FakeStore setContent(String contentId, StreamPayload payload) {
-        boolean policy = mFakeThreadUtils.enforceMainThread(false);
-        editContent().add(contentId, payload).commit();
-        mFakeThreadUtils.enforceMainThread(policy);
-        return this;
-    }
-
-    /** Adds the {@code payloads} to the store. */
-    public FakeStore setContent(List<PayloadWithId> payloads) {
-        boolean policy = mFakeThreadUtils.enforceMainThread(false);
-        ContentMutation mutation = editContent();
-        for (PayloadWithId payload : payloads) {
-            mutation.add(payload.contentId, payload.payload);
-        }
-        mutation.commit();
-        mFakeThreadUtils.enforceMainThread(policy);
-        return this;
-    }
-
-    /** Adds the {@code sharedStates} to the store. */
-    public FakeStore setSharedStates(StreamSharedState... sharedStates) {
-        boolean policy = mFakeThreadUtils.enforceMainThread(false);
-        ContentMutation mutation = editContent();
-        for (StreamSharedState sharedState : sharedStates) {
-            mutation.add(sharedState.getContentId(),
-                    StreamPayload.newBuilder().setStreamSharedState(sharedState).build());
-        }
-        mutation.commit();
-        mFakeThreadUtils.enforceMainThread(policy);
-        return this;
-    }
-
-    /** Adds the {@code structures} to the store for the specified {@code sessionId}. */
-    public FakeStore setStreamStructures(String sessionId, StreamStructure... structures) {
-        return setStreamStructures(sessionId, Arrays.asList(structures));
-    }
-
-    /** Adds the {@code structures} to the store for the specified {@code sessionId}. */
-    public FakeStore setStreamStructures(String sessionId, List<StreamStructure> structures) {
-        boolean policy = mFakeThreadUtils.enforceMainThread(false);
-        SessionMutation mutation = editSession(sessionId);
-        for (StreamStructure structure : structures) {
-            mutation.add(structure);
-        }
-        mutation.commit();
-        mFakeThreadUtils.enforceMainThread(policy);
-        return this;
-    }
-
-    /** Adds the {@code actions} to the store. */
-    public FakeStore setStreamUploadableActions(StreamUploadableAction... actions) {
-        boolean policy = mFakeThreadUtils.enforceMainThread(false);
-        UploadableActionMutation mutation = editUploadableActions();
-        for (StreamUploadableAction action : actions) {
-            mutation.upsert(action, action.getFeatureContentId());
-        }
-        mutation.commit();
-        mFakeThreadUtils.enforceMainThread(policy);
-        return this;
-    }
-
-    /** Adds the {@code actions} to the store. */
-    public FakeStore addSemanticProperties(String contentId, SemanticProperties properties) {
-        boolean policy = mFakeThreadUtils.enforceMainThread(false);
-        SemanticPropertiesMutation mutation = editSemanticProperties();
-        mutation.add(contentId, properties.getSemanticPropertiesData());
-        mutation.commit();
-        mFakeThreadUtils.enforceMainThread(policy);
-        return this;
-    }
-
-    /** Gets all content associated with the {@code contentId}. */
-    public List<Object> getContentById(String contentId) {
-        boolean policy = mFakeThreadUtils.enforceMainThread(false);
-        ArrayList<String> contentIds = new ArrayList<>(1);
-        contentIds.add(contentId);
-        ArrayList<Object> result = new ArrayList<>();
-        result.addAll(getPayloads(contentIds).getValue());
-        result.addAll(getSemanticProperties(contentIds).getValue());
-        for (StreamUploadableAction action : getAllUploadableActions().getValue()) {
-            if (action.getFeatureContentId().equals(contentId)) {
-                result.add(action);
-            }
-        }
-        mFakeThreadUtils.enforceMainThread(policy);
-        return result;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/FeedFeatures.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/FeedFeatures.java
index 7c6cfa51d..728e4fc2 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/FeedFeatures.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/FeedFeatures.java
@@ -5,8 +5,6 @@
 package org.chromium.chrome.browser.feed.shared;
 
 import org.chromium.base.Log;
-import org.chromium.chrome.browser.feed.FeedV1;
-import org.chromium.chrome.browser.feed.FeedV2;
 import org.chromium.chrome.browser.flags.CachedFeatureFlags;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.preferences.Pref;
@@ -47,15 +45,11 @@
     }
 
     public static boolean isV2Enabled() {
-        if (!FeedV1.IS_AVAILABLE) return true;
-        if (!FeedV2.IS_AVAILABLE) return false;
-        return ChromeFeatureList.isEnabled(ChromeFeatureList.INTEREST_FEED_V2);
+        return true;
     }
 
     public static boolean cachedIsV2Enabled() {
-        if (!FeedV1.IS_AVAILABLE) return true;
-        if (!FeedV2.IS_AVAILABLE) return false;
-        return CachedFeatureFlags.isEnabled(ChromeFeatureList.INTEREST_FEED_V2);
+        return true;
     }
 
     /**
@@ -93,9 +87,6 @@
             // logcat.
             Log.w(TAG, "Disabling Feed because of policy.");
             sEverDisabledForPolicy = true;
-            if (FeedV1.IS_AVAILABLE) {
-                FeedV1.destroy();
-            }
         }
     }
 
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/DEPS b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/DEPS
deleted file mode 100644
index a813f4c..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
-  "+chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library",
-]
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedActionHandler.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedActionHandler.java
deleted file mode 100644
index a1eb50d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedActionHandler.java
+++ /dev/null
@@ -1,214 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import android.app.Activity;
-
-import androidx.annotation.NonNull;
-
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.chrome.browser.feed.FeedV1ActionOptions;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.ContentMetadata;
-import org.chromium.chrome.browser.feed.library.api.host.action.ActionApi;
-import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncherImpl;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.native_page.NativePageNavigationDelegate;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.suggestions.NavigationRecorder;
-import org.chromium.chrome.browser.suggestions.SuggestionsConfig;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.components.embedder_support.util.UrlUtilities;
-import org.chromium.content_public.browser.LoadUrlParams;
-import org.chromium.content_public.common.Referrer;
-import org.chromium.network.mojom.ReferrerPolicy;
-import org.chromium.ui.base.PageTransition;
-import org.chromium.ui.mojom.WindowOpenDisposition;
-
-import java.util.HashMap;
-
-/**
- * Handles the actions user can trigger on the feed.
- */
-public class FeedActionHandler implements ActionApi {
-    private final FeedV1ActionOptions mOptions;
-    private final NativePageNavigationDelegate mDelegate;
-    private final Runnable mSuggestionConsumedObserver;
-    private final FeedLoggingBridge mLoggingBridge;
-    private final Activity mActivity;
-    private final Profile mProfile;
-    private static final String TAG = "FeedActionHandler";
-    private static final String FEEDBACK_REPORT_TYPE =
-            "com.google.chrome.feed.USER_INITIATED_FEEDBACK_REPORT";
-
-    // This must match the FeedSendFeedbackType enum in enums.xml.
-    public @interface FeedFeedbackType {
-        int FEEDBACK_TAPPED_ON_CARD = 0;
-        int FEEDBACK_TAPPED_ON_PAGE = 1;
-        int NUM_ENTRIES = 2;
-    }
-
-    // Map key names - These will be printed with the values in the feedback report.
-    public static final String CARD_URL = "CardUrl";
-    public static final String CARD_PUBLISHER = "CardPublisher";
-    public static final String CARD_PUBLISHING_DATE = "CardPublishingDate";
-    public static final String CARD_TITLE = "CardTitle";
-
-    /**
-     * @param delegate The {@link NativePageNavigationDelegate} that this handler calls when
-     * handling some of the actions.
-     * @param suggestionConsumedObserver An observer that is interested in any time a suggestion is
-     * consumed by the user.
-     * @param loggingBridge Reports pages visiting time.
-     */
-    public FeedActionHandler(FeedV1ActionOptions options,
-            @NonNull NativePageNavigationDelegate delegate,
-            @NonNull Runnable suggestionConsumedObserver, @NonNull FeedLoggingBridge loggingBridge,
-            Activity activity, Profile profile) {
-        mOptions = options;
-        mDelegate = delegate;
-        mSuggestionConsumedObserver = suggestionConsumedObserver;
-        mLoggingBridge = loggingBridge;
-        mActivity = activity;
-        mProfile = profile;
-    }
-
-    @Override
-    public void openUrl(String url) {
-        openAndRecord(WindowOpenDisposition.CURRENT_TAB, createLoadUrlParams(url));
-        mLoggingBridge.reportFeedInteraction();
-    }
-
-    @Override
-    public boolean canOpenUrl() {
-        return true;
-    }
-
-    @Override
-    public void openUrlInIncognitoMode(String url) {
-        assert !mOptions.inhibitOpenInIncognito;
-        mDelegate.openUrl(WindowOpenDisposition.OFF_THE_RECORD, createLoadUrlParams(url));
-        mSuggestionConsumedObserver.run();
-        mLoggingBridge.reportFeedInteraction();
-    }
-
-    @Override
-    public boolean canOpenUrlInIncognitoMode() {
-        return !mOptions.inhibitOpenInIncognito && mDelegate.isOpenInIncognitoEnabled();
-    }
-
-    @Override
-    public void openUrlInNewTab(String url) {
-        assert !mOptions.inhibitOpenInNewTab;
-        openAndRecord(WindowOpenDisposition.NEW_BACKGROUND_TAB, createLoadUrlParams(url));
-        mLoggingBridge.reportFeedInteraction();
-    }
-
-    @Override
-    public boolean canOpenUrlInNewTab() {
-        return !mOptions.inhibitOpenInNewTab;
-    }
-
-    @Override
-    public void openUrlInNewWindow(String url) {
-        openAndRecord(WindowOpenDisposition.NEW_WINDOW, createLoadUrlParams(url));
-    }
-
-    @Override
-    public boolean canOpenUrlInNewWindow() {
-        return mDelegate.isOpenInNewWindowEnabled();
-    }
-
-    @Override
-    public void downloadUrl(ContentMetadata contentMetadata) {
-        assert !mOptions.inhibitDownload;
-        mDelegate.openUrl(
-                WindowOpenDisposition.SAVE_TO_DISK, createLoadUrlParams(contentMetadata.getUrl()));
-        mSuggestionConsumedObserver.run();
-        mLoggingBridge.reportFeedInteraction();
-    }
-
-    @Override
-    public boolean canDownloadUrl() {
-        return !mOptions.inhibitDownload;
-    }
-
-    @Override
-    public void sendFeedback(ContentMetadata contentMetadata) {
-        RecordHistogram.recordEnumeratedHistogram("ContentSuggestions.Feed.SendFeedback",
-                FeedFeedbackType.FEEDBACK_TAPPED_ON_CARD, FeedFeedbackType.NUM_ENTRIES);
-        HashMap<String, String> feedContext = new HashMap<String, String>();
-
-        if (contentMetadata != null) {
-            // Get the pieces of metadata that we need.
-            String articlePublishingDate = String.valueOf(contentMetadata.getTimePublished());
-            String articleUrl = contentMetadata.getUrl();
-            String title = contentMetadata.getTitle();
-            String originalPublisher = contentMetadata.getPublisher();
-            // TODO(https://crbug.com/1992269) - Get the other data to add in.
-
-            // Fill the context map with the card specific data.
-            feedContext.put(CARD_URL, articleUrl);
-            feedContext.put(CARD_PUBLISHER, originalPublisher);
-            feedContext.put(CARD_PUBLISHING_DATE, articlePublishingDate);
-            feedContext.put(CARD_TITLE, title);
-        }
-
-        // Identifies this feedback as coming from chrome android (as opposed to desktop).
-        // This string is not used for allow list matching on the server.
-        String feedbackContext = "mobile_browser";
-        // Reports for Chrome mobile must have a contextTag of the form
-        // com.chrome.feed.USER_INITIATED_FEEDBACK_REPORT, or they will be discarded
-        // for not matching an allow list rule.
-        String contextTag = FEEDBACK_REPORT_TYPE;
-
-        HelpAndFeedbackLauncherImpl.getInstance().showFeedback(mActivity, mProfile,
-                contentMetadata.getUrl(), contextTag, feedContext, feedbackContext);
-        mLoggingBridge.reportFeedInteraction();
-        return;
-    }
-
-    @Override
-    public void learnMore() {
-        assert !mOptions.inhibitLearnMore;
-        mDelegate.navigateToHelpPage();
-        mLoggingBridge.reportFeedInteraction();
-    }
-
-    @Override
-    public boolean canLearnMore() {
-        return !mOptions.inhibitLearnMore;
-    }
-
-    private LoadUrlParams createLoadUrlParams(String url) {
-        LoadUrlParams params = new LoadUrlParams(url, PageTransition.AUTO_BOOKMARK);
-        params.setReferrer(
-                new Referrer(SuggestionsConfig.getReferrerUrl(
-                                     ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS),
-                        // WARNING: ReferrerPolicy.ALWAYS is assumed by other Chrome code for NTP
-                        // tiles to set consider_for_ntp_most_visited.
-                        ReferrerPolicy.ALWAYS));
-        return params;
-    }
-
-    /**
-     * Opens the given resource, specified by params, and records how much time the user spends on
-     * the suggested page.
-     *
-     * @param disposition How to open the article.
-     * @param loadUrlParams Parameters specifying the URL to load and other navigation details.
-     */
-    private void openAndRecord(int disposition, LoadUrlParams loadUrlParams) {
-        Tab loadingTab = mDelegate.openUrl(disposition, loadUrlParams);
-        if (loadingTab != null) {
-            // Records how long the user spending on the suggested page, and whether the user got
-            // back to the NTP.
-            NavigationRecorder.record(loadingTab,
-                    visitData
-                    -> mLoggingBridge.onContentTargetVisited(
-                            visitData.duration, UrlUtilities.isNTPUrl(visitData.endUrl)));
-        }
-        mSuggestionConsumedObserver.run();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedAppLifecycle.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedAppLifecycle.java
deleted file mode 100644
index c65efb53..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedAppLifecycle.java
+++ /dev/null
@@ -1,231 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import android.app.Activity;
-
-import androidx.annotation.IntDef;
-
-import org.chromium.base.ActivityState;
-import org.chromium.base.ApplicationStatus;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.chrome.browser.ChromeTabbedActivity;
-import org.chromium.chrome.browser.DeferredStartupHandler;
-import org.chromium.chrome.browser.feed.library.api.client.lifecycle.AppLifecycleListener;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
-import org.chromium.chrome.browser.signin.services.SigninManager;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Aggregation point for application lifecycle events that the Feed cares about. Events that
- * originate in Java flow directly to FeedAppLifecycle, while native-originating events arrive
- * via {@link FeedLifecycleBridge}.
- */
-public class FeedAppLifecycle
-        implements SigninManager.SignInStateObserver, ApplicationStatus.ActivityStateListener {
-    // Intdef used to assign each event a number for metrics logging purposes. This maps directly to
-    // the AppLifecycleEvent enum defined in tools/metrics/enums.xml
-    @IntDef({AppLifecycleEvent.ENTER_FOREGROUND, AppLifecycleEvent.ENTER_BACKGROUND,
-            AppLifecycleEvent.CLEAR_ALL, AppLifecycleEvent.INITIALIZE, AppLifecycleEvent.SIGN_IN,
-            AppLifecycleEvent.SIGN_OUT, AppLifecycleEvent.HISTORY_DELETED,
-            AppLifecycleEvent.CACHED_DATA_CLEARED})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface AppLifecycleEvent {
-        int ENTER_FOREGROUND = 0;
-        int ENTER_BACKGROUND = 1;
-        int CLEAR_ALL = 2;
-        int INITIALIZE = 3;
-        int SIGN_IN = 4;
-        int SIGN_OUT = 5;
-        int HISTORY_DELETED = 6;
-        int CACHED_DATA_CLEARED = 7;
-        int NUM_ENTRIES = 8;
-    }
-
-    private AppLifecycleListener mAppLifecycleListener;
-    private FeedLifecycleBridge mLifecycleBridge;
-    private FeedScheduler mFeedScheduler;
-
-    private int mTabbedActivityCount;
-    private boolean mInitializeCalled;
-    private boolean mDelayedInitializeStarted;
-
-    /**
-     * Create a FeedAppLifecycle instance. In normal use, this should only be called by {@link
-     * FeedAppLifecycleFactory}.
-     * @param appLifecycleListener The Feed-side instance of the {@link AppLifecycleListener}
-     *        interface that we will call into.
-     * @param lifecycleBridge FeedLifecycleBridge JNI bridge over which native lifecycle events are
-     *        delivered.
-     * @param feedScheduler Scheduler to be notified of several events.
-     */
-    public FeedAppLifecycle(AppLifecycleListener appLifecycleListener,
-            FeedLifecycleBridge lifecycleBridge, FeedScheduler feedScheduler) {
-        mAppLifecycleListener = appLifecycleListener;
-        mLifecycleBridge = lifecycleBridge;
-        mFeedScheduler = feedScheduler;
-
-        int resumedActivityCount = 0;
-        for (Activity activity : ApplicationStatus.getRunningActivities()) {
-            if (activity instanceof ChromeTabbedActivity) {
-                @ActivityState
-                int activityState = ApplicationStatus.getStateForActivity(activity);
-                if (activityState != ActivityState.STOPPED) {
-                    ++mTabbedActivityCount;
-                }
-                if (activityState == ActivityState.RESUMED) {
-                    ++resumedActivityCount;
-                }
-            }
-        }
-
-        if (mTabbedActivityCount > 0) {
-            onEnterForeground();
-        }
-        // The scheduler cares about Chrome entering the visual foreground, which corresponds to the
-        // RESUMED state. This state is entered regardless of whether or not the Activity was
-        // previously paused.
-        if (resumedActivityCount > 0) {
-            mFeedScheduler.onForegrounded();
-        }
-
-        ApplicationStatus.registerStateListenerForAllActivities(this);
-        IdentityServicesProvider.get()
-                .getSigninManager(Profile.getLastUsedRegularProfile())
-                .addSignInStateObserver(this);
-    }
-
-    /**
-     * This is called when an NTP is shown.
-     */
-    public void onNTPOpened() {
-        initialize();
-    }
-
-    /**
-     * This is called when the user has deleted some non-trivial number of history entries.
-     * We call onClearAll to avoid presenting personalized suggestions based on deleted history.
-     */
-    public void onHistoryDeleted() {
-        reportEvent(AppLifecycleEvent.HISTORY_DELETED);
-        onClearAll(/*suppressRefreshes*/ true);
-    }
-
-    /**
-     * This is called when cached browsing data is cleared. We call onClearAll so that the
-     * Feed deletes its cached browsing data.
-     */
-    public void onCachedDataCleared() {
-        reportEvent(AppLifecycleEvent.CACHED_DATA_CLEARED);
-        onClearAll(/*suppressRefreshes*/ false);
-    }
-
-    /**
-     * Unregisters listeners and cleans up any native resources held by FeedAppLifecycle.
-     */
-    public void destroy() {
-        IdentityServicesProvider.get()
-                .getSigninManager(Profile.getLastUsedRegularProfile())
-                .removeSignInStateObserver(this);
-        ApplicationStatus.unregisterActivityStateListener(this);
-        mLifecycleBridge.destroy();
-        mLifecycleBridge = null;
-        mAppLifecycleListener = null;
-        mFeedScheduler = null;
-    }
-
-    @Override
-    public void onActivityStateChange(Activity activity, @ActivityState int newState) {
-        // We only care about ChromeTabbedActivity since no other type of activity could potentially
-        // show the Feed.
-        if (activity != null && activity instanceof ChromeTabbedActivity) {
-            switch (newState) {
-                case ActivityState.STOPPED:
-                    --mTabbedActivityCount;
-                    if (mTabbedActivityCount == 0) {
-                        onEnterBackground();
-                    }
-                    break;
-                case ActivityState.STARTED:
-                    ++mTabbedActivityCount;
-                    if (mTabbedActivityCount == 1) {
-                        onEnterForeground();
-                    }
-                    break;
-                case ActivityState.RESUMED:
-                    mFeedScheduler.onForegrounded();
-                    break;
-            }
-        }
-    }
-
-    @Override
-    public void onSignedIn() {
-        reportEvent(AppLifecycleEvent.SIGN_IN);
-        onClearAll(/*suppressRefreshes*/ false);
-    }
-
-    @Override
-    public void onSignedOut() {
-        reportEvent(AppLifecycleEvent.SIGN_OUT);
-        onClearAll(/*suppressRefreshes*/ false);
-    }
-
-    private void onEnterForeground() {
-        reportEvent(AppLifecycleEvent.ENTER_FOREGROUND);
-        mAppLifecycleListener.onEnterForeground();
-
-        if (!mDelayedInitializeStarted) {
-            mDelayedInitializeStarted = true;
-            boolean initFeed = ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                    ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, "init_feed_after_startup",
-                    false);
-            if (initFeed) {
-                DeferredStartupHandler.getInstance().addDeferredTask(() -> {
-                    // Since this is being run asynchronously, it's possible #destroy() is called
-                    // before the delay finishes. Must guard against this.
-                    if (mLifecycleBridge != null) {
-                        initialize();
-                    }
-                });
-            }
-        }
-    }
-
-    private void onEnterBackground() {
-        reportEvent(AppLifecycleEvent.ENTER_BACKGROUND);
-        mAppLifecycleListener.onEnterBackground();
-    }
-
-    private void onClearAll(boolean suppressRefreshes) {
-        reportEvent(AppLifecycleEvent.CLEAR_ALL);
-        // Clearing and triggering refreshes are both asynchronous operations. The Feed is able to
-        // better coordinate them if {@link AppLifecycleListener#onClearAllWithRefresh} is called.
-        // If the scheduler returns true from {@link FeedScheduler#onArticlesCleared}, this means
-        // that it did not trigger the refresh, but is allowing us to do so.
-        if (mFeedScheduler.onArticlesCleared(suppressRefreshes)) {
-            mAppLifecycleListener.onClearAllWithRefresh();
-        } else {
-            mAppLifecycleListener.onClearAll();
-        }
-    }
-
-    private void initialize() {
-        if (!mInitializeCalled) {
-            reportEvent(AppLifecycleEvent.INITIALIZE);
-            mAppLifecycleListener.initialize();
-            mInitializeCalled = true;
-        }
-    }
-
-    private void reportEvent(@AppLifecycleEvent int event) {
-        RecordHistogram.recordEnumeratedHistogram("ContentSuggestions.Feed.AppLifecycle.Events",
-                event, AppLifecycleEvent.NUM_ENTRIES);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedApplicationInfo.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedApplicationInfo.java
deleted file mode 100644
index 0606d31..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedApplicationInfo.java
+++ /dev/null
@@ -1,78 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.BuildInfo;
-import org.chromium.base.ContextUtils;
-import org.chromium.chrome.browser.feed.library.api.host.config.ApplicationInfo;
-import org.chromium.components.version_info.Channel;
-import org.chromium.components.version_info.VersionConstants;
-
-/**
- * Logic to translate built in constants from ChromeVersionInfo into an {@link ApplicationInfo} the
- * Feed can consume.
- * */
-public final class FeedApplicationInfo {
-    /** Do not allow construction */
-    private FeedApplicationInfo() {}
-
-    // Constants to see if they are contained in the ABI string.
-    private static final String ABI_64_SUBSTRING = "64";
-    private static final String ABI_MIPS_SUBSTRING = "mips";
-    private static final String ABI_ARM_SUBSTRING = "arm";
-    private static final String ABI_X86_SUBSTRING = "x86";
-
-    /**
-     * @param abi The first ABI string returned by the Android API.
-     * @return Device architecture in a Feed consumable format.
-     */
-    @VisibleForTesting
-    static int getArchitecture(String abi) {
-        boolean is64 = abi.contains(ABI_64_SUBSTRING);
-        if (abi.contains(ABI_MIPS_SUBSTRING)) {
-            return is64 ? ApplicationInfo.Architecture.MIPS64 : ApplicationInfo.Architecture.MIPS;
-        } else if (abi.contains(ABI_ARM_SUBSTRING)) {
-            return is64 ? ApplicationInfo.Architecture.ARM64 : ApplicationInfo.Architecture.ARM;
-        } else if (abi.contains(ABI_X86_SUBSTRING)) {
-            return is64 ? ApplicationInfo.Architecture.X86_64 : ApplicationInfo.Architecture.X86;
-        } else {
-            return ApplicationInfo.Architecture.UNKNOWN_ACHITECTURE;
-        }
-    }
-
-    /**
-     * @channel The channel this was build for.
-     * @return Channel in a Feed consumable format.
-     */
-    @VisibleForTesting
-    static int getBuildType(@Channel int channel) {
-        switch (channel) {
-            case Channel.STABLE:
-                return ApplicationInfo.BuildType.RELEASE;
-            case Channel.BETA:
-                return ApplicationInfo.BuildType.BETA;
-            case Channel.DEV:
-                return ApplicationInfo.BuildType.ALPHA;
-            case Channel.CANARY:
-                return ApplicationInfo.BuildType.DEV;
-            default:
-                return ApplicationInfo.BuildType.UNKNOWN_BUILD_TYPE;
-        }
-    }
-
-    /**
-     * @return A fully built {@link ApplicationInfo }, ready to be given to the Feed.
-     */
-    public static ApplicationInfo createApplicationInfo() {
-        // Don't need to set the version string, it'll pick that up correctly on its own.
-        return new ApplicationInfo.Builder(ContextUtils.getApplicationContext())
-                .setAppType(ApplicationInfo.AppType.CHROME)
-                .setBuildType(getBuildType(VersionConstants.CHANNEL))
-                .setArchitecture(getArchitecture(BuildInfo.getInstance().abiString))
-                .build();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedConfiguration.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedConfiguration.java
deleted file mode 100644
index e14c6e2..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedConfiguration.java
+++ /dev/null
@@ -1,476 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import android.text.TextUtils;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-
-/**
- * Collection of configurable parameters and default values given to the Feed. Every getter passes
- * checks to see if it has been overridden by a field trail param.
- */
-public final class FeedConfiguration {
-    /** Do not allow construction */
-    private FeedConfiguration() {}
-
-    private static final String ABANDON_RESTORE_BELOW_FOLD = "abandon_restore_below_fold";
-    /** Default value for whether to restore below fold. */
-    public static final boolean ABANDON_RESTORE_BELOW_FOLD_DEFAULT = false;
-
-    private static final String CARD_MENU_TOOLTIP_ELIGIBLE = "card_menu_tooltip_eligible";
-    /** Default value for if card menus should have tooltips enabled. */
-    public static final boolean CARD_MENU_TOOLTIP_ELIGIBLE_DEFAULT = true;
-
-    private static final String CONSUME_SYNTHETIC_TOKENS = "consume_synthetic_tokens_bool";
-    /** Default value for whether to consumer synthetic tokens on load. */
-    public static final boolean CONSUME_SYNTHETIC_TOKENS_DEFAULT = false;
-
-    private static final String CONSUME_SYNTHETIC_TOKENS_WHILE_RESTORING =
-            "consume_synthetic_tokens_while_restoring_bool";
-    /** Default value for whether to consumer synthetic tokens on restore. */
-    public static final boolean CONSUME_SYNTHETIC_TOKENS_WHILE_RESTORING_DEFAULT = true;
-
-    private static final String DEFAULT_ACTION_TTL_SECONDS = "default_action_ttl_seconds";
-    /** Default value for the TTL of default action (25hrs). */
-    public static final long DEFAULT_ACTION_TTL_SECONDS_DEFAULT = 90000;
-
-    private static final String FEED_ACTION_SERVER_ENDPOINT = "feed_action_server_endpoint";
-    /** Default value for the endpoint used for recording uploaded actions to the server. */
-    public static final String FEED_ACTION_SERVER_ENDPOINT_DEFAULT =
-            "https://www.google.com/httpservice/retry/ClankActionUploadService/ClankActionUpload";
-
-    private static final String FEED_ACTION_SERVER_MAX_ACTIONS_PER_REQUEST =
-            "feed_action_server_max_actions_per_request";
-    /**
-     * Default value for maximum number of actions to be uploaded to the enpoint in a single
-     * request.
-     */
-    public static final long FEED_ACTION_SERVER_MAX_ACTIONS_PER_REQUEST_DEFAULT = 20;
-
-    private static final String FEED_ACTION_SERVER_MAX_SIZE_PER_REQUEST =
-            "feed_action_server_max_size_per_request";
-    /**
-     * Default value for maximum size in bytes of the request to be uploaded to the enpoint in a
-     * single request.
-     */
-    public static final long FEED_ACTION_SERVER_MAX_SIZE_PER_REQUEST_DEFAULT = 1000;
-
-    private static final String FEED_ACTION_SERVER_METHOD = "feed_action_server_method";
-    /** Default value for the HTTP method call to the feed action server (put/post/etc). */
-    public static final String FEED_ACTION_SERVER_METHOD_DEFAULT = "POST";
-
-    private static final String FEED_SERVER_ENDPOINT = "feed_server_endpoint";
-    /** Default value for server endpoint. */
-    public static final String FEED_SERVER_ENDPOINT_DEFAULT =
-            "https://www.google.com/httpservice/noretry/DiscoverClankService/FeedQuery";
-
-    private static final String FEED_SERVER_METHOD = "feed_server_method";
-    /** Default value for feed server method. */
-    public static final String FEED_SERVER_METHOD_DEFAULT = "GET";
-
-    private static final String FEED_SERVER_RESPONSE_LENGTH_PREFIXED =
-            "feed_server_response_length_prefixed";
-    /** Default value for feed server response length prefixed. */
-    public static final boolean FEED_SERVER_RESPONSE_LENGTH_PREFIXED_DEFAULT = true;
-
-    private static final String FEED_UI_ENABLED = "feed_ui_enabled";
-    /** Default value for the type of UI to request from the server. */
-    public static final boolean FEED_UI_ENABLED_DEFAULT = true;
-
-    private static final String INITIAL_NON_CACHED_PAGE_SIZE = "initial_non_cached_page_size";
-    /** Default value for initial non cached page size. */
-    public static final long INITIAL_NON_CACHED_PAGE_SIZE_DEFAULT = 10;
-
-    private static final String LIMIT_PAGE_UPDATES_IN_HEAD = "limit_page_updates_in_head";
-    /** Default value for whether to update HEAD when making a page request. */
-    public static final boolean LIMIT_PAGE_UPDATES_IN_HEAD_DEFAULT = false;
-
-    private static final String LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS =
-            "logging_immediate_content_threshold_ms";
-    /** Default value for logging immediate content threshold. */
-    public static final long LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS_DEFAULT = 1000;
-
-    private static final String MANAGE_INTERESTS_ENABLED = "manage_interests_enabled";
-    /** Default value for whether to use menu options to launch interest management page. */
-    public static final boolean MANAGE_INTERESTS_ENABLED_DEFAULT = true;
-
-    private static final String SEND_FEEDBACK_ENABLED = "send_feedback_enabled";
-
-    private static final String MAXIMUM_GC_ATTEMPTS = "maximum_gc_attempts";
-    /** Default value for the maximum number of times that the GC task can re-enqueue itself. */
-    public static final long MAXIMUM_GC_ATTEMPTS_DEFAULT = 10;
-
-    private static final String NON_CACHED_MIN_PAGE_SIZE = "non_cached_min_page_size";
-    /** Default value for non cached minimum page size. */
-    public static final long NON_CACHED_MIN_PAGE_SIZE_DEFAULT = 5;
-
-    private static final String NON_CACHED_PAGE_SIZE = "non_cached_page_size";
-    /** Default value for non cached page size. */
-    public static final long NON_CACHED_PAGE_SIZE_DEFAULT = 25;
-
-    private static final String SESSION_LIFETIME_MS = "session_lifetime_ms";
-    /** Default value for session lifetime. */
-    public static final long SESSION_LIFETIME_MS_DEFAULT = 3600000;
-
-    private static final String SNIPPETS_ENABLED = "snippets_enabled";
-    /** Default value for whether to show article snippets. */
-    public static final boolean SNIPPETS_ENABLED_DEFAULT = true;
-
-    private static final String SPINNER_DELAY_MS = "spinner_delay";
-    /** Default value for delay before showing a spinner. */
-    public static final long SPINNER_DELAY_MS_DEFAULT = 500;
-
-    private static final String SPINNER_MINIMUM_SHOW_TIME_MS = "spinner_minimum_show_time";
-    /** Default value for how long spinners must be shown for. */
-    public static final long SPINNER_MINIMUM_SHOW_TIME_MS_DEFAULT = 0;
-
-    private static final String STORAGE_MISS_THRESHOLD = "storage_miss_threshold";
-    /** Default number of items that can be missing from a call to FeedStore before failing. */
-    public static final long STORAGE_MISS_THRESHOLD_DEFAULT = 100;
-
-    private static final String TRIGGER_IMMEDIATE_PAGINATION = "trigger_immediate_pagination";
-    /** Default value for triggering immediate pagination. */
-    public static final boolean TRIGGER_IMMEDIATE_PAGINATION_DEFAULT = false;
-
-    private static final String UNDOABLE_ACTIONS_ENABLED = "undoable_actions_enabled";
-    /** Default value for if undoable actions should be presented to the user. */
-    public static final boolean UNDOABLE_ACTIONS_ENABLED_DEFAULT = true;
-
-    private static final String USE_SECONDARY_PAGE_REQUEST = "use_secondary_page_request";
-    /** Default value for pagination behavior. */
-    public static final boolean USE_SECONDARY_PAGE_REQUEST_DEFAULT = false;
-
-    private static final String USE_TIMEOUT_SCHEDULER = "use_timeout_scheduler";
-    /** Default value for the type of scheduler handling. */
-    public static final boolean USE_TIMEOUT_SCHEDULER_DEFAULT = true;
-
-    private static final String VIEW_LOG_THRESHOLD = "view_log_threshold";
-    /** Default value for logging view threshold. */
-    public static final double VIEW_LOG_THRESHOLD_DEFAULT = 0.66d;
-
-    /** @return Whether the Stream aborts restores if user is past configured fold count. */
-    @VisibleForTesting
-    static boolean getAbandonRestoreBelowFold() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, ABANDON_RESTORE_BELOW_FOLD,
-                ABANDON_RESTORE_BELOW_FOLD_DEFAULT);
-    }
-
-    /** @return Whether to show card tooltips. */
-    @VisibleForTesting
-    static boolean getCardMenuTooltipEligible() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, CARD_MENU_TOOLTIP_ELIGIBLE,
-                CARD_MENU_TOOLTIP_ELIGIBLE_DEFAULT);
-    }
-
-    /** @return Whether synthetic tokens should be consumed when they are found. */
-    @VisibleForTesting
-    static boolean getConsumeSyntheticTokens() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, CONSUME_SYNTHETIC_TOKENS,
-                CONSUME_SYNTHETIC_TOKENS_DEFAULT);
-    }
-
-    /**
-     * @return Whether synthetic tokens should be automatically consume when restoring. This will
-     * not cause synthetic tokens to be consumed when opening with a new session.
-     */
-    @VisibleForTesting
-    static boolean getConsumeSyntheticTokensWhileRestoring() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS,
-                CONSUME_SYNTHETIC_TOKENS_WHILE_RESTORING,
-                CONSUME_SYNTHETIC_TOKENS_WHILE_RESTORING_DEFAULT);
-    }
-
-    /** @return The TTL (in seconds) for the default action. */
-    @VisibleForTesting
-    static long getDefaultActionTtlSeconds() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, DEFAULT_ACTION_TTL_SECONDS,
-                (int) DEFAULT_ACTION_TTL_SECONDS_DEFAULT);
-    }
-
-    /** @return The endpoint used for recording uploaded actions to the server. */
-    @VisibleForTesting
-    static String getFeedActionServerEndpoint() {
-        String paramValue = ChromeFeatureList.getFieldTrialParamByFeature(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, FEED_ACTION_SERVER_ENDPOINT);
-        return TextUtils.isEmpty(paramValue) ? FEED_ACTION_SERVER_ENDPOINT_DEFAULT : paramValue;
-    }
-
-    /**
-     * @return Maximum number of actions to be uploaded to the endpoint in a single request.
-     */
-    @VisibleForTesting
-    static long getFeedActionServerMaxActionsPerRequest() {
-        return (long) ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS,
-                FEED_ACTION_SERVER_MAX_ACTIONS_PER_REQUEST,
-                (int) FEED_ACTION_SERVER_MAX_ACTIONS_PER_REQUEST_DEFAULT);
-    }
-
-    /**
-     * @return Maximum size in bytes of the request to be uploaded to the endpoint in a single
-     *         request.
-     */
-    @VisibleForTesting
-    static long getFeedActionServerMaxSizePerRequest() {
-        return (long) ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS,
-                FEED_ACTION_SERVER_MAX_SIZE_PER_REQUEST,
-                (int) FEED_ACTION_SERVER_MAX_SIZE_PER_REQUEST_DEFAULT);
-    }
-
-    /** @return The HTTP method call to the feed action server (put/post/etc). */
-    @VisibleForTesting
-    static String getFeedActionServerMethod() {
-        String paramValue = ChromeFeatureList.getFieldTrialParamByFeature(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, FEED_ACTION_SERVER_METHOD);
-        return TextUtils.isEmpty(paramValue) ? FEED_ACTION_SERVER_METHOD_DEFAULT : paramValue;
-    }
-
-    /** @return Feed server endpoint to use to fetch content suggestions. */
-    static String getFeedServerEndpoint() {
-        String paramValue = ChromeFeatureList.getFieldTrialParamByFeature(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, FEED_SERVER_ENDPOINT);
-        return TextUtils.isEmpty(paramValue) ? FEED_SERVER_ENDPOINT_DEFAULT : paramValue;
-    }
-
-    /** @return Feed server method to use when fetching content suggestions. */
-    @VisibleForTesting
-    static String getFeedServerMethod() {
-        String paramValue = ChromeFeatureList.getFieldTrialParamByFeature(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, FEED_SERVER_METHOD);
-        return TextUtils.isEmpty(paramValue) ? FEED_SERVER_METHOD_DEFAULT : paramValue;
-    }
-
-    /** @return Whether server response should be length prefixed. */
-    @VisibleForTesting
-    static boolean getFeedServerResponseLengthPrefixed() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS,
-                FEED_SERVER_RESPONSE_LENGTH_PREFIXED, FEED_SERVER_RESPONSE_LENGTH_PREFIXED_DEFAULT);
-    }
-
-    /** @return Whether to ask the server for "Feed" UI or just basic UI. */
-    public static boolean getFeedUiEnabled() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, FEED_UI_ENABLED,
-                FEED_UI_ENABLED_DEFAULT);
-    }
-
-    /** @return Used to decide where to place the more button initially. */
-    @VisibleForTesting
-    static int getInitialNonCachedPageSize() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, INITIAL_NON_CACHED_PAGE_SIZE,
-                (int) INITIAL_NON_CACHED_PAGE_SIZE_DEFAULT);
-    }
-
-    /** @return Whether to update HEAD when making a page request. */
-    @VisibleForTesting
-    static boolean getLimitPageUpdatesInHead() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, LIMIT_PAGE_UPDATES_IN_HEAD,
-                LIMIT_PAGE_UPDATES_IN_HEAD_DEFAULT);
-    }
-
-    /**
-     * @return How long before showing content after opening NTP is no longer considered immediate
-     *         in UMA.
-     */
-    @VisibleForTesting
-    static long getLoggingImmediateContentThresholdMs() {
-        return (long) ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS,
-                LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS,
-                (int) LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS_DEFAULT);
-    }
-
-    /** @return Whether to show context menu option to launch to customization page. */
-    @VisibleForTesting
-    static boolean getManageInterestsEnabled() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, MANAGE_INTERESTS_ENABLED,
-                MANAGE_INTERESTS_ENABLED_DEFAULT);
-    }
-
-    /** @return The maximum number of times that the GC task can re-enqueue itself. */
-    @VisibleForTesting
-    static long getMaximumGcAttempts() {
-        return (long) ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, MAXIMUM_GC_ATTEMPTS,
-                (int) MAXIMUM_GC_ATTEMPTS_DEFAULT);
-    }
-
-    /** @return Used to decide where to place the more button. */
-    @VisibleForTesting
-    static int getNonCachedMinPageSize() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, NON_CACHED_MIN_PAGE_SIZE,
-                (int) NON_CACHED_MIN_PAGE_SIZE_DEFAULT);
-    }
-
-    /** @return Used to decide where to place the more button. */
-    @VisibleForTesting
-    static int getNonCachedPageSize() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, NON_CACHED_PAGE_SIZE,
-                (int) NON_CACHED_PAGE_SIZE_DEFAULT);
-    }
-
-    /** @return Time until feed stops restoring the UI. */
-    @VisibleForTesting
-    static long getSessionLifetimeMs() {
-        return (long) ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, SESSION_LIFETIME_MS,
-                (int) SESSION_LIFETIME_MS_DEFAULT);
-    }
-
-    /** @return Whether the article snippets feature is enabled. */
-    @VisibleForTesting
-    static boolean getSnippetsEnabled() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, SNIPPETS_ENABLED,
-                SNIPPETS_ENABLED_DEFAULT);
-    }
-
-    /** @return Delay before a spinner should be shown after content is requested. */
-    @VisibleForTesting
-    static long getSpinnerDelayMs() {
-        return (long) ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, SPINNER_DELAY_MS,
-                (int) SPINNER_DELAY_MS_DEFAULT);
-    }
-
-    /** @return Minimum time before a spinner should show before disappearing. */
-    @VisibleForTesting
-    static long getSpinnerMinimumShowTimeMs() {
-        return (long) ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, SPINNER_MINIMUM_SHOW_TIME_MS,
-                (int) SPINNER_MINIMUM_SHOW_TIME_MS_DEFAULT);
-    }
-
-    /** @return The number of items that can be missing from a call to FeedStore before failing. */
-    @VisibleForTesting
-    static long getStorageMissThreshold() {
-        return (long) ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, STORAGE_MISS_THRESHOLD,
-                (int) STORAGE_MISS_THRESHOLD_DEFAULT);
-    }
-
-    /**
-     * @return Whether UI initially shows "More" button upon reaching the end of known content,
-     *         when server could potentially have more content.
-     */
-    @VisibleForTesting
-    static boolean getTriggerImmediatePagination() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, TRIGGER_IMMEDIATE_PAGINATION,
-                TRIGGER_IMMEDIATE_PAGINATION_DEFAULT);
-    }
-
-    /** @return Whether to allow the present the user with the ability to undo actions. */
-    @VisibleForTesting
-    static boolean getUndoableActionsEnabled() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, UNDOABLE_ACTIONS_ENABLED,
-                UNDOABLE_ACTIONS_ENABLED_DEFAULT);
-    }
-
-    /**
-     * @return Whether the Feed's session handling should use logic to deal with timeouts and
-     * placing new results below the fold.
-     */
-    @VisibleForTesting
-    static boolean getUseTimeoutScheduler() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, USE_TIMEOUT_SCHEDULER,
-                USE_TIMEOUT_SCHEDULER_DEFAULT);
-    }
-
-    /**
-     * @return If secondary (a more intuitive) pagination approach should be used, or the original
-     * Zine matching behavior should be used.
-     */
-    @VisibleForTesting
-    static boolean getUseSecondaryPageRequest() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, USE_SECONDARY_PAGE_REQUEST,
-                USE_SECONDARY_PAGE_REQUEST_DEFAULT);
-    }
-
-    /** @return How much of a card must be on screen to generate a UMA log view. */
-    @VisibleForTesting
-    static double getViewLogThreshold() {
-        return ChromeFeatureList.getFieldTrialParamByFeatureAsDouble(
-                ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, VIEW_LOG_THRESHOLD,
-                VIEW_LOG_THRESHOLD_DEFAULT);
-    }
-
-    /**
-     * @return A fully built {@link Configuration}, ready to be given to the Feed.
-     */
-    public static Configuration createConfiguration() {
-        return new Configuration.Builder()
-                .put(ConfigKey.ABANDON_RESTORE_BELOW_FOLD,
-                        FeedConfiguration.getAbandonRestoreBelowFold())
-                .put(ConfigKey.CARD_MENU_TOOLTIP_ELIGIBLE,
-                        FeedConfiguration.getCardMenuTooltipEligible())
-                .put(ConfigKey.CONSUME_SYNTHETIC_TOKENS,
-                        FeedConfiguration.getConsumeSyntheticTokens())
-                .put(ConfigKey.CONSUME_SYNTHETIC_TOKENS_WHILE_RESTORING,
-                        FeedConfiguration.getConsumeSyntheticTokensWhileRestoring())
-                .put(ConfigKey.DEFAULT_ACTION_TTL_SECONDS,
-                        FeedConfiguration.getDefaultActionTtlSeconds())
-                .put(ConfigKey.FEED_ACTION_SERVER_ENDPOINT,
-                        FeedConfiguration.getFeedActionServerEndpoint())
-                .put(ConfigKey.FEED_ACTION_SERVER_MAX_ACTIONS_PER_REQUEST,
-                        FeedConfiguration.getFeedActionServerMaxActionsPerRequest())
-                .put(ConfigKey.FEED_ACTION_SERVER_MAX_SIZE_PER_REQUEST,
-                        FeedConfiguration.getFeedActionServerMaxSizePerRequest())
-                .put(ConfigKey.FEED_ACTION_SERVER_METHOD,
-                        FeedConfiguration.getFeedActionServerMethod())
-                .put(ConfigKey.FEED_SERVER_ENDPOINT, FeedConfiguration.getFeedServerEndpoint())
-                .put(ConfigKey.FEED_SERVER_METHOD, FeedConfiguration.getFeedServerMethod())
-                .put(ConfigKey.FEED_SERVER_RESPONSE_LENGTH_PREFIXED,
-                        FeedConfiguration.getFeedServerResponseLengthPrefixed())
-                .put(ConfigKey.FEED_UI_ENABLED, FeedConfiguration.getFeedUiEnabled())
-                .put(ConfigKey.INITIAL_NON_CACHED_PAGE_SIZE,
-                        FeedConfiguration.getInitialNonCachedPageSize())
-                .put(ConfigKey.LIMIT_PAGE_UPDATES_IN_HEAD,
-                        FeedConfiguration.getLimitPageUpdatesInHead())
-                .put(ConfigKey.LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS,
-                        FeedConfiguration.getLoggingImmediateContentThresholdMs())
-                .put(ConfigKey.MANAGE_INTERESTS_ENABLED,
-                        FeedConfiguration.getManageInterestsEnabled())
-                .put(ConfigKey.MAXIMUM_GC_ATTEMPTS, FeedConfiguration.getMaximumGcAttempts())
-                .put(ConfigKey.NON_CACHED_MIN_PAGE_SIZE,
-                        FeedConfiguration.getNonCachedMinPageSize())
-                .put(ConfigKey.NON_CACHED_PAGE_SIZE, FeedConfiguration.getNonCachedPageSize())
-                .put(ConfigKey.SESSION_LIFETIME_MS, FeedConfiguration.getSessionLifetimeMs())
-                .put(ConfigKey.SNIPPETS_ENABLED, FeedConfiguration.getSnippetsEnabled())
-                .put(ConfigKey.SPINNER_DELAY_MS, FeedConfiguration.getSpinnerDelayMs())
-                .put(ConfigKey.SPINNER_MINIMUM_SHOW_TIME_MS,
-                        FeedConfiguration.getSpinnerMinimumShowTimeMs())
-                .put(ConfigKey.STORAGE_MISS_THRESHOLD, FeedConfiguration.getStorageMissThreshold())
-                .put(ConfigKey.TRIGGER_IMMEDIATE_PAGINATION,
-                        FeedConfiguration.getTriggerImmediatePagination())
-                .put(ConfigKey.UNDOABLE_ACTIONS_ENABLED,
-                        FeedConfiguration.getUndoableActionsEnabled())
-                .put(ConfigKey.USE_TIMEOUT_SCHEDULER, FeedConfiguration.getUseTimeoutScheduler())
-                .put(ConfigKey.USE_SECONDARY_PAGE_REQUEST,
-                        FeedConfiguration.getUseSecondaryPageRequest())
-                .put(ConfigKey.VIEW_LOG_THRESHOLD, FeedConfiguration.getViewLogThreshold())
-                .build();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedContentBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedContentBridge.java
deleted file mode 100644
index 3d306bf..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedContentBridge.java
+++ /dev/null
@@ -1,151 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.Callback;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Delete;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.DeleteByPrefix;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Type;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentOperation.Upsert;
-import org.chromium.chrome.browser.profiles.Profile;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Provides access to native implementations of content storage.
- */
-@JNINamespace("feed")
-public class FeedContentBridge {
-    private long mNativeFeedContentBridge;
-
-    /**
-     * Creates a {@link FeedContentBridge} for accessing native content storage
-     * implementation for the current user, and initial native side bridge.
-     *
-     * @param profile {@link Profile} of the user we are rendering the Feed for.
-     */
-    public FeedContentBridge(Profile profile) {
-        mNativeFeedContentBridge = FeedContentBridgeJni.get().init(FeedContentBridge.this, profile);
-    }
-
-    /**
-     * Creates a {@link FeedContentBridge} for accessing native content storage
-     * implementation for the current user, and initial native side bridge.
-     */
-    @VisibleForTesting
-    public FeedContentBridge() {}
-
-    /** Cleans up native half of this bridge. */
-    public void destroy() {
-        assert mNativeFeedContentBridge != 0;
-        FeedContentBridgeJni.get().destroy(mNativeFeedContentBridge, FeedContentBridge.this);
-        mNativeFeedContentBridge = 0;
-    }
-
-    public void loadContent(List<String> keys, Callback<Map<String, byte[]>> successCallback,
-            Callback<Void> failureCallback) {
-        assert mNativeFeedContentBridge != 0;
-        String[] keysArray = keys.toArray(new String[keys.size()]);
-        FeedContentBridgeJni.get().loadContent(mNativeFeedContentBridge, FeedContentBridge.this,
-                keysArray, successCallback, failureCallback);
-    }
-
-    public void loadContentByPrefix(String prefix, Callback<Map<String, byte[]>> successCallback,
-            Callback<Void> failureCallback) {
-        assert mNativeFeedContentBridge != 0;
-        FeedContentBridgeJni.get().loadContentByPrefix(mNativeFeedContentBridge,
-                FeedContentBridge.this, prefix, successCallback, failureCallback);
-    }
-
-    public void loadAllContentKeys(
-            Callback<String[]> successCallback, Callback<Void> failureCallback) {
-        assert mNativeFeedContentBridge != 0;
-        FeedContentBridgeJni.get().loadAllContentKeys(
-                mNativeFeedContentBridge, FeedContentBridge.this, successCallback, failureCallback);
-    }
-
-    public void commitContentMutation(ContentMutation contentMutation, Callback<Boolean> callback) {
-        assert mNativeFeedContentBridge != 0;
-
-        FeedContentBridgeJni.get().createContentMutation(
-                mNativeFeedContentBridge, FeedContentBridge.this);
-        for (ContentOperation operation : contentMutation.getOperations()) {
-            switch (operation.getType()) {
-                case Type.UPSERT:
-                    Upsert upsert = (Upsert) operation;
-                    FeedContentBridgeJni.get().appendUpsertOperation(mNativeFeedContentBridge,
-                            FeedContentBridge.this, upsert.getKey(), upsert.getValue());
-                    break;
-                case Type.DELETE:
-                    Delete delete = (Delete) operation;
-                    FeedContentBridgeJni.get().appendDeleteOperation(
-                            mNativeFeedContentBridge, FeedContentBridge.this, delete.getKey());
-                    break;
-                case Type.DELETE_BY_PREFIX:
-                    DeleteByPrefix deleteByPrefix = (DeleteByPrefix) operation;
-                    FeedContentBridgeJni.get().appendDeleteByPrefixOperation(
-                            mNativeFeedContentBridge, FeedContentBridge.this,
-                            deleteByPrefix.getPrefix());
-                    break;
-                case Type.DELETE_ALL:
-                    FeedContentBridgeJni.get().appendDeleteAllOperation(
-                            mNativeFeedContentBridge, FeedContentBridge.this);
-                    break;
-                default:
-                    // Operation type is not supported, therefore failing immediately.
-                    assert false : "Unsupported type of operation.";
-                    FeedContentBridgeJni.get().deleteContentMutation(
-                            mNativeFeedContentBridge, FeedContentBridge.this);
-                    callback.onResult(false);
-                    return;
-            }
-        }
-        FeedContentBridgeJni.get().commitContentMutation(
-                mNativeFeedContentBridge, FeedContentBridge.this, callback);
-    }
-
-    @CalledByNative
-    private static Object createKeyAndDataMap(String[] keys, byte[][] data) {
-        assert keys.length == data.length;
-        Map<String, byte[]> valueMap = new HashMap<>(keys.length);
-        for (int i = 0; i < keys.length && i < data.length; ++i) {
-            valueMap.put(keys[i], data[i]);
-        }
-        return valueMap;
-    }
-
-    @NativeMethods
-    interface Natives {
-        long init(FeedContentBridge caller, Profile profile);
-        void destroy(long nativeFeedContentBridge, FeedContentBridge caller);
-        void loadContent(long nativeFeedContentBridge, FeedContentBridge caller, String[] keys,
-                Callback<Map<String, byte[]>> successCallback, Callback<Void> failureCallback);
-        void loadContentByPrefix(long nativeFeedContentBridge, FeedContentBridge caller,
-                String prefix, Callback<Map<String, byte[]>> successCallback,
-                Callback<Void> failureCallback);
-        void loadAllContentKeys(long nativeFeedContentBridge, FeedContentBridge caller,
-                Callback<String[]> successCallback, Callback<Void> failureCallback);
-        void commitContentMutation(
-                long nativeFeedContentBridge, FeedContentBridge caller, Callback<Boolean> callback);
-        void createContentMutation(long nativeFeedContentBridge, FeedContentBridge caller);
-        void deleteContentMutation(long nativeFeedContentBridge, FeedContentBridge caller);
-        void appendDeleteOperation(
-                long nativeFeedContentBridge, FeedContentBridge caller, String key);
-        void appendDeleteByPrefixOperation(
-                long nativeFeedContentBridge, FeedContentBridge caller, String prefix);
-        void appendUpsertOperation(
-                long nativeFeedContentBridge, FeedContentBridge caller, String key, byte[] data);
-        void appendDeleteAllOperation(long nativeFeedContentBridge, FeedContentBridge caller);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedContentStorage.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedContentStorage.java
deleted file mode 100644
index 6fa9555a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedContentStorage.java
+++ /dev/null
@@ -1,99 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorage;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.profiles.Profile;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Implementation of {@link ContentStorage} that persisits data on native side.
- */
-public class FeedContentStorage implements ContentStorage {
-    private FeedContentBridge mFeedContentBridge;
-
-    /**
-     * Creates a {@link FeedContentStorage} for storing content for the current user.
-     *
-     * @param profile {@link Profile} of the user we are rendering the Feed for.
-     */
-    public FeedContentStorage(Profile profile) {
-        mFeedContentBridge = new FeedContentBridge(profile);
-    }
-
-    /**
-     * Creates a {@link FeedContentStorage} for testing.
-     *
-     * @param bridge {@link FeedContentBridge} implementation can handle content storage request.
-     */
-    @VisibleForTesting
-    public FeedContentStorage(FeedContentBridge bridge) {
-        mFeedContentBridge = bridge;
-    }
-
-    /** Cleans up {@link FeedContentStorage}. */
-    public void destroy() {
-        assert mFeedContentBridge != null;
-        mFeedContentBridge.destroy();
-        mFeedContentBridge = null;
-    }
-
-    @Override
-    public void get(List<String> keys, Consumer<Result<Map<String, byte[]>>> consumer) {
-        if (mFeedContentBridge == null) {
-            consumer.accept(Result.failure());
-        } else {
-            mFeedContentBridge.loadContent(keys,
-                    (Map<String, byte[]> data)
-                            -> consumer.accept(Result.success(data)),
-                    (Void ignored) -> consumer.accept(Result.failure()));
-        }
-    }
-
-    @Override
-    public void getAll(String prefix, Consumer<Result<Map<String, byte[]>>> consumer) {
-        if (mFeedContentBridge == null) {
-            consumer.accept(Result.failure());
-        } else {
-            mFeedContentBridge.loadContentByPrefix(prefix,
-                    (Map<String, byte[]> data)
-                            -> consumer.accept(Result.success(data)),
-                    (Void ignored) -> consumer.accept(Result.failure()));
-        }
-    }
-
-    @Override
-    public void commit(ContentMutation mutation, Consumer<CommitResult> consumer) {
-        if (mFeedContentBridge == null) {
-            consumer.accept(CommitResult.FAILURE);
-        } else {
-            mFeedContentBridge.commitContentMutation(mutation,
-                    (Boolean result)
-                            -> consumer.accept(
-                                    result ? CommitResult.SUCCESS : CommitResult.FAILURE));
-        }
-    }
-
-    @Override
-    public void getAllKeys(Consumer<Result<List<String>>> consumer) {
-        if (mFeedContentBridge == null) {
-            consumer.accept(Result.failure());
-        } else {
-            mFeedContentBridge.loadAllContentKeys(
-                    (String[] keys)
-                            -> consumer.accept(Result.success(Arrays.asList(keys))),
-                    (Void ignored) -> consumer.accept(Result.failure()));
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedContentStorageDirect.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedContentStorageDirect.java
deleted file mode 100644
index 87f88ae..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedContentStorageDirect.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorage;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorageDirect;
-import org.chromium.chrome.browser.feed.library.common.Result;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Wrapper around {@link ContentStorage}, providing a synchronous implementation.
- */
-public final class FeedContentStorageDirect implements ContentStorageDirect {
-    private static final String LOCATION = "FeedContentStorageDirect.";
-    private final ContentStorage mContentStorage;
-
-    FeedContentStorageDirect(ContentStorage contentStorage) {
-        mContentStorage = contentStorage;
-    }
-
-    @Override
-    public Result<Map<String, byte[]>> get(List<String> keys) {
-        if (keys.isEmpty()) {
-            return Result.success(Collections.emptyMap());
-        }
-
-        return FutureTaskConsumer.consume(LOCATION + "get",
-                (consumer) -> mContentStorage.get(keys, consumer), Result.failure());
-    }
-
-    @Override
-    public Result<Map<String, byte[]>> getAll(String prefix) {
-        return FutureTaskConsumer.consume(LOCATION + "getAll",
-                (consumer) -> mContentStorage.getAll(prefix, consumer), Result.failure());
-    }
-
-    @Override
-    public CommitResult commit(ContentMutation mutation) {
-        return FutureTaskConsumer.consume(LOCATION + "commit",
-                (consumer) -> mContentStorage.commit(mutation, consumer), CommitResult.FAILURE);
-    }
-
-    @Override
-    public Result<List<String>> getAllKeys() {
-        return FutureTaskConsumer.consume(
-                LOCATION + "getAllKeys", mContentStorage::getAllKeys, Result.failure());
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedDebuggingBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedDebuggingBridge.java
deleted file mode 100644
index 613ee8a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedDebuggingBridge.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.chrome.browser.feed.library.api.client.requestmanager.RequestManager;
-import org.chromium.chrome.browser.feed.library.api.client.scope.ProcessScope;
-import org.chromium.chrome.browser.feed.library.common.logging.Dumper;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-/**
- * Java-side bridge that receives and responds to native-initiated requests for debugging data. This
- * data is then used to populate the Feed Internals page.
- */
-@JNINamespace("feed")
-public class FeedDebuggingBridge {
-    @CalledByNative
-    static String getFeedFetchUrl() {
-        return FeedConfiguration.getFeedServerEndpoint();
-    }
-
-    @CalledByNative
-    static String getProcessScopeDump() {
-        ProcessScope processScope = FeedProcessScopeFactory.getFeedProcessScope();
-        Dumper dumper = Dumper.newDefaultDumper();
-        dumper.dump(processScope);
-
-        try {
-            StringWriter writer = new StringWriter();
-            dumper.write(writer);
-            return writer.toString();
-        } catch (IOException e) {
-            return "Unable to dump ProcessScope";
-        }
-    }
-
-    @CalledByNative
-    static void triggerRefresh() {
-        ProcessScope processScope = FeedProcessScopeFactory.getFeedProcessScope();
-
-        // Do nothing if Feed is disabled.
-        if (processScope == null) return;
-
-        RequestManager requestManager = processScope.getRequestManager();
-
-        // The only notification of this completing is through the SchedulerApi interface, like all
-        // other refreshes.
-        requestManager.triggerScheduledRefresh();
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedImageLoader.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedImageLoader.java
deleted file mode 100644
index 1488d9a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedImageLoader.java
+++ /dev/null
@@ -1,193 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.text.TextUtils;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.VisibleForTesting;
-import androidx.appcompat.content.res.AppCompatResources;
-
-import org.chromium.base.Callback;
-import org.chromium.base.Consumer;
-import org.chromium.base.DiscardableReferencePool;
-import org.chromium.base.SysUtils;
-import org.chromium.base.task.PostTask;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.library.api.host.imageloader.BundledAssets;
-import org.chromium.chrome.browser.feed.library.api.host.imageloader.ImageLoaderApi;
-import org.chromium.chrome.browser.image_fetcher.ImageFetcher;
-import org.chromium.chrome.browser.image_fetcher.ImageFetcherConfig;
-import org.chromium.chrome.browser.image_fetcher.ImageFetcherFactory;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.suggestions.ThumbnailGradient;
-import org.chromium.content_public.browser.UiThreadTaskTraits;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Provides image loading and other host-specific asset fetches for Feed.
- */
-public class FeedImageLoader implements ImageLoaderApi {
-    private static final String ASSET_PREFIX = "asset://";
-    private static final String OVERLAY_IMAGE_PREFIX = "overlay-image://";
-    private static final String OVERLAY_IMAGE_URL_PARAM = "url";
-    private static final String OVERLAY_IMAGE_DIRECTION_PARAM = "direction";
-    private static final String OVERLAY_IMAGE_DIRECTION_START = "start";
-    private static final String OVERLAY_IMAGE_DIRECTION_END = "end";
-
-    private Context mActivityContext;
-    private ImageFetcher mImageFetcher;
-
-    /**
-     * Creates a FeedImageLoader for fetching image for the current user.
-     *
-     * @param activityContext Context of the user we are rendering the Feed for.
-     */
-    public FeedImageLoader(Context activityContext, DiscardableReferencePool referencePool) {
-        mActivityContext = activityContext;
-        mImageFetcher = ImageFetcherFactory.createImageFetcher(SysUtils.isLowEndDevice()
-                        ? ImageFetcherConfig.DISK_CACHE_ONLY
-                        : ImageFetcherConfig.IN_MEMORY_WITH_DISK_CACHE,
-                Profile.getLastUsedRegularProfile(), referencePool);
-    }
-
-    public void destroy() {
-        mImageFetcher.destroy();
-        mImageFetcher = null;
-    }
-
-    @Override
-    public void loadDrawable(
-            List<String> urls, int widthPx, int heightPx, Consumer<Drawable> consumer) {
-        loadDrawableWithIter(urls.iterator(), widthPx, heightPx, consumer);
-    }
-
-    /**
-     * Tries to load the next value in urlsIter, and recursively calls itself on failure to
-     * continue processing. Being recursive allows resuming after an async call across the bridge.
-     *
-     * @param urlsIter The stateful iterator of all urls to load. Each call removes one value.
-     * @param widthPx The width of the image in pixels. Will be {@link #DIMENSION_UNKNOWN} if
-     * unknown.
-     * @param heightPx The height of the image in pixels. Will be {@link #DIMENSION_UNKNOWN} if
-     * unknown.
-     * @param consumer The callback to be given the first successful image.
-     */
-    private void loadDrawableWithIter(
-            Iterator<String> urlsIter, int widthPx, int heightPx, Consumer<Drawable> consumer) {
-        if (!urlsIter.hasNext() || mImageFetcher == null) {
-            // Post to ensure callback is not run synchronously.
-            PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> consumer.accept(null));
-            return;
-        }
-
-        String url = urlsIter.next();
-        if (url.startsWith(ASSET_PREFIX)) {
-            Drawable drawable = getAssetDrawable(url);
-            if (drawable == null) {
-                loadDrawableWithIter(urlsIter, widthPx, heightPx, consumer);
-            } else {
-                // Post to ensure callback is not run synchronously.
-                PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> consumer.accept(drawable));
-            }
-        } else if (url.startsWith(OVERLAY_IMAGE_PREFIX)) {
-            Uri uri = Uri.parse(url);
-            int direction = overlayDirection(uri);
-            String sourceUrl = uri.getQueryParameter(OVERLAY_IMAGE_URL_PARAM);
-            assert !TextUtils.isEmpty(sourceUrl) : "Overlay image source URL empty";
-            fetchImage(sourceUrl, widthPx, heightPx, (Bitmap bitmap) -> {
-                if (bitmap == null) {
-                    loadDrawableWithIter(urlsIter, widthPx, heightPx, consumer);
-                } else {
-                    consumer.accept(ThumbnailGradient.createDrawableWithGradientIfNeeded(
-                            bitmap, direction, mActivityContext.getResources()));
-                }
-            });
-        } else {
-            fetchImage(url, widthPx, heightPx, (Bitmap bitmap) -> {
-                if (bitmap == null) {
-                    loadDrawableWithIter(urlsIter, widthPx, heightPx, consumer);
-                } else {
-                    consumer.accept(new BitmapDrawable(mActivityContext.getResources(), bitmap));
-                }
-            });
-        }
-    }
-
-    /**
-     * @param url The fully qualified name of the resource.
-     * @return The resource as a Drawable on success, null otherwise.
-     */
-    private Drawable getAssetDrawable(String url) {
-        String resourceName = url.substring(ASSET_PREFIX.length());
-        @DrawableRes
-        int id = lookupDrawableIdentifier(resourceName);
-        return id == 0 ? null : AppCompatResources.getDrawable(mActivityContext, id);
-    }
-
-    /**
-     * Translate {@Link BundledAssets} to android drawable resource. This method only translate
-     * resource name defined in {@Link BundledAssets}.
-     *
-     * @param resourceName The name of the drawable asset.
-     * @return The id of the drawable asset. May be 0 if it could not be found.
-     */
-    private @DrawableRes int lookupDrawableIdentifier(String resourceName) {
-        switch (resourceName) {
-            case BundledAssets.AMP_ICON:
-            case BundledAssets.AMP_ICON_DARK_BG:
-                return R.drawable.ic_amp_24dp;
-            case BundledAssets.MENU_ICON:
-                return R.drawable.ic_more_vert_24dp_on_light_bg;
-            case BundledAssets.MENU_ICON_DARK_BG:
-                return R.drawable.ic_more_vert_24dp_on_dark_bg;
-            case BundledAssets.OFFLINE_INDICATOR_BADGE:
-                return R.drawable.ic_offline_pin_24dp_on_light_bg;
-            case BundledAssets.OFFLINE_INDICATOR_BADGE_DARK_BG:
-                return R.drawable.ic_offline_pin_24dp_on_dark_bg;
-            case BundledAssets.VIDEO_INDICATOR_BADGE:
-                return R.drawable.ic_play_circle_filled_24dp_on_light_bg;
-            case BundledAssets.VIDEO_INDICATOR_BADGE_DARK_BG:
-                return R.drawable.ic_play_circle_filled_24dp_on_dark_bg;
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns where the thumbnail is located in the card using the "direction" query param.
-     * @param overlayImageUri The URI for the overlay image.
-     * @return The direction in which the thumbnail is located relative to the card.
-     */
-    private int overlayDirection(Uri overlayImageUri) {
-        String direction = overlayImageUri.getQueryParameter(OVERLAY_IMAGE_DIRECTION_PARAM);
-        assert TextUtils.equals(direction, OVERLAY_IMAGE_DIRECTION_START)
-                || TextUtils.equals(direction, OVERLAY_IMAGE_DIRECTION_END)
-            : "Overlay image direction must be either start or end";
-        return TextUtils.equals(direction, OVERLAY_IMAGE_DIRECTION_START)
-                ? ThumbnailGradient.ThumbnailLocation.START
-                : ThumbnailGradient.ThumbnailLocation.END;
-    }
-
-    @VisibleForTesting
-    protected void fetchImage(String url, int width, int height, Callback<Bitmap> callback) {
-        ImageFetcher.Params params =
-                ImageFetcher.Params.create(url, ImageFetcher.FEED_UMA_CLIENT_NAME, width, height);
-        mImageFetcher.fetchImage(params, callback);
-    }
-
-    @VisibleForTesting
-    FeedImageLoader(Context activityContext, ImageFetcher imageFetcher) {
-        mActivityContext = activityContext;
-        mImageFetcher = imageFetcher;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedJournalBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedJournalBridge.java
deleted file mode 100644
index f647c6af..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedJournalBridge.java
+++ /dev/null
@@ -1,145 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.Callback;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Append;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Copy;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalOperation.Type;
-import org.chromium.chrome.browser.profiles.Profile;
-
-/**
- * Provides access to native implementations of journal storage.
- */
-@JNINamespace("feed")
-public class FeedJournalBridge {
-    private long mNativeFeedJournalBridge;
-
-    /**
-     * Creates a {@link FeedJournalBridge} for accessing native journal storage
-     * implementation for the current user, and initial native side bridge.
-     *
-     * @param profile {@link Profile} of the user we are rendering the Feed for.
-     */
-
-    public FeedJournalBridge(Profile profile) {
-        mNativeFeedJournalBridge = FeedJournalBridgeJni.get().init(FeedJournalBridge.this, profile);
-    }
-
-    /**
-     * Creates a {@link FeedJournalBridge} for testing.
-     */
-    @VisibleForTesting
-    public FeedJournalBridge() {}
-
-    /** Cleans up native half of this bridge. */
-    public void destroy() {
-        assert mNativeFeedJournalBridge != 0;
-        FeedJournalBridgeJni.get().destroy(mNativeFeedJournalBridge, FeedJournalBridge.this);
-        mNativeFeedJournalBridge = 0;
-    }
-
-    /** Loads the journal and asynchronously returns the contents. */
-    public void loadJournal(String journalName, Callback<byte[][]> successCallback,
-            Callback<Void> failureCallback) {
-        assert mNativeFeedJournalBridge != 0;
-        FeedJournalBridgeJni.get().loadJournal(mNativeFeedJournalBridge, FeedJournalBridge.this,
-                journalName, successCallback, failureCallback);
-    }
-
-    /**
-     * Commits the operations in {@link JournalMutation} in order and asynchronously reports the
-     * {@link CommitResult}. If all the operations succeed, {@code callback} is called with a
-     * success result. If any operation fails, {@code callback} is called with a failure result and
-     * the remaining operations are not processed.
-     */
-    public void commitJournalMutation(JournalMutation mutation, Callback<Boolean> callback) {
-        assert mNativeFeedJournalBridge != 0;
-
-        FeedJournalBridgeJni.get().startJournalMutation(
-                mNativeFeedJournalBridge, FeedJournalBridge.this, mutation.getJournalName());
-        for (JournalOperation operation : mutation.getOperations()) {
-            switch (operation.getType()) {
-                case Type.APPEND:
-                    Append append = (Append) operation;
-                    FeedJournalBridgeJni.get().addAppendOperation(
-                            mNativeFeedJournalBridge, FeedJournalBridge.this, append.getValue());
-                    break;
-                case Type.COPY:
-                    Copy copy = (Copy) operation;
-                    FeedJournalBridgeJni.get().addCopyOperation(mNativeFeedJournalBridge,
-                            FeedJournalBridge.this, copy.getToJournalName());
-                    break;
-                case Type.DELETE:
-                    FeedJournalBridgeJni.get().addDeleteOperation(
-                            mNativeFeedJournalBridge, FeedJournalBridge.this);
-                    break;
-                default:
-                    // Operation type is not supported, therefore failing immediately.
-                    assert false : "Unsupported type of operation.";
-                    FeedJournalBridgeJni.get().deleteJournalMutation(
-                            mNativeFeedJournalBridge, FeedJournalBridge.this);
-                    callback.onResult(false);
-                    return;
-            }
-        }
-        FeedJournalBridgeJni.get().commitJournalMutation(
-                mNativeFeedJournalBridge, FeedJournalBridge.this, callback);
-    }
-
-    /** Determines whether a journal exists and asynchronously responds. */
-    public void doesJournalExist(
-            String journalName, Callback<Boolean> successCallback, Callback<Void> failureCallback) {
-        assert mNativeFeedJournalBridge != 0;
-        FeedJournalBridgeJni.get().doesJournalExist(mNativeFeedJournalBridge,
-                FeedJournalBridge.this, journalName, successCallback, failureCallback);
-    }
-
-    /** Asynchronously retrieve a list of all current journals' name. */
-    public void loadAllJournalKeys(
-            Callback<String[]> successCallback, Callback<Void> failureCallback) {
-        assert mNativeFeedJournalBridge != 0;
-        FeedJournalBridgeJni.get().loadAllJournalKeys(
-                mNativeFeedJournalBridge, FeedJournalBridge.this, successCallback, failureCallback);
-    }
-
-    /** Delete all journals. Reports success or failure. */
-    public void deleteAllJournals(Callback<Boolean> callback) {
-        assert mNativeFeedJournalBridge != 0;
-        FeedJournalBridgeJni.get().deleteAllJournals(
-                mNativeFeedJournalBridge, FeedJournalBridge.this, callback);
-    }
-
-    @NativeMethods
-    interface Natives {
-        long init(FeedJournalBridge caller, Profile profile);
-        void destroy(long nativeFeedJournalBridge, FeedJournalBridge caller);
-        void loadJournal(long nativeFeedJournalBridge, FeedJournalBridge caller, String journalName,
-                Callback<byte[][]> successCallback, Callback<Void> failureCallback);
-        void commitJournalMutation(
-                long nativeFeedJournalBridge, FeedJournalBridge caller, Callback<Boolean> callback);
-        void startJournalMutation(
-                long nativeFeedJournalBridge, FeedJournalBridge caller, String journalName);
-        void deleteJournalMutation(long nativeFeedJournalBridge, FeedJournalBridge caller);
-        void addAppendOperation(
-                long nativeFeedJournalBridge, FeedJournalBridge caller, byte[] value);
-        void addCopyOperation(
-                long nativeFeedJournalBridge, FeedJournalBridge caller, String toJournalName);
-        void addDeleteOperation(long nativeFeedJournalBridge, FeedJournalBridge caller);
-        void doesJournalExist(long nativeFeedJournalBridge, FeedJournalBridge caller,
-                String journalName, Callback<Boolean> successCallback,
-                Callback<Void> failureCallback);
-        void loadAllJournalKeys(long nativeFeedJournalBridge, FeedJournalBridge caller,
-                Callback<String[]> successCallback, Callback<Void> failureCallback);
-        void deleteAllJournals(
-                long nativeFeedJournalBridge, FeedJournalBridge caller, Callback<Boolean> callback);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorage.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorage.java
deleted file mode 100644
index f970994..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorage.java
+++ /dev/null
@@ -1,110 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorage;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.profiles.Profile;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Implementation of {@link JournalStorage} that persisits data on native side.
- */
-public class FeedJournalStorage implements JournalStorage {
-    private FeedJournalBridge mFeedJournalBridge;
-
-    /**
-     * Creates a {@link FeedJournalStorage} for storing journals for the current user.
-     *
-     * @param profile {@link Profile} of the user we are rendering the Feed for.
-     */
-    public FeedJournalStorage(Profile profile) {
-        mFeedJournalBridge = new FeedJournalBridge(profile);
-    }
-
-    /**
-     * Creates a {@link FeedJournalStorage} for testing.
-     *
-     * @param bridge {@link FeedJournalBridge} implementation can handle journal storage request.
-     */
-    @VisibleForTesting
-    public FeedJournalStorage(FeedJournalBridge bridge) {
-        mFeedJournalBridge = bridge;
-    }
-
-    /** Cleans up {@link FeedJournalStorage}. */
-    public void destroy() {
-        assert mFeedJournalBridge != null;
-        mFeedJournalBridge.destroy();
-        mFeedJournalBridge = null;
-    }
-
-    @Override
-    public void read(String journalName, Consumer<Result<List<byte[]>>> consumer) {
-        if (mFeedJournalBridge == null) {
-            consumer.accept(Result.failure());
-        } else {
-            mFeedJournalBridge.loadJournal(journalName, (byte[][] entries) -> {
-                List<byte[]> journal = Arrays.asList(entries);
-                consumer.accept(Result.success(journal));
-            }, (Void ignored) -> consumer.accept(Result.failure()));
-        }
-    }
-
-    @Override
-    public void commit(JournalMutation mutation, Consumer<CommitResult> consumer) {
-        if (mFeedJournalBridge == null) {
-            consumer.accept(CommitResult.FAILURE);
-        } else {
-            mFeedJournalBridge.commitJournalMutation(mutation,
-                    (Boolean result)
-                            -> consumer.accept(
-                                    result ? CommitResult.SUCCESS : CommitResult.FAILURE));
-        }
-    }
-
-    @Override
-    public void exists(String journalName, Consumer<Result<Boolean>> consumer) {
-        if (mFeedJournalBridge == null) {
-            consumer.accept(Result.failure());
-        } else {
-            mFeedJournalBridge.doesJournalExist(journalName,
-                    (Boolean exist)
-                            -> consumer.accept(Result.success(exist)),
-                    (Void ignored) -> consumer.accept(Result.failure()));
-        }
-    }
-
-    @Override
-    public void getAllJournals(Consumer<Result<List<String>>> consumer) {
-        if (mFeedJournalBridge == null) {
-            consumer.accept(Result.failure());
-        } else {
-            mFeedJournalBridge.loadAllJournalKeys(
-                    (String[] data)
-                            -> consumer.accept(Result.success(Arrays.asList(data))),
-                    (Void ignored) -> consumer.accept(Result.failure()));
-        }
-    }
-
-    @Override
-    public void deleteAll(Consumer<CommitResult> consumer) {
-        if (mFeedJournalBridge == null) {
-            consumer.accept(CommitResult.FAILURE);
-        } else {
-            mFeedJournalBridge.deleteAllJournals(
-                    (Boolean result)
-                            -> consumer.accept(
-                                    result ? CommitResult.SUCCESS : CommitResult.FAILURE));
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorageDirect.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorageDirect.java
deleted file mode 100644
index 7e79ba0d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorageDirect.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalMutation;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorage;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorageDirect;
-import org.chromium.chrome.browser.feed.library.common.Result;
-
-import java.util.List;
-
-/**
- * Wrapper around {@link JournalStorage}, providing a synchronous implementation.
- */
-public final class FeedJournalStorageDirect implements JournalStorageDirect {
-    private static final String LOCATION = "FeedJournalStorageDirect.";
-    private final JournalStorage mJournalStorage;
-
-    FeedJournalStorageDirect(JournalStorage journalStorage) {
-        this.mJournalStorage = journalStorage;
-    }
-
-    @Override
-    public Result<List<byte[]>> read(String journalName) {
-        return FutureTaskConsumer.consume(LOCATION + "read",
-                (consumer) -> mJournalStorage.read(journalName, consumer), Result.failure());
-    }
-
-    @Override
-    public CommitResult commit(JournalMutation mutation) {
-        return FutureTaskConsumer.consume(LOCATION + "commit",
-                (consumer) -> mJournalStorage.commit(mutation, consumer), CommitResult.FAILURE);
-    }
-
-    @Override
-    public Result<Boolean> exists(String journalName) {
-        return FutureTaskConsumer.consume(LOCATION + "exists",
-                (consumer) -> mJournalStorage.exists(journalName, consumer), Result.failure());
-    }
-
-    @Override
-    public Result<List<String>> getAllJournals() {
-        return FutureTaskConsumer.consume(
-                LOCATION + "getAllJournals", mJournalStorage::getAllJournals, Result.failure());
-    }
-
-    @Override
-    public CommitResult deleteAll() {
-        return FutureTaskConsumer.consume(
-                LOCATION + "deleteAll", mJournalStorage::deleteAll, CommitResult.FAILURE);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedLifecycleBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedLifecycleBridge.java
deleted file mode 100644
index da13c426..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedLifecycleBridge.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
-import org.chromium.chrome.browser.profiles.Profile;
-
-/**
- * Java-side bridge that receives native-initiated lifecycle events and forwards them to
- * FeedAppLifecycle. These events include, e.g., cached data clearing and history deletion.
- */
-@JNINamespace("feed")
-public class FeedLifecycleBridge {
-    private long mNativeBridge;
-
-    /**
-     * Creates a FeedLifecycleBridge, which is responsible for receiving and forwarding native
-     * lifecycle events.
-     * @param profile Profile of the user whose lifecycle events we care about.
-     */
-    public FeedLifecycleBridge(Profile profile) {
-        mNativeBridge = FeedLifecycleBridgeJni.get().init(FeedLifecycleBridge.this, profile);
-    }
-
-    /*
-     * Cleans up native half of this bridge.
-     */
-    public void destroy() {
-        assert mNativeBridge != 0;
-        FeedLifecycleBridgeJni.get().destroy(mNativeBridge, FeedLifecycleBridge.this);
-        mNativeBridge = 0;
-    }
-
-    @VisibleForTesting
-    @CalledByNative
-    static void onCachedDataCleared() {
-        FeedAppLifecycle lifecycle = FeedProcessScopeFactory.getFeedAppLifecycle();
-        if (lifecycle != null) {
-            lifecycle.onCachedDataCleared();
-        }
-    }
-
-    @VisibleForTesting
-    @CalledByNative
-    static void onHistoryDeleted() {
-        FeedAppLifecycle lifecycle = FeedProcessScopeFactory.getFeedAppLifecycle();
-        if (lifecycle != null) {
-            lifecycle.onHistoryDeleted();
-        }
-    }
-
-    @NativeMethods
-    interface Natives {
-        long init(FeedLifecycleBridge caller, Profile profile);
-        void destroy(long nativeFeedLifecycleBridge, FeedLifecycleBridge caller);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedLoggingBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedLoggingBridge.java
deleted file mode 100644
index fcded1f..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedLoggingBridge.java
+++ /dev/null
@@ -1,649 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import androidx.annotation.NonNull;
-
-import org.chromium.base.ContextUtils;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.chrome.browser.feed.FeedUma;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ActionType;
-import org.chromium.chrome.browser.feed.library.api.host.logging.BasicLoggingApi;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ContentLoggingData;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ElementLoggingData;
-import org.chromium.chrome.browser.feed.library.api.host.logging.InternalFeedError;
-import org.chromium.chrome.browser.feed.library.api.host.logging.RequestReason;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ScrollType;
-import org.chromium.chrome.browser.feed.library.api.host.logging.SessionEvent;
-import org.chromium.chrome.browser.feed.library.api.host.logging.SpinnerType;
-import org.chromium.chrome.browser.feed.library.api.host.logging.Task;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ZeroStateShowReason;
-import org.chromium.chrome.browser.feed.library.common.time.Clock;
-import org.chromium.chrome.browser.feed.shared.stream.Stream.ScrollListener;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.ntp.NewTabPageUma;
-import org.chromium.chrome.browser.preferences.Pref;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.components.feed.core.proto.ui.action.FeedActionProto;
-import org.chromium.components.user_prefs.UserPrefs;
-import org.chromium.ui.mojom.WindowOpenDisposition;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Implementation of {@link BasicLoggingApi} that log actions performed on the Feed,
- * and provides access to native implementation of feed logging.
- */
-@JNINamespace("feed")
-public class FeedLoggingBridge implements BasicLoggingApi {
-    private static final String TAG = "FeedLoggingBridge";
-    private static final int SHOWN_INDEX_THRESHOLD = 2;
-
-    private long mNativeFeedLoggingBridge;
-    private static final int MIN_SCROLL_THRESHOLD_DP = 160; // one inch.
-    private static final long VISIT_TIME_THRESHOLD = 1000 * 60 * 5; // 5 min in ms.
-    private boolean mEngagedReported;
-    private boolean mEngagedSimpleReported;
-    private boolean mScrolledReported;
-    private long mVisitStartTime;
-    private Clock mClock;
-    private boolean mHasReachedShownIndexesThreshold;
-
-    // This enum is used for UMA, don't move or reassign these numbers.
-    public @interface FeedEngagementType {
-        int FEED_ENGAGED = 0;
-        int FEED_ENGAGED_SIMPLE = 1;
-        int FEED_INTERACTED = 2;
-        int DEPRECATED_FEED_SCROLLED = 3;
-        int FEED_SCROLLED = 4;
-        int NUM_ENTRIES = 5;
-    }
-
-    /**
-     * Creates a {@link FeedLoggingBridge} for accessing native feed logging
-     * implementation for the current user, and initial native side bridge.
-     *
-     * @param profile {@link Profile} of the user we are rendering the Feed for.
-     */
-    public FeedLoggingBridge(Profile profile, Clock clock) {
-        mNativeFeedLoggingBridge = FeedLoggingBridgeJni.get().init(FeedLoggingBridge.this, profile);
-        mEngagedReported = false;
-        mEngagedSimpleReported = false;
-        mScrolledReported = false;
-        mClock = clock;
-        mVisitStartTime = 0;
-        // Set the initial value to true when the conditional logging feature is disabled because
-        // the threshold isn't needed in that case.
-        mHasReachedShownIndexesThreshold = !ChromeFeatureList.isEnabled(
-                ChromeFeatureList.INTEREST_FEEDV1_CLICKS_AND_VIEWS_CONDITIONAL_UPLOAD);
-    }
-
-    /** Cleans up native half of this bridge. */
-    public void destroy() {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        FeedLoggingBridgeJni.get().destroy(mNativeFeedLoggingBridge, FeedLoggingBridge.this);
-        mNativeFeedLoggingBridge = 0;
-    }
-
-    @Override
-    public void onContentViewed(ContentLoggingData data) {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        onShownSlice(data.getPositionInStream());
-
-        FeedLoggingBridgeJni.get().onContentViewed(mNativeFeedLoggingBridge, FeedLoggingBridge.this,
-                data.getPositionInStream(),
-                TimeUnit.SECONDS.toMillis(data.getPublishedTimeSeconds()),
-                TimeUnit.SECONDS.toMillis(data.getTimeContentBecameAvailable()), data.getScore(),
-                data.isAvailableOffline());
-    }
-
-    private void onShownSlice(int index) {
-        maybeUpdateNoticeCardViewsCount(index);
-
-        if (mHasReachedShownIndexesThreshold) {
-            return;
-        }
-        if (!lastRefreshWasSignedIn()) {
-            return;
-        }
-        if (index + 1 >= SHOWN_INDEX_THRESHOLD) {
-            mHasReachedShownIndexesThreshold = true;
-            UserPrefs.get(getProfile())
-                    .setBoolean(Pref.HAS_REACHED_CLICK_AND_VIEW_ACTIONS_UPLOAD_CONDITIONS, true);
-        }
-    }
-
-    private boolean lastRefreshWasSignedIn() {
-        return UserPrefs.get(getProfile()).getBoolean(Pref.LAST_REFRESH_WAS_SIGNED_IN);
-    }
-
-    private void maybeUpdateNoticeCardViewsCount(int index) {
-        if (!shouldUpdateNoticeCardClicksAndViewsCounters()) {
-            return;
-        }
-
-        if (!hasNoticeCard()) {
-            return;
-        }
-
-        if (index != getNoticeCardIndex()) {
-            return;
-        }
-
-        // Increment the stored notice card views count by 1.
-        int count = UserPrefs.get(getProfile()).getInteger(Pref.NOTICE_CARD_VIEWS_COUNT);
-        UserPrefs.get(getProfile()).setInteger(Pref.NOTICE_CARD_VIEWS_COUNT, count + 1);
-    }
-
-    private void maybeUpdateNoticeCardClicksCount(int index) {
-        if (!shouldUpdateNoticeCardClicksAndViewsCounters()) {
-            return;
-        }
-
-        if (!hasNoticeCard()) {
-            return;
-        }
-
-        if (index != getNoticeCardIndex()) {
-            return;
-        }
-
-        // Increment the stored notice card clicks count by 1.
-        int count = UserPrefs.get(getProfile()).getInteger(Pref.NOTICE_CARD_CLICKS_COUNT);
-        UserPrefs.get(getProfile()).setInteger(Pref.NOTICE_CARD_CLICKS_COUNT, count + 1);
-    }
-
-    private boolean hasNoticeCard() {
-        return UserPrefs.get(getProfile()).getBoolean(Pref.LAST_FETCH_HAD_NOTICE_CARD);
-    }
-
-    private static int getNoticeCardIndex() {
-        // Infer that the notice card is at the 2nd position when the feature related to putting the
-        // notice card at the second position is enabled.
-        if (ChromeFeatureList.isEnabled(
-                    ChromeFeatureList.INTEREST_FEEDV1_CLICKS_AND_VIEWS_CONDITIONAL_UPLOAD)) {
-            return 1;
-        }
-        return 0;
-    }
-
-    private static boolean shouldUpdateNoticeCardClicksAndViewsCounters() {
-        return ChromeFeatureList.isEnabled(
-                ChromeFeatureList.INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS);
-    }
-
-    private static Profile getProfile() {
-        return Profile.getLastUsedRegularProfile();
-    }
-
-    @Override
-    public void onContentDismissed(ContentLoggingData data, boolean wasCommitted) {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        FeedLoggingBridgeJni.get().onContentDismissed(mNativeFeedLoggingBridge,
-                FeedLoggingBridge.this, data.getPositionInStream(), data.getRepresentationUri(),
-                wasCommitted);
-    }
-
-    @Override
-    public void onContentSwiped(ContentLoggingData data) {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        FeedLoggingBridgeJni.get().onContentSwiped(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this);
-    }
-
-    @Override
-    public void onContentClicked(ContentLoggingData data) {
-        // Records content's clicks in onClientAction. When a user clicks on content, Feed libraries
-        // will call both onClientAction and onContentClicked, and onClientAction will receive
-        // ActionType.OPEN_URL in this case. so to avoid double counts, we records content's clicks
-        // in onClientAction.
-    }
-
-    @Override
-    public void onClientAction(ContentLoggingData data, @ActionType int actionType) {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        recordUserAction(actionType);
-        maybeUpdateNoticeCardClicksCount(data.getPositionInStream());
-        FeedLoggingBridgeJni.get().onClientAction(mNativeFeedLoggingBridge, FeedLoggingBridge.this,
-                feedActionToWindowOpenDisposition(actionType), data.getPositionInStream(),
-                TimeUnit.SECONDS.toMillis(data.getPublishedTimeSeconds()), data.getScore(),
-                data.isAvailableOffline());
-    }
-
-    @Override
-    public void onContentContextMenuOpened(ContentLoggingData data) {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        FeedLoggingBridgeJni.get().onContentContextMenuOpened(mNativeFeedLoggingBridge,
-                FeedLoggingBridge.this, data.getPositionInStream(),
-                TimeUnit.SECONDS.toMillis(data.getPublishedTimeSeconds()), data.getScore());
-    }
-
-    @Override
-    public void onMoreButtonViewed(int position) {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        FeedLoggingBridgeJni.get().onMoreButtonViewed(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this, position);
-    }
-
-    @Override
-    public void onMoreButtonClicked(int position) {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        FeedLoggingBridgeJni.get().onMoreButtonClicked(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this, position);
-    }
-
-    @Override
-    public void onNotInterestedIn(int interestType, ContentLoggingData data, boolean wasCommitted) {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        // TODO(crbug.com/935602): Fail to compile when new values are added to NotInterestedInData.
-        if (interestType == FeedActionProto.NotInterestedInData.RecordedInterestType.TOPIC_VALUE) {
-            FeedLoggingBridgeJni.get().onNotInterestedInTopic(mNativeFeedLoggingBridge,
-                    FeedLoggingBridge.this, data.getPositionInStream(), wasCommitted);
-        } else if (interestType
-                == FeedActionProto.NotInterestedInData.RecordedInterestType.SOURCE_VALUE) {
-            FeedLoggingBridgeJni.get().onNotInterestedInSource(mNativeFeedLoggingBridge,
-                    FeedLoggingBridge.this, data.getPositionInStream(), wasCommitted);
-        }
-    }
-
-    @Override
-    public void onOpenedWithContent(int timeToPopulateMs, int contentCount) {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        FeedLoggingBridgeJni.get().onOpenedWithContent(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this, timeToPopulateMs, contentCount);
-    }
-
-    @Override
-    public void onOpenedWithNoImmediateContent() {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        FeedLoggingBridgeJni.get().onOpenedWithNoImmediateContent(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this);
-    }
-
-    @Override
-    public void onOpenedWithNoContent() {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        FeedLoggingBridgeJni.get().onOpenedWithNoContent(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this);
-    }
-
-    @Override
-    public void onSpinnerStarted(@SpinnerType int spinnerType) {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        FeedLoggingBridgeJni.get().onSpinnerStarted(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this, spinnerType);
-    }
-
-    @Override
-    public void onSpinnerFinished(int timeShownMs, @SpinnerType int spinnerType) {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        FeedLoggingBridgeJni.get().onSpinnerFinished(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this, timeShownMs, spinnerType);
-    }
-
-    @Override
-    public void onSpinnerDestroyedWithoutCompleting(int timeShownMs, @SpinnerType int spinnerType) {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        FeedLoggingBridgeJni.get().onSpinnerDestroyedWithoutCompleting(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this, timeShownMs, spinnerType);
-    }
-
-    @Override
-    public void onPietFrameRenderingEvent(List<Integer> pietErrorCodes) {
-        if (mNativeFeedLoggingBridge == 0) return;
-        int[] pietErrorCodesArray = new int[pietErrorCodes.size()];
-        for (int i = 0; i < pietErrorCodes.size(); ++i) {
-            pietErrorCodesArray[i] = pietErrorCodes.get(i);
-        }
-        FeedLoggingBridgeJni.get().onPietFrameRenderingEvent(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this, pietErrorCodesArray);
-    }
-
-    @Override
-    public void onVisualElementClicked(ElementLoggingData data, int elementType) {
-        if (mNativeFeedLoggingBridge == 0) return;
-        FeedLoggingBridgeJni.get().onVisualElementClicked(mNativeFeedLoggingBridge,
-                FeedLoggingBridge.this, elementType, data.getPositionInStream(),
-                TimeUnit.SECONDS.toMillis(data.getTimeContentBecameAvailable()));
-    }
-
-    @Override
-    public void onVisualElementViewed(ElementLoggingData data, int elementType) {
-        if (mNativeFeedLoggingBridge == 0) return;
-        FeedLoggingBridgeJni.get().onVisualElementViewed(mNativeFeedLoggingBridge,
-                FeedLoggingBridge.this, elementType, data.getPositionInStream(),
-                TimeUnit.SECONDS.toMillis(data.getTimeContentBecameAvailable()));
-    }
-
-    @Override
-    public void onInternalError(@InternalFeedError int internalError) {
-        if (mNativeFeedLoggingBridge == 0) return;
-        FeedLoggingBridgeJni.get().onInternalError(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this, internalError);
-    }
-
-    @Override
-    public void onTokenCompleted(boolean wasSynthetic, int contentCount, int tokenCount) {
-        if (mNativeFeedLoggingBridge == 0) return;
-        FeedLoggingBridgeJni.get().onTokenCompleted(mNativeFeedLoggingBridge,
-                FeedLoggingBridge.this, wasSynthetic, contentCount, tokenCount);
-    }
-
-    @Override
-    public void onTokenFailedToComplete(boolean wasSynthetic, int failureCount) {
-        if (mNativeFeedLoggingBridge == 0) return;
-        FeedLoggingBridgeJni.get().onTokenFailedToComplete(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this, wasSynthetic, failureCount);
-    }
-
-    @Override
-    public void onServerRequest(@RequestReason int requestReason) {
-        if (mNativeFeedLoggingBridge == 0) return;
-        FeedLoggingBridgeJni.get().onServerRequest(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this, requestReason);
-    }
-
-    @Override
-    public void onZeroStateShown(@ZeroStateShowReason int zeroStateShowReason) {
-        if (mNativeFeedLoggingBridge == 0) return;
-        FeedLoggingBridgeJni.get().onZeroStateShown(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this, zeroStateShowReason);
-    }
-
-    @Override
-    public void onZeroStateRefreshCompleted(int newContentCount, int newTokenCount) {
-        if (mNativeFeedLoggingBridge == 0) return;
-        FeedLoggingBridgeJni.get().onZeroStateRefreshCompleted(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this, newContentCount, newTokenCount);
-    }
-
-    @Override
-    public void onInitialSessionEvent(
-            @SessionEvent int sessionEvent, int timeFromRegisteringMs, int sessionCount) {
-        // TODO(https://crbug.com/924739): Implementation.
-    }
-
-    @Override
-    public void onScroll(@ScrollType int scrollType, int distanceScrolled) {
-        reportScrollActivity(distanceScrolled);
-    }
-
-    @Override
-    public void onTaskFinished(@Task int task, int delayTime, int taskTime) {
-        if (mNativeFeedLoggingBridge == 0) return;
-        FeedLoggingBridgeJni.get().onTaskFinished(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this, task, delayTime, taskTime);
-    }
-
-    /**
-     * Reports how long a user spends on the page.
-     *
-     * @param visitTimeMs Time spent reading the page.
-     * @param returnToNtp User backed to NTP after visit the page.
-     */
-    public void onContentTargetVisited(long visitTimeMs, boolean returnToNtp) {
-        // We cannot assume that the|mNativeFeedLoggingBridge| is always available like other
-        // methods. This method is called by objects not controlled by Feed lifetimes, and destroy()
-        // may have already been called if Feed is disabled by policy.
-        if (mNativeFeedLoggingBridge != 0) {
-            FeedLoggingBridgeJni.get().onContentTargetVisited(
-                    mNativeFeedLoggingBridge, FeedLoggingBridge.this, visitTimeMs, returnToNtp);
-        }
-    }
-
-    private int feedActionToWindowOpenDisposition(@ActionType int actionType) {
-        switch (actionType) {
-            case ActionType.OPEN_URL:
-                return WindowOpenDisposition.CURRENT_TAB;
-            case ActionType.OPEN_URL_INCOGNITO:
-                return WindowOpenDisposition.OFF_THE_RECORD;
-            case ActionType.OPEN_URL_NEW_TAB:
-                return WindowOpenDisposition.NEW_BACKGROUND_TAB;
-            case ActionType.OPEN_URL_NEW_WINDOW:
-                return WindowOpenDisposition.NEW_WINDOW;
-            case ActionType.DOWNLOAD:
-                return WindowOpenDisposition.SAVE_TO_DISK;
-            case ActionType.LEARN_MORE:
-            case ActionType.MANAGE_INTERESTS:
-            case ActionType.BLOCK_CONTENT:
-            case ActionType.UNKNOWN:
-            default:
-                return WindowOpenDisposition.UNKNOWN;
-        }
-    }
-
-    private void recordUserAction(@ActionType int actionType) {
-        switch (actionType) {
-            case ActionType.BLOCK_CONTENT:
-                NewTabPageUma.recordAction(NewTabPageUma.ACTION_BLOCK_CONTENT);
-                break;
-            case ActionType.OPEN_URL:
-            case ActionType.OPEN_URL_INCOGNITO:
-            case ActionType.OPEN_URL_NEW_TAB:
-            case ActionType.OPEN_URL_NEW_WINDOW:
-                NewTabPageUma.recordAction(NewTabPageUma.ACTION_OPENED_SNIPPET);
-                break;
-            case ActionType.LEARN_MORE:
-                NewTabPageUma.recordAction(NewTabPageUma.ACTION_CLICKED_LEARN_MORE);
-                FeedUma.recordFeedControlsAction(FeedUma.CONTROLS_ACTION_CLICKED_LEARN_MORE);
-                break;
-            case ActionType.MANAGE_INTERESTS:
-                NewTabPageUma.recordAction(NewTabPageUma.ACTION_CLICKED_MANAGE_INTERESTS);
-                FeedUma.recordFeedControlsAction(FeedUma.CONTROLS_ACTION_CLICKED_MANAGE_INTERESTS);
-                break;
-            case ActionType.DOWNLOAD:
-            case ActionType.UNKNOWN:
-            default:
-                break;
-        }
-    }
-
-    private void reportScrolledAfterOpen() {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeFeedLoggingBridge == 0) return;
-
-        FeedLoggingBridgeJni.get().reportScrolledAfterOpen(
-                mNativeFeedLoggingBridge, FeedLoggingBridge.this);
-    }
-
-    /**
-     * One-shot reporter that records the first time the user scrolls in the {@link Stream}.
-     */
-    public static class ScrollEventReporter implements ScrollListener {
-        private final FeedLoggingBridge mLoggingBridge;
-        private boolean mFired;
-
-        public ScrollEventReporter(@NonNull FeedLoggingBridge loggingBridge) {
-            super();
-            mLoggingBridge = loggingBridge;
-        }
-
-        @Override
-        public void onScrollStateChanged(@ScrollState int state) {
-            if (mFired) return;
-            if (state != ScrollState.DRAGGING) return;
-
-            mLoggingBridge.reportScrolledAfterOpen();
-            mFired = true;
-        }
-
-        @Override
-        public void onScrolled(int dx, int dy) {}
-    }
-
-    @Override
-    public void reportScrollActivity(int scrollAmount) {
-        // Report each engagement type if we have not already reported it this session.
-        recordEngagement(scrollAmount, false /* no user interaction */);
-
-        if (!mScrolledReported) {
-            recordEngagementType(FeedEngagementType.FEED_SCROLLED);
-            mScrolledReported = true;
-        }
-    }
-
-    @Override
-    public void reportFeedInteraction() {
-        recordEngagement(0, true /* user interacted */);
-        recordEngagementType(FeedEngagementType.FEED_INTERACTED);
-    }
-
-    private int convertPixelsToDP(int pixels) {
-        return (int) (pixels
-                / ContextUtils.getApplicationContext().getResources().getDisplayMetrics().density);
-    }
-
-    /** Records FEED_ENGAGED and FEED_ENGAGED_SIMPLE if appropriate. */
-    private void recordEngagement(int scrollAmount, boolean interacted) {
-        // Convert scrollAmount from pixels to DP.
-        scrollAmount = Math.abs(scrollAmount);
-        int dpScrolled = 0;
-        if (scrollAmount > 0) {
-            dpScrolled = convertPixelsToDP(scrollAmount);
-        }
-
-        resetVisitIfNeeded();
-
-        // Report the user as engaged-simple if they have scrolled any amount or interacted
-        // with the card, and we have not already reported it for this chrome run.
-        if (!mEngagedSimpleReported && (scrollAmount > 0 || interacted)) {
-            recordEngagementType(FeedEngagementType.FEED_ENGAGED_SIMPLE);
-            mEngagedSimpleReported = true;
-        }
-
-        // Report the user as engaged if they have scrolled more than the threshold or interacted
-        // with the card, and we have not already reported it this chrome run.
-        if (!mEngagedReported && (dpScrolled > MIN_SCROLL_THRESHOLD_DP || interacted)) {
-            recordEngagementType(FeedEngagementType.FEED_ENGAGED);
-            mEngagedReported = true;
-        }
-    }
-
-    /**
-     * If enough time has elapsed since we the user started a visit, start a new visit.
-     *  If the user interacts within the window, reset the window.
-     */
-    private void resetVisitIfNeeded() {
-        if (mClock.elapsedRealtime() - mVisitStartTime > VISIT_TIME_THRESHOLD) {
-            mEngagedReported = false;
-            mEngagedSimpleReported = false;
-            mScrolledReported = false;
-        }
-        // Reset the last active time for session measurement.
-        mVisitStartTime = mClock.elapsedRealtime();
-    }
-
-    private void recordEngagementType(int engagementType) {
-        RecordHistogram.recordEnumeratedHistogram("ContentSuggestions.Feed.EngagementType",
-                engagementType, FeedEngagementType.NUM_ENTRIES);
-    }
-
-    @NativeMethods
-    interface Natives {
-        long init(FeedLoggingBridge caller, Profile profile);
-        void destroy(long nativeFeedLoggingBridge, FeedLoggingBridge caller);
-        void onContentViewed(long nativeFeedLoggingBridge, FeedLoggingBridge caller, int position,
-                long publishedTimeMs, long timeContentBecameAvailableMs, float score,
-                boolean isAvailableOffline);
-        void onContentDismissed(long nativeFeedLoggingBridge, FeedLoggingBridge caller,
-                int position, String uri, boolean wasCommitted);
-        void onContentSwiped(long nativeFeedLoggingBridge, FeedLoggingBridge caller);
-        void onClientAction(long nativeFeedLoggingBridge, FeedLoggingBridge caller,
-                int windowOpenDisposition, int position, long publishedTimeMs, float score,
-                boolean isAvailableOffline);
-        void onContentContextMenuOpened(long nativeFeedLoggingBridge, FeedLoggingBridge caller,
-                int position, long publishedTimeMs, float score);
-        void onMoreButtonViewed(
-                long nativeFeedLoggingBridge, FeedLoggingBridge caller, int position);
-        void onMoreButtonClicked(
-                long nativeFeedLoggingBridge, FeedLoggingBridge caller, int position);
-        void onNotInterestedInSource(long nativeFeedLoggingBridge, FeedLoggingBridge caller,
-                int position, boolean wasCommitted);
-        void onNotInterestedInTopic(long nativeFeedLoggingBridge, FeedLoggingBridge caller,
-                int position, boolean wasCommitted);
-        void onOpenedWithContent(long nativeFeedLoggingBridge, FeedLoggingBridge caller,
-                int timeToPopulateMs, int contentCount);
-        void onOpenedWithNoImmediateContent(long nativeFeedLoggingBridge, FeedLoggingBridge caller);
-        void onOpenedWithNoContent(long nativeFeedLoggingBridge, FeedLoggingBridge caller);
-        void onSpinnerStarted(
-                long nativeFeedLoggingBridge, FeedLoggingBridge caller, int spinnerType);
-        void onSpinnerFinished(long nativeFeedLoggingBridge, FeedLoggingBridge caller,
-                long spinnerShownTimeMs, int spinnerType);
-        void onSpinnerDestroyedWithoutCompleting(long nativeFeedLoggingBridge,
-                FeedLoggingBridge caller, long spinnerShownTimeMs, int spinnerType);
-        void onPietFrameRenderingEvent(
-                long nativeFeedLoggingBridge, FeedLoggingBridge caller, int[] pietErrorCodes);
-        void onVisualElementClicked(long nativeFeedLoggingBridge, FeedLoggingBridge caller,
-                int elementType, int position, long timeContentBecameAvailableMs);
-        void onVisualElementViewed(long nativeFeedLoggingBridge, FeedLoggingBridge caller,
-                int elementType, int position, long timeContentBecameAvailableMs);
-        void onInternalError(
-                long nativeFeedLoggingBridge, FeedLoggingBridge caller, int internalError);
-        void onTokenCompleted(long nativeFeedLoggingBridge, FeedLoggingBridge caller,
-                boolean wasSynthetic, int contentCount, int tokenCount);
-        void onTokenFailedToComplete(long nativeFeedLoggingBridge, FeedLoggingBridge caller,
-                boolean wasSynthetic, int failureCount);
-        void onServerRequest(
-                long nativeFeedLoggingBridge, FeedLoggingBridge caller, int requestReason);
-        void onZeroStateShown(
-                long nativeFeedLoggingBridge, FeedLoggingBridge caller, int zeroStateShowReason);
-        void onZeroStateRefreshCompleted(long nativeFeedLoggingBridge, FeedLoggingBridge caller,
-                int newContentCount, int newTokenCount);
-        void onTaskFinished(long nativeFeedLoggingBridge, FeedLoggingBridge caller, int task,
-                int delayTimeMs, int taskTimeMs);
-        void onContentTargetVisited(long nativeFeedLoggingBridge, FeedLoggingBridge caller,
-                long visitTimeMs, boolean returnToNtp);
-        void reportScrolledAfterOpen(long nativeFeedLoggingBridge, FeedLoggingBridge caller);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedNetworkBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedNetworkBridge.java
deleted file mode 100644
index 77886e2..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedNetworkBridge.java
+++ /dev/null
@@ -1,76 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import org.chromium.base.Callback;
-import org.chromium.base.Consumer;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpResponse;
-import org.chromium.chrome.browser.feed.library.api.host.network.NetworkClient;
-import org.chromium.chrome.browser.profiles.Profile;
-
-/**
- * Provides access to native implementations of NetworkClient.
- */
-@JNINamespace("feed")
-public class FeedNetworkBridge implements NetworkClient {
-    private long mNativeBridge;
-
-    /**
-     * Creates a FeedNetworkBridge for accessing native network implementation for the current
-     * user.
-     *
-     * @param profile Profile of the user we are rendering the Feed for.
-     */
-    public FeedNetworkBridge(Profile profile) {
-        mNativeBridge = FeedNetworkBridgeJni.get().init(FeedNetworkBridge.this, profile);
-    }
-
-    /*
-     * Cleans up native half of this bridge.
-     */
-    public void destroy() {
-        assert mNativeBridge != 0;
-        FeedNetworkBridgeJni.get().destroy(mNativeBridge, FeedNetworkBridge.this);
-        mNativeBridge = 0;
-    }
-
-    @Override
-    public void send(HttpRequest request, Consumer<HttpResponse> responseConsumer) {
-        if (mNativeBridge == 0) {
-            responseConsumer.accept(createHttpResponse(500, new byte[0], false));
-        } else {
-            FeedNetworkBridgeJni.get().sendNetworkRequest(mNativeBridge, FeedNetworkBridge.this,
-                    request.getUri().toString(), request.getMethod(), request.getBody(),
-                    result -> responseConsumer.accept(result));
-        }
-    }
-
-    @Override
-    public void close() {
-        // Bridge could have been destroyed for policy when this is called.
-        // See https://crbug.com/901414.
-        if (mNativeBridge == 0) return;
-
-        FeedNetworkBridgeJni.get().cancelRequests(mNativeBridge, FeedNetworkBridge.this);
-    }
-
-    @CalledByNative
-    private static HttpResponse createHttpResponse(int code, byte[] body, boolean isSignedIn) {
-        return new HttpResponse(code, body, isSignedIn);
-    }
-
-    @NativeMethods
-    interface Natives {
-        long init(FeedNetworkBridge caller, Profile profile);
-        void destroy(long nativeFeedNetworkBridge, FeedNetworkBridge caller);
-        void sendNetworkRequest(long nativeFeedNetworkBridge, FeedNetworkBridge caller, String url,
-                String requestType, byte[] body, Callback<HttpResponse> resultCallback);
-        void cancelRequests(long nativeFeedNetworkBridge, FeedNetworkBridge caller);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedOfflineBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedOfflineBridge.java
deleted file mode 100644
index a0eee13..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedOfflineBridge.java
+++ /dev/null
@@ -1,179 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.Callback;
-import org.chromium.base.Consumer;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.ContentMetadata;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.ContentRemoval;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.KnownContent;
-import org.chromium.chrome.browser.profiles.Profile;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/** Provides access to native implementations of OfflineIndicatorApi. */
-@JNINamespace("feed")
-public class FeedOfflineBridge implements FeedOfflineIndicator, KnownContent.Listener {
-    private long mNativeBridge;
-    private KnownContent mKnownContentApi;
-
-    /**
-     * Hold onto listeners in Java. It is difficult to offload this completely to native, because we
-     * need to remove with object reference equality in removeOfflineStatusListener().
-     */
-    private Set<OfflineStatusListener> mListeners = new HashSet<>();
-
-    /**
-     * Creates a FeedOfflineBridge for accessing native offlining logic.
-     *
-     * @param profile Profile of the user we are rendering the Feed for.
-     * @param knownContent Interface to access information about the Feed's articles.
-     */
-    public FeedOfflineBridge(Profile profile, KnownContent knownContent) {
-        mNativeBridge = FeedOfflineBridgeJni.get().init(FeedOfflineBridge.this, profile);
-        mKnownContentApi = knownContent;
-        mKnownContentApi.addListener(this);
-    }
-
-    @Override
-    public void destroy() {
-        assert mNativeBridge != 0;
-        FeedOfflineBridgeJni.get().destroy(mNativeBridge, FeedOfflineBridge.this);
-        mNativeBridge = 0;
-        mKnownContentApi.removeListener(this);
-    }
-
-    @Override
-    public Long getOfflineIdIfPageIsOfflined(String url) {
-        if (mNativeBridge == 0) {
-            return 0L;
-        } else {
-            return (Long) FeedOfflineBridgeJni.get().getOfflineId(
-                    mNativeBridge, FeedOfflineBridge.this, url);
-        }
-    }
-
-    @Override
-    public void getOfflineStatus(
-            List<String> urlsToRetrieve, Consumer<List<String>> urlListConsumer) {
-        if (mNativeBridge == 0) {
-            urlListConsumer.accept(Collections.emptyList());
-        } else {
-            String[] urlsArray = urlsToRetrieve.toArray(new String[urlsToRetrieve.size()]);
-            FeedOfflineBridgeJni.get().getOfflineStatus(mNativeBridge, FeedOfflineBridge.this,
-                    urlsArray,
-                    (String[] urlsAsArray) -> urlListConsumer.accept(Arrays.asList(urlsAsArray)));
-        }
-    }
-
-    @Override
-    public void addOfflineStatusListener(OfflineStatusListener offlineStatusListener) {
-        if (mNativeBridge != 0) {
-            mListeners.add(offlineStatusListener);
-        }
-    }
-
-    @Override
-    public void removeOfflineStatusListener(OfflineStatusListener offlineStatusListener) {
-        if (mNativeBridge != 0) {
-            mListeners.remove(offlineStatusListener);
-            if (mListeners.isEmpty()) {
-                FeedOfflineBridgeJni.get().onNoListeners(mNativeBridge, FeedOfflineBridge.this);
-            }
-        }
-    }
-
-    @Override
-    public void onContentRemoved(List<ContentRemoval> contentRemoved) {
-        if (mNativeBridge != 0) {
-            List<String> userDrivenRemovals = takeUserDriveRemovalsOnly(contentRemoved);
-            if (!userDrivenRemovals.isEmpty()) {
-                FeedOfflineBridgeJni.get().onContentRemoved(mNativeBridge, FeedOfflineBridge.this,
-                        userDrivenRemovals.toArray(new String[userDrivenRemovals.size()]));
-            }
-        }
-    }
-
-    @Override
-    public void onNewContentReceived(boolean isNewRefresh, long contentCreationDateTimeMs) {
-        if (mNativeBridge != 0) {
-            FeedOfflineBridgeJni.get().onNewContentReceived(mNativeBridge, FeedOfflineBridge.this);
-        }
-    }
-
-    /**
-     * Filters out any {@link ContentRemoval} that was not user driven, such as old articles being
-     * garbage collected.
-     *
-     * @param contentRemoved The articles being removed, may or may not be user driven.
-     * @return All and only the user driven removals.
-     */
-    @VisibleForTesting
-    static List<String> takeUserDriveRemovalsOnly(List<ContentRemoval> contentRemoved) {
-        List<String> urlsRemovedByUser = new ArrayList<>();
-        for (ContentRemoval removal : contentRemoved) {
-            if (removal.isRequestedByUser()) {
-                urlsRemovedByUser.add(removal.getUrl());
-            }
-        }
-        return urlsRemovedByUser;
-    }
-
-    @CalledByNative
-    private static Long createLong(long id) {
-        return Long.valueOf(id);
-    }
-
-    @CalledByNative
-    private void getKnownContent() {
-        mKnownContentApi.getKnownContent((List<ContentMetadata> metadataList) -> {
-            if (mNativeBridge == 0) return;
-
-            for (ContentMetadata metadata : metadataList) {
-                long time_published_ms = TimeUnit.SECONDS.toMillis(metadata.getTimePublished());
-                FeedOfflineBridgeJni.get().appendContentMetadata(mNativeBridge,
-                        FeedOfflineBridge.this, metadata.getUrl(), metadata.getTitle(),
-                        time_published_ms, metadata.getImageUrl(), metadata.getPublisher(),
-                        metadata.getFaviconUrl(), metadata.getSnippet());
-            }
-            FeedOfflineBridgeJni.get().onGetKnownContentDone(mNativeBridge, FeedOfflineBridge.this);
-        });
-    }
-
-    @CalledByNative
-    private void notifyStatusChange(String url, boolean availableOffline) {
-        for (OfflineStatusListener listener : mListeners) {
-            listener.updateOfflineStatus(url, availableOffline);
-        }
-    }
-
-    @NativeMethods
-    interface Natives {
-        long init(FeedOfflineBridge caller, Profile profile);
-        void destroy(long nativeFeedOfflineBridge, FeedOfflineBridge caller);
-        Object getOfflineId(long nativeFeedOfflineBridge, FeedOfflineBridge caller, String url);
-        void getOfflineStatus(long nativeFeedOfflineBridge, FeedOfflineBridge caller,
-                String[] urlsToRetrieve, Callback<String[]> urlListConsumer);
-        void onContentRemoved(
-                long nativeFeedOfflineBridge, FeedOfflineBridge caller, String[] urlsRemoved);
-        void onNewContentReceived(long nativeFeedOfflineBridge, FeedOfflineBridge caller);
-        void onNoListeners(long nativeFeedOfflineBridge, FeedOfflineBridge caller);
-        void appendContentMetadata(long nativeFeedOfflineBridge, FeedOfflineBridge caller,
-                String url, String title, long timePublishedMs, String imageUrl, String publisher,
-                String faviconUrl, String snippet);
-        void onGetKnownContentDone(long nativeFeedOfflineBridge, FeedOfflineBridge caller);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedOfflineIndicator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedOfflineIndicator.java
deleted file mode 100644
index b8409fc..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedOfflineIndicator.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import org.chromium.chrome.browser.feed.library.api.host.offlineindicator.OfflineIndicatorApi;
-
-/**
- * An extension of the {@link OfflineIndicatorApi} with additional methods needed for offline logic
- * in Chromium.
- */
-public interface FeedOfflineIndicator extends OfflineIndicatorApi {
-    /** Cleans up native resources, should be called when no longer needed. */
-    void destroy();
-
-    /**
-     * @param url The url of the page that was previously queried for through
-     * {@link OfflineIndicatorApi#getOfflineStatus()} or
-     * {@link OfflineStatusListener#updateOfflineStatus()}.
-     * @return the offline id of the page if offlined, otherwise null.
-     */
-    Long getOfflineIdIfPageIsOfflined(String url);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedProcessScopeFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedProcessScopeFactory.java
deleted file mode 100644
index 800382a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedProcessScopeFactory.java
+++ /dev/null
@@ -1,282 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.ContextUtils;
-import org.chromium.base.task.PostTask;
-import org.chromium.base.task.SequencedTaskRunner;
-import org.chromium.base.task.TaskTraits;
-import org.chromium.chrome.browser.feed.library.api.client.scope.ProcessScope;
-import org.chromium.chrome.browser.feed.library.api.client.scope.ProcessScopeBuilder;
-import org.chromium.chrome.browser.feed.library.api.host.config.ApplicationInfo;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.DebugBehavior;
-import org.chromium.chrome.browser.feed.library.api.host.network.NetworkClient;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentStorageDirect;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalStorageDirect;
-import org.chromium.chrome.browser.feed.library.common.time.SystemClockImpl;
-import org.chromium.chrome.browser.feed.shared.FeedFeatures;
-import org.chromium.chrome.browser.feed.v1.tooltip.BasicTooltipSupportedApi;
-import org.chromium.chrome.browser.preferences.Pref;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.components.prefs.PrefService;
-import org.chromium.components.user_prefs.UserPrefs;
-
-/** Holds singleton {@link ProcessScope} and some of the scope's host implementations. */
-public class FeedProcessScopeFactory {
-    private static final String TAG = "FeedProcessScopeFtry";
-
-    /**
-     * Tracks whether the article suggestions should be visible to the user during the current
-     * session. If user opts in to the suggestions during the current session, the suggestions
-     * services will be immediately warmed up. If user opts out during the current session,
-     * the suggestions services will not shut down until the next session.
-     */
-    private static boolean sArticlesVisibleDuringSession;
-
-    private static FeedAppLifecycle sFeedAppLifecycle;
-    private static ProcessScope sProcessScope;
-    private static FeedScheduler sFeedScheduler;
-    private static FeedOfflineIndicator sFeedOfflineIndicator;
-    private static NetworkClient sTestNetworkClient;
-    private static ContentStorageDirect sTestContentStorageDirect;
-    private static JournalStorageDirect sTestJournalStorageDirect;
-    private static FeedLoggingBridge sFeedLoggingBridge;
-
-    /** @return The shared {@link ProcessScope} instance. Null if the Feed is disabled. */
-    public static @Nullable ProcessScope getFeedProcessScope() {
-        if (sProcessScope == null) {
-            initialize();
-        }
-        return sProcessScope;
-    }
-
-    /**
-     * @return The {@link FeedScheduler} that was given to the {@link ProcessScope}. Null if
-     * the Feed is disabled.
-     */
-    public static @Nullable FeedScheduler getFeedScheduler() {
-        if (sFeedScheduler == null) {
-            initialize();
-        }
-        return sFeedScheduler;
-    }
-
-    /**
-     * @return The {@link Runnable} to notify feed has been consumed.
-     */
-    public static Runnable getFeedConsumptionObserver() {
-        Runnable consumptionObserver = () -> {
-            FeedScheduler scheduler = getFeedScheduler();
-            if (scheduler != null) {
-                scheduler.onSuggestionConsumed();
-            }
-        };
-        return consumptionObserver;
-    }
-
-    /**
-     * @return The {@link FeedOfflineIndicator} that was given to the {@link ProcessScope}.
-     * Null if the Feed is disabled.
-     */
-    public static @Nullable FeedOfflineIndicator getFeedOfflineIndicator() {
-        if (sFeedOfflineIndicator == null) {
-            initialize();
-        }
-        return sFeedOfflineIndicator;
-    }
-
-    /*
-     * @return The global instance of {@link FeedAppLifecycle} for the process.
-     *         Null if the Feed is disabled.
-     */
-    public static @Nullable FeedAppLifecycle getFeedAppLifecycle() {
-        if (sFeedAppLifecycle == null) {
-            initialize();
-        }
-        return sFeedAppLifecycle;
-    }
-
-    /**
-     * @return The {@link FeedLoggingBridge} that was given to the {@link FeedStreamScope}. Null if
-     * the Feed is disabled.
-     */
-    public static @Nullable FeedLoggingBridge getFeedLoggingBridge() {
-        if (sFeedLoggingBridge == null) {
-            initialize();
-        }
-        return sFeedLoggingBridge;
-    }
-
-    private static void initialize() {
-        assert !FeedFeatures.isV2Enabled();
-        assert sProcessScope == null && sFeedScheduler == null && sFeedOfflineIndicator == null
-                && sFeedAppLifecycle == null && sFeedLoggingBridge == null;
-        if (!FeedFeatures.isFeedEnabled()) return;
-
-        sArticlesVisibleDuringSession = getPrefService().getBoolean(Pref.ARTICLES_LIST_VISIBLE);
-
-        Profile profile = Profile.getLastUsedRegularProfile();
-        Configuration configHostApi = FeedConfiguration.createConfiguration();
-        ApplicationInfo applicationInfo = FeedApplicationInfo.createApplicationInfo();
-
-        FeedSchedulerBridge schedulerBridge = new FeedSchedulerBridge(profile);
-        sFeedScheduler = schedulerBridge;
-        ContentStorageDirect contentStorageDirect = sTestContentStorageDirect == null
-                ? new FeedContentStorageDirect(new FeedContentStorage(profile))
-                : sTestContentStorageDirect;
-        JournalStorageDirect journalStorageDirect = sTestJournalStorageDirect == null
-                ? new FeedJournalStorageDirect(new FeedJournalStorage(profile))
-                : sTestJournalStorageDirect;
-        NetworkClient networkClient =
-                sTestNetworkClient == null ? new FeedNetworkBridge(profile) : sTestNetworkClient;
-
-        sFeedLoggingBridge = new FeedLoggingBridge(profile, new SystemClockImpl());
-
-        SequencedTaskRunner sequencedTaskRunner =
-                PostTask.createSequencedTaskRunner(TaskTraits.USER_VISIBLE_MAY_BLOCK);
-
-        sProcessScope = new ProcessScopeBuilder(configHostApi, sequencedTaskRunner::postTask,
-                sFeedLoggingBridge, networkClient, schedulerBridge, DebugBehavior.SILENT,
-                ContextUtils.getApplicationContext(), applicationInfo,
-                new BasicTooltipSupportedApi())
-                                .setContentStorageDirect(contentStorageDirect)
-                                .setJournalStorageDirect(journalStorageDirect)
-                                .build();
-        schedulerBridge.initializeFeedDependencies(sProcessScope.getRequestManager());
-
-        sFeedOfflineIndicator = new FeedOfflineBridge(profile, sProcessScope.getKnownContent());
-
-        sFeedAppLifecycle = new FeedAppLifecycle(sProcessScope.getAppLifecycleListener(),
-                new FeedLifecycleBridge(profile), sFeedScheduler);
-    }
-
-    /**
-     * Creates a {@link ProcessScope} using the provided host implementations. Call {@link
-     * #clearFeedProcessScopeForTesting()} to reset the ProcessScope after testing is complete.
-     *
-     * @param feedScheduler A {@link FeedScheduler} to use for testing.
-     * @param networkClient A {@link NetworkClient} to use for testing.
-     * @param feedOfflineIndicator A {@link FeedOfflineIndicator} to use for testing.
-     * @param feedAppLifecycle A {@link FeedAppLifecycle} to use for testing.
-     * @param loggingBridge A {@link FeedLoggingBridge} to use for testing.
-     */
-    @VisibleForTesting
-    static void createFeedProcessScopeForTesting(FeedScheduler feedScheduler,
-            NetworkClient networkClient, FeedOfflineIndicator feedOfflineIndicator,
-            FeedAppLifecycle feedAppLifecycle, FeedLoggingBridge loggingBridge,
-            ContentStorageDirect contentStorage, JournalStorageDirect journalStorage) {
-        Configuration configHostApi = FeedConfiguration.createConfiguration();
-
-        sFeedScheduler = feedScheduler;
-        sFeedLoggingBridge = loggingBridge;
-        sFeedOfflineIndicator = feedOfflineIndicator;
-        sFeedAppLifecycle = feedAppLifecycle;
-        ApplicationInfo applicationInfo =
-                new ApplicationInfo.Builder(ContextUtils.getApplicationContext()).build();
-
-        SequencedTaskRunner sequencedTaskRunner =
-                PostTask.createSequencedTaskRunner(TaskTraits.USER_VISIBLE_MAY_BLOCK);
-
-        sProcessScope = new ProcessScopeBuilder(configHostApi, sequencedTaskRunner::postTask,
-                sFeedLoggingBridge, networkClient, sFeedScheduler, DebugBehavior.SILENT,
-                ContextUtils.getApplicationContext(), applicationInfo,
-                new BasicTooltipSupportedApi())
-                                .setContentStorageDirect(contentStorage)
-                                .setJournalStorageDirect(journalStorage)
-                                .build();
-    }
-
-    /** Use supplied NetworkClient instead of real one, for tests. */
-    @VisibleForTesting
-    public static void setTestNetworkClient(NetworkClient client) {
-        if (client == null) {
-            sTestNetworkClient = null;
-        } else if (sProcessScope == null) {
-            sTestNetworkClient = client;
-        } else {
-            throw(new IllegalStateException(
-                    "TestNetworkClient can not be set after ProcessScope has initialized."));
-        }
-    }
-
-    /** Use supplied ContentStorageDirect instead of real one, for tests. */
-    @VisibleForTesting
-    public static void setTestContentStorageDirect(ContentStorageDirect storage) {
-        if (storage == null) {
-            sTestContentStorageDirect = null;
-        } else if (sProcessScope == null) {
-            sTestContentStorageDirect = storage;
-        } else {
-            throw new IllegalStateException(
-                    "TestContentStorageDirect can not be set after ProcessScope has initialized.");
-        }
-    }
-
-    /** Use supplied JournalStorageDirect instead of real one, for tests. */
-    @VisibleForTesting
-    public static void setTestJournalStorageDirect(JournalStorageDirect storage) {
-        if (storage == null) {
-            sTestJournalStorageDirect = null;
-        } else if (sProcessScope == null) {
-            sTestJournalStorageDirect = storage;
-        } else {
-            throw new IllegalStateException(
-                    "TestJournalStorageDirect can not be set after ProcessScope has initialized.");
-        }
-    }
-
-    /** Resets the ProcessScope after testing is complete. */
-    @VisibleForTesting
-    static void clearFeedProcessScopeForTesting() {
-        destroy();
-    }
-
-    /**
-     * @return Whether article suggestions are prepared to be shown based on user preference. If
-     *         article suggestions are set hidden within a session, this will still return true
-     *         until the next restart.
-     */
-    static boolean areArticlesVisibleDuringSession() {
-        // Skip the native call if sArticlesVisibleDuringSession is already true to reduce overhead.
-        if (!sArticlesVisibleDuringSession
-                && getPrefService().getBoolean(Pref.ARTICLES_LIST_VISIBLE)) {
-            sArticlesVisibleDuringSession = true;
-        }
-
-        return sArticlesVisibleDuringSession;
-    }
-
-    private static PrefService getPrefService() {
-        return UserPrefs.get(Profile.getLastUsedRegularProfile());
-    }
-
-    /** Clears out all static state. */
-    public static void destroy() {
-        if (sProcessScope != null) {
-            sProcessScope.onDestroy();
-            sProcessScope = null;
-        }
-        if (sFeedScheduler != null) {
-            sFeedScheduler.destroy();
-            sFeedScheduler = null;
-        }
-        if (sFeedOfflineIndicator != null) {
-            sFeedOfflineIndicator.destroy();
-            sFeedOfflineIndicator = null;
-        }
-        if (sFeedAppLifecycle != null) {
-            sFeedAppLifecycle.destroy();
-            sFeedAppLifecycle = null;
-        }
-        if (sFeedLoggingBridge != null) {
-            sFeedLoggingBridge.destroy();
-            sFeedLoggingBridge = null;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedRefreshTask.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedRefreshTask.java
deleted file mode 100644
index e701b0a..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedRefreshTask.java
+++ /dev/null
@@ -1,102 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import android.content.Context;
-
-import org.chromium.base.ContextUtils;
-import org.chromium.base.task.PostTask;
-import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler;
-import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory;
-import org.chromium.components.background_task_scheduler.NativeBackgroundTask;
-import org.chromium.components.background_task_scheduler.TaskIds;
-import org.chromium.components.background_task_scheduler.TaskInfo;
-import org.chromium.components.background_task_scheduler.TaskParameters;
-import org.chromium.content_public.browser.UiThreadTaskTraits;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * A task implementation that loads native and then tries to refresh the Feed's articles. Failures
- * or interruptions are not retried or rescheduled.
- */
-public class FeedRefreshTask extends NativeBackgroundTask {
-    // The amount of "flex" to add around the fetching periods, as a ratio of the period.
-    private static final double FLEX_FACTOR = 0.1;
-
-    /**
-     * Schedules a periodic task to wake up every thresholdMs and try to refresh. Allows for a bit
-     * of flex time before and after thresholdMs. Replaces the previous scheduling of the feed
-     * refresh task.
-     *
-     * @param thresholdMs the target number of milliseconds between each refresh.
-     */
-    public static void scheduleWakeUp(long thresholdMs) {
-        // The flex given to the BackgroundTaskScheduler is a period of time before the |intervalMs|
-        // point in time. Because we want to schedule for +/- FLEX_FACTOR around |thresholdMs|, some
-        // adjustments below are needed.
-        long intervalMs = (long) (thresholdMs * (1 + FLEX_FACTOR));
-        long flexWindowSizeMs = (long) (thresholdMs * 2 * FLEX_FACTOR);
-
-        BackgroundTaskScheduler scheduler = BackgroundTaskSchedulerFactory.getScheduler();
-        TaskInfo taskInfo = TaskInfo.createPeriodicTask(TaskIds.FEED_REFRESH_JOB_ID, intervalMs,
-                                            flexWindowSizeMs)
-                                    .setIsPersisted(true)
-                                    .setUpdateCurrent(true)
-                                    .setRequiredNetworkType(TaskInfo.NetworkType.ANY)
-                                    .build();
-        scheduler.schedule(ContextUtils.getApplicationContext(), taskInfo);
-    }
-
-    /** Clears previously scheduled task. */
-    public static void cancelWakeUp() {
-        BackgroundTaskScheduler scheduler = BackgroundTaskSchedulerFactory.getScheduler();
-        scheduler.cancel(ContextUtils.getApplicationContext(), TaskIds.FEED_REFRESH_JOB_ID);
-    }
-
-    @Override
-    protected @NativeBackgroundTask.StartBeforeNativeResult int onStartTaskBeforeNativeLoaded(
-            Context context, TaskParameters taskParameters, TaskFinishedCallback callback) {
-        // Nothing to setup without native, just wait.
-        return NativeBackgroundTask.StartBeforeNativeResult.LOAD_NATIVE;
-    }
-
-    @Override
-    protected void onStartTaskWithNative(
-            Context context, TaskParameters taskParameters, TaskFinishedCallback callback) {
-        FeedScheduler scheduler = FeedProcessScopeFactory.getFeedScheduler();
-        if (scheduler != null) {
-            scheduler.onFixedTimer(() -> {
-                // Regardless of success, mark ourselves as completed.
-                callback.taskFinished(false);
-            });
-        } else {
-            // If the FeedProcessScopeFactory is vending nulls, the Feed is disabled.
-            cancelWakeUp();
-        }
-    }
-
-    @Override
-    protected boolean onStopTaskBeforeNativeLoaded(Context context, TaskParameters taskParameters) {
-        // Don't retry, this task is periodic anyways.
-        return false;
-    }
-
-    @Override
-    protected boolean onStopTaskWithNative(Context context, TaskParameters taskParameters) {
-        // Don't retry, this task is periodic anyways.
-        return false;
-    }
-
-    @Override
-    public void reschedule(Context context) {
-        // The user may be trying to do something other than use Chrome right now, so we want to be
-        // as light weight as possible. Instead of going to native to reschedule with a more
-        // informed threshold, just schedule for 1 day from now. The next time a successful fetch
-        // occurs, this value will be set to a value tailored to current usage patterns.
-        PostTask.runOrPostTask(
-                UiThreadTaskTraits.DEFAULT, () -> scheduleWakeUp(TimeUnit.DAYS.toMillis(1)));
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedScheduler.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedScheduler.java
deleted file mode 100644
index f37a9bd..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedScheduler.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi;
-
-/**
- * An extension of the {@link SchedulerApi} with additional methods needed for scheduling logic
- * in Chromium.
- */
-public interface FeedScheduler extends SchedulerApi {
-    /** Cleans up native resources, should be called when no longer needed. */
-    void destroy();
-
-    /** To be called whenever the browser is foregrounded. */
-    void onForegrounded();
-
-    /**
-     * To be called when a background scheduling task wakes up the browser.
-     * @param onCompletion to be run when the fixed timer logic is complete.
-     */
-    void onFixedTimer(Runnable onCompletion);
-
-    /** To be called when an article is consumed, influencing future scheduling. */
-    void onSuggestionConsumed();
-
-    /**
-     * To be called when articles are cleared.
-     * @param suppressRefreshes whether the scheduler should temporarily avoid kicking off
-     * refreshes. This is used, for example, when history data is deleted.
-     * @return If a refresh should be made by the caller.
-     */
-    boolean onArticlesCleared(boolean suppressRefreshes);
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedSchedulerBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedSchedulerBridge.java
deleted file mode 100644
index 566d62e..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedSchedulerBridge.java
+++ /dev/null
@@ -1,163 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import androidx.annotation.NonNull;
-
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
-import org.chromium.chrome.browser.feed.library.api.client.requestmanager.RequestManager;
-import org.chromium.chrome.browser.feed.library.api.host.scheduler.SchedulerApi;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.components.feed.NativeRequestBehavior;
-
-/**
- * Provides access to native implementations of SchedulerApi.
- */
-@JNINamespace("feed")
-public class FeedSchedulerBridge implements FeedScheduler {
-    private long mNativeBridge;
-    private RequestManager mRequestManager;
-
-    /**
-     * Creates a FeedSchedulerBridge for accessing native scheduling logic.
-     *
-     * @param profile Profile of the user we are rendering the Feed for.
-     */
-    public FeedSchedulerBridge(Profile profile) {
-        mNativeBridge = FeedSchedulerBridgeJni.get().init(FeedSchedulerBridge.this, profile);
-    }
-
-    @Override
-    public void destroy() {
-        assert mNativeBridge != 0;
-        FeedSchedulerBridgeJni.get().destroy(mNativeBridge, FeedSchedulerBridge.this);
-        mNativeBridge = 0;
-    }
-
-    /**
-     * Sets our copies for various interfaces provided by the Feed library. Should be done as early
-     * as possible, as the scheduler will be unable to trigger refreshes until after it has the
-     * mechanisms to correctly do so. When this is called, it is assumed that the given
-     * RequestManager is initialized and can be used immediately.
-     *
-     * @param requestManager The interface that allows us make refresh requests.
-     */
-    public void initializeFeedDependencies(@NonNull RequestManager requestManager) {
-        assert mRequestManager == null;
-        mRequestManager = requestManager;
-    }
-
-    @Override
-    public int shouldSessionRequestData(SessionState sessionState) {
-        if (mNativeBridge == 0) return SchedulerApi.RequestBehavior.UNKNOWN;
-
-        @NativeRequestBehavior
-        int nativeBehavior = FeedSchedulerBridgeJni.get().shouldSessionRequestData(mNativeBridge,
-                FeedSchedulerBridge.this, sessionState.hasContent,
-                sessionState.contentCreationDateTimeMs, sessionState.hasOutstandingRequest);
-        // If this breaks, it is because SchedulerApi.RequestBehavior and the NativeRequestBehavior
-        // defined in feed_scheduler_host.h have diverged. If this happens during a feed DEPS roll,
-        // it likely means that the native side needs to be updated. Note that this will not catch
-        // new values and should handle value changes. Only removals/renames will cause compile
-        // failures.
-        switch (nativeBehavior) {
-            case NativeRequestBehavior.REQUEST_WITH_WAIT:
-                return SchedulerApi.RequestBehavior.REQUEST_WITH_WAIT;
-            case NativeRequestBehavior.REQUEST_WITH_CONTENT:
-                return SchedulerApi.RequestBehavior.REQUEST_WITH_CONTENT;
-            case NativeRequestBehavior.REQUEST_WITH_TIMEOUT:
-                return SchedulerApi.RequestBehavior.REQUEST_WITH_TIMEOUT;
-            case NativeRequestBehavior.NO_REQUEST_WITH_WAIT:
-                return SchedulerApi.RequestBehavior.NO_REQUEST_WITH_WAIT;
-            case NativeRequestBehavior.NO_REQUEST_WITH_CONTENT:
-                return SchedulerApi.RequestBehavior.NO_REQUEST_WITH_CONTENT;
-            case NativeRequestBehavior.NO_REQUEST_WITH_TIMEOUT:
-                return SchedulerApi.RequestBehavior.NO_REQUEST_WITH_TIMEOUT;
-        }
-
-        return SchedulerApi.RequestBehavior.UNKNOWN;
-    }
-
-    @Override
-    public void onReceiveNewContent(long contentCreationDateTimeMs) {
-        if (mNativeBridge != 0) {
-            FeedSchedulerBridgeJni.get().onReceiveNewContent(
-                    mNativeBridge, FeedSchedulerBridge.this, contentCreationDateTimeMs);
-        }
-    }
-
-    @Override
-    public void onRequestError(int networkResponseCode) {
-        if (mNativeBridge != 0) {
-            FeedSchedulerBridgeJni.get().onRequestError(
-                    mNativeBridge, FeedSchedulerBridge.this, networkResponseCode);
-        }
-    }
-
-    @Override
-    public void onForegrounded() {
-        assert mNativeBridge != 0;
-        FeedSchedulerBridgeJni.get().onForegrounded(mNativeBridge, FeedSchedulerBridge.this);
-    }
-
-    @Override
-    public void onFixedTimer(Runnable onCompletion) {
-        assert mNativeBridge != 0;
-        FeedSchedulerBridgeJni.get().onFixedTimer(
-                mNativeBridge, FeedSchedulerBridge.this, onCompletion);
-    }
-
-    @Override
-    public void onSuggestionConsumed() {
-        assert mNativeBridge != 0;
-        FeedSchedulerBridgeJni.get().onSuggestionConsumed(mNativeBridge, FeedSchedulerBridge.this);
-    }
-
-    @Override
-    public boolean onArticlesCleared(boolean suppressRefreshes) {
-        assert mNativeBridge != 0;
-        return FeedSchedulerBridgeJni.get().onArticlesCleared(
-                mNativeBridge, FeedSchedulerBridge.this, suppressRefreshes);
-    }
-
-    @CalledByNative
-    private boolean triggerRefresh() {
-        if (mRequestManager != null) {
-            mRequestManager.triggerScheduledRefresh();
-            return true;
-        }
-        return false;
-    }
-
-    @CalledByNative
-    private void scheduleWakeUp(long thresholdMs) {
-        FeedRefreshTask.scheduleWakeUp(thresholdMs);
-    }
-
-    @CalledByNative
-    private void cancelWakeUp() {
-        FeedRefreshTask.cancelWakeUp();
-    }
-
-    @NativeMethods
-    interface Natives {
-        long init(FeedSchedulerBridge caller, Profile profile);
-        void destroy(long nativeFeedSchedulerBridge, FeedSchedulerBridge caller);
-        int shouldSessionRequestData(long nativeFeedSchedulerBridge, FeedSchedulerBridge caller,
-                boolean hasContent, long contentCreationDateTimeMs, boolean hasOutstandingRequest);
-        void onReceiveNewContent(long nativeFeedSchedulerBridge, FeedSchedulerBridge caller,
-                long contentCreationDateTimeMs);
-        void onRequestError(long nativeFeedSchedulerBridge, FeedSchedulerBridge caller,
-                int networkResponseCode);
-        void onForegrounded(long nativeFeedSchedulerBridge, FeedSchedulerBridge caller);
-        void onFixedTimer(
-                long nativeFeedSchedulerBridge, FeedSchedulerBridge caller, Runnable onCompletion);
-        void onSuggestionConsumed(long nativeFeedSchedulerBridge, FeedSchedulerBridge caller);
-        boolean onArticlesCleared(long nativeFeedSchedulerBridge, FeedSchedulerBridge caller,
-                boolean suppressRefreshes);
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedStreamWrapper.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedStreamWrapper.java
deleted file mode 100644
index 5c963d6..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedStreamWrapper.java
+++ /dev/null
@@ -1,83 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import android.app.Activity;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.FeedSurfaceCoordinator;
-import org.chromium.chrome.browser.feed.FeedV1ActionOptions;
-import org.chromium.chrome.browser.feed.library.api.host.action.ActionApi;
-import org.chromium.chrome.browser.feed.shared.stream.Stream;
-import org.chromium.chrome.browser.native_page.NativePageNavigationDelegate;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.share.ShareDelegate;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
-import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
-import org.chromium.components.browser_ui.util.GlobalDiscardableReferencePool;
-import org.chromium.components.browser_ui.widget.displaystyle.UiConfig;
-
-/**
- * Wraps management of the Feed V1 stream.
- */
-public class FeedStreamWrapper implements FeedSurfaceCoordinator.StreamWrapper {
-    private @Nullable FeedImageLoader mImageLoader;
-    private Stream mStream;
-
-    public FeedStreamWrapper() {}
-
-    @Override
-    public int defaultMarginPixels(Activity activity) {
-        return activity.getResources().getDimensionPixelSize(
-                R.dimen.content_suggestions_card_modern_margin);
-    }
-
-    @Override
-    public int wideMarginPixels(Activity activity) {
-        return activity.getResources().getDimensionPixelSize(R.dimen.ntp_wide_card_lateral_margins);
-    }
-
-    @Override
-    public Stream createStream(Profile profile, Activity activity, boolean showDarkBackground,
-            SnackbarManager snackbarManager, NativePageNavigationDelegate pageNavigationDelegate,
-            UiConfig uiConfig, boolean placeholderShown,
-            BottomSheetController bottomSheetController, Supplier<Tab> tabSupplier,
-            FeedV1ActionOptions v1ActionOptions, Supplier<ShareDelegate> shareDelegateSupplier) {
-        FeedAppLifecycle appLifecycle = FeedProcessScopeFactory.getFeedAppLifecycle();
-        appLifecycle.onNTPOpened();
-
-        mImageLoader =
-                new FeedImageLoader(activity, GlobalDiscardableReferencePool.getReferencePool());
-
-        ActionApi actionApi = new FeedActionHandler(v1ActionOptions, pageNavigationDelegate,
-                FeedProcessScopeFactory.getFeedConsumptionObserver(),
-                FeedProcessScopeFactory.getFeedLoggingBridge(), activity, profile);
-        mStream = FeedV1StreamCreator.createStream(activity, mImageLoader, actionApi, uiConfig,
-                snackbarManager, showDarkBackground, placeholderShown);
-        return mStream;
-    }
-
-    @Override
-    public boolean isPlaceholderShown() {
-        return mStream.isPlaceholderShown();
-    }
-
-    @Override
-    public void doneWithStream() {
-        if (mImageLoader != null) {
-            mImageLoader.destroy();
-            mImageLoader = null;
-        }
-    }
-    @Override
-    public void addScrollListener() {
-        mStream.addScrollListener(new FeedLoggingBridge.ScrollEventReporter(
-                FeedProcessScopeFactory.getFeedLoggingBridge()));
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedV1StreamCreator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedV1StreamCreator.java
deleted file mode 100644
index 4cea674d..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedV1StreamCreator.java
+++ /dev/null
@@ -1,152 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import android.app.Activity;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-
-import org.chromium.base.ApiCompatibilityUtils;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.library.api.client.scope.ProcessScope;
-import org.chromium.chrome.browser.feed.library.api.host.action.ActionApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.CardConfiguration;
-import org.chromium.chrome.browser.feed.library.api.host.stream.SnackbarApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.SnackbarCallbackApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.StreamConfiguration;
-import org.chromium.chrome.browser.feed.shared.stream.Stream;
-import org.chromium.chrome.browser.feed.v1.tooltip.BasicTooltipApi;
-import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar;
-import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
-import org.chromium.components.browser_ui.widget.displaystyle.UiConfig;
-
-/**
- * Creates a {@link Stream}. This class was created to reduce feed v1 clutter in
- * {@link FeedSurfaceCoordinator}.
- */
-class FeedV1StreamCreator {
-    /**
-     * Create a feed v1 {@link Stream}.
-     */
-    public static Stream createStream(Activity activity, FeedImageLoader imageLoader,
-            ActionApi actionApi, UiConfig uiConfig, SnackbarManager snackbarManager,
-            boolean showDarkBackground, boolean isPlaceholderShown) {
-        ProcessScope processScope = FeedProcessScopeFactory.getFeedProcessScope();
-        assert processScope != null;
-
-        return processScope
-                .createStreamScopeBuilder(activity, imageLoader, actionApi,
-                        new BasicStreamConfiguration(),
-                        new BasicCardConfiguration(activity.getResources(), uiConfig),
-                        new BasicSnackbarApi(snackbarManager),
-                        FeedProcessScopeFactory.getFeedOfflineIndicator(), new BasicTooltipApi())
-                .setIsBackgroundDark(showDarkBackground)
-                .setIsPlaceholderShown(isPlaceholderShown)
-                .build()
-                .getStream();
-    }
-
-    private static class BasicSnackbarApi implements SnackbarApi {
-        private final SnackbarManager mManager;
-
-        public BasicSnackbarApi(SnackbarManager manager) {
-            mManager = manager;
-        }
-
-        @Override
-        public void show(String message) {
-            mManager.showSnackbar(Snackbar.make(message, new SnackbarManager.SnackbarController() {
-            }, Snackbar.TYPE_ACTION, Snackbar.UMA_FEED_NTP_STREAM));
-        }
-
-        @Override
-        public void show(String message, String action, SnackbarCallbackApi callback) {
-            mManager.showSnackbar(
-                    Snackbar.make(message,
-                                    new SnackbarManager.SnackbarController() {
-                                        @Override
-                                        public void onAction(Object actionData) {
-                                            callback.onDismissedWithAction();
-                                        }
-
-                                        @Override
-                                        public void onDismissNoAction(Object actionData) {
-                                            callback.onDismissNoAction();
-                                        }
-                                    },
-                                    Snackbar.TYPE_ACTION, Snackbar.UMA_FEED_NTP_STREAM)
-                            .setAction(action, null));
-        }
-    }
-
-    private static class BasicStreamConfiguration implements StreamConfiguration {
-        public BasicStreamConfiguration() {}
-
-        @Override
-        public int getPaddingStart() {
-            return 0;
-        }
-        @Override
-        public int getPaddingEnd() {
-            return 0;
-        }
-        @Override
-        public int getPaddingTop() {
-            return 0;
-        }
-        @Override
-        public int getPaddingBottom() {
-            return 0;
-        }
-    }
-
-    private static class BasicCardConfiguration implements CardConfiguration {
-        private final Resources mResources;
-        private final UiConfig mUiConfig;
-        private final int mCornerRadius;
-        private final int mCardMargin;
-        private final int mCardWideMargin;
-
-        public BasicCardConfiguration(Resources resources, UiConfig uiConfig) {
-            mResources = resources;
-            mUiConfig = uiConfig;
-            mCornerRadius = mResources.getDimensionPixelSize(R.dimen.default_rounded_corner_radius);
-            mCardMargin = mResources.getDimensionPixelSize(
-                    R.dimen.content_suggestions_card_modern_margin);
-            mCardWideMargin =
-                    mResources.getDimensionPixelSize(R.dimen.ntp_wide_card_lateral_margins);
-        }
-
-        @Override
-        public int getDefaultCornerRadius() {
-            return mCornerRadius;
-        }
-
-        @Override
-        public Drawable getCardBackground() {
-            return ApiCompatibilityUtils.getDrawable(mResources,
-                    FeedConfiguration.getFeedUiEnabled()
-                            ? R.drawable.hairline_border_card_background_with_inset
-                            : R.drawable.hairline_border_card_background);
-        }
-
-        @Override
-        public int getCardBottomMargin() {
-            return mCardMargin;
-        }
-
-        @Override
-        public int getCardStartMargin() {
-            return 0;
-        }
-
-        @Override
-        public int getCardEndMargin() {
-            return 0;
-        }
-    }
-
-    private FeedV1StreamCreator() {}
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FutureTaskConsumer.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FutureTaskConsumer.java
deleted file mode 100644
index b0248ed2..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FutureTaskConsumer.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import org.chromium.base.Callback;
-import org.chromium.base.Consumer;
-import org.chromium.base.Log;
-import org.chromium.chrome.browser.feed.library.common.concurrent.SimpleSettableFuture;
-
-import java.util.concurrent.ExecutionException;
-
-/**
- * Processes a {@link Callback} on a {@link SimpleSettableFuture}. This is necessary to provide a
- * synchronous interface to the Feed consumer.
- */
-public class FutureTaskConsumer {
-    private static final String TAG = "FutureTaskConsumer";
-    /**
-     * Sets the task result on a Future and returns it.
-     *
-     * @param location Caller location for error logging.
-     * @param task Callback on which to run the results.
-     * @param failure Default result in case of failure.
-     * @param <T> Type of result expected by the Feed {@link Consumer}.
-     * @return Result of the task.
-     */
-    public static <T> T consume(String location, Callback<Consumer<T>> task, T failure) {
-        SimpleSettableFuture<T> sharedStatesFuture = new SimpleSettableFuture<>();
-        task.onResult(sharedStatesFuture::put);
-        try {
-            return sharedStatesFuture.get();
-        } catch (InterruptedException | ExecutionException e) {
-            Log.e(TAG, "%s: %s", location, e.toString());
-            return failure;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/TestNetworkClient.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/TestNetworkClient.java
deleted file mode 100644
index 6df85853..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/TestNetworkClient.java
+++ /dev/null
@@ -1,165 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import android.util.Base64;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.google.protobuf.ByteString;
-import com.google.protobuf.CodedOutputStream;
-import com.google.protobuf.ExtensionRegistryLite;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.task.PostTask;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest.HttpMethod;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpResponse;
-import org.chromium.chrome.browser.feed.library.api.host.network.NetworkClient;
-import org.chromium.chrome.browser.feed.library.feedrequestmanager.RequestHelper;
-import org.chromium.components.feed.core.proto.wire.FeedRequestProto.FeedRequest;
-import org.chromium.components.feed.core.proto.wire.RequestProto.Request;
-import org.chromium.components.feed.core.proto.wire.ResponseProto.Response;
-import org.chromium.components.feed.core.proto.wire.mockserver.MockServerProto.ConditionalResponse;
-import org.chromium.components.feed.core.proto.wire.mockserver.MockServerProto.MockServer;
-import org.chromium.content_public.browser.UiThreadTaskTraits;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * A network client that returns configurable responses
- *  modified from org.chromium.chrome.browser.feed.library.mocknetworkclient.MockServerNetworkClient
- */
-public class TestNetworkClient implements NetworkClient {
-    private static final String TAG = "TestNetworkClient";
-
-    private final ExtensionRegistryLite mExtensionRegistry;
-    private final long mResponseDelay;
-    private final AtomicBoolean mAlreadyClosed = new AtomicBoolean(false);
-
-    private MockServer mMockServer;
-
-    public TestNetworkClient() {
-        Configuration config = new Configuration.Builder().build();
-        mExtensionRegistry = ExtensionRegistryLite.newInstance();
-        mExtensionRegistry.add(FeedRequest.feedRequest);
-        // TODO(aluo): Add ability to delay responses.
-        mResponseDelay = 0L;
-        mMockServer = MockServer.getDefaultInstance();
-    }
-
-    /**
-     * Set stored protobuf responses from the filePath
-     *
-     * @param filePath The file path of the compiled MockServer proto, pass in null to use the
-     *                 default response.
-     */
-    @VisibleForTesting
-    public void setNetworkResponseFile(String filePath) throws IOException {
-        if (filePath == null) {
-            setResponseData(null);
-        } else {
-            FileInputStream fs = new FileInputStream(filePath);
-            setResponseData(fs);
-            fs.close();
-        }
-    }
-
-    /**
-     * Set stored protobuf responses from the InputStream
-     *
-     * @param fs A {@link InputStream} with response pb data.
-     *           Pass in null to clear.
-     */
-    public void setResponseData(InputStream fs) throws IOException {
-        if (fs == null) {
-            mMockServer = MockServer.getDefaultInstance();
-        } else {
-            mMockServer = MockServer.parseFrom(fs);
-        }
-    }
-
-    @Override
-    public void send(HttpRequest httpRequest, Consumer<HttpResponse> responseConsumer) {
-        // TODO(aluo): Add ability to respond with HTTP Errors.
-        try {
-            Request request = getRequest(httpRequest);
-            ByteString requestToken =
-                    (request.getExtension(FeedRequest.feedRequest).getFeedQuery().hasPageToken())
-                    ? request.getExtension(FeedRequest.feedRequest).getFeedQuery().getPageToken()
-                    : null;
-            if (requestToken != null) {
-                for (ConditionalResponse response : mMockServer.getConditionalResponsesList()) {
-                    if (!response.hasContinuationToken()) {
-                        continue;
-                    }
-                    if (requestToken.equals(response.getContinuationToken())) {
-                        delayedAccept(createHttpResponse(response.getResponse()), responseConsumer);
-                        return;
-                    }
-                }
-                delayedAccept(createHttpResponse(Response.getDefaultInstance()), responseConsumer);
-            } else {
-                delayedAccept(
-                        createHttpResponse(mMockServer.getInitialResponse()), responseConsumer);
-            }
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private void delayedAccept(HttpResponse httpResponse, Consumer<HttpResponse> responseConsumer) {
-        if (mResponseDelay <= 0) {
-            maybeAccept(httpResponse, responseConsumer);
-        } else {
-            PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT,
-                    () -> maybeAccept(httpResponse, responseConsumer), mResponseDelay);
-        }
-    }
-
-    private Request getRequest(HttpRequest httpRequest) throws IOException {
-        byte[] rawRequest = new byte[0];
-        if (httpRequest.getMethod().equals(HttpMethod.GET)) {
-            if (httpRequest.getUri().getQueryParameter(RequestHelper.MOTHERSHIP_PARAM_PAYLOAD)
-                    != null) {
-                rawRequest = Base64.decode(httpRequest.getUri().getQueryParameter(
-                                                   RequestHelper.MOTHERSHIP_PARAM_PAYLOAD),
-                        Base64.URL_SAFE);
-            }
-        } else {
-            rawRequest = httpRequest.getBody();
-        }
-        return Request.parseFrom(rawRequest, mExtensionRegistry);
-    }
-
-    @Override
-    public void close() {
-        mAlreadyClosed.set(true);
-    }
-
-    private HttpResponse createHttpResponse(Response response) {
-        try {
-            byte[] rawResponse = response.toByteArray();
-            byte[] newResponse = new byte[rawResponse.length + (Integer.SIZE / 8)];
-            CodedOutputStream codedOutputStream = CodedOutputStream.newInstance(newResponse);
-            codedOutputStream.writeUInt32NoTag(rawResponse.length);
-            codedOutputStream.writeRawBytes(rawResponse);
-            codedOutputStream.flush();
-            return new HttpResponse(200, newResponse, /* isSignedIn= */ false);
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private void maybeAccept(HttpResponse httpResponse, Consumer<HttpResponse> responseConsumer) {
-        if (!mAlreadyClosed.get()) {
-            responseConsumer.accept(httpResponse);
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/tooltip/BasicTooltipApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/tooltip/BasicTooltipApi.java
deleted file mode 100644
index fc3e093..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/tooltip/BasicTooltipApi.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1.tooltip;
-
-import android.text.TextUtils;
-import android.view.View;
-
-import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipCallbackApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipInfo;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
-import org.chromium.components.browser_ui.widget.textbubble.TextBubble;
-import org.chromium.components.feature_engagement.Tracker;
-import org.chromium.ui.widget.ViewRectProvider;
-
-/**
- * A basic implementation of the {@link TooltipApi}.
- */
-public class BasicTooltipApi implements TooltipApi {
-    private static final int TEXT_BUBBLE_TIMEOUT_MS = 10000;
-
-    @Override
-    public boolean maybeShowHelpUi(
-            TooltipInfo tooltipInfo, View view, TooltipCallbackApi tooltipCallback) {
-        final String featureForIPH =
-                FeedTooltipUtils.getFeatureForIPH(tooltipInfo.getFeatureName());
-        if (TextUtils.isEmpty(featureForIPH)) return false;
-
-        final Tracker tracker =
-                TrackerFactory.getTrackerForProfile(Profile.getLastUsedRegularProfile());
-        if (!tracker.shouldTriggerHelpUI(featureForIPH)) return false;
-
-        ViewRectProvider rectProvider = new ViewRectProvider(view);
-        rectProvider.setInsetPx(0, tooltipInfo.getTopInset(), 0, tooltipInfo.getBottomInset());
-
-        TextBubble textBubble = new TextBubble(view.getContext(), view, tooltipInfo.getLabel(),
-                tooltipInfo.getAccessibilityLabel(), true, rectProvider,
-                ChromeAccessibilityUtil.get().isAccessibilityEnabled());
-        textBubble.setAutoDismissTimeout(TEXT_BUBBLE_TIMEOUT_MS);
-        textBubble.addOnDismissListener(() -> {
-            tracker.dismissed(featureForIPH);
-            tooltipCallback.onHide(TooltipCallbackApi.TooltipDismissType.TIMEOUT);
-        });
-
-        textBubble.show();
-        tooltipCallback.onShow();
-        return true;
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/tooltip/BasicTooltipSupportedApi.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/tooltip/BasicTooltipSupportedApi.java
deleted file mode 100644
index 6ebd1f4..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/tooltip/BasicTooltipSupportedApi.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1.tooltip;
-
-import android.text.TextUtils;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipSupportedApi;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.components.feature_engagement.Tracker;
-
-/**
- * A basic implementation of the {@link TooltipSupportedApi}.
- */
-public class BasicTooltipSupportedApi implements TooltipSupportedApi {
-    @Override
-    public void wouldTriggerHelpUi(String featureName, Consumer<Boolean> consumer) {
-        final String featureForIPH = FeedTooltipUtils.getFeatureForIPH(featureName);
-        if (TextUtils.isEmpty(featureForIPH)) {
-            consumer.accept(false);
-            return;
-        }
-
-        final Tracker tracker =
-                TrackerFactory.getTrackerForProfile(Profile.getLastUsedRegularProfile());
-        consumer.accept(tracker.wouldTriggerHelpUI(featureForIPH));
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/tooltip/FeedTooltipUtils.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/tooltip/FeedTooltipUtils.java
deleted file mode 100644
index 76e63f0..0000000
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/tooltip/FeedTooltipUtils.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1.tooltip;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipApi;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipInfo;
-import org.chromium.chrome.browser.feed.library.api.host.stream.TooltipSupportedApi;
-import org.chromium.components.feature_engagement.FeatureConstants;
-
-/**
- * Helper methods for implementation of {@link TooltipApi} and {@link TooltipSupportedApi}.
- */
-class FeedTooltipUtils {
-    /**
-     * @param featureName The feature name from {@link TooltipInfo.FeatureName}.
-     * @return A corresponding IPH feature name from {@link FeatureConstants} for the specified
-     *         {@code featureName}.
-     */
-    @Nullable
-    @FeatureConstants
-    static String getFeatureForIPH(@TooltipInfo.FeatureName String featureName) {
-        switch (featureName) {
-            case TooltipInfo.FeatureName.CARD_MENU_TOOLTIP:
-                return FeatureConstants.FEED_CARD_MENU_FEATURE;
-            case TooltipInfo.FeatureName.UNKNOWN:
-                return null;
-            default:
-                assert false
-                    : String.format("Unknown mapping to IPH feature for TooltipInfo.FeatureName %s",
-                              featureName);
-                return null;
-        }
-    }
-}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedServiceBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedServiceBridge.java
index 1dc65f3..071936a 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedServiceBridge.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedServiceBridge.java
@@ -4,6 +4,9 @@
 
 package org.chromium.chrome.browser.feed.v2;
 
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.os.Build;
 import android.util.DisplayMetrics;
 
 import org.chromium.base.ContextUtils;
@@ -11,9 +14,11 @@
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.chrome.browser.AppHooks;
-import org.chromium.chrome.browser.feed.library.common.locale.LocaleUtils;
 import org.chromium.chrome.browser.xsurface.ImagePrefetcher;
 import org.chromium.chrome.browser.xsurface.ProcessScope;
+
+import java.util.Locale;
+
 /**
  * Bridge for FeedService-related calls.
  */
@@ -33,10 +38,18 @@
         return FeedServiceBridgeJni.get().isEnabled();
     }
 
+    /** Returns the top user specified locale. */
+    @TargetApi(Build.VERSION_CODES.N)
+    private static Locale getLocale(Context context) {
+        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
+                ? context.getResources().getConfiguration().getLocales().get(0)
+                : context.getResources().getConfiguration().locale;
+    }
+
     // Java functionality needed for the native FeedService.
     @CalledByNative
     public static String getLanguageTag() {
-        return LocaleUtils.getLanguageTag(ContextUtils.getApplicationContext());
+        return getLocale(ContextUtils.getApplicationContext()).toLanguageTag();
     }
     @CalledByNative
     public static double[] getDisplayMetrics() {
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/ConsumerSyncWrapper.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/ConsumerSyncWrapper.java
deleted file mode 100644
index 8824eeb..0000000
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/ConsumerSyncWrapper.java
+++ /dev/null
@@ -1,58 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import org.junit.Assert;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.task.PostTask;
-import org.chromium.content_public.browser.UiThreadTaskTraits;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * ConsumerSyncWrapper allows the user to wait for the wrapped consumer to
- * accept an input.
- */
-class ConsumerSyncWrapper<T> implements Consumer<T> {
-    private final Consumer<T> mWrapped;
-    private final AtomicReference<T> mResult;
-    private final CountDownLatch mLatch;
-    private ConsumerSyncWrapper(Consumer<T> wrappedConsumer) {
-        mWrapped = wrappedConsumer;
-        mResult = new AtomicReference<>();
-        mLatch = new CountDownLatch(1);
-    }
-    private void blockAndWrappedAccept(long timeoutMs) {
-        try {
-            mLatch.await(timeoutMs, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            Assert.fail("waitForAccept was interrupted: " + e.getMessage());
-        }
-        mWrapped.accept(mResult.get());
-    }
-    @Override
-    public void accept(T input) {
-        mResult.set(input);
-        mLatch.countDown();
-    }
-
-    /**
-     * waitForConsumer calls the consumer operation on the UI Thread then blocks until the
-     * consumer has accepted the results of the operation.
-     *
-     * @param consumer The {@link Consumer} to block on.
-     * @param operation The operation that should feed its result to the consumer.
-     * @param timeoutMs The timeout in milliseconds to wait for operation to execute
-     */
-    public static <T> void waitForConsumer(
-            Consumer<T> consumer, Consumer<Consumer<T>> operation, long timeoutMs) {
-        ConsumerSyncWrapper<T> wrapper = new ConsumerSyncWrapper<>(consumer);
-        PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> operation.accept(wrapper));
-        wrapper.blockAndWrappedAccept(timeoutMs);
-    }
-}
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/DataFilePath.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/DataFilePath.java
deleted file mode 100644
index c296c75..0000000
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/DataFilePath.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * We use this annotation, together with {@FeedDataInjectRule}, to tell
- * which data file to inject for each test cases.
- *
- * For instance, if file_foo is used in test A, file_bar is used
- * in test B.
- *
- *     @Rule
- *     public FeedDataInjectRule mDataInjector = new FeedDataInjectRule();
- *
- *     @DataFilePath("file_foo")
- *     public void test_A() {
- *        // Write the test case here.
- *     }
- *
- *     @DataFilePath("file_bar")
- *     public void test_B() {
- *        // Write the test case here.
- *     }
- *
- *  In test_A, the FeedDataInjectRule will then injects file_foo via testNetworkClient,
- *  invokes triggerRefresh at UI thread, responses the seeded mockserver response from
- *  file_foo, and then blocks waiting for the content change notification. It does the
- *  similar for test_B except it injects file_bar.
- */
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface DataFilePath {
-    /**
-     * @return one DataFilePath.
-     */
-    public String value();
-}
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedAppLifecycleTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedAppLifecycleTest.java
deleted file mode 100644
index 71e26aa..0000000
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedAppLifecycleTest.java
+++ /dev/null
@@ -1,396 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Activity;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import org.chromium.base.ActivityState;
-import org.chromium.base.ApplicationStatus;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.base.task.PostTask;
-import org.chromium.base.test.util.CallbackHelper;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.DisabledTest;
-import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.browser.ChromeTabbedActivity;
-import org.chromium.chrome.browser.DeferredStartupHandler;
-import org.chromium.chrome.browser.feed.library.api.client.lifecycle.AppLifecycleListener;
-import org.chromium.chrome.browser.feed.library.api.host.network.NetworkClient;
-import org.chromium.chrome.browser.feed.library.common.time.testing.FakeClock;
-import org.chromium.chrome.browser.feed.library.hostimpl.storage.testing.InMemoryContentStorage;
-import org.chromium.chrome.browser.feed.library.hostimpl.storage.testing.InMemoryJournalStorage;
-import org.chromium.chrome.browser.feed.v1.FeedAppLifecycle.AppLifecycleEvent;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
-import org.chromium.chrome.browser.multiwindow.MultiWindowTestHelper;
-import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
-import org.chromium.chrome.browser.preferences.Pref;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
-import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
-import org.chromium.components.embedder_support.util.UrlConstants;
-import org.chromium.components.user_prefs.UserPrefs;
-import org.chromium.content_public.browser.LoadUrlParams;
-import org.chromium.content_public.browser.UiThreadTaskTraits;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * Unit tests for {@link FeedAppLifecycle}
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE)
-@DisableFeatures({ChromeFeatureList.INTEREST_FEED_V2})
-public class FeedAppLifecycleTest {
-    @Rule
-    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
-
-    @Mock
-    private FeedScheduler mFeedScheduler;
-    @Mock
-    private NetworkClient mNetworkClient;
-    @Mock
-    private FeedOfflineIndicator mOfflineIndicator;
-    @Mock
-    private AppLifecycleListener mAppLifecycleListener;
-
-    private TestDeferredStartupHandler mTestDeferredStartupHandler =
-            new TestDeferredStartupHandler();
-
-    private ChromeTabbedActivity mActivity;
-    private FeedAppLifecycle mAppLifecycle;
-    private FeedLifecycleBridge mLifecycleBridge;
-    private final String mHistogramAppLifecycleEvents =
-            "ContentSuggestions.Feed.AppLifecycle.Events";
-    private Profile mProfile;
-
-    private static class TestDeferredStartupHandler extends DeferredStartupHandler {
-        private List<Runnable> mDeferredTaskQueue = new ArrayList<>();
-        @Override
-        public void addDeferredTask(Runnable deferredTask) {
-            mDeferredTaskQueue.add(deferredTask);
-        }
-        public void runAllTasks() {
-            TestThreadUtils.runOnUiThreadBlocking(() -> {
-                for (Runnable deferredTask : mDeferredTaskQueue) {
-                    deferredTask.run();
-                }
-            });
-        }
-    }
-
-    @Before
-    public void setUp() throws InterruptedException {
-        MockitoAnnotations.initMocks(this);
-
-        DeferredStartupHandler.setInstanceForTests(mTestDeferredStartupHandler);
-
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            ChromeBrowserInitializer.getInstance().handleSynchronousStartup();
-            mProfile = Profile.getLastUsedRegularProfile();
-            mLifecycleBridge = new FeedLifecycleBridge(mProfile);
-            mAppLifecycle =
-                    new FeedAppLifecycle(mAppLifecycleListener, mLifecycleBridge, mFeedScheduler);
-            FeedProcessScopeFactory.createFeedProcessScopeForTesting(mFeedScheduler, mNetworkClient,
-                    mOfflineIndicator, mAppLifecycle,
-                    new FeedLoggingBridge(mProfile, new FakeClock()), new InMemoryContentStorage(),
-                    new InMemoryJournalStorage());
-        });
-
-        mActivityTestRule.startMainActivityOnBlankPage();
-        mActivity = mActivityTestRule.getActivity();
-    }
-
-    @After
-    public void tearDown() {
-        DeferredStartupHandler.setInstanceForTests(null);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void testConstructionChecksActiveTabbedActivities() {
-        verify(mAppLifecycleListener, times(1)).onEnterForeground();
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void testActivityStateChangesIncrementStateCounters() throws TimeoutException {
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.ENTER_BACKGROUND, 0);
-        verify(mAppLifecycleListener, times(1)).onEnterForeground();
-        signalActivityStop(mActivity);
-        signalActivityStart(mActivity);
-
-        verify(mAppLifecycleListener, times(1)).onEnterBackground();
-        verify(mAppLifecycleListener, times(2)).onEnterForeground();
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.ENTER_BACKGROUND, 1);
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.ENTER_FOREGROUND, 2);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void testNtpOpeningTriggersInitializeOnlyOnce() {
-        // We open to about:blank initially so we shouldn't have called initialize() yet.
-        verify(mAppLifecycleListener, times(0)).initialize();
-        mActivityTestRule.loadUrl(UrlConstants.NTP_URL);
-        verify(mAppLifecycleListener, times(1)).initialize();
-
-        // Opening the NTP again shouldn't trigger another call to initialize().
-        mActivityTestRule.loadUrlInNewTab(UrlConstants.NTP_URL);
-        verify(mAppLifecycleListener, times(1)).initialize();
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.INITIALIZE, 1);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void testOnHistoryDeleted() {
-        verify(mAppLifecycleListener, times(0)).onClearAll();
-        verify(mAppLifecycleListener, times(0)).onClearAllWithRefresh();
-        verify(mFeedScheduler, times(0)).onArticlesCleared(anyBoolean());
-        // Note that typically calling onArticlesCleared(true) will not return true, but the
-        // FeedAppLifecycle should not necessarily care.
-        when(mFeedScheduler.onArticlesCleared(anyBoolean())).thenReturn(true).thenReturn(false);
-
-        mAppLifecycle.onHistoryDeleted();
-        verify(mAppLifecycleListener, times(1)).onClearAllWithRefresh();
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.CLEAR_ALL, 1);
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.HISTORY_DELETED, 1);
-        verify(mFeedScheduler, times(1)).onArticlesCleared(true);
-
-        mAppLifecycle.onHistoryDeleted();
-        verify(mAppLifecycleListener, times(1)).onClearAll();
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.CLEAR_ALL, 2);
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.HISTORY_DELETED, 2);
-        verify(mFeedScheduler, times(2)).onArticlesCleared(true);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void testOnCachedDataCleared() {
-        verify(mAppLifecycleListener, times(0)).onClearAll();
-        verify(mAppLifecycleListener, times(0)).onClearAllWithRefresh();
-        verify(mFeedScheduler, times(0)).onArticlesCleared(anyBoolean());
-        when(mFeedScheduler.onArticlesCleared(anyBoolean())).thenReturn(true).thenReturn(false);
-
-        mAppLifecycle.onCachedDataCleared();
-        verify(mAppLifecycleListener, times(1)).onClearAllWithRefresh();
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.CLEAR_ALL, 1);
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.CACHED_DATA_CLEARED, 1);
-        verify(mFeedScheduler, times(1)).onArticlesCleared(false);
-
-        mAppLifecycle.onCachedDataCleared();
-        verify(mAppLifecycleListener, times(1)).onClearAll();
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.CLEAR_ALL, 2);
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.CACHED_DATA_CLEARED, 2);
-        verify(mFeedScheduler, times(2)).onArticlesCleared(false);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void testOnSignedOut() {
-        verify(mAppLifecycleListener, times(0)).onClearAll();
-        verify(mAppLifecycleListener, times(0)).onClearAllWithRefresh();
-        verify(mFeedScheduler, times(0)).onArticlesCleared(anyBoolean());
-        when(mFeedScheduler.onArticlesCleared(anyBoolean())).thenReturn(true).thenReturn(false);
-
-        mAppLifecycle.onSignedOut();
-        verify(mAppLifecycleListener, times(1)).onClearAllWithRefresh();
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.CLEAR_ALL, 1);
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.SIGN_OUT, 1);
-        verify(mFeedScheduler, times(1)).onArticlesCleared(false);
-
-        mAppLifecycle.onSignedOut();
-        verify(mAppLifecycleListener, times(1)).onClearAll();
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.CLEAR_ALL, 2);
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.SIGN_OUT, 2);
-        verify(mFeedScheduler, times(2)).onArticlesCleared(false);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void testOnSignedIn() {
-        verify(mAppLifecycleListener, times(0)).onClearAll();
-        verify(mAppLifecycleListener, times(0)).onClearAllWithRefresh();
-        verify(mFeedScheduler, times(0)).onArticlesCleared(anyBoolean());
-        when(mFeedScheduler.onArticlesCleared(anyBoolean())).thenReturn(true).thenReturn(false);
-
-        mAppLifecycle.onSignedIn();
-        verify(mAppLifecycleListener, times(1)).onClearAllWithRefresh();
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.CLEAR_ALL, 1);
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.SIGN_IN, 1);
-        verify(mFeedScheduler, times(1)).onArticlesCleared(false);
-
-        mAppLifecycle.onSignedIn();
-        verify(mAppLifecycleListener, times(1)).onClearAll();
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.CLEAR_ALL, 2);
-        verifyHistogram(mHistogramAppLifecycleEvents, AppLifecycleEvent.SIGN_IN, 2);
-        verify(mFeedScheduler, times(2)).onArticlesCleared(false);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    @DisabledTest(message = "https://crbug.com/1157507")
-    public void testSecondWindowDoesNotTriggerForegroundOrBackground() throws TimeoutException {
-        verify(mAppLifecycleListener, times(1)).onEnterForeground();
-
-        MultiWindowUtils.getInstance().setIsInMultiWindowModeForTesting(true);
-        ChromeTabbedActivity activity2 = MultiWindowTestHelper.createSecondChromeTabbedActivity(
-                mActivity, new LoadUrlParams(UrlConstants.NTP_URL));
-
-        signalActivityStop(activity2);
-
-        // Starting and then stopping the second activity shouldn't trigger either foreground or
-        // background.
-        verify(mAppLifecycleListener, times(0)).onEnterBackground();
-        verify(mAppLifecycleListener, times(1)).onEnterForeground();
-
-        signalActivityStop(mActivity);
-
-        // Only now that both TabbedActivity instances have stopped should we get a background
-        // event.
-        verify(mAppLifecycleListener, times(1)).onEnterBackground();
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    @EnableFeatures({ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS})
-    public void testMultiWindowDoesNotCauseMultipleInitialize() {
-        mActivityTestRule.loadUrl(UrlConstants.NTP_URL);
-        verify(mAppLifecycleListener, times(1)).initialize();
-
-        MultiWindowUtils.getInstance().setIsInMultiWindowModeForTesting(true);
-        ChromeTabbedActivity activity2 = MultiWindowTestHelper.createSecondChromeTabbedActivity(
-                mActivity, new LoadUrlParams(UrlConstants.NTP_URL));
-
-        verify(mAppLifecycleListener, times(1)).initialize();
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void testResumeTriggersSchedulerForegrounded() throws TimeoutException {
-        verify(mFeedScheduler, times(1)).onForegrounded();
-        signalActivityResume(mActivity);
-        verify(mFeedScheduler, times(2)).onForegrounded();
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void testClearDataAfterDisablingDoesNotCrash() {
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            FeedProcessScopeFactory.clearFeedProcessScopeForTesting();
-            UserPrefs.get(mProfile).setBoolean(Pref.ENABLE_SNIPPETS, false);
-            FeedLifecycleBridge.onCachedDataCleared();
-            FeedLifecycleBridge.onHistoryDeleted();
-        });
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void testDelayedInitNoParam() {
-        verify(mAppLifecycleListener, times(1)).onEnterForeground();
-        mTestDeferredStartupHandler.runAllTasks();
-        verify(mAppLifecycleListener, times(0)).initialize();
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:init_feed_after_startup/true"})
-    public void
-    testDelayedInitWithParamTrue() {
-        verify(mAppLifecycleListener, times(1)).onEnterForeground();
-        verify(mAppLifecycleListener, times(0)).initialize();
-        mTestDeferredStartupHandler.runAllTasks();
-        verify(mAppLifecycleListener, times(1)).initialize();
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:init_feed_after_startup/false"})
-    public void
-    testDelayedInitZeroParamFalse() {
-        verify(mAppLifecycleListener, times(1)).onEnterForeground();
-        mTestDeferredStartupHandler.runAllTasks();
-        verify(mAppLifecycleListener, times(0)).initialize();
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:init_feed_after_startup/notboolean"})
-    public void
-    testDelayedInitZeroParamNotBoolean() {
-        verify(mAppLifecycleListener, times(1)).onEnterForeground();
-        mTestDeferredStartupHandler.runAllTasks();
-        verify(mAppLifecycleListener, times(0)).initialize();
-    }
-
-    private void signalActivityStart(Activity activity) throws TimeoutException {
-        signalActivityState(activity, ActivityState.STARTED);
-    }
-
-    private void signalActivityResume(Activity activity) throws TimeoutException {
-        signalActivityState(activity, ActivityState.RESUMED);
-    }
-
-    private void signalActivityStop(Activity activity) throws TimeoutException {
-        signalActivityState(activity, ActivityState.STOPPED);
-    }
-
-    private void signalActivityState(final Activity activity,
-            final @ActivityState int activityState) throws TimeoutException {
-        final CallbackHelper waitForStateChangeHelper = new CallbackHelper();
-        PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> {
-            ApplicationStatus.onStateChangeForTesting(activity, activityState);
-            waitForStateChangeHelper.notifyCalled();
-        });
-
-        waitForStateChangeHelper.waitForCallback(0);
-    }
-
-    private void verifyHistogram(String name, @AppLifecycleEvent int sample, int expectedCount) {
-        assertEquals(expectedCount, RecordHistogram.getHistogramValueCountForTesting(name, sample));
-    }
-}
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedConfigurationTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedConfigurationTest.java
deleted file mode 100644
index d8a870f1..0000000
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedConfigurationTest.java
+++ /dev/null
@@ -1,474 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration;
-import org.chromium.chrome.browser.feed.library.api.host.config.Configuration.ConfigKey;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.test.ChromeBrowserTestRule;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.browser.Features;
-
-/** Tests for {@link FeedConfiguration}. */
-@SmallTest
-@RunWith(ChromeJUnit4ClassRunner.class)
-public class FeedConfigurationTest {
-    @Rule
-    public final ChromeBrowserTestRule mRule = new ChromeBrowserTestRule();
-
-    private static final double ASSERT_EQUALS_DOUBLE_DELTA = 0.001d;
-
-    @Test
-    @Feature({"Feed"})
-    @Features.EnableFeatures({ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS})
-    public void testDefaultFeedConfigurationValues() {
-        Assert.assertEquals(FeedConfiguration.ABANDON_RESTORE_BELOW_FOLD_DEFAULT,
-                FeedConfiguration.getAbandonRestoreBelowFold());
-        Assert.assertEquals(FeedConfiguration.CARD_MENU_TOOLTIP_ELIGIBLE_DEFAULT,
-                FeedConfiguration.getCardMenuTooltipEligible());
-        Assert.assertEquals(FeedConfiguration.CONSUME_SYNTHETIC_TOKENS_DEFAULT,
-                FeedConfiguration.getConsumeSyntheticTokens());
-        Assert.assertEquals(FeedConfiguration.CONSUME_SYNTHETIC_TOKENS_WHILE_RESTORING_DEFAULT,
-                FeedConfiguration.getConsumeSyntheticTokensWhileRestoring());
-        Assert.assertEquals(FeedConfiguration.DEFAULT_ACTION_TTL_SECONDS_DEFAULT,
-                FeedConfiguration.getDefaultActionTtlSeconds());
-        Assert.assertEquals(FeedConfiguration.FEED_ACTION_SERVER_ENDPOINT_DEFAULT,
-                FeedConfiguration.getFeedActionServerEndpoint());
-        Assert.assertEquals(FeedConfiguration.FEED_ACTION_SERVER_MAX_ACTIONS_PER_REQUEST_DEFAULT,
-                FeedConfiguration.getFeedActionServerMaxActionsPerRequest());
-        Assert.assertEquals(FeedConfiguration.FEED_ACTION_SERVER_MAX_SIZE_PER_REQUEST_DEFAULT,
-                FeedConfiguration.getFeedActionServerMaxSizePerRequest());
-        Assert.assertEquals(FeedConfiguration.FEED_ACTION_SERVER_METHOD_DEFAULT,
-                FeedConfiguration.getFeedActionServerMethod());
-        Assert.assertEquals(FeedConfiguration.FEED_SERVER_ENDPOINT_DEFAULT,
-                FeedConfiguration.getFeedServerEndpoint());
-        Assert.assertEquals(FeedConfiguration.FEED_SERVER_METHOD_DEFAULT,
-                FeedConfiguration.getFeedServerMethod());
-        Assert.assertEquals(FeedConfiguration.FEED_SERVER_RESPONSE_LENGTH_PREFIXED_DEFAULT,
-                FeedConfiguration.getFeedServerResponseLengthPrefixed());
-        Assert.assertEquals(
-                FeedConfiguration.FEED_UI_ENABLED_DEFAULT, FeedConfiguration.getFeedUiEnabled());
-        Assert.assertEquals(FeedConfiguration.INITIAL_NON_CACHED_PAGE_SIZE_DEFAULT,
-                FeedConfiguration.getInitialNonCachedPageSize());
-        Assert.assertEquals(FeedConfiguration.LIMIT_PAGE_UPDATES_IN_HEAD_DEFAULT,
-                FeedConfiguration.getLimitPageUpdatesInHead());
-        Assert.assertEquals(FeedConfiguration.LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS_DEFAULT,
-                FeedConfiguration.getLoggingImmediateContentThresholdMs());
-        Assert.assertEquals(FeedConfiguration.MANAGE_INTERESTS_ENABLED_DEFAULT,
-                FeedConfiguration.getManageInterestsEnabled());
-        Assert.assertEquals(FeedConfiguration.MAXIMUM_GC_ATTEMPTS_DEFAULT,
-                FeedConfiguration.getMaximumGcAttempts());
-        Assert.assertEquals(FeedConfiguration.NON_CACHED_MIN_PAGE_SIZE_DEFAULT,
-                FeedConfiguration.getNonCachedMinPageSize());
-        Assert.assertEquals(FeedConfiguration.NON_CACHED_PAGE_SIZE_DEFAULT,
-                FeedConfiguration.getNonCachedPageSize());
-        Assert.assertEquals(FeedConfiguration.SESSION_LIFETIME_MS_DEFAULT,
-                FeedConfiguration.getSessionLifetimeMs());
-        Assert.assertEquals(
-                FeedConfiguration.SNIPPETS_ENABLED_DEFAULT, FeedConfiguration.getSnippetsEnabled());
-        Assert.assertEquals(
-                FeedConfiguration.SPINNER_DELAY_MS_DEFAULT, FeedConfiguration.getSpinnerDelayMs());
-        Assert.assertEquals(FeedConfiguration.SPINNER_MINIMUM_SHOW_TIME_MS_DEFAULT,
-                FeedConfiguration.getSpinnerMinimumShowTimeMs());
-        Assert.assertEquals(FeedConfiguration.STORAGE_MISS_THRESHOLD_DEFAULT,
-                FeedConfiguration.getStorageMissThreshold());
-        Assert.assertEquals(FeedConfiguration.TRIGGER_IMMEDIATE_PAGINATION_DEFAULT,
-                FeedConfiguration.getTriggerImmediatePagination());
-        Assert.assertEquals(FeedConfiguration.UNDOABLE_ACTIONS_ENABLED_DEFAULT,
-                FeedConfiguration.getUndoableActionsEnabled());
-        Assert.assertEquals(FeedConfiguration.USE_TIMEOUT_SCHEDULER_DEFAULT,
-                FeedConfiguration.getUseTimeoutScheduler());
-        Assert.assertEquals(FeedConfiguration.USE_SECONDARY_PAGE_REQUEST_DEFAULT,
-                FeedConfiguration.getUseSecondaryPageRequest());
-        Assert.assertEquals(FeedConfiguration.VIEW_LOG_THRESHOLD_DEFAULT,
-                FeedConfiguration.getViewLogThreshold(), ASSERT_EQUALS_DOUBLE_DELTA);
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:abandon_restore_below_fold/false"})
-    public void
-    testAbandonRestoreBelowFold() {
-        Assert.assertFalse(FeedConfiguration.getAbandonRestoreBelowFold());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:card_menu_tooltip_eligible/true"})
-    public void
-    testCardMenuTooltipEligible() {
-        Assert.assertTrue(FeedConfiguration.getCardMenuTooltipEligible());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:consume_synthetic_tokens_bool/true"})
-    public void
-    testConsumeSyntheticTokens() {
-        Assert.assertTrue(FeedConfiguration.getConsumeSyntheticTokens());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:consume_synthetic_tokens_while_restoring_bool/"
-                    + "true"})
-    public void
-    testConsumeSyntheticTokensWhileRestoring() {
-        Assert.assertTrue(FeedConfiguration.getConsumeSyntheticTokensWhileRestoring());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:default_action_ttl_seconds/42"})
-    public void
-    testDefaultActionTTLSeconds() {
-        Assert.assertEquals(42, FeedConfiguration.getDefaultActionTtlSeconds());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:feed_action_server_endpoint/"
-                    + "https%3A%2F%2Ffeed%2Egoogle%2Ecom%2Fpath"})
-    public void
-    testFeedActionServerEndpoint() {
-        Assert.assertEquals(
-                "https://feed.google.com/path", FeedConfiguration.getFeedActionServerEndpoint());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:feed_action_server_max_actions_per_request/1234"})
-    public void
-    testFeedActionServerMaxActionsPerRequest() {
-        Assert.assertEquals(1234, FeedConfiguration.getFeedActionServerMaxActionsPerRequest());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:feed_action_server_max_size_per_request/1234"})
-    public void
-    testFeedActionServerMaxSizePerRequest() {
-        Assert.assertEquals(1234, FeedConfiguration.getFeedActionServerMaxSizePerRequest());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:feed_action_server_method/PUT"})
-    public void
-    testFeedActionServerMethod() {
-        Assert.assertEquals("PUT", FeedConfiguration.getFeedActionServerMethod());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:feed_server_endpoint/"
-                    + "https%3A%2F%2Ffeed%2Egoogle%2Ecom%2Fpath"})
-    public void
-    testFeedServerEndpoint() {
-        Assert.assertEquals(
-                "https://feed.google.com/path", FeedConfiguration.getFeedServerEndpoint());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:feed_server_method/POST"})
-    public void
-    testFeedServerMethod() {
-        Assert.assertEquals("POST", FeedConfiguration.getFeedServerMethod());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:feed_server_response_length_prefixed/false"})
-    public void
-    testFeedServerResponseLengthPrefixed() {
-        Assert.assertEquals(false, FeedConfiguration.getFeedServerResponseLengthPrefixed());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:feed_ui_enabled/true"})
-    public void
-    testFeedUiEnabled() {
-        Assert.assertTrue(FeedConfiguration.getFeedUiEnabled());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:initial_non_cached_page_size/100"})
-    public void
-    testInitialNonCachedPageSize() {
-        Assert.assertEquals(100, FeedConfiguration.getInitialNonCachedPageSize());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:limit_page_updates_in_head/true"})
-    public void
-    testLimitPageUpdatesInHead() {
-        Assert.assertTrue(FeedConfiguration.getLimitPageUpdatesInHead());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:logging_immediate_content_threshold_ms/5000"})
-    public void
-    testLoggingImmediateContentThresholdMs() {
-        Assert.assertEquals(5000, FeedConfiguration.getLoggingImmediateContentThresholdMs());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:manage_interests_enabled/true"})
-    public void
-    testManageInterestsEnabled() {
-        Assert.assertTrue(FeedConfiguration.getManageInterestsEnabled());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:maximum_gc_attempts/5"})
-    public void
-    testMaximumGcAttempts() {
-        Assert.assertEquals(5, FeedConfiguration.getMaximumGcAttempts());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:non_cached_min_page_size/100"})
-    public void
-    testNonCachedMinPageSize() {
-        Assert.assertEquals(100, FeedConfiguration.getNonCachedMinPageSize());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:non_cached_page_size/100"})
-    public void
-    testNonCachedPageSize() {
-        Assert.assertEquals(100, FeedConfiguration.getNonCachedPageSize());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:session_lifetime_ms/60000"})
-    public void
-    testSessionLifetimeMs() {
-        Assert.assertEquals(60000, FeedConfiguration.getSessionLifetimeMs());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:snippets_enabled/true"})
-    public void
-    testSnippetsEnabled() {
-        Assert.assertTrue(FeedConfiguration.getSnippetsEnabled());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:spinner_delay/333"})
-    public void
-    testSpinnerDelayMs() {
-        Assert.assertEquals(333, FeedConfiguration.getSpinnerDelayMs());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:storage_miss_threshold/444"})
-    public void
-    testStorageMissThreshold() {
-        Assert.assertEquals(444, FeedConfiguration.getStorageMissThreshold());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:spinner_minimum_show_time/444"})
-    public void
-    testSpinnerMinimumShowTimeMs() {
-        Assert.assertEquals(444, FeedConfiguration.getSpinnerMinimumShowTimeMs());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:trigger_immediate_pagination/true"})
-    public void
-    testTriggerImmedatePagination() {
-        Assert.assertTrue(FeedConfiguration.getTriggerImmediatePagination());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:undoable_actions_enabled/true"})
-    public void
-    testUndoableActionsEnabled() {
-        Assert.assertTrue(FeedConfiguration.getUndoableActionsEnabled());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:use_timeout_scheduler/false"})
-    public void
-    testUseTimeoutScheduler() {
-        Assert.assertFalse(FeedConfiguration.getUseTimeoutScheduler());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:use_secondary_page_request/true"})
-    public void
-    testUseSecondaryPageRequest() {
-        Assert.assertTrue(FeedConfiguration.getUseSecondaryPageRequest());
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @CommandLineFlags.
-    Add({"enable-features=InterestFeedContentSuggestions<Trial", "force-fieldtrials=Trial/Group",
-            "force-fieldtrial-params=Trial.Group:view_log_threshold/0.33"})
-    public void
-    testViewLogThreshold() {
-        Assert.assertEquals(
-                0.33d, FeedConfiguration.getViewLogThreshold(), ASSERT_EQUALS_DOUBLE_DELTA);
-    }
-
-    @Test
-    @Feature({"Feed"})
-    @Features.EnableFeatures({ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS})
-    public void testCreateConfiguration() {
-        Configuration configuration = FeedConfiguration.createConfiguration();
-        Assert.assertFalse(
-                configuration.getValueOrDefault(ConfigKey.ABANDON_RESTORE_BELOW_FOLD, true));
-        Assert.assertTrue(
-                configuration.getValueOrDefault(ConfigKey.CARD_MENU_TOOLTIP_ELIGIBLE, false));
-        Assert.assertFalse(
-                configuration.getValueOrDefault(ConfigKey.CONSUME_SYNTHETIC_TOKENS, true));
-        Assert.assertTrue(configuration.getValueOrDefault(
-                ConfigKey.CONSUME_SYNTHETIC_TOKENS_WHILE_RESTORING, false));
-        Assert.assertEquals((long) FeedConfiguration.DEFAULT_ACTION_TTL_SECONDS_DEFAULT,
-                configuration.getValueOrDefault(ConfigKey.DEFAULT_ACTION_TTL_SECONDS, 0));
-        Assert.assertEquals(FeedConfiguration.FEED_ACTION_SERVER_ENDPOINT_DEFAULT,
-                configuration.getValueOrDefault(ConfigKey.FEED_ACTION_SERVER_ENDPOINT, ""));
-        Assert.assertEquals(
-                (long) FeedConfiguration.FEED_ACTION_SERVER_MAX_ACTIONS_PER_REQUEST_DEFAULT,
-                configuration.getValueOrDefault(
-                        ConfigKey.FEED_ACTION_SERVER_MAX_ACTIONS_PER_REQUEST, 0));
-        Assert.assertEquals(
-                (long) FeedConfiguration.FEED_ACTION_SERVER_MAX_SIZE_PER_REQUEST_DEFAULT,
-                configuration.getValueOrDefault(
-                        ConfigKey.FEED_ACTION_SERVER_MAX_SIZE_PER_REQUEST, 0));
-        Assert.assertEquals(FeedConfiguration.FEED_ACTION_SERVER_METHOD_DEFAULT,
-                configuration.getValueOrDefault(ConfigKey.FEED_ACTION_SERVER_METHOD, ""));
-        Assert.assertEquals(FeedConfiguration.FEED_SERVER_ENDPOINT_DEFAULT,
-                configuration.getValueOrDefault(ConfigKey.FEED_SERVER_ENDPOINT, ""));
-        Assert.assertEquals(FeedConfiguration.FEED_SERVER_METHOD_DEFAULT,
-                configuration.getValueOrDefault(ConfigKey.FEED_SERVER_METHOD, ""));
-        Assert.assertEquals(FeedConfiguration.FEED_SERVER_RESPONSE_LENGTH_PREFIXED_DEFAULT,
-                configuration.getValueOrDefault(
-                        ConfigKey.FEED_SERVER_RESPONSE_LENGTH_PREFIXED, false));
-        Assert.assertTrue(configuration.getValueOrDefault(ConfigKey.FEED_UI_ENABLED, false));
-        Assert.assertEquals((long) FeedConfiguration.INITIAL_NON_CACHED_PAGE_SIZE_DEFAULT,
-                configuration.getValueOrDefault(ConfigKey.INITIAL_NON_CACHED_PAGE_SIZE, 0));
-        Assert.assertFalse(
-                configuration.getValueOrDefault(ConfigKey.LIMIT_PAGE_UPDATES_IN_HEAD, true));
-        Assert.assertEquals((long) FeedConfiguration.LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS_DEFAULT,
-                configuration.getValueOrDefault(
-                        ConfigKey.LOGGING_IMMEDIATE_CONTENT_THRESHOLD_MS, 0L));
-        Assert.assertTrue(
-                configuration.getValueOrDefault(ConfigKey.MANAGE_INTERESTS_ENABLED, false));
-        Assert.assertEquals((long) FeedConfiguration.MAXIMUM_GC_ATTEMPTS_DEFAULT,
-                configuration.getValueOrDefault(ConfigKey.MAXIMUM_GC_ATTEMPTS, 0L));
-        Assert.assertEquals((long) FeedConfiguration.NON_CACHED_MIN_PAGE_SIZE_DEFAULT,
-                configuration.getValueOrDefault(ConfigKey.NON_CACHED_MIN_PAGE_SIZE, 0));
-        Assert.assertEquals((long) FeedConfiguration.NON_CACHED_PAGE_SIZE_DEFAULT,
-                configuration.getValueOrDefault(ConfigKey.NON_CACHED_PAGE_SIZE, 0));
-        Assert.assertEquals((long) FeedConfiguration.SESSION_LIFETIME_MS_DEFAULT,
-                configuration.getValueOrDefault(ConfigKey.SESSION_LIFETIME_MS, 0L));
-        Assert.assertTrue(configuration.getValueOrDefault(ConfigKey.SNIPPETS_ENABLED, false));
-        Assert.assertEquals((long) FeedConfiguration.SPINNER_DELAY_MS_DEFAULT,
-                configuration.getValueOrDefault(ConfigKey.SPINNER_DELAY_MS, 0L));
-        Assert.assertEquals((long) FeedConfiguration.SPINNER_MINIMUM_SHOW_TIME_MS_DEFAULT,
-                configuration.getValueOrDefault(ConfigKey.SPINNER_MINIMUM_SHOW_TIME_MS, 0L));
-        Assert.assertEquals((long) FeedConfiguration.STORAGE_MISS_THRESHOLD_DEFAULT,
-                configuration.getValueOrDefault(ConfigKey.STORAGE_MISS_THRESHOLD, 0L));
-        Assert.assertFalse(
-                configuration.getValueOrDefault(ConfigKey.TRIGGER_IMMEDIATE_PAGINATION, true));
-        Assert.assertTrue(
-                configuration.getValueOrDefault(ConfigKey.UNDOABLE_ACTIONS_ENABLED, false));
-        Assert.assertTrue(configuration.getValueOrDefault(ConfigKey.USE_TIMEOUT_SCHEDULER, false));
-        Assert.assertFalse(
-                configuration.getValueOrDefault(ConfigKey.USE_SECONDARY_PAGE_REQUEST, true));
-        Assert.assertEquals(Double.valueOf(FeedConfiguration.VIEW_LOG_THRESHOLD_DEFAULT),
-                configuration.getValueOrDefault(ConfigKey.VIEW_LOG_THRESHOLD, 0d),
-                ASSERT_EQUALS_DOUBLE_DELTA);
-    }
-}
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedContentStorageConformanceTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedContentStorageConformanceTest.java
deleted file mode 100644
index 5914afb..0000000
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedContentStorageConformanceTest.java
+++ /dev/null
@@ -1,91 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.testing.conformance.storage.ContentStorageConformanceTest;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.test.ChromeBrowserTestRule;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Conformance Tests for {@link FeedContentStorage}.
- * The actual tests are implemented in ContentStorageConformanceTest.
- */
-
-// The @SmallTest class annotation is needed to allow the inherited @Test methods to run using
-// build/android/test_runner.py.
-@SmallTest
-@RunWith(ChromeJUnit4ClassRunner.class)
-@DisableFeatures({ChromeFeatureList.INTEREST_FEED_V2})
-public final class FeedContentStorageConformanceTest extends ContentStorageConformanceTest {
-    private static final long TIMEOUT = scaleTimeout(3000);
-
-    class ContentStorageWrapper extends FeedContentStorage {
-        public ContentStorageWrapper(Profile p) {
-            super(p);
-        }
-
-        @Override
-        public void getAllKeys(Consumer<Result<List<String>>> consumer) {
-            ConsumerSyncWrapper.waitForConsumer(
-                    consumer, (wrapper) -> { super.getAllKeys(wrapper); }, TIMEOUT);
-        }
-
-        @Override
-        public void get(List<String> keys, Consumer<Result<Map<String, byte[]>>> consumer) {
-            ConsumerSyncWrapper.waitForConsumer(
-                    consumer, (wrapper) -> { super.get(keys, wrapper); }, TIMEOUT);
-        }
-
-        @Override
-        public void getAll(String prefix, Consumer<Result<Map<String, byte[]>>> consumer) {
-            ConsumerSyncWrapper.waitForConsumer(
-                    consumer, (wrapper) -> { super.getAll(prefix, wrapper); }, TIMEOUT);
-        }
-
-        @Override
-        public void commit(ContentMutation mutation, Consumer<CommitResult> consumer) {
-            ConsumerSyncWrapper.waitForConsumer(
-                    consumer, (wrapper) -> { super.commit(mutation, wrapper); }, TIMEOUT);
-        }
-    }
-
-    @Rule
-    public final ChromeBrowserTestRule mRule = new ChromeBrowserTestRule();
-
-    @Before
-    public void setUp() {
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            // storage is declared and tested in ContentStorageConformanceTest.
-            mStorage = new ContentStorageWrapper(Profile.getLastUsedRegularProfile());
-        });
-    }
-
-    @After
-    public void tearDown() {
-        TestThreadUtils.runOnUiThreadBlocking(
-                () -> { ((ContentStorageWrapper) mStorage).destroy(); });
-        mStorage = null;
-    }
-}
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedDataInjectRule.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedDataInjectRule.java
deleted file mode 100644
index 9aabbc9..0000000
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedDataInjectRule.java
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import static org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ViewHolderType.TYPE_CARD;
-
-import androidx.recyclerview.widget.RecyclerView;
-
-import org.junit.Assert;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
-
-import org.chromium.base.Log;
-import org.chromium.base.test.util.CallbackHelper;
-import org.chromium.base.test.util.UrlUtils;
-import org.chromium.chrome.browser.feed.library.hostimpl.storage.testing.InMemoryContentStorage;
-import org.chromium.chrome.browser.feed.library.hostimpl.storage.testing.InMemoryJournalStorage;
-import org.chromium.chrome.browser.feed.shared.stream.Stream;
-import org.chromium.chrome.browser.ntp.cards.SignInPromo;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-
-import java.io.IOException;
-import java.util.concurrent.TimeoutException;
-
-/**
- * A test rule to inject feed card data, base on the {@DataFilePath} annotation,
- * into the FeedProcessScopeFactory via TestNetworkClient.
- * If there is no {@DataFilePath} annotation, then no data injection happens
- * for that test case.
- *
- * <pre>
- * {@code
- *
- * @RunWith(ChromeJUnit4ClassRunner.class)
- * @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
- * public class MyTest{
- *     // Provide FeedDataInjectRule with the path from src/ to the test data directory.
- *     @Rule
- *     public FeedDataInjectRule mDataInjector = new FeedDataInjectRule();
- *
- *     @Rule
- *     public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
- *
- *     @Test
- *     @Feature({"FeedNewTabPage"})
- *     @DataFilePath("foo")
- *     public void testViewCard() {
- *         mActivityTestRule.loadUrlInNewTab(UrlConstants.NTP_URL);
- *         Tab tab = mActivityTestRule.getActivity().getActivityTab();
- *         NewTabPageTestUtils.waitForNtpLoaded(tab);
- *
- *         FeedNewTabPage ntp = (FeedNewTabPage) tab.getNativePage();
- *         mInjectDataRule.triggerFeedRefreshOnUiThreadBlocking(ntp.getStreamForTesting());
- *     }
- * }
- * }
- * </pre>
- */
-public final class FeedDataInjectRule extends TestWatcher {
-    private static final String TAG = "FeedDataInjectRule";
-    private static final int FIRST_CARD_BASE_POSITION = 2;
-
-    private TestNetworkClient mClient;
-    private boolean mTestCaseDataFileInjected;
-    private int mFirstCardIndexOffset;
-
-    public FeedDataInjectRule(boolean disableSigninPromo) {
-        // Disable Signin Promo to disable flakiness due to uncertainty in Signin Promo loading.
-        // More context see crbug/1028997.
-        if (disableSigninPromo) {
-            SignInPromo.setDisablePromoForTests(true);
-            mFirstCardIndexOffset = 0;
-        } else {
-            // Once we enable Signin Promo, the FIRST_CARD_POSITION becomes 3.
-            mFirstCardIndexOffset = 1;
-        }
-    }
-
-    public int getFirstCardPosition() {
-        return FIRST_CARD_BASE_POSITION + mFirstCardIndexOffset;
-    }
-
-    @Override
-    protected void starting(Description desc) {
-        DataFilePath filePath = desc.getAnnotation(DataFilePath.class);
-        if (filePath != null) {
-            mClient = new TestNetworkClient();
-            try {
-                mClient.setNetworkResponseFile(UrlUtils.getIsolatedTestFilePath(filePath.value()));
-                FeedProcessScopeFactory.setTestNetworkClient(mClient);
-                FeedProcessScopeFactory.setTestContentStorageDirect(new InMemoryContentStorage());
-                FeedProcessScopeFactory.setTestJournalStorageDirect(new InMemoryJournalStorage());
-                mTestCaseDataFileInjected = true;
-            } catch (IOException e) {
-                Log.e(TAG, "fails to set response file %s, err %s", filePath.value(),
-                        e.getMessage());
-                Assert.fail(
-                        String.format("starting fails to set response file %s", filePath.value()));
-            }
-        }
-    }
-
-    @Override
-    protected void finished(Description description) {
-        FeedProcessScopeFactory.setTestNetworkClient(null);
-        FeedProcessScopeFactory.setTestContentStorageDirect(null);
-        FeedProcessScopeFactory.setTestJournalStorageDirect(null);
-        mTestCaseDataFileInjected = false;
-    }
-
-    public void triggerFeedRefreshOnUiThreadBlocking(Stream stream)
-            throws IllegalArgumentException, TimeoutException {
-        if (stream == null) {
-            throw new IllegalArgumentException("stream should not be null.");
-        }
-        if (mTestCaseDataFileInjected) {
-            TestObserver observer =
-                    new TestObserver(((RecyclerView) stream.getView()).getAdapter());
-            stream.addOnContentChangedListener(observer);
-            int callCount = observer.firstCardShownCallback.getCallCount();
-            Log.i(TAG, "Waiting for %d callback calls", callCount);
-            TestThreadUtils.runOnUiThreadBlocking(() -> stream.triggerRefresh());
-            observer.firstCardShownCallback.waitForCallback(callCount);
-        }
-    }
-
-    private class TestObserver implements Stream.ContentChangedListener {
-        public final CallbackHelper firstCardShownCallback = new CallbackHelper();
-        private final RecyclerView.Adapter mRecyclerViewAdapter;
-
-        TestObserver(RecyclerView.Adapter adapter) {
-            mRecyclerViewAdapter = adapter;
-        }
-
-        @Override
-        public void onContentChanged() {
-            if (mRecyclerViewAdapter.getItemViewType(getFirstCardPosition()) == TYPE_CARD) {
-                firstCardShownCallback.notifyCalled();
-            }
-        }
-    }
-}
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorageConformanceTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorageConformanceTest.java
deleted file mode 100644
index 90b0fc6..0000000
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorageConformanceTest.java
+++ /dev/null
@@ -1,101 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.Consumer;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalMutation;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.feed.library.testing.conformance.storage.JournalStorageConformanceTest;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.test.ChromeBrowserTestRule;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-
-import java.util.List;
-
-/**
- * Conformance Tests for {@link FeedJournalStorage}.
- * The actual tests are implemented in JournalConformanceTest.
- */
-
-// The @SmallTest class annotation is needed to allow the inherited @Test methods to run using
-// build/android/test_runner.py.
-@SmallTest
-@RunWith(ChromeJUnit4ClassRunner.class)
-@DisableFeatures({ChromeFeatureList.INTEREST_FEED_V2})
-public final class FeedJournalStorageConformanceTest extends JournalStorageConformanceTest {
-    private static final long TIMEOUT = scaleTimeout(3000);
-
-    /**
-     * JournalStorageWrapper executes FeedJournalStorage operations
-     * in the UiThread and blocks the test thread until the consumer
-     * has been called.
-     */
-    class JournalStorageWrapper extends FeedJournalStorage {
-        public JournalStorageWrapper(Profile p) {
-            super(p);
-        }
-
-        @Override
-        public void read(String journalName, Consumer<Result<List<byte[]>>> consumer) {
-            ConsumerSyncWrapper.waitForConsumer(
-                    consumer, (wrapper) -> { super.read(journalName, wrapper); }, TIMEOUT);
-        }
-
-        @Override
-        public void commit(JournalMutation mutation, Consumer<CommitResult> consumer) {
-            ConsumerSyncWrapper.waitForConsumer(
-                    consumer, (wrapper) -> { super.commit(mutation, wrapper); }, TIMEOUT);
-        }
-
-        @Override
-        public void exists(String journalName, Consumer<Result<Boolean>> consumer) {
-            ConsumerSyncWrapper.waitForConsumer(
-                    consumer, (wrapper) -> { super.exists(journalName, wrapper); }, TIMEOUT);
-        }
-
-        @Override
-        public void getAllJournals(Consumer<Result<List<String>>> consumer) {
-            ConsumerSyncWrapper.waitForConsumer(
-                    consumer, (wrapper) -> { super.getAllJournals(wrapper); }, TIMEOUT);
-        }
-
-        @Override
-        public void deleteAll(Consumer<CommitResult> consumer) {
-            ConsumerSyncWrapper.waitForConsumer(
-                    consumer, (wrapper) -> { super.deleteAll(wrapper); }, TIMEOUT);
-        }
-    }
-
-    @Rule
-    public final ChromeBrowserTestRule mRule = new ChromeBrowserTestRule();
-
-    @Before
-    public void setUp() {
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            // journalStorage is declared and tested in JournalStorageConformanceTest.
-            mJournalStorage = new JournalStorageWrapper(Profile.getLastUsedRegularProfile());
-        });
-    }
-
-    @After
-    public void tearDown() {
-        TestThreadUtils.runOnUiThreadBlocking(
-                () -> { ((JournalStorageWrapper) mJournalStorage).destroy(); });
-        mJournalStorage = null;
-    }
-}
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedNetworkBridgeConformanceTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedNetworkBridgeConformanceTest.java
deleted file mode 100644
index 2d7b5cf..0000000
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedNetworkBridgeConformanceTest.java
+++ /dev/null
@@ -1,136 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
-
-import android.content.Context;
-import android.net.Uri;
-import android.support.test.InstrumentationRegistry;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.Log;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpRequest;
-import org.chromium.chrome.browser.feed.library.api.host.network.HttpResponse;
-import org.chromium.chrome.browser.feed.library.testing.conformance.network.NetworkClientConformanceTest;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.test.ChromeBrowserTestRule;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-import org.chromium.net.test.EmbeddedTestServer;
-
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Conformance Tests for {@link FeedNetworkBridge}.
- * The actual tests are implemented in NetworkClientConformanceTest
- */
-
-// The @SmallTest class annotation is needed to allow
-// the inherited @Test methods to run using build/android/test_runner.py
-@SmallTest
-@RunWith(ChromeJUnit4ClassRunner.class)
-@DisableFeatures({ChromeFeatureList.INTEREST_FEED_V2})
-public final class FeedNetworkBridgeConformanceTest extends NetworkClientConformanceTest {
-    private static final String TAG = "FeedConformanceTest";
-    private static final long TIMEOUT = scaleTimeout(3000);
-
-    @Rule
-    public final ChromeBrowserTestRule mRule = new ChromeBrowserTestRule();
-
-    private EmbeddedTestServer mTestServer;
-
-    class TestConsumer implements Consumer<HttpResponse> {
-        private FutureTask<Void> mAcceptFuture;
-        private Consumer<HttpResponse> mConsumer;
-
-        public TestConsumer(Consumer<HttpResponse> consumer) {
-            mConsumer = consumer;
-            mAcceptFuture = new FutureTask<Void>(() -> null);
-        }
-
-        @Override
-        public void accept(HttpResponse input) {
-            mConsumer.accept(input);
-            mAcceptFuture.run();
-        }
-
-        public void waitUntilCalled(long milliSecsTimeout) {
-            try {
-                mAcceptFuture.get(milliSecsTimeout, TimeUnit.MILLISECONDS);
-            } catch (Exception e) {
-                Log.w(TAG, "Exception while waiting for accept: " + e);
-                e.printStackTrace();
-            }
-        }
-    }
-
-    class FeedTestNetworkBridge extends FeedNetworkBridge {
-        public FeedTestNetworkBridge(Profile p) {
-            super(p);
-        }
-
-        @Override
-        public void send(HttpRequest request, Consumer<HttpResponse> responseConsumer) {
-            // TODO(aluo): remove once b/79609987 is fixed
-            // The NetworkClientConformanceTest sends requests to google.com,
-            // change it to use a local URI in tests.
-            String url = mTestServer.getURL("/chrome/test/data/google/google.html");
-            Uri uri = Uri.parse(url);
-            HttpRequest testServerRequest = new HttpRequest(
-                    uri, request.getMethod(), request.getHeaders(), request.getBody());
-            TestConsumer testConsumer = new TestConsumer(responseConsumer);
-            TestThreadUtils.runOnUiThreadBlocking(
-                    () -> super.send(testServerRequest, testConsumer));
-            // TODO(aluo): remove once b/79753857 is fixed
-            // Need convert the send into a sync call due to
-            // NetworkClientConformanceTest not waiting before checking that
-            // responseConsumer is accepted.
-            testConsumer.waitUntilCalled(TIMEOUT);
-        }
-    }
-
-    private void createNetworkClient() {
-        // The networkClient is declared and tested in NetworkClientConformanceTest
-        mNetworkClient = new FeedTestNetworkBridge(Profile.getLastUsedRegularProfile());
-    }
-
-    private void destroyNetworkClient() {
-        ((FeedTestNetworkBridge) mNetworkClient).destroy();
-        mNetworkClient = null;
-    }
-
-    private void createAndStartTestServer() {
-        Context c = InstrumentationRegistry.getContext();
-        mTestServer = EmbeddedTestServer.createAndStartServer(c);
-    }
-
-    private void stopAndDestroyTestServer() {
-        mTestServer.stopAndDestroyServer();
-        mTestServer = null;
-    }
-
-    @Before
-    public void setUp() {
-        createAndStartTestServer();
-        TestThreadUtils.runOnUiThreadBlocking(() -> createNetworkClient());
-    }
-
-    @After
-    public void tearDown() {
-        TestThreadUtils.runOnUiThreadBlocking(() -> destroyNetworkClient());
-        stopAndDestroyTestServer();
-    }
-}
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedNewTabPageCardRenderTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedNewTabPageCardRenderTest.java
deleted file mode 100644
index 3eb62bb2..0000000
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedNewTabPageCardRenderTest.java
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import static androidx.test.espresso.Espresso.onView;
-
-import static org.hamcrest.Matchers.instanceOf;
-
-import android.view.ViewGroup;
-
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.espresso.contrib.RecyclerViewActions;
-import androidx.test.filters.MediumTest;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.IntegrationTest;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.browser.ntp.NewTabPage;
-import org.chromium.chrome.browser.ntp.snippets.SectionHeader;
-import org.chromium.chrome.browser.preferences.Pref;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.suggestions.SiteSuggestion;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
-import org.chromium.chrome.test.util.ChromeRenderTestRule;
-import org.chromium.chrome.test.util.NewTabPageTestUtils;
-import org.chromium.chrome.test.util.browser.Features;
-import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule;
-import org.chromium.chrome.test.util.browser.suggestions.mostvisited.FakeMostVisitedSites;
-import org.chromium.components.browser_ui.widget.RecyclerViewTestUtils;
-import org.chromium.components.embedder_support.util.UrlConstants;
-import org.chromium.components.user_prefs.UserPrefs;
-import org.chromium.net.test.EmbeddedTestServerRule;
-
-import java.util.List;
-
-/**
- * Tests for {@link NewTabPage} with card rendering. Other tests can be found in
- * {@link org.chromium.chrome.browser.feed.FeedNewTabPageTest}.
- */
-// clang-format off
-@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
-        "disable-features=IPH_FeedHeaderMenu"})
-@Features.EnableFeatures({ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS,
-    ChromeFeatureList.OMNIBOX_SEARCH_ENGINE_LOGO})
-@Features.DisableFeatures({ChromeFeatureList.REPORT_FEED_USER_ACTIONS,
-    ChromeFeatureList.QUERY_TILES, ChromeFeatureList.VIDEO_TUTORIALS,
-    ChromeFeatureList.ENHANCED_PROTECTION_PROMO_CARD,
-    ChromeFeatureList.INTEREST_FEED_V2, ChromeFeatureList.INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS,
-    ChromeFeatureList.INTEREST_FEEDV1_CLICKS_AND_VIEWS_CONDITIONAL_UPLOAD})
-public class FeedNewTabPageCardRenderTest {
-    // clang-format on
-    private static final String TEST_FEED_DATA_BASE_PATH = "/chrome/test/data/android/feed/";
-
-    @Rule
-    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
-
-    @Rule
-    public SuggestionsDependenciesRule mSuggestionsDeps = new SuggestionsDependenciesRule();
-
-    @Rule
-    public ChromeRenderTestRule mRenderTestRule =
-            ChromeRenderTestRule.Builder.withPublicCorpus().build();
-
-    @Rule
-    public FeedDataInjectRule mFeedDataInjector = new FeedDataInjectRule(true);
-
-    @Rule
-    public EmbeddedTestServerRule mTestServer = new EmbeddedTestServerRule();
-
-    private Tab mTab;
-    private NewTabPage mNtp;
-    private ViewGroup mTileGridLayout;
-    private FakeMostVisitedSites mMostVisitedSites;
-    private List<SiteSuggestion> mSiteSuggestions;
-
-    @Before
-    public void setUp() throws Exception {
-        mActivityTestRule.startMainActivityOnBlankPage();
-        mSiteSuggestions = NewTabPageTestUtils.createFakeSiteSuggestions(mTestServer.getServer());
-        mMostVisitedSites = new FakeMostVisitedSites();
-        mMostVisitedSites.setTileSuggestions(mSiteSuggestions);
-        mSuggestionsDeps.getFactory().mostVisitedSites = mMostVisitedSites;
-
-        mActivityTestRule.loadUrl(UrlConstants.NTP_URL);
-        mTab = mActivityTestRule.getActivity().getActivityTab();
-        NewTabPageTestUtils.waitForNtpLoaded(mTab);
-
-        Assert.assertTrue(mTab.getNativePage() instanceof NewTabPage);
-        mNtp = (NewTabPage) mTab.getNativePage();
-        mTileGridLayout = mNtp.getView().findViewById(R.id.tile_grid_layout);
-        Assert.assertEquals(mSiteSuggestions.size(), mTileGridLayout.getChildCount());
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"FeedNewTabPage", "RenderTest"})
-    @DataFilePath(TEST_FEED_DATA_BASE_PATH + "feed_world.gcl.bin")
-    @IntegrationTest
-    // The IntegrationTest annotation skips this test on android-arm-official-tests.
-    public void testFeedCardRenderingScenarioWorld() throws Exception {
-        renderFeedCards("world");
-    }
-
-    private void renderFeedCards(String scenarioName) throws Exception {
-        // Open a new tab.
-        SectionHeader firstHeader = mNtp.getCoordinatorForTesting()
-                                            .getMediatorForTesting()
-                                            .getSectionHeaderForTesting();
-        RecyclerView recycleView =
-                (RecyclerView) mNtp.getCoordinatorForTesting().getStreamForTesting().getView();
-
-        // Check header is expanded.
-        Assert.assertTrue(firstHeader.isExpandable() && firstHeader.isExpanded());
-        Assert.assertTrue(getPreferenceForArticleSectionHeader());
-
-        // Trigger a refresh to get feed cards.
-        mFeedDataInjector.triggerFeedRefreshOnUiThreadBlocking(
-                mNtp.getCoordinatorForTesting().getStreamForTesting());
-
-        // Scroll to the first feed card.
-        onView(instanceOf(RecyclerView.class))
-                .perform(RecyclerViewActions.scrollToPosition(
-                        mFeedDataInjector.getFirstCardPosition()));
-
-        RecyclerViewTestUtils.waitForStableRecyclerView(recycleView);
-        mRenderTestRule.render(
-                recycleView, String.format("render_feed_cards_top_%s", scenarioName));
-
-        // Scroll to the bottom.
-        RecyclerViewTestUtils.scrollToBottom(recycleView);
-        RecyclerViewTestUtils.waitForStableRecyclerView(recycleView);
-        mRenderTestRule.render(
-                recycleView, String.format("render_feed_cards_bottom_%s", scenarioName));
-
-        // Scroll to the first feed card again.
-        onView(instanceOf(RecyclerView.class))
-                .perform(RecyclerViewActions.scrollToPosition(
-                        mFeedDataInjector.getFirstCardPosition()));
-        RecyclerViewTestUtils.waitForStableRecyclerView(recycleView);
-        mRenderTestRule.render(
-                recycleView, String.format("render_feed_cards_top_again_%s", scenarioName));
-    }
-
-    private boolean getPreferenceForArticleSectionHeader() throws Exception {
-        return ThreadUtils.runOnUiThreadBlocking(
-                ()
-                        -> UserPrefs.get(Profile.getLastUsedRegularProfile())
-                                   .getBoolean(Pref.ARTICLES_LIST_VISIBLE));
-    }
-}
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedNewTabPageTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedNewTabPageTest.java
deleted file mode 100644
index 9f70ad7..0000000
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedNewTabPageTest.java
+++ /dev/null
@@ -1,497 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.RootMatchers.withDecorView;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static org.hamcrest.Matchers.allOf;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-
-import static org.chromium.chrome.test.util.ViewUtils.VIEW_NULL;
-import static org.chromium.chrome.test.util.ViewUtils.waitForView;
-
-import android.support.test.InstrumentationRegistry;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.espresso.ViewAction;
-import androidx.test.espresso.action.GeneralLocation;
-import androidx.test.espresso.action.GeneralSwipeAction;
-import androidx.test.espresso.action.Press;
-import androidx.test.espresso.action.Swipe;
-import androidx.test.espresso.contrib.RecyclerViewActions;
-import androidx.test.filters.MediumTest;
-
-import org.hamcrest.Matcher;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.RuleChain;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.test.params.ParameterAnnotations;
-import org.chromium.base.test.params.ParameterProvider;
-import org.chromium.base.test.params.ParameterSet;
-import org.chromium.base.test.params.ParameterizedRunner;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.DisabledTest;
-import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.browser.ntp.NewTabPage;
-import org.chromium.chrome.browser.ntp.cards.SignInPromo;
-import org.chromium.chrome.browser.ntp.snippets.SectionHeader;
-import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
-import org.chromium.chrome.browser.preferences.Pref;
-import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.suggestions.SiteSuggestion;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
-import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
-import org.chromium.chrome.test.util.ChromeTabUtils;
-import org.chromium.chrome.test.util.NewTabPageTestUtils;
-import org.chromium.chrome.test.util.ViewUtils;
-import org.chromium.chrome.test.util.browser.Features;
-import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule;
-import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule;
-import org.chromium.chrome.test.util.browser.suggestions.mostvisited.FakeMostVisitedSites;
-import org.chromium.components.browser_ui.widget.RecyclerViewTestUtils;
-import org.chromium.components.embedder_support.util.UrlConstants;
-import org.chromium.components.prefs.PrefService;
-import org.chromium.components.signin.test.util.FakeAccountManagerFacade;
-import org.chromium.components.user_prefs.UserPrefs;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-import org.chromium.net.test.EmbeddedTestServer;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Tests for {@link NewTabPage}. Other tests can be found in
- * {@link org.chromium.chrome.browser.ntp.NewTabPageTest}.
- * TODO(https://crbug.com/1069183): Combine test suites.
- */
-@RunWith(ParameterizedRunner.class)
-@ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
-@CommandLineFlags.
-Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, "disable-features=IPH_FeedHeaderMenu"})
-@Features.EnableFeatures(ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS)
-@Features.DisableFeatures({ChromeFeatureList.REPORT_FEED_USER_ACTIONS,
-        ChromeFeatureList.QUERY_TILES, ChromeFeatureList.ENHANCED_PROTECTION_PROMO_CARD})
-public class FeedNewTabPageTest {
-    private static final int ARTICLE_SECTION_HEADER_POSITION = 1;
-    private static final int SIGNIN_PROMO_POSITION = 2;
-
-    // Espresso ViewAction that performs a swipe from center to left across the vertical center
-    // of the view. Used instead of ViewAction.swipeLeft which swipes from right edge to
-    // avoid conflict with gesture navigation UI which consumes the edge swipe.
-    private static final ViewAction SWIPE_LEFT = new GeneralSwipeAction(
-            Swipe.FAST, GeneralLocation.CENTER, GeneralLocation.CENTER_LEFT, Press.FINGER);
-
-    private boolean mIsCachePopulatedInAccountManagerFacade = true;
-
-    @Rule
-    public final SuggestionsDependenciesRule mSuggestionsDeps = new SuggestionsDependenciesRule();
-
-    private final ChromeTabbedActivityTestRule mActivityTestRule =
-            new ChromeTabbedActivityTestRule();
-
-    private final AccountManagerTestRule mAccountManagerTestRule =
-            new AccountManagerTestRule(new FakeAccountManagerFacade(null) {
-                @Override
-                public boolean isCachePopulated() {
-                    // Attention. When isCachePopulated() returns false,
-                    // runAfterCacheIsPopulated(...) shouldn't run. If this becomes a problem,
-                    // we can override runAfterCacheIsPopulated(...) as well.
-                    return mIsCachePopulatedInAccountManagerFacade;
-                }
-            });
-
-    // Mock sign-in environment needs to be destroyed after ChromeActivity in case there are
-    // observers registered in the AccountManagerFacade mock.
-    @Rule
-    public final RuleChain mRuleChain =
-            RuleChain.outerRule(mAccountManagerTestRule).around(mActivityTestRule);
-
-    /** Parameter provider for enabling/disabling the signin promo card. */
-    public static class SigninPromoParams implements ParameterProvider {
-        @Override
-        public Iterable<ParameterSet> getParameters() {
-            return Collections.singletonList(
-                    new ParameterSet().value(true).name("DisableSigninPromo"));
-        }
-    }
-
-    private Tab mTab;
-    private NewTabPage mNtp;
-    private ViewGroup mTileGridLayout;
-    private FakeMostVisitedSites mMostVisitedSites;
-    private EmbeddedTestServer mTestServer;
-    private List<SiteSuggestion> mSiteSuggestions;
-    private boolean mDisableSigninPromoCard;
-
-    @ParameterAnnotations.UseMethodParameterBefore(SigninPromoParams.class)
-    public void disableSigninPromoCard(boolean disableSigninPromoCard) {
-        mDisableSigninPromoCard = disableSigninPromoCard;
-    }
-
-    @Before
-    public void setUp() {
-        SignInPromo.setDisablePromoForTests(mDisableSigninPromoCard);
-        mActivityTestRule.startMainActivityWithURL("about:blank");
-
-        mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
-        mSiteSuggestions = NewTabPageTestUtils.createFakeSiteSuggestions(mTestServer);
-        mMostVisitedSites = new FakeMostVisitedSites();
-        mMostVisitedSites.setTileSuggestions(mSiteSuggestions);
-        mSuggestionsDeps.getFactory().mostVisitedSites = mMostVisitedSites;
-    }
-
-    @After
-    public void tearDown() {
-        mTestServer.stopAndDestroyServer();
-        FeedProcessScopeFactory.setTestNetworkClient(null);
-    }
-
-    private void openNewTabPage() {
-        mActivityTestRule.loadUrl(UrlConstants.NTP_URL);
-        mTab = mActivityTestRule.getActivity().getActivityTab();
-        NewTabPageTestUtils.waitForNtpLoaded(mTab);
-
-        Assert.assertTrue(mTab.getNativePage() instanceof NewTabPage);
-        mNtp = (NewTabPage) mTab.getNativePage();
-        mTileGridLayout = mNtp.getView().findViewById(R.id.tile_grid_layout);
-        Assert.assertEquals(mSiteSuggestions.size(), mTileGridLayout.getChildCount());
-    }
-
-    private void waitForPopup(Matcher<View> matcher) {
-        View mainDecorView = mActivityTestRule.getActivity().getWindow().getDecorView();
-        onView(isRoot())
-                .inRoot(withDecorView(not(is(mainDecorView))))
-                .check(waitForView(matcher, ViewUtils.VIEW_VISIBLE));
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"FeedNewTabPage"})
-    @Features.DisableFeatures(ChromeFeatureList.INTEREST_FEED_V2)
-    @DisabledTest(message = "Flaky -- crbug.com/1136923")
-    public void testSignInPromo() {
-        openNewTabPage();
-        SignInPromo.SigninObserver signinObserver = mNtp.getCoordinatorForTesting()
-                                                            .getMediatorForTesting()
-                                                            .getSignInPromoForTesting()
-                                                            .getSigninObserverForTesting();
-        RecyclerView recyclerView =
-                (RecyclerView) mNtp.getCoordinatorForTesting().getStreamForTesting().getView();
-
-        // Prioritize RecyclerView's focusability so that the sign-in promo button and the action
-        // button don't get focused initially to avoid flakiness.
-        int descendantFocusability = recyclerView.getDescendantFocusability();
-        TestThreadUtils.runOnUiThreadBlocking((() -> {
-            recyclerView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
-            recyclerView.requestFocus();
-        }));
-
-        // Simulate sign in, scroll to the position where sign-in promo could be placed, and verify
-        // that sign-in promo is not shown.
-        TestThreadUtils.runOnUiThreadBlocking(signinObserver::onSignedIn);
-        RecyclerViewTestUtils.waitForStableRecyclerView(recyclerView);
-        onView(instanceOf(RecyclerView.class))
-                .perform(RecyclerViewActions.scrollToPosition(SIGNIN_PROMO_POSITION));
-        onView(withId(R.id.signin_promo_view_container)).check(doesNotExist());
-
-        // Simulate sign out, scroll to the position where sign-in promo could be placed, and verify
-        // that sign-in promo is shown.
-        TestThreadUtils.runOnUiThreadBlocking(signinObserver::onSignedOut);
-        RecyclerViewTestUtils.waitForStableRecyclerView(recyclerView);
-        onView(instanceOf(RecyclerView.class))
-                .perform(RecyclerViewActions.scrollToPosition(SIGNIN_PROMO_POSITION));
-        onView(withId(R.id.signin_promo_view_container)).check(matches(isDisplayed()));
-
-        // Hide articles and verify that the sign-in promo is not shown.
-        toggleHeader(recyclerView, false);
-        onView(withId(R.id.signin_promo_view_container)).check(doesNotExist());
-
-        // Show articles and verify that the sign-in promo is shown.
-        toggleHeader(recyclerView, true);
-        onView(withId(R.id.signin_promo_view_container)).check(matches(isDisplayed()));
-
-        // Reset states.
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            mNtp.getCoordinatorForTesting().getMediatorForTesting().destroyForTesting();
-            recyclerView.setDescendantFocusability(descendantFocusability);
-        });
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"FeedNewTabPage"})
-    @DisabledTest(message = "https://crbug.com/1046822")
-    public void testSignInPromo_DismissBySwipe() {
-        openNewTabPage();
-        boolean dismissed = SharedPreferencesManager.getInstance().readBoolean(
-                ChromePreferenceKeys.SIGNIN_PROMO_NTP_PROMO_DISMISSED, false);
-        if (dismissed) {
-            SharedPreferencesManager.getInstance().writeBoolean(
-                    ChromePreferenceKeys.SIGNIN_PROMO_NTP_PROMO_DISMISSED, false);
-        }
-
-        // Verify that sign-in promo is displayed initially.
-        onView(instanceOf(RecyclerView.class))
-                .perform(RecyclerViewActions.scrollToPosition(SIGNIN_PROMO_POSITION));
-        onView(withId(R.id.signin_promo_view_container)).check(matches(isDisplayed()));
-
-        // Swipe away the sign-in promo.
-        onView(instanceOf(RecyclerView.class))
-                .perform(RecyclerViewActions.actionOnItemAtPosition(
-                        SIGNIN_PROMO_POSITION, SWIPE_LEFT));
-
-        ViewGroup view =
-                (ViewGroup) mNtp.getCoordinatorForTesting().getStreamForTesting().getView();
-        waitForView(view, withId(R.id.signin_promo_view_container), VIEW_NULL);
-        waitForView(view, allOf(withId(R.id.header_title), isDisplayed()));
-
-        // Verify that sign-in promo is gone, but new tab page layout and header are displayed.
-        onView(withId(R.id.signin_promo_view_container)).check(doesNotExist());
-        onView(withId(R.id.header_title)).check(matches(isDisplayed()));
-        onView(withId(R.id.ntp_content)).check(matches(isDisplayed()));
-
-        // Reset state.
-        SharedPreferencesManager.getInstance().writeBoolean(
-                ChromePreferenceKeys.SIGNIN_PROMO_NTP_PROMO_DISMISSED, dismissed);
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"FeedNewTabPage"})
-    public void testSignInPromo_AccountsNotReady() {
-        mIsCachePopulatedInAccountManagerFacade = false;
-        openNewTabPage();
-        // Check that the sign-in promo is not shown if accounts are not ready.
-        onView(instanceOf(RecyclerView.class))
-                .perform(RecyclerViewActions.scrollToPosition(SIGNIN_PROMO_POSITION));
-        onView(withId(R.id.signin_promo_view_container)).check(doesNotExist());
-
-        mIsCachePopulatedInAccountManagerFacade = true;
-        TestThreadUtils.runOnUiThreadBlocking(mTab::reload);
-        ChromeTabUtils.waitForTabPageLoaded(mTab, ChromeTabUtils.getUrlStringOnUiThread(mTab));
-
-        // Check that the sign-in promo is displayed this time.
-        onView(instanceOf(RecyclerView.class))
-                .perform(RecyclerViewActions.scrollToPosition(SIGNIN_PROMO_POSITION));
-        onView(withId(R.id.signin_promo_view_container)).check(matches(isDisplayed()));
-    }
-
-    @Test
-    @MediumTest
-    @Features.EnableFeatures(ChromeFeatureList.REPORT_FEED_USER_ACTIONS)
-    @Features.DisableFeatures(ChromeFeatureList.INTEREST_FEED_V2)
-    @Feature({"NewTabPage", "FeedNewTabPage"})
-    @ParameterAnnotations.UseMethodParameter(SigninPromoParams.class)
-    public void testArticleSectionHeaderWithMenu(boolean disableSigninPromoCard) throws Exception {
-        openNewTabPage();
-        // Scroll to the article section header in case it is not visible.
-        onView(instanceOf(RecyclerView.class))
-                .perform(RecyclerViewActions.scrollToPosition(ARTICLE_SECTION_HEADER_POSITION));
-        waitForView((ViewGroup) mNtp.getView(), allOf(withId(R.id.header_title), isDisplayed()));
-
-        View sectionHeaderView = mNtp.getCoordinatorForTesting().getSectionHeaderViewForTesting();
-        TextView headerStatusView = sectionHeaderView.findViewById(R.id.header_title);
-
-        // Assert that the feed is expanded and that the header title text is correct.
-        Assert.assertTrue(mNtp.getCoordinatorForTesting()
-                                  .getMediatorForTesting()
-                                  .getSectionHeaderForTesting()
-                                  .isExpanded());
-        Assert.assertEquals(sectionHeaderView.getContext().getString(R.string.ntp_discover_on),
-                headerStatusView.getText());
-
-        // Toggle header on the current tab.
-        onView(withId(R.id.header_menu)).perform(click());
-        View mainDecorView = mActivityTestRule.getActivity().getWindow().getDecorView();
-        waitForPopup(withText(R.string.ntp_turn_off_feed));
-        onView(withText(R.string.ntp_turn_off_feed))
-                .inRoot(withDecorView(not(is(mainDecorView))))
-                .perform(click());
-
-        // Assert that the feed is collapsed and that the header title text is correct.
-        Assert.assertFalse(mNtp.getCoordinatorForTesting()
-                                   .getMediatorForTesting()
-                                   .getSectionHeaderForTesting()
-                                   .isExpanded());
-        Assert.assertEquals(sectionHeaderView.getContext().getString(R.string.ntp_discover_off),
-                headerStatusView.getText());
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"FeedNewTabPage"})
-    @DisabledTest(message = "https://crbug.com/914068")
-    public void testArticleSectionHeader() throws Exception {
-        openNewTabPage();
-        final int expectedCountWhenCollapsed = 2;
-        final int expectedCountWhenExpanded = 4; // 3 header views and the empty view.
-
-        // Open a new tab.
-        Tab tab1 = mActivityTestRule.loadUrlInNewTab(UrlConstants.NTP_URL);
-        NewTabPage ntp1 = (NewTabPage) tab1.getNativePage();
-        SectionHeader firstHeader = ntp1.getCoordinatorForTesting()
-                                            .getMediatorForTesting()
-                                            .getSectionHeaderForTesting();
-        RecyclerView.Adapter adapter1 =
-                ((RecyclerView) ntp1.getCoordinatorForTesting().getStreamForTesting().getView())
-                        .getAdapter();
-
-        // Check header is expanded.
-        Assert.assertTrue(firstHeader.isExpandable() && firstHeader.isExpanded());
-        Assert.assertEquals(expectedCountWhenExpanded, adapter1.getItemCount());
-        Assert.assertTrue(getPreferenceForArticleSectionHeader());
-
-        // Toggle header on the current tab.
-        toggleHeader(
-                (ViewGroup) ntp1.getCoordinatorForTesting().getStreamForTesting().getView(), false);
-
-        // Check header is collapsed.
-        Assert.assertTrue(firstHeader.isExpandable() && !firstHeader.isExpanded());
-        Assert.assertEquals(expectedCountWhenCollapsed, adapter1.getItemCount());
-        Assert.assertFalse(getPreferenceForArticleSectionHeader());
-
-        // Open a second new tab.
-        Tab tab2 = mActivityTestRule.loadUrlInNewTab(UrlConstants.NTP_URL);
-        NewTabPage ntp2 = (NewTabPage) tab2.getNativePage();
-        SectionHeader secondHeader = ntp2.getCoordinatorForTesting()
-                                             .getMediatorForTesting()
-                                             .getSectionHeaderForTesting();
-        RecyclerView.Adapter adapter2 =
-                ((RecyclerView) ntp2.getCoordinatorForTesting().getStreamForTesting().getView())
-                        .getAdapter();
-
-        // Check header on the second tab is collapsed.
-        Assert.assertTrue(secondHeader.isExpandable() && !secondHeader.isExpanded());
-        Assert.assertEquals(expectedCountWhenCollapsed, adapter2.getItemCount());
-        Assert.assertFalse(getPreferenceForArticleSectionHeader());
-
-        // Toggle header on the second tab.
-        toggleHeader(
-                (ViewGroup) ntp2.getCoordinatorForTesting().getStreamForTesting().getView(), true);
-
-        // Check header on the second tab is expanded.
-        Assert.assertTrue(secondHeader.isExpandable() && secondHeader.isExpanded());
-        Assert.assertEquals(expectedCountWhenExpanded, adapter2.getItemCount());
-        Assert.assertTrue(getPreferenceForArticleSectionHeader());
-
-        // Go back to the first tab and wait for a stable recycler view.
-        ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), tab1.getId());
-
-        // Check header on the first tab is expanded.
-        Assert.assertTrue(firstHeader.isExpandable() && firstHeader.isExpanded());
-        Assert.assertEquals(expectedCountWhenExpanded, adapter1.getItemCount());
-        Assert.assertTrue(getPreferenceForArticleSectionHeader());
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"FeedNewTabPage"})
-    @DisabledTest(message = "crbug.com/1064388")
-    public void testFeedDisabledByPolicy() throws Exception {
-        openNewTabPage();
-        final boolean pref = TestThreadUtils.runOnUiThreadBlocking(
-                () -> getPrefService().getBoolean(Pref.ENABLE_SNIPPETS));
-
-        // Policy is disabled. Verify the NTP root view contains only the Stream view as child.
-        ViewGroup rootView = (ViewGroup) mNtp.getView();
-        ViewUtils.waitForStableView(rootView);
-        Assert.assertNotNull(mNtp.getCoordinatorForTesting().getStreamForTesting());
-        Assert.assertNull(mNtp.getCoordinatorForTesting().getScrollViewForPolicy());
-        Assert.assertEquals(1, rootView.getChildCount());
-        Assert.assertEquals(mNtp.getCoordinatorForTesting().getStreamForTesting().getView(),
-                rootView.getChildAt(0));
-
-        // Simulate that policy is enabled. Verify the NTP root view contains only the view for
-        // policy as child.
-        TestThreadUtils.runOnUiThreadBlocking(
-                () -> getPrefService().setBoolean(Pref.ENABLE_SNIPPETS, false));
-        Assert.assertNotNull(mNtp.getCoordinatorForTesting().getScrollViewForPolicy());
-        Assert.assertNull(mNtp.getCoordinatorForTesting().getStreamForTesting());
-        Assert.assertEquals(1, rootView.getChildCount());
-        Assert.assertEquals(
-                mNtp.getCoordinatorForTesting().getScrollViewForPolicy(), rootView.getChildAt(0));
-
-        // Open a new tab while policy is still enabled.
-        Tab tab2 = mActivityTestRule.loadUrlInNewTab(UrlConstants.NTP_URL);
-        NewTabPage ntp2 = (NewTabPage) tab2.getNativePage();
-        ViewGroup rootView2 = (ViewGroup) ntp2.getView();
-
-        // Verify that NTP root view contains only the view for policy as child.
-        Assert.assertNotNull(ntp2.getCoordinatorForTesting().getScrollViewForPolicy());
-        Assert.assertNull(ntp2.getCoordinatorForTesting().getStream());
-        Assert.assertEquals(1, rootView2.getChildCount());
-        Assert.assertEquals(
-                ntp2.getCoordinatorForTesting().getScrollViewForPolicy(), rootView2.getChildAt(0));
-
-        // Simulate that policy is disabled. Verify the NTP root view is the view for policy. We
-        // don't re-enable the Feed until the next restart.
-        TestThreadUtils.runOnUiThreadBlocking(
-                () -> getPrefService().setBoolean(Pref.ENABLE_SNIPPETS, true));
-        Assert.assertNotNull(ntp2.getCoordinatorForTesting().getScrollViewForPolicy());
-        Assert.assertNull(ntp2.getCoordinatorForTesting().getStream());
-        Assert.assertEquals(1, rootView2.getChildCount());
-        Assert.assertEquals(
-                ntp2.getCoordinatorForTesting().getScrollViewForPolicy(), rootView2.getChildAt(0));
-
-        // Switch to the old tab. Verify the NTP root view is the view for policy.
-        ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), mTab.getId());
-        Assert.assertNotNull(mNtp.getCoordinatorForTesting().getScrollViewForPolicy());
-        Assert.assertNull(mNtp.getCoordinatorForTesting().getStream());
-        Assert.assertEquals(1, rootView.getChildCount());
-        Assert.assertEquals(
-                mNtp.getCoordinatorForTesting().getScrollViewForPolicy(), rootView.getChildAt(0));
-
-        // Reset state.
-        TestThreadUtils.runOnUiThreadBlocking(
-                () -> getPrefService().setBoolean(Pref.ENABLE_SNIPPETS, pref));
-    }
-
-    /**
-     * Toggles the header and checks whether the header has the right status.
-     * @param rootView The {@link ViewGroup} that contains the header view.
-     * @param expanded Whether the header should be expanded.
-     */
-    private void toggleHeader(ViewGroup rootView, boolean expanded) {
-        onView(instanceOf(RecyclerView.class))
-                .perform(RecyclerViewActions.scrollToPosition(ARTICLE_SECTION_HEADER_POSITION),
-                        RecyclerViewActions.actionOnItemAtPosition(
-                                ARTICLE_SECTION_HEADER_POSITION, click()));
-        waitForView(rootView,
-                allOf(withId(R.id.header_status),
-                        withText(expanded ? R.string.hide_content : R.string.show_content)));
-    }
-
-    private boolean getPreferenceForArticleSectionHeader() throws Exception {
-        return TestThreadUtils.runOnUiThreadBlocking(
-                () -> getPrefService().getBoolean(Pref.ARTICLES_LIST_VISIBLE));
-    }
-
-    private PrefService getPrefService() {
-        return UserPrefs.get(Profile.getLastUsedRegularProfile());
-    }
-}
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedRefreshTaskTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedRefreshTaskTest.java
deleted file mode 100644
index 3550c9a..0000000
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedRefreshTaskTest.java
+++ /dev/null
@@ -1,136 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import android.content.Context;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
-import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
-import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler;
-import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory;
-import org.chromium.components.background_task_scheduler.TaskIds;
-import org.chromium.components.background_task_scheduler.TaskInfo;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Unit tests for {@link FeedSchedulerBridge}.
- */
-// TODO(https://crbug.com/894334): Remove format suppression once formatting bug is fixed.
-// clang-format off
-@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE)
-@EnableFeatures(ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS)
-@DisableFeatures({ChromeFeatureList.INTEREST_FEED_V2})
-public class FeedRefreshTaskTest {
-    // clang-format on
-
-    @Rule
-    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
-
-    private static class TestBackgroundTaskScheduler implements BackgroundTaskScheduler {
-        private List<TaskInfo> mTaskInfoList = new ArrayList<>();
-        private List<Integer> mCanceledTaskIds = new ArrayList<>();
-
-        public List<TaskInfo> getTaskInfoList() {
-            return mTaskInfoList;
-        }
-
-        public List<Integer> getCanceledTaskIds() {
-            return mCanceledTaskIds;
-        }
-
-        @Override
-        public boolean schedule(Context context, TaskInfo taskInfo) {
-            mTaskInfoList.add(taskInfo);
-            return true;
-        }
-
-        @Override
-        public void cancel(Context context, int taskId) {
-            mCanceledTaskIds.add(taskId);
-        }
-
-        @Override
-        public void checkForOSUpgrade(Context context) {}
-
-        @Override
-        public void reschedule(Context context) {}
-    }
-
-    private TestBackgroundTaskScheduler mTaskScheduler;
-
-    @Before
-    public void setUp() throws InterruptedException {
-        mTaskScheduler = new TestBackgroundTaskScheduler();
-        BackgroundTaskSchedulerFactory.setSchedulerForTesting(mTaskScheduler);
-
-        // The FeedSchedulerHost might create a task during initialization. Clear out any tasks
-        // created before the test case starts.
-        mActivityTestRule.startMainActivityOnBlankPage();
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            // Accessing the bridge will create if needed, and may run initialization logic.
-            FeedProcessScopeFactory.getFeedScheduler();
-            mTaskScheduler.getTaskInfoList().clear();
-        });
-    }
-
-    @Test
-    @SmallTest
-    public void testSchedule() {
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            Assert.assertEquals(0, mTaskScheduler.getTaskInfoList().size());
-            FeedRefreshTask.scheduleWakeUp(/*thresholdMs=*/1234);
-            Assert.assertEquals(1, mTaskScheduler.getTaskInfoList().size());
-            TaskInfo actualInfo = mTaskScheduler.getTaskInfoList().get(0);
-            Assert.assertEquals(TaskIds.FEED_REFRESH_JOB_ID, actualInfo.getTaskId());
-            Assert.assertEquals(TaskInfo.NetworkType.ANY, actualInfo.getRequiredNetworkType());
-            Assert.assertEquals(false, actualInfo.requiresCharging());
-            Assert.assertEquals(true, actualInfo.isPeriodic());
-            Assert.assertEquals(true, actualInfo.isPersisted());
-            Assert.assertEquals(true, actualInfo.shouldUpdateCurrent());
-            // 1234 * 1.1 = 1357
-            Assert.assertEquals(1357, actualInfo.getPeriodicInfo().getIntervalMs());
-            // 1234 * 0.2 = 246
-            Assert.assertEquals(246, actualInfo.getPeriodicInfo().getFlexMs());
-        });
-    }
-
-    @Test
-    @SmallTest
-    public void testCancelWakeUp() {
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            int initialCanceledTasks = mTaskScheduler.getCanceledTaskIds().size();
-            FeedRefreshTask.cancelWakeUp();
-            Assert.assertEquals(
-                    initialCanceledTasks + 1, mTaskScheduler.getCanceledTaskIds().size());
-        });
-    }
-
-    @Test
-    @SmallTest
-    public void testReschedule() {
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            Assert.assertEquals(0, mTaskScheduler.getTaskInfoList().size());
-            new FeedRefreshTask().reschedule(mActivityTestRule.getActivity());
-            Assert.assertEquals(1, mTaskScheduler.getTaskInfoList().size());
-        });
-    }
-}
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedSchedulerBridgeConformanceTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedSchedulerBridgeConformanceTest.java
deleted file mode 100644
index de36ee7..0000000
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedSchedulerBridgeConformanceTest.java
+++ /dev/null
@@ -1,75 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-
-import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
-import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
-import org.chromium.base.test.params.ParameterSet;
-import org.chromium.base.test.params.ParameterizedRunner;
-import org.chromium.chrome.browser.feed.library.api.client.requestmanager.RequestManager;
-import org.chromium.chrome.browser.feed.library.testing.conformance.scheduler.SchedulerConformanceTest;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.test.ChromeBrowserTestRule;
-import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Conformance Tests for {@link FeedSchedulerBridge}.
- * The actual tests are implemented in SchedulerConformanceTest.
- */
-
-// The @SmallTest class annotation is needed to allow the inherited @Test methods to run using
-// build/android/test_runner.py.
-@SmallTest
-@RunWith(ParameterizedRunner.class)
-@UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
-@DisableFeatures({ChromeFeatureList.INTEREST_FEED_V2})
-public final class FeedSchedulerBridgeConformanceTest extends SchedulerConformanceTest {
-    @ClassParameter
-    private static List<ParameterSet> sClassParams =
-            Arrays.asList(new ParameterSet().value(false).name("withoutRequestManager"),
-                    new ParameterSet().value(true).name("withRequestManager"));
-
-    @Rule
-    public final ChromeBrowserTestRule mChromeBrowserTestRule = new ChromeBrowserTestRule();
-
-    @Mock
-    private RequestManager mRequestManager;
-    private boolean mUseRequestManager;
-
-    public FeedSchedulerBridgeConformanceTest(boolean useRequestManager) {
-        mUseRequestManager = useRequestManager;
-    }
-
-    @Before
-    public void setUp() {
-        // The scheduler is declared and tested in SchedulerConformanceTest.
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            mScheduler = new FeedSchedulerBridge(Profile.getLastUsedRegularProfile());
-            if (mUseRequestManager) {
-                ((FeedSchedulerBridge) mScheduler).initializeFeedDependencies(mRequestManager);
-            }
-        });
-    }
-
-    @After
-    public void tearDown() {
-        TestThreadUtils.runOnUiThreadBlocking(() -> ((FeedSchedulerBridge) mScheduler).destroy());
-        mScheduler = null;
-    }
-}
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/tooltip/FeedTooltipTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/tooltip/FeedTooltipTest.java
deleted file mode 100644
index 1711f85..0000000
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/tooltip/FeedTooltipTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1.tooltip;
-
-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.withText;
-
-import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-
-import static org.chromium.chrome.browser.feed.library.basicstream.internal.viewholders.ViewHolderType.TYPE_CARD;
-
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.espresso.contrib.RecyclerViewActions;
-import androidx.test.espresso.matcher.RootMatchers;
-import androidx.test.filters.MediumTest;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.test.util.CallbackHelper;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.browser.feed.v1.DataFilePath;
-import org.chromium.chrome.browser.feed.v1.FeedDataInjectRule;
-import org.chromium.chrome.browser.feed.shared.stream.Stream;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.browser.ntp.NewTabPage;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
-import org.chromium.chrome.test.util.NewTabPageTestUtils;
-import org.chromium.chrome.test.util.browser.Features;
-import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule;
-import org.chromium.components.embedder_support.util.UrlConstants;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-
-/**
- * Tests for tooltips (i.e. in-product help) shown on the {@link Stream}.
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
-        "enable-features=IPH_DemoMode<Trial", "force-fieldtrials=Trial/Group",
-        "force-fieldtrial-params=Trial.Group:chosen_feature/IPH_FeedCardMenu"})
-@Features.EnableFeatures(ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS)
-@Features.DisableFeatures(ChromeFeatureList.INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS)
-public class FeedTooltipTest {
-    private static final String FEED_TEST_RESPONSE_FILE_PATH =
-            "/chrome/test/data/android/feed/feed_tooltip.gcl.bin";
-
-    // Defined in feed_tooltip.gcl.textpb.
-    private static final String TOOLTIP_TEXT = "oh look a pretty tooltip";
-
-    private static final int FIRST_CARD_POSITION = 3;
-
-    @Rule
-    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
-
-    @Rule
-    public FeedDataInjectRule mFeedDataInjector = new FeedDataInjectRule(false);
-
-    @Rule
-    public SuggestionsDependenciesRule mSuggestionsDeps = new SuggestionsDependenciesRule();
-
-    private class TestObserver implements Stream.ContentChangedListener {
-        public final CallbackHelper firstCardShownCallback = new CallbackHelper();
-
-        @Override
-        public void onContentChanged() {
-            if (mRecyclerViewAdapter.getItemViewType(FIRST_CARD_POSITION) == TYPE_CARD) {
-                firstCardShownCallback.notifyCalled();
-            }
-        }
-    }
-
-    private final TestObserver mTestObserver = new TestObserver();
-
-    private Stream mStream;
-    private RecyclerView.Adapter mRecyclerViewAdapter;
-
-    @Before
-    public void setUp() {
-        mActivityTestRule.startMainActivityWithURL("about:blank");
-        mActivityTestRule.loadUrl(UrlConstants.NTP_URL);
-        final Tab tab = mActivityTestRule.getActivity().getActivityTab();
-        NewTabPageTestUtils.waitForNtpLoaded(tab);
-
-        Assert.assertTrue(
-                "The current tab is not a NewTabPage.", tab.getNativePage() instanceof NewTabPage);
-        final NewTabPage ntp = (NewTabPage) tab.getNativePage();
-        mStream = ntp.getCoordinatorForTesting().getStreamForTesting();
-
-        Assert.assertTrue("The Stream view should be a RecyclerView.",
-                mStream.getView() instanceof RecyclerView);
-        mRecyclerViewAdapter = ((RecyclerView) mStream.getView()).getAdapter();
-
-        mStream.addOnContentChangedListener(mTestObserver);
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"FeedNewTabPage"})
-    @DataFilePath(FEED_TEST_RESPONSE_FILE_PATH)
-    public void testShowTooltip() throws Exception {
-        int callCount = mTestObserver.firstCardShownCallback.getCallCount();
-        TestThreadUtils.runOnUiThreadBlocking(() -> mStream.triggerRefresh());
-        mTestObserver.firstCardShownCallback.waitForCallback(callCount);
-
-        onView(instanceOf(RecyclerView.class))
-                .perform(RecyclerViewActions.scrollToPosition(FIRST_CARD_POSITION),
-                        RecyclerViewActions.actionOnItemAtPosition(FIRST_CARD_POSITION, click()));
-        onView(withText(TOOLTIP_TEXT))
-                .inRoot(RootMatchers.withDecorView(
-                        not(is(mActivityTestRule.getActivity().getWindow().getDecorView()))))
-                .check(matches(isDisplayed()));
-    }
-}
diff --git a/chrome/android/feed/dummy/java/src/org/chromium/chrome/browser/feed/FeedV1.java b/chrome/android/feed/dummy/java/src/org/chromium/chrome/browser/feed/FeedV1.java
deleted file mode 100644
index b284cfe..0000000
--- a/chrome/android/feed/dummy/java/src/org/chromium/chrome/browser/feed/FeedV1.java
+++ /dev/null
@@ -1,26 +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.
-
-package org.chromium.chrome.browser.feed;
-
-import org.chromium.components.background_task_scheduler.BackgroundTask;
-
-/**
- * A stub of FeedV1.
- */
-public class FeedV1 {
-    // Whether FeedV1 is compiled in.
-    public static final boolean IS_AVAILABLE = false;
-
-    public static void startup() {}
-
-    public static FeedSurfaceCoordinator.StreamWrapper createStreamWrapper() {
-        return null;
-    }
-
-    public static BackgroundTask createRefreshTask() {
-        return null;
-    }
-    public static void destroy() {}
-}
diff --git a/chrome/android/feed/feed_java_sources.gni b/chrome/android/feed/feed_java_sources.gni
index 3a9248e..8c2fce2 100644
--- a/chrome/android/feed/feed_java_sources.gni
+++ b/chrome/android/feed/feed_java_sources.gni
@@ -19,13 +19,6 @@
   "//third_party/android_deps:protobuf_lite_runtime_java",
 ]
 
-if (enable_feed_v1) {
-  feed_deps += [
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library:piet_resources",
-    "//components/feed/core/proto:proto_java",
-  ]
-}
-
 feed_java_sources = [
   "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java",
   "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java",
@@ -35,7 +28,6 @@
   "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/HeaderIphScrollListener.java",
   "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManager.java",
   "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/StreamLifecycleManager.java",
-  "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/locale/LocaleUtils.java",
   "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/FeedFeatures.java",
   "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/FeedSurfaceDelegate.java",
   "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/shared/FeedSurfaceProvider.java",
@@ -63,367 +55,7 @@
   feed_java_sources += [ "//chrome/android/feed/dummy/java/src/org/chromium/chrome/browser/feed/FeedV2BuildFlag.java" ]
 }
 
-if (enable_feed_v1) {
-  feed_java_sources += [
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedV1.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/knowncontent/ContentMetadata.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/knowncontent/ContentRemoval.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/knowncontent/KnownContent.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/lifecycle/AppLifecycleListener.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/requestmanager/RequestManager.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/ProcessScope.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/ProcessScopeBuilder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/StreamScope.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/client/scope/StreamScopeBuilder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/common/MutationContext.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/ActionApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/ActionEnabledApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/ActionPeformerApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/action/StreamActionApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/config/ApplicationInfo.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/config/Configuration.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/config/DebugBehavior.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/imageloader/BundledAssets.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/imageloader/ImageLoaderApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ActionType.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/BasicLoggingApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ContentLoggingData.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ElementLoggingData.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/InternalFeedError.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/LoggingApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/RequestReason.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ScrollType.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/SessionEvent.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/SpinnerType.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/Task.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/logging/ZeroStateShowReason.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/HttpHeader.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/HttpRequest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/HttpResponse.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/network/NetworkClient.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/offlineindicator/OfflineIndicatorApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/proto/ProtoExtensionProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/scheduler/SchedulerApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/CommitResult.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentOperation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentOperationListSimplifier.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentStorage.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/ContentStorageDirect.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalOperation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalStorage.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/storage/JournalStorageDirect.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/CardConfiguration.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/SnackbarApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/SnackbarCallbackApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/StreamConfiguration.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipCallbackApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipInfo.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/host/stream/TooltipSupportedApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionmanager/ActionManager.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionmanager/ActionReader.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionmanager/ViewActionManager.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionParser.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionParserFactory.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionSource.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/actionparser/ActionSourceConverter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/DismissActionWithSemanticProperties.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/Model.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/PayloadWithId.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/SemanticPropertiesWithId.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/ThreadUtils.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/knowncontent/FeedKnownContent.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/lifecycle/Resettable.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/FeatureChange.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/FeatureChangeObserver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelChild.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelCursor.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelError.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelFeature.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelProviderFactory.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelProviderObserver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/ModelToken.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/RemoveTracking.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/TokenCompleted.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/TokenCompletedObserver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/protocoladapter/ProtocolAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/protocoladapter/RequiredContentAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/requestmanager/ActionUploadRequestManager.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/requestmanager/FeedRequestManager.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/scope/ClearAllListener.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/scope/FeedProcessScope.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/scope/FeedStreamScope.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/sessionmanager/FeedSessionManager.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/ContentMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/LocalActionMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/SemanticPropertiesMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/SessionMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/Store.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/StoreListener.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/store/UploadableActionMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/stream/BasicStreamFactory.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/stream/StreamFactory.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/BasicStream.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamItemAnimator.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamItemTouchCallbacks.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamRecyclerViewAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/actions/StreamActionApiImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/actions/ViewElementActionHandler.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/CardDriver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ClusterDriver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ContentDriver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ContinuationDriver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/FeatureDriver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/HeaderDriver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/LeafFeatureDriver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/NoContentDriver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/StreamDriver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ZeroStateDriver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/pendingdismiss/ClusterPendingDismissHelper.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/pendingdismiss/PendingDismissHandler.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/BasicStreamScrollMonitor.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/BasicStreamScrollTracker.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/ScrollRestorer.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/ContinuationViewHolder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/FeedViewHolder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/HeaderViewHolder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/NoContentViewHolder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/PietViewHolder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/SwipeNotifier.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/SwipeableViewHolder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/ViewHolderType.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/ZeroStateViewHolder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewloggingupdater/ResettableOneShotVisibilityLoggingListener.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewloggingupdater/ViewLoggingUpdater.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/Result.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/Validators.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/CancelableRunnableTask.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/CancelableTask.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/DirectHostSupported.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/MainThreadCaller.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/MainThreadRunner.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/SimpleSettableFuture.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/TaskQueue.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/FeedObservable.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/ImmediatelyNotifyingObservableNotifier.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/Observable.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/feedobservable/ObservableNotifier.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/functional/Committer.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/functional/Predicate.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/functional/Suppliers.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/HashPoolInterner.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/InternedMap.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/Interner.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/InternerWithStats.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/PoolInternerBase.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/ProtoStringInternerBase.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/intern/WeakPoolInterner.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/Dumpable.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/Dumper.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/Logger.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/logging/StringFormattingUtils.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/protoextensions/FeedExtensionRegistry.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/Clock.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/SystemClockImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/TimingUtils.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/ui/LayoutUtils.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionmanager/FeedActionManagerImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParser.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParserFactory.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/ActionTypesConverter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/PietFeedActionPayloadRetriever.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionparser/internal/TooltipInfoImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedactionreader/FeedActionReader.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedapplifecyclelistener/FeedAppLifecycleListener.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedapplifecyclelistener/FeedLifecycleListener.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedknowncontent/FeedKnownContentImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/FeedModelProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/FeedModelProviderFactory.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/CursorProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/FeatureChangeImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelChildBinder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelCursorImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelMutationImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/UpdatableModelChild.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/UpdatableModelFeature.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/UpdatableModelToken.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/FeedProtocolAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/internal/transformers/ContentDataOperationTransformer.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/internal/transformers/DataOperationTransformer.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/internal/transformers/FeatureDataOperationTransformer.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedActionUploadRequestManager.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedRequestManagerImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/RequestHelper.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/RequestManagerImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/UploadableActionsRequestBuilder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/internal/Utils.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/FeedSessionManagerFactory.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/FeedSessionManagerImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/ContentCache.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/HeadAsStructure.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/HeadSessionImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/InitializableSession.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/Session.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionCache.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionContentTracker.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionFactory.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionManagerMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/TimeoutSessionImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/ContentStorageDirectImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/FeedStore.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/JournalStorageDirectImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/ClearableStore.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/ContentGc.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/EphemeralFeedStore.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedContentMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedLocalActionMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedSemanticPropertiesMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedSessionMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedStoreConstants.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedStoreHelper.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/FeedUploadableActionMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/LocalActionGc.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/PersistentFeedStore.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/StreamPayloadInterner.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/internal/StreamStructureInterner.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/logging/NoOpBasicLoggingApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/network/NetworkClientWrapper.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/scheduler/SchedulerApiWrapper.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/PersistentContentStorage.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/PersistentJournalStorage.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/mocknetworkclient/MockServerNetworkClient.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/AdapterFactory.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/AdapterParameters.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ChunkedTextElementAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/CustomElementAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/DebugLogger.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementAdapterFactory.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementContainerAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementListAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ElementStackAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/FrameAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/FrameAdapterImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/FrameContext.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/GridRowAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/HostProviders.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ImageElementAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/KeyedRecyclerPool.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/LoadImageCallback.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/MediaQueryHelper.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/NoKeyOverwriteHashMap.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ParameterizedTextElementAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ParameterizedTextEvaluator.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietFatalException.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietManager.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietManagerImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/PietStylesHelper.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/RecyclerKey.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/RecyclerPool.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/SingleKeyRecyclerPool.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/StyleProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/TemplateBinder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/TextElementAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ViewUtils.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/ActionHandler.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/AssetProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/CustomElementProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/EmptyStringFormatter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/EventLogger.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/HostBindingProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/ImageLoader.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/LogDataCallback.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/NullImageLoader.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/NullTypefaceProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/StringFormatter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/ThrowingCustomElementProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/host/TypefaceProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/AspectRatioScalingImageView.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/BitmapMaskingRoundedCornerDelegate.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/BorderDrawable.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/ClipPathRoundedCornerDelegate.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/GradientDrawable.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/GradientShader.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/GridRowView.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/OutlineProviderRoundedCornerDelegate.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerDelegate.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerDelegateFactory.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerMaskCache.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerViewHelper.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerWrapperView.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/constants/Constants.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contentchanged/StreamContentChangedListener.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contextmenumanager/ContextMenuManager.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contextmenumanager/ContextMenuManagerImpl.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/contextmenumanager/FloatingContextMenuManager.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/deepestcontenttracker/DeepestContentTracker.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/LoggingListener.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/OneShotVisibilityLoggingListener.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/SpinnerLogger.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/StreamContentLoggingData.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/UiSessionRequestLogger.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/VisibilityListener.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/VisibilityMonitor.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/offlinemonitor/StreamOfflineMonitor.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/pendingdismiss/PendingDismissCallback.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietCustomElementProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietEventLogger.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietHostBindingProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietImageLoader.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietRequiredContentAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietStringFormatter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/menumeasurer/MenuMeasurer.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/menumeasurer/Size.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/scroll/ScrollObservable.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/scroll/ScrollObserver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/removetrackingfactory/StreamRemoveTrackingFactory.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/PietScrollObserver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollEvents.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollListenerNotifier.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollLogger.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollRestoreHelper.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedActionHandler.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedAppLifecycle.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedApplicationInfo.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedConfiguration.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedContentBridge.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedContentStorage.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedContentStorageDirect.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedDebuggingBridge.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedImageLoader.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedJournalBridge.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorage.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorageDirect.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedLifecycleBridge.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedLoggingBridge.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedNetworkBridge.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedOfflineBridge.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedOfflineIndicator.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedProcessScopeFactory.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedRefreshTask.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedScheduler.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedSchedulerBridge.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedStreamWrapper.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FeedV1StreamCreator.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/FutureTaskConsumer.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/TestNetworkClient.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/tooltip/BasicTooltipApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/tooltip/BasicTooltipSupportedApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v1/tooltip/FeedTooltipUtils.java",
-  ]
-} else {  # !enable_feed_v1
-  feed_java_sources += [ "//chrome/android/feed/dummy/java/src/org/chromium/chrome/browser/feed/FeedV1.java" ]
-}
-
 feed_srcjar_deps = []
-if (enable_feed_v1) {
-  feed_srcjar_deps += [ "//components/feed/core:feed_core_java_enums_srcjar" ]
-}
 
 feed_junit_test_java_sources = []
 
@@ -439,300 +71,8 @@
   ]
 }
 
-if (enable_feed_v1) {
-  feed_junit_test_java_sources += [
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/testing/ContentIdGenerators.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/api/internal/common/testing/InternalProtocolBuilder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/testing/FakeFeatureDriver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/testing/FakeLeafFeatureDriver.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeDirectExecutor.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeMainThreadRunner.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeTaskQueue.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeThreadUtils.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/InfraIntegrationScope.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/ModelProviderValidator.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/PagingState.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/RequiredConsumer.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/ResponseBuilder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/RunnableSubject.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/SessionTestUtils.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/testing/FakeClock.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/testing/AbstractSessionImplTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/AbstractClearableFeedStoreTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/AbstractFeedStoreTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/DelegatingContentStorage.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/DelegatingJournalStorage.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/feedstore/testing/DelegatingStore.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/testing/InMemoryContentStorage.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/testing/InMemoryJournalStorage.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/piet/testing/FakeFrameAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/actionmanager/FakeActionReader.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/actionmanager/FakeViewActionManager.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/android/LinearLayoutManagerForTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/network/NetworkClientConformanceTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/scheduler/SchedulerConformanceTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/ContentStorageConformanceTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/ContentStorageDirectConformanceTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/JournalStorageConformanceTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/JournalStorageDirectConformanceTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/logging/FakeBasicLoggingApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/offlineindicator/FakeOfflineIndicatorApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/scheduler/FakeSchedulerApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/stream/FakeCardConfiguration.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/stream/FakeTooltipSupportedApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelChild.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelCursor.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelFeature.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelMutation.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelProviderFactory.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeModelToken.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FakeViewDepthProvider.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/modelprovider/FeatureChangeBuilder.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/network/FakeNetworkClient.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/protocoladapter/FakeProtocolAdapter.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/requestmanager/FakeActionUploadRequestManager.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/requestmanager/FakeFeedRequestManager.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/shadows/ExtendedShadowLinearLayout.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/shadows/ExtendedShadowView.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/shadows/ShadowRecycledViewPool.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/sharedstream/contextmenumanager/FakeContextMenuManager.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/sharedstream/offlinemonitor/FakeStreamOfflineMonitor.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/store/FakeStore.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/api/client/knowncontent/ContentMetadataTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/api/client/scope/ProcessScopeBuilderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/api/client/scope/StreamScopeBuilderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/api/common/MutationContextTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/api/host/config/ConfigurationTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/api/host/network/HttpHeaderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/api/host/network/HttpRequestTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/api/host/storage/CommitResultTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/api/internal/common/ThreadUtilsTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/RemoveTrackingTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/api/internal/modelprovider/TokenCompletedTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/api/internal/scope/ClearAllListenerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/api/internal/scope/FeedProcessScopeTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/BasicStreamTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamItemAnimatorTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamItemTouchCallbacksTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/StreamRecyclerViewAdapterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/actions/StreamActionApiImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/CardDriverTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ClusterDriverTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ContentDriverTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ContinuationDriverTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/HeaderDriverTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/NoContentDriverTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/StreamDriverTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/drivers/ZeroStateDriverTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/BasicStreamScrollMonitorTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/BasicStreamScrollTrackerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/scroll/ScrollRestorerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/ContinuationViewHolderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/HeaderViewHolderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/NoContentViewHolderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/PietViewHolderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewholders/ZeroStateViewHolderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewloggingupdater/ResettableOneShotVisibilityLoggingListenerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/basicstream/internal/viewloggingupdater/ViewLoggingUpdaterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/ResultTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/ValidatorsTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/concurrent/CancelableRunnableTaskTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/concurrent/SimpleSettableFutureTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/concurrent/TaskQueueTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/feedobservable/FeedObservableTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/intern/HashPoolInternerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/intern/InternedMapTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/intern/InternerWithStatsTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/intern/WeakPoolInternerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/locale/LocaleUtilsTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/logging/DumperTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/logging/LoggerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/testing/RequiredConsumerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/testing/RunnableSubjectTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/common/ui/LayoutUtilsTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedactionmanager/FeedActionManagerImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedactionparser/FeedActionParserTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedactionreader/FeedActionReaderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedapplifecyclelistener/FeedAppLifecycleListenerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedknowncontent/FeedKnownContentImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/FeedModelProviderFactoryTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/FeedModelProviderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/FeatureChangeImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelCursorImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelFeatureImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelMutationImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedmodelprovider/internal/ModelTokenImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/FeedProtocolAdapterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedprotocoladapter/internal/transformers/FeatureDataOperationTransformerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedActionUploadRequestManagerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/FeedRequestManagerImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/RequestManagerImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/UploadableActionsRequestBuilderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedrequestmanager/internal/UtilsTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/FeedSessionManagerImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/ContentCacheTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/HeadAsStructureTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/HeadSessionImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionCacheTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionContentTrackerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/SessionManagerMutationTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedsessionmanager/internal/TimeoutSessionImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedstore/FeedStoreEphemeralModeTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedstore/FeedStoreTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedstore/internal/ContentGcTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedstore/internal/EphemeralFeedStoreTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedstore/internal/LocalActionGcTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedstore/internal/PersistentFeedStoreTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedstore/internal/StreamPayloadInternerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/feedstore/internal/StreamStructureInternerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/hostimpl/network/NetworkClientWrapperTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/hostimpl/scheduler/SchedulerApiWrapperTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/PersistentContentStorageDirectTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/PersistentContentStorageTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/PersistentJournalStorageDirectTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/PersistentJournalStorageTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/testing/InMemoryContentStorageDirectTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/testing/InMemoryContentStorageTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/testing/InMemoryJournalStorageDirectTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/testing/InMemoryJournalStorageTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/ClearAllTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/ClientRequestManagerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/ContentRemoveTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/ContentUpdateTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/DetachSessionTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/EmptyStreamTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/ExistingSessionTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/FilterHeadTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/GcTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/LimitedPagingTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/MultiSessionPagingTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/NoRequestWithContentTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/NoRequestWithTimeoutTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/NoRequestWithWaitTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/RemoveTrackingBehaviorTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/RequestWithContentTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/RequestWithTimeoutTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/RequestWithWaitTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/RootOnlyTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/SemanticPropertiesTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/SharedStateTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/SimpleStreamTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/StreamPagingTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/StructureUpdateTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/SyntheticTokensTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/TimeoutSessionBaseTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/TimeoutSessionWithContentTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/infraintegration/ViewDepthProviderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/mocknetworkclient/MockServerNetworkClientTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ChunkedTextElementAdapterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/CustomElementAdapterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/DebugLoggerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ElementAdapterFactoryTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ElementAdapterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ElementContainerAdapterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ElementListAdapterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ElementStackAdapterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/FrameAdapterImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/FrameContextTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/GridRowAdapterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ImageElementAdapterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/KeyedRecyclerPoolTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/LoadImageCallbackTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/MediaQueryHelperTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/NoKeyOverwriteHashMapTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ParameterizedTextElementAdapterFactoryTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ParameterizedTextElementAdapterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ParameterizedTextEvaluatorTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/PietManagerImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/PietStylesHelperTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/SingleKeyRecyclerPoolTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/StyleProviderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/TemplateBinderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/TextElementAdapterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ViewUtilsTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/host/AssetProviderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ui/AspectRatioScalingImageViewTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ui/BitmapMaskingRoundedCornerDelegateTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ui/BorderDrawableTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ui/GradientDrawableTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ui/GradientShaderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ui/GridRowViewTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerMaskCacheTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerViewHelperTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/ui/RoundedCornerWrapperViewTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/contentchanged/StreamContentChangedListenerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/contextmenumanager/ContextMenuManagerImplTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/contextmenumanager/FloatingContextMenuManagerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/deepestcontenttracker/DeepestContentTrackerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/OneShotVisibilityLoggingListenerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/SpinnerLoggerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/UiSessionRequestLoggerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/logging/VisibilityMonitorTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/offlinemonitor/StreamOfflineMonitorTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietCustomElementProviderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietEventLoggerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietHostBindingProviderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietImageLoaderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietRequiredContentAdapterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/piet/PietStringFormatterTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/publicapi/menumeasurer/MenuMeasurerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/removetrackingfactory/StreamRemoveTrackingFactoryTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/PietScrollObserverTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollListenerNotifierTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollLoggerTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/sharedstream/scroll/ScrollRestoreHelperTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/shared/ui/MaterialSpinnerViewTest.java",
-    "junit/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManagerTest.java",
-    "junit/src/org/chromium/chrome/browser/feed/shared/ScrollTrackerTest.java",
-    "junit/src/org/chromium/chrome/browser/feed/v1/FeedActionHandlerTest.java",
-    "junit/src/org/chromium/chrome/browser/feed/v1/FeedApplicationInfoTest.java",
-    "junit/src/org/chromium/chrome/browser/feed/v1/FeedContentStorageTest.java",
-    "junit/src/org/chromium/chrome/browser/feed/v1/FeedImageLoaderTest.java",
-    "junit/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorageTest.java",
-    "junit/src/org/chromium/chrome/browser/feed/v1/FeedLoggingBridgeTest.java",
-    "junit/src/org/chromium/chrome/browser/feed/v1/FeedOfflineBridgeTest.java",
-    "junit/src/org/chromium/chrome/browser/feed/v1/FutureTaskConsumerTest.java",
-  ]
-}
-
 feed_test_java_sources = [ "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/HeaderIphScrollListenerTest.java" ]
 
-if (enable_feed_v1) {
-  feed_test_java_sources += [
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeDirectExecutor.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeMainThreadRunner.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeTaskQueue.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/concurrent/testing/FakeThreadUtils.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/testing/RequiredConsumer.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/time/testing/FakeClock.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/testing/InMemoryContentStorage.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/hostimpl/storage/testing/InMemoryJournalStorage.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/network/NetworkClientConformanceTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/scheduler/SchedulerConformanceTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/ContentStorageConformanceTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/ContentStorageDirectConformanceTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/JournalStorageConformanceTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/conformance/storage/JournalStorageDirectConformanceTest.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/host/logging/FakeBasicLoggingApi.java",
-    "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/testing/store/FakeStore.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/ConsumerSyncWrapper.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/DataFilePath.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedAppLifecycleTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedConfigurationTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedContentStorageConformanceTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedDataInjectRule.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorageConformanceTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedNetworkBridgeConformanceTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedNewTabPageCardRenderTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedNewTabPageTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedRefreshTaskTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/FeedSchedulerBridgeConformanceTest.java",
-    "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v1/tooltip/FeedTooltipTest.java",
-  ]
-}
-
 if (enable_feed_v2) {
   feed_test_java_sources += [
     "//chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/v2/FeedProcessScopeDependencyProviderNativeTest.java",
@@ -743,7 +83,7 @@
 }
 
 feed_test_deps = []
-if (enable_feed_v1 || enable_feed_v2) {
+if (enable_feed_v2) {
   feed_test_deps += feed_deps + [
                       "//chrome/browser/privacy:java",
                       "//chrome/browser/user_education:java",
diff --git a/chrome/android/java/res/layout/start_top_toolbar.xml b/chrome/android/java/res/layout/start_top_toolbar.xml
index 9431371..1d3343ad 100644
--- a/chrome/android/java/res/layout/start_top_toolbar.xml
+++ b/chrome/android/java/res/layout/start_top_toolbar.xml
@@ -10,30 +10,17 @@
     android:id="@+id/tab_switcher_toolbar"
     android:layout_width="match_parent"
     android:layout_height="@dimen/toolbar_height_no_shadow"
-    android:paddingStart="8dp"
     android:clickable="true"
     android:visibility="gone">
 
-    <org.chromium.chrome.browser.toolbar.HomeButton
-        android:id="@+id/home_button_on_tab_switcher"
-        style="@style/ToolbarButton"
-        android:layout_width="wrap_content"
-        android:layout_centerVertical="true"
-        android:paddingStart="8dp"
-        android:paddingEnd="8dp"
-        android:contentDescription="@string/accessibility_toolbar_btn_home"
-        android:src="@drawable/btn_toolbar_home"
-        android:visibility="gone"
-        app:tint="@color/default_icon_color_tint_list" />
-
     <Switch
         tools:ignore="UseSwitchCompatOrMaterialXml"
         android:id="@+id/incognito_switch"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_toEndOf="@+id/home_button_on_tab_switcher"
         android:layout_centerVertical="true"
-        android:paddingStart="8dp"
+        android:layout_alignParentStart="true"
+        android:paddingStart="16dp"
         android:paddingEnd="8dp"
         android:thumb="@drawable/incognito_switch"
         android:track="@drawable/incognito_switch_track"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index e4e053d7..9660219 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -82,9 +82,7 @@
 import org.chromium.chrome.browser.download.DownloadOpenSource;
 import org.chromium.chrome.browser.download.DownloadUtils;
 import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
-import org.chromium.chrome.browser.feed.FeedV1;
 import org.chromium.chrome.browser.feed.FeedV2;
-import org.chromium.chrome.browser.feed.shared.FeedFeatures;
 import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor;
 import org.chromium.chrome.browser.flags.ActivityType;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
@@ -761,11 +759,7 @@
     private void maybeGetFeedAppLifecycleAndMaybeCreatePageViewObserver() {
         try (TraceEvent e = TraceEvent.scoped("ChromeTabbedActivity."
                      + "maybeGetFeedAppLifecycleAndMaybeCreatePageViewObserver")) {
-            if (FeedFeatures.isV2Enabled()) {
-                FeedV2.startup();
-            } else {
-                FeedV1.startup();
-            }
+            FeedV2.startup();
 
             if (UsageStatsService.isEnabled()) {
                 UsageStatsService.getInstance().createPageViewObserver(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
index ef81122..5a144b1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -94,7 +94,6 @@
                 ConditionalTabStripUtils.CONDITIONAL_TAB_STRIP_SESSION_TIME_MS,
                 PageAnnotationsServiceConfig.PAGE_ANNOTATIONS_BASE_URL,
                 ReturnToChromeExperimentsUtil.TAB_SWITCHER_ON_RETURN_MS,
-                StartSurfaceConfiguration.HOME_BUTTON_ON_GRID_TAB_SWITCHER,
                 StartSurfaceConfiguration.OMNIBOX_FOCUSED_ON_NEW_TAB,
                 StartSurfaceConfiguration.START_SURFACE_EXCLUDE_MV_TILES,
                 StartSurfaceConfiguration.START_SURFACE_HIDE_INCOGNITO_SWITCH,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/ChromeBackgroundTaskFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/ChromeBackgroundTaskFactory.java
index 432c86fd..ee116a3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/ChromeBackgroundTaskFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/ChromeBackgroundTaskFactory.java
@@ -11,7 +11,6 @@
 import org.chromium.chrome.browser.download.DownloadResumptionBackgroundTask;
 import org.chromium.chrome.browser.download.service.DownloadBackgroundTask;
 import org.chromium.chrome.browser.explore_sites.ExploreSitesBackgroundTask;
-import org.chromium.chrome.browser.feed.FeedV1;
 import org.chromium.chrome.browser.notifications.NotificationTriggerBackgroundTask;
 import org.chromium.chrome.browser.notifications.scheduler.NotificationSchedulerTask;
 import org.chromium.chrome.browser.offline.measurements.OfflineMeasurementsBackgroundTask;
@@ -77,8 +76,6 @@
                 return new WebApkUpdateTask();
             case TaskIds.DOWNLOAD_RESUMPTION_JOB_ID:
                 return new DownloadResumptionBackgroundTask();
-            case TaskIds.FEED_REFRESH_JOB_ID:
-                return FeedV1.createRefreshTask();
             case TaskIds.COMPONENT_UPDATE_JOB_ID:
                 return new UpdateTask();
             case TaskIds.DEPRECATED_EXPLORE_SITES_REFRESH_JOB_ID:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java
index 17a1733..8d3e59c4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java
@@ -20,6 +20,7 @@
 import org.chromium.base.BundleUtils;
 import org.chromium.base.CommandLineInitUtil;
 import org.chromium.base.ContextUtils;
+import org.chromium.base.EarlyTraceEvent;
 import org.chromium.base.JNIUtils;
 import org.chromium.base.LocaleUtils;
 import org.chromium.base.PathUtils;
@@ -51,6 +52,7 @@
  */
 public class SplitCompatApplication extends Application {
     private static final String COMMAND_LINE_FILE = "chrome-command-line";
+    private static final String ATTACH_BASE_CONTEXT_EVENT = "ChromeApplication.attachBaseContext";
     // Public to allow use in ChromeBackupAgent
     public static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "chrome";
 
@@ -144,7 +146,10 @@
                 ProductConfig.USE_CHROMIUM_LINKER, ProductConfig.USE_MODERN_LINKER);
         LibraryLoader.getInstance().enableJniChecks();
 
-        if (isBrowserProcess) {
+        if (!isBrowserProcess) {
+            EarlyTraceEvent.earlyEnableInChildWithoutCommandLine();
+            TraceEvent.begin(ATTACH_BASE_CONTEXT_EVENT);
+        } else {
             checkAppBeingReplaced();
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                 // Fixes are never required before O (where "cmd package compile" does not exist).
@@ -165,7 +170,7 @@
             TraceEvent.maybeEnableEarlyTracing(
                     (isAppDebuggable || isOsDebuggable) ? TraceEvent.ATRACE_TAG_APP : 0,
                     /*readCommandLine=*/true);
-            TraceEvent.begin("ChromeApplication.attachBaseContext");
+            TraceEvent.begin(ATTACH_BASE_CONTEXT_EVENT);
 
             // Register for activity lifecycle callbacks. Must be done before any activities are
             // created and is needed only by processes that use the ApplicationStatus api (which
@@ -192,9 +197,7 @@
             PureJavaExceptionHandler.installHandler();
         }
 
-        if (isBrowserProcess) {
-            TraceEvent.end("ChromeApplication.attachBaseContext");
-        }
+        TraceEvent.end(ATTACH_BASE_CONTEXT_EVENT);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java
index 7c08688..f07d1cb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java
@@ -73,7 +73,7 @@
     // Whether to allow to refetch tab thumbnail if the aspect ratio is not matching.
     public static final BooleanCachedFieldTrialParameter ALLOW_TO_REFETCH_TAB_THUMBNAIL_VARIATION =
             new BooleanCachedFieldTrialParameter(
-                    ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, "allow_to_refetch", false);
+                    ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, "allow_to_refetch", true);
 
     @VisibleForTesting
     public static final String UMA_THUMBNAIL_FETCHING_RESULT =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java
index e931dd0..c1f1bbd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java
@@ -19,6 +19,7 @@
 import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncherImpl;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.notifications.channels.SiteChannelsManager;
+import org.chromium.chrome.browser.privacy_sandbox.PrivacySandboxBridge;
 import org.chromium.chrome.browser.privacy_sandbox.PrivacySandboxSnackbarController;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.settings.ChromeManagedPreferenceDelegate;
@@ -237,19 +238,18 @@
 
     @Override
     public void maybeDisplayPrivacySandboxSnackbar() {
-        if (mPrivacySandboxController == null
-                || !ChromeFeatureList.isEnabled(ChromeFeatureList.PRIVACY_SANDBOX_SETTINGS)) {
-            return;
+        // Only show the snackbar when the Privacy Sandbox APIs are enabled.
+        if (mPrivacySandboxController != null && PrivacySandboxBridge.isPrivacySandboxFunctional()
+                && PrivacySandboxBridge.isPrivacySandboxEnabled()) {
+            mPrivacySandboxController.showSnackbar();
         }
-        mPrivacySandboxController.showSnackbar();
     }
 
     @Override
     public void dismissPrivacySandboxSnackbar() {
-        if (mPrivacySandboxController == null
-                || !ChromeFeatureList.isEnabled(ChromeFeatureList.PRIVACY_SANDBOX_SETTINGS)) {
-            return;
+        if (mPrivacySandboxController != null
+                && PrivacySandboxBridge.isPrivacySandboxFunctional()) {
+            mPrivacySandboxController.dismissSnackbar();
         }
-        mPrivacySandboxController.dismissSnackbar();
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/DEPS b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/DEPS
index c3558e1..773fef3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/DEPS
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/DEPS
@@ -22,8 +22,5 @@
   'ToolbarButtonInProductHelpController.java': [
     "+chrome/android/java/src/org/chromium/chrome/browser",
     "-chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java",
-  ],
-  'StartSurfaceToolbarView.java': [
-    "+chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java",
   ]
 }
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 aeb60e9..b1dff96 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
@@ -888,8 +888,7 @@
                 buttonDataProviders, mLayoutStateProviderSupplier, browsingModeThemeColorProvider,
                 mAppThemeColorProvider, mMenuButtonCoordinator, startSurfaceMenuButtonCoordinator,
                 mMenuButtonCoordinator.getMenuButtonHelperSupplier(), mTabModelSelectorSupplier,
-                mHomeButtonVisibilitySupplier, mHomepageManagedByPolicySupplier,
-                mIdentityDiscStateSupplier, (client) -> {
+                mHomeButtonVisibilitySupplier, mIdentityDiscStateSupplier, (client) -> {
                     if (invalidator != null) {
                         invalidator.invalidate(client);
                     } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java
index 37d7f58b..30a5001 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java
@@ -60,10 +60,7 @@
             OneshotSupplier<LayoutStateProvider> layoutStateProviderSupplier,
             ObservableSupplier<Boolean> identityDiscStateSupplier, ThemeColorProvider provider,
             MenuButtonCoordinator menuButtonCoordinator,
-            Supplier<ButtonData> identityDiscButtonSupplier, boolean isGridTabSwitcherEnabled,
-            ObservableSupplier<Boolean> homepageEnabledSupplier,
-            ObservableSupplier<Boolean> homepageManagedByPolicySupplier,
-            OnClickListener homeButtonOnClickHandler) {
+            Supplier<ButtonData> identityDiscButtonSupplier, boolean isGridTabSwitcherEnabled) {
         mStub = startSurfaceToolbarStub;
 
         layoutStateProviderSupplier.onAvailable(
@@ -95,9 +92,7 @@
                 },
                 StartSurfaceConfiguration.START_SURFACE_HIDE_INCOGNITO_SWITCH_NO_TAB.getValue(),
                 StartSurfaceConfiguration.START_SURFACE_HIDE_INCOGNITO_SWITCH.getValue(),
-                StartSurfaceConfiguration.HOME_BUTTON_ON_GRID_TAB_SWITCHER.getValue(),
-                menuButtonCoordinator, identityDiscStateSupplier, identityDiscButtonSupplier,
-                homepageEnabledSupplier, homepageManagedByPolicySupplier, homeButtonOnClickHandler);
+                menuButtonCoordinator, identityDiscStateSupplier, identityDiscButtonSupplier);
 
         mThemeColorProvider = provider;
         mMenuButtonCoordinator = menuButtonCoordinator;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java
index 9fcca59..7265ff6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java
@@ -6,10 +6,6 @@
 
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.ACCESSIBILITY_ENABLED;
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.BUTTONS_CLICKABLE;
-import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.HOMEPAGE_ENABLED_SUPPLIER;
-import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.HOMEPAGE_MANAGED_BY_POLICY_SUPPLIER;
-import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.HOME_BUTTON_CLICK_HANDLER;
-import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.HOME_BUTTON_IS_VISIBLE;
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_CLICK_HANDLER;
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_DESCRIPTION;
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_IMAGE;
@@ -71,16 +67,11 @@
     private CallbackController mCallbackController = new CallbackController();
     private float mNonIncognitoHomepageTranslationY;
 
-    private boolean mShowHomeButtonOnTabSwitcher;
-
     StartSurfaceToolbarMediator(PropertyModel model, Callback<IPHCommandBuilder> showIPHCallback,
             boolean hideIncognitoSwitchWhenNoTabs, boolean hideIncognitoSwitchOnHomePage,
-            boolean showHomeButtonOnTabSwitcher, MenuButtonCoordinator menuButtonCoordinator,
+            MenuButtonCoordinator menuButtonCoordinator,
             ObservableSupplier<Boolean> identityDiscStateSupplier,
-            Supplier<ButtonData> identityDiscButtonSupplier,
-            ObservableSupplier<Boolean> homepageEnabledSupplier,
-            ObservableSupplier<Boolean> homepageManagedByPolicySupplier,
-            View.OnClickListener homeButtonOnClickHandler) {
+            Supplier<ButtonData> identityDiscButtonSupplier) {
         mPropertyModel = model;
         mOverviewModeState = StartSurfaceState.NOT_SHOWN;
         mShowIPHCallback = showIPHCallback;
@@ -93,14 +84,6 @@
             if (!canShowHint && !mPropertyModel.get(IDENTITY_DISC_IS_VISIBLE)) return;
             updateIdentityDisc(mIdentityDiscButtonSupplier.get());
         });
-
-        mShowHomeButtonOnTabSwitcher = showHomeButtonOnTabSwitcher;
-        if (mShowHomeButtonOnTabSwitcher) {
-            mPropertyModel.set(HOMEPAGE_ENABLED_SUPPLIER, homepageEnabledSupplier);
-            mPropertyModel.set(
-                    HOMEPAGE_MANAGED_BY_POLICY_SUPPLIER, homepageManagedByPolicySupplier);
-            mPropertyModel.set(HOME_BUTTON_CLICK_HANDLER, homeButtonOnClickHandler);
-        }
     }
 
     void onNativeLibraryReady() {
@@ -140,7 +123,6 @@
         setStartSurfaceToolbarVisibility(shouldShowStartSurfaceToolbar);
         updateIncognitoSwitchVisibility();
         updateNewTabButtonVisibility();
-        updateHomeButtonVisibility();
         updateLogoVisibility(mIsGoogleSearchEngine);
         updateIdentityDisc(mIdentityDiscButtonSupplier.get());
         updateTranslationY(mNonIncognitoHomepageTranslationY);
@@ -307,16 +289,6 @@
         mPropertyModel.set(NEW_TAB_BUTTON_IS_VISIBLE, isShownTabswitcherState);
     }
 
-    private void updateHomeButtonVisibility() {
-        boolean isShownTabswitcherState = mOverviewModeState == StartSurfaceState.SHOWN_TABSWITCHER
-                || mOverviewModeState == StartSurfaceState.SHOWN_TABSWITCHER_TASKS_ONLY
-                || mOverviewModeState == StartSurfaceState.SHOWN_TABSWITCHER_OMNIBOX_ONLY
-                || mOverviewModeState == StartSurfaceState.SHOWN_TABSWITCHER_TRENDY_TERMS;
-        mPropertyModel.set(HOME_BUTTON_IS_VISIBLE,
-                isShownTabswitcherState && !mPropertyModel.get(IS_INCOGNITO)
-                        && mShowHomeButtonOnTabSwitcher);
-    }
-
     private void updateTranslationY(float transY) {
         if (mOverviewModeState == StartSurfaceState.SHOWN_HOMEPAGE
                 && !mPropertyModel.get(IS_INCOGNITO)) {
@@ -335,9 +307,4 @@
     int getOverviewModeStateForTesting() {
         return mOverviewModeState;
     }
-
-    @VisibleForTesting
-    void setShowHomeButtonOnTabSwitcherForTesting(boolean showHomeButtonOnTabSwitcher) {
-        mShowHomeButtonOnTabSwitcher = showHomeButtonOnTabSwitcher;
-    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarProperties.java
index 54f7eba..aafd9cf6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarProperties.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarProperties.java
@@ -7,7 +7,6 @@
 import android.graphics.drawable.Drawable;
 import android.view.View;
 
-import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider;
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -72,25 +71,11 @@
     public static final PropertyModel.WritableFloatPropertyKey TRANSLATION_Y =
             new PropertyModel.WritableFloatPropertyKey();
 
-    public static final PropertyModel.WritableBooleanPropertyKey HOME_BUTTON_IS_VISIBLE =
-            new PropertyModel.WritableBooleanPropertyKey();
-    public static final PropertyModel
-            .WritableObjectPropertyKey<ObservableSupplier<Boolean>> HOMEPAGE_ENABLED_SUPPLIER =
-            new PropertyModel.WritableObjectPropertyKey<ObservableSupplier<Boolean>>();
-    public static final PropertyModel.WritableObjectPropertyKey<ObservableSupplier<Boolean>>
-            HOMEPAGE_MANAGED_BY_POLICY_SUPPLIER =
-            new PropertyModel.WritableObjectPropertyKey<ObservableSupplier<Boolean>>();
-    public static final PropertyModel
-            .WritableObjectPropertyKey<View.OnClickListener> HOME_BUTTON_CLICK_HANDLER =
-            new PropertyModel.WritableObjectPropertyKey<View.OnClickListener>();
-
-    public static final PropertyKey[] ALL_KEYS =
-            new PropertyKey[] {NEW_TAB_CLICK_HANDLER, IS_VISIBLE, LOGO_IS_VISIBLE, IS_INCOGNITO,
-                    INCOGNITO_STATE_PROVIDER, ACCESSIBILITY_ENABLED, MENU_IS_VISIBLE,
-                    NEW_TAB_BUTTON_IS_VISIBLE, BUTTONS_CLICKABLE, GRID_TAB_SWITCHER_ENABLED,
-                    IDENTITY_DISC_AT_START, INCOGNITO_SWITCHER_VISIBLE, NEW_TAB_BUTTON_AT_START,
-                    IDENTITY_DISC_IS_VISIBLE, IDENTITY_DISC_CLICK_HANDLER, IDENTITY_DISC_IMAGE,
-                    IDENTITY_DISC_DESCRIPTION, IN_START_SURFACE_MODE, NEW_TAB_BUTTON_HIGHLIGHT,
-                    TRANSLATION_Y, HOME_BUTTON_IS_VISIBLE, HOMEPAGE_ENABLED_SUPPLIER,
-                    HOMEPAGE_MANAGED_BY_POLICY_SUPPLIER, HOME_BUTTON_CLICK_HANDLER};
+    public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {NEW_TAB_CLICK_HANDLER,
+            IS_VISIBLE, LOGO_IS_VISIBLE, IS_INCOGNITO, INCOGNITO_STATE_PROVIDER,
+            ACCESSIBILITY_ENABLED, MENU_IS_VISIBLE, NEW_TAB_BUTTON_IS_VISIBLE, BUTTONS_CLICKABLE,
+            GRID_TAB_SWITCHER_ENABLED, IDENTITY_DISC_AT_START, INCOGNITO_SWITCHER_VISIBLE,
+            NEW_TAB_BUTTON_AT_START, IDENTITY_DISC_IS_VISIBLE, IDENTITY_DISC_CLICK_HANDLER,
+            IDENTITY_DISC_IMAGE, IDENTITY_DISC_DESCRIPTION, IN_START_SURFACE_MODE,
+            NEW_TAB_BUTTON_HIGHLIGHT, TRANSLATION_Y};
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarView.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarView.java
index 42610f9..5a641b8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarView.java
@@ -19,11 +19,9 @@
 import androidx.annotation.StringRes;
 import androidx.appcompat.content.res.AppCompatResources;
 
-import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.device.DeviceClassManager;
 import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider;
-import org.chromium.chrome.browser.toolbar.HomeButton;
 import org.chromium.chrome.browser.toolbar.NewTabButton;
 import org.chromium.components.browser_ui.styles.ChromeColors;
 import org.chromium.components.browser_ui.widget.animation.Interpolators;
@@ -32,7 +30,6 @@
 /** View of the StartSurfaceToolbar */
 class StartSurfaceToolbarView extends RelativeLayout {
     private NewTabButton mNewTabButton;
-    private HomeButton mHomeButton;
     private View mIncognitoSwitch;
     private View mLogo;
     @Nullable
@@ -49,10 +46,6 @@
     private boolean mInStartSurfaceMode;
     private boolean mIsShowing;
 
-    private ObservableSupplier<Boolean> mHomepageEnabledSupplier;
-    private ObservableSupplier<Boolean> mHomepageManagedByPolicySupplier;
-    private boolean mIsHomeButtonInitialized;
-
     public StartSurfaceToolbarView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
@@ -61,7 +54,6 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         mNewTabButton = findViewById(R.id.new_tab_button);
-        mHomeButton = findViewById(R.id.home_button_on_tab_switcher);
         mIncognitoSwitch = findViewById(R.id.incognito_switch);
         mLogo = findViewById(R.id.logo);
         mIdentityDiscButton = findViewById(R.id.identity_disc_button);
@@ -139,54 +131,6 @@
     }
 
     /**
-     * @param isVisible Whether the home button is visible.
-     */
-    void setHomeButtonVisibility(boolean isVisible) {
-        mayInitializeHomeButton();
-        mHomeButton.setVisibility(isVisible ? View.VISIBLE : View.GONE);
-    }
-
-    /**
-     * @param homepageEnabledSupplier Supplier of whether homepage is enabled.
-     */
-    void setHomepageEnabledSupplier(ObservableSupplier<Boolean> homepageEnabledSupplier) {
-        assert mHomepageEnabledSupplier == null;
-        mHomepageEnabledSupplier = homepageEnabledSupplier;
-    }
-
-    /**
-     * @param homepageManagedByPolicySupplier Supplier of whether the homepage is managed by policy.
-     */
-    void setHomepageManagedByPolicySupplier(
-            ObservableSupplier<Boolean> homepageManagedByPolicySupplier) {
-        assert mHomepageManagedByPolicySupplier == null;
-        mHomepageManagedByPolicySupplier = homepageManagedByPolicySupplier;
-    }
-
-    /**
-     * Initializes the home button if not yet.
-     */
-    private void mayInitializeHomeButton() {
-        if (mIsHomeButtonInitialized || mHomepageEnabledSupplier == null
-                || mHomepageManagedByPolicySupplier == null) {
-            return;
-        }
-
-        // The long click which shows the change homepage settings is disabled when the Start
-        // surface is enabled.
-        mHomeButton.init(mHomepageEnabledSupplier, null, mHomepageManagedByPolicySupplier);
-        mIsHomeButtonInitialized = true;
-    }
-
-    /**
-     * @param homeButtonClickHandler The callback that will be notified when the home button is
-     *                               pressed.
-     */
-    void setHomeButtonClickHandler(OnClickListener homeButtonClickHandler) {
-        mHomeButton.setOnClickListener(homeButtonClickHandler);
-    }
-
-    /**
      * @param isClickable Whether the buttons are clickable.
      */
     void setButtonClickableState(boolean isClickable) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarViewBinder.java
index d443ead11..d50f0a2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarViewBinder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarViewBinder.java
@@ -7,10 +7,6 @@
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.ACCESSIBILITY_ENABLED;
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.BUTTONS_CLICKABLE;
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.GRID_TAB_SWITCHER_ENABLED;
-import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.HOMEPAGE_ENABLED_SUPPLIER;
-import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.HOMEPAGE_MANAGED_BY_POLICY_SUPPLIER;
-import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.HOME_BUTTON_CLICK_HANDLER;
-import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.HOME_BUTTON_IS_VISIBLE;
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_AT_START;
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_CLICK_HANDLER;
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_DESCRIPTION;
@@ -76,14 +72,6 @@
             view.setNewTabButtonVisibility(model.get(NEW_TAB_BUTTON_IS_VISIBLE));
         } else if (propertyKey == TRANSLATION_Y) {
             view.setTranslationY(model.get(TRANSLATION_Y));
-        } else if (propertyKey == HOME_BUTTON_IS_VISIBLE) {
-            view.setHomeButtonVisibility(model.get(HOME_BUTTON_IS_VISIBLE));
-        } else if (propertyKey == HOMEPAGE_ENABLED_SUPPLIER) {
-            view.setHomepageEnabledSupplier(model.get(HOMEPAGE_ENABLED_SUPPLIER));
-        } else if (propertyKey == HOMEPAGE_MANAGED_BY_POLICY_SUPPLIER) {
-            view.setHomepageManagedByPolicySupplier(model.get(HOMEPAGE_MANAGED_BY_POLICY_SUPPLIER));
-        } else if (propertyKey == HOME_BUTTON_CLICK_HANDLER) {
-            view.setHomeButtonClickHandler(model.get(HOME_BUTTON_CLICK_HANDLER));
         }
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java
index e7265bc..3ed9096 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java
@@ -188,10 +188,10 @@
     private boolean isNewTabVariationEnabled() {
         return mIsGridTabSwitcherEnabled && ChromeFeatureList.isInitialized()
                 && IncognitoUtils.isIncognitoModeEnabled()
-                && ChromeFeatureList
-                           .getFieldTrialParamByFeature(ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID,
-                                   "tab_grid_layout_android_new_tab")
-                           .equals("NewTabVariation");
+                && !ChromeFeatureList
+                            .getFieldTrialParamByFeature(ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID,
+                                    "tab_grid_layout_android_new_tab")
+                            .equals("false");
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
index 52e48f74..e257078 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -104,7 +104,6 @@
      * @param overviewThemeColorProvider The {@link ThemeColorProvider} for overview mode.
      * @param tabModelSelectorSupplier Supplier of the {@link TabModelSelector}.
      * @param homeButtonVisibilitySupplier Supplier of the visibility change of Home button.
-     * @param homepageManagedByPolicySupplier Supplier of whether the homepage is managed by policy.
      * @param identityDiscStateSupplier Supplier of the state change of identity disc button.
      * @param invalidatorCallback Callback that will be invoked  when the toolbar attempts to
      *        invalidate the drawing surface.  This will give the object that registers as the host
@@ -129,7 +128,6 @@
             ObservableSupplier<AppMenuButtonHelper> appMenuButtonHelperSupplier,
             ObservableSupplier<TabModelSelector> tabModelSelectorSupplier,
             ObservableSupplier<Boolean> homeButtonVisibilitySupplier,
-            ObservableSupplier<Boolean> homepageManagedByPolicySupplier,
             ObservableSupplier<Boolean> identityDiscStateSupplier,
             Callback<Runnable> invalidatorCallback, Supplier<ButtonData> identityDiscButtonSupplier,
             OneshotSupplier<StartSurface> startSurfaceSupplier,
@@ -147,18 +145,11 @@
 
         if (mToolbarLayout instanceof ToolbarPhone) {
             if (isStartSurfaceEnabled) {
-                View.OnClickListener homeButtonOnClickListener = v -> {
-                    if (tabController != null) {
-                        tabController.openHomepage();
-                    }
-                };
                 mStartSurfaceToolbarCoordinator = new StartSurfaceToolbarCoordinator(
                         controlContainer.getRootView().findViewById(R.id.tab_switcher_toolbar_stub),
                         userEducationHelper, layoutStateProviderSupplier, identityDiscStateSupplier,
                         overviewThemeColorProvider, overviewModeMenuButtonCoordinator,
-                        identityDiscButtonSupplier, isGridTabSwitcherEnabled,
-                        homeButtonVisibilitySupplier, homepageManagedByPolicySupplier,
-                        homeButtonOnClickListener);
+                        identityDiscButtonSupplier, isGridTabSwitcherEnabled);
             } else {
                 mTabSwitcherModeCoordinatorPhone = new TabSwitcherModeTTCoordinatorPhone(
                         controlContainer.getRootView().findViewById(R.id.tab_switcher_toolbar_stub),
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageColorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageColorTest.java
deleted file mode 100644
index ab81d2c..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageColorTest.java
+++ /dev/null
@@ -1,112 +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.
-
-package org.chromium.chrome.browser.ntp;
-
-import android.content.res.Resources;
-import android.graphics.Color;
-
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.filters.MediumTest;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.ApiCompatibilityUtils;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.Restriction;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.feed.v1.DataFilePath;
-import org.chromium.chrome.browser.feed.v1.FeedDataInjectRule;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
-import org.chromium.chrome.test.util.NewTabPageTestUtils;
-import org.chromium.chrome.test.util.browser.Features;
-import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule;
-import org.chromium.components.browser_ui.styles.ChromeColors;
-import org.chromium.components.browser_ui.widget.RecyclerViewTestUtils;
-import org.chromium.components.embedder_support.util.UrlConstants;
-import org.chromium.ui.test.util.UiRestriction;
-
-/**
- * Tests for colors used in UI components in the native android New Tab Page.
- */
-// clang-format off
-@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
-                       "disable-features=IPH_FeedHeaderMenu"})
-@Features.DisableFeatures({ChromeFeatureList.EXPLORE_SITES,
-                           ChromeFeatureList.REPORT_FEED_USER_ACTIONS,
-                           ChromeFeatureList.QUERY_TILES, ChromeFeatureList.VIDEO_TUTORIALS,
-                           ChromeFeatureList.INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS})
-// clang-format on
-public class NewTabPageColorTest {
-    @Rule
-    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
-    @Rule
-    public SuggestionsDependenciesRule mSuggestionsDeps = new SuggestionsDependenciesRule();
-
-    @Rule
-    public FeedDataInjectRule mFeedDataInjector = new FeedDataInjectRule(true);
-
-    private static final String TEST_FEED_DATA_BASE_PATH = "/chrome/test/data/android/feed/";
-
-    private Tab mTab;
-    private NewTabPage mNtp;
-
-    @Before
-    public void setUp() throws Exception {
-        mActivityTestRule.startMainActivityWithURL("about:blank");
-
-        mActivityTestRule.loadUrl(UrlConstants.NTP_URL);
-        mTab = mActivityTestRule.getActivity().getActivityTab();
-        NewTabPageTestUtils.waitForNtpLoaded(mTab);
-
-        Assert.assertTrue(mTab.getNativePage() instanceof NewTabPage);
-        mNtp = (NewTabPage) mTab.getNativePage();
-    }
-
-    // clang-format off
-    @Test
-    @MediumTest
-    @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
-    @Feature({"NewTabPage", "FeedNewTabPage"})
-    @Features.EnableFeatures({ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS,
-                              ChromeFeatureList.OMNIBOX_SEARCH_ENGINE_LOGO})
-    @Features.DisableFeatures({
-            ChromeFeatureList.ENHANCED_PROTECTION_PROMO_CARD,
-            ChromeFeatureList.INTEREST_FEED_V2,
-            ChromeFeatureList.INTEREST_FEEDV1_CLICKS_AND_VIEWS_CONDITIONAL_UPLOAD})
-    @DataFilePath(TEST_FEED_DATA_BASE_PATH + "feed_world.gcl.bin")
-    public void testTextBoxBackgroundColor() throws Exception {
-        // clang-format on
-        RecyclerView recycleView =
-                (RecyclerView) mNtp.getCoordinatorForTesting().getStreamForTesting().getView();
-
-        Resources resources = mActivityTestRule.getActivity().getResources();
-        Assert.assertEquals(ChromeColors.getPrimaryBackgroundColor(resources, false),
-                mNtp.getToolbarTextBoxBackgroundColor(Color.BLACK));
-
-        // Trigger a refresh to get feed cards so that page becomes long enough
-        // for the location bar to get placed to the top of the page after scrolling.
-        mFeedDataInjector.triggerFeedRefreshOnUiThreadBlocking(
-                mNtp.getCoordinatorForTesting().getStreamForTesting());
-
-        // Scroll to the bottom.
-        RecyclerViewTestUtils.scrollToBottom(recycleView);
-        RecyclerViewTestUtils.waitForStableRecyclerView(recycleView);
-
-        Assert.assertTrue(mNtp.isLocationBarScrolledToTopInNtp());
-        Assert.assertEquals(
-                ApiCompatibilityUtils.getColor(resources, R.color.toolbar_text_box_background),
-                mNtp.getToolbarTextBoxBackgroundColor(Color.BLACK));
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchFeedFlowTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchFeedFlowTest.java
deleted file mode 100644
index 4d1c71e..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchFeedFlowTest.java
+++ /dev/null
@@ -1,548 +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.
-
-package org.chromium.chrome.browser.offlinepages.prefetch;
-
-import android.graphics.Bitmap;
-import android.net.ConnectivityManager;
-import android.net.Uri;
-import android.util.Base64;
-
-import androidx.test.filters.MediumTest;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.CommandLine;
-import org.chromium.base.ContextUtils;
-import org.chromium.base.test.util.CallbackHelper;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.CriteriaHelper;
-import org.chromium.base.test.util.DisableIf;
-import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.UrlUtils;
-import org.chromium.chrome.browser.background_task_scheduler.ChromeNativeBackgroundTaskDelegate;
-import org.chromium.chrome.browser.download.items.OfflineContentAggregatorFactory;
-import org.chromium.chrome.browser.feed.v1.FeedProcessScopeFactory;
-import org.chromium.chrome.browser.feed.v1.TestNetworkClient;
-import org.chromium.chrome.browser.firstrun.FirstRunUtils;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
-import org.chromium.chrome.browser.offlinepages.OfflinePageItem;
-import org.chromium.chrome.browser.offlinepages.OfflineTestUtil;
-import org.chromium.chrome.browser.profiles.ProfileKey;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
-import org.chromium.chrome.test.ReducedModeNativeTestRule;
-import org.chromium.chrome.test.util.browser.Features;
-import org.chromium.components.background_task_scheduler.TaskIds;
-import org.chromium.components.background_task_scheduler.TaskParameters;
-import org.chromium.components.download.NetworkStatusListenerAndroid;
-import org.chromium.components.embedder_support.util.UrlConstants;
-import org.chromium.components.gcm_driver.instance_id.FakeInstanceIDWithSubtype;
-import org.chromium.components.offline_items_collection.ContentId;
-import org.chromium.components.offline_items_collection.OfflineContentProvider;
-import org.chromium.components.offline_items_collection.OfflineItem;
-import org.chromium.components.offline_pages.core.prefetch.proto.StatusOuterClass;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-import org.chromium.net.NetworkChangeNotifier;
-import org.chromium.net.NetworkChangeNotifierAutoDetect;
-import org.chromium.net.test.util.WebServer;
-import org.chromium.ui.test.util.UiDisableIf;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Instrumentation tests for Prefetch, using the Feed as the suggestion provider. Most test cases
- * are run both in full browser mode and in reduced mode.
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-@Features.DisableFeatures({ChromeFeatureList.INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS})
-public class PrefetchFeedFlowTest {
-    private TestOfflinePageService mOPS = new TestOfflinePageService();
-    private WebServer mServer;
-    private CallbackHelper mPageAddedHelper = new CallbackHelper();
-    private List<OfflinePageItem> mAddedPages = Collections.synchronizedList(new ArrayList<>());
-    private boolean mUseReducedMode;
-
-    /* Feed test data
-     * This file contains test data for Feed so that suggestions can be populated. This test
-     * attempts to assume as little as possible about this data, so that it can be changed in the
-     * future. Note: There are many other suggested URLs in this file, and URLs can even be
-     * repeated.
-     */
-    private static final String TEST_FEED =
-            UrlUtils.getIsolatedTestFilePath("/chrome/test/data/android/feed/feed_large.gcl.bin");
-
-    // The first suggestion URL, thumbnail URL, and title.
-    private static final String URL1 =
-            "http://profootballtalk.nbcsports.com/2017/11/10/jerry-jones-owners-should-approve-of-"
-            + "roger-goodells-decisions/";
-    private static final String THUMBNAIL_URL1 =
-            "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcRydPYA9MW5_G1lKk6fM8OVNf9z7lF5e7"
-            + "ZI2hAAVIAAb-_b3eyQrCQN6j2AcNAaWu-KO11XpQfC-A";
-    private static final String FAVICON_URL1 =
-            "https://www.google.com/s2/favicons?domain=www.profootballtalk.com&sz=48";
-    private static final String TITLE1 =
-            "Jerry Jones: Owners should approve of Roger Goodell's decisions (2097)";
-
-    // The second suggestion URL and thumbnail URL.
-    private static final String URL2 =
-            "https://www.nytimes.com/2017/11/10/world/asia/trump-apec-asia-trade.html";
-    private static final String THUMBNAIL_URL2 =
-            "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRh1tEaJT-br6mBxM89U3vgjDldwb9L_b"
-            + "aZszhstAGMQh3_fuG13ax3C9ewR2tq45tbZj74CHl3KNU";
-    private static final String FAVICON_URL2 =
-            "https://www.google.com/s2/favicons?domain=www.nytimes.com&sz=48";
-    private static final String TITLE2 =
-            "Trump Pitches 'American First' Trade Policy at Asia-Pacific Gathering";
-
-    private static final int THUMBNAIL_WIDTH = 4;
-    private static final int THUMBNAIL_HEIGHT = 4;
-
-    @Rule
-    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
-
-    @Rule
-    public ReducedModeNativeTestRule mReducedModeNativeTestRule =
-            new ReducedModeNativeTestRule(/*autoLoadNative=*/false);
-
-    private WebServer.RequestHandler mRequestHandler = new WebServer.RequestHandler() {
-        @Override
-        public void handleRequest(WebServer.HTTPRequest request, OutputStream stream) {
-            try {
-                if (mOPS.handleRequest(request, stream)) {
-                    // Handled.
-                } else {
-                    Assert.fail("Unhandled request: " + request.toString());
-                }
-            } catch (IOException e) {
-                Assert.fail(e.getMessage() + " \n while handling request: " + request.toString());
-            }
-        }
-    };
-
-    private void loadNative() throws InterruptedException {
-        if (mUseReducedMode) {
-            mReducedModeNativeTestRule.loadNative();
-        } else {
-            mActivityTestRule.startMainActivityOnBlankPage();
-        }
-    }
-
-    private void forceLoadSnippets() {
-        if (mUseReducedMode) {
-            // NTP suggestions require a connection.
-            TestThreadUtils.runOnUiThreadBlocking(() -> {
-                NetworkChangeNotifier.forceConnectivityState(true);
-                PrefetchTestBridge.addCandidatePrefetchURL(
-                        URL1, TITLE1, THUMBNAIL_URL1, FAVICON_URL1, "", "");
-                PrefetchTestBridge.addCandidatePrefetchURL(
-                        URL2, TITLE2, THUMBNAIL_URL2, FAVICON_URL2, "", "");
-            });
-        } else {
-            // NTP suggestions require a connection and an accepted EULA.
-            TestThreadUtils.runOnUiThreadBlocking(() -> {
-                NetworkChangeNotifier.forceConnectivityState(true);
-                FirstRunUtils.setEulaAccepted();
-            });
-
-            // Loading the NTP triggers loading suggestions.
-            mActivityTestRule.loadUrl(UrlConstants.NTP_URL);
-        }
-    }
-
-    // A fake NetworkChangeNotifierAutoDetect which always reports a connection.
-    private static class FakeAutoDetect extends NetworkChangeNotifierAutoDetect {
-        public FakeAutoDetect(Observer observer, RegistrationPolicy policy) {
-            super(observer, policy);
-        }
-        @Override
-        public NetworkState getCurrentNetworkState() {
-            return new NetworkState(true, ConnectivityManager.TYPE_WIFI, 0, null, false, "");
-        }
-    }
-
-    // Returns a small PNG image data.
-    private static byte[] testImageData() {
-        final String imageBase64 =
-                "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAABHNCSVQICAgIfAhkiAAAADRJREFU"
-                + "CJlNwTERgDAABLA8h7AaqCwUdcYCmOFYn5UkbSsBWvsU7/GAM7H5u4a07RTrHuADaewQm6Wdp7oA"
-                + "AAAASUVORK5CYII=";
-        return Base64.decode(imageBase64, Base64.DEFAULT);
-    }
-
-    // Helper for checking isPrefetchingEnabledByServer().
-    private boolean isEnabledByServer() {
-        final AtomicBoolean isEnabled = new AtomicBoolean();
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            isEnabled.set(PrefetchConfiguration.isPrefetchingEnabledByServer(
-                    ProfileKey.getLastUsedRegularProfileKey()));
-        });
-        return isEnabled.get();
-    }
-
-    private void waitForServerEnabledValue(boolean wanted) {
-        CriteriaHelper.pollUiThread(() -> {
-            return PrefetchConfiguration.isPrefetchingEnabledByServer(
-                           ProfileKey.getLastUsedRegularProfileKey())
-                    == wanted;
-        }, "never got wanted value", 5000, 200);
-    }
-
-    private void doSetUp(boolean isReducedMode) throws Exception {
-        mUseReducedMode = isReducedMode;
-        if (mUseReducedMode) {
-            PrefetchBackgroundTask.alwaysSupportMinimalBrowserForTesting();
-        }
-
-        TestNetworkClient client = new TestNetworkClient();
-        client.setNetworkResponseFile(TEST_FEED);
-        FeedProcessScopeFactory.setTestNetworkClient(client);
-
-        // Start the server before Chrome starts, offline_pages_backend is overridden later with
-        // this server's address.
-        mServer = new WebServer(0, false);
-        mServer.setRequestHandler(mRequestHandler);
-        // Inject FakeAutoDetect so that the download component will attempt to download a file even
-        // when there is no connection.
-        NetworkStatusListenerAndroid.setAutoDetectFactory(
-                new NetworkStatusListenerAndroid.AutoDetectFactory() {
-                    @Override
-                    public NetworkChangeNotifierAutoDetect create(
-                            NetworkChangeNotifierAutoDetect.Observer observer,
-                            NetworkChangeNotifierAutoDetect.RegistrationPolicy policy) {
-                        return new FakeAutoDetect(observer, policy);
-                    }
-                });
-
-        // Configure flags:
-        // - Enable OfflinePagesPrefetching and InterestFeedContentSuggestions.
-        // - Set DownloadService's start_up_delay_ms to 100 ms (5 seconds is default).
-        // - Set offline_pages_backend.
-        final String offlinePagesBackend = Uri.encode(mServer.getBaseUrl());
-        CommandLine.getInstance().appendSwitchWithValue("enable-features",
-                ChromeFeatureList.OFFLINE_PAGES_PREFETCHING + "<Trial,DownloadService<Trial"
-                        + "," + ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS + "<Trial");
-        CommandLine.getInstance().appendSwitchWithValue("force-fieldtrials", "Trial/Group");
-        CommandLine.getInstance().appendSwitchWithValue("force-fieldtrial-params",
-                "Trial.Group:start_up_delay_ms/100/offline_pages_backend/" + offlinePagesBackend);
-
-        // TestOfflinePageService will send GCM. Enable fake GCM.
-        FakeInstanceIDWithSubtype.clearDataAndSetEnabled(true);
-
-        // Start Chrome.
-        loadNative();
-
-        // Register Offline Page observer and enable limitless prefetching.
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            OfflinePageBridge.getForProfileKey(ProfileKey.getLastUsedRegularProfileKey())
-                    .addObserver(new OfflinePageBridge.OfflinePageModelObserver() {
-                        @Override
-                        public void offlinePageAdded(OfflinePageItem addedPage) {
-                            mAddedPages.add(addedPage);
-                            mPageAddedHelper.notifyCalled();
-                        }
-                    });
-            PrefetchTestBridge.enableLimitlessPrefetching(true);
-        });
-
-        OfflineTestUtil.setPrefetchingEnabledByServer(true);
-        OfflineTestUtil.setGCMTokenForTesting("dummy_gcm_token");
-    }
-
-    @After
-    public void tearDown() {
-        FakeInstanceIDWithSubtype.clearDataAndSetEnabled(false);
-        mServer.shutdown();
-    }
-
-    private static OfflineContentProvider offlineContentProvider() {
-        return OfflineContentAggregatorFactory.get();
-    }
-
-    private OfflineItem findItemByUrl(String url) throws TimeoutException {
-        for (OfflineItem item : OfflineTestUtil.getOfflineItems()) {
-            if (item.pageUrl.equals(url)) {
-                return item;
-            }
-        }
-        return null;
-    }
-
-    private OfflinePageItem findPageByUrl(String url) throws TimeoutException {
-        for (OfflinePageItem page : OfflineTestUtil.getAllPages()) {
-            if (page.getUrl().equals(url)) {
-                return page;
-            }
-        }
-        return null;
-    }
-
-    private Bitmap findVisuals(ContentId id) throws TimeoutException {
-        final CallbackHelper finished = new CallbackHelper();
-        final AtomicReference<Bitmap> result = new AtomicReference<>();
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            offlineContentProvider().getVisualsForItem(id, (resultId, visuals) -> {
-                if (visuals != null) {
-                    result.set(visuals.icon);
-                }
-                finished.notifyCalled();
-            });
-        });
-        finished.waitForCallback(0);
-        return result.get();
-    }
-
-    private void runAndWaitForBackgroundTask() throws Throwable {
-        final CallbackHelper finished = new CallbackHelper();
-        PrefetchBackgroundTask task = new PrefetchBackgroundTask();
-        task.setDelegate(new ChromeNativeBackgroundTaskDelegate());
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            TaskParameters.Builder builder =
-                    TaskParameters.create(TaskIds.OFFLINE_PAGES_PREFETCH_JOB_ID);
-            PrefetchBackgroundTask.skipConditionCheckingForTesting();
-            task.onStartTask(ContextUtils.getApplicationContext(), builder.build(),
-                    (boolean needsReschedule) -> { finished.notifyCalled(); });
-        });
-        finished.waitForCallback(0);
-    }
-
-    /**
-     * Waits for |callbackHelper| to be notified. Runs the background task while waiting.
-     * @param callbackHelper The callback helper to wait for.
-     * @param currentCallCount |callbackHelper|'s current call count.
-     * @param numberOfCallsToWaitFor number of calls to wait for.
-     */
-    private void runBackgroundTaskUntilCallCountReached(CallbackHelper callbackHelper,
-            int currentCallCount, int numberOfCallsToWaitFor) throws Throwable {
-        // It's necessary to run the background task multiple times because we don't always have a
-        // hook to know when the system is ready for background processing.
-        long startTime = System.nanoTime();
-        final long timeoutTime = startTime + TimeUnit.SECONDS.toNanos(5);
-        while (true) {
-            runAndWaitForBackgroundTask();
-            try {
-                callbackHelper.waitForCallback(
-                        currentCallCount, numberOfCallsToWaitFor, 200, TimeUnit.MILLISECONDS);
-                return;
-            } catch (TimeoutException e) {
-                if (System.nanoTime() > timeoutTime) {
-                    throw e;
-                }
-            }
-        }
-    }
-
-    /**
-     * Serve a single suggestion to NTP snippets. That suggestion is successfully handled by
-     * offline prefetch.
-     */
-    public void doTestPrefetchSinglePageSuccess() throws Throwable {
-        // TODO(crbug.com/845310): Expand this test. There's some important flows missing and
-        // systems missing.
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            PrefetchTestBridge.insertIntoCachedImageFetcher(THUMBNAIL_URL1, testImageData());
-        });
-
-        // Set up default (success) OPS behavior for a URL.
-        TestOfflinePageService.PageBehavior behavior = new TestOfflinePageService.PageBehavior();
-        mOPS.setPageBehavior(URL1, behavior);
-        // Set up failure status for all other URLs.
-        mOPS.setDefaultGenerateStatus(StatusOuterClass.Code.UNKNOWN);
-
-        forceLoadSnippets();
-
-        // Wait for the page to be added to the offline model.
-        runBackgroundTaskUntilCallCountReached(mPageAddedHelper, 0, 1);
-
-        // Check that the page was downloaded and saved.
-        Assert.assertEquals(1, mOPS.ReadCalled.getCallCount());
-        Assert.assertTrue(mAddedPages.size() >= 1);
-        Assert.assertEquals(URL1, mAddedPages.get(0).getUrl());
-        Assert.assertEquals(TITLE1, mAddedPages.get(0).getTitle());
-        Assert.assertEquals(behavior.body.length, mAddedPages.get(0).getFileSize());
-        Assert.assertNotEquals("", mAddedPages.get(0).getFilePath());
-
-        // Check that the thumbnail was fetched.
-        OfflinePageItem page1 = findPageByUrl(URL1);
-        Assert.assertNotNull(page1);
-        byte[] rawThumbnail = OfflineTestUtil.getRawThumbnail(page1.getOfflineId());
-        Assert.assertArrayEquals(testImageData(), rawThumbnail);
-    }
-
-    /**
-     *  Request two pages. One is ready later, and one fails immediately.
-     *
-     *  WARNING: this test might be flakey, sometimes waiting for the callback times out regardless.
-     */
-    public void doTestPrefetchPageReadyLater() throws Throwable {
-        TestOfflinePageService.PageBehavior pageFail = new TestOfflinePageService.PageBehavior();
-        pageFail.generateStatus = StatusOuterClass.Code.UNKNOWN;
-        pageFail.getStatus = StatusOuterClass.Code.UNKNOWN;
-        mOPS.setPageBehavior(URL1, pageFail);
-
-        TestOfflinePageService.PageBehavior readyLater = new TestOfflinePageService.PageBehavior();
-        readyLater.generateStatus = StatusOuterClass.Code.NOT_FOUND;
-        mOPS.setPageBehavior(URL2, readyLater);
-
-        // Set up failure status for all other URLs.
-        mOPS.setDefaultGenerateStatus(StatusOuterClass.Code.UNKNOWN);
-
-        forceLoadSnippets();
-        runBackgroundTaskUntilCallCountReached(mOPS.GeneratePageBundleCalled, 0, 1);
-
-        // At this point, the bundle has been requested. Send the GCM message, and wait for the page
-        // to be imported. If this assert fails, GeneratePageBundle may not have been called.
-        Assert.assertEquals("operation-1", mOPS.sendPushMessage());
-        runAndWaitForBackgroundTask();
-        mPageAddedHelper.waitForCallback(0, 1);
-
-        // Only URL2 is added.
-        Assert.assertEquals(1, mAddedPages.size());
-        Assert.assertEquals(URL2, mAddedPages.get(0).getUrl());
-        Assert.assertEquals(readyLater.body.length, mAddedPages.get(0).getFileSize());
-        Assert.assertNotEquals("", mAddedPages.get(0).getFilePath());
-    }
-
-    /** Request a page and get a Forbidden response. The enabled-by-server state should change. */
-    public void doTestPrefetchForbiddenByServer() throws Throwable {
-        mOPS.setForbidGeneratePageBundle(true);
-
-        Assert.assertTrue(isEnabledByServer());
-
-        forceLoadSnippets();
-        runBackgroundTaskUntilCallCountReached(mOPS.GeneratePageBundleCalled, 0, 1);
-        waitForServerEnabledValue(false);
-
-        Assert.assertFalse(isEnabledByServer());
-    }
-
-    /**
-     * Check that a server-enabled check can enable prefetching.
-     */
-    public void doTestPrefetchBecomesEnabledByServer() {
-        OfflineTestUtil.setPrefetchingEnabledByServer(false);
-
-        Assert.assertFalse(isEnabledByServer());
-
-        forceLoadSnippets();
-        waitForServerEnabledValue(true);
-
-        Assert.assertTrue(isEnabledByServer());
-    }
-
-    /**
-     * Check that prefetching remains disabled by the server after receiving a forbidden
-     * response.
-     */
-    public void doTestPrefetchRemainsDisabledByServer() {
-        OfflineTestUtil.setPrefetchingEnabledByServer(false);
-        mOPS.setForbidGeneratePageBundle(true);
-
-        Assert.assertFalse(isEnabledByServer());
-
-        forceLoadSnippets();
-        waitForServerEnabledValue(false);
-
-        Assert.assertFalse(isEnabledByServer());
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"OfflinePrefetchFeed"})
-    public void testPrefetchSinglePageSuccess_FullBrowser() throws Throwable {
-        doSetUp(/*isReducedMode=*/false);
-        doTestPrefetchSinglePageSuccess();
-
-        OfflineItem item1 = findItemByUrl(URL1);
-        Assert.assertNotNull(item1);
-        Bitmap visuals = findVisuals(item1.id);
-        Assert.assertNotNull(visuals);
-        Assert.assertEquals(THUMBNAIL_WIDTH, visuals.getWidth());
-        Assert.assertEquals(THUMBNAIL_HEIGHT, visuals.getHeight());
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"OfflinePrefetchFeed"})
-    @DisableIf.Device(type = {UiDisableIf.TABLET}) // https://crbug.com/1060685
-    public void testPrefetchPageReadyLater_FullBrowser() throws Throwable {
-        doSetUp(/*isReducedMode=*/false);
-        doTestPrefetchPageReadyLater();
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"OfflinePrefetchFeed"})
-    @DisableIf.Device(type = {UiDisableIf.TABLET}) // https://crbug.com/950749
-    public void testPrefetchForbiddenByServer_FullBrowser() throws Throwable {
-        doSetUp(/*isReducedMode=*/false);
-        doTestPrefetchForbiddenByServer();
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"OfflinePrefetchFeed"})
-    @DisableIf.Device(type = {UiDisableIf.TABLET}) // https://crbug.com/950749
-    public void testPrefetchBecomesEnabledByServer_FullBrowser() throws Throwable {
-        doSetUp(/*isReducedMode=*/false);
-        doTestPrefetchBecomesEnabledByServer();
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"OfflinePrefetchFeed"})
-    public void testPrefetchRemainsDisabledByServer_FullBrowser() throws Throwable {
-        doSetUp(/*isReducedMode=*/false);
-        doTestPrefetchRemainsDisabledByServer();
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"OfflinePrefetchFeed"})
-    public void testPrefetchSinglePageSuccess_ReducedMode() throws Throwable {
-        doSetUp(/*isReducedMode=*/true);
-        doTestPrefetchSinglePageSuccess();
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"OfflinePrefetchFeed"})
-    @DisableIf.Device(type = {UiDisableIf.TABLET}) // https://crbug.com/950749
-    public void testPrefetchForbiddenByServer_ReducedMode() throws Throwable {
-        doSetUp(/*isReducedMode=*/true);
-        doTestPrefetchForbiddenByServer();
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"OfflinePrefetchFeed"})
-    @DisableIf.Device(type = {UiDisableIf.TABLET}) // https://crbug.com/950749
-    public void testPrefetchBecomesEnabledByServer_ReducedMode() throws Throwable {
-        doSetUp(/*isReducedMode=*/true);
-        doTestPrefetchBecomesEnabledByServer();
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"OfflinePrefetchFeed"})
-    public void testPrefetchRemainsDisabledByServer_ReducedMode() throws Throwable {
-        doSetUp(/*isReducedMode=*/true);
-        doTestPrefetchRemainsDisabledByServer();
-    }
-}
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 ac4abfc9..899d4a6 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
@@ -38,7 +38,6 @@
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.FlakyTest;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.app.ChromeActivity;
 import org.chromium.chrome.browser.browsing_data.BrowsingDataBridge;
@@ -450,7 +449,6 @@
     @Test
     @MediumTest
     @Features.EnableFeatures(PageInfoFeatureList.PAGE_INFO_V2)
-    @FlakyTest(message = "https://crbug.com/1147236")
     public void testClearCookiesOnSubpage() throws Exception {
         sActivityTestRule.loadUrl(mTestServerRule.getServer().getURL(sSiteDataHtml));
         // Create cookies.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedActionHandlerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedActionHandlerTest.java
deleted file mode 100644
index 3e6d654..0000000
--- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedActionHandlerTest.java
+++ /dev/null
@@ -1,156 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.support.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestRule;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.robolectric.annotation.Config;
-
-import org.chromium.base.Callback;
-import org.chromium.base.test.BaseRobolectricTestRunner;
-import org.chromium.chrome.browser.feed.FeedV1ActionOptions;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.suggestions.SuggestionsNavigationDelegate;
-import org.chromium.chrome.browser.tab.TabImpl;
-import org.chromium.chrome.test.util.browser.Features;
-import org.chromium.content_public.browser.LoadUrlParams;
-import org.chromium.content_public.browser.NavigationController;
-import org.chromium.content_public.browser.WebContents;
-import org.chromium.content_public.browser.WebContentsObserver;
-import org.chromium.ui.mojom.WindowOpenDisposition;
-
-/**
- * Unit tests for {@link FeedActionHandler}.
- */
-@RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE)
-@Features.EnableFeatures(ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS)
-public class FeedActionHandlerTest {
-    private static final String TEST_URL = "http://www.one.com/";
-
-    @Rule
-    public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor();
-
-    @Mock
-    private SuggestionsNavigationDelegate mDelegate;
-    @Mock
-    private Runnable mSuggestionConsumedObserver;
-    @Mock
-    private FeedLoggingBridge mLoggingBridge;
-    @Mock
-    private TabImpl mTab;
-    @Mock
-    private WebContents mWebContents;
-    @Mock
-    private NavigationController mNavigationController;
-
-    @Captor
-    private ArgumentCaptor<Integer> mDispositionCapture;
-    @Captor
-    private ArgumentCaptor<LoadUrlParams> mLoadParamsCapture;
-    @Captor
-    private ArgumentCaptor<Callback<LoadUrlParams>> mLoadUrlParamsCallbackCaptor;
-    @Captor
-    ArgumentCaptor<WebContentsObserver> mWebContentsObserverCaptor;
-
-    int mLastCommittedEntryIndex;
-    private FeedActionHandler mActionHandler;
-
-    private void verifyOpenedOnline(int expectedDisposition) {
-        verify(mDelegate, times(1))
-                .openUrl(mDispositionCapture.capture(), mLoadParamsCapture.capture());
-        assertEquals((int) mDispositionCapture.getValue(), expectedDisposition);
-        assertEquals(null, mLoadParamsCapture.getValue().getVerbatimHeaders());
-        verify(mSuggestionConsumedObserver, times(1)).run();
-    }
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mActionHandler = new FeedActionHandler(new FeedV1ActionOptions(), mDelegate,
-                mSuggestionConsumedObserver, mLoggingBridge, null, null);
-
-        // Setup mocks such that when NavigationRecorder#record is called, it immediately invokes
-        // the passed callback.
-        when(mDelegate.openUrl(anyInt(), any(LoadUrlParams.class))).thenReturn(mTab);
-        when(mTab.getWebContents()).thenReturn(mWebContents);
-        when(mWebContents.getNavigationController()).thenReturn(mNavigationController);
-        when(mNavigationController.getLastCommittedEntryIndex())
-                .thenReturn(mLastCommittedEntryIndex++);
-        doAnswer((InvocationOnMock invocation) -> {
-            mWebContentsObserverCaptor.getValue().navigationEntryCommitted();
-            return null;
-        })
-                .when(mWebContents)
-                .addObserver(mWebContentsObserverCaptor.capture());
-    }
-
-    @Test
-    @SmallTest
-    public void testOpenUrlOnline() {
-        mActionHandler.openUrl(TEST_URL);
-        verifyOpenedOnline(WindowOpenDisposition.CURRENT_TAB);
-        verify(mLoggingBridge, times(1)).onContentTargetVisited(anyLong(), anyBoolean());
-    }
-
-    @Test
-    @SmallTest
-    public void testOpenUrlInIncognitoMode() {
-        mActionHandler.openUrlInIncognitoMode(TEST_URL);
-
-        // Even though this page has an offlined version, it should not be used because offline
-        // pages does not support incognito mode.
-        verifyOpenedOnline(WindowOpenDisposition.OFF_THE_RECORD);
-    }
-
-    @Test
-    @SmallTest
-    public void testOpenUrlInNewTabOnline() {
-        mActionHandler.openUrlInNewTab(TEST_URL);
-        verifyOpenedOnline(WindowOpenDisposition.NEW_BACKGROUND_TAB);
-        verify(mLoggingBridge, times(1)).onContentTargetVisited(anyLong(), anyBoolean());
-    }
-
-    @Test
-    @SmallTest
-    public void testOpenUrlInNewWindowOnline() {
-        mActionHandler.openUrlInNewWindow(TEST_URL);
-        verifyOpenedOnline(WindowOpenDisposition.NEW_WINDOW);
-        verify(mLoggingBridge, times(1)).onContentTargetVisited(anyLong(), anyBoolean());
-    }
-
-    @Test
-    @SmallTest
-    public void testOpenUrlNullTab() {
-        // If openUrl returns null, then the {@link NavigationRecorder} logic should be skipped.
-        reset(mDelegate);
-        when(mDelegate.openUrl(anyInt(), any(LoadUrlParams.class))).thenReturn(null);
-
-        mActionHandler.openUrl(TEST_URL);
-        verifyOpenedOnline(WindowOpenDisposition.CURRENT_TAB);
-        verify(mLoggingBridge, times(0)).onContentTargetVisited(anyLong(), anyBoolean());
-    }
-}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedApplicationInfoTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedApplicationInfoTest.java
deleted file mode 100644
index 030f867..0000000
--- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedApplicationInfoTest.java
+++ /dev/null
@@ -1,73 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import static org.junit.Assert.assertEquals;
-
-import android.support.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.annotation.Config;
-
-import org.chromium.base.BuildInfo;
-import org.chromium.base.test.BaseRobolectricTestRunner;
-import org.chromium.chrome.browser.feed.library.api.host.config.ApplicationInfo;
-import org.chromium.components.version_info.Channel;
-import org.chromium.components.version_info.VersionConstants;
-
-/** Unit tests for {@link FeedApplicationInfo}. */
-@RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE)
-public class FeedApplicationInfoTest {
-    @Test
-    @SmallTest
-    public void testGetArchitecture() {
-        assertEquals(
-                ApplicationInfo.Architecture.MIPS, FeedApplicationInfo.getArchitecture("mips"));
-        assertEquals(
-                ApplicationInfo.Architecture.MIPS64, FeedApplicationInfo.getArchitecture("mips64"));
-        assertEquals(
-                ApplicationInfo.Architecture.ARM, FeedApplicationInfo.getArchitecture("armeabi"));
-        assertEquals(ApplicationInfo.Architecture.ARM,
-                FeedApplicationInfo.getArchitecture("armeabi-v7a"));
-        assertEquals(ApplicationInfo.Architecture.ARM64,
-                FeedApplicationInfo.getArchitecture("arm64-v8a"));
-        assertEquals(ApplicationInfo.Architecture.X86, FeedApplicationInfo.getArchitecture("x86"));
-        assertEquals(
-                ApplicationInfo.Architecture.X86_64, FeedApplicationInfo.getArchitecture("x86_64"));
-        assertEquals(ApplicationInfo.Architecture.UNKNOWN_ACHITECTURE,
-                FeedApplicationInfo.getArchitecture("notarealthing"));
-    }
-
-    @Test
-    @SmallTest
-    public void testGetBuildType() {
-        assertEquals(ApplicationInfo.BuildType.RELEASE,
-                FeedApplicationInfo.getBuildType(Channel.STABLE));
-        assertEquals(
-                ApplicationInfo.BuildType.BETA, FeedApplicationInfo.getBuildType(Channel.BETA));
-        assertEquals(
-                ApplicationInfo.BuildType.ALPHA, FeedApplicationInfo.getBuildType(Channel.DEV));
-        assertEquals(
-                ApplicationInfo.BuildType.DEV, FeedApplicationInfo.getBuildType(Channel.CANARY));
-        assertEquals(ApplicationInfo.BuildType.UNKNOWN_BUILD_TYPE,
-                FeedApplicationInfo.getBuildType(Channel.DEFAULT));
-        assertEquals(ApplicationInfo.BuildType.UNKNOWN_BUILD_TYPE,
-                FeedApplicationInfo.getBuildType(Channel.UNKNOWN));
-    }
-
-    @Test
-    @SmallTest
-    public void testcreateApplicationInfo() {
-        ApplicationInfo info = FeedApplicationInfo.createApplicationInfo();
-        assertEquals(ApplicationInfo.AppType.CHROME, info.getAppType());
-        assertEquals(FeedApplicationInfo.getArchitecture(BuildInfo.getInstance().abiString),
-                info.getArchitecture());
-        assertEquals(
-                FeedApplicationInfo.getBuildType(VersionConstants.CHANNEL), info.getBuildType());
-        // Don't test version, it isn't set correctly for unit tests.
-    }
-}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedContentStorageTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedContentStorageTest.java
deleted file mode 100644
index ee431ee8..0000000
--- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedContentStorageTest.java
+++ /dev/null
@@ -1,273 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.support.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.robolectric.annotation.Config;
-
-import org.chromium.base.Callback;
-import org.chromium.base.Consumer;
-import org.chromium.base.test.BaseRobolectricTestRunner;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.ContentMutation;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.profiles.Profile;
-
-import java.nio.charset.Charset;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Unit tests for {@link FeedContentStorage}.
- */
-@RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE)
-public class FeedContentStorageTest {
-    public static final String CONTENT_KEY1 = "CONTENT_KEY_1";
-    public static final String CONTENT_KEY2 = "CONTENT_KEY_2";
-    public static final String CONTENT_KEY3 = "CONTENT_KEY_3";
-    public static final byte[] CONTENT_DATA1 = "CONTENT_DATA_1".getBytes(Charset.forName("UTF-8"));
-    public static final byte[] CONTENT_DATA2 = "CONTENT_DATA_2".getBytes(Charset.forName("UTF-8"));
-    public static final byte[] CONTENT_DATA3 = "CONTENT_DATA_3".getBytes(Charset.forName("UTF-8"));
-
-    @Mock
-    private FeedContentBridge mBridge;
-    @Mock
-    private Consumer<CommitResult> mBooleanConsumer;
-    @Mock
-    private Consumer<Result<List<String>>> mListConsumer;
-    @Mock
-    private Consumer<Result<Map<String, byte[]>>> mMapConsumer;
-    @Mock
-    private Profile mProfile;
-    @Captor
-    private ArgumentCaptor<CommitResult> mCommitResultCaptor;
-    @Captor
-    private ArgumentCaptor<Result<List<String>>> mStringListCaptor;
-    @Captor
-    private ArgumentCaptor<Result<Map<String, byte[]>>> mMapCaptor;
-    @Captor
-    private ArgumentCaptor<String> mStringArgument;
-    @Captor
-    private ArgumentCaptor<List<String>> mStringListArgument;
-    @Captor
-    private ArgumentCaptor<ContentMutation> mContentMutationArgument;
-    @Captor
-    private ArgumentCaptor<byte[][]> mByteArrayOfArrayArgument;
-    @Captor
-    private ArgumentCaptor<Callback<Boolean>> mBooleanCallbackArgument;
-    @Captor
-    private ArgumentCaptor<Callback<String[]>> mArrayOfStringSuccessCallbackArgument;
-    @Captor
-    private ArgumentCaptor<Callback<Map<String, byte[]>>> mMapSuccessCallbackArgument;
-    @Captor
-    private ArgumentCaptor<Callback<Void>> mFailureCallbackArgument;
-
-    private FeedContentStorage mContentStorage;
-
-    private Answer<Void> createMapSuccessAnswer(Map<String, byte[]> map) {
-        return new Answer<Void>() {
-            @Override
-            public Void answer(InvocationOnMock invocation) {
-                mMapSuccessCallbackArgument.getValue().onResult(map);
-                return null;
-            }
-        };
-    }
-
-    private Answer<Void> createFailureAnswer() {
-        return new Answer<Void>() {
-            @Override
-            public Void answer(InvocationOnMock invocation) {
-                mFailureCallbackArgument.getValue().onResult(null);
-                return null;
-            }
-        };
-    }
-
-    private Answer<Void> createArrayOfStringSuccessAnswer(String[] arrayOfString) {
-        return new Answer<Void>() {
-            @Override
-            public Void answer(InvocationOnMock invocation) {
-                mArrayOfStringSuccessCallbackArgument.getValue().onResult(arrayOfString);
-                return null;
-            }
-        };
-    }
-
-    private Answer<Void> createBooleanAnswer(Boolean bool) {
-        return new Answer<Void>() {
-            @Override
-            public Void answer(InvocationOnMock invocation) {
-                mBooleanCallbackArgument.getValue().onResult(bool);
-                return null;
-            }
-        };
-    }
-
-    private void verifyMapResult(Map<String, byte[]> expectedMap, boolean expectedBoolean,
-            Result<Map<String, byte[]>> actualResult) {
-        assertEquals(expectedBoolean, actualResult.isSuccessful());
-        if (!expectedBoolean) return;
-
-        Map<String, byte[]> actualMap = actualResult.getValue();
-        assertEquals(expectedMap.size(), actualMap.size());
-        for (Map.Entry<String, byte[]> entry : expectedMap.entrySet()) {
-            assertTrue(actualMap.containsKey(entry.getKey()));
-            assertEquals(entry.getValue(), actualMap.get(entry.getKey()));
-        }
-    }
-
-    private void verifyArrayOfStringResult(
-            String[] expectedArray, boolean expectedBoolean, Result<List<String>> actualResult) {
-        assertEquals(expectedBoolean, actualResult.isSuccessful());
-        if (!expectedBoolean) return;
-
-        List<String> expectedList = Arrays.asList(expectedArray);
-        List<String> actualList = actualResult.getValue();
-        assertEquals(expectedList.size(), actualList.size());
-        for (String expectedString : expectedList) {
-            assertTrue(actualList.contains(expectedString));
-        }
-    }
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContentStorage = new FeedContentStorage(mBridge);
-    }
-
-    @Test
-    @SmallTest
-    public void getTest() {
-        Map<String, byte[]> answerMap = new HashMap<>();
-        answerMap.put(CONTENT_KEY1, CONTENT_DATA1);
-        Answer<Void> answer = createMapSuccessAnswer(answerMap);
-        doAnswer(answer).when(mBridge).loadContent(mStringListArgument.capture(),
-                mMapSuccessCallbackArgument.capture(), mFailureCallbackArgument.capture());
-        List<String> keys = Arrays.asList(CONTENT_KEY1, CONTENT_KEY2);
-
-        mContentStorage.get(keys, mMapConsumer);
-        verify(mBridge, times(1))
-                .loadContent(eq(keys), mMapSuccessCallbackArgument.capture(),
-                        mFailureCallbackArgument.capture());
-        verify(mMapConsumer, times(1)).accept(mMapCaptor.capture());
-        verifyMapResult(answerMap, true, mMapCaptor.getValue());
-    }
-
-    @Test
-    @SmallTest
-    public void getFailureTest() {
-        Map<String, byte[]> answerMap = new HashMap<>();
-        Answer<Void> answer = createFailureAnswer();
-        doAnswer(answer).when(mBridge).loadContent(mStringListArgument.capture(),
-                mMapSuccessCallbackArgument.capture(), mFailureCallbackArgument.capture());
-        List<String> keys = Arrays.asList(CONTENT_KEY1, CONTENT_KEY2);
-
-        mContentStorage.get(keys, mMapConsumer);
-        verify(mBridge, times(1))
-                .loadContent(eq(keys), mMapSuccessCallbackArgument.capture(),
-                        mFailureCallbackArgument.capture());
-        verify(mMapConsumer, times(1)).accept(mMapCaptor.capture());
-        verifyMapResult(answerMap, false, mMapCaptor.getValue());
-    }
-
-    @Test
-    @SmallTest
-    public void getAllTest() {
-        Map<String, byte[]> answerMap = new HashMap<>();
-        answerMap.put(CONTENT_KEY1, CONTENT_DATA1);
-        answerMap.put(CONTENT_KEY2, CONTENT_DATA2);
-        answerMap.put(CONTENT_KEY3, CONTENT_DATA3);
-        Answer<Void> answer = createMapSuccessAnswer(answerMap);
-        doAnswer(answer).when(mBridge).loadContentByPrefix(mStringArgument.capture(),
-                mMapSuccessCallbackArgument.capture(), mFailureCallbackArgument.capture());
-
-        mContentStorage.getAll(CONTENT_KEY1, mMapConsumer);
-        verify(mBridge, times(1))
-                .loadContentByPrefix(eq(CONTENT_KEY1), mMapSuccessCallbackArgument.capture(),
-                        mFailureCallbackArgument.capture());
-        verify(mMapConsumer, times(1)).accept(mMapCaptor.capture());
-        verifyMapResult(answerMap, true, mMapCaptor.getValue());
-    }
-
-    @Test
-    @SmallTest
-    public void getAllKeysTest() {
-        String[] answerStrings = {CONTENT_KEY1, CONTENT_KEY2, CONTENT_KEY3};
-        Answer<Void> answer = createArrayOfStringSuccessAnswer(answerStrings);
-        doAnswer(answer).when(mBridge).loadAllContentKeys(
-                mArrayOfStringSuccessCallbackArgument.capture(),
-                mFailureCallbackArgument.capture());
-
-        mContentStorage.getAllKeys(mListConsumer);
-        verify(mBridge, times(1))
-                .loadAllContentKeys(mArrayOfStringSuccessCallbackArgument.capture(),
-                        mFailureCallbackArgument.capture());
-        verify(mListConsumer, times(1)).accept(mStringListCaptor.capture());
-        verifyArrayOfStringResult(answerStrings, true, mStringListCaptor.getValue());
-    }
-
-    @Test
-    @SmallTest
-    public void getAllKeysFailureTest() {
-        String[] answerStrings = {CONTENT_KEY1, CONTENT_KEY2, CONTENT_KEY3};
-        Answer<Void> answer = createFailureAnswer();
-        doAnswer(answer).when(mBridge).loadAllContentKeys(
-                mArrayOfStringSuccessCallbackArgument.capture(),
-                mFailureCallbackArgument.capture());
-
-        mContentStorage.getAllKeys(mListConsumer);
-        verify(mBridge, times(1))
-                .loadAllContentKeys(mArrayOfStringSuccessCallbackArgument.capture(),
-                        mFailureCallbackArgument.capture());
-        verify(mListConsumer, times(1)).accept(mStringListCaptor.capture());
-        verifyArrayOfStringResult(answerStrings, false, mStringListCaptor.getValue());
-    }
-
-    @Test
-    @SmallTest
-    public void commitTest() {
-        Answer<Void> answerCommitContent = createBooleanAnswer(true);
-        doAnswer(answerCommitContent)
-                .when(mBridge)
-                .commitContentMutation(
-                        mContentMutationArgument.capture(), mBooleanCallbackArgument.capture());
-
-        mContentStorage.commit(new ContentMutation.Builder()
-                                       .upsert(CONTENT_KEY1, CONTENT_DATA1)
-                                       .delete(CONTENT_KEY2)
-                                       .deleteByPrefix(CONTENT_KEY3)
-                                       .deleteAll()
-                                       .build(),
-                mBooleanConsumer);
-        verify(mBridge, times(1))
-                .commitContentMutation(
-                        mContentMutationArgument.capture(), mBooleanCallbackArgument.capture());
-
-        verify(mBooleanConsumer, times(1)).accept(mCommitResultCaptor.capture());
-        CommitResult commitResult = mCommitResultCaptor.getValue();
-        assertEquals(CommitResult.SUCCESS, commitResult);
-    }
-}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedImageLoaderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedImageLoaderTest.java
deleted file mode 100644
index c539b628..0000000
--- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedImageLoaderTest.java
+++ /dev/null
@@ -1,276 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.graphics.Bitmap;
-import android.graphics.drawable.Drawable;
-import android.support.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.AdditionalMatchers;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.robolectric.annotation.Config;
-
-import org.chromium.base.Callback;
-import org.chromium.base.Consumer;
-import org.chromium.base.ContextUtils;
-import org.chromium.base.test.BaseRobolectricTestRunner;
-import org.chromium.chrome.browser.feed.library.api.host.imageloader.BundledAssets;
-import org.chromium.chrome.browser.feed.library.api.host.imageloader.ImageLoaderApi;
-import org.chromium.chrome.browser.image_fetcher.CachedImageFetcher;
-
-import java.util.Arrays;
-
-/**
- * Unit tests for {@link FeedImageLoader}.
- */
-@RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE)
-public class FeedImageLoaderTest {
-    private static final String HTTP_STRING1 = "http://www.test1.com";
-    private static final String HTTP_STRING2 = "http://www.test2.com";
-    private static final String HTTP_STRING3 = "http://www.test3.com";
-
-    private static final String ASSET_PREFIX = "asset://";
-    private static final String OFFLINE_ASSET_STRING =
-            ASSET_PREFIX + BundledAssets.OFFLINE_INDICATOR_BADGE;
-    private static final String VIDEO_ASSET_STRING =
-            ASSET_PREFIX + BundledAssets.VIDEO_INDICATOR_BADGE;
-    private static final String BAD_ASSET_STRING = ASSET_PREFIX + "does_not_exist";
-
-    private static final String OVERLAY_IMAGE_START =
-            "overlay-image://?direction=start&url=http://www.test1.com";
-    private static final String OVERLAY_IMAGE_END =
-            "overlay-image://?direction=end&url=http://www.test1.com";
-    private static final String OVERLAY_IMAGE_MISSING_URL = "overlay-image://?direction=end";
-    private static final String OVERLAY_IMAGE_MISSING_DIRECTION =
-            "overlay-image://?url=http://www.test1.com";
-    private static final String OVERLAY_IMAGE_BAD_DIRECTION =
-            "overlay-image://?direction=east&url=http://www.test1.com";
-
-    @Mock
-    CachedImageFetcher mCachedImageFetcher;
-    @Mock
-    private Consumer<Drawable> mConsumer;
-    @Mock
-    private Bitmap mBitmap;
-    @Captor
-    ArgumentCaptor<Integer> mWidthPxCaptor;
-    @Captor
-    ArgumentCaptor<Integer> mHeightPxCaptor;
-    @Captor
-    ArgumentCaptor<Callback<Bitmap>> mCallbackArgument;
-
-    private FeedImageLoader mImageLoader;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        setUpWithImageFetcher(mCachedImageFetcher);
-    }
-
-    public void setUpWithImageFetcher(CachedImageFetcher cachedImageFetcher) {
-        mImageLoader = Mockito.spy(
-                new FeedImageLoader(ContextUtils.getApplicationContext(), cachedImageFetcher));
-    }
-
-    private void answerFetchImage(String url, Bitmap bitmap) {
-        doAnswer((InvocationOnMock invocation) -> {
-            mCallbackArgument.getValue().onResult(bitmap);
-            return null;
-        })
-                .when(mImageLoader)
-                .fetchImage(eq(url), mWidthPxCaptor.capture(), mHeightPxCaptor.capture(),
-                        mCallbackArgument.capture());
-    }
-
-    private void loadDrawable(int widthPx, int heightPx, String... urls) {
-        // While normally {@link FeedImageLoader#loadDrawable} guarantees that the return callback
-        // is invoked asynchronously, this is not the case in tests. It seems that both
-        // {@link FeedImageLoaderTest#answerFetchImage}, {@link AndroidThreadUtils.postOnUiThread}
-        // run synchronously.
-        mImageLoader.loadDrawable(Arrays.asList(urls), widthPx, heightPx, mConsumer);
-    }
-
-    private void loadDrawable(String... urls) {
-        loadDrawable(ImageLoaderApi.DIMENSION_UNKNOWN, ImageLoaderApi.DIMENSION_UNKNOWN, urls);
-    }
-
-    @Test
-    @SmallTest
-    public void testLoadDrawable() {
-        answerFetchImage(HTTP_STRING1, mBitmap);
-
-        loadDrawable(100, 200, HTTP_STRING1);
-
-        verify(mImageLoader, times(1)).fetchImage(eq(HTTP_STRING1), eq(100), eq(200), any());
-        verify(mConsumer, times(1)).accept(AdditionalMatchers.not(eq(null)));
-    }
-
-    @Test
-    @SmallTest
-    public void testLoadDrawableFailure() {
-        answerFetchImage(HTTP_STRING1, null);
-
-        loadDrawable(HTTP_STRING1);
-
-        verify(mImageLoader, times(1))
-                .fetchImage(eq(HTTP_STRING1), eq(ImageLoaderApi.DIMENSION_UNKNOWN),
-                        eq(ImageLoaderApi.DIMENSION_UNKNOWN), any());
-        verify(mConsumer, times(1)).accept(eq(null));
-    }
-
-    @Test
-    @SmallTest
-    public void testLoadDrawableWithNullFetcher() {
-        setUpWithImageFetcher(null);
-        loadDrawable(HTTP_STRING1);
-        verify(mConsumer, times(1)).accept(eq(null));
-        verify(mImageLoader, times(0))
-                .fetchImage(eq(HTTP_STRING1), eq(ImageLoaderApi.DIMENSION_UNKNOWN),
-                        eq(ImageLoaderApi.DIMENSION_UNKNOWN), any());
-    }
-
-    @Test
-    @SmallTest
-    public void testLoadDrawableMultiple() {
-        answerFetchImage(HTTP_STRING1, null);
-        answerFetchImage(HTTP_STRING2, mBitmap);
-
-        loadDrawable(HTTP_STRING1, HTTP_STRING2, HTTP_STRING3);
-
-        verify(mImageLoader, times(1))
-                .fetchImage(eq(HTTP_STRING1), eq(ImageLoaderApi.DIMENSION_UNKNOWN),
-                        eq(ImageLoaderApi.DIMENSION_UNKNOWN), any());
-        verify(mImageLoader, times(1))
-                .fetchImage(eq(HTTP_STRING2), eq(ImageLoaderApi.DIMENSION_UNKNOWN),
-                        eq(ImageLoaderApi.DIMENSION_UNKNOWN), any());
-        verify(mImageLoader, times(0))
-                .fetchImage(eq(HTTP_STRING3), eq(ImageLoaderApi.DIMENSION_UNKNOWN),
-                        eq(ImageLoaderApi.DIMENSION_UNKNOWN), any());
-        verify(mConsumer, times(1)).accept(AdditionalMatchers.not(eq(null)));
-    }
-
-    @Test
-    @SmallTest
-    public void testLoadOfflineBadge() {
-        loadDrawable(OFFLINE_ASSET_STRING);
-        verify(mConsumer, times(1)).accept(AdditionalMatchers.not(eq(null)));
-    }
-
-    @Test
-    @SmallTest
-    public void testLoadVideoBadge() {
-        loadDrawable(VIDEO_ASSET_STRING);
-        verify(mConsumer, times(1)).accept(AdditionalMatchers.not(eq(null)));
-    }
-
-    @Test
-    @SmallTest
-    public void testLoadDrawableMissingAsset() {
-        loadDrawable(BAD_ASSET_STRING);
-        verify(mConsumer, times(1)).accept(eq(null));
-    }
-
-    @Test
-    @SmallTest
-    public void testLoadDrawableAssetFallback() {
-        loadDrawable(BAD_ASSET_STRING, OFFLINE_ASSET_STRING);
-        verify(mConsumer, times(1)).accept(AdditionalMatchers.not(eq(null)));
-    }
-
-    @Test
-    @SmallTest
-    public void testLoadDrawableAssetFirst() {
-        loadDrawable(VIDEO_ASSET_STRING, HTTP_STRING1);
-        verify(mImageLoader, times(0))
-                .fetchImage(eq(HTTP_STRING1), eq(ImageLoaderApi.DIMENSION_UNKNOWN),
-                        eq(ImageLoaderApi.DIMENSION_UNKNOWN), any());
-        verify(mConsumer, times(1)).accept(AdditionalMatchers.not(eq(null)));
-    }
-
-    @Test
-    @SmallTest
-    public void testLoadDrawableEmptyList() {
-        loadDrawable();
-        verify(mImageLoader, times(0)).fetchImage(any(), anyInt(), anyInt(), any());
-        verify(mConsumer, times(1)).accept(eq(null));
-    }
-
-    @Test
-    @SmallTest
-    public void testLoadDrawableOverlay_Start() {
-        answerFetchImage(HTTP_STRING1, mBitmap);
-
-        loadDrawable(OVERLAY_IMAGE_START);
-
-        verify(mImageLoader, times(1))
-                .fetchImage(eq(HTTP_STRING1), eq(ImageLoaderApi.DIMENSION_UNKNOWN),
-                        eq(ImageLoaderApi.DIMENSION_UNKNOWN), mCallbackArgument.capture());
-        verify(mConsumer, times(1)).accept(AdditionalMatchers.not(eq(null)));
-    }
-
-    @Test
-    @SmallTest
-    public void testLoadDrawableOverlay_End() {
-        answerFetchImage(HTTP_STRING1, mBitmap);
-
-        loadDrawable(OVERLAY_IMAGE_END);
-
-        verify(mImageLoader, times(1))
-                .fetchImage(eq(HTTP_STRING1), eq(ImageLoaderApi.DIMENSION_UNKNOWN),
-                        eq(ImageLoaderApi.DIMENSION_UNKNOWN), mCallbackArgument.capture());
-        verify(mConsumer, times(1)).accept(AdditionalMatchers.not(eq(null)));
-    }
-
-    @Test(expected = AssertionError.class)
-    @SmallTest
-    public void testLoadDrawableOverlay_MissingUrl() {
-        loadDrawable(OVERLAY_IMAGE_MISSING_URL);
-    }
-
-    @Test
-    @SmallTest
-    public void testLoadDrawableOverlay_Fallback() {
-        answerFetchImage(HTTP_STRING1, null);
-        answerFetchImage(HTTP_STRING2, mBitmap);
-
-        loadDrawable(OVERLAY_IMAGE_END, HTTP_STRING2);
-
-        verify(mImageLoader, times(1))
-                .fetchImage(eq(HTTP_STRING1), eq(ImageLoaderApi.DIMENSION_UNKNOWN),
-                        eq(ImageLoaderApi.DIMENSION_UNKNOWN), mCallbackArgument.capture());
-        verify(mImageLoader, times(1))
-                .fetchImage(eq(HTTP_STRING2), eq(ImageLoaderApi.DIMENSION_UNKNOWN),
-                        eq(ImageLoaderApi.DIMENSION_UNKNOWN), mCallbackArgument.capture());
-        verify(mConsumer, times(1)).accept(AdditionalMatchers.not(eq(null)));
-    }
-
-    @Test(expected = AssertionError.class)
-    @SmallTest
-    public void testLoadDrawableOverlay_MissingDirection() {
-        loadDrawable(OVERLAY_IMAGE_MISSING_DIRECTION);
-    }
-
-    @Test(expected = AssertionError.class)
-    @SmallTest
-    public void overlayImageTest_BadDirection() {
-        loadDrawable(OVERLAY_IMAGE_BAD_DIRECTION);
-    }
-}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorageTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorageTest.java
deleted file mode 100644
index f50f4ba1..0000000
--- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedJournalStorageTest.java
+++ /dev/null
@@ -1,298 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.support.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.robolectric.annotation.Config;
-
-import org.chromium.base.Callback;
-import org.chromium.base.Consumer;
-import org.chromium.base.test.BaseRobolectricTestRunner;
-import org.chromium.chrome.browser.feed.library.api.host.storage.CommitResult;
-import org.chromium.chrome.browser.feed.library.api.host.storage.JournalMutation;
-import org.chromium.chrome.browser.feed.library.common.Result;
-import org.chromium.chrome.browser.profiles.Profile;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Unit tests for {@link FeedJournalStorage}.
- */
-@RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE)
-public class FeedJournalStorageTest {
-    public static final String JOURNAL_KEY1 = "JOURNAL_KEY_1";
-    public static final String JOURNAL_KEY2 = "JOURNAL_KEY_2";
-    public static final String JOURNAL_KEY3 = "JOURNAL_KEY_3";
-    public static final byte[] JOURNAL_DATA1 = {24, -119, -10, -71, -35, 5};
-    public static final byte[] JOURNAL_DATA2 = {8, 3, 18, 53, 70, 69, 65, 84, 85, 82, 69};
-    public static final byte[] JOURNAL_DATA3 = {54, 55, 56, 48, 51, 57, 24, -119, -10};
-
-    @Mock
-    private FeedJournalBridge mBridge;
-    @Mock
-    private Consumer<CommitResult> mCommitResultConsumer;
-    @Mock
-    private Consumer<Result<Boolean>> mBooleanConsumer;
-    @Mock
-    private Consumer<Result<List<byte[]>>> mListOfByteArrayConsumer;
-    @Mock
-    private Consumer<Result<List<String>>> mListOfStringConsumer;
-    @Mock
-    private Profile mProfile;
-    @Captor
-    private ArgumentCaptor<CommitResult> mCommitResultCaptor;
-    @Captor
-    private ArgumentCaptor<Result<Boolean>> mBooleanCaptor;
-    @Captor
-    private ArgumentCaptor<Result<List<String>>> mListOfStringCaptor;
-    @Captor
-    private ArgumentCaptor<Result<List<byte[]>>> mListOfByteArrayCaptor;
-    @Captor
-    private ArgumentCaptor<String> mStringArgument;
-    @Captor
-    private ArgumentCaptor<Callback<Boolean>> mBooleanSuccessCallbackArgument;
-    @Captor
-    private ArgumentCaptor<Callback<byte[][]>> mArrayOfByteArraySuccessCallbackArgument;
-    @Captor
-    private ArgumentCaptor<Callback<String[]>> mStringArraySuccessCallbackArgument;
-    @Captor
-    private ArgumentCaptor<Callback<Void>> mFailureCallbackArgument;
-    @Captor
-    private ArgumentCaptor<JournalMutation> mJournalMutationArgument;
-
-    private FeedJournalStorage mJournalStorage;
-
-    private Answer<Void> createArrayOfByteArraySuccessAnswer(byte[][] arrayOfByteArray) {
-        return new Answer<Void>() {
-            @Override
-            public Void answer(InvocationOnMock invocation) {
-                mArrayOfByteArraySuccessCallbackArgument.getValue().onResult(arrayOfByteArray);
-                return null;
-            }
-        };
-    }
-
-    private Answer<Void> createStringArraySuccessAnswer(String[] stringArray) {
-        return new Answer<Void>() {
-            @Override
-            public Void answer(InvocationOnMock invocation) {
-                mStringArraySuccessCallbackArgument.getValue().onResult(stringArray);
-                return null;
-            }
-        };
-    }
-
-    private Answer<Void> createFailureAnswer() {
-        return new Answer<Void>() {
-            @Override
-            public Void answer(InvocationOnMock invocation) {
-                mFailureCallbackArgument.getValue().onResult(null);
-                return null;
-            }
-        };
-    }
-
-    private Answer<Void> createBooleanSuccessAnswer(Boolean bool) {
-        return new Answer<Void>() {
-            @Override
-            public Void answer(InvocationOnMock invocation) {
-                mBooleanSuccessCallbackArgument.getValue().onResult(bool);
-                return null;
-            }
-        };
-    }
-
-    private void verifyListOfBytesResult(
-            List<byte[]> expectedList, Result<List<byte[]>> actualResult) {
-        List<byte[]> actualList = actualResult.getValue();
-        assertEquals(expectedList.size(), actualList.size());
-        for (byte[] actualString : actualList) {
-            boolean foundSame = false;
-            for (byte[] expectedBytes : expectedList) {
-                if (Arrays.equals(expectedBytes, actualString)) {
-                    foundSame = true;
-                    break;
-                }
-            }
-            assertTrue(foundSame);
-        }
-    }
-
-    private void verifyListOfStringResult(
-            String[] expectedStrings, boolean expectedSuccess, Result<List<String>> actualResult) {
-        assertEquals(expectedSuccess, actualResult.isSuccessful());
-        if (!expectedSuccess) return;
-
-        List<String> actualList = actualResult.getValue();
-        assertEquals(expectedStrings.length, actualList.size());
-        for (String expectedString : expectedStrings) {
-            assertTrue(actualList.contains(expectedString));
-        }
-    }
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mJournalStorage = new FeedJournalStorage(mBridge);
-    }
-
-    @Test
-    @SmallTest
-    public void readTest() {
-        byte[][] answerStrings = {JOURNAL_DATA1, JOURNAL_DATA2, JOURNAL_DATA3};
-        Answer<Void> answer = createArrayOfByteArraySuccessAnswer(answerStrings);
-        doAnswer(answer).when(mBridge).loadJournal(mStringArgument.capture(),
-                mArrayOfByteArraySuccessCallbackArgument.capture(),
-                mFailureCallbackArgument.capture());
-
-        mJournalStorage.read(JOURNAL_KEY1, mListOfByteArrayConsumer);
-        verify(mBridge, times(1))
-                .loadJournal(eq(JOURNAL_KEY1), mArrayOfByteArraySuccessCallbackArgument.capture(),
-                        mFailureCallbackArgument.capture());
-        verify(mListOfByteArrayConsumer, times(1)).accept(mListOfByteArrayCaptor.capture());
-        assertEquals(true, mListOfByteArrayCaptor.getValue().isSuccessful());
-        List<byte[]> expectedStrings = new ArrayList<byte[]>();
-        expectedStrings.add(JOURNAL_DATA1);
-        expectedStrings.add(JOURNAL_DATA2);
-        expectedStrings.add(JOURNAL_DATA3);
-        verifyListOfBytesResult(expectedStrings, mListOfByteArrayCaptor.getValue());
-    }
-
-    @Test
-    @SmallTest
-    public void readFailureTest() {
-        byte[][] answerStrings = {};
-        Answer<Void> answer = createFailureAnswer();
-        doAnswer(answer).when(mBridge).loadJournal(mStringArgument.capture(),
-                mArrayOfByteArraySuccessCallbackArgument.capture(),
-                mFailureCallbackArgument.capture());
-
-        mJournalStorage.read(JOURNAL_KEY1, mListOfByteArrayConsumer);
-        verify(mBridge, times(1))
-                .loadJournal(eq(JOURNAL_KEY1), mArrayOfByteArraySuccessCallbackArgument.capture(),
-                        mFailureCallbackArgument.capture());
-        verify(mListOfByteArrayConsumer, times(1)).accept(mListOfByteArrayCaptor.capture());
-        assertEquals(false, mListOfByteArrayCaptor.getValue().isSuccessful());
-    }
-
-    @Test
-    @SmallTest
-    public void existsTest() {
-        Answer<Void> answer = createBooleanSuccessAnswer(true);
-        doAnswer(answer).when(mBridge).doesJournalExist(mStringArgument.capture(),
-                mBooleanSuccessCallbackArgument.capture(), mFailureCallbackArgument.capture());
-
-        mJournalStorage.exists(JOURNAL_KEY1, mBooleanConsumer);
-        verify(mBridge, times(1))
-                .doesJournalExist(eq(JOURNAL_KEY1), mBooleanSuccessCallbackArgument.capture(),
-                        mFailureCallbackArgument.capture());
-        verify(mBooleanConsumer, times(1)).accept(mBooleanCaptor.capture());
-        assertTrue(mBooleanCaptor.getValue().getValue());
-    }
-
-    @Test
-    @SmallTest
-    public void existsFailureTest() {
-        Answer<Void> answer = createFailureAnswer();
-        doAnswer(answer).when(mBridge).doesJournalExist(mStringArgument.capture(),
-                mBooleanSuccessCallbackArgument.capture(), mFailureCallbackArgument.capture());
-
-        mJournalStorage.exists(JOURNAL_KEY1, mBooleanConsumer);
-        verify(mBridge, times(1))
-                .doesJournalExist(eq(JOURNAL_KEY1), mBooleanSuccessCallbackArgument.capture(),
-                        mFailureCallbackArgument.capture());
-        verify(mBooleanConsumer, times(1)).accept(mBooleanCaptor.capture());
-        assertFalse(mBooleanCaptor.getValue().isSuccessful());
-    }
-
-    @Test
-    @SmallTest
-    public void getAllJournalsTest() {
-        String[] answerStrings = {JOURNAL_KEY1, JOURNAL_KEY2, JOURNAL_KEY3};
-        Answer<Void> answer = createStringArraySuccessAnswer(answerStrings);
-        doAnswer(answer).when(mBridge).loadAllJournalKeys(
-                mStringArraySuccessCallbackArgument.capture(), mFailureCallbackArgument.capture());
-
-        mJournalStorage.getAllJournals(mListOfStringConsumer);
-        verify(mBridge, times(1))
-                .loadAllJournalKeys(mStringArraySuccessCallbackArgument.capture(),
-                        mFailureCallbackArgument.capture());
-        verify(mListOfStringConsumer, times(1)).accept(mListOfStringCaptor.capture());
-        verifyListOfStringResult(answerStrings, true, mListOfStringCaptor.getValue());
-    }
-
-    @Test
-    @SmallTest
-    public void getAllJournalsFailureTest() {
-        Answer<Void> answer = createFailureAnswer();
-        doAnswer(answer).when(mBridge).loadAllJournalKeys(
-                mStringArraySuccessCallbackArgument.capture(), mFailureCallbackArgument.capture());
-
-        mJournalStorage.getAllJournals(mListOfStringConsumer);
-        verify(mBridge, times(1))
-                .loadAllJournalKeys(mStringArraySuccessCallbackArgument.capture(),
-                        mFailureCallbackArgument.capture());
-        verify(mListOfStringConsumer, times(1)).accept(mListOfStringCaptor.capture());
-        assertFalse(mListOfStringCaptor.getValue().isSuccessful());
-    }
-
-    @Test
-    @SmallTest
-    public void deleteAllTest() {
-        Answer<Void> answer = createBooleanSuccessAnswer(true);
-        doAnswer(answer).when(mBridge).deleteAllJournals(mBooleanSuccessCallbackArgument.capture());
-
-        mJournalStorage.deleteAll(mCommitResultConsumer);
-        verify(mBridge, times(1)).deleteAllJournals(mBooleanSuccessCallbackArgument.capture());
-        verify(mCommitResultConsumer, times(1)).accept(mCommitResultCaptor.capture());
-        CommitResult commitResult = mCommitResultCaptor.getValue();
-        assertEquals(CommitResult.SUCCESS, commitResult);
-    }
-
-    @Test
-    @SmallTest
-    public void commitTest() {
-        Answer<Void> answerCommitJournal = createBooleanSuccessAnswer(true);
-        doAnswer(answerCommitJournal)
-                .when(mBridge)
-                .commitJournalMutation(mJournalMutationArgument.capture(),
-                        mBooleanSuccessCallbackArgument.capture());
-
-        mJournalStorage.commit(new JournalMutation.Builder(JOURNAL_KEY1)
-                                       .append(JOURNAL_DATA1)
-                                       .copy(JOURNAL_KEY2)
-                                       .delete()
-                                       .build(),
-                mCommitResultConsumer);
-        verify(mBridge, times(1))
-                .commitJournalMutation(mJournalMutationArgument.capture(),
-                        mBooleanSuccessCallbackArgument.capture());
-
-        verify(mCommitResultConsumer, times(1)).accept(mCommitResultCaptor.capture());
-        CommitResult commitResult = mCommitResultCaptor.getValue();
-        assertEquals(CommitResult.SUCCESS, commitResult);
-    }
-}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedLoggingBridgeTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedLoggingBridgeTest.java
deleted file mode 100644
index fb3584c..0000000
--- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedLoggingBridgeTest.java
+++ /dev/null
@@ -1,404 +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.
-package org.chromium.chrome.browser.feed.v1;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.support.test.filters.SmallTest;
-
-import androidx.annotation.Nullable;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestRule;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
-
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.base.metrics.test.ShadowRecordHistogram;
-import org.chromium.base.test.BaseRobolectricTestRunner;
-import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.JniMocker;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ActionType;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ContentLoggingData;
-import org.chromium.chrome.browser.feed.library.api.host.logging.ScrollType;
-import org.chromium.chrome.browser.feed.library.common.time.testing.FakeClock;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.preferences.Pref;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.test.util.browser.Features;
-import org.chromium.components.prefs.PrefService;
-import org.chromium.components.user_prefs.UserPrefs;
-import org.chromium.components.user_prefs.UserPrefsJni;
-
-/** Tests of the {@link FeedLoggingBridge} class. */
-@RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE, shadows = {ShadowRecordHistogram.class})
-@Features.DisableFeatures({ChromeFeatureList.INTEREST_FEEDV1_CLICKS_AND_VIEWS_CONDITIONAL_UPLOAD,
-        ChromeFeatureList.INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS})
-public class FeedLoggingBridgeTest {
-    private static final String HISTOGRAM_ENGAGEMENT_TYPE =
-            "ContentSuggestions.Feed.EngagementType";
-    private static final long LESS_THAN_FIVE_MINUTES_IN_MILLISECONDS = (1000 * 60 * 5) - 1;
-    private static final long MORE_THAN_FIVE_MINUTES_IN_MILLISECONDS = (1000 * 60 * 5) + 1;
-    private static final int SHORT_SCROLL_DISTANCE = 10;
-    private static final int LONG_SCROLL_DISTANCE = 1000;
-    private FeedLoggingBridge mFeedLoggingBridge;
-    private FakeClock mFakeClock;
-
-    @Rule
-    public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor();
-
-    @Rule
-    public JniMocker mocker = new JniMocker();
-
-    @Mock
-    private FeedLoggingBridge.Natives mFeedLoggingBridgeJniMock;
-
-    @Mock
-    private UserPrefs.Natives mUserPrefsJniMock;
-
-    @Mock
-    private Profile mProfile;
-
-    @Mock
-    private PrefService mPrefService;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        ShadowRecordHistogram.reset();
-        mocker.mock(FeedLoggingBridgeJni.TEST_HOOKS, mFeedLoggingBridgeJniMock);
-        when(mFeedLoggingBridgeJniMock.init(any(), any())).thenReturn((long) 1);
-
-        mocker.mock(UserPrefsJni.TEST_HOOKS, mUserPrefsJniMock);
-        Profile.setLastUsedProfileForTesting(mProfile);
-        when(mUserPrefsJniMock.get(mProfile)).thenReturn(mPrefService);
-
-        when(mPrefService.getBoolean(Pref.LAST_REFRESH_WAS_SIGNED_IN)).thenReturn(true);
-
-        Profile profile = null;
-        mFakeClock = new FakeClock();
-        mFeedLoggingBridge = new FeedLoggingBridge(profile, mFakeClock);
-    }
-
-    @After
-    public void tearDown() {}
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void reportScrollActivity() throws Exception {
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_SCROLLED, 0);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED, 0);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED_SIMPLE, 0);
-
-        mFeedLoggingBridge.onScroll(ScrollType.STREAM_SCROLL, LONG_SCROLL_DISTANCE);
-
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_SCROLLED, 1);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED, 1);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED_SIMPLE, 1);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void reportFeedInteraction() throws Exception {
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_INTERACTED, 0);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED, 0);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED_SIMPLE, 0);
-
-        mFeedLoggingBridge.reportFeedInteraction();
-
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_INTERACTED, 1);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED, 1);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED_SIMPLE, 1);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void smallScroll() throws Exception {
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED, 0);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED_SIMPLE, 0);
-
-        // A small scroll should count as simple, but not engaged.
-        mFeedLoggingBridge.onScroll(ScrollType.STREAM_SCROLL, SHORT_SCROLL_DISTANCE);
-
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED, 0);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED_SIMPLE, 1);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_SCROLLED, 1);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void negativeScroll() throws Exception {
-        mFeedLoggingBridge.onScroll(ScrollType.STREAM_SCROLL, -1);
-
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED_SIMPLE, 1);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_SCROLLED, 1);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void multipleCalls() throws Exception {
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED, 0);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED_SIMPLE, 0);
-
-        // If we interact several times, we only report engaged once.
-        mFeedLoggingBridge.reportFeedInteraction();
-        mFeedLoggingBridge.reportFeedInteraction();
-        mFeedLoggingBridge.onScroll(ScrollType.STREAM_SCROLL, LONG_SCROLL_DISTANCE);
-
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED, 1);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED_SIMPLE, 1);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void oncePerDay() throws Exception {
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED, 0);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED_SIMPLE, 0);
-
-        mFeedLoggingBridge.reportFeedInteraction();
-        mFeedLoggingBridge.onScroll(ScrollType.STREAM_SCROLL, LONG_SCROLL_DISTANCE);
-
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED, 1);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED_SIMPLE, 1);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_SCROLLED, 1);
-
-        // Make almost 5 minutes pass then an interaction, it should not be counted as a new visit.
-        mFakeClock.advance(LESS_THAN_FIVE_MINUTES_IN_MILLISECONDS);
-        mFeedLoggingBridge.reportFeedInteraction();
-        mFeedLoggingBridge.onScroll(ScrollType.STREAM_SCROLL, LONG_SCROLL_DISTANCE);
-
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED, 1);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED_SIMPLE, 1);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_SCROLLED, 1);
-
-        // Make more than 5 minutes pass with no interaction, should be counted as a new visit.
-        mFakeClock.advance(MORE_THAN_FIVE_MINUTES_IN_MILLISECONDS);
-        mFeedLoggingBridge.reportFeedInteraction();
-        mFeedLoggingBridge.onScroll(ScrollType.STREAM_SCROLL, LONG_SCROLL_DISTANCE);
-
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED, 2);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_ENGAGED_SIMPLE, 2);
-        verifyHistogram(FeedLoggingBridge.FeedEngagementType.FEED_SCROLLED, 2);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    @Features.EnableFeatures(ChromeFeatureList.INTEREST_FEEDV1_CLICKS_AND_VIEWS_CONDITIONAL_UPLOAD)
-    public void onContentViewed_setPrefOnce_whenReachLoggingThresholdAndFeatureEnabled()
-            throws Exception {
-        ContentLoggingData data = makeContentData(2);
-        mFeedLoggingBridge.onContentViewed(data);
-        mFeedLoggingBridge.onContentViewed(data);
-
-        verify(mPrefService, times(1))
-                .setBoolean(Pref.HAS_REACHED_CLICK_AND_VIEW_ACTIONS_UPLOAD_CONDITIONS, true);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    @Features.DisableFeatures(ChromeFeatureList.INTEREST_FEEDV1_CLICKS_AND_VIEWS_CONDITIONAL_UPLOAD)
-    public void onContentViewed_dontSetPref_whenReachLoggingThresholdAndFeatureDisabled()
-            throws Exception {
-        ContentLoggingData data = makeContentData(2);
-        mFeedLoggingBridge.onContentViewed(data);
-
-        verify(mPrefService, never())
-                .setBoolean(Pref.HAS_REACHED_CLICK_AND_VIEW_ACTIONS_UPLOAD_CONDITIONS, true);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    @Features.EnableFeatures(ChromeFeatureList.INTEREST_FEEDV1_CLICKS_AND_VIEWS_CONDITIONAL_UPLOAD)
-    public void onContentViewed_dontSetPref_whenLastRefreshWasNotSignedIn() throws Exception {
-        when(mPrefService.getBoolean(Pref.LAST_REFRESH_WAS_SIGNED_IN)).thenReturn(false);
-
-        ContentLoggingData data = makeContentData(2);
-        mFeedLoggingBridge.onContentViewed(data);
-
-        verify(mPrefService, never())
-                .setBoolean(Pref.HAS_REACHED_CLICK_AND_VIEW_ACTIONS_UPLOAD_CONDITIONS, true);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    @Features.EnableFeatures({ChromeFeatureList.INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS,
-            ChromeFeatureList.INTEREST_FEEDV1_CLICKS_AND_VIEWS_CONDITIONAL_UPLOAD})
-    public void
-    onContentViewed_updateClicksAndViewsCount_whenNoticeCardAt2ndPos() throws Exception {
-        when(mPrefService.getBoolean(Pref.LAST_FETCH_HAD_NOTICE_CARD)).thenReturn(true);
-
-        int initialCount = 1;
-        when(mPrefService.getInteger(Pref.NOTICE_CARD_CLICKS_COUNT)).thenReturn(initialCount);
-        when(mPrefService.getInteger(Pref.NOTICE_CARD_VIEWS_COUNT)).thenReturn(initialCount);
-
-        // Determine the notice card index to be one because the conditional logging feature is
-        // enabled which is tied to having the notice card at the 2nd position.
-        int noticeCardIndex = 1;
-        ContentLoggingData data = makeContentData(noticeCardIndex);
-        mFeedLoggingBridge.onContentViewed(data);
-        mFeedLoggingBridge.onClientAction(data, ActionType.UNKNOWN);
-
-        // Verify that the counts are incremented by one.
-        verify(mPrefService, times(1)).setInteger(Pref.NOTICE_CARD_CLICKS_COUNT, initialCount + 1);
-        verify(mPrefService, times(1)).setInteger(Pref.NOTICE_CARD_VIEWS_COUNT, initialCount + 1);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    @Features.EnableFeatures({ChromeFeatureList.INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS})
-    public void onContentViewed_updateClicksAndViewsCount_whenNoticeCardAt1stPos()
-            throws Exception {
-        when(mPrefService.getBoolean(Pref.LAST_FETCH_HAD_NOTICE_CARD)).thenReturn(true);
-
-        int initialCount = 1;
-        when(mPrefService.getInteger(Pref.NOTICE_CARD_CLICKS_COUNT)).thenReturn(initialCount);
-        when(mPrefService.getInteger(Pref.NOTICE_CARD_VIEWS_COUNT)).thenReturn(initialCount);
-
-        // Determine the notice card index to be zero because the notice card at the 1st position
-        // when conditional logging is disabled.
-        int noticeCardIndex = 0;
-        ContentLoggingData data = makeContentData(noticeCardIndex);
-        mFeedLoggingBridge.onContentViewed(data);
-        mFeedLoggingBridge.onClientAction(data, ActionType.UNKNOWN);
-
-        // Verify that the counts are incremented by one.
-        verify(mPrefService, times(1)).setInteger(Pref.NOTICE_CARD_CLICKS_COUNT, initialCount + 1);
-        verify(mPrefService, times(1)).setInteger(Pref.NOTICE_CARD_VIEWS_COUNT, initialCount + 1);
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    public void onContentViewed_dontUpdateClicksAndViewsCount_whenFeatureDisabled()
-            throws Exception {
-        when(mPrefService.getBoolean(Pref.LAST_FETCH_HAD_NOTICE_CARD)).thenReturn(true);
-
-        // Determine the notice card index to be zero because the notice card is at the 1st position
-        // when conditional logging is disabled.
-        int noticeCardIndex = 0;
-        ContentLoggingData data = makeContentData(noticeCardIndex);
-        mFeedLoggingBridge.onContentViewed(data);
-        mFeedLoggingBridge.onClientAction(data, ActionType.UNKNOWN);
-
-        // Verify that the counts are not incremented.
-        verify(mPrefService, never()).setInteger(eq(Pref.NOTICE_CARD_CLICKS_COUNT), anyInt());
-        verify(mPrefService, never()).setInteger(eq(Pref.NOTICE_CARD_VIEWS_COUNT), anyInt());
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    @Features.EnableFeatures({ChromeFeatureList.INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS})
-    public void onContentViewed_dontUpdateClicksAndViewsCount_whenNoNoticeCard() throws Exception {
-        when(mPrefService.getBoolean(Pref.LAST_FETCH_HAD_NOTICE_CARD)).thenReturn(false);
-
-        // Determine the notice card index to be zero because the notice card at the 1st position
-        // when conditional logging is disabled.
-        int noticeCardIndex = 0;
-        ContentLoggingData data = makeContentData(noticeCardIndex);
-        mFeedLoggingBridge.onContentViewed(data);
-        mFeedLoggingBridge.onClientAction(data, ActionType.UNKNOWN);
-
-        // Verify that the counts are not incremented.
-        verify(mPrefService, never()).setInteger(eq(Pref.NOTICE_CARD_CLICKS_COUNT), anyInt());
-        verify(mPrefService, never()).setInteger(eq(Pref.NOTICE_CARD_VIEWS_COUNT), anyInt());
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Feed"})
-    @Features.EnableFeatures({ChromeFeatureList.INTEREST_FEED_NOTICE_CARD_AUTO_DISMISS})
-    public void onContentViewed_dontUpdateClicksAndViewsCount_whenNotNoticeCardIndex()
-            throws Exception {
-        when(mPrefService.getBoolean(Pref.LAST_FETCH_HAD_NOTICE_CARD)).thenReturn(true);
-
-        int nonNoticeCardIndex = 4;
-        ContentLoggingData data = makeContentData(nonNoticeCardIndex);
-        mFeedLoggingBridge.onContentViewed(data);
-        mFeedLoggingBridge.onClientAction(data, ActionType.UNKNOWN);
-
-        // Verify that the counts are not incremented.
-        verify(mPrefService, never()).setInteger(eq(Pref.NOTICE_CARD_CLICKS_COUNT), anyInt());
-        verify(mPrefService, never()).setInteger(eq(Pref.NOTICE_CARD_VIEWS_COUNT), anyInt());
-    }
-
-    private void verifyHistogram(int sample, int expectedCount) {
-        assertEquals(expectedCount,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        HISTOGRAM_ENGAGEMENT_TYPE, sample));
-    }
-
-    private ContentLoggingData makeContentData(int positionInStream) {
-        return new ContentLoggingData() {
-            @Override
-            public int getPositionInStream() {
-                return positionInStream;
-            }
-
-            @Override
-            public long getPublishedTimeSeconds() {
-                return 0;
-            }
-
-            @Override
-            public long getTimeContentBecameAvailable() {
-                return 0;
-            }
-
-            @Override
-            public float getScore() {
-                return 0.0f;
-            }
-
-            @Override
-            public String getRepresentationUri() {
-                return "";
-            }
-
-            @Override
-            public boolean isAvailableOffline() {
-                return true;
-            }
-
-            @Override
-            public int hashCode() {
-                return 0;
-            }
-
-            @Override
-            public boolean equals(@Nullable Object o) {
-                return true;
-            }
-
-            @Override
-            public String toString() {
-                return "";
-            }
-        };
-    }
-}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedOfflineBridgeTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedOfflineBridgeTest.java
deleted file mode 100644
index 01615d8..0000000
--- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FeedOfflineBridgeTest.java
+++ /dev/null
@@ -1,46 +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.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.support.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.annotation.Config;
-
-import org.chromium.base.test.BaseRobolectricTestRunner;
-import org.chromium.chrome.browser.feed.library.api.client.knowncontent.ContentRemoval;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Unit tests for {@link FeedOfflineBridge}. */
-@RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE)
-public class FeedOfflineBridgeTest {
-    @Test
-    @SmallTest
-    public void testUserDrivenRemovalsOnlyMultiple() {
-        List<ContentRemoval> removals = new ArrayList<>();
-        removals.add(new ContentRemoval("a", true));
-        removals.add(new ContentRemoval("b", false));
-        removals.add(new ContentRemoval("c", true));
-        removals.add(new ContentRemoval("d", false));
-        List<String> filtered = FeedOfflineBridge.takeUserDriveRemovalsOnly(removals);
-        assertEquals(2, filtered.size());
-        assertTrue(filtered.contains("a"));
-        assertTrue(filtered.contains("c"));
-    }
-
-    @Test
-    @SmallTest
-    public void testUserDrivenRemovalsOnlyEmpty() {
-        List<String> filtered = FeedOfflineBridge.takeUserDriveRemovalsOnly(new ArrayList<>());
-        assertEquals(0, filtered.size());
-    }
-}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FutureTaskConsumerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FutureTaskConsumerTest.java
deleted file mode 100644
index 641f6c1..0000000
--- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/v1/FutureTaskConsumerTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.feed.v1;
-
-import static org.junit.Assert.assertEquals;
-
-import android.support.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.annotation.Config;
-
-import org.chromium.base.Callback;
-import org.chromium.base.Consumer;
-import org.chromium.base.test.BaseRobolectricTestRunner;
-
-/** Unit tests for {@link FutureTaskConsumer}. */
-@RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE)
-public class FutureTaskConsumerTest {
-    @Test
-    @SmallTest
-    public void testConsume() {
-        Integer expected = 42;
-        Integer failure = -1;
-
-        Callback<Consumer<Integer>> callback = new Callback<Consumer<Integer>>() {
-            @Override
-            public void onResult(Consumer<Integer> result) {
-                result.accept(expected);
-            }
-        };
-
-        Integer actual = FutureTaskConsumer.consume("", callback, failure);
-
-        assertEquals(expected, actual);
-    }
-}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediatorUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediatorUnitTest.java
index 503465a8..063c956 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediatorUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediatorUnitTest.java
@@ -13,7 +13,6 @@
 import static org.mockito.Mockito.verify;
 
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.BUTTONS_CLICKABLE;
-import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.HOME_BUTTON_IS_VISIBLE;
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_AT_START;
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_CLICK_HANDLER;
 import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_DESCRIPTION;
@@ -694,48 +693,14 @@
         assertEquals(mPropertyModel.get(IS_VISIBLE), true);
     }
 
-    @Test
-    public void testShowHomeButtonInTabSwitcher() {
-        createMediator(false, false, true);
-        mMediator.setTabModelSelector(mTabModelSelector);
-        doReturn(0).when(mIncognitoTabModel).getCount();
-        mMediator.onNativeLibraryReady();
-        verify(mTemplateUrlService).addObserver(mTemplateUrlServiceObserver.capture());
-        assertEquals(mPropertyModel.get(HOME_BUTTON_IS_VISIBLE), false);
-
-        mMediator.setStartSurfaceMode(true);
-        mLayoutStateObserverCaptor.getValue().onStartedShowing(LayoutType.TAB_SWITCHER, false);
-        mLayoutStateObserverCaptor.getValue().onFinishedShowing(LayoutType.TAB_SWITCHER);
-        mMediator.onStartSurfaceStateChanged(StartSurfaceState.SHOWN_HOMEPAGE, true);
-        assertEquals(mPropertyModel.get(IN_START_SURFACE_MODE), true);
-        assertEquals(mPropertyModel.get(HOME_BUTTON_IS_VISIBLE), false);
-
-        mLayoutStateObserverCaptor.getValue().onStartedShowing(LayoutType.TAB_SWITCHER, false);
-        mLayoutStateObserverCaptor.getValue().onFinishedShowing(LayoutType.TAB_SWITCHER);
-        mMediator.onStartSurfaceStateChanged(StartSurfaceState.SHOWN_TABSWITCHER, true);
-        assertEquals(mPropertyModel.get(HOME_BUTTON_IS_VISIBLE), true);
-
-        mMediator.setShowHomeButtonOnTabSwitcherForTesting(false);
-        mLayoutStateObserverCaptor.getValue().onStartedShowing(LayoutType.TAB_SWITCHER, false);
-        mLayoutStateObserverCaptor.getValue().onFinishedShowing(LayoutType.TAB_SWITCHER);
-        mMediator.onStartSurfaceStateChanged(StartSurfaceState.SHOWN_TABSWITCHER, true);
-        assertEquals(mPropertyModel.get(HOME_BUTTON_IS_VISIBLE), false);
-    }
-
     private void createMediator(
             boolean hideIncognitoSwitchWhenNoTabs, boolean hideIncognitoSwitchOnHomePage) {
-        createMediator(hideIncognitoSwitchWhenNoTabs, hideIncognitoSwitchOnHomePage, false);
-    }
-
-    private void createMediator(boolean hideIncognitoSwitchWhenNoTabs,
-            boolean hideIncognitoSwitchOnHomePage, boolean showHomeButtonOnTabSwitcher) {
         mMediator = new StartSurfaceToolbarMediator(mPropertyModel, mMockCallback,
                 hideIncognitoSwitchWhenNoTabs, hideIncognitoSwitchOnHomePage,
-                showHomeButtonOnTabSwitcher, mMenuButtonCoordinator, mIdentityDiscStateSupplier,
+                mMenuButtonCoordinator, mIdentityDiscStateSupplier,
                 ()
                         -> mIdentityDiscController.getForStartSurface(
-                                mMediator.getOverviewModeStateForTesting()),
-                new ObservableSupplierImpl<>(), new ObservableSupplierImpl<>(), null);
+                                mMediator.getOverviewModeStateForTesting()));
 
         mMediator.setLayoutStateProvider(mLayoutStateProvider);
         verify(mLayoutStateProvider).addObserver(mLayoutStateObserverCaptor.capture());
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index b8deb5c..9d7c745d 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-90.0.4411.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-amd64-90.0.4412.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/android/static_initializers.gni b/chrome/android/static_initializers.gni
index d5fe702..fe7d7a10 100644
--- a/chrome/android/static_initializers.gni
+++ b/chrome/android/static_initializers.gni
@@ -17,7 +17,8 @@
   # * base_logging.cc
   # * iostream.cpp
   if (target_cpu == "arm" || target_cpu == "arm64") {
-    expected_static_initializer_count = 2
+    expected_static_initializer_count = 3
+
     # TODO(https://crbug.com/1172451): remove global variables from ANGLE:
     # * SPVRemapper.cpp
     # * doc.cpp
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 8c5449f..39160d2 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -1133,7 +1133,7 @@
     Continue setup
   </message>
   <message name="IDS_LOGIN_MARKETING_OPT_IN_SCREEN_TITLE" desc="The title of the last dialog in the set of screens that are always displayed to the user on the first login to the Chrome OS device.">
-    All set!
+    You are all set!
   </message>
   <message name="IDS_LOGIN_MARKETING_OPT_IN_SCREEN_SUBTITLE" desc="The sub-title of the dialog that allows user to opt-in into several Google marketing options.">
     Get <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> tips, offers, and updates, and share feedback.
diff --git a/chrome/app/chromeos_strings_grdp/IDS_LOGIN_MARKETING_OPT_IN_SCREEN_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_LOGIN_MARKETING_OPT_IN_SCREEN_TITLE.png.sha1
index a75361d..326569843 100644
--- a/chrome/app/chromeos_strings_grdp/IDS_LOGIN_MARKETING_OPT_IN_SCREEN_TITLE.png.sha1
+++ b/chrome/app/chromeos_strings_grdp/IDS_LOGIN_MARKETING_OPT_IN_SCREEN_TITLE.png.sha1
@@ -1 +1 @@
-6a686d4f29ea4402b2341813b76a7d4d88303717
\ No newline at end of file
+582dcdb9ff4c5e28f136f16555fd6b652b559c79
\ No newline at end of file
diff --git a/chrome/app/resources/generated_resources_az.xtb b/chrome/app/resources/generated_resources_az.xtb
index d78562c..53955cc 100644
--- a/chrome/app/resources/generated_resources_az.xtb
+++ b/chrome/app/resources/generated_resources_az.xtb
@@ -1512,7 +1512,7 @@
 <translation id="2690024944919328218">Dil seçimlərini göstərin</translation>
 <translation id="2691385045260836588">Model</translation>
 <translation id="2691440343905273290">Daxiletmə ayarlarını dəyişin</translation>
-<translation id="2693176596243495071">Ups! Naməlum xəta baş verdi. Daha sonra yenidən cəhd edin və ya problem davam edərsə, administratorunuz ilə əlaqə saxlayın.</translation>
+<translation id="2693176596243495071">Xəta oldu. Sonra cəhd edin və ya administratorla əlaqə saxlayın.</translation>
 <translation id="2695749433451188613">İnternet Çap Protokolu (HTTPS)</translation>
 <translation id="2699911226086014512">PIN əməliyyatı <ph name="RETRIES" /> kodu ilə alınmadı.</translation>
 <translation id="2701737434167469065">Daxil olun, <ph name="EMAIL" /></translation>
diff --git a/chrome/app/resources/generated_resources_eu.xtb b/chrome/app/resources/generated_resources_eu.xtb
index 5a4a981..e18daf5 100644
--- a/chrome/app/resources/generated_resources_eu.xtb
+++ b/chrome/app/resources/generated_resources_eu.xtb
@@ -1198,7 +1198,7 @@
 <translation id="2326931316514688470">&amp;Kargatu berriro aplikazioa</translation>
 <translation id="2327492829706409234">Gaitu aplikazioa</translation>
 <translation id="2328561734797404498">Berrabiarazi gailua <ph name="APP_NAME" /> erabiltzeko.</translation>
-<translation id="2329182534073751090">leihoaren kokalekua</translation>
+<translation id="2329182534073751090">leihoen agerpena</translation>
 <translation id="2329597144923131178">Hasi saioa laster-markak, historia, pasahitzak eta bestelakoak gailu guztietan izateko.</translation>
 <translation id="2332131598580221120">Ikusi dendan</translation>
 <translation id="2332192922827071008">Ireki hobespenak</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb
index aa95434..6dc779a 100644
--- a/chrome/app/resources/generated_resources_fa.xtb
+++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -1219,7 +1219,7 @@
 <translation id="2349896577940037438">‏اگر تنظیم «فعالیت وب و برنامه» تکمیلی روشن باشد، ممکن است این داده‌ها در «حساب Google» شما ذخیره شود. می‌توانید در account.google.com، داده‌هایتان را ببینید، حذف کنید، و تنظیمات حسابتان را تغییر دهید.</translation>
 <translation id="2350133097354918058">تازه‌سازی شد</translation>
 <translation id="2350182423316644347">راه‌اندازی برنامه کاربردی...</translation>
-<translation id="2350796302381711542">به <ph name="HANDLER_HOSTNAME" /> امکان داده شود همه پیوندهای <ph name="PROTOCOL" /> را به جای <ph name="REPLACED_HANDLER_TITLE" /> باز کند؟</translation>
+<translation id="2350796302381711542">به <ph name="HANDLER_HOSTNAME" /> امکان داده شود همه پیوندهای <ph name="PROTOCOL" /> را به‌جای <ph name="REPLACED_HANDLER_TITLE" /> باز کند؟</translation>
 <translation id="2351266942280602854">زبان و ورودی</translation>
 <translation id="2352495879228166246">{NUM_ITEMS,plural, =1{۱ مورد}one{{NUM_ITEMS} مورد}other{{NUM_ITEMS} مورد}}</translation>
 <translation id="2352662711729498748">کمتر از ۱ مگابایت</translation>
@@ -3830,7 +3830,7 @@
 <translation id="5376169624176189338">برای برگشت به عقب کلیک کنید، برای دیدن سابقه نگه دارید</translation>
 <translation id="5376931455988532197">فایل بسیار بزرگ است</translation>
 <translation id="5377721922656071359">{COUNT,plural, =1{<ph name="ATTACHMENTS" /> باموفقیت به <ph name="DEVICE_NAME" /> ارسال شد}one{<ph name="ATTACHMENTS" /> باموفقیت به <ph name="DEVICE_NAME" /> ارسال شد}other{<ph name="ATTACHMENTS" /> باموفقیت به <ph name="DEVICE_NAME" /> ارسال شد}}</translation>
-<translation id="537813040452600081">صفحاتی که در این پنجره مشاهده می‌کنید در سابقه مروگر نشان داده نمی‌شوند و بعد از خروج از سیستم هیچ رد دیگری در رایانه از خود به جای نمی‌گذارند (مانند کوکی‌ها). فایل‌هایی که بارگیری می‌کنید و نشانک‌هایی که ایجاد می‌کنید حفظ نمی‌شوند.</translation>
+<translation id="537813040452600081">صفحاتی که در این پنجره مشاهده می‌کنید در سابقه مروگر نشان داده نمی‌شوند و بعد از خروج از سیستم هیچ رد دیگری در رایانه از خود به‌جای نمی‌گذارند (مانند کوکی‌ها). فایل‌هایی که بارگیری می‌کنید و نشانک‌هایی که ایجاد می‌کنید حفظ نمی‌شوند.</translation>
 <translation id="5379140238605961210">ادامه مسدود کردن دسترسی به میکروفون</translation>
 <translation id="5382591305415226340">مدیریت پیوندهای پشتیبانی‌شده</translation>
 <translation id="5383377866517186886">‏در «تنظیمات برگزیده سیستم Mac»، دوربین خاموش است</translation>
@@ -4700,7 +4700,7 @@
 <translation id="6388429472088318283">زبان‌های جستجو</translation>
 <translation id="6388711141388085034">مشغول</translation>
 <translation id="6390020764191254941">انتقال برگه به پنجره جدید</translation>
-<translation id="6390799748543157332">صفحاتی که در این پنجره مشاهده می‌کنید در سابقه مرورگر نشان داده نمی‌شوند و بعد از بسته شدن همه پنجره‌های مهمان باز، هیچ رد دیگری (مانند کوکی) در رایانه از خود به جای نمی‌گذارند. با این وجود، فایل‌هایی که بارگیری می‌کنید، حفظ می‌شوند.</translation>
+<translation id="6390799748543157332">صفحاتی که در این پنجره مشاهده می‌کنید در سابقه مرورگر نشان داده نمی‌شوند و بعد از بسته شدن همه پنجره‌های مهمان باز، هیچ رد دیگری (مانند کوکی) در رایانه از خود به‌جای نمی‌گذارند. با این وجود، فایل‌هایی که بارگیری می‌کنید، حفظ می‌شوند.</translation>
 <translation id="6393156038355142111">پیشنهاد گذرواژه قوی</translation>
 <translation id="6393550101331051049">اجازه دارد محتوای ناامن را نشان دهد</translation>
 <translation id="6395423953133416962">ارسال <ph name="BEGIN_LINK1" />اطلاعات سیستم<ph name="END_LINK1" /> و <ph name="BEGIN_LINK2" />معیارها<ph name="END_LINK2" /></translation>
@@ -6745,7 +6745,7 @@
 <translation id="8734674662128056360">مسدود کردن کوکی‌های شخص ثالث</translation>
 <translation id="873545264931343897">وفتی به‌روزرسانی <ph name="PLUGIN_NAME" /> تمام شد، برای فعال کردن آن، صفحه را تازه‌سازی کنید</translation>
 <translation id="8736288397686080465">این سایت در پس‌زمینه به‌روزرسانی شده است.</translation>
-<translation id="8737685506611670901">باز کردن پیوندهای <ph name="PROTOCOL" /> به جای <ph name="REPLACED_HANDLER_TITLE" /></translation>
+<translation id="8737685506611670901">باز کردن پیوندهای <ph name="PROTOCOL" /> به‌جای <ph name="REPLACED_HANDLER_TITLE" /></translation>
 <translation id="8737709691285775803">Shill</translation>
 <translation id="8737914367566358838">انتخاب کنید صفحه به چه زبانی ترجمه شود</translation>
 <translation id="8740247629089392745">‏می‌توانید این Chromebook را به <ph name="SUPERVISED_USER_NAME" /> بدهید. راه‌اندازی به‌زودی تمام می‌شود و زمان کاوش دستگاه می‌رسد.</translation>
diff --git a/chrome/app/resources/generated_resources_fr.xtb b/chrome/app/resources/generated_resources_fr.xtb
index eb347eb..68d193cf 100644
--- a/chrome/app/resources/generated_resources_fr.xtb
+++ b/chrome/app/resources/generated_resources_fr.xtb
@@ -2925,7 +2925,7 @@
 <translation id="4303079906735388947">Configurez un nouveau code pour votre clé de sécurité</translation>
 <translation id="4305402730127028764">Copier sur <ph name="DEVICE_NAME" /></translation>
 <translation id="4306119971288449206">Les applications doivent être diffusées avec le type de contenu <ph name="CONTENT_TYPE" /></translation>
-<translation id="4307992518367153382">Options de base</translation>
+<translation id="4307992518367153382">Paramètres de base</translation>
 <translation id="4309420042698375243"><ph name="NUM_KILOBYTES" /> Ko (<ph name="NUM_KILOBYTES_LIVE" /> Ko effectifs)</translation>
 <translation id="4310139701823742692">Le format du fichier n'est pas valide. Vérifiez le fichier PPD, puis réessayez.</translation>
 <translation id="431076611119798497">&amp;Détails</translation>
diff --git a/chrome/app/resources/generated_resources_ja.xtb b/chrome/app/resources/generated_resources_ja.xtb
index b26089f..548bc82 100644
--- a/chrome/app/resources/generated_resources_ja.xtb
+++ b/chrome/app/resources/generated_resources_ja.xtb
@@ -4623,7 +4623,7 @@
 <translation id="6309443618838462258">この入力方法は管理者によって許可されていません</translation>
 <translation id="6309510305002439352">マイクがオフになっています</translation>
 <translation id="6310472381159916879">プロファイルを削除</translation>
-<translation id="6311220991371174222">プロフィールを開こうとして問題が発生したため、Chrome を起動できません。Chrome を再起動してみてください。</translation>
+<translation id="6311220991371174222">プロファイルを開こうとして問題が発生したため、Chrome を起動できません。Chrome を再起動してみてください。</translation>
 <translation id="6312403991423642364">ネットワークが不明なためエラーが発生しました</translation>
 <translation id="6312567056350025599">{NUM_DAYS,plural, =1{安全確認を 1 日前に実行しました}other{安全確認を {NUM_DAYS} 日前に実行しました}}</translation>
 <translation id="6312638141433622592">記事をリーダーモードで表示するか確認します(可能な場合)</translation>
diff --git a/chrome/app/resources/generated_resources_ky.xtb b/chrome/app/resources/generated_resources_ky.xtb
index 17ab043b..ee917e0e 100644
--- a/chrome/app/resources/generated_resources_ky.xtb
+++ b/chrome/app/resources/generated_resources_ky.xtb
@@ -667,7 +667,7 @@
 <translation id="1726100011689679555">Ысым серверлери</translation>
 <translation id="1727662110063605623"><ph name="USB_DEVICE_NAME" /> менен Parallels Desktop же Linux'ту байланыштыруу үчүн Жөндөөлөрдү ачыңыз</translation>
 <translation id="1729533290416704613">Omnibox'тон изделгенде, кайсы бет көрсөтүлө тургандыгын көзөмөлдөйт.</translation>
-<translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Колдонмолорду алып салуу үчүн, Жөндөөлөр &gt; Google Play Store &gt; Android түзмөгүнүн параметрлерин башкаруу &gt; Колдонмолор же Колдонмолорду башкаргычка өтүңүз. Андан соң, чыгарып салгыңыз келген колдонмону таптап (колдонмону табуу үчүн оңго же солго серпүүгө туура келиши мүмкүн), анан "Чыгарып салуу" же "Өчүрүү" баскычын басыңыз.<ph name="END_PARAGRAPH1" /></translation>
+<translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Колдонмолорду алып салуу үчүн, Жөндөөлөр &gt; Google Play Store &gt; Android түзмөгүнүн параметрлерин башкаруу &gt; Колдонмолор же Колдонмолорду башкаргычка өтүңүз. Андан соң, чыгарып салгыңыз келген колдонмону таптап (колдонмону табуу үчүн оңго же солго сүрүүгө туура келиши мүмкүн), анан "Чыгарып салуу" же "Өчүрүү" баскычын басыңыз.<ph name="END_PARAGRAPH1" /></translation>
 <translation id="1731911755844941020">Сурам жөнөтүлүүдө…</translation>
 <translation id="1733383495376208985">Шайкештирилген дайындарды өзүңүздүн <ph name="BEGIN_LINK" />шайкештирүүчү купуя сөз айкашыңыз<ph name="END_LINK" /> менен шифрлеңиз. Бул Google Pay'деги төлөм ыкмалары менен даректерге карата колдонулбайт.</translation>
 <translation id="1734212868489994726">Мала көк</translation>
@@ -979,7 +979,7 @@
 <translation id="208586643495776849">Кайталап көрүңүз</translation>
 <translation id="2087822576218954668">Басып чыгаруу: <ph name="PRINT_NAME" /></translation>
 <translation id="2088690981887365033">VPN тармагы</translation>
-<translation id="208928984520943006">Башкы экранга каалаган убакта өтүү үчүн экранды ылдый жагынан өйдө карай сүрүңүз.</translation>
+<translation id="208928984520943006">Башкы экранга каалаган убакта өтүү үчүн экранды ылдыйдан өйдө сүрүңүз.</translation>
 <translation id="2089566709556890888">Google Chrome менен коопсуз серептөө</translation>
 <translation id="2089795179672254991">Алмашуу буферине көчүргөн текстти жана сүрөттөрдү сайт көргүсү келгенде суралсын (сунушталат)</translation>
 <translation id="2090165459409185032">Аккаунтуңуздун маалыматын калыбына келтирүү үчүн, төмөнкүгө өтүңүз: google.com/accounts/recovery</translation>
@@ -1430,7 +1430,7 @@
 <translation id="2588636910004461974">Камсыздоочунун (<ph name="VENDOR_NAME" />) түзмөктөрү</translation>
 <translation id="25899519884572181">Окугуч режиминен чыгуу</translation>
 <translation id="2594999711683503743">Google'дан издеңиз же URL'ди териңиз</translation>
-<translation id="2602501489742255173">Баштоо үчүн, өйдө серпип коюңуз</translation>
+<translation id="2602501489742255173">Баштоо үчүн, өйдө сүрүп коюңуз</translation>
 <translation id="2603115962224169880">Компьютерди тазалоо</translation>
 <translation id="2603463522847370204">&amp;Жашыруун терезеде ачуу</translation>
 <translation id="2604255671529671813">Тармакка туташуу катасы</translation>
@@ -2442,7 +2442,7 @@
 <translation id="3742666961763734085">Мындай аталыштагы уюмдук бөлүм табылбай жатат. Кайталап көрүңүз.</translation>
 <translation id="3744111561329211289">Фонду шайкештирүү</translation>
 <translation id="3746127522257263495">G Suite for Education аккаунтун Android колдонмолоруна кошууга болбойт.</translation>
-<translation id="3747077776423672805">Колдонмолорду алып салуу үчүн, Жөндөөлөр &gt; Google Play Store &gt; Android түзмөгүнүн параметрлерин башкаруу &gt; Колдонмолор же Колдонмолорду башкаргычка өтүңүз. Андан соң, чыгарып салгыңыз келген колдонмону таптап (колдонмону табуу үчүн оңго же солго серпүүгө туура келиши мүмкүн), анан "Чыгарып салуу" же "Өчүрүү" баскычын басыңыз.</translation>
+<translation id="3747077776423672805">Колдонмолорду алып салуу үчүн, Жөндөөлөр &gt; Google Play Store &gt; Android түзмөгүнүн параметрлерин башкаруу &gt; Колдонмолор же Колдонмолорду башкаргычка өтүңүз. Андан соң, чыгарып салгыңыз келген колдонмону таптап (колдонмону табуу үчүн оңго же солго сүрүүгө туура келиши мүмкүн), анан "Чыгарып салуу" же "Өчүрүү" баскычын басыңыз.</translation>
 <translation id="3748706263662799310">Мүчүлүштүк жөнүндө кабарлаңыз</translation>
 <translation id="3752582316358263300">OK…</translation>
 <translation id="3753033997400164841">Бир жолу сактайсыз. Бардык жерде колдоносуз</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ar.xtb b/chrome/app/resources/google_chrome_strings_ar.xtb
index 3d9fde8..54c7390 100644
--- a/chrome/app/resources/google_chrome_strings_ar.xtb
+++ b/chrome/app/resources/google_chrome_strings_ar.xtb
@@ -65,7 +65,7 @@
 <translation id="2574930892358684005">‏سبَق تسجيل دخول <ph name="EXISTING_USER" /> إلى هذا الملف الشخصي على Chrome. للحصول على تجربة تصفّح منفصلة، يمكن لمتصفِّح Chrome إنشاء ملف شخصي خاص بك.</translation>
 <translation id="2580411288591421699">‏لا يمكن تثبيت نفس الإصدار المثبت من Google Chrome والذي يتم تشغيله حاليًا. يُرجى إغلاق Google Chrome وإعادة المحاولة.</translation>
 <translation id="2586406160782125153">‏سيؤدي هذا إلى حذف بيانات التصفح من هذا الجهاز. لاسترداد بياناتك لاحقًا، سجّل الدخول إلى Chrome كـ <ph name="USER_EMAIL" />.</translation>
-<translation id="2588634262982826227">‏بإمكان "نظام التشغيل Chrome" في أي وقت استعادة تطبيقاتك وصفحاتك بعد إعادة التشغيل بدون السؤال كل مرة.</translation>
+<translation id="2588634262982826227">‏بإمكان "نظام التشغيل Chrome" استعادة تطبيقاتك وصفحاتك بعد إعادة تشغيله بدون السؤال كل مرة.</translation>
 <translation id="2622559029861875898">‏يتعذّر على Chrome البحث عن تحديثات. يُرجى التحقّق من اتصال الإنترنت.</translation>
 <translation id="2644798301485385923">‏نظام التشغيل Chrome</translation>
 <translation id="2652691236519827073">‏فتح الرابط في علامة تبويب جديدة في Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_az.xtb b/chrome/app/resources/google_chrome_strings_az.xtb
index 315fc3c2..2762575 100644
--- a/chrome/app/resources/google_chrome_strings_az.xtb
+++ b/chrome/app/resources/google_chrome_strings_az.xtb
@@ -136,7 +136,7 @@
 <translation id="4384570495110188418">Hesaba daxil olmadığınız üçün Chrome parollarınızı yoxlaya bilmir</translation>
 <translation id="4407807842708586359">Google Chrome OS</translation>
 <translation id="4450664632294415862">Chrome - Şəbəkəyə Giriş - <ph name="PAGE_TITLE" /></translation>
-<translation id="4458462641685292929">Google Chrome'da digər əməliyyat davam edir. Daha sonra yenidən cəhd edin.</translation>
+<translation id="4458462641685292929">Google Chrome'da digər əməliyyat davam edir. Sonra cəhd edin.</translation>
 <translation id="4480040274068703980">Hesaba giriş xətası üzündən Chrome OS datanızı sinxronlaşdıra bilmədi.</translation>
 <translation id="4521185804071812304">İstəyə görə: Diaqnostika və istifadəçi datasını avtomatik Google'a göndərməklə Chrome ƏS funksiyalarını təkmilləşdirməyə yardım edin.</translation>
 <translation id="4561051373932531560">Google Chrome Sizə imkan verir ki, telefon nömrənizə vebdə klikləyərək Skype'da zəng edəsiniz!</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ja.xtb b/chrome/app/resources/google_chrome_strings_ja.xtb
index dfb4076d..5bfec08 100644
--- a/chrome/app/resources/google_chrome_strings_ja.xtb
+++ b/chrome/app/resources/google_chrome_strings_ja.xtb
@@ -34,14 +34,14 @@
 <translation id="174539241580958092">ログイン時にエラーが発生したため、Google Chrome はデータを同期できませんでした。</translation>
 <translation id="1759842336958782510">Chrome</translation>
 <translation id="1786003790898721085"><ph name="TARGET_DEVICE_NAME" /> で Chrome にログインしていることを確認してから、もう一度送信してください。</translation>
-<translation id="1807517590912578995">個別の Chrome プロフィールを使用しますか?</translation>
+<translation id="1807517590912578995">個別の Chrome プロファイルを使用しますか?</translation>
 <translation id="1812689907177901597">この設定を無効にすると、Chrome にログインすることなく Gmail などの Google サイトにログインできます</translation>
 <translation id="1860536484129686729">このサイトを利用するには、Chrome でカメラの使用を許可する必要があります</translation>
 <translation id="1873233029667955273">Google Chrome はデフォルトのブラウザとして設定されていません</translation>
 <translation id="1874309113135274312">Google Chrome ベータ版(mDNS-In)</translation>
 <translation id="1877026089748256423">Chrome は古いバージョンです</translation>
 <translation id="1919130412786645364">Chrome へのログインを許可する</translation>
-<translation id="2018528049276128029">Chrome の情報(ブックマーク、履歴、パスワードなど)はプロフィールごとに分けて保持されます</translation>
+<translation id="2018528049276128029">Chrome の情報(ブックマーク、履歴、パスワードなど)はプロファイルごとに分けて保持されます</translation>
 <translation id="2063848847527508675">アップデートを適用するには、Chrome OS を再起動する必要があります。</translation>
 <translation id="2094919256425865063">今すぐ Chrome を終了しますか?</translation>
 <translation id="2120620239521071941">このデバイスから <ph name="ITEMS_COUNT" /> 件の項目を削除します。後でデータを取得するには、<ph name="USER_EMAIL" /> として Chrome にログインしてください。</translation>
@@ -59,7 +59,7 @@
 <translation id="2467438592969358367">Google Chrome からパスワードをエクスポートするための許可を求められています。許可するには Windows のパスワードを入力してください。</translation>
 <translation id="2485422356828889247">アンインストール</translation>
 <translation id="2534507159460261402">Google Pay(Chrome にコピー)</translation>
-<translation id="2574930892358684005"><ph name="EXISTING_USER" /> さんはこの Chrome プロフィールにすでにログインしています。ブラウジング環境を分ける場合は、Chrome で自分用のプロフィールを作成できます。</translation>
+<translation id="2574930892358684005"><ph name="EXISTING_USER" /> さんはこの Chrome プロファイルにすでにログインしています。ブラウジング環境を分ける場合は、Chrome で自分用のプロファイルを作成できます。</translation>
 <translation id="2580411288591421699">実行中の Google Chrome と同じバージョンをインストールすることはできません。Google Chrome を閉じてからもう一度お試しください。</translation>
 <translation id="2586406160782125153">このデバイスから閲覧データを削除します。後でデータを取得するには、<ph name="USER_EMAIL" /> として Chrome にログインしてください。</translation>
 <translation id="2588634262982826227">Chrome OS は再起動後に毎回確認することなくアプリとページを復元できます。</translation>
@@ -74,7 +74,7 @@
 <translation id="2799223571221894425">再起動</translation>
 <translation id="2847461019998147611">Google Chrome をこの言語で表示</translation>
 <translation id="2857540653560290388">Chrome を起動しています...</translation>
-<translation id="2857972467023607093">このアカウントの Chrome プロフィールはすでに存在します</translation>
+<translation id="2857972467023607093">このアカウントの Chrome プロファイルはすでに存在します</translation>
 <translation id="2871893339301912279">Chrome にログインしました</translation>
 <translation id="2885378588091291677">タスク マネージャ</translation>
 <translation id="2888126860611144412">Chrome について</translation>
@@ -118,7 +118,7 @@
 <translation id="4053720452172726777">Google Chrome の設定</translation>
 <translation id="4110895483821904099">新しい Chrome プロファイルの設定</translation>
 <translation id="4143243756087420366">Chrome の名前と画像</translation>
-<translation id="4147555960264124640">現在、管理対象アカウントでログインしており、あなたの Google Chrome プロフィールを管理者が制御できる状態になっています。あなたの Chrome データ(アプリ、ブックマーク、履歴、パスワードなどの設定)は永続的に <ph name="USER_NAME" /> に関連付けられます。このデータは Google アカウントのダッシュボードを介して削除できますが、このデータを別のアカウントに関連付けることはできなくなります。<ph name="LEARN_MORE" /></translation>
+<translation id="4147555960264124640">現在、管理対象アカウントでログインしており、あなたの Google Chrome プロファイルを管理者が制御できる状態になっています。あなたの Chrome データ(アプリ、ブックマーク、履歴、パスワードなどの設定)は永続的に <ph name="USER_NAME" /> に関連付けられます。このデータは Google アカウントのダッシュボードを介して削除できますが、このデータを別のアカウントに関連付けることはできなくなります。<ph name="LEARN_MORE" /></translation>
 <translation id="4149882025268051530">インストーラー アーカイブを解凍できませんでした。Google Chrome をダウンロードし直してください。</translation>
 <translation id="4191857738314598978">{0,plural, =1{1 日以内に Chrome を再起動してください}other{# 日以内に Chrome を再起動してください}}</translation>
 <translation id="4205939740494406371">Chrome でパスワードを確認できません。24 時間後にもう一度お試しいただくか、<ph name="BEGIN_LINK" />Google アカウントでパスワードをご確認ください<ph name="END_LINK" />。</translation>
@@ -157,9 +157,9 @@
 <translation id="4990567037958725628">Google Chrome Canary</translation>
 <translation id="5062123544085870375">Chrome OS を再起動してください</translation>
 <translation id="5132929315877954718">Google Chrome のすばらしいアプリ、ゲーム、拡張機能、テーマをぜひご利用ください。</translation>
-<translation id="5139423532931106058">Chrome プロフィールをカスタマイズ</translation>
+<translation id="5139423532931106058">Chrome プロファイルをカスタマイズ</translation>
 <translation id="5163087008893166964">Chrome へようこそ。新しいブラウザ ウィンドウが開いています</translation>
-<translation id="5170938038195470297">バージョンが新しい Google Chrome のプロフィールは使用できません。一部の機能が利用できない可能性があります。別の場所のプロフィールを指定するか、新しいバージョンの Chrome をご使用ください。</translation>
+<translation id="5170938038195470297">バージョンが新しい Google Chrome のプロファイルは使用できません。一部の機能が利用できない可能性があります。別の場所のプロファイルを指定するか、新しいバージョンの Chrome をご使用ください。</translation>
 <translation id="5193136243808726294">Google Chrome OS ではこのページを開けません。</translation>
 <translation id="521447420733633466">デバイスを共有している場合でも、友だちや家族はそれぞれ Chrome を自分専用のブラウザとして自分用の設定をして使うことができます</translation>
 <translation id="5251420635869119124">ゲスト ユーザーは、記録を残さずに Chrome を使用できます。</translation>
@@ -197,14 +197,14 @@
 <translation id="6291549208091401781">Google Chrome は既にパソコンのすべてのユーザー対してインストールされています。</translation>
 <translation id="6338556085225130112">Google Chrome を更新しています</translation>
 <translation id="6368958679917195344">Chrome OS は、さらに追加の<ph name="BEGIN_LINK_CROS_OSS" />オープンソース ソフトウェア<ph name="END_LINK_CROS_OSS" />によって実現しました。</translation>
-<translation id="6418662306461808273">既存の Chrome プロフィールに切り替えますか?</translation>
+<translation id="6418662306461808273">既存の Chrome プロファイルに切り替えますか?</translation>
 <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation>
 <translation id="6566149418543181476">Google Chrome を更新しています(<ph name="PROGRESS_PERCENT" />)</translation>
 <translation id="6568793831116033768">Chrome OS システム</translation>
 <translation id="6650333065969705433">Rosetta を使用して、保護されたメディアを再生するには、Chrome を再起動する必要があります。</translation>
 <translation id="6676384891291319759">インターネットにアクセス</translation>
 <translation id="6679975945624592337">Google Chrome をバックグラウンドで実行する</translation>
-<translation id="6739177684496155661">新しい Chrome プロフィールで続行しますか?</translation>
+<translation id="6739177684496155661">新しい Chrome プロファイルで続行しますか?</translation>
 <translation id="6750954913813541382">スペルミスを修正するために、ブラウザに入力したテキストが Chrome から Google に送信されます</translation>
 <translation id="6755885556185485672">Chrome OS は正しく終了しませんでした。</translation>
 <translation id="677276454032249905">今すぐ Chrome を終了しますか?</translation>
@@ -219,10 +219,10 @@
 <translation id="7106741999175697885">タスク マネージャ - Google Chrome</translation>
 <translation id="7140653346177713799">{COUNT,plural, =0{Chrome の新しいアップデートを利用できます。再起動するとすぐにアップデートが適用されます。}=1{Chrome の新しいアップデートを利用できます。再起動するとすぐにアップデートが適用されます。シークレット ウィンドウは、再起動後は自動的には開きません。}other{Chrome の新しいアップデートを利用できます。再起動するとすぐにアップデートが適用されます。現在開いている # 個のシークレット ウィンドウは、再起動後は自動的には開きません。}}</translation>
 <translation id="7155997830309522122">その場合は、Chrome に保存したパスワードを編集して、新しいパスワードと一致するようにしてください。</translation>
-<translation id="7242029209006116544">現在、管理対象アカウントでログインしており、あなたの Google Chrome プロフィールを管理者が制御できる状態になっています。あなたの Chrome データ(アプリ、ブックマーク、履歴、パスワードなどの設定)は永続的に <ph name="USER_NAME" /> に関連付けられます。このデータは Google アカウントのダッシュボードを介して削除できますが、このデータを別のアカウントに関連付けることはできなくなります。新しいプロフィールを作成して、既存の Chrome データを別に保管することができます。<ph name="LEARN_MORE" /></translation>
+<translation id="7242029209006116544">現在、管理対象アカウントでログインしており、あなたの Google Chrome プロファイルを管理者が制御できる状態になっています。あなたの Chrome データ(アプリ、ブックマーク、履歴、パスワードなどの設定)は永続的に <ph name="USER_NAME" /> に関連付けられます。このデータは Google アカウントのダッシュボードを介して削除できますが、このデータを別のアカウントに関連付けることはできなくなります。新しいプロファイルを作成して、既存の Chrome データを別に保管することができます。<ph name="LEARN_MORE" /></translation>
 <translation id="7295052994004373688">この言語が Google Chrome UI の表示に使用されます</translation>
 <translation id="7296210096911315575">使用と安全に関する重要事項</translation>
-<translation id="7303916856901595720">新しい Chrome プロフィールにアカウントを移動しますか?</translation>
+<translation id="7303916856901595720">新しい Chrome プロファイルにアカウントを移動しますか?</translation>
 <translation id="7308322188646931570">ファイルをダウンロードするには、Chrome でストレージへのアクセスを許可する必要があります</translation>
 <translation id="7339898014177206373">新しいウィンドウ</translation>
 <translation id="7398801000654795464">Chrome に <ph name="USER_EMAIL_ADDRESS" /> としてログインしていました。再度ログインするには同じアカウントを使用してください。</translation>
@@ -240,7 +240,7 @@
 <translation id="7761834446675418963">Chrome を開いてブラウジングを始めるには、名前をクリックしてください。</translation>
 <translation id="7777080907402804672">画像に有効な説明が設定されていない場合に、Chrome で説明を自動的に生成できるよう Google に画像が送信されます。この機能は設定でいつでも無効にできます。</translation>
 <translation id="7781002470561365167">Google クロームブラウザの最新バージョンを是非お試しください。</translation>
-<translation id="7787950393032327779">プロフィールは、別のコンピュータ(<ph name="HOST_NAME" />)の別の Google Chrome プロセス(<ph name="PROCESS_ID" />)で使用されているようです。Chrome はプロフィールが破損しないようにプロフィールをロックしています。他のプロセスがこのプロフィールを使用していないことが確実であれば、プロフィールのロックを解除して Chrome を再起動できます。</translation>
+<translation id="7787950393032327779">プロファイルは、別のコンピュータ(<ph name="HOST_NAME" />)の別の Google Chrome プロセス(<ph name="PROCESS_ID" />)で使用されているようです。Chrome はプロファイルが破損しないようにプロファイルをロックしています。他のプロセスがこのプロファイルを使用していないことが確実であれば、プロファイルのロックを解除して Chrome を再起動できます。</translation>
 <translation id="7801699035218095297">Google Chrome がパスワードをコピーしようとしています。続行するには、Windows のパスワードを入力してください。</translation>
 <translation id="7808348361785373670">Chrome から削除...</translation>
 <translation id="7825851276765848807">原因不明のエラーによりインストールに失敗しました。Google Chrome をもう一度ダウンロードしてください。</translation>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index ced6d317..e287ae0 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2093,7 +2093,6 @@
     "//components/feature_engagement",
     "//components/federated_learning",
     "//components/feed:buildflags",
-    "//components/feed/content:feed_content",
     "//components/feed/core/common:feed_core_common",
     "//components/feed/core/shared_prefs:feed_shared_prefs",
     "//components/feed/core/v2:feed_core_v2",
@@ -3160,7 +3159,6 @@
       "previews/android/previews_android_bridge.h",
       "privacy/secure_dns_bridge.cc",
       "privacy_sandbox/android/privacy_sandbox_bridge.cc",
-      "profiles/android/profile_downloader_android.cc",
       "profiles/android/profile_manager_utils.cc",
       "profiles/incognito_utils_android.cc",
       "profiles/profile_android.cc",
@@ -5002,8 +5000,12 @@
       "metrics/power/power_metrics_provider_mac.h",
       "metrics/power/power_metrics_provider_mac.mm",
       "notifications/alert_dispatcher_mac.h",
+      "notifications/alert_dispatcher_mojo.h",
+      "notifications/alert_dispatcher_mojo.mm",
       "notifications/alert_dispatcher_xpc.h",
       "notifications/alert_dispatcher_xpc.mm",
+      "notifications/notification_alert_service_bridge.h",
+      "notifications/notification_alert_service_bridge.mm",
       "notifications/notification_platform_bridge_mac.h",
       "notifications/notification_platform_bridge_mac.mm",
       "notifications/notification_platform_bridge_mac_unnotification.h",
@@ -5032,6 +5034,7 @@
       "//chrome/app_shim",
       "//chrome/browser/apps/app_shim",
       "//chrome/browser/ui/cocoa/notifications:common",
+      "//chrome/services/mac_notifications/public/mojom",
       "//components/crash/core/app",
       "//components/metal_util",
       "//sandbox/mac:seatbelt",
@@ -5832,32 +5835,6 @@
     }
   }
 
-  if (enable_feed_v1) {
-    sources += [
-      "android/feed/feed_content_bridge.cc",
-      "android/feed/feed_content_bridge.h",
-      "android/feed/feed_debugging_bridge.cc",
-      "android/feed/feed_debugging_bridge.h",
-      "android/feed/feed_host_service_factory.cc",
-      "android/feed/feed_host_service_factory.h",
-      "android/feed/feed_journal_bridge.cc",
-      "android/feed/feed_journal_bridge.h",
-      "android/feed/feed_lifecycle_bridge.cc",
-      "android/feed/feed_lifecycle_bridge.h",
-      "android/feed/feed_logging_bridge.cc",
-      "android/feed/feed_logging_bridge.h",
-      "android/feed/feed_network_bridge.cc",
-      "android/feed/feed_network_bridge.h",
-      "android/feed/feed_offline_bridge.cc",
-      "android/feed/feed_offline_bridge.h",
-      "android/feed/feed_scheduler_bridge.cc",
-      "android/feed/feed_scheduler_bridge.h",
-      "android/feed/history/feed_history_helper.cc",
-      "android/feed/history/feed_history_helper.h",
-    ]
-    deps += [ "//components/feed/content:feed_content" ]
-  }
-
   if (enable_library_cdms) {
     sources += [
       "media/output_protection_impl.cc",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index f16bfe2c..e4a9555 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -17,13 +17,6 @@
   "+chrome/android/modules",
   "+chrome/android/test_support_jni_headers",
   "+chrome/app",
-  "+chrome/browser/error_reporting",
-  "+chrome/browser/flags/android",
-  "+chrome/browser/preferences/android",
-  "+chrome/browser/profiles/android/jni_headers",
-  "+chrome/browser/util/android",
-  "+chrome/browser/version",
-  "+chrome/browser/video_tutorials",
   "+chrome/credential_provider/common",
   "+chrome/grit",
   "+chrome/install_static",
diff --git a/chrome/browser/android/compositor/tab_content_manager.cc b/chrome/browser/android/compositor/tab_content_manager.cc
index de7b2c2..89eedee 100644
--- a/chrome/browser/android/compositor/tab_content_manager.cc
+++ b/chrome/browser/android/compositor/tab_content_manager.cc
@@ -43,6 +43,8 @@
 
 namespace {
 
+const double kDefaultThumbnailAspectRatio = 0.85;
+
 using TabReadbackCallback = base::OnceCallback<void(float, const SkBitmap&)>;
 
 }  // namespace
@@ -72,7 +74,7 @@
     if (crop_to_match_aspect_ratio) {
       double aspect_ratio = base::GetFieldTrialParamByFeatureAsDouble(
           chrome::android::kTabGridLayoutAndroid, "thumbnail_aspect_ratio",
-          1.0);
+          kDefaultThumbnailAspectRatio);
       aspect_ratio = ThumbnailCache::clampAspectRatio(aspect_ratio, 0.5, 2.0);
       int height = std::min(view_size_in_pixels.height(),
                             (int)(view_size_in_pixels.width() / aspect_ratio));
@@ -130,7 +132,8 @@
                                      jboolean save_jpeg_thumbnails)
     : weak_java_tab_content_manager_(env, obj) {
   double jpeg_aspect_ratio = base::GetFieldTrialParamByFeatureAsDouble(
-      chrome::android::kTabGridLayoutAndroid, "thumbnail_aspect_ratio", 1.0);
+      chrome::android::kTabGridLayoutAndroid, "thumbnail_aspect_ratio",
+      kDefaultThumbnailAspectRatio);
   thumbnail_cache_ = std::make_unique<ThumbnailCache>(
       static_cast<size_t>(default_cache_size),
       static_cast<size_t>(approximation_cache_size),
@@ -393,7 +396,8 @@
     // landscape mode.
     int scale = need_downsampling ? 2 : 1;
     double aspect_ratio = base::GetFieldTrialParamByFeatureAsDouble(
-        chrome::android::kTabGridLayoutAndroid, "thumbnail_aspect_ratio", 1.0);
+        chrome::android::kTabGridLayoutAndroid, "thumbnail_aspect_ratio",
+        kDefaultThumbnailAspectRatio);
     aspect_ratio = ThumbnailCache::clampAspectRatio(aspect_ratio, 0.5, 2.0);
 
     int width = std::min(bitmap.width() / scale,
diff --git a/chrome/browser/android/feed/feed_content_bridge.cc b/chrome/browser/android/feed/feed_content_bridge.cc
deleted file mode 100644
index 8ce51011..0000000
--- a/chrome/browser/android/feed/feed_content_bridge.cc
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/feed/feed_content_bridge.h"
-
-#include <jni.h>
-
-#include <list>
-#include <memory>
-#include <utility>
-
-#include "base/android/callback_android.h"
-#include "base/android/jni_array.h"
-#include "base/android/jni_string.h"
-#include "base/bind.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "chrome/android/chrome_jni_headers/FeedContentBridge_jni.h"
-#include "chrome/browser/android/feed/feed_host_service_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_android.h"
-#include "components/feed/content/feed_host_service.h"
-#include "components/feed/core/feed_content_database.h"
-#include "components/feed/core/feed_content_mutation.h"
-#include "ui/gfx/android/java_bitmap.h"
-#include "ui/gfx/image/image.h"
-
-namespace feed {
-
-using base::android::AppendJavaStringArrayToStringVector;
-using base::android::AttachCurrentThread;
-using base::android::ConvertJavaStringToUTF8;
-using base::android::JavaArrayOfByteArrayToStringVector;
-using base::android::JavaIntArrayToIntVector;
-using base::android::JavaRef;
-using base::android::JavaParamRef;
-using base::android::ScopedJavaGlobalRef;
-using base::android::ScopedJavaLocalRef;
-using base::android::ToJavaArrayOfByteArray;
-using base::android::ToJavaArrayOfStrings;
-using base::android::JavaByteArrayToString;
-
-static jlong JNI_FeedContentBridge_Init(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& j_this,
-    const JavaParamRef<jobject>& j_profile) {
-  Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
-  FeedHostService* host_service =
-      FeedHostServiceFactory::GetForBrowserContext(profile);
-  DCHECK(host_service);
-  FeedContentDatabase* feed_content_database =
-      host_service->GetContentDatabase();
-  DCHECK(feed_content_database);
-  FeedContentBridge* native_content_bridge =
-      new FeedContentBridge(feed_content_database);
-  return reinterpret_cast<intptr_t>(native_content_bridge);
-}
-
-FeedContentBridge::FeedContentBridge(FeedContentDatabase* feed_content_database)
-    : feed_content_database_(feed_content_database) {}
-
-FeedContentBridge::~FeedContentBridge() = default;
-
-void FeedContentBridge::Destroy(JNIEnv* env, const JavaRef<jobject>& j_this) {
-  delete this;
-}
-
-void FeedContentBridge::LoadContent(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const JavaRef<jobjectArray>& j_keys,
-    const JavaRef<jobject>& j_success_callback,
-    const JavaRef<jobject>& j_failure_callback) {
-  std::vector<std::string> keys;
-  AppendJavaStringArrayToStringVector(j_env, j_keys, &keys);
-  ScopedJavaGlobalRef<jobject> success_callback(j_success_callback);
-  ScopedJavaGlobalRef<jobject> failure_callback(j_failure_callback);
-
-  feed_content_database_->LoadContent(
-      keys, base::BindOnce(&FeedContentBridge::OnLoadContentDone,
-                           weak_ptr_factory_.GetWeakPtr(), success_callback,
-                           failure_callback));
-}
-
-void FeedContentBridge::LoadContentByPrefix(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const JavaRef<jstring>& j_prefix,
-    const JavaRef<jobject>& j_success_callback,
-    const JavaRef<jobject>& j_failure_callback) {
-  std::string prefix = ConvertJavaStringToUTF8(j_env, j_prefix);
-  ScopedJavaGlobalRef<jobject> success_callback(j_success_callback);
-  ScopedJavaGlobalRef<jobject> failure_callback(j_failure_callback);
-
-  feed_content_database_->LoadContentByPrefix(
-      prefix, base::BindOnce(&FeedContentBridge::OnLoadContentDone,
-                             weak_ptr_factory_.GetWeakPtr(), success_callback,
-                             failure_callback));
-}
-
-void FeedContentBridge::LoadAllContentKeys(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const JavaRef<jobject>& j_success_callback,
-    const JavaRef<jobject>& j_failure_callback) {
-  ScopedJavaGlobalRef<jobject> success_callback(j_success_callback);
-  ScopedJavaGlobalRef<jobject> failure_callback(j_failure_callback);
-
-  feed_content_database_->LoadAllContentKeys(base::BindOnce(
-      &FeedContentBridge::OnLoadAllContentKeysDone,
-      weak_ptr_factory_.GetWeakPtr(), success_callback, failure_callback));
-}
-
-void FeedContentBridge::CommitContentMutation(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const JavaRef<jobject>& j_callback) {
-  DCHECK(content_mutation_);
-  ScopedJavaGlobalRef<jobject> callback(j_callback);
-
-  feed_content_database_->CommitContentMutation(
-      std::move(content_mutation_),
-      base::BindOnce(&FeedContentBridge::OnStorageCommitDone,
-                     weak_ptr_factory_.GetWeakPtr(), callback));
-}
-
-void FeedContentBridge::CreateContentMutation(JNIEnv* j_env,
-                                              const JavaRef<jobject>& j_this) {
-  DCHECK(!content_mutation_);
-  content_mutation_ = std::make_unique<ContentMutation>();
-}
-
-void FeedContentBridge::DeleteContentMutation(JNIEnv* j_env,
-                                              const JavaRef<jobject>& j_this) {
-  DCHECK(content_mutation_);
-  content_mutation_.reset();
-}
-
-void FeedContentBridge::AppendDeleteOperation(JNIEnv* j_env,
-                                              const JavaRef<jobject>& j_this,
-                                              const JavaRef<jstring>& j_key) {
-  DCHECK(content_mutation_);
-  std::string key(ConvertJavaStringToUTF8(j_env, j_key));
-
-  content_mutation_->AppendDeleteOperation(key);
-}
-
-void FeedContentBridge::AppendDeleteByPrefixOperation(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const JavaRef<jstring>& j_prefix) {
-  DCHECK(content_mutation_);
-  std::string prefix(ConvertJavaStringToUTF8(j_env, j_prefix));
-
-  content_mutation_->AppendDeleteByPrefixOperation(prefix);
-}
-
-void FeedContentBridge::AppendUpsertOperation(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const JavaRef<jstring>& j_key,
-    const JavaRef<jbyteArray>& j_data) {
-  DCHECK(content_mutation_);
-  std::string key(ConvertJavaStringToUTF8(j_env, j_key));
-  std::string data;
-  JavaByteArrayToString(j_env, j_data, &data);
-
-  content_mutation_->AppendUpsertOperation(key, data);
-}
-
-void FeedContentBridge::AppendDeleteAllOperation(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this) {
-  DCHECK(content_mutation_);
-
-  content_mutation_->AppendDeleteAllOperation();
-}
-
-void FeedContentBridge::OnLoadContentDone(
-    ScopedJavaGlobalRef<jobject> success_callback,
-    ScopedJavaGlobalRef<jobject> failure_callback,
-    bool success,
-    std::vector<FeedContentDatabase::KeyAndData> pairs) {
-  std::vector<std::string> keys;
-  std::vector<std::string> data;
-  for (auto pair : pairs) {
-    keys.push_back(std::move(pair.first));
-    data.push_back(std::move(pair.second));
-  }
-
-  JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jobjectArray> j_keys = ToJavaArrayOfStrings(env, keys);
-  ScopedJavaLocalRef<jobjectArray> j_data = ToJavaArrayOfByteArray(env, data);
-
-  // Create Java Map by JNI call.
-  ScopedJavaLocalRef<jobject> j_pairs =
-      Java_FeedContentBridge_createKeyAndDataMap(env, j_keys, j_data);
-
-  if (!success) {
-    RunObjectCallbackAndroid(failure_callback, nullptr);
-    return;
-  }
-  RunObjectCallbackAndroid(success_callback, j_pairs);
-}
-
-void FeedContentBridge::OnLoadAllContentKeysDone(
-    ScopedJavaGlobalRef<jobject> success_callback,
-    ScopedJavaGlobalRef<jobject> failure_callback,
-    bool success,
-    std::vector<std::string> keys) {
-  JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jobjectArray> j_keys = ToJavaArrayOfStrings(env, keys);
-
-  if (!success) {
-    RunObjectCallbackAndroid(failure_callback, nullptr);
-    return;
-  }
-  RunObjectCallbackAndroid(success_callback, j_keys);
-}
-
-void FeedContentBridge::OnStorageCommitDone(
-    ScopedJavaGlobalRef<jobject> callback,
-    bool success) {
-  RunBooleanCallbackAndroid(callback, success);
-}
-
-}  // namespace feed
diff --git a/chrome/browser/android/feed/feed_content_bridge.h b/chrome/browser/android/feed/feed_content_bridge.h
deleted file mode 100644
index 70a95aa..0000000
--- a/chrome/browser/android/feed/feed_content_bridge.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_FEED_FEED_CONTENT_BRIDGE_H_
-#define CHROME_BROWSER_ANDROID_FEED_FEED_CONTENT_BRIDGE_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/android/scoped_java_ref.h"
-#include "base/memory/weak_ptr.h"
-#include "components/feed/core/feed_content_database.h"
-
-namespace feed {
-
-class FeedContentDatabase;
-
-// Native counterpart of FeedContentBridge.java. Holds non-owning pointers
-// to native implementation to which operations are delegated. Results are
-// passed back by a single argument callback so
-// base::android::RunBooleanCallbackAndroid() and
-// base::android::RunObjectCallbackAndroid() can be used. This bridge is
-// instantiated, owned, and destroyed from Java.
-class FeedContentBridge {
- public:
-  explicit FeedContentBridge(FeedContentDatabase* feed_Storage_database);
-  ~FeedContentBridge();
-
-  void Destroy(JNIEnv* j_env, const base::android::JavaRef<jobject>& j_this);
-
-  void LoadContent(JNIEnv* j_env,
-                   const base::android::JavaRef<jobject>& j_this,
-                   const base::android::JavaRef<jobjectArray>& j_keys,
-                   const base::android::JavaRef<jobject>& j_success_callback,
-                   const base::android::JavaRef<jobject>& j_failure_callback);
-  void LoadContentByPrefix(
-      JNIEnv* j_env,
-      const base::android::JavaRef<jobject>& j_this,
-      const base::android::JavaRef<jstring>& j_prefix,
-      const base::android::JavaRef<jobject>& j_success_callback,
-      const base::android::JavaRef<jobject>& j_failure_callback);
-  void LoadAllContentKeys(
-      JNIEnv* j_env,
-      const base::android::JavaRef<jobject>& j_this,
-      const base::android::JavaRef<jobject>& j_success_callback,
-      const base::android::JavaRef<jobject>& j_failure_callback);
-  void CommitContentMutation(JNIEnv* j_env,
-                             const base::android::JavaRef<jobject>& j_this,
-                             const base::android::JavaRef<jobject>& j_callback);
-
-  void CreateContentMutation(JNIEnv* j_env,
-                             const base::android::JavaRef<jobject>& j_this);
-  void DeleteContentMutation(JNIEnv* j_env,
-                             const base::android::JavaRef<jobject>& j_this);
-  void AppendDeleteOperation(JNIEnv* j_env,
-                             const base::android::JavaRef<jobject>& j_this,
-                             const base::android::JavaRef<jstring>& j_key);
-  void AppendDeleteByPrefixOperation(
-      JNIEnv* j_env,
-      const base::android::JavaRef<jobject>& j_this,
-      const base::android::JavaRef<jstring>& j_prefix);
-  void AppendUpsertOperation(JNIEnv* j_env,
-                             const base::android::JavaRef<jobject>& j_this,
-                             const base::android::JavaRef<jstring>& j_key,
-                             const base::android::JavaRef<jbyteArray>& j_data);
-  void AppendDeleteAllOperation(JNIEnv* j_env,
-                                const base::android::JavaRef<jobject>& j_this);
-
- private:
-  void OnLoadContentDone(
-      base::android::ScopedJavaGlobalRef<jobject> success_callback,
-      base::android::ScopedJavaGlobalRef<jobject> failure_callback,
-      bool success,
-      std::vector<FeedContentDatabase::KeyAndData> pairs);
-  void OnLoadAllContentKeysDone(
-      base::android::ScopedJavaGlobalRef<jobject> success_callback,
-      base::android::ScopedJavaGlobalRef<jobject> failure_callback,
-      bool success,
-      std::vector<std::string> keys);
-  void OnStorageCommitDone(base::android::ScopedJavaGlobalRef<jobject> callback,
-                           bool success);
-
-  // This unique_ptr will hold a list of ContentOperations which are not
-  // committed yet. After commit to database, this unique_ptr will be reset.
-  std::unique_ptr<ContentMutation> content_mutation_;
-
-  FeedContentDatabase* feed_content_database_;
-
-  base::WeakPtrFactory<FeedContentBridge> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FeedContentBridge);
-};
-
-}  // namespace feed
-
-#endif  // CHROME_BROWSER_ANDROID_FEED_FEED_CONTENT_BRIDGE_H_
diff --git a/chrome/browser/android/feed/feed_debugging_bridge.cc b/chrome/browser/android/feed/feed_debugging_bridge.cc
deleted file mode 100644
index 305d9ef1..0000000
--- a/chrome/browser/android/feed/feed_debugging_bridge.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/feed/feed_debugging_bridge.h"
-
-#include "base/android/jni_string.h"
-#include "chrome/android/chrome_jni_headers/FeedDebuggingBridge_jni.h"
-#include "url/gurl.h"
-
-namespace feed {
-
-GURL GetFeedFetchUrlForDebugging() {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  base::android::ScopedJavaLocalRef<jstring> j_string =
-      Java_FeedDebuggingBridge_getFeedFetchUrl(env);
-  return GURL(ConvertJavaStringToUTF8(env, j_string));
-}
-
-std::string GetFeedProcessScopeDumpForDebugging() {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  base::android::ScopedJavaLocalRef<jstring> j_string =
-      Java_FeedDebuggingBridge_getProcessScopeDump(env);
-  return ConvertJavaStringToUTF8(env, j_string);
-}
-
-void TriggerRefreshForDebugging() {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  Java_FeedDebuggingBridge_triggerRefresh(env);
-}
-
-}  // namespace feed
diff --git a/chrome/browser/android/feed/feed_debugging_bridge.h b/chrome/browser/android/feed/feed_debugging_bridge.h
deleted file mode 100644
index daf587e6..0000000
--- a/chrome/browser/android/feed/feed_debugging_bridge.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_FEED_FEED_DEBUGGING_BRIDGE_H_
-#define CHROME_BROWSER_ANDROID_FEED_FEED_DEBUGGING_BRIDGE_H_
-
-#include <jni.h>
-#include <string>
-
-class GURL;
-
-// Native counterpart of FeedDebuggingBridge.java.
-namespace feed {
-
-GURL GetFeedFetchUrlForDebugging();
-
-std::string GetFeedProcessScopeDumpForDebugging();
-
-void TriggerRefreshForDebugging();
-
-}  // namespace feed
-
-#endif  // CHROME_BROWSER_ANDROID_FEED_FEED_DEBUGGING_BRIDGE_H_
diff --git a/chrome/browser/android/feed/feed_host_service_factory.cc b/chrome/browser/android/feed/feed_host_service_factory.cc
deleted file mode 100644
index d60916b..0000000
--- a/chrome/browser/android/feed/feed_host_service_factory.cc
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/feed/feed_host_service_factory.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/feature_list.h"
-#include "base/files/file_path.h"
-#include "base/time/default_clock.h"
-#include "base/time/default_tick_clock.h"
-#include "chrome/browser/android/feed/history/feed_history_helper.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/history/history_service_factory.h"
-#include "chrome/browser/offline_pages/offline_page_model_factory.h"
-#include "chrome/browser/offline_pages/prefetch/prefetch_service_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_key.h"
-#include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/common/channel_info.h"
-#include "components/feed/content/feed_host_service.h"
-#include "components/feed/content/feed_offline_host.h"
-#include "components/feed/core/feed_content_database.h"
-#include "components/feed/core/feed_journal_database.h"
-#include "components/feed/core/feed_logging_metrics.h"
-#include "components/feed/core/feed_networking_host.h"
-#include "components/feed/core/feed_scheduler_host.h"
-#include "components/feed/feed_feature_list.h"
-#include "components/keyed_service/content/browser_context_dependency_manager.h"
-#include "components/version_info/version_info.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/storage_partition.h"
-#include "google_apis/google_api_keys.h"
-
-namespace history {
-class HistoryService;
-}
-
-namespace feed {
-
-namespace {
-const char kFeedFolder[] = "feed";
-}  // namespace
-
-// static
-FeedHostService* FeedHostServiceFactory::GetForBrowserContext(
-    content::BrowserContext* context) {
-  return static_cast<FeedHostService*>(
-      GetInstance()->GetServiceForBrowserContext(context, true));
-}
-
-// static
-FeedHostServiceFactory* FeedHostServiceFactory::GetInstance() {
-  return base::Singleton<FeedHostServiceFactory>::get();
-}
-
-FeedHostServiceFactory::FeedHostServiceFactory()
-    : BrowserContextKeyedServiceFactory(
-          "FeedHostService",
-          BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(IdentityManagerFactory::GetInstance());
-  // Depends on offline_pages::OfflinePageModelFactory in
-  // SimpleDependencyManager.
-  DependsOn(offline_pages::PrefetchServiceFactory::GetInstance());
-  DependsOn(HistoryServiceFactory::GetInstance());
-}
-
-FeedHostServiceFactory::~FeedHostServiceFactory() = default;
-
-KeyedService* FeedHostServiceFactory::BuildServiceInstanceFor(
-    content::BrowserContext* context) const {
-  // Code here is not compatible with V2.
-  DCHECK(!feed::IsV2Enabled());
-
-  Profile* profile = Profile::FromBrowserContext(context);
-
-  content::StoragePartition* storage_partition =
-      content::BrowserContext::GetDefaultStoragePartition(context);
-
-  signin::IdentityManager* identity_manager =
-      IdentityManagerFactory::GetForProfile(profile);
-  std::string api_key;
-  if (google_apis::IsGoogleChromeAPIKeyUsed()) {
-    bool is_stable_channel =
-        chrome::GetChannel() == version_info::Channel::STABLE;
-    api_key = is_stable_channel ? google_apis::GetAPIKey()
-                                : google_apis::GetNonStableAPIKey();
-  }
-  auto networking_host = std::make_unique<FeedNetworkingHost>(
-      identity_manager, api_key,
-      storage_partition->GetURLLoaderFactoryForBrowserProcess(),
-      base::DefaultTickClock::GetInstance(), profile->GetPrefs());
-
-  auto scheduler_host = std::make_unique<FeedSchedulerHost>(
-      profile->GetPrefs(), g_browser_process->local_state(),
-      base::DefaultClock::GetInstance());
-
-  base::FilePath feed_dir(profile->GetPath().Append(kFeedFolder));
-  leveldb_proto::ProtoDatabaseProvider* proto_database_provider =
-      content::BrowserContext::GetDefaultStoragePartition(profile)
-          ->GetProtoDatabaseProvider();
-  auto content_database =
-      std::make_unique<FeedContentDatabase>(proto_database_provider, feed_dir);
-  auto journal_database =
-      std::make_unique<FeedJournalDatabase>(proto_database_provider, feed_dir);
-
-  offline_pages::OfflinePageModel* offline_page_model =
-      offline_pages::OfflinePageModelFactory::GetForBrowserContext(profile);
-  offline_pages::PrefetchService* prefetch_service =
-      offline_pages::PrefetchServiceFactory::GetForKey(
-          profile->GetProfileKey());
-  // Using base::Unretained is safe because the FeedSchedulerHost ensures the
-  // |scheduler_host| will outlive the |offline_host|, and calls to
-  // |the scheduler_host| are never posted to a message loop.
-  auto offline_host = std::make_unique<FeedOfflineHost>(
-      offline_page_model, prefetch_service,
-      base::BindRepeating(&FeedSchedulerHost::OnSuggestionConsumed,
-                          base::Unretained(scheduler_host.get())),
-      base::BindRepeating(&FeedSchedulerHost::OnSuggestionsShown,
-                          base::Unretained(scheduler_host.get())));
-
-  history::HistoryService* history_service =
-      HistoryServiceFactory::GetForProfile(profile,
-                                           ServiceAccessType::EXPLICIT_ACCESS);
-  auto history_helper = std::make_unique<FeedHistoryHelper>(history_service);
-  auto logging_metrics = std::make_unique<FeedLoggingMetrics>(
-      base::BindRepeating(&FeedHistoryHelper::CheckURL,
-                          std::move(history_helper)),
-      base::DefaultClock::GetInstance(), scheduler_host.get());
-
-  return new FeedHostService(
-      std::move(logging_metrics), std::move(networking_host),
-      std::move(scheduler_host), std::move(content_database),
-      std::move(journal_database), std::move(offline_host));
-}
-
-content::BrowserContext* FeedHostServiceFactory::GetBrowserContextToUse(
-    content::BrowserContext* context) const {
-  return context->IsOffTheRecord() ? nullptr : context;
-}
-
-bool FeedHostServiceFactory::ServiceIsNULLWhileTesting() const {
-  return true;
-}
-
-}  // namespace feed
diff --git a/chrome/browser/android/feed/feed_host_service_factory.h b/chrome/browser/android/feed/feed_host_service_factory.h
deleted file mode 100644
index 03c014c..0000000
--- a/chrome/browser/android/feed/feed_host_service_factory.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_FEED_FEED_HOST_SERVICE_FACTORY_H_
-#define CHROME_BROWSER_ANDROID_FEED_FEED_HOST_SERVICE_FACTORY_H_
-
-#include "base/macros.h"
-#include "base/memory/singleton.h"
-#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
-
-namespace content {
-class BrowserContext;
-}
-
-namespace feed {
-
-class FeedHostService;
-
-// Factory to create one FeedHostService per browser context. Callers need to
-// watch out for nullptr when incognito, as the feed should not be used then.
-class FeedHostServiceFactory : public BrowserContextKeyedServiceFactory {
- public:
-  static FeedHostService* GetForBrowserContext(
-      content::BrowserContext* context);
-
-  static FeedHostServiceFactory* GetInstance();
-
- private:
-  friend struct base::DefaultSingletonTraits<FeedHostServiceFactory>;
-
-  FeedHostServiceFactory();
-  ~FeedHostServiceFactory() override;
-
-  // BrowserContextKeyedServiceFactory:
-  KeyedService* BuildServiceInstanceFor(
-      content::BrowserContext* context) const override;
-  content::BrowserContext* GetBrowserContextToUse(
-      content::BrowserContext* context) const override;
-  bool ServiceIsNULLWhileTesting() const override;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedHostServiceFactory);
-};
-
-}  // namespace feed
-
-#endif  // CHROME_BROWSER_ANDROID_FEED_FEED_HOST_SERVICE_FACTORY_H_
diff --git a/chrome/browser/android/feed/feed_journal_bridge.cc b/chrome/browser/android/feed/feed_journal_bridge.cc
deleted file mode 100644
index d189271..0000000
--- a/chrome/browser/android/feed/feed_journal_bridge.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/feed/feed_journal_bridge.h"
-
-#include <jni.h>
-
-#include <list>
-#include <memory>
-#include <utility>
-
-#include "base/android/callback_android.h"
-#include "base/android/jni_array.h"
-#include "base/android/jni_string.h"
-#include "base/bind.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "chrome/android/chrome_jni_headers/FeedJournalBridge_jni.h"
-#include "chrome/browser/android/feed/feed_host_service_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_android.h"
-#include "components/feed/content/feed_host_service.h"
-#include "components/feed/core/feed_journal_database.h"
-#include "components/feed/core/feed_journal_mutation.h"
-
-namespace feed {
-
-using base::android::AttachCurrentThread;
-using base::android::JavaByteArrayToByteVector;
-using base::android::JavaRef;
-using base::android::JavaParamRef;
-using base::android::ScopedJavaGlobalRef;
-using base::android::ScopedJavaLocalRef;
-using base::android::ToJavaArrayOfByteArray;
-using base::android::ToJavaArrayOfStrings;
-
-static jlong JNI_FeedJournalBridge_Init(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& j_this,
-    const JavaParamRef<jobject>& j_profile) {
-  Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
-  FeedHostService* host_service =
-      FeedHostServiceFactory::GetForBrowserContext(profile);
-  DCHECK(host_service);
-  FeedJournalDatabase* feed_journal_database =
-      host_service->GetJournalDatabase();
-  DCHECK(feed_journal_database);
-  FeedJournalBridge* native_journal_bridge =
-      new FeedJournalBridge(feed_journal_database);
-  return reinterpret_cast<intptr_t>(native_journal_bridge);
-}
-
-FeedJournalBridge::FeedJournalBridge(FeedJournalDatabase* feed_journal_database)
-    : feed_journal_database_(feed_journal_database) {
-  DCHECK(feed_journal_database_);
-}
-
-FeedJournalBridge::~FeedJournalBridge() = default;
-
-void FeedJournalBridge::Destroy(JNIEnv* env, const JavaRef<jobject>& j_this) {
-  delete this;
-}
-
-void FeedJournalBridge::LoadJournal(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const JavaRef<jstring>& j_journal_name,
-    const JavaRef<jobject>& j_success_callback,
-    const JavaRef<jobject>& j_failure_callback) {
-  std::string journal_name = ConvertJavaStringToUTF8(j_env, j_journal_name);
-  ScopedJavaGlobalRef<jobject> success_callback(j_success_callback);
-  ScopedJavaGlobalRef<jobject> failure_callback(j_failure_callback);
-
-  feed_journal_database_->LoadJournal(
-      journal_name, base::BindOnce(&FeedJournalBridge::OnLoadJournalDone,
-                                   weak_ptr_factory_.GetWeakPtr(),
-                                   success_callback, failure_callback));
-}
-
-void FeedJournalBridge::CommitJournalMutation(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const JavaRef<jobject>& j_callback) {
-  DCHECK(journal_mutation_);
-  ScopedJavaGlobalRef<jobject> callback(j_callback);
-
-  feed_journal_database_->CommitJournalMutation(
-      std::move(journal_mutation_),
-      base::BindOnce(&FeedJournalBridge::OnStorageBooleanCallbackDone,
-                     weak_ptr_factory_.GetWeakPtr(), callback));
-}
-
-void FeedJournalBridge::DoesJournalExist(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const JavaRef<jstring>& j_journal_name,
-    const JavaRef<jobject>& j_success_callback,
-    const JavaRef<jobject>& j_failure_callback) {
-  std::string journal_name = ConvertJavaStringToUTF8(j_env, j_journal_name);
-  ScopedJavaGlobalRef<jobject> success_callback(j_success_callback);
-  ScopedJavaGlobalRef<jobject> failure_callback(j_failure_callback);
-
-  feed_journal_database_->DoesJournalExist(
-      journal_name,
-      base::BindOnce(&FeedJournalBridge::OnStorageCheckExistingCallbackDone,
-                     weak_ptr_factory_.GetWeakPtr(), success_callback,
-                     failure_callback));
-}
-
-void FeedJournalBridge::LoadAllJournalKeys(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const JavaRef<jobject>& j_success_callback,
-    const JavaRef<jobject>& j_failure_callback) {
-  ScopedJavaGlobalRef<jobject> success_callback(j_success_callback);
-  ScopedJavaGlobalRef<jobject> failure_callback(j_failure_callback);
-
-  feed_journal_database_->LoadAllJournalKeys(base::BindOnce(
-      &FeedJournalBridge::OnLoadJournalKeyDone, weak_ptr_factory_.GetWeakPtr(),
-      success_callback, failure_callback));
-}
-
-void FeedJournalBridge::DeleteAllJournals(JNIEnv* j_env,
-                                          const JavaRef<jobject>& j_this,
-                                          const JavaRef<jobject>& j_callback) {
-  ScopedJavaGlobalRef<jobject> callback(j_callback);
-
-  feed_journal_database_->DeleteAllJournals(
-      base::BindOnce(&FeedJournalBridge::OnStorageBooleanCallbackDone,
-                     weak_ptr_factory_.GetWeakPtr(), callback));
-}
-
-void FeedJournalBridge::StartJournalMutation(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const JavaRef<jstring>& j_journal_name) {
-  DCHECK(!journal_mutation_);
-  std::string journal_name = ConvertJavaStringToUTF8(j_env, j_journal_name);
-  journal_mutation_ =
-      std::make_unique<JournalMutation>(std::move(journal_name));
-}
-
-void FeedJournalBridge::DeleteJournalMutation(JNIEnv* j_env,
-                                              const JavaRef<jobject>& j_this) {
-  DCHECK(journal_mutation_);
-  journal_mutation_.reset();
-}
-
-void FeedJournalBridge::AddAppendOperation(JNIEnv* j_env,
-                                           const JavaRef<jobject>& j_this,
-                                           const JavaRef<jbyteArray>& j_value) {
-  DCHECK(journal_mutation_);
-  std::vector<uint8_t> bytes_vector;
-  JavaByteArrayToByteVector(j_env, j_value, &bytes_vector);
-  journal_mutation_->AddAppendOperation(
-      std::string(bytes_vector.begin(), bytes_vector.end()));
-}
-
-void FeedJournalBridge::AddCopyOperation(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const JavaRef<jstring>& j_to_journal_name) {
-  DCHECK(journal_mutation_);
-  std::string to_journal_name =
-      ConvertJavaStringToUTF8(j_env, j_to_journal_name);
-  journal_mutation_->AddCopyOperation(std::move(to_journal_name));
-}
-
-void FeedJournalBridge::AddDeleteOperation(JNIEnv* j_env,
-                                           const JavaRef<jobject>& j_this) {
-  DCHECK(journal_mutation_);
-  journal_mutation_->AddDeleteOperation();
-}
-
-void FeedJournalBridge::OnLoadJournalDone(
-    ScopedJavaGlobalRef<jobject> success_callback,
-    ScopedJavaGlobalRef<jobject> failure_callback,
-    bool success,
-    std::vector<std::string> entries) {
-  JNIEnv* env = AttachCurrentThread();
-
-  if (success) {
-    RunObjectCallbackAndroid(success_callback,
-                             ToJavaArrayOfByteArray(env, entries));
-  } else {
-    RunObjectCallbackAndroid(failure_callback, nullptr);
-  }
-}
-
-void FeedJournalBridge::OnLoadJournalKeyDone(
-    ScopedJavaGlobalRef<jobject> success_callback,
-    ScopedJavaGlobalRef<jobject> failure_callback,
-    bool success,
-    std::vector<std::string> entries) {
-  JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jobjectArray> j_entries =
-      ToJavaArrayOfStrings(env, entries);
-
-  if (success) {
-    RunObjectCallbackAndroid(success_callback, j_entries);
-  } else {
-    RunObjectCallbackAndroid(failure_callback, nullptr);
-  }
-}
-
-void FeedJournalBridge::OnStorageCheckExistingCallbackDone(
-    ScopedJavaGlobalRef<jobject> success_callback,
-    ScopedJavaGlobalRef<jobject> failure_callback,
-    bool success,
-    bool exists) {
-  if (success) {
-    RunBooleanCallbackAndroid(success_callback, exists);
-  } else {
-    RunObjectCallbackAndroid(failure_callback, nullptr);
-  }
-}
-
-void FeedJournalBridge::OnStorageBooleanCallbackDone(
-    ScopedJavaGlobalRef<jobject> callback,
-    bool exists) {
-  RunBooleanCallbackAndroid(callback, exists);
-}
-
-}  // namespace feed
diff --git a/chrome/browser/android/feed/feed_journal_bridge.h b/chrome/browser/android/feed/feed_journal_bridge.h
deleted file mode 100644
index 466d0051..0000000
--- a/chrome/browser/android/feed/feed_journal_bridge.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_FEED_FEED_JOURNAL_BRIDGE_H_
-#define CHROME_BROWSER_ANDROID_FEED_FEED_JOURNAL_BRIDGE_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/android/scoped_java_ref.h"
-#include "base/memory/weak_ptr.h"
-
-namespace feed {
-
-class FeedJournalDatabase;
-class JournalMutation;
-
-// Native counterpart of FeedJournalBridge.java. Holds non-owning pointers
-// to native implementation to which operations are delegated. Results are
-// passed back by a single argument callback so
-// base::android::RunBooleanCallbackAndroid() and
-// base::android::RunObjectCallbackAndroid() can be used. This bridge is
-// instantiated, owned, and destroyed from Java.
-class FeedJournalBridge {
- public:
-  explicit FeedJournalBridge(FeedJournalDatabase* feed_Storage_database);
-  ~FeedJournalBridge();
-
-  void Destroy(JNIEnv* j_env, const base::android::JavaRef<jobject>& j_this);
-
-  // Database related methods, they add/delete/update database.
-  void LoadJournal(JNIEnv* j_env,
-                   const base::android::JavaRef<jobject>& j_this,
-                   const base::android::JavaRef<jstring>& j_journal_name,
-                   const base::android::JavaRef<jobject>& j_success_callback,
-                   const base::android::JavaRef<jobject>& j_failure_callback);
-  void CommitJournalMutation(JNIEnv* j_env,
-                             const base::android::JavaRef<jobject>& j_this,
-                             const base::android::JavaRef<jobject>& j_callback);
-  void DoesJournalExist(
-      JNIEnv* j_env,
-      const base::android::JavaRef<jobject>& j_this,
-      const base::android::JavaRef<jstring>& j_journal_name,
-      const base::android::JavaRef<jobject>& j_success_callback,
-      const base::android::JavaRef<jobject>& j_failure_callback);
-  void LoadAllJournalKeys(
-      JNIEnv* j_env,
-      const base::android::JavaRef<jobject>& j_this,
-      const base::android::JavaRef<jobject>& j_success_callback,
-      const base::android::JavaRef<jobject>& j_failure_callback);
-  void DeleteAllJournals(JNIEnv* j_env,
-                         const base::android::JavaRef<jobject>& j_this,
-                         const base::android::JavaRef<jobject>& j_callback);
-
-  // The following  methods create/delete mutation, and add operations into
-  // mutation.
-  void StartJournalMutation(
-      JNIEnv* j_env,
-      const base::android::JavaRef<jobject>& j_this,
-      const base::android::JavaRef<jstring>& j_journal_name);
-  void DeleteJournalMutation(JNIEnv* j_env,
-                             const base::android::JavaRef<jobject>& j_this);
-  void AddAppendOperation(JNIEnv* j_env,
-                          const base::android::JavaRef<jobject>& j_this,
-                          const base::android::JavaRef<jbyteArray>& j_value);
-  void AddCopyOperation(
-      JNIEnv* j_env,
-      const base::android::JavaRef<jobject>& j_this,
-      const base::android::JavaRef<jstring>& j_to_journal_name);
-  void AddDeleteOperation(JNIEnv* j_env,
-                          const base::android::JavaRef<jobject>& j_this);
-
- private:
-  void OnLoadJournalDone(
-      base::android::ScopedJavaGlobalRef<jobject> success_callback,
-      base::android::ScopedJavaGlobalRef<jobject> failure_callback,
-      bool success,
-      std::vector<std::string> entries);
-  void OnLoadJournalKeyDone(
-      base::android::ScopedJavaGlobalRef<jobject> success_callback,
-      base::android::ScopedJavaGlobalRef<jobject> failure_callback,
-      bool success,
-      std::vector<std::string> entries);
-  void OnStorageCheckExistingCallbackDone(
-      base::android::ScopedJavaGlobalRef<jobject> success_callback,
-      base::android::ScopedJavaGlobalRef<jobject> failure_callback,
-      bool success,
-      bool exists);
-  void OnStorageBooleanCallbackDone(
-      base::android::ScopedJavaGlobalRef<jobject> callback,
-      bool exists);
-
-  // This unique_ptr will hold a list of JournalOperations which are not
-  // committed yet. After send |journal_mutation_| to database, this unique_ptr
-  // will be reset.
-  std::unique_ptr<JournalMutation> journal_mutation_;
-
-  FeedJournalDatabase* feed_journal_database_;
-
-  base::WeakPtrFactory<FeedJournalBridge> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FeedJournalBridge);
-};
-
-}  // namespace feed
-
-#endif  // CHROME_BROWSER_ANDROID_FEED_FEED_JOURNAL_BRIDGE_H_
diff --git a/chrome/browser/android/feed/feed_lifecycle_bridge.cc b/chrome/browser/android/feed/feed_lifecycle_bridge.cc
deleted file mode 100644
index 5ff64fd..0000000
--- a/chrome/browser/android/feed/feed_lifecycle_bridge.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/feed/feed_lifecycle_bridge.h"
-
-#include "base/android/jni_android.h"
-#include "base/metrics/histogram_macros.h"
-#include "chrome/android/chrome_jni_headers/FeedLifecycleBridge_jni.h"
-#include "chrome/browser/history/history_service_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_android.h"
-#include "components/history/core/browser/history_service.h"
-
-using base::android::JavaRef;
-using base::android::JavaParamRef;
-
-namespace feed {
-
-static jlong JNI_FeedLifecycleBridge_Init(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& j_this,
-    const JavaParamRef<jobject>& j_profile) {
-  Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
-  return reinterpret_cast<intptr_t>(new FeedLifecycleBridge(profile));
-}
-
-FeedLifecycleBridge::FeedLifecycleBridge(Profile* profile) : profile_(profile) {
-  history::HistoryService* history_service =
-      HistoryServiceFactory::GetForProfile(profile_,
-                                           ServiceAccessType::IMPLICIT_ACCESS);
-  if (history_service)
-    history_service_observation_.Observe(history_service);
-}
-
-FeedLifecycleBridge::~FeedLifecycleBridge() {
-  history::HistoryService* history_service =
-      HistoryServiceFactory::GetForProfile(profile_,
-                                           ServiceAccessType::IMPLICIT_ACCESS);
-  if (history_service)
-    history_service_observation_.Reset();
-}
-
-void FeedLifecycleBridge::Destroy(JNIEnv* env, const JavaRef<jobject>& j_this) {
-  delete this;
-}
-
-void FeedLifecycleBridge::OnURLsDeleted(
-    history::HistoryService* history_service,
-    const history::DeletionInfo& deletion_info) {
-  // We ignore expirations since they're not user-initiated.
-  if (deletion_info.is_from_expiration()) {
-    return;
-  }
-
-  // If a user deletes a single URL, we don't consider this a clear user intent
-  // to clear our data.
-  if (deletion_info.IsAllHistory() || deletion_info.deleted_rows().size() > 1) {
-    if (!deletion_info.IsAllHistory()) {
-      UMA_HISTOGRAM_EXACT_LINEAR(
-          "ContentSuggestions.Feed.AppLifecycle.NumRowsForDeletion",
-          deletion_info.deleted_rows().size(), 50);
-    }
-
-    JNIEnv* env = base::android::AttachCurrentThread();
-    Java_FeedLifecycleBridge_onHistoryDeleted(env);
-  }
-}
-
-// static
-void FeedLifecycleBridge::ClearCachedData() {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  Java_FeedLifecycleBridge_onCachedDataCleared(env);
-}
-
-}  // namespace feed
diff --git a/chrome/browser/android/feed/feed_lifecycle_bridge.h b/chrome/browser/android/feed/feed_lifecycle_bridge.h
deleted file mode 100644
index eb4a956..0000000
--- a/chrome/browser/android/feed/feed_lifecycle_bridge.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_FEED_FEED_LIFECYCLE_BRIDGE_H_
-#define CHROME_BROWSER_ANDROID_FEED_FEED_LIFECYCLE_BRIDGE_H_
-
-#include <jni.h>
-
-#include "base/android/scoped_java_ref.h"
-#include "base/macros.h"
-#include "base/scoped_observation.h"
-#include "components/history/core/browser/history_service.h"
-#include "components/history/core/browser/history_service_observer.h"
-
-class Profile;
-
-namespace feed {
-
-// Native counterpart of FeedLifecycleBridge.java. Receives lifecycle events
-// that originate in native code (namely, history deletion and cached data
-// clearing) and forwards them to Java so that the Feed library can be notified.
-class FeedLifecycleBridge : public history::HistoryServiceObserver {
- public:
-  explicit FeedLifecycleBridge(Profile* profile);
-  ~FeedLifecycleBridge() override;
-
-  void Destroy(JNIEnv* env, const base::android::JavaRef<jobject>& j_this);
-
-  // Overridden from history::HistoryServiceObserver.
-  void OnURLsDeleted(history::HistoryService* history_service,
-                     const history::DeletionInfo& deletion_info) override;
-
-  // Triggers clearing of all data cached by the Feed library. This should only
-  // be called if Feed is enabled.
-  static void ClearCachedData();
-
- private:
-  // Reference to the Java half of this bridge. Always valid.
-  base::android::ScopedJavaGlobalRef<jobject> j_this_;
-
-  Profile* profile_;
-
-  base::ScopedObservation<history::HistoryService,
-                          history::HistoryServiceObserver>
-      history_service_observation_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FeedLifecycleBridge);
-};
-
-}  // namespace feed
-
-#endif  // CHROME_BROWSER_ANDROID_FEED_FEED_LIFECYCLE_BRIDGE_H_
diff --git a/chrome/browser/android/feed/feed_logging_bridge.cc b/chrome/browser/android/feed/feed_logging_bridge.cc
deleted file mode 100644
index a890c44..0000000
--- a/chrome/browser/android/feed/feed_logging_bridge.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/feed/feed_logging_bridge.h"
-
-#include <jni.h>
-#include <vector>
-
-#include "base/android/jni_array.h"
-#include "base/android/jni_string.h"
-#include "base/time/time.h"
-#include "chrome/android/chrome_jni_headers/FeedLoggingBridge_jni.h"
-#include "chrome/browser/android/feed/feed_host_service_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_android.h"
-#include "components/feed/content/feed_host_service.h"
-#include "components/feed/core/feed_logging_metrics.h"
-
-namespace feed {
-
-using base::android::JavaRef;
-using base::android::JavaParamRef;
-
-static jlong JNI_FeedLoggingBridge_Init(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& j_this,
-    const JavaParamRef<jobject>& j_profile) {
-  Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
-  FeedHostService* host_service =
-      FeedHostServiceFactory::GetForBrowserContext(profile);
-  FeedLoggingMetrics* feed_logging_metrics = host_service->GetLoggingMetrics();
-  FeedLoggingBridge* native_logging_bridge =
-      new FeedLoggingBridge(feed_logging_metrics);
-  return reinterpret_cast<intptr_t>(native_logging_bridge);
-}
-
-FeedLoggingBridge::FeedLoggingBridge(FeedLoggingMetrics* feed_logging_metrics)
-    : feed_logging_metrics_(feed_logging_metrics) {
-  DCHECK(feed_logging_metrics_);
-}
-
-FeedLoggingBridge::~FeedLoggingBridge() = default;
-
-void FeedLoggingBridge::Destroy(JNIEnv* j_env, const JavaRef<jobject>& j_this) {
-  delete this;
-}
-
-void FeedLoggingBridge::OnContentViewed(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const jint j_position,
-    const jlong j_publishedTimeMs,
-    const jlong j_timeContentBecameAvailableMs,
-    const jfloat j_score,
-    const jboolean j_is_available_offline) {
-  feed_logging_metrics_->OnSuggestionShown(
-      j_position, base::Time::FromJavaTime(j_publishedTimeMs), j_score,
-      base::Time::FromJavaTime(j_timeContentBecameAvailableMs),
-      j_is_available_offline);
-}
-
-void FeedLoggingBridge::OnContentDismissed(JNIEnv* j_env,
-                                           const JavaRef<jobject>& j_this,
-                                           const jint j_position,
-                                           const JavaRef<jstring>& j_url,
-                                           const jboolean j_was_committed) {
-  feed_logging_metrics_->OnSuggestionDismissed(
-      j_position, GURL(ConvertJavaStringToUTF8(j_env, j_url)), j_was_committed);
-}
-
-void FeedLoggingBridge::OnContentSwiped(JNIEnv* j_env,
-                                        const JavaRef<jobject>& j_this) {
-  feed_logging_metrics_->OnSuggestionSwiped();
-}
-
-void FeedLoggingBridge::OnClientAction(JNIEnv* j_env,
-                                       const JavaRef<jobject>& j_this,
-                                       const jint j_window_open_disposition,
-                                       const jint j_position,
-                                       const jlong j_publishedTimeMs,
-                                       const jfloat j_score,
-                                       const jboolean j_is_available_offline) {
-  feed_logging_metrics_->OnSuggestionOpened(
-      j_position, base::Time::FromJavaTime(j_publishedTimeMs), j_score,
-      j_is_available_offline);
-  feed_logging_metrics_->OnSuggestionWindowOpened(
-      static_cast<WindowOpenDisposition>(j_window_open_disposition));
-}
-
-void FeedLoggingBridge::OnContentContextMenuOpened(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const jint j_position,
-    const jlong j_publishedTimeMs,
-    const jfloat j_score) {
-  feed_logging_metrics_->OnSuggestionMenuOpened(
-      j_position, base::Time::FromJavaTime(j_publishedTimeMs), j_score);
-}
-
-void FeedLoggingBridge::OnMoreButtonViewed(JNIEnv* j_env,
-                                           const JavaRef<jobject>& j_this,
-                                           const jint j_position) {
-  feed_logging_metrics_->OnMoreButtonShown(j_position);
-}
-
-void FeedLoggingBridge::OnMoreButtonClicked(JNIEnv* j_env,
-                                            const JavaRef<jobject>& j_this,
-                                            const jint j_position) {
-  feed_logging_metrics_->OnMoreButtonClicked(j_position);
-}
-
-void FeedLoggingBridge::OnNotInterestedInSource(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const jint j_position,
-    const jboolean j_was_committed) {
-  feed_logging_metrics_->OnNotInterestedInSource(j_position, j_was_committed);
-}
-
-void FeedLoggingBridge::OnNotInterestedInTopic(JNIEnv* j_env,
-                                               const JavaRef<jobject>& j_this,
-                                               const jint j_position,
-                                               const jboolean j_was_committed) {
-  feed_logging_metrics_->OnNotInterestedInTopic(j_position, j_was_committed);
-}
-
-void FeedLoggingBridge::OnOpenedWithContent(JNIEnv* j_env,
-                                            const JavaRef<jobject>& j_this,
-                                            const jlong j_time_to_populate,
-                                            const jint j_content_count) {
-  feed_logging_metrics_->OnPageShown(j_content_count);
-  feed_logging_metrics_->OnPagePopulated(
-      base::TimeDelta::FromMilliseconds(j_time_to_populate));
-}
-
-void FeedLoggingBridge::OnOpenedWithNoImmediateContent(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this) {}
-
-void FeedLoggingBridge::OnOpenedWithNoContent(JNIEnv* j_env,
-                                              const JavaRef<jobject>& j_this) {
-  feed_logging_metrics_->OnPageShown(/*suggestions_count=*/0);
-}
-
-void FeedLoggingBridge::OnSpinnerStarted(JNIEnv* j_env,
-                                         const JavaRef<jobject>& j_this,
-                                         const jint j_spinner_type) {
-  feed_logging_metrics_->OnSpinnerStarted(j_spinner_type);
-}
-
-void FeedLoggingBridge::OnSpinnerFinished(JNIEnv* j_env,
-                                          const JavaRef<jobject>& j_this,
-                                          const jlong j_shownTimeMs,
-                                          const jint j_spinner_type) {
-  feed_logging_metrics_->OnSpinnerFinished(
-      base::TimeDelta::FromMilliseconds(j_shownTimeMs), j_spinner_type);
-}
-
-void FeedLoggingBridge::OnSpinnerDestroyedWithoutCompleting(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const jlong j_shownTimeMs,
-    const jint j_spinner_type) {
-  feed_logging_metrics_->OnSpinnerDestroyedWithoutCompleting(
-      base::TimeDelta::FromMilliseconds(j_shownTimeMs), j_spinner_type);
-}
-
-void FeedLoggingBridge::OnPietFrameRenderingEvent(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this,
-    const JavaRef<jintArray>& j_piet_error_codes) {
-  std::vector<int> piet_error_codes;
-  base::android::JavaIntArrayToIntVector(j_env, j_piet_error_codes,
-                                         &piet_error_codes);
-  feed_logging_metrics_->OnPietFrameRenderingEvent(std::move(piet_error_codes));
-}
-
-void FeedLoggingBridge::OnVisualElementClicked(
-    JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this,
-    const jint j_element_type,
-    const jint j_position,
-    const jlong j_timeContentBecameAvailableMs) {
-  feed_logging_metrics_->OnVisualElementClicked(
-      j_element_type, j_position,
-      base::Time::FromJavaTime(j_timeContentBecameAvailableMs));
-}
-
-void FeedLoggingBridge::OnVisualElementViewed(
-    JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this,
-    const jint j_element_type,
-    const jint j_position,
-    const jlong j_timeContentBecameAvailableMs) {
-  feed_logging_metrics_->OnVisualElementViewed(
-      j_element_type, j_position,
-      base::Time::FromJavaTime(j_timeContentBecameAvailableMs));
-}
-
-void FeedLoggingBridge::OnInternalError(JNIEnv* j_env,
-                                        const JavaRef<jobject>& j_this,
-                                        const jint j_internal_error) {
-  feed_logging_metrics_->OnInternalError(j_internal_error);
-}
-
-void FeedLoggingBridge::OnTokenCompleted(
-    JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this,
-    const jboolean j_was_synthetic,
-    const jint j_content_count,
-    const jint j_token_count) {
-  feed_logging_metrics_->OnTokenCompleted(j_was_synthetic, j_content_count,
-                                          j_token_count);
-}
-
-void FeedLoggingBridge::OnTokenFailedToComplete(
-    JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this,
-    const jboolean j_was_synthetic,
-    const jint j_failure_count) {
-  feed_logging_metrics_->OnTokenFailedToComplete(j_was_synthetic,
-                                                 j_failure_count);
-}
-
-void FeedLoggingBridge::OnServerRequest(
-    JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this,
-    const jint j_request_reason) {
-  feed_logging_metrics_->OnServerRequest(j_request_reason);
-}
-
-void FeedLoggingBridge::OnZeroStateShown(
-    JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this,
-    const jint j_zero_state_show_reason) {
-  feed_logging_metrics_->OnZeroStateShown(j_zero_state_show_reason);
-}
-
-void FeedLoggingBridge::OnZeroStateRefreshCompleted(
-    JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this,
-    const jint j_new_content_count,
-    const jint j_new_token_count) {
-  feed_logging_metrics_->OnZeroStateRefreshCompleted(j_new_content_count,
-                                                     j_new_token_count);
-}
-
-void FeedLoggingBridge::OnTaskFinished(
-    JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this,
-    const jint j_task_type,
-    const jint j_delay_time_ms,
-    const jint j_task_time_ms) {
-  feed_logging_metrics_->OnTaskFinished(j_task_type, j_delay_time_ms,
-                                        j_task_time_ms);
-}
-
-void FeedLoggingBridge::OnContentTargetVisited(JNIEnv* j_env,
-                                               const JavaRef<jobject>& j_this,
-                                               const jlong visit_time_ms,
-                                               const jboolean j_return_to_ntp) {
-  feed_logging_metrics_->OnSuggestionArticleVisited(
-      base::TimeDelta::FromMilliseconds(visit_time_ms), j_return_to_ntp);
-}
-
-void FeedLoggingBridge::ReportScrolledAfterOpen(
-    JNIEnv* j_env,
-    const JavaRef<jobject>& j_this) {
-  feed_logging_metrics_->ReportScrolledAfterOpen();
-}
-
-}  // namespace feed
diff --git a/chrome/browser/android/feed/feed_logging_bridge.h b/chrome/browser/android/feed/feed_logging_bridge.h
deleted file mode 100644
index 3fa0de5..0000000
--- a/chrome/browser/android/feed/feed_logging_bridge.h
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_FEED_FEED_LOGGING_BRIDGE_H_
-#define CHROME_BROWSER_ANDROID_FEED_FEED_LOGGING_BRIDGE_H_
-
-#include <utility>
-
-#include "base/android/scoped_java_ref.h"
-
-namespace feed {
-
-class FeedLoggingMetrics;
-
-// Native counterpart of FeedLoggingBridge.java. Holds non-owning pointers
-// to native implementation, to which operations are delegated. This bridge is
-// instantiated, owned, and destroyed from Java.
-class FeedLoggingBridge {
- public:
-  explicit FeedLoggingBridge(FeedLoggingMetrics* feed_logging_metrics);
-  ~FeedLoggingBridge();
-
-  void Destroy(JNIEnv* j_env, const base::android::JavaRef<jobject>& j_this);
-
-  void OnContentViewed(JNIEnv* j_env,
-                       const base::android::JavaRef<jobject>& j_this,
-                       const jint j_position,
-                       const jlong j_publishedTimeMs,
-                       const jlong j_timeContentBecameAvailableMs,
-                       const jfloat j_score,
-                       const jboolean j_is_available_offline);
-
-  void OnContentDismissed(JNIEnv* j_env,
-                          const base::android::JavaRef<jobject>& j_this,
-                          const jint j_position,
-                          const base::android::JavaRef<jstring>& j_url,
-                          const jboolean j_was_committed);
-
-  void OnContentSwiped(JNIEnv* j_env,
-                       const base::android::JavaRef<jobject>& j_this);
-
-  void OnClientAction(JNIEnv* j_env,
-                      const base::android::JavaRef<jobject>& j_this,
-                      const jint j_window_open_disposition,
-                      const jint j_position,
-                      const jlong j_publishedTimeMs,
-                      const jfloat j_score,
-                      const jboolean j_is_available_offline);
-
-  void OnContentContextMenuOpened(JNIEnv* j_env,
-                                  const base::android::JavaRef<jobject>& j_this,
-                                  const jint j_position,
-                                  const jlong j_publishedTimeMs,
-                                  const jfloat j_score);
-
-  void OnMoreButtonViewed(JNIEnv* j_env,
-                          const base::android::JavaRef<jobject>& j_this,
-                          const jint j_position);
-
-  void OnMoreButtonClicked(JNIEnv* j_env,
-                           const base::android::JavaRef<jobject>& j_this,
-                           const jint j_position);
-
-  void OnNotInterestedInSource(JNIEnv* j_env,
-                               const base::android::JavaRef<jobject>& j_this,
-                               const jint j_position,
-                               const jboolean j_was_committed);
-
-  void OnNotInterestedInTopic(JNIEnv* j_env,
-                              const base::android::JavaRef<jobject>& j_this,
-                              const jint j_position,
-                              const jboolean j_was_committed);
-
-  void OnOpenedWithContent(JNIEnv* j_env,
-                           const base::android::JavaRef<jobject>& j_this,
-                           const jlong j_time_to_populate,
-                           const jint j_content_count);
-
-  void OnOpenedWithNoImmediateContent(
-      JNIEnv* j_env,
-      const base::android::JavaRef<jobject>& j_this);
-
-  void OnOpenedWithNoContent(JNIEnv* j_env,
-                             const base::android::JavaRef<jobject>& j_this);
-
-  void OnSpinnerStarted(JNIEnv* j_env,
-                        const base::android::JavaRef<jobject>& j_this,
-                        const jint j_spinner_type);
-
-  void OnSpinnerFinished(JNIEnv* j_env,
-                         const base::android::JavaRef<jobject>& j_this,
-                         const jlong j_shownTimeMs,
-                         const jint j_spinner_type);
-
-  void OnSpinnerDestroyedWithoutCompleting(
-      JNIEnv* j_env,
-      const base::android::JavaRef<jobject>& j_this,
-      const jlong j_shownTimeMs,
-      const jint j_spinner_type);
-
-  void OnPietFrameRenderingEvent(
-      JNIEnv* j_env,
-      const base::android::JavaRef<jobject>& j_this,
-      const base::android::JavaRef<jintArray>& j_piet_error_codes);
-
-  void OnVisualElementClicked(JNIEnv* j_env,
-                              const base::android::JavaRef<jobject>& j_this,
-                              const jint j_element_type,
-                              const jint j_position,
-                              const jlong j_timeContentBecameAvailableMs);
-
-  void OnVisualElementViewed(JNIEnv* j_env,
-                             const base::android::JavaRef<jobject>& j_this,
-                             const jint j_element_type,
-                             const jint j_position,
-                             const jlong j_timeContentBecameAvailableMs);
-
-  void OnInternalError(JNIEnv* j_env,
-                       const base::android::JavaRef<jobject>& j_this,
-                       const jint j_internal_error);
-
-  void OnTokenCompleted(JNIEnv* j_env,
-                        const base::android::JavaRef<jobject>& j_this,
-                        const jboolean j_was_synthetic,
-                        const jint j_content_count,
-                        const jint j_token_count);
-
-  void OnTokenFailedToComplete(JNIEnv* j_env,
-                               const base::android::JavaRef<jobject>& j_this,
-                               const jboolean j_was_synthetic,
-                               const jint j_failure_count);
-
-  void OnServerRequest(JNIEnv* j_env,
-                       const base::android::JavaRef<jobject>& j_this,
-                       const jint j_request_reason);
-
-  void OnZeroStateShown(JNIEnv* j_env,
-                        const base::android::JavaRef<jobject>& j_this,
-                        const jint j_zero_state_show_reason);
-
-  void OnZeroStateRefreshCompleted(
-      JNIEnv* j_env,
-      const base::android::JavaRef<jobject>& j_this,
-      const jint j_new_content_count,
-      const jint j_new_token_count);
-
-  void OnTaskFinished(JNIEnv* j_env,
-                      const base::android::JavaRef<jobject>& j_this,
-                      const jint j_task_type,
-                      const jint j_delay_time_ms,
-                      const jint j_task_time_ms);
-
-  void OnContentTargetVisited(JNIEnv* j_env,
-                              const base::android::JavaRef<jobject>& j_this,
-                              const jlong visit_time_ms,
-                              const jboolean j_return_to_ntp);
-
-  void ReportScrolledAfterOpen(JNIEnv* j_env,
-                               const base::android::JavaRef<jobject>& j_this);
-
- private:
-  FeedLoggingMetrics* feed_logging_metrics_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedLoggingBridge);
-};
-
-}  // namespace feed
-
-#endif  // CHROME_BROWSER_ANDROID_FEED_FEED_LOGGING_BRIDGE_H_
diff --git a/chrome/browser/android/feed/feed_network_bridge.cc b/chrome/browser/android/feed/feed_network_bridge.cc
deleted file mode 100644
index 6c0f63e..0000000
--- a/chrome/browser/android/feed/feed_network_bridge.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/feed/feed_network_bridge.h"
-
-#include <utility>
-
-#include "base/android/callback_android.h"
-#include "base/android/jni_android.h"
-#include "base/android/jni_array.h"
-#include "base/android/jni_string.h"
-#include "base/bind.h"
-#include "base/memory/ptr_util.h"
-#include "base/trace_event/trace_event.h"
-#include "chrome/android/chrome_jni_headers/FeedNetworkBridge_jni.h"
-#include "chrome/browser/android/feed/feed_host_service_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_android.h"
-#include "components/feed/content/feed_host_service.h"
-#include "components/feed/core/feed_networking_host.h"
-
-using base::android::ConvertJavaStringToUTF8;
-using base::android::JavaParamRef;
-using base::android::ScopedJavaLocalRef;
-using base::android::ScopedJavaGlobalRef;
-
-namespace feed {
-
-FeedNetworkBridge::FeedNetworkBridge(const JavaParamRef<jobject>& j_profile) {
-  Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
-  FeedHostService* host_service =
-      FeedHostServiceFactory::GetForBrowserContext(profile);
-  networking_host_ = host_service->GetNetworkingHost();
-  DCHECK(networking_host_);
-}
-
-FeedNetworkBridge::~FeedNetworkBridge() = default;
-
-static jlong JNI_FeedNetworkBridge_Init(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& j_this,
-    const JavaParamRef<jobject>& j_profile) {
-  return reinterpret_cast<intptr_t>(new FeedNetworkBridge(j_profile));
-}
-
-void FeedNetworkBridge::Destroy(JNIEnv* env,
-                                const JavaParamRef<jobject>& j_this) {
-  delete this;
-}
-
-void FeedNetworkBridge::SendNetworkRequest(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& j_this,
-    const JavaParamRef<jstring>& j_url,
-    const JavaParamRef<jstring>& j_request_type,
-    const JavaParamRef<jbyteArray>& j_body,
-    const JavaParamRef<jobject>& j_callback) {
-  auto url = GURL(ConvertJavaStringToUTF8(env, j_url));
-  FeedNetworkingHost::ResponseCallback callback =
-      base::BindOnce(&FeedNetworkBridge::OnResult, weak_factory_.GetWeakPtr(),
-                     ScopedJavaGlobalRef<jobject>(env, j_callback));
-  std::vector<uint8_t> request_body;
-  base::android::JavaByteArrayToByteVector(env, j_body, &request_body);
-
-  networking_host_->Send(url, ConvertJavaStringToUTF8(env, j_request_type),
-                         std::move(request_body), std::move(callback));
-}
-
-void FeedNetworkBridge::CancelRequests(JNIEnv* env,
-                                       const JavaParamRef<jobject>& j_this) {
-  networking_host_->CancelRequests();
-}
-
-void FeedNetworkBridge::OnResult(const ScopedJavaGlobalRef<jobject>& j_callback,
-                                 int32_t http_code,
-                                 std::vector<uint8_t> response_bytes,
-                                 bool isSignedIn) {
-  // TODO(ssid): Remove after fixing https://crbug.com/916791.
-  TRACE_EVENT0("browser", "FeedNetworkBridge::OnResult");
-  JNIEnv* env = base::android::AttachCurrentThread();
-  ScopedJavaLocalRef<jbyteArray> j_response_bytes =
-      base::android::ToJavaByteArray(env, response_bytes);
-  ScopedJavaLocalRef<jobject> j_http_response =
-      Java_FeedNetworkBridge_createHttpResponse(env, http_code,
-                                                j_response_bytes, isSignedIn);
-  TRACE_EVENT0("browser", "FeedNetworkBridge::OnResult_Callback");
-  base::android::RunObjectCallbackAndroid(j_callback, j_http_response);
-}
-
-}  // namespace feed
diff --git a/chrome/browser/android/feed/feed_network_bridge.h b/chrome/browser/android/feed/feed_network_bridge.h
deleted file mode 100644
index db5e0c0..0000000
--- a/chrome/browser/android/feed/feed_network_bridge.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_FEED_FEED_NETWORK_BRIDGE_H_
-#define CHROME_BROWSER_ANDROID_FEED_FEED_NETWORK_BRIDGE_H_
-
-#include <jni.h>
-#include <vector>
-
-#include "base/android/scoped_java_ref.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-
-namespace feed {
-
-class FeedNetworkingHost;
-
-// Native counterpart of FeedNetworkBridge.java. Holds non-owning pointers to
-// native implementation, to which operations are delegated. Results are passed
-// back by a single argument callback so base::android::RunObjectCallbackAndroid
-// can be used. This bridge is instantiated, owned, and destroyed from Java.
-class FeedNetworkBridge {
- public:
-  explicit FeedNetworkBridge(
-      const base::android::JavaParamRef<jobject>& j_profile);
-  ~FeedNetworkBridge();
-
-  void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& j_this);
-
-  void SendNetworkRequest(
-      JNIEnv* env,
-      const base::android::JavaParamRef<jobject>& j_this,
-      const base::android::JavaParamRef<jstring>& j_url,
-      const base::android::JavaParamRef<jstring>& j_request_type,
-      const base::android::JavaParamRef<jbyteArray>& j_body,
-      const base::android::JavaParamRef<jobject>& j_callback);
-
-  void CancelRequests(JNIEnv* env,
-                      const base::android::JavaParamRef<jobject>& j_this);
-
- private:
-  void OnResult(const base::android::ScopedJavaGlobalRef<jobject>& j_callback,
-                int32_t http_code,
-                std::vector<uint8_t> response_bytes,
-                bool is_signed_in);
-
-  FeedNetworkingHost* networking_host_;
-
-  base::WeakPtrFactory<FeedNetworkBridge> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FeedNetworkBridge);
-};
-
-}  // namespace feed
-
-#endif  // CHROME_BROWSER_ANDROID_FEED_FEED_NETWORK_BRIDGE_H_
diff --git a/chrome/browser/android/feed/feed_offline_bridge.cc b/chrome/browser/android/feed/feed_offline_bridge.cc
deleted file mode 100644
index 658f5ef3..0000000
--- a/chrome/browser/android/feed/feed_offline_bridge.cc
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/feed/feed_offline_bridge.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/android/callback_android.h"
-#include "base/android/jni_android.h"
-#include "base/android/jni_array.h"
-#include "base/android/jni_string.h"
-#include "base/bind.h"
-#include "base/optional.h"
-#include "base/time/time.h"
-#include "chrome/android/chrome_jni_headers/FeedOfflineBridge_jni.h"
-#include "chrome/browser/android/feed/feed_host_service_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_android.h"
-#include "components/feed/content/feed_host_service.h"
-#include "components/feed/core/content_metadata.h"
-
-using base::android::JavaRef;
-using base::android::JavaParamRef;
-using base::android::ScopedJavaGlobalRef;
-using base::android::ScopedJavaLocalRef;
-
-namespace feed {
-
-static jlong JNI_FeedOfflineBridge_Init(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& j_this,
-    const JavaParamRef<jobject>& j_profile) {
-  Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
-  FeedHostService* host_service =
-      FeedHostServiceFactory::GetForBrowserContext(profile);
-  return reinterpret_cast<intptr_t>(
-      new FeedOfflineBridge(j_this, host_service->GetOfflineHost()));
-}
-
-FeedOfflineBridge::FeedOfflineBridge(const JavaRef<jobject>& j_this,
-                                     FeedOfflineHost* offline_host)
-    : j_this_(ScopedJavaGlobalRef<jobject>(j_this)),
-      offline_host_(offline_host) {
-  DCHECK(offline_host_);
-  // The host guarantees to not invoke these callbacks until Initialize() exits.
-  // This is important because until the Java bridge's constructor finishes, any
-  // attempt to cross JNI from native to Java will fail.
-  offline_host_->Initialize(
-      base::BindRepeating(&FeedOfflineBridge::TriggerGetKnownContent,
-                          weak_factory_.GetWeakPtr()),
-      base::BindRepeating(&FeedOfflineBridge::NotifyStatusChange,
-                          weak_factory_.GetWeakPtr()));
-}
-
-FeedOfflineBridge::~FeedOfflineBridge() = default;
-
-void FeedOfflineBridge::Destroy(JNIEnv* env, const JavaRef<jobject>& j_this) {
-  delete this;
-}
-
-ScopedJavaLocalRef<jobject> FeedOfflineBridge::GetOfflineId(
-    JNIEnv* env,
-    const JavaRef<jobject>& j_this,
-    const JavaRef<jstring>& j_url) {
-  std::string url = ConvertJavaStringToUTF8(env, j_url);
-  base::Optional<int64_t> id = offline_host_->GetOfflineId(url);
-  return id ? Java_FeedOfflineBridge_createLong(env, *id) : nullptr;
-}
-
-void FeedOfflineBridge::GetOfflineStatus(JNIEnv* env,
-                                         const JavaRef<jobject>& j_this,
-                                         const JavaRef<jobjectArray>& j_urls,
-                                         const JavaRef<jobject>& j_callback) {
-  std::vector<std::string> urls;
-  base::android::AppendJavaStringArrayToStringVector(env, j_urls, &urls);
-  ScopedJavaGlobalRef<jobject> callback(j_callback);
-  offline_host_->GetOfflineStatus(
-      std::move(urls), base::BindOnce(&FeedOfflineBridge::OnGetOfflineStatus,
-                                      weak_factory_.GetWeakPtr(), callback));
-}
-
-void FeedOfflineBridge::OnContentRemoved(
-    JNIEnv* env,
-    const base::android::JavaRef<jobject>& j_this,
-    const base::android::JavaRef<jobjectArray>& j_urls) {
-  std::vector<std::string> urls;
-  base::android::AppendJavaStringArrayToStringVector(env, j_urls, &urls);
-  offline_host_->OnContentRemoved(urls);
-}
-
-void FeedOfflineBridge::OnNewContentReceived(
-    JNIEnv* env,
-    const base::android::JavaRef<jobject>& j_this) {
-  offline_host_->OnNewContentReceived();
-}
-
-void FeedOfflineBridge::OnNoListeners(
-    JNIEnv* env,
-    const base::android::JavaRef<jobject>& j_this) {
-  offline_host_->OnNoListeners();
-}
-
-void FeedOfflineBridge::AppendContentMetadata(
-    JNIEnv* env,
-    const base::android::JavaRef<jobject>& j_this,
-    const base::android::JavaRef<jstring>& j_url,
-    const base::android::JavaRef<jstring>& j_title,
-    const jlong j_time_published_ms,
-    const base::android::JavaRef<jstring>& j_image_url,
-    const base::android::JavaRef<jstring>& j_publisher,
-    const base::android::JavaRef<jstring>& j_favicon_url,
-    const base::android::JavaRef<jstring>& j_snippet) {
-  ContentMetadata metadata;
-  DCHECK(!j_url.is_null());
-  metadata.url = base::android::ConvertJavaStringToUTF8(env, j_url);
-  DCHECK(!j_title.is_null());
-  metadata.title = base::android::ConvertJavaStringToUTF8(env, j_title);
-  metadata.time_published = base::Time::FromJavaTime(j_time_published_ms);
-  if (!j_image_url.is_null()) {
-    metadata.image_url =
-        base::android::ConvertJavaStringToUTF8(env, j_image_url);
-  }
-  if (!j_publisher.is_null()) {
-    metadata.publisher =
-        base::android::ConvertJavaStringToUTF8(env, j_publisher);
-  }
-  if (!j_favicon_url.is_null()) {
-    metadata.favicon_url =
-        base::android::ConvertJavaStringToUTF8(env, j_favicon_url);
-  }
-  if (!j_snippet.is_null()) {
-    metadata.snippet = base::android::ConvertJavaStringToUTF8(env, j_snippet);
-  }
-  known_content_metadata_buffer_.emplace_back(std::move(metadata));
-}
-
-void FeedOfflineBridge::OnGetKnownContentDone(
-    JNIEnv* env,
-    const base::android::JavaRef<jobject>& j_this) {
-  offline_host_->OnGetKnownContentDone(
-      std::move(known_content_metadata_buffer_));
-}
-
-void FeedOfflineBridge::TriggerGetKnownContent() {
-  DCHECK(known_content_metadata_buffer_.empty());
-  JNIEnv* env = base::android::AttachCurrentThread();
-  Java_FeedOfflineBridge_getKnownContent(env, j_this_);
-}
-
-void FeedOfflineBridge::NotifyStatusChange(const std::string& url,
-                                           bool available_offline) {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  ScopedJavaLocalRef<jstring> j_string =
-      base::android::ConvertUTF8ToJavaString(env, url);
-  Java_FeedOfflineBridge_notifyStatusChange(env, j_this_, j_string,
-                                            available_offline);
-}
-
-void FeedOfflineBridge::OnGetOfflineStatus(
-    ScopedJavaGlobalRef<jobject> callback,
-    std::vector<std::string> urls) {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  ScopedJavaLocalRef<jobjectArray> j_urls =
-      base::android::ToJavaArrayOfStrings(env, urls);
-  RunObjectCallbackAndroid(callback, j_urls);
-}
-
-}  // namespace feed
diff --git a/chrome/browser/android/feed/feed_offline_bridge.h b/chrome/browser/android/feed/feed_offline_bridge.h
deleted file mode 100644
index 628a5055..0000000
--- a/chrome/browser/android/feed/feed_offline_bridge.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_FEED_FEED_OFFLINE_BRIDGE_H_
-#define CHROME_BROWSER_ANDROID_FEED_FEED_OFFLINE_BRIDGE_H_
-
-#include <jni.h>
-#include <string>
-#include <vector>
-
-#include "base/android/scoped_java_ref.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "components/feed/content/feed_offline_host.h"
-#include "components/feed/core/content_metadata.h"
-
-namespace feed {
-
-class FeedOfflineHost;
-
-// Native counterpart of FeedOfflineBridge.java. Holds non-owning pointers to
-// native implementation, to which operations are delegated. Also capable of
-// calling back into Java half.
-class FeedOfflineBridge {
- public:
-  FeedOfflineBridge(const base::android::JavaRef<jobject>& j_this,
-                    FeedOfflineHost* offline_host);
-  ~FeedOfflineBridge();
-
-  void Destroy(JNIEnv* env, const base::android::JavaRef<jobject>& j_this);
-
-  base::android::ScopedJavaLocalRef<jobject> GetOfflineId(
-      JNIEnv* env,
-      const base::android::JavaRef<jobject>& j_this,
-      const base::android::JavaRef<jstring>& j_url);
-
-  void GetOfflineStatus(JNIEnv* env,
-                        const base::android::JavaRef<jobject>& j_this,
-                        const base::android::JavaRef<jobjectArray>& j_urls,
-                        const base::android::JavaRef<jobject>& j_callback);
-
-  void OnContentRemoved(JNIEnv* env,
-                        const base::android::JavaRef<jobject>& j_this,
-                        const base::android::JavaRef<jobjectArray>& j_urls);
-
-  void OnNewContentReceived(JNIEnv* env,
-                            const base::android::JavaRef<jobject>& j_this);
-
-  void OnNoListeners(JNIEnv* env,
-                     const base::android::JavaRef<jobject>& j_this);
-
-  // Used to convert from Java ContentMetadata to a native ContentMetadata, and
-  // put the resulting object into |known_content_metadata_buffer_|. When a
-  // GetKnownContent() call finishes, this method should be synchronously called
-  // for every piece of data, and then OnGetKnownContentDone() should be called.
-  void AppendContentMetadata(
-      JNIEnv* env,
-      const base::android::JavaRef<jobject>& j_this,
-      const base::android::JavaRef<jstring>& j_url,
-      const base::android::JavaRef<jstring>& j_title,
-      const jlong j_time_published_ms,
-      const base::android::JavaRef<jstring>& j_image_url,
-      const base::android::JavaRef<jstring>& j_publisher,
-      const base::android::JavaRef<jstring>& j_favicon_url,
-      const base::android::JavaRef<jstring>& j_snippet);
-
-  // Called to flush the contents of |known_content_metadata_buffer_| to the
-  // |offline_host_|. This should happen at the end of a GetKnownContent() call,
-  // and after AppendContentMetadata() is called for all data.
-  void OnGetKnownContentDone(JNIEnv* env,
-                             const base::android::JavaRef<jobject>& j_this);
-
-  void NotifyStatusChange(const std::string& url, bool available_offline);
-
- private:
-  // Starts an the async request for ContentMetadata through KnownContentApi's
-  // GetKnownContent(). Assumes the caller was FeedOfflineHost and will directly
-  // call FeedOfflineHost::OnGetKnownContentDone() on async completion.
-  void TriggerGetKnownContent();
-
-  void OnGetOfflineStatus(base::android::ScopedJavaGlobalRef<jobject> callback,
-                          std::vector<std::string> urls);
-
-  // Reference to the Java half of this bridge. Always valid.
-  base::android::ScopedJavaGlobalRef<jobject> j_this_;
-
-  // Object to which all Java to native calls are delegated.
-  FeedOfflineHost* offline_host_;
-
-  // Temporarily holds ContentMetadata objects during the completion of a
-  // GetKnownContent call.
-  std::vector<ContentMetadata> known_content_metadata_buffer_;
-
-  base::WeakPtrFactory<FeedOfflineBridge> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FeedOfflineBridge);
-};
-
-}  // namespace feed
-
-#endif  // CHROME_BROWSER_ANDROID_FEED_FEED_OFFLINE_BRIDGE_H_
diff --git a/chrome/browser/android/feed/feed_scheduler_bridge.cc b/chrome/browser/android/feed/feed_scheduler_bridge.cc
deleted file mode 100644
index 20e2e21..0000000
--- a/chrome/browser/android/feed/feed_scheduler_bridge.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/feed/feed_scheduler_bridge.h"
-
-#include <utility>
-
-#include "base/android/callback_android.h"
-#include "base/android/jni_android.h"
-#include "base/bind.h"
-#include "base/time/time.h"
-#include "chrome/android/chrome_jni_headers/FeedSchedulerBridge_jni.h"
-#include "chrome/browser/android/feed/feed_host_service_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_android.h"
-#include "components/feed/content/feed_host_service.h"
-
-using base::android::JavaRef;
-using base::android::JavaParamRef;
-using base::android::ScopedJavaGlobalRef;
-
-namespace feed {
-
-static jlong JNI_FeedSchedulerBridge_Init(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& j_this,
-    const JavaParamRef<jobject>& j_profile) {
-  Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
-  FeedHostService* host_service =
-      FeedHostServiceFactory::GetForBrowserContext(profile);
-  return reinterpret_cast<intptr_t>(
-      new FeedSchedulerBridge(j_this, host_service->GetSchedulerHost()));
-}
-
-FeedSchedulerBridge::FeedSchedulerBridge(const JavaRef<jobject>& j_this,
-                                         FeedSchedulerHost* scheduler_host)
-    : j_this_(ScopedJavaGlobalRef<jobject>(j_this)),
-      scheduler_host_(scheduler_host) {
-  DCHECK(scheduler_host_);
-  scheduler_host_->Initialize(
-      base::BindRepeating(&FeedSchedulerBridge::TriggerRefresh,
-                          weak_factory_.GetWeakPtr()),
-      base::BindRepeating(&FeedSchedulerBridge::ScheduleWakeUp,
-                          weak_factory_.GetWeakPtr()),
-      base::BindRepeating(&FeedSchedulerBridge::CancelWakeUp,
-                          weak_factory_.GetWeakPtr()));
-}
-
-FeedSchedulerBridge::~FeedSchedulerBridge() = default;
-
-void FeedSchedulerBridge::Destroy(JNIEnv* env, const JavaRef<jobject>& j_this) {
-  delete this;
-}
-
-jint FeedSchedulerBridge::ShouldSessionRequestData(
-    JNIEnv* env,
-    const JavaRef<jobject>& j_this,
-    const jboolean j_has_content,
-    const jlong j_content_creation_date_time_ms,
-    const jboolean j_has_outstanding_request) {
-  return static_cast<int>(scheduler_host_->ShouldSessionRequestData(
-      j_has_content, base::Time::FromJavaTime(j_content_creation_date_time_ms),
-      j_has_outstanding_request));
-}
-
-void FeedSchedulerBridge::OnReceiveNewContent(
-    JNIEnv* env,
-    const JavaRef<jobject>& j_this,
-    const jlong j_content_creation_date_time_ms) {
-  scheduler_host_->OnReceiveNewContent(
-      base::Time::FromJavaTime(j_content_creation_date_time_ms));
-}
-
-void FeedSchedulerBridge::OnRequestError(JNIEnv* env,
-                                         const JavaRef<jobject>& j_this,
-                                         const jint j_network_response_code) {
-  scheduler_host_->OnRequestError(j_network_response_code);
-}
-
-void FeedSchedulerBridge::OnForegrounded(JNIEnv* env,
-                                         const JavaRef<jobject>& j_this) {
-  scheduler_host_->OnForegrounded();
-}
-
-void FeedSchedulerBridge::OnFixedTimer(
-    JNIEnv* env,
-    const JavaRef<jobject>& j_this,
-    const base::android::JavaRef<jobject>& j_runnable) {
-  base::OnceClosure callback = base::BindOnce(
-      &FeedSchedulerBridge::FixedTimerHandlingDone, weak_factory_.GetWeakPtr(),
-      ScopedJavaGlobalRef<jobject>(j_runnable));
-  scheduler_host_->OnFixedTimer(std::move(callback));
-}
-
-void FeedSchedulerBridge::OnSuggestionConsumed(
-    JNIEnv* env,
-    const base::android::JavaRef<jobject>& j_this) {
-  scheduler_host_->OnSuggestionConsumed();
-}
-
-bool FeedSchedulerBridge::OnArticlesCleared(
-    JNIEnv* env,
-    const base::android::JavaRef<jobject>& j_this,
-    jboolean j_suppress_refreshes) {
-  return scheduler_host_->OnArticlesCleared(j_suppress_refreshes);
-}
-
-void FeedSchedulerBridge::TriggerRefresh() {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  Java_FeedSchedulerBridge_triggerRefresh(env, j_this_);
-}
-
-void FeedSchedulerBridge::ScheduleWakeUp(base::TimeDelta threshold) {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  Java_FeedSchedulerBridge_scheduleWakeUp(env, j_this_,
-                                          threshold.InMilliseconds());
-}
-
-void FeedSchedulerBridge::CancelWakeUp() {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  Java_FeedSchedulerBridge_cancelWakeUp(env, j_this_);
-}
-
-void FeedSchedulerBridge::FixedTimerHandlingDone(
-    ScopedJavaGlobalRef<jobject> j_runnable) {
-  base::android::RunRunnableAndroid(j_runnable);
-}
-
-}  // namespace feed
diff --git a/chrome/browser/android/feed/feed_scheduler_bridge.h b/chrome/browser/android/feed/feed_scheduler_bridge.h
deleted file mode 100644
index f3ab31e..0000000
--- a/chrome/browser/android/feed/feed_scheduler_bridge.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_FEED_FEED_SCHEDULER_BRIDGE_H_
-#define CHROME_BROWSER_ANDROID_FEED_FEED_SCHEDULER_BRIDGE_H_
-
-#include <jni.h>
-#include <stdint.h>
-
-#include "base/android/scoped_java_ref.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "components/feed/core/feed_scheduler_host.h"
-
-namespace base {
-class TimeDelta;
-}  // namespace base
-
-namespace feed {
-
-class FeedSchedulerHost;
-
-// Native counterpart of FeedSchedulerBridge.java. Holds non-owning pointers to
-// native implementation, to which operations are delegated. Also capable of
-// calling back into Java half.
-class FeedSchedulerBridge {
- public:
-  FeedSchedulerBridge(const base::android::JavaRef<jobject>& j_this,
-                      FeedSchedulerHost* scheduler_host);
-  ~FeedSchedulerBridge();
-
-  void Destroy(JNIEnv* env, const base::android::JavaRef<jobject>& j_this);
-
-  jint ShouldSessionRequestData(JNIEnv* env,
-                                const base::android::JavaRef<jobject>& j_this,
-                                const jboolean j_has_content,
-                                const jlong j_content_creation_date_time_ms,
-                                const jboolean j_has_outstanding_request);
-
-  void OnReceiveNewContent(JNIEnv* env,
-                           const base::android::JavaRef<jobject>& j_this,
-                           const jlong j_content_creation_date_time_ms);
-
-  void OnRequestError(JNIEnv* env,
-                      const base::android::JavaRef<jobject>& j_this,
-                      jint j_network_response_code);
-
-  void OnForegrounded(JNIEnv* env,
-                      const base::android::JavaRef<jobject>& j_this);
-
-  void OnFixedTimer(JNIEnv* env,
-                    const base::android::JavaRef<jobject>& j_this,
-                    const base::android::JavaRef<jobject>& j_callback);
-
-  void OnSuggestionConsumed(JNIEnv* env,
-                            const base::android::JavaRef<jobject>& j_this);
-
-  bool OnArticlesCleared(JNIEnv* env,
-                         const base::android::JavaRef<jobject>& j_this,
-                         jboolean j_suppress_refreshes);
-
- private:
-  // Callable by native code to invoke Java code. Sends a request to the Feed
-  // library to make the refresh call.
-  void TriggerRefresh();
-
-  // Calls into Java logic to schedule a background task to wake up Chrome and
-  // call back into the FeedHostScheduler.
-  void ScheduleWakeUp(base::TimeDelta threshold_ms);
-
-  // Cancels previously scheduled background task.
-  void CancelWakeUp();
-
-  void FixedTimerHandlingDone(
-      base::android::ScopedJavaGlobalRef<jobject> j_callback);
-
-  // Reference to the Java half of this bridge. Always valid.
-  base::android::ScopedJavaGlobalRef<jobject> j_this_;
-
-  // Object to which all Java to native calls are delegated.
-  FeedSchedulerHost* scheduler_host_;
-
-  base::WeakPtrFactory<FeedSchedulerBridge> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FeedSchedulerBridge);
-};
-
-}  // namespace feed
-
-#endif  // CHROME_BROWSER_ANDROID_FEED_FEED_SCHEDULER_BRIDGE_H_
diff --git a/chrome/browser/android/feed/history/feed_history_helper.cc b/chrome/browser/android/feed/history/feed_history_helper.cc
deleted file mode 100644
index 550b4b5..0000000
--- a/chrome/browser/android/feed/history/feed_history_helper.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/feed/history/feed_history_helper.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "components/history/core/browser/history_service.h"
-#include "components/history/core/browser/url_row.h"
-
-namespace feed {
-
-FeedHistoryHelper::FeedHistoryHelper(history::HistoryService* history_service)
-    : history_service_(history_service) {}
-
-FeedHistoryHelper::~FeedHistoryHelper() = default;
-
-void FeedHistoryHelper::CheckURL(
-    const GURL& url,
-    FeedLoggingMetrics::CheckURLVisitCallback callback) {
-  DCHECK(history_service_);
-  history_service_->QueryURL(
-      url, /*want_visits=*/false,
-      base::BindOnce(&FeedHistoryHelper::OnCheckURLDone,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
-      &tracker_);
-}
-
-void FeedHistoryHelper::OnCheckURLDone(
-    FeedLoggingMetrics::CheckURLVisitCallback callback,
-    history::QueryURLResult result) {
-  std::move(callback).Run(result.success && result.row.visit_count() != 0);
-}
-
-}  // namespace feed
diff --git a/chrome/browser/android/feed/history/feed_history_helper.h b/chrome/browser/android/feed/history/feed_history_helper.h
deleted file mode 100644
index 6d388a4..0000000
--- a/chrome/browser/android/feed/history/feed_history_helper.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_FEED_HISTORY_FEED_HISTORY_HELPER_H_
-#define CHROME_BROWSER_ANDROID_FEED_HISTORY_FEED_HISTORY_HELPER_H_
-
-#include "base/task/cancelable_task_tracker.h"
-#include "components/feed/core/feed_logging_metrics.h"
-#include "components/history/core/browser/history_types.h"
-#include "url/gurl.h"
-
-namespace history {
-class HistoryService;
-struct QueryURLResult;
-}  // namespace history
-
-namespace feed {
-
-// This class helps components/feed to check history service without directly
-// depends on components/history. This class holds a raw pointer of history
-// service, which means |history_service_| should outlive of this class. Whoever
-// instantiates this class needs to guarantee the history service outlives this
-// helper class.
-class FeedHistoryHelper {
- public:
-  explicit FeedHistoryHelper(history::HistoryService* history_service);
-  ~FeedHistoryHelper();
-
-  // Check if |url| is visited by querying history service, and return the
-  // result to |callback|.
-  void CheckURL(const GURL& url,
-                FeedLoggingMetrics::CheckURLVisitCallback callback);
-
- private:
-  history::HistoryService* history_service_;
-  base::CancelableTaskTracker tracker_;
-
-  void OnCheckURLDone(FeedLoggingMetrics::CheckURLVisitCallback callback,
-                      history::QueryURLResult result);
-
-  base::WeakPtrFactory<FeedHistoryHelper> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FeedHistoryHelper);
-};
-
-}  // namespace feed
-
-#endif  // CHROME_BROWSER_ANDROID_FEED_HISTORY_FEED_HISTORY_HELPER_H_
diff --git a/chrome/browser/android/feed/history/feed_history_helper_unittest.cc b/chrome/browser/android/feed/history/feed_history_helper_unittest.cc
deleted file mode 100644
index 98cf195b..0000000
--- a/chrome/browser/android/feed/history/feed_history_helper_unittest.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/feed/history/feed_history_helper.h"
-
-#include <memory>
-
-#include "base/run_loop.h"
-#include "base/test/bind.h"
-#include "chrome/browser/history/history_service_factory.h"
-#include "chrome/test/base/testing_profile.h"
-#include "components/history/core/browser/history_service.h"
-#include "content/public/test/browser_task_environment.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace feed {
-
-namespace {
-
-const char kURL1[] = "http://foo.com";
-const char kURL2[] = "http://bar.com";
-
-}  // namespace
-
-class FeedHistoryHelperTest : public testing::Test {
- protected:
-  FeedHistoryHelperTest() {}
-
-  void SetUp() override {
-    ASSERT_TRUE(profile_.CreateHistoryService());
-    history_service_ = HistoryServiceFactory::GetForProfile(
-        &profile_, ServiceAccessType::IMPLICIT_ACCESS);
-    ASSERT_TRUE(history_service_);
-    feed_history_helper_ =
-        std::make_unique<FeedHistoryHelper>(history_service_);
-    history_service_->AddPage(
-        GURL(kURL1), base::Time(), /*context_id=*/nullptr,
-        /*nav_entry_id=*/0,
-        /*referrer=*/GURL(), history::RedirectList(), ui::PAGE_TRANSITION_TYPED,
-        history::SOURCE_BROWSED, /*did_replace_entry=*/false,
-        /*floc_allowed=*/false);
-  }
-
-  void CheckURLExist(GURL url, bool expected) {
-    base::RunLoop loop;
-    feed_history_helper()->CheckURL(
-        url, base::BindLambdaForTesting(([&](bool found) {
-          EXPECT_EQ(expected, found);
-          loop.Quit();
-        })));
-    loop.Run();
-  }
-
-  FeedHistoryHelper* feed_history_helper() {
-    return feed_history_helper_.get();
-  }
-
- private:
-  content::BrowserTaskEnvironment task_environment_;
-  history::HistoryService* history_service_;
-  TestingProfile profile_;
-  std::unique_ptr<FeedHistoryHelper> feed_history_helper_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedHistoryHelperTest);
-};
-
-TEST_F(FeedHistoryHelperTest, CheckURLSuccessTest) {
-  CheckURLExist(GURL(kURL1), true);
-}
-
-TEST_F(FeedHistoryHelperTest, CheckURLFailureTest) {
-  CheckURLExist(GURL(kURL2), false);
-}
-
-}  // namespace feed
diff --git a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc
index 61411f0..b0ccb9e 100644
--- a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc
+++ b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc
@@ -143,14 +143,14 @@
   // observing too. It is based on our assumption that it is invalid for
   // web developers to change the Web Manifest location. When it does
   // change, we will treat the new Web Manifest as the one of another WebAPK.
-  if (!data.NoBlockingErrors() || data.manifest->IsEmpty() ||
+  if (!data.NoBlockingErrors() || data.manifest.IsEmpty() ||
       web_manifest_url_ != data.manifest_url ||
       !webapps::WebappsUtils::AreWebManifestUrlsWebApkCompatible(
-          *data.manifest)) {
+          data.manifest)) {
     return;
   }
 
-  info_.UpdateFromManifest(*data.manifest);
+  info_.UpdateFromManifest(data.manifest);
   info_.manifest_url = data.manifest_url;
   info_.best_primary_icon_url = data.primary_icon_url;
   primary_icon_ = *data.primary_icon;
diff --git a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
index 8a40593..f67d1316 100644
--- a/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_interactive_browsertest.cc
@@ -868,6 +868,12 @@
 }
 
 IN_PROC_BROWSER_TEST_F(WebViewNewWindowInteractiveTest,
+                       NewWindow_AttachInSubFrame) {
+  TestHelper("testNewWindowAttachInSubFrame", "web_view/newwindow",
+             NEEDS_TEST_SERVER);
+}
+
+IN_PROC_BROWSER_TEST_F(WebViewNewWindowInteractiveTest,
                        NewWindow_NewWindowNameTakesPrecedence) {
   TestHelper("testNewWindowNameTakesPrecedence",
              "web_view/newwindow",
diff --git a/chrome/browser/ash/mobile/mobile_activator.cc b/chrome/browser/ash/mobile/mobile_activator.cc
index 0e81587..2aba5fd 100644
--- a/chrome/browser/ash/mobile/mobile_activator.cc
+++ b/chrome/browser/ash/mobile/mobile_activator.cc
@@ -29,7 +29,6 @@
 #include "chromeos/network/network_connection_handler.h"
 #include "chromeos/network/network_event_log.h"
 #include "chromeos/network/network_handler_callbacks.h"
-#include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -37,7 +36,7 @@
 
 using content::BrowserThread;
 
-namespace chromeos {
+namespace ash {
 
 namespace {
 
@@ -886,4 +885,4 @@
          kRecentPlanPaymentHours;
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/mobile/mobile_activator.h b/chrome/browser/ash/mobile/mobile_activator.h
index df9b3e8..a136c05f7 100644
--- a/chrome/browser/ash/mobile/mobile_activator.h
+++ b/chrome/browser/ash/mobile/mobile_activator.h
@@ -16,15 +16,17 @@
 #include "base/observer_list.h"
 #include "base/timer/timer.h"
 #include "chromeos/network/network_handler_callbacks.h"
+// TODO(https://crbug.com/1164001): restore network_state.h as forward
+// declaration after it is moved to ash.
+#include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler_observer.h"
 
 namespace base {
 class DictionaryValue;
 }
 
-namespace chromeos {
+namespace ash {
 
-class NetworkState;
 class TestMobileActivator;
 
 // This class performs mobile plan activation process.
@@ -258,6 +260,6 @@
   DISALLOW_COPY_AND_ASSIGN(MobileActivator);
 };
 
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // CHROME_BROWSER_ASH_MOBILE_MOBILE_ACTIVATOR_H_
diff --git a/chrome/browser/ash/mobile/mobile_activator_unittest.cc b/chrome/browser/ash/mobile/mobile_activator_unittest.cc
index 61015a3..ce2bfb7 100644
--- a/chrome/browser/ash/mobile/mobile_activator_unittest.cc
+++ b/chrome/browser/ash/mobile/mobile_activator_unittest.cc
@@ -35,7 +35,7 @@
 const char kTestServicePath[] = "/a/service/path";
 
 }  // namespace
-namespace chromeos {
+namespace ash {
 
 class TestMobileActivator : public MobileActivator {
  public:
@@ -285,4 +285,4 @@
             mobile_activator_.InvokePickNextState(&cellular_network_));
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/banners/android/BUILD.gn b/chrome/browser/banners/android/BUILD.gn
index 74de143..496a233 100644
--- a/chrome/browser/banners/android/BUILD.gn
+++ b/chrome/browser/banners/android/BUILD.gn
@@ -64,7 +64,7 @@
     "//components/feature_engagement/public:public_java",
     "//components/infobars/android:java",
     "//components/signin/core/browser/android:java",
-    "//components/signin/core/browser/android:signin_java_test_support",
+    "//components/signin/public/android:signin_java_test_support",
     "//components/site_engagement/content/android:java",
     "//components/webapps/browser/android:java",
     "//content/public/android:content_java",
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc
index 401110c..310cc60 100644
--- a/chrome/browser/banners/app_banner_manager_browsertest.cc
+++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -708,9 +708,11 @@
   GURL test_url = GetBannerURLWithAction("stash_event");
   service->ResetBaseScoreForURL(test_url, 10);
 
+  blink::Manifest manifest;
+  std::vector<SkBitmap> screenshots;
   installable_manager_->FailNext(base::WrapUnique(new InstallableData(
-      {MANIFEST_URL_CHANGED}, GURL(), nullptr, GURL(), nullptr, false, GURL(),
-      nullptr, std::vector<SkBitmap>(), false, false)));
+      {MANIFEST_URL_CHANGED}, GURL::EmptyGURL(), manifest, GURL::EmptyGURL(),
+      nullptr, false, GURL::EmptyGURL(), nullptr, screenshots, false, false)));
 
   // The page should record one failure of MANIFEST_URL_CHANGED, but it should
   // still successfully get to the PENDING_PROMPT state of the pipeline, as it
diff --git a/chrome/browser/browser_features.cc b/chrome/browser/browser_features.cc
index ffc3aae..f403918 100644
--- a/chrome/browser/browser_features.cc
+++ b/chrome/browser/browser_features.cc
@@ -53,12 +53,6 @@
 
 #endif
 
-#if defined(OS_MAC)
-// Enables the usage of Apple's new Notification API on macOS 10.14+
-const base::Feature kNewMacNotificationAPI{"NewMacNotificationAPI",
-                                           base::FEATURE_DISABLED_BY_DEFAULT};
-#endif
-
 #if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 // Enables taking snapshots of the user data directory after a major
 // milestone update and restoring them after a version rollback.
diff --git a/chrome/browser/browser_features.h b/chrome/browser/browser_features.h
index 8b0118d..df3b8a2 100644
--- a/chrome/browser/browser_features.h
+++ b/chrome/browser/browser_features.h
@@ -34,10 +34,6 @@
 extern const base::Feature kShutdownSupportForKeepalive;
 #endif
 
-#if defined(OS_MAC)
-extern const base::Feature kNewMacNotificationAPI;
-#endif
-
 #if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 extern const base::Feature kUserDataSnapshot;
 #endif
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index a9702936..1c1e25c 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -380,17 +380,6 @@
         <include name="IDR_IDENTITY_INTERNALS_CSS" file="resources\identity_internals\identity_internals.css" type="BINDATA" />
         <include name="IDR_IDENTITY_INTERNALS_JS" file="resources\identity_internals\identity_internals.js" type="BINDATA" />
       </if>
-      <if expr="chromeos">
-        <include name="IDR_NETWORK_UI_PAGE_HTML" file="resources\chromeos\network_ui\network.html" type="BINDATA" />
-        <include name="IDR_NETWORK_UI_BROWSER_PROXY_HTML" file="resources\chromeos\network_ui\network_ui_browser_proxy.html" type="BINDATA" />
-        <include name="IDR_NETWORK_UI_BROWSER_PROXY_JS" file="resources\chromeos\network_ui\network_ui_browser_proxy.js" type="BINDATA" />
-        <include name="IDR_NETWORK_UI_HTML" file="resources\chromeos\network_ui\network_ui.html" type="BINDATA" />
-        <include name="IDR_NETWORK_UI_JS" file="resources\chromeos\network_ui\network_ui.js" type="BINDATA" />
-        <include name="IDR_NETWORK_STATE_UI_HTML" file="resources\chromeos\network_ui\network_state_ui.html" type="BINDATA" />
-        <include name="IDR_NETWORK_STATE_UI_JS" file="resources\chromeos\network_ui\network_state_ui.js" type="BINDATA" />
-        <include name="IDR_NETWORK_LOGS_UI_HTML" file="resources\chromeos\network_ui\network_logs_ui.html" type="BINDATA" />
-        <include name="IDR_NETWORK_LOGS_UI_JS" file="resources\chromeos\network_ui\network_logs_ui.js" type="BINDATA" />
-      </if>
       <if expr="_google_chrome">
         <include name="IDR_PREF_HASH_SEED_BIN" file="resources\settings_internal\pref_hash_seed.bin" type="BINDATA" />
         <include name="IDR_ADDITIONAL_MODULE_IDS" file="${additional_modules_list_file}" use_base_dir="false" type="BINDATA" />
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_lifetime_manager.cc b/chrome/browser/browsing_data/chrome_browsing_data_lifetime_manager.cc
index d1381b21..3aacad0 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_lifetime_manager.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_lifetime_manager.cc
@@ -54,7 +54,13 @@
 class BrowsingDataRemoverObserver
     : public content::BrowsingDataRemover::Observer {
  public:
-  ~BrowsingDataRemoverObserver() override = default;
+  ~BrowsingDataRemoverObserver() override {
+    // The BrowsingDataRemoverImpl notifying us is indirectly owned by Profile,
+    // so triggering ~Profile() from here causes UAF bugs. Post the profile
+    // deletion to another task to avoid this.
+    base::ThreadTaskRunnerHandle::Get()->DeleteSoon(
+        FROM_HERE, std::move(profile_keep_alive_));
+  }
 
   // Creates an instance of BrowsingDataRemoverObserver that
   // manages its own lifetime. The instance will be deleted after
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
index 0f98b89..60a5a62 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -23,7 +23,6 @@
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
-#include "chrome/browser/android/feed/feed_host_service_factory.h"
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
 #include "chrome/browser/autofill/strike_database_factory.h"
 #include "chrome/browser/availability/availability_prober.h"
@@ -101,7 +100,6 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
 #include "components/device_event_log/device_event_log.h"
-#include "components/feed/content/feed_host_service.h"
 #include "components/history/core/browser/history_service.h"
 #include "components/keyed_service/core/service_access_type.h"
 #include "components/language/core/browser/url_language_histogram.h"
@@ -140,7 +138,6 @@
 #include "chrome/android/chrome_jni_headers/PackageHash_jni.h"
 #include "chrome/browser/android/customtabs/origin_verifier.h"
 #include "chrome/browser/android/explore_sites/explore_sites_service_factory.h"
-#include "chrome/browser/android/feed/feed_lifecycle_bridge.h"
 #include "chrome/browser/android/feed/v2/feed_service_factory.h"
 #include "chrome/browser/android/oom_intervention/oom_intervention_decider.h"
 #include "chrome/browser/android/search_permissions/search_permissions_service.h"
@@ -992,26 +989,15 @@
 
 #if defined(OS_ANDROID)
 #if BUILDFLAG(ENABLE_FEED_V2)
-    if (feed::IsV2Enabled()) {
-      // Don't bridge through if the service isn't present, which means we're
-      // probably running in a native unit test.
-      feed::FeedService* service =
-          feed::FeedServiceFactory::GetForBrowserContext(profile_);
-      if (service) {
-        service->ClearCachedData();
-      }
+    // Don't bridge through if the service isn't present, which means we're
+    // probably running in a native unit test.
+    feed::FeedService* service =
+        feed::FeedServiceFactory::GetForBrowserContext(profile_);
+    if (service) {
+      service->ClearCachedData();
     }
 #endif  // BUILDFLAG(ENABLE_FEED_V2)
 
-#if BUILDFLAG(ENABLE_FEED_V1)
-    if (feed::IsV1Enabled()) {
-      // Don't bridge through if the service isn't present, which means we're
-      // probably running in a native unit test.
-      if (feed::FeedHostServiceFactory::GetForBrowserContext(profile_)) {
-        feed::FeedLifecycleBridge::ClearCachedData();
-      }
-    }
-#endif  // BUILDFLAG(ENABLE_FEED_V1)
 #endif  // defined(OS_ANDROID)
 
 #if defined(OS_ANDROID)
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_factory.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_factory.cc
index 2b36744..64f330f6 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_factory.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_factory.cc
@@ -33,7 +33,6 @@
 #endif
 
 #if defined(OS_ANDROID)
-#include "chrome/browser/android/feed/feed_host_service_factory.h"
 #include "chrome/browser/android/feed/v2/feed_service_factory.h"
 #include "components/feed/buildflags.h"
 #include "components/feed/feed_feature_list.h"
@@ -61,15 +60,8 @@
   DependsOn(DataReductionProxyChromeSettingsFactory::GetInstance());
 #if defined(OS_ANDROID)
 #if BUILDFLAG(ENABLE_FEED_V2)
-  if (feed::IsV2Enabled()) {
-    DependsOn(feed::FeedServiceFactory::GetInstance());
-  }
+  DependsOn(feed::FeedServiceFactory::GetInstance());
 #endif  // BUILDFLAG(ENABLE_FEED_V2)
-#if BUILDFLAG(ENABLE_FEED_V1)
-  if (feed::IsV1Enabled()) {
-    DependsOn(feed::FeedHostServiceFactory::GetInstance());
-  }
-#endif  // BUILDFLAG(ENABLE_FEED_V1)
 #endif  // defined(OS_ANDROID)
   DependsOn(HistoryServiceFactory::GetInstance());
   DependsOn(HostContentSettingsMapFactory::GetInstance());
diff --git a/chrome/browser/capability_delegation_browsertest.cc b/chrome/browser/capability_delegation_browsertest.cc
new file mode 100644
index 0000000..c02dea0
--- /dev/null
+++ b/chrome/browser/capability_delegation_browsertest.cc
@@ -0,0 +1,78 @@
+// 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 "base/command_line.h"
+#include "base/feature_list.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "chrome/test/payments/payment_request_platform_browsertest_base.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_features.h"
+#include "content/public/test/browser_test.h"
+#include "net/dns/mock_host_resolver.h"
+#include "url/gurl.h"
+
+class CapabilityDelegationBrowserTest
+    : public payments::PaymentRequestPlatformBrowserTestBase {
+ public:
+  CapabilityDelegationBrowserTest() {
+    feature_list_.InitAndEnableFeature(
+        features::kCapabilityDelegationPaymentRequest);
+  }
+
+  ~CapabilityDelegationBrowserTest() override = default;
+
+  void SetUpOnMainThread() override {
+    host_resolver()->AddRule("*", "127.0.0.1");
+    ASSERT_TRUE(https_server()->InitializeAndListen());
+    content::SetupCrossSiteRedirector(https_server());
+    https_server()->ServeFilesFromSourceDirectory(
+        "chrome/test/data/capability_delegation");
+    https_server()->StartAcceptingConnections();
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(CapabilityDelegationBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(CapabilityDelegationBrowserTest, PaymentRequest) {
+  // Navigate the top frame.
+  GURL main_url(
+      https_server()->GetURL("a.com", "/payment_request_delegation.html"));
+  ui_test_utils::NavigateToURL(browser(), main_url);
+
+  // Navigate the sub-frame cross-site.
+  content::WebContents* active_web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  GURL cross_site_url(
+      https_server()->GetURL("b.com", "/payment_request_delegation_sub.html"));
+  EXPECT_TRUE(
+      NavigateIframeToURL(active_web_contents, "iframe", cross_site_url));
+
+  // Confirm that the subframe is cross-process.
+  content::RenderFrameHost* frame_host =
+      ChildFrameAt(active_web_contents->GetMainFrame(), 0);
+  ASSERT_TRUE(frame_host);
+  EXPECT_EQ(cross_site_url, frame_host->GetLastCommittedURL());
+  EXPECT_TRUE(frame_host->IsCrossProcessSubframe());
+
+  // TODO(mustaq): We need to duplicate the following checks to include the
+  // cases without any user activation.  Calling |EvalJs| with the option
+  // EXECUTE_SCRIPT_NO_USER_GESTURE is not enough because the
+  // |NavigateIframeToURL| call above activates the top frame, perhaps to allow
+  // the navigation to complete.
+
+  // Without payment request token, PaymentRequest dialog is not allowed.
+  EXPECT_EQ("NotAllowedError", content::EvalJs(active_web_contents,
+                                               "sendRequestToSubframe(false)"));
+
+  // With payment request token (plus user activation from |NavigateIframeToURL|
+  // above), PaymentRequest dialog is shown and then successfully aborted by the
+  // script.
+  EXPECT_EQ("AbortError", content::EvalJs(active_web_contents,
+                                          "sendRequestToSubframe(true)"));
+}
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc
index ae6e16a..277a7349 100644
--- a/chrome/browser/chrome_browser_interface_binders.cc
+++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -810,7 +810,7 @@
                                          DiscardsUI>(map);
 #endif
 
-#if BUILDFLAG(ENABLE_FEED_V1) || BUILDFLAG(ENABLE_FEED_V2)
+#if BUILDFLAG(ENABLE_FEED_V2)
   RegisterWebUIControllerInterfaceBinder<feed_internals::mojom::PageHandler,
                                          FeedInternalsUI>(map);
 #endif
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index c53d3e4..2801656b 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -330,6 +330,7 @@
     "//components/user_prefs:user_prefs",
     "//components/vector_icons",
     "//extensions/browser/api:api_implementations",
+    "//extensions/browser/updater",
     "//media/capture/video/chromeos/public:public",
 
     # This depends directly on the variations target, rather than just
@@ -2281,17 +2282,23 @@
     "policy/display_rotation_default_handler.h",
     "policy/display_settings_handler.cc",
     "policy/display_settings_handler.h",
+    "policy/dlp/clipboard_bubble.cc",
+    "policy/dlp/clipboard_bubble.h",
     "policy/dlp/data_transfer_dlp_controller.cc",
     "policy/dlp/data_transfer_dlp_controller.h",
     "policy/dlp/dlp_clipboard_bubble_constants.h",
-    "policy/dlp/dlp_clipboard_notification_helper.cc",
-    "policy/dlp/dlp_clipboard_notification_helper.h",
+    "policy/dlp/dlp_clipboard_notifier.cc",
+    "policy/dlp/dlp_clipboard_notifier.h",
     "policy/dlp/dlp_content_manager.cc",
     "policy/dlp/dlp_content_manager.h",
     "policy/dlp/dlp_content_restriction_set.cc",
     "policy/dlp/dlp_content_restriction_set.h",
     "policy/dlp/dlp_content_tab_helper.cc",
     "policy/dlp/dlp_content_tab_helper.h",
+    "policy/dlp/dlp_data_transfer_notifier.cc",
+    "policy/dlp/dlp_data_transfer_notifier.h",
+    "policy/dlp/dlp_drag_drop_notifier.cc",
+    "policy/dlp/dlp_drag_drop_notifier.h",
     "policy/dlp/dlp_notification_helper.cc",
     "policy/dlp/dlp_notification_helper.h",
     "policy/dlp/dlp_policy_constants.h",
@@ -3871,7 +3878,7 @@
     "policy/device_local_account_policy_service_unittest.cc",
     "policy/device_policy_decoder_chromeos_unittest.cc",
     "policy/dlp/data_transfer_dlp_controller_unittest.cc",
-    "policy/dlp/dlp_clipboard_notification_helper_unittest.cc",
+    "policy/dlp/dlp_clipboard_notifier_unittest.cc",
     "policy/dlp/dlp_content_manager_unittest.cc",
     "policy/dlp/dlp_content_tab_helper_unittest.cc",
     "policy/dlp/dlp_rules_manager_impl_unittest.cc",
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index 23ff2fe..0e99baa4 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -677,7 +677,8 @@
         TestCase("driveOfflineInfoBannerWithoutFlag"),
         TestCase("driveEnableDocsOfflineDialog"),
         TestCase("driveEnableDocsOfflineDialogWithoutWindow"),
-        TestCase("driveEnableDocsOfflineDialogMultipleWindows")));
+        TestCase("driveEnableDocsOfflineDialogMultipleWindows"),
+        TestCase("driveEnableDocsOfflineDialogDisappearsOnUnmount")));
 
 WRAPPED_INSTANTIATE_TEST_SUITE_P(
     HoldingSpace, /* holding_space.js */
diff --git a/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc b/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc
index ed8fc41..1264d53 100644
--- a/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc
+++ b/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc
@@ -35,9 +35,20 @@
 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
 #include "ui/views/controls/webview/web_dialog_view.h"
 #include "ui/views/focus/focus_manager.h"
+#include "ui/views/metadata/metadata_header_macros.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
+#include "ui/views/metadata/type_conversion.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
 
+DEFINE_ENUM_CONVERTERS(chromeos::OobeDialogPaddingMode,
+                       {chromeos::OobeDialogPaddingMode::PADDING_AUTO,
+                        STRING16_LITERAL("PADDING_AUTO")},
+                       {chromeos::OobeDialogPaddingMode::PADDING_WIDE,
+                        STRING16_LITERAL("PADDING_WIDE")},
+                       {chromeos::OobeDialogPaddingMode::PADDING_NARROW,
+                        STRING16_LITERAL("PADDING_NARROW")})
+
 namespace chromeos {
 
 namespace {
@@ -60,10 +71,13 @@
 
 class OobeWebDialogView : public views::WebDialogView {
  public:
+  METADATA_HEADER(OobeWebDialogView);
   OobeWebDialogView(content::BrowserContext* context,
                     ui::WebDialogDelegate* delegate,
                     std::unique_ptr<WebContentsHandler> handler)
       : views::WebDialogView(context, delegate, std::move(handler)) {}
+  OobeWebDialogView(const OobeWebDialogView&) = delete;
+  OobeWebDialogView& operator=(const OobeWebDialogView&) = delete;
 
   // content::WebContentsDelegate:
   void RequestMediaAccessPermission(
@@ -96,10 +110,11 @@
 
  private:
   views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(OobeWebDialogView);
 };
 
+BEGIN_METADATA(OobeWebDialogView, views::WebDialogView)
+END_METADATA
+
 // View that controls size of OobeUIDialog.
 // Dialog can be shown as a full-screen (in this case it will fit whole screen)
 // except for Virtual Keyboard or as a window.
@@ -117,6 +132,7 @@
 // display.
 class LayoutWidgetDelegateView : public views::WidgetDelegateView {
  public:
+  METADATA_HEADER(LayoutWidgetDelegateView);
   LayoutWidgetDelegateView(OobeUIDialogDelegate* dialog_delegate,
                            OobeWebDialogView* oobe_view)
       : dialog_delegate_(dialog_delegate), oobe_view_(oobe_view) {
@@ -124,21 +140,28 @@
     AddChildView(oobe_view_);
   }
 
+  LayoutWidgetDelegateView(const LayoutWidgetDelegateView&) = delete;
+  LayoutWidgetDelegateView& operator=(const LayoutWidgetDelegateView&) = delete;
+
   ~LayoutWidgetDelegateView() override { delete dialog_delegate_; }
 
   void SetFullscreen(bool value) {
     if (fullscreen_ == value)
       return;
     fullscreen_ = value;
-    Layout();
+    OnPropertyChanged(&fullscreen_, views::kPropertyEffectsLayout);
   }
+  bool GetFullscreen() const { return fullscreen_; }
 
   void SetHasShelf(bool value) {
+    if (has_shelf_ == value)
+      return;
     has_shelf_ = value;
-    Layout();
+    OnPropertyChanged(&has_shelf_, views::kPropertyEffectsLayout);
   }
+  bool GetHasShelf() const { return has_shelf_; }
 
-  OobeDialogPaddingMode padding() { return padding_; }
+  OobeDialogPaddingMode GetPadding() const { return padding_; }
 
   // views::WidgetDelegateView:
   ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_WINDOW; }
@@ -181,10 +204,14 @@
 
   // Tracks dialog margins after last size calculations.
   OobeDialogPaddingMode padding_ = OobeDialogPaddingMode::PADDING_AUTO;
-
-  DISALLOW_COPY_AND_ASSIGN(LayoutWidgetDelegateView);
 };
 
+BEGIN_METADATA(LayoutWidgetDelegateView, views::WidgetDelegateView)
+ADD_PROPERTY_METADATA(bool, Fullscreen)
+ADD_PROPERTY_METADATA(bool, HasShelf)
+ADD_READONLY_PROPERTY_METADATA(OobeDialogPaddingMode, Padding)
+END_METADATA
+
 class CaptivePortalDialogDelegate
     : public ui::WebDialogDelegate,
       public ChromeWebModalDialogManagerDelegate,
@@ -509,7 +536,7 @@
   if (!widget_)
     return;
   GetOobeUI()->GetCoreOobeView()->SetDialogPaddingMode(
-      ConvertDialogPaddingMode(layout_view_->padding()));
+      ConvertDialogPaddingMode(layout_view_->GetPadding()));
   GetOobeUI()->GetCoreOobeView()->UpdateClientAreaSize(
       layout_view_->GetContentsBounds().size());
 }
diff --git a/chrome/browser/chromeos/policy/dlp/clipboard_bubble.cc b/chrome/browser/chromeos/policy/dlp/clipboard_bubble.cc
new file mode 100644
index 0000000..fe5d0b4
--- /dev/null
+++ b/chrome/browser/chromeos/policy/dlp/clipboard_bubble.cc
@@ -0,0 +1,252 @@
+// 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/chromeos/policy/dlp/clipboard_bubble.h"
+
+#include "ash/public/cpp/ash_features.h"
+#include "ash/public/cpp/style/color_provider.h"
+#include "chrome/browser/chromeos/policy/dlp/dlp_clipboard_bubble_constants.h"
+#include "components/strings/grit/components_strings.h"
+#include "components/vector_icons/vector_icons.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/paint_vector_icon.h"
+#include "ui/gfx/text_utils.h"
+#include "ui/views/bubble/bubble_border.h"
+#include "ui/views/controls/button/label_button.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
+
+namespace policy {
+
+namespace {
+
+// The corner radius of the bubble.
+constexpr int kBubbleCornerRadius = 8;
+constexpr gfx::RoundedCornersF kCornerRadii(kBubbleCornerRadius);
+
+// The blur radius for the bubble background.
+constexpr int kBubbleBlurRadius = 80;
+
+// The size of the managed icon.
+constexpr int kManagedIconSize = 20;
+
+// The maximum width of the bubble.
+constexpr int kBubbleWidth = 360;
+
+// The spacing between the icon and label in the bubble.
+constexpr int kIconLabelSpacing = 16;
+
+// The padding which separates the bubble border with its inner contents.
+constexpr int kBubblePadding = 16;
+
+// The line height of the bubble text.
+constexpr int kLineHeight = 20;
+
+// The insets of the bubble borders.
+constexpr gfx::Insets kBubbleBorderInsets(1);
+
+// The font name of the text used in the bubble.
+constexpr char kTextFontName[] = "Roboto";
+
+// The font size of the text used in the bubble.
+constexpr int kTextFontSize = 13;
+
+// The height of the dismiss button.
+constexpr int kButtonHeight = 32;
+
+// The padding which separates the button border with its inner contents.
+constexpr int kButtonPadding = 16;
+
+// The spacing between the button border and label.
+constexpr int kButtonLabelSpacing = 8;
+
+// The spacing between the buttons.
+constexpr int kButtonsSpacing = 8;
+
+class Button : public views::LabelButton {
+ public:
+  METADATA_HEADER(Button);
+  explicit Button(const base::string16& button_label) {
+    SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_CENTER);
+
+    SetText(button_label);
+
+    const gfx::FontList font_list = GetFontList();
+    label()->SetFontList(font_list);
+
+    SetTextColor(
+        ButtonState::STATE_NORMAL,
+        ash::ColorProvider::Get()->GetContentLayerColor(
+            ash::ColorProvider::ContentLayerType::kButtonLabelColorBlue));
+    SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_CENTER);
+    SetSize({gfx::GetStringWidth(button_label, font_list) + 2 * kButtonPadding,
+             kButtonHeight});
+  }
+
+  Button(const Button&) = delete;
+  Button& operator=(const Button&) = delete;
+  ~Button() override = default;
+
+  int GetLabelWidth() const { return label()->bounds().width(); }
+
+  static gfx::FontList GetFontList() {
+    return gfx::FontList({kTextFontName}, gfx::Font::NORMAL, kTextFontSize,
+                         gfx::Font::Weight::MEDIUM);
+  }
+};
+
+}  // namespace
+
+BEGIN_METADATA(Button, views::LabelButton)
+ADD_READONLY_PROPERTY_METADATA(int, LabelWidth)
+END_METADATA
+
+ClipboardBubbleView::ClipboardBubbleView(const base::string16& text) {
+  SetPaintToLayer(ui::LAYER_SOLID_COLOR);
+  ash::ColorProvider* color_provider = ash::ColorProvider::Get();
+  layer()->SetColor(color_provider->GetBaseLayerColor(
+      ash::ColorProvider::BaseLayerType::kTransparent80));
+  if (ash::features::IsBackgroundBlurEnabled())
+    layer()->SetBackgroundBlur(kBubbleBlurRadius);
+  layer()->SetRoundedCornerRadius(kCornerRadii);
+
+  // Add the managed icon.
+  SkColor icon_color = color_provider->GetContentLayerColor(
+      ash::ColorProvider::ContentLayerType::kIconColorPrimary);
+  managed_icon_ = AddChildView(std::make_unique<views::ImageView>());
+  managed_icon_->SetPaintToLayer();
+  managed_icon_->layer()->SetFillsBoundsOpaquely(false);
+  managed_icon_->SetBounds(kBubblePadding, kBubblePadding, kManagedIconSize,
+                           kManagedIconSize);
+  managed_icon_->SetImage(gfx::CreateVectorIcon(vector_icons::kBusinessIcon,
+                                                kManagedIconSize, icon_color));
+
+  // Add the bubble text.
+  label_ = AddChildView(std::make_unique<views::Label>());
+  label_->SetPaintToLayer();
+  label_->layer()->SetFillsBoundsOpaquely(false);
+  label_->SetPosition(gfx::Point(
+      kBubblePadding + kManagedIconSize + kIconLabelSpacing, kBubblePadding));
+
+  // Set the styling of the text.
+  // TODO(crbug.com/1150741): Handle RTL.
+  label_->SetText(text);
+  label_->SetFontList(gfx::FontList({kTextFontName}, gfx::Font::NORMAL,
+                                    kTextFontSize, gfx::Font::Weight::NORMAL));
+  label_->SetEnabledColor(color_provider->GetContentLayerColor(
+      ash::ColorProvider::ContentLayerType::kTextColorPrimary));
+  label_->SetLineHeight(kLineHeight);
+  label_->SetMultiLine(true);
+  label_->SizeToFit(kBubbleWidth - 2 * kBubblePadding - kManagedIconSize -
+                    kIconLabelSpacing);
+  label_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
+
+  // Bubble borders
+  border_ = AddChildView(std::make_unique<views::ImageView>());
+  border_->SetPaintToLayer();
+  border_->layer()->SetFillsBoundsOpaquely(false);
+  auto shadow_border = std::make_unique<views::BubbleBorder>(
+      views::BubbleBorder::FLOAT, views::BubbleBorder::STANDARD_SHADOW,
+      SK_ColorTRANSPARENT);
+  shadow_border->SetCornerRadius(kBubbleCornerRadius);
+  shadow_border->set_background_color(SK_ColorTRANSPARENT);
+  shadow_border->set_insets(kBubbleBorderInsets);
+  border_->SetSize({kBubbleWidth, INT_MAX});
+  border_->SetBorder(std::move(shadow_border));
+}
+
+ClipboardBubbleView::~ClipboardBubbleView() = default;
+
+void ClipboardBubbleView::UpdateBorderSize(const gfx::Size& size) {
+  border_->SetSize(size);
+}
+
+BEGIN_METADATA(ClipboardBubbleView, views::View)
+ADD_READONLY_PROPERTY_METADATA(gfx::Size, BubbleSize)
+END_METADATA
+
+ClipboardBlockBubble::ClipboardBlockBubble(const base::string16& text)
+    : ClipboardBubbleView(text) {
+  // Add "Got it" button.
+  base::string16 button_label =
+      l10n_util::GetStringUTF16(IDS_POLICY_DLP_CLIPBOARD_BLOCK_DISMISS_BUTTON);
+  button_ = AddChildView(std::make_unique<Button>(button_label));
+  button_->SetPaintToLayer();
+  button_->layer()->SetFillsBoundsOpaquely(false);
+  button_->SetPosition(
+      gfx::Point(kBubbleWidth - kBubblePadding - button_->width(),
+                 kBubblePadding + label_->height() + kButtonLabelSpacing));
+
+  UpdateBorderSize(GetBubbleSize());
+}
+
+ClipboardBlockBubble::~ClipboardBlockBubble() = default;
+
+gfx::Size ClipboardBlockBubble::GetBubbleSize() const {
+  DCHECK(label_);
+  DCHECK(button_);
+  return {kBubbleWidth, 2 * kBubblePadding + label_->bounds().height() +
+                            kButtonLabelSpacing + button_->height()};
+}
+
+void ClipboardBlockBubble::SetDismissCallback(
+    base::RepeatingCallback<void()> cb) {
+  DCHECK(button_);
+  button_->SetCallback(std::move(cb));
+}
+
+BEGIN_METADATA(ClipboardBlockBubble, ClipboardBubbleView)
+END_METADATA
+
+ClipboardWarnBubble::ClipboardWarnBubble(const base::string16& text)
+    : ClipboardBubbleView(text) {
+  // Add paste button.
+  base::string16 paste_label =
+      l10n_util::GetStringUTF16(IDS_POLICY_DLP_CLIPBOARD_WARN_PROCEED_BUTTON);
+  paste_button_ = AddChildView(std::make_unique<Button>(paste_label));
+  paste_button_->SetPaintToLayer();
+  paste_button_->layer()->SetFillsBoundsOpaquely(false);
+  paste_button_->SetPosition(
+      gfx::Point(kBubbleWidth - kBubblePadding - paste_button_->width(),
+                 kBubblePadding + label_->height() + kButtonLabelSpacing));
+
+  // Add cancel button.
+  base::string16 cancel_label =
+      l10n_util::GetStringUTF16(IDS_POLICY_DLP_CLIPBOARD_WARN_DISMISS_BUTTON);
+  cancel_button_ = AddChildView(std::make_unique<Button>(cancel_label));
+  cancel_button_->SetPaintToLayer();
+  cancel_button_->layer()->SetFillsBoundsOpaquely(false);
+  cancel_button_->SetPosition(
+      gfx::Point(kBubbleWidth - kBubblePadding - paste_button_->width() -
+                     kButtonsSpacing - cancel_button_->width(),
+                 kBubblePadding + label_->height() + kButtonLabelSpacing));
+
+  UpdateBorderSize(GetBubbleSize());
+}
+
+ClipboardWarnBubble::~ClipboardWarnBubble() = default;
+
+gfx::Size ClipboardWarnBubble::GetBubbleSize() const {
+  DCHECK(label_);
+  DCHECK(cancel_button_);
+  DCHECK(paste_button_);
+  return {kBubbleWidth, 2 * kBubblePadding + label_->bounds().height() +
+                            kButtonLabelSpacing + paste_button_->height()};
+}
+
+void ClipboardWarnBubble::SetDismissCallback(
+    base::RepeatingCallback<void()> cb) {
+  DCHECK(cancel_button_);
+  cancel_button_->SetCallback(std::move(cb));
+}
+
+void ClipboardWarnBubble::SetProceedCallback(
+    base::RepeatingCallback<void()> cb) {
+  DCHECK(paste_button_);
+  paste_button_->SetCallback(std::move(cb));
+}
+
+BEGIN_METADATA(ClipboardWarnBubble, ClipboardBubbleView)
+END_METADATA
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/clipboard_bubble.h b/chrome/browser/chromeos/policy/dlp/clipboard_bubble.h
new file mode 100644
index 0000000..f78a2f0
--- /dev/null
+++ b/chrome/browser/chromeos/policy/dlp/clipboard_bubble.h
@@ -0,0 +1,78 @@
+// 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_CHROMEOS_POLICY_DLP_CLIPBOARD_BUBBLE_H_
+#define CHROME_BROWSER_CHROMEOS_POLICY_DLP_CLIPBOARD_BUBBLE_H_
+
+#include "base/callback.h"
+#include "base/strings/string16.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/views/metadata/metadata_header_macros.h"
+#include "ui/views/view.h"
+
+namespace views {
+class Label;
+class ImageView;
+class LabelButton;
+}  // namespace views
+
+namespace policy {
+
+// This inline bubble shown for restricted copy/paste.
+class ClipboardBubbleView : public views::View {
+ public:
+  METADATA_HEADER(ClipboardBubbleView);
+
+  explicit ClipboardBubbleView(const base::string16& text);
+  ~ClipboardBubbleView() override;
+
+  virtual gfx::Size GetBubbleSize() const = 0;
+
+ protected:
+  // This function should get called if the view got updated e.g. AddChildView.
+  void UpdateBorderSize(const gfx::Size& size);
+
+  views::Label* label_ = nullptr;
+  views::ImageView* managed_icon_ = nullptr;
+  views::ImageView* border_ = nullptr;
+};
+
+class ClipboardBlockBubble : public ClipboardBubbleView {
+ public:
+  METADATA_HEADER(ClipboardBlockBubble);
+
+  explicit ClipboardBlockBubble(const base::string16& text);
+  ~ClipboardBlockBubble() override;
+
+  // ClipboardBubbleView::
+  gfx::Size GetBubbleSize() const override;
+
+  void SetDismissCallback(base::RepeatingCallback<void()> cb);
+
+ private:
+  views::LabelButton* button_ = nullptr;
+};
+
+class ClipboardWarnBubble : public ClipboardBubbleView {
+ public:
+  METADATA_HEADER(ClipboardWarnBubble);
+
+  explicit ClipboardWarnBubble(const base::string16& text);
+  ~ClipboardWarnBubble() override;
+
+  // ClipboardBubbleView::
+  gfx::Size GetBubbleSize() const override;
+
+  void SetDismissCallback(base::RepeatingCallback<void()> cb);
+
+  void SetProceedCallback(base::RepeatingCallback<void()> cb);
+
+ private:
+  views::LabelButton* cancel_button_ = nullptr;
+  views::LabelButton* paste_button_ = nullptr;
+};
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_CHROMEOS_POLICY_DLP_CLIPBOARD_BUBBLE_H_
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.cc
index 9242db3..716220d 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.cc
@@ -133,10 +133,19 @@
       break;
 
     case DlpRulesManager::Level::kWarn:
-      if (notify_on_paste && !ShouldProceedOnWarn(data_dst)) {
-        SYSLOG(INFO) << "DLP warned on paste from clipboard";
-        WarnOnPaste(data_src, data_dst);
-        is_read_allowed = false;
+      if (notify_on_paste) {
+        // In case the clipboard data is in warning mode, it will be allowed to
+        // be shared with Arc, Crostini, and Plugin VM without waiting for the
+        // user decision.
+        if (data_dst && (data_dst->type() == ui::EndpointType::kArc ||
+                         data_dst->type() == ui::EndpointType::kPluginVm ||
+                         data_dst->type() == ui::EndpointType::kCrostini)) {
+          WarnOnPaste(data_src, data_dst);
+        } else if (!ShouldProceedOnWarn(data_dst)) {
+          SYSLOG(INFO) << "DLP warned on paste from clipboard";
+          WarnOnPaste(data_src, data_dst);
+          is_read_allowed = false;
+        }
       }
       break;
 
@@ -170,18 +179,24 @@
 void DataTransferDlpController::NotifyBlockedPaste(
     const ui::DataTransferEndpoint* const data_src,
     const ui::DataTransferEndpoint* const data_dst) {
-  helper_.NotifyBlockedPaste(data_src, data_dst);
+  clipboard_notifier_.NotifyBlockedAction(data_src, data_dst);
 }
 
 void DataTransferDlpController::WarnOnPaste(
     const ui::DataTransferEndpoint* const data_src,
     const ui::DataTransferEndpoint* const data_dst) {
-  helper_.WarnOnPaste(data_src, data_dst);
+  clipboard_notifier_.WarnOnAction(data_src, data_dst);
 }
 
 bool DataTransferDlpController::ShouldProceedOnWarn(
     const ui::DataTransferEndpoint* const data_dst) {
-  return helper_.DidUserProceedOnWarn(data_dst);
+  return clipboard_notifier_.DidUserProceedOnWarn(data_dst);
+}
+
+void DataTransferDlpController::NotifyBlockedDrop(
+    const ui::DataTransferEndpoint* const data_src,
+    const ui::DataTransferEndpoint* const data_dst) {
+  drag_drop_notifier_.NotifyBlockedAction(data_src, data_dst);
 }
 
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h
index 616d214bd..d96a69e 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h
@@ -6,7 +6,8 @@
 #define CHROME_BROWSER_CHROMEOS_POLICY_DLP_DATA_TRANSFER_DLP_CONTROLLER_H_
 
 #include "base/strings/string16.h"
-#include "chrome/browser/chromeos/policy/dlp/dlp_clipboard_notification_helper.h"
+#include "chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.h"
+#include "chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.h"
 #include "ui/base/data_transfer_policy/data_transfer_policy_controller.h"
 
 namespace ui {
@@ -55,8 +56,13 @@
   virtual bool ShouldProceedOnWarn(
       const ui::DataTransferEndpoint* const data_dst);
 
+  virtual void NotifyBlockedDrop(
+      const ui::DataTransferEndpoint* const data_src,
+      const ui::DataTransferEndpoint* const data_dst);
+
   const DlpRulesManager& dlp_rules_manager_;
-  DlpClipboardNotificationHelper helper_;
+  DlpClipboardNotifier clipboard_notifier_;
+  DlpDragDropNotifier drag_drop_notifier_;
 };
 
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
index bcd80c7..56916cfd 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
@@ -50,19 +50,19 @@
 constexpr char kDocsUrl[] = "https://docs.google.com";
 constexpr char kExampleUrl[] = "https://example.com";
 
-class FakeNotificationHelper : public DlpClipboardNotificationHelper {
+class FakeClipboardNotifier : public DlpClipboardNotifier {
  public:
   views::Widget* GetWidget() { return GetWidgetForTesting(); }
 
   void ProceedOnWarn(const ui::DataTransferEndpoint& data_dst) {
-    DlpClipboardNotificationHelper::ProceedOnWarn(GetWidget(), data_dst);
+    DlpClipboardNotifier::ProceedOnWarn(GetWidget(), data_dst);
   }
 };
 
 class FakeDlpController : public DataTransferDlpController,
                           public views::WidgetObserver {
  public:
-  FakeDlpController(FakeNotificationHelper* helper)
+  explicit FakeDlpController(FakeClipboardNotifier* helper)
       : DataTransferDlpController(
             *DlpRulesManagerFactory::GetForPrimaryProfile()),
         helper_(helper) {
@@ -78,12 +78,12 @@
   void NotifyBlockedPaste(
       const ui::DataTransferEndpoint* const data_src,
       const ui::DataTransferEndpoint* const data_dst) override {
-    helper_->NotifyBlockedPaste(data_src, data_dst);
+    helper_->NotifyBlockedAction(data_src, data_dst);
   }
 
   void WarnOnPaste(const ui::DataTransferEndpoint* const data_src,
                    const ui::DataTransferEndpoint* const data_dst) override {
-    helper_->WarnOnPaste(data_src, data_dst);
+    helper_->WarnOnAction(data_src, data_dst);
   }
 
   bool ShouldProceedOnWarn(
@@ -102,7 +102,7 @@
 
   MOCK_METHOD1(OnWidgetClosing, void(views::Widget* widget));
   views::Widget* widget_;
-  FakeNotificationHelper* helper_;
+  FakeClipboardNotifier* helper_;
 };
 
 void SetClipboardText(base::string16 text,
@@ -205,8 +205,8 @@
   SkipToLoginScreen();
   LogIn(kAccountId, kAccountPassword, kEmptyServices);
 
-  std::unique_ptr<FakeNotificationHelper> helper =
-      std::make_unique<FakeNotificationHelper>();
+  std::unique_ptr<FakeClipboardNotifier> helper =
+      std::make_unique<FakeClipboardNotifier>();
   FakeDlpController dlp_controller(helper.get());
 
   base::Value rules(base::Value::Type::LIST);
@@ -283,12 +283,10 @@
 
   SetupCrostini();
 
-  const std::string kUrl1 = "https://mail.google.com";
-
   base::Value rules(base::Value::Type::LIST);
 
   base::Value src_urls(base::Value::Type::LIST);
-  src_urls.Append(kUrl1);
+  src_urls.Append(kMailUrl);
   base::Value dst_components(base::Value::Type::LIST);
   dst_components.Append(dlp::kArc);
   dst_components.Append(dlp::kCrostini);
@@ -305,7 +303,7 @@
   {
     ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste,
                                      std::make_unique<ui::DataTransferEndpoint>(
-                                         url::Origin::Create(GURL(kUrl1))));
+                                         url::Origin::Create(GURL(kMailUrl))));
     writer.WriteText(base::UTF8ToUTF16(kClipboardText1));
   }
   ui::DataTransferEndpoint data_dst1(ui::EndpointType::kDefault);
@@ -331,8 +329,8 @@
   SkipToLoginScreen();
   LogIn(kAccountId, kAccountPassword, kEmptyServices);
 
-  std::unique_ptr<FakeNotificationHelper> helper =
-      std::make_unique<FakeNotificationHelper>();
+  std::unique_ptr<FakeClipboardNotifier> helper =
+      std::make_unique<FakeClipboardNotifier>();
   FakeDlpController dlp_controller(helper.get());
 
   {
@@ -473,4 +471,59 @@
   FlushMessageLoop();
 }
 
+IN_PROC_BROWSER_TEST_F(DataTransferDlpBrowserTest, WarnComponent) {
+  SkipToLoginScreen();
+  LogIn(kAccountId, kAccountPassword, kEmptyServices);
+
+  SetupCrostini();
+
+  {
+    ListPrefUpdate update(g_browser_process->local_state(),
+                          policy_prefs::kDlpRulesList);
+    base::Value rule(base::Value::Type::DICTIONARY);
+    base::Value src_urls(base::Value::Type::DICTIONARY);
+    base::Value src_urls_list(base::Value::Type::LIST);
+    src_urls_list.Append(base::Value(kMailUrl));
+    src_urls.SetKey("urls", std::move(src_urls_list));
+    rule.SetKey("sources", std::move(src_urls));
+
+    base::Value dst_components(base::Value::Type::DICTIONARY);
+    base::Value dst_components_list(base::Value::Type::LIST);
+    dst_components_list.Append(base::Value("ARC"));
+    dst_components_list.Append(base::Value("CROSTINI"));
+    dst_components_list.Append(base::Value("PLUGIN_VM"));
+    dst_components.SetKey("components", std::move(dst_components_list));
+    rule.SetKey("destinations", std::move(dst_components));
+
+    base::Value restrictions(base::Value::Type::DICTIONARY);
+    base::Value restrictions_list(base::Value::Type::LIST);
+    base::Value class_level_dict(base::Value::Type::DICTIONARY);
+    class_level_dict.SetKey("class", base::Value("CLIPBOARD"));
+    class_level_dict.SetKey("level", base::Value("WARN"));
+    restrictions_list.Append(std::move(class_level_dict));
+    rule.SetKey("restrictions", std::move(restrictions_list));
+
+    update->Append(std::move(rule));
+  }
+
+  {
+    ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste,
+                                     std::make_unique<ui::DataTransferEndpoint>(
+                                         url::Origin::Create(GURL(kMailUrl))));
+    writer.WriteText(base::UTF8ToUTF16(kClipboardText1));
+  }
+
+  ui::DataTransferEndpoint arc_endpoint(ui::EndpointType::kArc);
+  base::string16 result;
+  ui::Clipboard::GetForCurrentThread()->ReadText(
+      ui::ClipboardBuffer::kCopyPaste, &arc_endpoint, &result);
+  EXPECT_EQ(base::UTF8ToUTF16(kClipboardText1), result);
+
+  ui::DataTransferEndpoint crostini_endpoint(ui::EndpointType::kCrostini);
+  result.clear();
+  ui::Clipboard::GetForCurrentThread()->ReadText(
+      ui::ClipboardBuffer::kCopyPaste, &crostini_endpoint, &result);
+  EXPECT_EQ(base::UTF8ToUTF16(kClipboardText1), result);
+}
+
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
index dea626f6..ca416570 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
@@ -278,4 +278,22 @@
   testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
 }
 
+TEST_P(DlpControllerVMsTest, Warn) {
+  ui::DataTransferEndpoint data_src(url::Origin::Create(GURL(kExample1Url)));
+  base::Optional<ui::EndpointType> endpoint_type;
+  bool do_notify;
+  std::tie(endpoint_type, do_notify) = GetParam();
+  ASSERT_TRUE(endpoint_type.has_value());
+  ui::DataTransferEndpoint data_dst(endpoint_type.value(), do_notify);
+
+  // IsClipboardReadAllowed
+  EXPECT_CALL(rules_manager_, IsRestrictedComponent)
+      .WillOnce(testing::Return(DlpRulesManager::Level::kWarn));
+  if (do_notify)
+    EXPECT_CALL(dlp_controller_, WarnOnPaste);
+
+  EXPECT_EQ(true, dlp_controller_.IsClipboardReadAllowed(&data_src, &data_dst));
+  testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
+}
+
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_bubble_constants.h b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_bubble_constants.h
index ebca694..1e3dd728 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_bubble_constants.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_bubble_constants.h
@@ -7,16 +7,30 @@
 
 namespace policy {
 
-// Clipboard ARC toast ID.
-constexpr char kClipboardDlpArcToastId[] = "clipboard_dlp_block_arc";
+// Clipboard ARC toast ID in block mode.
+constexpr char kClipboardBlockArcToastId[] = "clipboard_dlp_block_arc";
 
-// Clipboard Crostini toast ID.
-constexpr char kClipboardDlpCrostiniToastId[] = "clipboard_dlp_block_crostini";
+// Clipboard ARC toast ID in warning mode.
+constexpr char kClipboardWarnArcToastId[] = "clipboard_dlp_warn_arc";
 
-// Clipboard Plugin VM toast ID.
-constexpr char kClipboardDlpPluginVmToastId[] = "clipboard_dlp_block_plugin_vm";
+// Clipboard Crostini toast ID in block mode.
+constexpr char kClipboardBlockCrostiniToastId[] =
+    "clipboard_dlp_block_crostini";
+
+// Clipboard Crostini toast ID in warning mode.
+constexpr char kClipboardWarnCrostiniToastId[] = "clipboard_dlp_warn_crostini";
+
+// Clipboard Plugin VM toast ID in block mode.
+constexpr char kClipboardBlockPluginVmToastId[] =
+    "clipboard_dlp_block_plugin_vm";
+
+// Clipboard Plugin VM toast ID in warning mode.
+constexpr char kClipboardWarnPluginVmToastId[] = "clipboard_dlp_warn_plugin_vm";
 
 // The duration of the clipboard toast/bubble shown on blocked paste.
+constexpr int kClipboardDlpToastDurationMs = 2500;
+
+// The duration of the clipboard bubble shown on blocked paste.
 constexpr int kClipboardDlpBlockDurationMs = 2500;
 
 // The duration of the clipboard warning shown before paste.
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notification_helper.cc b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notification_helper.cc
index 52e9ccda..bd16d336 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notification_helper.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notification_helper.cc
@@ -435,27 +435,20 @@
 
   if (data_dst) {
     if (data_dst->type() == ui::EndpointType::kCrostini) {
-      ShowClipboardBlockToast(
-          kClipboardDlpCrostiniToastId,
-          l10n_util::GetStringFUTF16(
-              IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_COPY_VM, host_name,
-              l10n_util::GetStringUTF16(IDS_CROSTINI_LINUX)));
+      ShowClipboardBlockToast(kClipboardBlockCrostiniToastId, host_name,
+                              l10n_util::GetStringUTF16(IDS_CROSTINI_LINUX));
       return;
     }
     if (data_dst->type() == ui::EndpointType::kPluginVm) {
       ShowClipboardBlockToast(
-          kClipboardDlpPluginVmToastId,
-          l10n_util::GetStringFUTF16(
-              IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_COPY_VM, host_name,
-              l10n_util::GetStringUTF16(IDS_PLUGIN_VM_APP_NAME)));
+          kClipboardBlockPluginVmToastId, host_name,
+          l10n_util::GetStringUTF16(IDS_PLUGIN_VM_APP_NAME));
       return;
     }
     if (data_dst->type() == ui::EndpointType::kArc) {
       ShowClipboardBlockToast(
-          kClipboardDlpArcToastId,
-          l10n_util::GetStringFUTF16(
-              IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_COPY_VM, host_name,
-              l10n_util::GetStringUTF16(IDS_POLICY_DLP_ANDROID_APPS)));
+          kClipboardBlockArcToastId, host_name,
+          l10n_util::GetStringUTF16(IDS_POLICY_DLP_ANDROID_APPS));
       return;
     }
   }
@@ -473,15 +466,19 @@
 
   if (data_dst) {
     if (data_dst->type() == ui::EndpointType::kCrostini) {
-      // TODO(crbug.com/1168104): Support toasts in warning mode.
+      ShowClipboardWarnToast(kClipboardWarnCrostiniToastId,
+                             l10n_util::GetStringUTF16(IDS_CROSTINI_LINUX));
       return;
     }
     if (data_dst->type() == ui::EndpointType::kPluginVm) {
-      // TODO(crbug.com/1168104): Support toasts in warning mode.
+      ShowClipboardWarnToast(kClipboardWarnPluginVmToastId,
+                             l10n_util::GetStringUTF16(IDS_PLUGIN_VM_APP_NAME));
       return;
     }
     if (data_dst->type() == ui::EndpointType::kArc) {
-      // TODO(crbug.com/1168104): Support toasts in warning mode.
+      ShowClipboardWarnToast(
+          kClipboardWarnArcToastId,
+          l10n_util::GetStringUTF16(IDS_POLICY_DLP_ANDROID_APPS));
       return;
     }
   }
@@ -537,8 +534,11 @@
 
 void DlpClipboardNotificationHelper::ShowClipboardBlockToast(
     const std::string& id,
-    const base::string16& text) {
-  ash::ToastData toast(id, text, kClipboardDlpBlockDurationMs,
+    const base::string16& src_name,
+    const base::string16& dst_name) {
+  const base::string16 text = l10n_util::GetStringFUTF16(
+      IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_COPY_VM, src_name, dst_name);
+  ash::ToastData toast(id, text, kClipboardDlpToastDurationMs,
                        /*dismiss_text=*/base::nullopt);
   toast.is_managed = true;
   ash::ToastManager::Get()->Show(toast);
@@ -564,6 +564,17 @@
                       kClipboardDlpWarnDurationMs);
 }
 
+void DlpClipboardNotificationHelper::ShowClipboardWarnToast(
+    const std::string& id,
+    const base::string16& dst_name) {
+  const base::string16 text = l10n_util::GetStringFUTF16(
+      IDS_POLICY_DLP_CLIPBOARD_WARN_ON_COPY_VM, dst_name);
+  ash::ToastData toast(id, text, kClipboardDlpToastDurationMs,
+                       /*dismiss_text=*/base::nullopt);
+  toast.is_managed = true;
+  ash::ToastManager::Get()->Show(toast);
+}
+
 void DlpClipboardNotificationHelper::OnWidgetClosing(views::Widget* widget) {
   if (widget == widget_.get())
     widget_.reset();
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notification_helper.h b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notification_helper.h
deleted file mode 100644
index afb191fe..0000000
--- a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notification_helper.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_CLIPBOARD_NOTIFICATION_HELPER_H_
-#define CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_CLIPBOARD_NOTIFICATION_HELPER_H_
-
-#include <vector>
-
-#include "base/strings/string16.h"
-#include "ui/base/clipboard/clipboard_observer.h"
-#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
-#include "ui/views/widget/unique_widget_ptr.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_observer.h"
-
-namespace ui {
-class DataTransferEndpoint;
-}
-
-namespace policy {
-
-class DlpClipboardNotificationHelper : public views::WidgetObserver,
-                                       public ui::ClipboardObserver {
- public:
-  DlpClipboardNotificationHelper();
-  ~DlpClipboardNotificationHelper() override;
-
-  DlpClipboardNotificationHelper(const DlpClipboardNotificationHelper&) =
-      delete;
-  void operator=(const DlpClipboardNotificationHelper&) = delete;
-
-  // Shows a bubble that clipboard paste is not allowed. If the type of
-  // `data_dst` is kCrostini, kPluginVm or kArc, it will show a toast instead of
-  // a notification.
-  void NotifyBlockedPaste(const ui::DataTransferEndpoint* const data_src,
-                          const ui::DataTransferEndpoint* const data_dst);
-  // Shows a bubble that warns the user that clipboard paste is not recommended.
-  // If the type of `data_dst` is kCrostini, kPluginVm or kArc, it will show a
-  // toast instead of a notification.
-  void WarnOnPaste(const ui::DataTransferEndpoint* const data_src,
-                   const ui::DataTransferEndpoint* const data_dst);
-
-  // Returns true if the user approved to paste the clipboard data to this
-  // |data_dst| before.
-  bool DidUserProceedOnWarn(const ui::DataTransferEndpoint* const data_dst);
-
-  // Needed for testing.
- protected:
-  void ProceedOnWarn(views::Widget* widget,
-                     const ui::DataTransferEndpoint& data_dst);
-
-  void ResetUserWarnSelection();
-
-  views::Widget* GetWidgetForTesting() { return widget_.get(); }
-
- private:
-  virtual void ShowClipboardBlockBubble(const base::string16& text);
-  virtual void ShowClipboardBlockToast(const std::string& id,
-                                       const base::string16& text);
-  virtual void ShowClipboardWarnBubble(
-      const base::string16& text,
-      const ui::DataTransferEndpoint* const data_dst);
-
-  // views::WidgetObserver
-  void OnWidgetClosing(views::Widget* widget) override;
-  void OnWidgetDestroyed(views::Widget* widget) override;
-  void OnWidgetActivationChanged(views::Widget* widget, bool active) override;
-
-  // ui::ClipboardObserver
-  void OnClipboardDataChanged() override;
-
-  virtual void InitWidget();
-
-  virtual void ResizeAndShowWidget(const gfx::Size& bubble_size,
-                                   int timeout_duration_ms);
-
-  virtual void CloseWidget(views::Widget* widget,
-                           views::Widget::ClosedReason reason);
-
-  // Vector of destinations approved by the user on warning for copy/paste. It
-  // gets reset when the clipboard data changes.
-  std::vector<ui::DataTransferEndpoint> approved_dsts_;
-
-  views::UniqueWidgetPtr widget_;
-};
-
-}  // namespace policy
-
-#endif  // CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_CLIPBOARD_NOTIFICATION_HELPER_H_
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notification_helper_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notification_helper_unittest.cc
deleted file mode 100644
index 3d52583..0000000
--- a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notification_helper_unittest.cc
+++ /dev/null
@@ -1,203 +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 "chrome/browser/chromeos/policy/dlp/dlp_clipboard_notification_helper.h"
-
-#include <string>
-
-#include "base/optional.h"
-#include "base/stl_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/chromeos/policy/dlp/dlp_clipboard_bubble_constants.h"
-#include "chrome/grit/generated_resources.h"
-#include "components/strings/grit/components_strings.h"
-#include "testing/gmock/include/gmock/gmock-matchers.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "url/gurl.h"
-#include "url/origin.h"
-
-namespace policy {
-
-namespace {
-
-constexpr char kUrl[] = "https://example.com";
-
-struct ToastTest {
-  ToastTest(ui::EndpointType dst_type,
-            const std::string& toast_id,
-            int dst_name_id)
-      : dst_type(dst_type),
-        expected_toast_id(toast_id),
-        expected_dst_name_id(dst_name_id) {}
-
-  const ui::EndpointType dst_type;
-  const std::string expected_toast_id;
-  const int expected_dst_name_id;
-};
-
-}  // namespace
-
-class MockDlpClipboardNotificationHelper
-    : public DlpClipboardNotificationHelper {
- public:
-  MOCK_METHOD1(ShowClipboardBlockBubble, void(const base::string16& text));
-  MOCK_METHOD2(ShowClipboardBlockToast,
-               void(const std::string& id, const base::string16& text));
-  MOCK_METHOD2(ShowClipboardWarnBubble,
-               void(const base::string16& text,
-                    const ui::DataTransferEndpoint* const data_dst));
-  void ProceedOnWarn(views::Widget* widget,
-                     const ui::DataTransferEndpoint& data_dst) {
-    DlpClipboardNotificationHelper::ProceedOnWarn(widget, data_dst);
-  }
-
-  void ResetUserWarnSelection() {
-    DlpClipboardNotificationHelper::ResetUserWarnSelection();
-  }
-
- private:
-  void InitWidget() override {}
-
-  void ResizeAndShowWidget(const gfx::Size& bubble_size,
-                           int timeout_duration_ms) override {}
-
-  void CloseWidget(views::Widget* widget,
-                   views::Widget::ClosedReason reason) override {}
-};
-
-class DlpClipboardBubbleTest
-    : public ::testing::TestWithParam<base::Optional<ui::EndpointType>> {};
-
-TEST_P(DlpClipboardBubbleTest, BlockBubble) {
-  ::testing::StrictMock<MockDlpClipboardNotificationHelper> notification_helper;
-  url::Origin origin = url::Origin::Create(GURL(kUrl));
-  ui::DataTransferEndpoint data_src(origin);
-  base::Optional<ui::DataTransferEndpoint> data_dst;
-  auto param = GetParam();
-  if (param.has_value()) {
-    if (param.value() == ui::EndpointType::kUrl)
-      data_dst.emplace(url::Origin::Create(GURL(kUrl)));
-    else
-      data_dst.emplace(param.value());
-  }
-
-  base::string16 expected_bubble_str =
-      l10n_util::GetStringFUTF16(IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_PASTE,
-                                 base::UTF8ToUTF16(origin.host()));
-  EXPECT_CALL(notification_helper,
-              ShowClipboardBlockBubble(expected_bubble_str));
-
-  notification_helper.NotifyBlockedPaste(&data_src,
-                                         base::OptionalOrNullptr(data_dst));
-}
-
-TEST_P(DlpClipboardBubbleTest, WarnBubble) {
-  ::testing::StrictMock<MockDlpClipboardNotificationHelper> notification_helper;
-  url::Origin origin = url::Origin::Create(GURL(kUrl));
-  ui::DataTransferEndpoint data_src(origin);
-  base::Optional<ui::DataTransferEndpoint> data_dst;
-  auto param = GetParam();
-  if (param.has_value()) {
-    if (param.value() == ui::EndpointType::kUrl)
-      data_dst.emplace(url::Origin::Create(GURL(kUrl)));
-    else
-      data_dst.emplace(param.value());
-  }
-
-  base::string16 expected_bubble_str = l10n_util::GetStringFUTF16(
-      IDS_POLICY_DLP_CLIPBOARD_WARN_ON_PASTE, base::UTF8ToUTF16(origin.host()));
-  const ui::DataTransferEndpoint* dst_ptr = base::OptionalOrNullptr(data_dst);
-  EXPECT_CALL(notification_helper,
-              ShowClipboardWarnBubble(expected_bubble_str, dst_ptr));
-
-  notification_helper.WarnOnPaste(&data_src, dst_ptr);
-}
-
-TEST_P(DlpClipboardBubbleTest, ProceedOnWarn) {
-  ::testing::StrictMock<MockDlpClipboardNotificationHelper> notification_helper;
-  base::Optional<ui::DataTransferEndpoint> data_dst;
-  auto param = GetParam();
-  // ProceedOnWarn gets called with const reference to DataTransferEndpoint.
-  if (!param.has_value())
-    return;
-
-  if (param.value() == ui::EndpointType::kUrl)
-    data_dst.emplace(url::Origin::Create(GURL(kUrl)));
-  else
-    data_dst.emplace(param.value());
-
-  const ui::DataTransferEndpoint* dst_ptr = base::OptionalOrNullptr(data_dst);
-  notification_helper.ProceedOnWarn(nullptr, *dst_ptr);
-  EXPECT_TRUE(notification_helper.DidUserProceedOnWarn(dst_ptr));
-}
-
-INSTANTIATE_TEST_SUITE_P(DlpClipboard,
-                         DlpClipboardBubbleTest,
-                         ::testing::Values(base::nullopt,
-                                           ui::EndpointType::kDefault,
-                                           ui::EndpointType::kUnknownVm,
-                                           ui::EndpointType::kBorealis,
-                                           ui::EndpointType::kUrl));
-
-TEST_F(DlpClipboardBubbleTest, ProceedSavedHistory) {
-  ::testing::StrictMock<MockDlpClipboardNotificationHelper> notification_helper;
-  const ui::DataTransferEndpoint url_dst(url::Origin::Create(GURL(kUrl)));
-  const ui::DataTransferEndpoint default_dst(ui::EndpointType::kDefault);
-  const ui::DataTransferEndpoint arc_dst(ui::EndpointType::kArc);
-  const ui::DataTransferEndpoint crostini_dst(ui::EndpointType::kCrostini);
-
-  notification_helper.ProceedOnWarn(nullptr, url_dst);
-  notification_helper.ProceedOnWarn(nullptr, default_dst);
-  notification_helper.ProceedOnWarn(nullptr, arc_dst);
-  notification_helper.ProceedOnWarn(nullptr, crostini_dst);
-
-  EXPECT_TRUE(notification_helper.DidUserProceedOnWarn(&url_dst));
-  EXPECT_TRUE(notification_helper.DidUserProceedOnWarn(&default_dst));
-  EXPECT_TRUE(notification_helper.DidUserProceedOnWarn(&arc_dst));
-  EXPECT_TRUE(notification_helper.DidUserProceedOnWarn(&crostini_dst));
-
-  notification_helper.ResetUserWarnSelection();
-
-  EXPECT_FALSE(notification_helper.DidUserProceedOnWarn(&url_dst));
-  EXPECT_FALSE(notification_helper.DidUserProceedOnWarn(&default_dst));
-  EXPECT_FALSE(notification_helper.DidUserProceedOnWarn(&arc_dst));
-  EXPECT_FALSE(notification_helper.DidUserProceedOnWarn(&crostini_dst));
-}
-
-class DlpClipboardToastTest : public ::testing::TestWithParam<ToastTest> {};
-
-TEST_P(DlpClipboardToastTest, BlockToast) {
-  ::testing::StrictMock<MockDlpClipboardNotificationHelper> notification_helper;
-  url::Origin origin = url::Origin::Create(GURL(kUrl));
-  ui::DataTransferEndpoint data_src(origin);
-  ui::DataTransferEndpoint data_dst(GetParam().dst_type);
-
-  base::string16 expected_toast_str = l10n_util::GetStringFUTF16(
-      IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_COPY_VM,
-      base::UTF8ToUTF16(origin.host()),
-      l10n_util::GetStringUTF16(GetParam().expected_dst_name_id));
-  EXPECT_CALL(notification_helper,
-              ShowClipboardBlockToast(GetParam().expected_toast_id,
-                                      expected_toast_str));
-
-  notification_helper.NotifyBlockedPaste(&data_src, &data_dst);
-}
-
-INSTANTIATE_TEST_SUITE_P(
-    DlpClipboard,
-    DlpClipboardToastTest,
-    ::testing::Values(ToastTest(ui::EndpointType::kCrostini,
-                                kClipboardDlpCrostiniToastId,
-                                IDS_CROSTINI_LINUX),
-                      ToastTest(ui::EndpointType::kPluginVm,
-                                kClipboardDlpPluginVmToastId,
-                                IDS_PLUGIN_VM_APP_NAME),
-                      ToastTest(ui::EndpointType::kArc,
-                                kClipboardDlpArcToastId,
-                                IDS_POLICY_DLP_ANDROID_APPS)));
-
-}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
new file mode 100644
index 0000000..490e47c1
--- /dev/null
+++ b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
@@ -0,0 +1,188 @@
+// 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/chromeos/policy/dlp/dlp_clipboard_notifier.h"
+
+#include <memory>
+
+#include "ash/public/cpp/toast_data.h"
+#include "ash/public/cpp/toast_manager.h"
+#include "ash/public/cpp/window_tree_host_lookup.h"
+#include "chrome/browser/chromeos/policy/dlp/clipboard_bubble.h"
+#include "chrome/browser/chromeos/policy/dlp/dlp_clipboard_bubble_constants.h"
+#include "chrome/grit/generated_resources.h"
+#include "components/strings/grit/components_strings.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/base/clipboard/clipboard_monitor.h"
+#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/display/screen.h"
+
+namespace policy {
+
+namespace {
+
+ui::DataTransferEndpoint CloneEndpoint(
+    const ui::DataTransferEndpoint* const data_endpoint) {
+  if (data_endpoint == nullptr)
+    return ui::DataTransferEndpoint(ui::EndpointType::kDefault);
+
+  return ui::DataTransferEndpoint(*data_endpoint);
+}
+
+void SynthesizePaste() {
+  ui::KeyEvent control_press(/*type=*/ui::ET_KEY_PRESSED, ui::VKEY_CONTROL,
+                             /*code=*/static_cast<ui::DomCode>(0),
+                             /*flags=*/0);
+  if (!display::Screen::GetScreen())  // Doesn't exist in unittests.
+    return;
+  auto* host = ash::GetWindowTreeHostForDisplay(
+      display::Screen::GetScreen()->GetDisplayForNewWindows().id());
+  DCHECK(host);
+  host->DeliverEventToSink(&control_press);
+
+  ui::KeyEvent v_press(/*type=*/ui::ET_KEY_PRESSED, ui::VKEY_V,
+                       /*code=*/static_cast<ui::DomCode>(0),
+                       /*flags=*/ui::EF_CONTROL_DOWN);
+
+  host->DeliverEventToSink(&v_press);
+
+  ui::KeyEvent v_release(/*type=*/ui::ET_KEY_RELEASED, ui::VKEY_V,
+                         /*code=*/static_cast<ui::DomCode>(0),
+                         /*flags=*/ui::EF_CONTROL_DOWN);
+  host->DeliverEventToSink(&v_release);
+
+  ui::KeyEvent control_release(/*type=*/ui::ET_KEY_RELEASED, ui::VKEY_CONTROL,
+                               /*code=*/static_cast<ui::DomCode>(0),
+                               /*flags=*/0);
+  host->DeliverEventToSink(&control_release);
+}
+
+}  // namespace
+
+DlpClipboardNotifier::DlpClipboardNotifier() {
+  ui::ClipboardMonitor::GetInstance()->AddObserver(this);
+}
+
+DlpClipboardNotifier::~DlpClipboardNotifier() {
+  ui::ClipboardMonitor::GetInstance()->RemoveObserver(this);
+}
+
+void DlpClipboardNotifier::NotifyBlockedAction(
+    const ui::DataTransferEndpoint* const data_src,
+    const ui::DataTransferEndpoint* const data_dst) {
+  DCHECK(data_src);
+  DCHECK(data_src->origin());
+  const base::string16 host_name =
+      base::UTF8ToUTF16(data_src->origin()->host());
+  if (data_dst) {
+    if (data_dst->type() == ui::EndpointType::kCrostini) {
+      ShowToast(kClipboardBlockCrostiniToastId,
+                l10n_util::GetStringFUTF16(
+                    IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_COPY_VM, host_name,
+                    l10n_util::GetStringUTF16(IDS_CROSTINI_LINUX)));
+      return;
+    }
+    if (data_dst->type() == ui::EndpointType::kPluginVm) {
+      ShowToast(kClipboardBlockPluginVmToastId,
+                l10n_util::GetStringFUTF16(
+                    IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_COPY_VM, host_name,
+                    l10n_util::GetStringUTF16(IDS_PLUGIN_VM_APP_NAME)));
+      return;
+    }
+    if (data_dst->type() == ui::EndpointType::kArc) {
+      ShowToast(kClipboardBlockArcToastId,
+                l10n_util::GetStringFUTF16(
+                    IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_COPY_VM, host_name,
+                    l10n_util::GetStringUTF16(IDS_POLICY_DLP_ANDROID_APPS)));
+      return;
+    }
+  }
+
+  ShowBlockBubble(l10n_util::GetStringFUTF16(
+      IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_PASTE, host_name));
+}
+
+void DlpClipboardNotifier::WarnOnAction(
+    const ui::DataTransferEndpoint* const data_src,
+    const ui::DataTransferEndpoint* const data_dst) {
+  DCHECK(data_src);
+  DCHECK(data_src->origin());
+  const base::string16 host_name =
+      base::UTF8ToUTF16(data_src->origin()->host());
+
+  if (data_dst) {
+    if (data_dst->type() == ui::EndpointType::kCrostini) {
+      ShowToast(kClipboardWarnCrostiniToastId,
+                l10n_util::GetStringFUTF16(
+                    IDS_POLICY_DLP_CLIPBOARD_WARN_ON_COPY_VM,
+                    l10n_util::GetStringUTF16(IDS_CROSTINI_LINUX)));
+      return;
+    }
+    if (data_dst->type() == ui::EndpointType::kPluginVm) {
+      ShowToast(kClipboardWarnPluginVmToastId,
+                l10n_util::GetStringFUTF16(
+                    IDS_POLICY_DLP_CLIPBOARD_WARN_ON_COPY_VM,
+                    l10n_util::GetStringUTF16(IDS_PLUGIN_VM_APP_NAME)));
+      return;
+    }
+    if (data_dst->type() == ui::EndpointType::kArc) {
+      ShowToast(kClipboardWarnArcToastId,
+                l10n_util::GetStringFUTF16(
+                    IDS_POLICY_DLP_CLIPBOARD_WARN_ON_COPY_VM,
+                    l10n_util::GetStringUTF16(IDS_POLICY_DLP_ANDROID_APPS)));
+      return;
+    }
+  }
+
+  auto proceed_cb = base::BindRepeating(&DlpClipboardNotifier::ProceedOnWarn,
+                                        base::Unretained(this), widget_.get(),
+                                        CloneEndpoint(data_dst));
+  ShowWarningBubble(l10n_util::GetStringFUTF16(
+                        IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_PASTE, host_name),
+                    proceed_cb);
+}
+
+bool DlpClipboardNotifier::DidUserProceedOnWarn(
+    const ui::DataTransferEndpoint* const data_dst) {
+  const ui::EndpointType dst_type =
+      data_dst ? data_dst->type() : ui::EndpointType::kDefault;
+
+  for (const auto& endpoint : approved_dsts_) {
+    if (endpoint.type() == dst_type) {
+      if (dst_type != ui::EndpointType::kUrl)
+        return true;
+      else if (endpoint.IsSameOriginWith(*data_dst))
+        return true;
+    }
+  }
+  return false;
+}
+
+void DlpClipboardNotifier::ProceedOnWarn(
+    views::Widget* widget,
+    const ui::DataTransferEndpoint& data_dst) {
+  CloseWidget(widget, views::Widget::ClosedReason::kAcceptButtonClicked);
+  approved_dsts_.push_back(data_dst);
+  SynthesizePaste();
+}
+
+void DlpClipboardNotifier::ResetUserWarnSelection() {
+  approved_dsts_.clear();
+}
+
+void DlpClipboardNotifier::ShowToast(const std::string& id,
+                                     const base::string16& text) const {
+  ash::ToastData toast(id, text, kClipboardDlpBlockDurationMs,
+                       /*dismiss_text=*/base::nullopt);
+  toast.is_managed = true;
+  ash::ToastManager::Get()->Show(toast);
+}
+
+void DlpClipboardNotifier::OnClipboardDataChanged() {
+  CloseWidget(widget_.get(), views::Widget::ClosedReason::kUnspecified);
+  ResetUserWarnSelection();
+}
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.h b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.h
new file mode 100644
index 0000000..aa8f1a1
--- /dev/null
+++ b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.h
@@ -0,0 +1,57 @@
+// 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_CHROMEOS_POLICY_DLP_DLP_CLIPBOARD_NOTIFIER_H_
+#define CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_CLIPBOARD_NOTIFIER_H_
+
+#include "chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.h"
+#include "ui/base/clipboard/clipboard_observer.h"
+
+namespace policy {
+
+class DlpClipboardNotifier : public DlpDataTransferNotifier,
+                             public ui::ClipboardObserver {
+ public:
+  DlpClipboardNotifier();
+  ~DlpClipboardNotifier() override;
+
+  DlpClipboardNotifier(const DlpClipboardNotifier&) = delete;
+  void operator=(const DlpClipboardNotifier&) = delete;
+
+  // DlpDataTransferNotifier::
+  // If the type of `data_dst` is kCrostini, kPluginVm or kArc, it will show a
+  // toast instead of a bubble.
+  void NotifyBlockedAction(
+      const ui::DataTransferEndpoint* const data_src,
+      const ui::DataTransferEndpoint* const data_dst) override;
+  // If the type of `data_dst` is kCrostini, kPluginVm or kArc, it will show a
+  // toast instead of a bubble.
+  void WarnOnAction(const ui::DataTransferEndpoint* const data_src,
+                    const ui::DataTransferEndpoint* const data_dst) override;
+
+  // Returns true if the user approved to paste the clipboard data to this
+  // |data_dst| before.
+  bool DidUserProceedOnWarn(const ui::DataTransferEndpoint* const data_dst);
+
+ protected:
+  void ProceedOnWarn(views::Widget* widget,
+                     const ui::DataTransferEndpoint& data_dst);
+
+  void ResetUserWarnSelection();
+
+ private:
+  virtual void ShowToast(const std::string& id,
+                         const base::string16& text) const;
+
+  // ui::ClipboardObserver
+  void OnClipboardDataChanged() override;
+
+  // Vector of destinations approved by the user on warning for copy/paste. It
+  // gets reset when the clipboard data changes.
+  std::vector<ui::DataTransferEndpoint> approved_dsts_;
+};
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_CLIPBOARD_NOTIFIER_H_
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier_unittest.cc
new file mode 100644
index 0000000..c33eeff
--- /dev/null
+++ b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier_unittest.cc
@@ -0,0 +1,190 @@
+// 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 "chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.h"
+
+#include <string>
+
+#include "base/optional.h"
+#include "base/stl_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chromeos/policy/dlp/clipboard_bubble.h"
+#include "chrome/browser/chromeos/policy/dlp/dlp_clipboard_bubble_constants.h"
+#include "chrome/grit/generated_resources.h"
+#include "components/strings/grit/components_strings.h"
+#include "testing/gmock/include/gmock/gmock-matchers.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace policy {
+
+namespace {
+
+constexpr char kUrl[] = "https://example.com";
+
+struct ToastTest {
+  ToastTest(ui::EndpointType dst_type, int dst_name_id)
+      : dst_type(dst_type), expected_dst_name_id(dst_name_id) {}
+
+  const ui::EndpointType dst_type;
+  const int expected_dst_name_id;
+};
+
+}  // namespace
+
+class MockDlpClipboardNotifier : public DlpClipboardNotifier {
+ public:
+  MOCK_METHOD1(ShowBlockBubble, void(const base::string16& text));
+  MOCK_METHOD2(ShowWarningBubble,
+               void(const base::string16& text,
+                    base::RepeatingCallback<void()> proceed_cb));
+  MOCK_CONST_METHOD2(ShowToast,
+                     void(const std::string& id, const base::string16& text));
+  void ProceedOnWarn(views::Widget* widget,
+                     const ui::DataTransferEndpoint& data_dst) {
+    DlpClipboardNotifier::ProceedOnWarn(widget, data_dst);
+  }
+
+  void ResetUserWarnSelection() {
+    DlpClipboardNotifier::ResetUserWarnSelection();
+  }
+};
+
+class DlpClipboardBubbleTest
+    : public ::testing::TestWithParam<base::Optional<ui::EndpointType>> {};
+
+TEST_P(DlpClipboardBubbleTest, BlockBubble) {
+  ::testing::StrictMock<MockDlpClipboardNotifier> notifier;
+  url::Origin origin = url::Origin::Create(GURL(kUrl));
+  ui::DataTransferEndpoint data_src(origin);
+  base::Optional<ui::DataTransferEndpoint> data_dst;
+  auto param = GetParam();
+  if (param.has_value()) {
+    if (param.value() == ui::EndpointType::kUrl)
+      data_dst.emplace(url::Origin::Create(GURL(kUrl)));
+    else
+      data_dst.emplace(param.value());
+  }
+
+  EXPECT_CALL(notifier, ShowBlockBubble);
+
+  notifier.NotifyBlockedAction(&data_src, base::OptionalOrNullptr(data_dst));
+}
+
+TEST_P(DlpClipboardBubbleTest, WarnBubble) {
+  ::testing::StrictMock<MockDlpClipboardNotifier> notifier;
+  url::Origin origin = url::Origin::Create(GURL(kUrl));
+  ui::DataTransferEndpoint data_src(origin);
+  base::Optional<ui::DataTransferEndpoint> data_dst;
+  auto param = GetParam();
+  if (param.has_value()) {
+    if (param.value() == ui::EndpointType::kUrl)
+      data_dst.emplace(url::Origin::Create(GURL(kUrl)));
+    else
+      data_dst.emplace(param.value());
+  }
+
+  EXPECT_CALL(notifier, ShowWarningBubble);
+
+  const ui::DataTransferEndpoint* dst_ptr = base::OptionalOrNullptr(data_dst);
+  notifier.WarnOnAction(&data_src, dst_ptr);
+}
+
+TEST_P(DlpClipboardBubbleTest, ProceedOnWarn) {
+  ::testing::StrictMock<MockDlpClipboardNotifier> notifier;
+  base::Optional<ui::DataTransferEndpoint> data_dst;
+  auto param = GetParam();
+  // ProceedOnWarn gets called with const reference to DataTransferEndpoint.
+  if (!param.has_value())
+    return;
+
+  if (param.value() == ui::EndpointType::kUrl)
+    data_dst.emplace(url::Origin::Create(GURL(kUrl)));
+  else
+    data_dst.emplace(param.value());
+
+  const ui::DataTransferEndpoint* dst_ptr = base::OptionalOrNullptr(data_dst);
+  notifier.ProceedOnWarn(nullptr, *dst_ptr);
+  EXPECT_TRUE(notifier.DidUserProceedOnWarn(dst_ptr));
+}
+
+INSTANTIATE_TEST_SUITE_P(DlpClipboard,
+                         DlpClipboardBubbleTest,
+                         ::testing::Values(base::nullopt,
+                                           ui::EndpointType::kDefault,
+                                           ui::EndpointType::kUnknownVm,
+                                           ui::EndpointType::kBorealis,
+                                           ui::EndpointType::kUrl));
+
+TEST_F(DlpClipboardBubbleTest, ProceedSavedHistory) {
+  ::testing::StrictMock<MockDlpClipboardNotifier> notifier;
+  const ui::DataTransferEndpoint url_dst(url::Origin::Create(GURL(kUrl)));
+  const ui::DataTransferEndpoint default_dst(ui::EndpointType::kDefault);
+  const ui::DataTransferEndpoint arc_dst(ui::EndpointType::kArc);
+  const ui::DataTransferEndpoint crostini_dst(ui::EndpointType::kCrostini);
+
+  notifier.ProceedOnWarn(nullptr, url_dst);
+  notifier.ProceedOnWarn(nullptr, default_dst);
+  notifier.ProceedOnWarn(nullptr, arc_dst);
+  notifier.ProceedOnWarn(nullptr, crostini_dst);
+
+  EXPECT_TRUE(notifier.DidUserProceedOnWarn(&url_dst));
+  EXPECT_TRUE(notifier.DidUserProceedOnWarn(&default_dst));
+  EXPECT_TRUE(notifier.DidUserProceedOnWarn(&arc_dst));
+  EXPECT_TRUE(notifier.DidUserProceedOnWarn(&crostini_dst));
+
+  notifier.ResetUserWarnSelection();
+
+  EXPECT_FALSE(notifier.DidUserProceedOnWarn(&url_dst));
+  EXPECT_FALSE(notifier.DidUserProceedOnWarn(&default_dst));
+  EXPECT_FALSE(notifier.DidUserProceedOnWarn(&arc_dst));
+  EXPECT_FALSE(notifier.DidUserProceedOnWarn(&crostini_dst));
+}
+
+class DlpClipboardToastTest : public ::testing::TestWithParam<ToastTest> {};
+
+TEST_P(DlpClipboardToastTest, BlockToast) {
+  ::testing::StrictMock<MockDlpClipboardNotifier> notifier;
+  url::Origin origin = url::Origin::Create(GURL(kUrl));
+  ui::DataTransferEndpoint data_src(origin);
+  ui::DataTransferEndpoint data_dst(GetParam().dst_type);
+
+  base::string16 expected_toast_str = l10n_util::GetStringFUTF16(
+      IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_COPY_VM,
+      base::UTF8ToUTF16(origin.host()),
+      l10n_util::GetStringUTF16(GetParam().expected_dst_name_id));
+
+  EXPECT_CALL(notifier, ShowToast(testing::_, expected_toast_str));
+
+  notifier.NotifyBlockedAction(&data_src, &data_dst);
+}
+
+TEST_P(DlpClipboardToastTest, WarnToast) {
+  ::testing::StrictMock<MockDlpClipboardNotifier> notifier;
+  url::Origin origin = url::Origin::Create(GURL(kUrl));
+  ui::DataTransferEndpoint data_src(origin);
+  ui::DataTransferEndpoint data_dst(GetParam().dst_type);
+
+  base::string16 expected_toast_str = l10n_util::GetStringFUTF16(
+      IDS_POLICY_DLP_CLIPBOARD_WARN_ON_COPY_VM,
+      l10n_util::GetStringUTF16(GetParam().expected_dst_name_id));
+
+  EXPECT_CALL(notifier, ShowToast(testing::_, expected_toast_str));
+
+  notifier.WarnOnAction(&data_src, &data_dst);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    DlpClipboard,
+    DlpClipboardToastTest,
+    ::testing::Values(
+        ToastTest(ui::EndpointType::kCrostini, IDS_CROSTINI_LINUX),
+        ToastTest(ui::EndpointType::kPluginVm, IDS_PLUGIN_VM_APP_NAME),
+        ToastTest(ui::EndpointType::kArc, IDS_POLICY_DLP_ANDROID_APPS)));
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.cc b/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.cc
new file mode 100644
index 0000000..78836b7
--- /dev/null
+++ b/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.cc
@@ -0,0 +1,176 @@
+// 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/chromeos/policy/dlp/dlp_data_transfer_notifier.h"
+
+#include "ash/public/cpp/window_tree_host_lookup.h"
+#include "base/callback_forward.h"
+#include "chrome/browser/chromeos/policy/dlp/clipboard_bubble.h"
+#include "chrome/browser/chromeos/policy/dlp/dlp_clipboard_bubble_constants.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/base/ime/input_method.h"
+#include "ui/base/ime/text_input_client.h"
+#include "ui/compositor/scoped_layer_animation_settings.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
+#include "ui/views/widget/widget.h"
+
+namespace policy {
+
+namespace {
+
+// The name of the bubble.
+constexpr char kBubbleName[] = "ClipboardDlpBubble";
+
+constexpr base::TimeDelta kBubbleBoundsAnimationTime =
+    base::TimeDelta::FromMilliseconds(250);
+
+bool IsRectContainedByAnyDisplay(const gfx::Rect& rect) {
+  const std::vector<display::Display>& displays =
+      display::Screen::GetScreen()->GetAllDisplays();
+  for (const auto& display : displays) {
+    if (display.bounds().Contains(rect))
+      return true;
+  }
+  return false;
+}
+
+void CalculateAndSetWidgetBounds(views::Widget* widget,
+                                 const gfx::Size& bubble_size) {
+  display::Screen* screen = display::Screen::GetScreen();
+  display::Display display = screen->GetPrimaryDisplay();
+  auto* host = ash::GetWindowTreeHostForDisplay(display.id());
+
+  ui::TextInputClient* text_input_client =
+      host->GetInputMethod()->GetTextInputClient();
+
+  // `text_input_client` may be null. For example, in clamshell mode and without
+  // any window open.
+  if (!text_input_client)
+    return;
+
+  gfx::Rect caret_bounds = text_input_client->GetCaretBounds();
+
+  // Note that the width of caret's bounds may be zero in some views (such as
+  // the search bar of Google search web page). So we cannot use
+  // gfx::Size::IsEmpty() here. In addition, the applications using IFrame may
+  // provide unreliable `caret_bounds` which are not fully contained by the
+  // display bounds.
+  const bool caret_bounds_are_valid = caret_bounds.size() != gfx::Size() &&
+                                      IsRectContainedByAnyDisplay(caret_bounds);
+  if (!caret_bounds_are_valid) {
+    caret_bounds.set_origin(
+        display::Screen::GetScreen()->GetCursorScreenPoint());
+  }
+
+  const gfx::Rect widget_bounds =
+      gfx::Rect(caret_bounds.x(), caret_bounds.y(), bubble_size.width(),
+                bubble_size.height());
+
+  std::unique_ptr<ui::ScopedLayerAnimationSettings> settings;
+  if (widget->GetWindowBoundsInScreen().size() != gfx::Size()) {
+    settings = std::make_unique<ui::ScopedLayerAnimationSettings>(
+        widget->GetLayer()->GetAnimator());
+    settings->SetPreemptionStrategy(
+        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+    settings->SetTransitionDuration(kBubbleBoundsAnimationTime);
+    settings->SetTweenType(gfx::Tween::EASE_OUT);
+  }
+
+  widget->SetBounds(widget_bounds);
+}
+
+views::Widget::InitParams GetWidgetInitParams() {
+  views::Widget::InitParams params(
+      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+  params.z_order = ui::ZOrderLevel::kNormal;
+  params.activatable = views::Widget::InitParams::ACTIVATABLE_YES;
+  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+  params.name = kBubbleName;
+  params.layer_type = ui::LAYER_NOT_DRAWN;
+  params.parent = nullptr;
+  params.shadow_type = views::Widget::InitParams::ShadowType::kDrop;
+  return params;
+}
+
+}  // namespace
+
+DlpDataTransferNotifier::DlpDataTransferNotifier() = default;
+DlpDataTransferNotifier::~DlpDataTransferNotifier() {
+  if (widget_) {
+    widget_->RemoveObserver(this);
+    CloseWidget(widget_.get(), views::Widget::ClosedReason::kUnspecified);
+  }
+}
+
+void DlpDataTransferNotifier::ShowBlockBubble(const base::string16& text) {
+  InitWidget();
+  ClipboardBlockBubble* bubble =
+      widget_->SetContentsView(std::make_unique<ClipboardBlockBubble>(text));
+  bubble->SetDismissCallback(base::BindRepeating(
+      &DlpDataTransferNotifier::CloseWidget, base::Unretained(this),
+      widget_.get(), views::Widget::ClosedReason::kCancelButtonClicked));
+  ResizeAndShowWidget(bubble->GetBubbleSize(), kClipboardDlpBlockDurationMs);
+}
+
+void DlpDataTransferNotifier::ShowWarningBubble(
+    const base::string16& text,
+    base::RepeatingCallback<void()> proceed_cb) {
+  InitWidget();
+  ClipboardWarnBubble* bubble =
+      widget_->SetContentsView(std::make_unique<ClipboardWarnBubble>(text));
+  bubble->SetDismissCallback(base::BindRepeating(
+      &DlpDataTransferNotifier::CloseWidget, base::Unretained(this),
+      widget_.get(), views::Widget::ClosedReason::kCancelButtonClicked));
+  bubble->SetProceedCallback(proceed_cb);
+  ResizeAndShowWidget(bubble->GetBubbleSize(), kClipboardDlpWarnDurationMs);
+}
+
+void DlpDataTransferNotifier::CloseWidget(views::Widget* widget,
+                                          views::Widget::ClosedReason reason) {
+  if (widget && widget == widget_.get())
+    widget->CloseWithReason(reason);
+}
+
+void DlpDataTransferNotifier::OnWidgetClosing(views::Widget* widget) {
+  if (widget == widget_.get())
+    widget_.reset();
+}
+
+void DlpDataTransferNotifier::OnWidgetDestroyed(views::Widget* widget) {
+  if (widget == widget_.get())
+    widget_.reset();
+}
+
+void DlpDataTransferNotifier::OnWidgetActivationChanged(views::Widget* widget,
+                                                        bool active) {
+  if (!active)
+    CloseWidget(widget, views::Widget::ClosedReason::kLostFocus);
+}
+
+void DlpDataTransferNotifier::InitWidget() {
+  widget_ = std::make_unique<views::Widget>();
+  widget_->Init(GetWidgetInitParams());
+  widget_->AddObserver(this);
+}
+
+void DlpDataTransferNotifier::ResizeAndShowWidget(const gfx::Size& bubble_size,
+                                                  int timeout_duration_ms) {
+  DCHECK(widget_);
+
+  CalculateAndSetWidgetBounds(widget_.get(), bubble_size);
+
+  widget_->Show();
+
+  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+      FROM_HERE,
+      base::BindOnce(&DlpDataTransferNotifier::CloseWidget,
+                     base::Unretained(this),
+                     widget_.get(),  // Safe as DlpClipboardNotificationHelper
+                                     // owns `widget_` and outlives it.
+                     views::Widget::ClosedReason::kUnspecified),
+      base::TimeDelta::FromMilliseconds(timeout_duration_ms));
+}
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.h b/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.h
new file mode 100644
index 0000000..49a5f430
--- /dev/null
+++ b/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.h
@@ -0,0 +1,62 @@
+// 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_CHROMEOS_POLICY_DLP_DLP_DATA_TRANSFER_NOTIFIER_H_
+#define CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_DATA_TRANSFER_NOTIFIER_H_
+
+#include "ui/gfx/geometry/size.h"
+#include "ui/views/widget/unique_widget_ptr.h"
+#include "ui/views/widget/widget.h"
+#include "ui/views/widget/widget_observer.h"
+
+namespace ui {
+class DataTransferEndpoint;
+}
+
+namespace policy {
+
+class DlpDataTransferNotifier : public views::WidgetObserver {
+ public:
+  DlpDataTransferNotifier();
+  ~DlpDataTransferNotifier() override;
+
+  DlpDataTransferNotifier(const DlpDataTransferNotifier&) = delete;
+  void operator=(const DlpDataTransferNotifier&) = delete;
+
+  // Notifies the user that the data transfer action is not allowed.
+  virtual void NotifyBlockedAction(
+      const ui::DataTransferEndpoint* const data_src,
+      const ui::DataTransferEndpoint* const data_dst) = 0;
+
+  // Warns the user that the data transfer action is not recommended.
+  virtual void WarnOnAction(const ui::DataTransferEndpoint* const data_src,
+                            const ui::DataTransferEndpoint* const data_dst) = 0;
+
+ protected:
+  virtual void ShowBlockBubble(const base::string16& text);
+
+  virtual void ShowWarningBubble(const base::string16& text,
+                                 base::RepeatingCallback<void()> proceed_cb);
+
+  void CloseWidget(views::Widget* widget, views::Widget::ClosedReason reason);
+
+  views::Widget* GetWidgetForTesting() { return widget_.get(); }
+
+  views::UniqueWidgetPtr widget_;
+
+ private:
+  // views::WidgetObserver
+  void OnWidgetClosing(views::Widget* widget) override;
+  void OnWidgetDestroyed(views::Widget* widget) override;
+  void OnWidgetActivationChanged(views::Widget* widget, bool active) override;
+
+  void InitWidget();
+
+  void ResizeAndShowWidget(const gfx::Size& bubble_size,
+                           int timeout_duration_ms);
+};
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_DATA_TRANSFER_NOTIFIER_H_
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.cc b/chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.cc
new file mode 100644
index 0000000..2e4badc
--- /dev/null
+++ b/chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.cc
@@ -0,0 +1,39 @@
+// 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/chromeos/policy/dlp/dlp_drag_drop_notifier.h"
+
+#include <memory>
+
+#include "base/notreached.h"
+#include "chrome/browser/chromeos/policy/dlp/clipboard_bubble.h"
+#include "chrome/browser/chromeos/policy/dlp/dlp_clipboard_bubble_constants.h"
+#include "components/strings/grit/components_strings.h"
+#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace policy {
+
+DlpDragDropNotifier::DlpDragDropNotifier() = default;
+DlpDragDropNotifier::~DlpDragDropNotifier() = default;
+
+void DlpDragDropNotifier::NotifyBlockedAction(
+    const ui::DataTransferEndpoint* const data_src,
+    const ui::DataTransferEndpoint* const data_dst) {
+  DCHECK(data_src);
+  DCHECK(data_src->origin());
+  const base::string16 host_name =
+      base::UTF8ToUTF16(data_src->origin()->host());
+
+  ShowBlockBubble(l10n_util::GetStringFUTF16(
+      IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_PASTE, host_name));
+}
+
+void DlpDragDropNotifier::WarnOnAction(
+    const ui::DataTransferEndpoint* const data_src,
+    const ui::DataTransferEndpoint* const data_dst) {
+  NOTREACHED();
+}
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.h b/chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.h
new file mode 100644
index 0000000..2694bb6
--- /dev/null
+++ b/chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.h
@@ -0,0 +1,30 @@
+// 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_CHROMEOS_POLICY_DLP_DLP_DRAG_DROP_NOTIFIER_H_
+#define CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_DRAG_DROP_NOTIFIER_H_
+
+#include "chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.h"
+
+namespace policy {
+
+class DlpDragDropNotifier : public DlpDataTransferNotifier {
+ public:
+  DlpDragDropNotifier();
+  ~DlpDragDropNotifier() override;
+
+  DlpDragDropNotifier(const DlpDragDropNotifier&) = delete;
+  void operator=(const DlpDragDropNotifier&) = delete;
+
+  // DlpDataTransferNotifier::
+  void NotifyBlockedAction(
+      const ui::DataTransferEndpoint* const data_src,
+      const ui::DataTransferEndpoint* const data_dst) override;
+  void WarnOnAction(const ui::DataTransferEndpoint* const data_src,
+                    const ui::DataTransferEndpoint* const data_dst) override;
+};
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_DRAG_DROP_NOTIFIER_H_
diff --git a/chrome/browser/chromeos/ui/idle_app_name_notification_view.cc b/chrome/browser/chromeos/ui/idle_app_name_notification_view.cc
index 0a0112e7..128ec51 100644
--- a/chrome/browser/chromeos/ui/idle_app_name_notification_view.cc
+++ b/chrome/browser/chromeos/ui/idle_app_name_notification_view.cc
@@ -30,6 +30,8 @@
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/fill_layout.h"
+#include "ui/views/metadata/metadata_header_macros.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
@@ -100,6 +102,7 @@
     : public views::WidgetDelegateView,
       public ui::ImplicitAnimationObserver {
  public:
+  METADATA_HEADER(IdleAppNameNotificationDelegateView);
   // An idle message which will get shown from the caller and hides itself after
   // a time, calling |owner->CloseMessage| to inform the owner that it got
   // destroyed. The |app_name| is a string which gets used as message and
@@ -128,6 +131,11 @@
         &IdleAppNameNotificationDelegateView::RemoveMessage);
   }
 
+  IdleAppNameNotificationDelegateView(
+      const IdleAppNameNotificationDelegateView&) = delete;
+  IdleAppNameNotificationDelegateView& operator=(
+      const IdleAppNameNotificationDelegateView&) = delete;
+
   ~IdleAppNameNotificationDelegateView() override {
     // The widget is already closing, but the other cleanup items need to be
     // performed.
@@ -206,8 +214,6 @@
 
   // True if the widget got already closed.
   bool widget_closed_;
-
-  DISALLOW_COPY_AND_ASSIGN(IdleAppNameNotificationDelegateView);
 };
 
 IdleAppNameNotificationView::IdleAppNameNotificationView(
@@ -266,4 +272,7 @@
   CreateAndShowWidget(view_, animation_time_ms);
 }
 
+BEGIN_METADATA(IdleAppNameNotificationDelegateView, views::WidgetDelegateView)
+END_METADATA
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/ui/kiosk_external_update_notification.cc b/chrome/browser/chromeos/ui/kiosk_external_update_notification.cc
index 289e16c..1d536bfe 100644
--- a/chrome/browser/chromeos/ui/kiosk_external_update_notification.cc
+++ b/chrome/browser/chromeos/ui/kiosk_external_update_notification.cc
@@ -16,6 +16,8 @@
 #include "ui/gfx/canvas.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/fill_layout.h"
+#include "ui/views/metadata/metadata_header_macros.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
@@ -34,6 +36,7 @@
 
 class KioskExternalUpdateNotificationView : public views::WidgetDelegateView {
  public:
+  METADATA_HEADER(KioskExternalUpdateNotificationView);
   explicit KioskExternalUpdateNotificationView(
       KioskExternalUpdateNotification* owner)
       : owner_(owner), widget_closed_(false) {
@@ -41,6 +44,11 @@
     SetLayoutManager(std::make_unique<views::FillLayout>());
   }
 
+  KioskExternalUpdateNotificationView(
+      const KioskExternalUpdateNotificationView&) = delete;
+  KioskExternalUpdateNotificationView& operator=(
+      const KioskExternalUpdateNotificationView&) = delete;
+
   ~KioskExternalUpdateNotificationView() override {
     widget_closed_ = true;
     InformOwnerForDismiss();
@@ -98,8 +106,6 @@
 
   // True if the widget got already closed.
   bool widget_closed_;
-
-  DISALLOW_COPY_AND_ASSIGN(KioskExternalUpdateNotificationView);
 };
 
 KioskExternalUpdateNotification::KioskExternalUpdateNotification(
@@ -154,4 +160,7 @@
   }
 }
 
+BEGIN_METADATA(KioskExternalUpdateNotificationView, views::WidgetDelegateView)
+END_METADATA
+
 }  // namespace chromeos
diff --git a/chrome/browser/continuous_search/BUILD.gn b/chrome/browser/continuous_search/BUILD.gn
index 720dccb..ada2d278 100644
--- a/chrome/browser/continuous_search/BUILD.gn
+++ b/chrome/browser/continuous_search/BUILD.gn
@@ -5,14 +5,44 @@
 import("//build/config/android/rules.gni")
 
 android_library("java") {
-  sources = [ "android/java/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelper.java" ]
+  sources = [
+    "android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListCoordinator.java",
+    "android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListMediator.java",
+    "android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListProperties.java",
+    "android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListViewBinder.java",
+    "android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelper.java",
+  ]
 
   deps = [
+    ":java_resources",
     "//base:base_java",
+    "//base:jni_java",
+    "//chrome/browser/browser_controls/android:java",
     "//chrome/browser/continuous_search/internal:java",
     "//chrome/browser/flags:java",
     "//chrome/browser/tab:java",
+    "//chrome/browser/ui/android/layouts:java",
+    "//components/browser_ui/widget/android:java",
+    "//components/embedder_support/android:util_java",
+    "//content/public/android:content_java",
+    "//services/network/public/mojom:mojom_java",
+    "//third_party/android_deps:androidx_annotation_annotation_java",
+    "//third_party/android_deps:androidx_coordinatorlayout_coordinatorlayout_java",
+    "//third_party/android_deps:androidx_recyclerview_recyclerview_java",
+    "//ui/android:ui_full_java",
+    "//url:gurl_java",
   ]
+  resources_package = "org.chromium.chrome.browser.continuous_search"
+}
+
+android_resources("java_resources") {
+  sources = [
+    "android/java/res/layout/continuous_search_list_ad.xml",
+    "android/java/res/layout/continuous_search_list_group_label.xml",
+    "android/java/res/layout/continuous_search_list_item.xml",
+  ]
+
+  deps = [ "//chrome/android:chrome_app_java_resources" ]
 }
 
 android_library("javatests") {
@@ -40,3 +70,26 @@
     "//url:gurl_java",
   ]
 }
+
+android_library("junit") {
+  bypass_platform_checks = true
+  testonly = true
+
+  sources = [ "android/junit/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListMediatorTest.java" ]
+
+  deps = [
+    ":java",
+    "//base:base_java",
+    "//base:base_java_test_support",
+    "//base:base_junit_test_support",
+    "//chrome/browser/continuous_search/internal:java",
+    "//chrome/browser/tab:java",
+    "//content/public/android:content_java",
+    "//third_party/android_deps:robolectric_all_java",
+    "//third_party/junit",
+    "//third_party/mockito:mockito_java",
+    "//ui/android:ui_no_recycler_view_java",
+    "//url:gurl_java",
+    "//url:gurl_junit_test_support",
+  ]
+}
diff --git a/chrome/browser/continuous_search/DEPS b/chrome/browser/continuous_search/DEPS
index 7792e79..11a4bf0 100644
--- a/chrome/browser/continuous_search/DEPS
+++ b/chrome/browser/continuous_search/DEPS
@@ -1,6 +1,5 @@
 include_rules = [
-  "+content/public/android/java/src/org/chromium/content_public/browser",
   "+components/continuous_search/common/public",
-  "+content/public/android/java/src/org/chromium/content_public/browser/LoadUrlParams.java",
-  "+content/public/android/java/src/org/chromium/content_public/browser/WebContents.java",
+  "+content/public/android/java/src/org/chromium/content_public/browser",
+  "+content/public/android/java/src/org/chromium/content_public/common",
 ]
diff --git a/chrome/browser/continuous_search/android/java/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelper.java b/chrome/browser/continuous_search/android/java/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelper.java
deleted file mode 100644
index 333497e..0000000
--- a/chrome/browser/continuous_search/android/java/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelper.java
+++ /dev/null
@@ -1,32 +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.
-
-package org.chromium.chrome.browser.continuous_search;
-
-import org.chromium.base.FeatureList;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.tab.Tab;
-
-/**
- * Bootstraps continuous search by creating appropriate observers and user data objects.
- */
-public class ContinuousSearchTabHelper {
-    private ContinuousSearchTabHelper() {}
-
-    /**
-     * Activates continuous search navigation support for a tab.
-     * @param tab to enable continuous search support for.
-     */
-    public static void createForTab(Tab tab) {
-        if (!FeatureList.isNativeInitialized()) return;
-
-        if (!tab.isIncognito()) new BackNavigationTabObserver(tab);
-
-        if (!ChromeFeatureList.isEnabled(ChromeFeatureList.CONTINUOUS_SEARCH)) return;
-
-        SearchResultUserData.createForTab(tab);
-        SearchResultListCoordinator.createForTab(tab);
-        new ContinuousSearchTabObserver(tab);
-    }
-}
diff --git a/chrome/browser/continuous_search/android/java/res/layout/continuous_search_list_ad.xml b/chrome/browser/continuous_search/android/java/res/layout/continuous_search_list_ad.xml
new file mode 100644
index 0000000..3333a3e
--- /dev/null
+++ b/chrome/browser/continuous_search/android/java/res/layout/continuous_search_list_ad.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright 2020 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal">
+
+    <TextView
+        android:layout_marginStart="5dp"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:gravity="center_vertical"
+        android:text="@string/csn_ad_label"
+        android:textAppearance="@style/TextAppearance.TextMedium.Disabled" />
+
+    <include layout="@layout/continuous_search_list_item"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/chrome/browser/continuous_search/android/java/res/layout/continuous_search_list_group_label.xml b/chrome/browser/continuous_search/android/java/res/layout/continuous_search_list_group_label.xml
new file mode 100644
index 0000000..d88b613
--- /dev/null
+++ b/chrome/browser/continuous_search/android/java/res/layout/continuous_search_list_group_label.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright 2020 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"
+    android:padding="5dp">
+
+    <TextView
+        android:id="@+id/continuous_search_list_item_text"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:gravity="center_vertical"
+        android:textAppearance="@style/TextAppearance.TextMedium.Secondary" />
+
+</FrameLayout>
\ No newline at end of file
diff --git a/chrome/browser/continuous_search/android/java/res/layout/continuous_search_list_item.xml b/chrome/browser/continuous_search/android/java/res/layout/continuous_search_list_item.xml
new file mode 100644
index 0000000..4ee664ff
--- /dev/null
+++ b/chrome/browser/continuous_search/android/java/res/layout/continuous_search_list_item.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright 2020 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:padding="5dp">
+
+    <TextView
+        android:id="@+id/continuous_search_list_item_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:ellipsize="end"
+        android:singleLine="true"
+        android:maxWidth="100dp"
+        android:textAppearance="@style/TextAppearance.TextMedium.Primary" />
+
+    <TextView
+        android:id="@+id/continuous_search_list_item_description"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:ellipsize="start"
+        android:singleLine="true"
+        android:maxWidth="100dp"
+        android:textAppearance="@style/TextAppearance.TextMedium.Secondary" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListCoordinator.java b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListCoordinator.java
new file mode 100644
index 0000000..521ed08
--- /dev/null
+++ b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListCoordinator.java
@@ -0,0 +1,79 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.continuous_search;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import org.chromium.base.Callback;
+import org.chromium.chrome.browser.continuous_search.ContinuousSearchListProperties.ListItemType;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
+import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter;
+
+/**
+ * Coordinator for Continuous Search Navigation UI: A RecyclerView that displays items provided
+ * by the CSN infrastructure.
+ */
+public class ContinuousSearchListCoordinator {
+    private final ContinuousSearchListMediator mListMediator;
+    private final SimpleRecyclerViewAdapter mRecyclerViewAdapter;
+
+    public ContinuousSearchListCoordinator(Callback<Boolean> setLayoutVisibility) {
+        ModelList listItems = new ModelList();
+        mRecyclerViewAdapter = new SimpleRecyclerViewAdapter(listItems);
+        mRecyclerViewAdapter.registerType(ListItemType.GROUP_LABEL,
+                (parent)
+                        -> inflateListItemView(parent, ListItemType.GROUP_LABEL),
+                ContinuousSearchListViewBinder::bind);
+        mRecyclerViewAdapter.registerType(ListItemType.SEARCH_RESULT,
+                (parent)
+                        -> inflateListItemView(parent, ListItemType.SEARCH_RESULT),
+                ContinuousSearchListViewBinder::bind);
+        mRecyclerViewAdapter.registerType(ListItemType.AD,
+                (parent)
+                        -> inflateListItemView(parent, ListItemType.AD),
+                ContinuousSearchListViewBinder::bind);
+
+        mListMediator = new ContinuousSearchListMediator(listItems, setLayoutVisibility);
+    }
+
+    private View inflateListItemView(ViewGroup parentView, @ListItemType int listItemType) {
+        int layoutId = R.layout.continuous_search_list_group_label;
+        switch (listItemType) {
+            case ListItemType.SEARCH_RESULT:
+                layoutId = R.layout.continuous_search_list_item;
+                break;
+            case ListItemType.AD:
+                layoutId = R.layout.continuous_search_list_ad;
+                break;
+        }
+
+        return LayoutInflater.from(parentView.getContext()).inflate(layoutId, parentView, false);
+    }
+
+    void initializeLayout(ViewGroup root) {
+        RecyclerView recyclerView = new RecyclerView(root.getContext());
+        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        root.addView(recyclerView, lp);
+        LinearLayoutManager layoutManager =
+                new LinearLayoutManager(root.getContext(), LinearLayoutManager.HORIZONTAL, false);
+        recyclerView.setLayoutManager(layoutManager);
+        recyclerView.setAdapter(mRecyclerViewAdapter);
+    }
+
+    void onObserverNewTab(Tab tab) {
+        mListMediator.onObserverNewTab(tab);
+    }
+
+    void destroy() {
+        mListMediator.destroy();
+    }
+}
diff --git a/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListMediator.java b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListMediator.java
new file mode 100644
index 0000000..b3d07f4
--- /dev/null
+++ b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListMediator.java
@@ -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.
+
+package org.chromium.chrome.browser.continuous_search;
+
+import org.chromium.base.Callback;
+import org.chromium.chrome.browser.continuous_search.ContinuousSearchListProperties.ListItemType;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.content_public.browser.LoadUrlParams;
+import org.chromium.content_public.common.Referrer;
+import org.chromium.network.mojom.ReferrerPolicy;
+import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
+import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
+import org.chromium.ui.modelutil.PropertyModel;
+import org.chromium.url.GURL;
+
+/**
+ * Business logic for the UI component of Continuous Search Navigation. This class updates the UI on
+ * search result updates.
+ */
+class ContinuousSearchListMediator implements SearchResultUserDataObserver {
+    private final ModelList mModelList;
+    private final Callback<Boolean> mSetLayoutVisibility;
+    private Tab mCurrentTab;
+    private SearchResultUserData mCurrentSearchUserData;
+
+    ContinuousSearchListMediator(ModelList modelList, Callback<Boolean> setLayoutVisibility) {
+        mModelList = modelList;
+        mSetLayoutVisibility = setLayoutVisibility;
+    }
+
+    private void handleResultClick(GURL url) {
+        if (url == null || mCurrentTab == null) return;
+
+        LoadUrlParams params = new LoadUrlParams(url.getSpec());
+        params.setReferrer(new Referrer("https://www.google.com", ReferrerPolicy.STRICT_ORIGIN));
+        mCurrentTab.loadUrl(params);
+    }
+
+    void onObserverNewTab(Tab tab) {
+        mSetLayoutVisibility.onResult(false);
+        if (mCurrentSearchUserData != null) {
+            mCurrentSearchUserData.removeObserver(this);
+        }
+        mCurrentSearchUserData = SearchResultUserData.getForTab(tab);
+        if (mCurrentSearchUserData != null) {
+            mCurrentSearchUserData.addObserver(this);
+        }
+        mCurrentTab = tab;
+    }
+
+    @Override
+    public void onInvalidate() {
+        mModelList.clear();
+        mSetLayoutVisibility.onResult(false);
+    }
+
+    @Override
+    public void onUpdate(SearchResultMetadata metadata, GURL currentUrl) {
+        mModelList.clear();
+
+        for (SearchResultGroup group : metadata.getGroups()) {
+            if (!group.isAdGroup()) {
+                mModelList.add(new ListItem(
+                        ListItemType.GROUP_LABEL, generateListItem(group.getLabel(), null)));
+            }
+            int itemType = group.isAdGroup() ? ListItemType.AD : ListItemType.SEARCH_RESULT;
+            for (SearchResult result : group.getResults()) {
+                mModelList.add(new ListItem(
+                        itemType, generateListItem(result.getTitle(), result.getUrl())));
+            }
+        }
+        mSetLayoutVisibility.onResult(mModelList.size() > 0);
+    }
+
+    @Override
+    public void onUrlChanged(GURL currentUrl) {
+        for (ListItem listItem : mModelList) {
+            if (listItem.type == ListItemType.GROUP_LABEL) continue;
+
+            boolean isSelected = currentUrl != null
+                    && currentUrl.equals(listItem.model.get(ContinuousSearchListProperties.URL));
+            listItem.model.set(ContinuousSearchListProperties.IS_SELECTED, isSelected);
+        }
+    }
+
+    private PropertyModel generateListItem(String text, GURL url) {
+        return new PropertyModel.Builder(ContinuousSearchListProperties.ALL_KEYS)
+                .with(ContinuousSearchListProperties.LABEL, text)
+                .with(ContinuousSearchListProperties.URL, url)
+                .with(ContinuousSearchListProperties.IS_SELECTED, false)
+                .with(ContinuousSearchListProperties.CLICK_LISTENER,
+                        (view) -> handleResultClick(url))
+                .build();
+    }
+
+    void destroy() {
+        if (mCurrentSearchUserData != null) mCurrentSearchUserData.removeObserver(this);
+    }
+}
diff --git a/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListProperties.java b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListProperties.java
new file mode 100644
index 0000000..3eb2f40a
--- /dev/null
+++ b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListProperties.java
@@ -0,0 +1,39 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.continuous_search;
+
+import android.view.View.OnClickListener;
+
+import androidx.annotation.IntDef;
+
+import org.chromium.ui.modelutil.PropertyKey;
+import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey;
+import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey;
+import org.chromium.url.GURL;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Contains model properties for a single search list item in Continuous Search Navigation.
+ */
+class ContinuousSearchListProperties {
+    @IntDef({ListItemType.GROUP_LABEL, ListItemType.SEARCH_RESULT, ListItemType.AD})
+    @Retention(RetentionPolicy.SOURCE)
+
+    public @interface ListItemType {
+        int GROUP_LABEL = 0;
+        int SEARCH_RESULT = 1;
+        int AD = 2;
+    }
+
+    public static final WritableObjectPropertyKey<String> LABEL = new WritableObjectPropertyKey<>();
+    public static final WritableObjectPropertyKey<GURL> URL = new WritableObjectPropertyKey<>();
+    public static final WritableBooleanPropertyKey IS_SELECTED = new WritableBooleanPropertyKey();
+    public static final WritableObjectPropertyKey<OnClickListener> CLICK_LISTENER =
+            new WritableObjectPropertyKey<>();
+
+    public static final PropertyKey[] ALL_KEYS = {LABEL, URL, IS_SELECTED, CLICK_LISTENER};
+}
diff --git a/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListViewBinder.java b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListViewBinder.java
new file mode 100644
index 0000000..62685c55
--- /dev/null
+++ b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListViewBinder.java
@@ -0,0 +1,37 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.continuous_search;
+
+import android.view.View;
+import android.widget.TextView;
+
+import org.chromium.components.embedder_support.util.UrlUtilities;
+import org.chromium.ui.modelutil.PropertyKey;
+import org.chromium.ui.modelutil.PropertyModel;
+import org.chromium.url.GURL;
+
+/**
+ * Responsible for binding the {@link PropertyModel} for a search result item to a View.
+ */
+class ContinuousSearchListViewBinder {
+    public static void bind(PropertyModel model, View view, PropertyKey propertyKey) {
+        if (ContinuousSearchListProperties.LABEL == propertyKey) {
+            TextView textView = view.findViewById(R.id.continuous_search_list_item_text);
+            textView.setText(model.get(ContinuousSearchListProperties.LABEL));
+        } else if (ContinuousSearchListProperties.URL == propertyKey) {
+            GURL url = model.get(ContinuousSearchListProperties.URL);
+            TextView textView = view.findViewById(R.id.continuous_search_list_item_description);
+            String domain = "";
+            if (url != null) {
+                domain = UrlUtilities.getDomainAndRegistry(url.getSpec(), true);
+            }
+            textView.setText(domain);
+        } else if (ContinuousSearchListProperties.IS_SELECTED == propertyKey) {
+            view.setSelected(model.get(ContinuousSearchListProperties.IS_SELECTED));
+        } else if (ContinuousSearchListProperties.CLICK_LISTENER == propertyKey) {
+            view.setOnClickListener(model.get(ContinuousSearchListProperties.CLICK_LISTENER));
+        }
+    }
+}
diff --git a/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelper.java b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelper.java
new file mode 100644
index 0000000..cfc05f9a
--- /dev/null
+++ b/chrome/browser/continuous_search/android/java/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelper.java
@@ -0,0 +1,31 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.continuous_search;
+
+import org.chromium.base.FeatureList;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.tab.Tab;
+
+/**
+ * Bootstraps continuous search by creating appropriate observers and user data objects.
+ */
+public class ContinuousSearchTabHelper {
+    private ContinuousSearchTabHelper() {}
+
+    /**
+     * Activates continuous search navigation support for a tab.
+     * @param tab to enable continuous search support for.
+     */
+    public static void createForTab(Tab tab) {
+        if (!FeatureList.isNativeInitialized()) return;
+
+        if (!tab.isIncognito()) new BackNavigationTabObserver(tab);
+
+        if (!ChromeFeatureList.isEnabled(ChromeFeatureList.CONTINUOUS_SEARCH)) return;
+
+        SearchResultUserData.createForTab(tab);
+        new ContinuousSearchTabObserver(tab);
+    }
+}
diff --git a/chrome/browser/continuous_search/android/javatests/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelperTest.java b/chrome/browser/continuous_search/android/javatests/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelperTest.java
index a6bde01..4f44afaf 100644
--- a/chrome/browser/continuous_search/android/javatests/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelperTest.java
+++ b/chrome/browser/continuous_search/android/javatests/org/chromium/chrome/browser/continuous_search/ContinuousSearchTabHelperTest.java
@@ -80,7 +80,7 @@
             new Handler().postDelayed(() -> {
                 mListener.onResult(new SearchResultMetadata(
                         mSearchUrl, mQuery, 0, new ArrayList<SearchResultGroup>()));
-            }, 100);
+            }, 250);
         }
 
         @Override
@@ -218,7 +218,9 @@
         loadUrl(tab,
                 new LoadUrlParams(
                         mServer.getURLWithHostName("www.google.com", TEST_URL + "?q=cat+dog")));
-        observer.mOnUpdateCallbackHelper.waitForFirst(5000, TimeUnit.MILLISECONDS);
+        observer.mOnUpdateCallbackHelper.waitForFirst(
+                "Timed out waiting for SearchResultUserDataObserver#onUpdate", 5000,
+                TimeUnit.MILLISECONDS);
 
         // Check the retuned data.
         Assert.assertEquals("cat dog", observer.mMetadata.getQuery());
@@ -232,6 +234,8 @@
 
         // Invalidate the data.
         loadUrl(tab, new LoadUrlParams(UrlConstants.ABOUT_URL));
-        observer.mInvalidateCallbackHelper.waitForFirst(5000, TimeUnit.MILLISECONDS);
+        observer.mInvalidateCallbackHelper.waitForFirst(
+                "Timed out waiting for SearchResultUserDataObserver#onError", 5000,
+                TimeUnit.MILLISECONDS);
     }
 }
diff --git a/chrome/browser/continuous_search/android/junit/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListMediatorTest.java b/chrome/browser/continuous_search/android/junit/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListMediatorTest.java
new file mode 100644
index 0000000..abe8aaf
--- /dev/null
+++ b/chrome/browser/continuous_search/android/junit/src/org/chromium/chrome/browser/continuous_search/ContinuousSearchListMediatorTest.java
@@ -0,0 +1,159 @@
+// 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.continuous_search;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.chrome.browser.continuous_search.ContinuousSearchListProperties.ListItemType;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.ui.modelutil.MVCListAdapter;
+import org.chromium.url.GURL;
+
+import java.util.Arrays;
+
+/**
+ * Tests for {@link ContinuousSearchListMediator}.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+public class ContinuousSearchListMediatorTest {
+    private ContinuousSearchListMediator mMediator;
+    private MVCListAdapter.ModelList mModelList;
+    private CallbackHelper mLayoutVisibilityTrue;
+    private CallbackHelper mLayoutVisibilityFalse;
+
+    @Before
+    public void setUp() {
+        mModelList = new MVCListAdapter.ModelList();
+        mLayoutVisibilityTrue = new CallbackHelper();
+        mLayoutVisibilityFalse = new CallbackHelper();
+        mMediator = new ContinuousSearchListMediator(mModelList, (visibility) -> {
+            if (visibility) {
+                mLayoutVisibilityTrue.notifyCalled();
+            } else {
+                mLayoutVisibilityFalse.notifyCalled();
+            }
+        });
+        SearchResultUserData searchResultUserData = Mockito.mock(SearchResultUserData.class);
+        SearchResultUserData.setInstanceForTesting(searchResultUserData);
+    }
+
+    @After
+    public void tearDown() {
+        SearchResultUserData.setInstanceForTesting(null);
+    }
+
+    /**
+     * Tests the show/hide logic for the CNS.
+     */
+    @Test
+    public void testVisibility() {
+        Assert.assertEquals("mLayoutVisibilityTrue should not have been called.", 0,
+                mLayoutVisibilityTrue.getCallCount());
+        Assert.assertEquals("mLayoutVisibilityFalse should not have been called.", 0,
+                mLayoutVisibilityFalse.getCallCount());
+
+        // UI should hide on observing a new tab.
+        mMediator.onObserverNewTab(Mockito.mock(Tab.class));
+        Assert.assertEquals("mLayoutVisibilityTrue should not have been called.", 0,
+                mLayoutVisibilityTrue.getCallCount());
+        Assert.assertEquals("mLayoutVisibilityFalse should have been called.", 1,
+                mLayoutVisibilityFalse.getCallCount());
+
+        // UI should hide on invalidate.
+        mMediator.onInvalidate();
+        Assert.assertEquals("mLayoutVisibilityTrue should not have been called.", 0,
+                mLayoutVisibilityTrue.getCallCount());
+        Assert.assertEquals("mLayoutVisibilityFalse should have been called.", 2,
+                mLayoutVisibilityFalse.getCallCount());
+
+        // 1 result available. UI should be shown.
+        SearchResult searchResult = new SearchResult(Mockito.mock(GURL.class), "result 1");
+        SearchResultGroup searchResultGroup =
+                new SearchResultGroup("result", false, Arrays.asList(searchResult));
+        SearchResultMetadata searchResultMetadata = new SearchResultMetadata(
+                Mockito.mock(GURL.class), "query", 1, Arrays.asList(searchResultGroup));
+        mMediator.onUpdate(searchResultMetadata, Mockito.mock(GURL.class));
+        Assert.assertEquals("mLayoutVisibilityTrue should have been called.", 1,
+                mLayoutVisibilityTrue.getCallCount());
+        Assert.assertEquals("mLayoutVisibilityFalse should not have been called.", 2,
+                mLayoutVisibilityFalse.getCallCount());
+
+        // 0 results available. UI should be hidden.
+        searchResultMetadata =
+                new SearchResultMetadata(Mockito.mock(GURL.class), "query", 1, Arrays.asList());
+        mMediator.onUpdate(searchResultMetadata, Mockito.mock(GURL.class));
+        Assert.assertEquals("mLayoutVisibilityTrue should not have been called.", 1,
+                mLayoutVisibilityTrue.getCallCount());
+        Assert.assertEquals("mLayoutVisibilityFalse should have been called.", 3,
+                mLayoutVisibilityFalse.getCallCount());
+    }
+
+    /**
+     * Tests that the ModelList is correctly populated on updates from {@link SearchResultUserData}.
+     */
+    @Test
+    public void testModelList() {
+        // Mock 3 SearchResultGroups, with 1, 2 and 3 SearchResults. The first group is an ad group.
+        SearchResult searchResult11 = new SearchResult(Mockito.mock(GURL.class), "result 11");
+        SearchResult searchResult21 = new SearchResult(Mockito.mock(GURL.class), "result 21");
+        SearchResult searchResult22 = new SearchResult(Mockito.mock(GURL.class), "result 22");
+        SearchResult searchResult31 = new SearchResult(Mockito.mock(GURL.class), "result 31");
+        SearchResult searchResult32 = new SearchResult(Mockito.mock(GURL.class), "result 32");
+        SearchResult searchResult33 = new SearchResult(Mockito.mock(GURL.class), "result 33");
+
+        SearchResultGroup searchResultGroup1 =
+                new SearchResultGroup("group1", true, Arrays.asList(searchResult11));
+        SearchResultGroup searchResultGroup2 = new SearchResultGroup(
+                "group2", false, Arrays.asList(searchResult21, searchResult22));
+        SearchResultGroup searchResultGroup3 = new SearchResultGroup(
+                "group3", false, Arrays.asList(searchResult31, searchResult32, searchResult33));
+
+        SearchResultMetadata searchResultMetadata =
+                new SearchResultMetadata(Mockito.mock(GURL.class), "query", 1,
+                        Arrays.asList(searchResultGroup1, searchResultGroup2, searchResultGroup3));
+        mMediator.onUpdate(searchResultMetadata, Mockito.mock(GURL.class));
+
+        // Each non-ad SearchResultGroup will add a group label as an item. So in total we should
+        // have 8 items in the model list.
+        Assert.assertEquals("ModelList length is incorrect.", 8, mModelList.size());
+
+        // Assert the list items for group labels are correctly populated.
+        Assert.assertEquals("List item type should be GROUP_LABEL.", ListItemType.GROUP_LABEL,
+                mModelList.get(1).type);
+        Assert.assertEquals("List item type should be GROUP_LABEL.", ListItemType.GROUP_LABEL,
+                mModelList.get(4).type);
+        Assert.assertEquals("List item label doesn't match SearchResultGroup.",
+                searchResultGroup2.getLabel(),
+                mModelList.get(1).model.get(ContinuousSearchListProperties.LABEL));
+        Assert.assertEquals("List item label doesn't match SearchResultGroup.",
+                searchResultGroup3.getLabel(),
+                mModelList.get(4).model.get(ContinuousSearchListProperties.LABEL));
+
+        // Assert the list items for search results are correctly populated.
+        assertListItemEqualsSearchResult(mModelList.get(0), searchResult11, true);
+        assertListItemEqualsSearchResult(mModelList.get(2), searchResult21, false);
+        assertListItemEqualsSearchResult(mModelList.get(3), searchResult22, false);
+        assertListItemEqualsSearchResult(mModelList.get(5), searchResult31, false);
+        assertListItemEqualsSearchResult(mModelList.get(6), searchResult32, false);
+        assertListItemEqualsSearchResult(mModelList.get(7), searchResult33, false);
+    }
+
+    private void assertListItemEqualsSearchResult(
+            MVCListAdapter.ListItem listItem, SearchResult searchResult, boolean isAdGroup) {
+        Assert.assertEquals("List item type doesn't match SearchResult.",
+                isAdGroup ? ListItemType.AD : ListItemType.SEARCH_RESULT, listItem.type);
+        Assert.assertEquals("List item title doesn't match SearchResult.", searchResult.getTitle(),
+                listItem.model.get(ContinuousSearchListProperties.LABEL));
+        Assert.assertEquals("List item URL doesn't match SearchResult.", searchResult.getUrl(),
+                listItem.model.get(ContinuousSearchListProperties.URL));
+    }
+}
\ No newline at end of file
diff --git a/chrome/browser/continuous_search/internal/BUILD.gn b/chrome/browser/continuous_search/internal/BUILD.gn
index 06135b1b..9af3e00 100644
--- a/chrome/browser/continuous_search/internal/BUILD.gn
+++ b/chrome/browser/continuous_search/internal/BUILD.gn
@@ -24,10 +24,6 @@
     "android/java/src/org/chromium/chrome/browser/continuous_search/SearchResult.java",
     "android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultExtractorProducer.java",
     "android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultGroup.java",
-    "android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListCoordinator.java",
-    "android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListMediator.java",
-    "android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListProperties.java",
-    "android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListViewBinder.java",
     "android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListener.java",
     "android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultMetadata.java",
     "android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultProducer.java",
@@ -43,19 +39,15 @@
   ]
 
   deps = [
-    ":java_resources",
     "//base:base_java",
     "//base:jni_java",
     "//chrome/browser/tab:java",
     "//chrome/browser/tabmodel:java",
     "//content/public/android:content_java",
     "//third_party/android_deps:androidx_annotation_annotation_java",
-    "//third_party/android_deps:androidx_recyclerview_recyclerview_java",
-    "//ui/android:ui_full_java",
+    "//ui/android:ui_no_recycler_view_java",
     "//url:gurl_java",
   ]
-
-  resources_package = "org.chromium.chrome.browser.continuous_search"
 }
 
 android_library("junit") {
@@ -82,16 +74,6 @@
   ]
 }
 
-android_resources("java_resources") {
-  sources = [
-    "android/java/res/layout/continuous_search_list_ad.xml",
-    "android/java/res/layout/continuous_search_list_group_label.xml",
-    "android/java/res/layout/continuous_search_list_result.xml",
-  ]
-
-  deps = [ "//chrome/android:chrome_app_java_resources" ]
-}
-
 source_set("internal") {
   sources = [
     "search_result_category.h",
diff --git a/chrome/browser/continuous_search/internal/android/java/res/layout/continuous_search_list_ad.xml b/chrome/browser/continuous_search/internal/android/java/res/layout/continuous_search_list_ad.xml
deleted file mode 100644
index ee9e9784..0000000
--- a/chrome/browser/continuous_search/internal/android/java/res/layout/continuous_search_list_ad.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!-- Copyright 2020 The Chromium Authors. All rights reserved.
-     Use of this source code is governed by a BSD-style license that can be
-     found in the LICENSE file. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="horizontal"
-    android:padding="5dp">
-
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:text="@string/csn_ad_label"
-        android:textAppearance="@style/TextAppearance.TextMedium.Disabled" />
-
-    <TextView
-        android:id="@+id/continuous_search_list_item_text"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:textAppearance="@style/TextAppearance.TextMedium.Primary" />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/chrome/browser/continuous_search/internal/android/java/res/layout/continuous_search_list_group_label.xml b/chrome/browser/continuous_search/internal/android/java/res/layout/continuous_search_list_group_label.xml
deleted file mode 100644
index b5cddca..0000000
--- a/chrome/browser/continuous_search/internal/android/java/res/layout/continuous_search_list_group_label.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!-- Copyright 2020 The Chromium Authors. All rights reserved.
-     Use of this source code is governed by a BSD-style license that can be
-     found in the LICENSE file. -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:padding="5dp">
-
-    <TextView
-        android:id="@+id/continuous_search_list_item_text"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:textAppearance="@style/TextAppearance.TextMedium.Secondary" />
-
-</FrameLayout>
\ No newline at end of file
diff --git a/chrome/browser/continuous_search/internal/android/java/res/layout/continuous_search_list_result.xml b/chrome/browser/continuous_search/internal/android/java/res/layout/continuous_search_list_result.xml
deleted file mode 100644
index 22d0f25..0000000
--- a/chrome/browser/continuous_search/internal/android/java/res/layout/continuous_search_list_result.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!-- Copyright 2020 The Chromium Authors. All rights reserved.
-     Use of this source code is governed by a BSD-style license that can be
-     found in the LICENSE file. -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:padding="5dp">
-
-    <TextView
-        android:id="@+id/continuous_search_list_item_text"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:textAppearance="@style/TextAppearance.TextMedium.Primary" />
-
-</FrameLayout>
\ No newline at end of file
diff --git a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/BackNavigationTabObserver.java b/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/BackNavigationTabObserver.java
index 12a8e59e..89a08eb 100644
--- a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/BackNavigationTabObserver.java
+++ b/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/BackNavigationTabObserver.java
@@ -19,14 +19,14 @@
  * A tab observer to record the number of back navigations to SRP
  */
 public class BackNavigationTabObserver extends EmptyTabObserver {
-    private GURL mLastSrpUrl;
     private GURL mLastVisitedUrl;
+    private String mLastSrpUrlQuery;
     private int mBackNavigationCount;
 
     public BackNavigationTabObserver(Tab tab) {
         tab.addObserver(this);
-        mLastSrpUrl = null;
         mLastVisitedUrl = null;
+        mLastSrpUrlQuery = null;
         mBackNavigationCount = 0;
     }
 
@@ -43,14 +43,15 @@
         if (history.getEntryCount() == 0) return;
 
         NavigationEntry entry = history.getEntryAtIndex(history.getCurrentEntryIndex());
-        if (SearchUrlHelper.isSrpUrl(entry.getUrl())) {
-            if (entry.getUrl().equals(mLastSrpUrl)) {
+        String query = SearchUrlHelper.getQueryIfValidSrpUrl(entry.getUrl());
+        if (query != null) {
+            if (query.equals(mLastSrpUrlQuery)) {
                 // Treat re-navigation to the last seen SRP as a back navigation.
                 mBackNavigationCount++;
             } else {
                 // Encountered a new SRP session. Record the previous session and start a new one.
                 recordMetricAndClearCache();
-                mLastSrpUrl = entry.getUrl();
+                mLastSrpUrlQuery = query;
             }
             // A page opened through SRP has google.com as its referrer URL. Treat other cases as
             // navigating away from the SRP session.
@@ -86,11 +87,11 @@
     }
 
     private void recordMetricAndClearCache() {
-        if (mLastSrpUrl != null) {
+        if (mLastSrpUrlQuery != null) {
             RecordHistogram.recordCount100Histogram(
                     "Browser.ContinuousSearch.BackNavigationToSrp", mBackNavigationCount);
         }
-        mLastSrpUrl = null;
+        mLastSrpUrlQuery = null;
         mBackNavigationCount = 0;
     }
 }
diff --git a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListCoordinator.java b/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListCoordinator.java
deleted file mode 100644
index d82deaa..0000000
--- a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListCoordinator.java
+++ /dev/null
@@ -1,89 +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.
-
-package org.chromium.chrome.browser.continuous_search;
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.recyclerview.widget.RecyclerView;
-
-import org.chromium.base.UserData;
-import org.chromium.chrome.browser.continuous_search.SearchResultListProperties.ListItemType;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.content_public.browser.LoadUrlParams;
-import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
-import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter;
-
-/**
- * Entry point for the UI component of Continuous Search Navigation.
- */
-public class SearchResultListCoordinator implements UserData {
-    private static final Class<SearchResultListCoordinator> USER_DATA_KEY =
-            SearchResultListCoordinator.class;
-
-    private Tab mTab;
-    private SearchResultUserData mSearchResultUserData;
-    private SearchResultListMediator mMediator;
-    private RecyclerView mView;
-
-    static void createForTab(Tab tab) {
-        assert tab.getUserDataHost().getUserData(USER_DATA_KEY) == null;
-        tab.getUserDataHost().setUserData(USER_DATA_KEY, new SearchResultListCoordinator(tab));
-    }
-
-    static SearchResultListCoordinator getForTab(Tab tab) {
-        return tab.getUserDataHost().getUserData(USER_DATA_KEY);
-    }
-
-    private SearchResultListCoordinator(Tab tab) {
-        mTab = tab;
-        mView = new RecyclerView(mTab.getContext());
-        ModelList listItems = new ModelList();
-
-        SimpleRecyclerViewAdapter adapter = new SimpleRecyclerViewAdapter(listItems);
-        adapter.registerType(ListItemType.GROUP_LABEL,
-                (parent)
-                        -> inflateItemView(parent, ListItemType.GROUP_LABEL),
-                SearchResultListViewBinder::bind);
-        adapter.registerType(ListItemType.SEARCH_RESULT,
-                (parent)
-                        -> inflateItemView(parent, ListItemType.SEARCH_RESULT),
-                SearchResultListViewBinder::bind);
-        adapter.registerType(ListItemType.AD,
-                (parent)
-                        -> inflateItemView(parent, ListItemType.AD),
-                SearchResultListViewBinder::bind);
-
-        mView.setAdapter(adapter);
-        mMediator = new SearchResultListMediator(
-                listItems, (url) -> tab.loadUrl(new LoadUrlParams(url.getSpec())));
-        mSearchResultUserData = SearchResultUserData.getForTab(mTab);
-        mSearchResultUserData.addObserver(mMediator);
-    }
-
-    private View inflateItemView(ViewGroup parentView, @ListItemType int listItemType) {
-        int layoutId = R.layout.continuous_search_list_group_label;
-        switch (listItemType) {
-            case ListItemType.SEARCH_RESULT:
-                layoutId = R.layout.continuous_search_list_result;
-                break;
-            case ListItemType.AD:
-                layoutId = R.layout.continuous_search_list_ad;
-                break;
-        }
-
-        return LayoutInflater.from(parentView.getContext()).inflate(layoutId, parentView, false);
-    }
-
-    public View getView() {
-        return mView;
-    }
-
-    @Override
-    public void destroy() {
-        mSearchResultUserData.removeObserver(mMediator);
-    }
-}
diff --git a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListMediator.java b/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListMediator.java
deleted file mode 100644
index 4cfb318..0000000
--- a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListMediator.java
+++ /dev/null
@@ -1,74 +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.
-
-package org.chromium.chrome.browser.continuous_search;
-
-import org.chromium.base.Callback;
-import org.chromium.chrome.browser.continuous_search.SearchResultListProperties.ListItemType;
-import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
-import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
-import org.chromium.ui.modelutil.ModelListAdapter;
-import org.chromium.ui.modelutil.PropertyModel;
-import org.chromium.url.GURL;
-
-/**
- * Business logic for the UI component of Continuous Search Navigation. This class updates the UI on
- * search result updates.
- */
-public class SearchResultListMediator implements SearchResultUserDataObserver {
-    private ModelList mModelList;
-    private Callback<GURL> mUrlClickHandler;
-
-    SearchResultListMediator(ModelList modelList, Callback<GURL> urlClickHandler) {
-        mModelList = modelList;
-        mUrlClickHandler = urlClickHandler;
-    }
-
-    private void handleResultClick(GURL url) {
-        if (url == null || mUrlClickHandler == null) return;
-
-        mUrlClickHandler.onResult(url);
-    }
-
-    @Override
-    public void onInvalidate() {
-        mModelList.clear();
-    }
-
-    @Override
-    public void onUpdate(SearchResultMetadata metadata, GURL currentUrl) {
-        mModelList.clear();
-        for (SearchResultGroup group : metadata.getGroups()) {
-            if (!group.isAdGroup()) {
-                mModelList.add(new ModelListAdapter.ListItem(
-                        ListItemType.GROUP_LABEL, generateListItem(group.getLabel(), null)));
-            }
-            int itemType = group.isAdGroup() ? ListItemType.AD : ListItemType.SEARCH_RESULT;
-            for (SearchResult result : group.getResults()) {
-                mModelList.add(new ListItem(
-                        itemType, generateListItem(result.getTitle(), result.getUrl())));
-            }
-        }
-    }
-
-    @Override
-    public void onUrlChanged(GURL currentUrl) {
-        for (ListItem listItem : mModelList) {
-            if (listItem.type == ListItemType.GROUP_LABEL) continue;
-
-            boolean isSelected = currentUrl != null
-                    && currentUrl.equals(listItem.model.get(SearchResultListProperties.URL));
-            listItem.model.set(SearchResultListProperties.IS_SELECTED, isSelected);
-        }
-    }
-
-    private PropertyModel generateListItem(String text, GURL url) {
-        return new PropertyModel.Builder(SearchResultListProperties.ALL_KEYS)
-                .with(SearchResultListProperties.LABEL, text)
-                .with(SearchResultListProperties.URL, url)
-                .with(SearchResultListProperties.IS_SELECTED, false)
-                .with(SearchResultListProperties.CLICK_LISTENER, (view) -> handleResultClick(url))
-                .build();
-    }
-}
diff --git a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListProperties.java b/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListProperties.java
deleted file mode 100644
index 875e233b..0000000
--- a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListProperties.java
+++ /dev/null
@@ -1,39 +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.
-
-package org.chromium.chrome.browser.continuous_search;
-
-import android.view.View.OnClickListener;
-
-import androidx.annotation.IntDef;
-
-import org.chromium.ui.modelutil.PropertyKey;
-import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey;
-import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey;
-import org.chromium.url.GURL;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Contains model properties for the UI component of Continuous Search Navigation.
- */
-public class SearchResultListProperties {
-    @IntDef({ListItemType.GROUP_LABEL, ListItemType.SEARCH_RESULT, ListItemType.AD})
-    @Retention(RetentionPolicy.SOURCE)
-
-    public @interface ListItemType {
-        int GROUP_LABEL = 0;
-        int SEARCH_RESULT = 1;
-        int AD = 2;
-    }
-
-    public static final WritableObjectPropertyKey<String> LABEL = new WritableObjectPropertyKey<>();
-    public static final WritableObjectPropertyKey<GURL> URL = new WritableObjectPropertyKey<>();
-    public static final WritableBooleanPropertyKey IS_SELECTED = new WritableBooleanPropertyKey();
-    public static final WritableObjectPropertyKey<OnClickListener> CLICK_LISTENER =
-            new WritableObjectPropertyKey<>();
-
-    public static final PropertyKey[] ALL_KEYS = {LABEL, URL, IS_SELECTED, CLICK_LISTENER};
-}
diff --git a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListViewBinder.java b/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListViewBinder.java
deleted file mode 100644
index 7945802..0000000
--- a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultListViewBinder.java
+++ /dev/null
@@ -1,27 +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.
-
-package org.chromium.chrome.browser.continuous_search;
-
-import android.view.View;
-import android.widget.TextView;
-
-import org.chromium.ui.modelutil.PropertyKey;
-import org.chromium.ui.modelutil.PropertyModel;
-
-/**
- * Responsible for binding the {@link PropertyModel} for a search result item to a View.
- */
-public class SearchResultListViewBinder {
-    public static void bind(PropertyModel model, View view, PropertyKey propertyKey) {
-        if (SearchResultListProperties.LABEL == propertyKey) {
-            TextView textView = (TextView) view.findViewById(R.id.continuous_search_list_item_text);
-            textView.setText(model.get(SearchResultListProperties.LABEL));
-        } else if (SearchResultListProperties.IS_SELECTED == propertyKey) {
-            view.setSelected(model.get(SearchResultListProperties.IS_SELECTED));
-        } else if (SearchResultListProperties.CLICK_LISTENER == propertyKey) {
-            view.setOnClickListener(model.get(SearchResultListProperties.CLICK_LISTENER));
-        }
-    }
-}
diff --git a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultUserData.java b/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultUserData.java
index ccd1663..333c322 100644
--- a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultUserData.java
+++ b/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultUserData.java
@@ -4,6 +4,8 @@
 
 package org.chromium.chrome.browser.continuous_search;
 
+import androidx.annotation.VisibleForTesting;
+
 import org.chromium.base.UserData;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.url.GURL;
@@ -24,12 +26,16 @@
     private GURL mCurrentUrl;
     private int mCurrentPosition = INVALID_POSITION;
 
+    private static SearchResultUserData sInstanceForTesting;
+
     static void createForTab(Tab tab) {
         assert tab.getUserDataHost().getUserData(USER_DATA_KEY) == null;
         tab.getUserDataHost().setUserData(USER_DATA_KEY, new SearchResultUserData());
     }
 
     static SearchResultUserData getForTab(Tab tab) {
+        if (sInstanceForTesting != null) return sInstanceForTesting;
+
         assert tab.getUserDataHost().getUserData(USER_DATA_KEY) != null;
         return tab.getUserDataHost().getUserData(USER_DATA_KEY);
     }
@@ -106,4 +112,9 @@
             observer.onUrlChanged(url);
         }
     }
+
+    @VisibleForTesting
+    static void setInstanceForTesting(SearchResultUserData instance) {
+        sInstanceForTesting = instance;
+    }
 }
diff --git a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchUrlHelper.java b/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchUrlHelper.java
index 315c560..113b677 100644
--- a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchUrlHelper.java
+++ b/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchUrlHelper.java
@@ -27,15 +27,6 @@
     }
 
     /**
-     * Checks whether the provided url represents a valid Google search url.
-     * @param url the url to check.
-     * @return true if the url satisfies the criteria.
-     */
-    public static boolean isSrpUrl(GURL url) {
-        return SearchUrlHelperJni.get().isSrpUrl(url);
-    }
-
-    /**
      * Gets the query of the provided url if it is a SRP URL and shows the "All" or "News" tab
      * results.
      * @param url The url to try to extract the query from.
@@ -48,7 +39,6 @@
     @NativeMethods
     interface Natives {
         boolean isGoogleDomainUrl(GURL url);
-        boolean isSrpUrl(GURL url);
         String getQueryIfValidSrpUrl(GURL url);
     }
 }
diff --git a/chrome/browser/continuous_search/internal/android/junit/org/chromium/chrome/browser/continuous_search/BackNavigationTabObserverTest.java b/chrome/browser/continuous_search/internal/android/junit/org/chromium/chrome/browser/continuous_search/BackNavigationTabObserverTest.java
index ee25149..8338ff1a 100644
--- a/chrome/browser/continuous_search/internal/android/junit/org/chromium/chrome/browser/continuous_search/BackNavigationTabObserverTest.java
+++ b/chrome/browser/continuous_search/internal/android/junit/org/chromium/chrome/browser/continuous_search/BackNavigationTabObserverTest.java
@@ -65,19 +65,19 @@
         when(webContents.getNavigationController()).thenReturn(mNavigationController);
 
         GURL searchUrl = JUnitTestGURLs.getGURL(JUnitTestGURLs.SEARCH_URL);
-        doReturn(true).when(mSearchUrlHelperJniMock).isSrpUrl(eq(searchUrl));
-        doReturn(true)
+        doReturn("test").when(mSearchUrlHelperJniMock).getQueryIfValidSrpUrl(eq(searchUrl));
+        doReturn("query")
                 .when(mSearchUrlHelperJniMock)
-                .isSrpUrl(eq(JUnitTestGURLs.getGURL(JUnitTestGURLs.SEARCH_2_URL)));
-        doReturn(false)
+                .getQueryIfValidSrpUrl(eq(JUnitTestGURLs.getGURL(JUnitTestGURLs.SEARCH_2_URL)));
+        doReturn(null)
                 .when(mSearchUrlHelperJniMock)
-                .isSrpUrl(eq(JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL)));
-        doReturn(false)
+                .getQueryIfValidSrpUrl(eq(JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL)));
+        doReturn(null)
                 .when(mSearchUrlHelperJniMock)
-                .isSrpUrl(eq(JUnitTestGURLs.getGURL(JUnitTestGURLs.RED_1)));
-        doReturn(false)
+                .getQueryIfValidSrpUrl(eq(JUnitTestGURLs.getGURL(JUnitTestGURLs.RED_1)));
+        doReturn(null)
                 .when(mSearchUrlHelperJniMock)
-                .isSrpUrl(eq(JUnitTestGURLs.getGURL(JUnitTestGURLs.BLUE_1)));
+                .getQueryIfValidSrpUrl(eq(JUnitTestGURLs.getGURL(JUnitTestGURLs.BLUE_1)));
         doReturn(true).when(mSearchUrlHelperJniMock).isGoogleDomainUrl(eq(searchUrl));
         doReturn(false).when(mSearchUrlHelperJniMock).isGoogleDomainUrl(eq(GURL.emptyGURL()));
     }
diff --git a/chrome/browser/continuous_search/internal/search_url_helper.cc b/chrome/browser/continuous_search/internal/search_url_helper.cc
index 1fdf34a..a6bd4f0e 100644
--- a/chrome/browser/continuous_search/internal/search_url_helper.cc
+++ b/chrome/browser/continuous_search/internal/search_url_helper.cc
@@ -30,15 +30,6 @@
                                      google_util::DISALLOW_NON_STANDARD_PORTS));
 }
 
-jboolean JNI_SearchUrlHelper_IsSrpUrl(
-    JNIEnv* env,
-    const base::android::JavaParamRef<jobject>& j_gurl) {
-  std::unique_ptr<GURL> url = url::GURLAndroid::ToNativeGURL(env, j_gurl);
-  if (!url->is_valid())
-    return false;
-  return static_cast<jboolean>(google_util::IsGoogleSearchUrl(*url));
-}
-
 base::android::ScopedJavaLocalRef<jstring>
 JNI_SearchUrlHelper_GetQueryIfValidSrpUrl(
     JNIEnv* env,
diff --git a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
index d3402db..60917620 100644
--- a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
+++ b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
@@ -97,6 +97,11 @@
   DCHECK(!g_instance);
   g_instance = this;
 
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
+  // Only create and hold keep alive for automation test for non ChromeOS.
+  // ChromeOS automation test (aka tast) manages chrome instance via session
+  // manager daemon. The extra keep alive is not needed and makes ChromeOS
+  // not able to shutdown chrome properly. See https://crbug.com/1174627.
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
   if (command_line->HasSwitch(switches::kNoStartupWindow) &&
       (command_line->HasSwitch(switches::kRemoteDebuggingPipe) ||
@@ -108,6 +113,7 @@
     keep_alive_.reset(new ScopedKeepAlive(KeepAliveOrigin::REMOTE_DEBUGGING,
                                           KeepAliveRestartOption::DISABLED));
   }
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 ChromeDevToolsManagerDelegate::~ChromeDevToolsManagerDelegate() {
diff --git a/chrome/browser/devtools/devtools_eye_dropper.cc b/chrome/browser/devtools/devtools_eye_dropper.cc
index 434b559..5cb7a06 100644
--- a/chrome/browser/devtools/devtools_eye_dropper.cc
+++ b/chrome/browser/devtools/devtools_eye_dropper.cc
@@ -33,11 +33,7 @@
 
 DevToolsEyeDropper::DevToolsEyeDropper(content::WebContents* web_contents,
                                        EyeDropperCallback callback)
-    : content::WebContentsObserver(web_contents),
-      callback_(callback),
-      last_cursor_x_(-1),
-      last_cursor_y_(-1),
-      host_(nullptr) {
+    : content::WebContentsObserver(web_contents), callback_(callback) {
   mouse_event_callback_ = base::BindRepeating(
       &DevToolsEyeDropper::HandleMouseEvent, base::Unretained(this));
   if (web_contents->GetMainFrame()->IsRenderFrameCreated())
@@ -45,7 +41,10 @@
 }
 
 DevToolsEyeDropper::~DevToolsEyeDropper() {
-  DetachFromHost();
+  if (host_) {
+    // If the renderer frame was destroyed already, we're already detached.
+    DetachFromHost();
+  }
 }
 
 void DevToolsEyeDropper::AttachToHost(content::RenderFrameHost* frame_host) {
diff --git a/chrome/browser/devtools/devtools_eye_dropper.h b/chrome/browser/devtools/devtools_eye_dropper.h
index fe4639b..18b5662 100644
--- a/chrome/browser/devtools/devtools_eye_dropper.h
+++ b/chrome/browser/devtools/devtools_eye_dropper.h
@@ -55,10 +55,10 @@
 
   EyeDropperCallback callback_;
   SkBitmap frame_;
-  int last_cursor_x_;
-  int last_cursor_y_;
+  int last_cursor_x_ = -1;
+  int last_cursor_y_ = -1;
   content::RenderWidgetHost::MouseEventCallback mouse_event_callback_;
-  content::RenderWidgetHost* host_;
+  content::RenderWidgetHost* host_ = nullptr;
   std::unique_ptr<viz::ClientFrameSinkVideoCapturer> video_capturer_;
   base::WeakPtrFactory<DevToolsEyeDropper> weak_factory_{this};
 
diff --git a/chrome/browser/devtools/devtools_sanity_browsertest.cc b/chrome/browser/devtools/devtools_sanity_browsertest.cc
index 2b0aaa8..df429ef 100644
--- a/chrome/browser/devtools/devtools_sanity_browsertest.cc
+++ b/chrome/browser/devtools/devtools_sanity_browsertest.cc
@@ -2512,6 +2512,9 @@
   ui_test_utils::WaitForBrowserToClose(browser());
 }
 
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
+// Skip for ChromeOS because the keep alive is not created for ChromeOS.
+// See https://crbug.com/1174627.
 class KeepAliveDevToolsTest : public InProcessBrowserTest {
  protected:
   void SetUpCommandLine(base::CommandLine* command_line) override {
@@ -2535,6 +2538,7 @@
   EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsOriginRegistered(
       KeepAliveOrigin::REMOTE_DEBUGGING));
 }
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 
 class DevToolsPolicyTest : public InProcessBrowserTest {
  protected:
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index 9868fde..bc22d4c3 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -171,8 +171,6 @@
     "api/identity/extension_token_key.h",
     "api/identity/gaia_remote_consent_flow.cc",
     "api/identity/gaia_remote_consent_flow.h",
-    "api/identity/gaia_web_auth_flow.cc",
-    "api/identity/gaia_web_auth_flow.h",
     "api/identity/identity_api.cc",
     "api/identity/identity_api.h",
     "api/identity/identity_clear_all_cached_auth_tokens_function.cc",
@@ -889,6 +887,7 @@
     "//extensions/browser",
     "//extensions/browser:core_api_provider",
     "//extensions/browser/api:api_implementations",
+    "//extensions/browser/updater",
     "//extensions/buildflags",
     "//extensions/common",
     "//extensions/common/api",
diff --git a/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc b/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc
deleted file mode 100644
index 380623fb..0000000
--- a/chrome/browser/extensions/api/identity/gaia_web_auth_flow.cc
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h"
-
-#include "base/bind.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/trace_event.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/chrome_device_id_helper.h"
-#include "chrome/browser/signin/identity_manager_factory.h"
-#include "components/signin/public/identity_manager/identity_manager.h"
-#include "components/signin/public/identity_manager/ubertoken_fetcher.h"
-#include "content/public/browser/storage_partition.h"
-#include "google_apis/gaia/gaia_auth_fetcher.h"
-#include "google_apis/gaia/gaia_urls.h"
-#include "net/base/escape.h"
-#include "services/network/public/mojom/cookie_manager.mojom.h"
-
-namespace extensions {
-
-GaiaWebAuthFlow::GaiaWebAuthFlow(Delegate* delegate,
-                                 Profile* profile,
-                                 const ExtensionTokenKey* token_key,
-                                 const std::string& oauth2_client_id,
-                                 const std::string& locale)
-    : delegate_(delegate),
-      profile_(profile),
-      account_id_(token_key->account_info.account_id) {
-  TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(
-      "identity", "GaiaWebAuthFlow", this, "extension_id",
-      token_key->extension_id, "account_id",
-      token_key->account_info.account_id.ToString());
-
-  const char kOAuth2RedirectPathFormat[] = "/%s";
-  const char kOAuth2AuthorizeFormat[] =
-      "?response_type=token&approval_prompt=force&authuser=0&"
-      "client_id=%s&"
-      "scope=%s&"
-      "origin=chrome-extension://%s/&"
-      "redirect_uri=%s:/%s&"
-      "hl=%s";
-  // Additional parameters to pass if device_id is enabled.
-  const char kOAuth2AuthorizeFormatDeviceIdAddendum[] =
-      "&device_id=%s&"
-      "device_type=chrome";
-
-  std::vector<base::StringPiece> scopes(token_key->scopes.begin(),
-                                        token_key->scopes.end());
-  std::vector<base::StringPiece> client_id_parts = base::SplitStringPiece(
-      oauth2_client_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
-  std::reverse(client_id_parts.begin(), client_id_parts.end());
-  redirect_scheme_ = base::JoinString(client_id_parts, ".");
-  std::string signin_scoped_device_id;
-  if (profile_)
-    signin_scoped_device_id = GetSigninScopedDeviceIdForProfile(profile_);
-
-  redirect_path_prefix_ = base::StringPrintf(kOAuth2RedirectPathFormat,
-                                             token_key->extension_id.c_str());
-
-  std::string oauth2_authorize_params = base::StringPrintf(
-      kOAuth2AuthorizeFormat,
-      oauth2_client_id.c_str(),
-      net::EscapeUrlEncodedData(base::JoinString(scopes, " "), true).c_str(),
-      token_key->extension_id.c_str(),
-      redirect_scheme_.c_str(),
-      token_key->extension_id.c_str(),
-      locale.c_str());
-  if (!signin_scoped_device_id.empty()) {
-    oauth2_authorize_params += base::StringPrintf(
-        kOAuth2AuthorizeFormatDeviceIdAddendum,
-        net::EscapeUrlEncodedData(signin_scoped_device_id, true).c_str());
-  }
-  auth_url_ = GaiaUrls::GetInstance()->oauth2_auth_url().Resolve(
-      oauth2_authorize_params);
-}
-
-GaiaWebAuthFlow::~GaiaWebAuthFlow() {
-  TRACE_EVENT_NESTABLE_ASYNC_END0("identity", "GaiaWebAuthFlow", this);
-
-  if (web_flow_)
-    web_flow_.release()->DetachDelegateAndDelete();
-}
-
-void GaiaWebAuthFlow::Start() {
-  TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("identity", "UbertokenFetch", this);
-  auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_);
-  ubertoken_fetcher_ = identity_manager->CreateUbertokenFetcherForAccount(
-      account_id_,
-      base::BindOnce(&GaiaWebAuthFlow::OnUbertokenFetchComplete,
-                     base::Unretained(this)),
-      gaia::GaiaSource::kChrome, profile_->GetURLLoaderFactory());
-}
-
-void GaiaWebAuthFlow::OnUbertokenFetchComplete(GoogleServiceAuthError error,
-                                               const std::string& token) {
-  if (error != GoogleServiceAuthError::AuthErrorNone()) {
-    TRACE_EVENT_NESTABLE_ASYNC_END1("identity", "UbertokenFetch", this, "error",
-                                    error.ToString());
-
-    DVLOG(1) << "OnUbertokenFetchComplete failure: " << error.error_message();
-    delegate_->OnGaiaFlowFailure(GaiaWebAuthFlow::SERVICE_AUTH_ERROR, error,
-                                 std::string());
-    return;
-  }
-
-  TRACE_EVENT_NESTABLE_ASYNC_END0("identity", "UbertokenFetch", this);
-
-  const char kMergeSessionQueryFormat[] = "?uberauth=%s&"
-                                          "continue=%s&"
-                                          "source=appsv2";
-
-  std::string merge_query = base::StringPrintf(
-      kMergeSessionQueryFormat,
-      net::EscapeUrlEncodedData(token, true).c_str(),
-      net::EscapeUrlEncodedData(auth_url_.spec(), true).c_str());
-  GURL merge_url(
-      GaiaUrls::GetInstance()->merge_session_url().Resolve(merge_query));
-
-  web_flow_ = CreateWebAuthFlow(merge_url);
-  network::mojom::CookieManager* cookie_manager =
-      web_flow_->GetGuestPartition()->GetCookieManagerForBrowserProcess();
-  cookie_manager->DeleteCookies(
-      network::mojom::CookieDeletionFilter::New(),
-      base::BindOnce(&GaiaWebAuthFlow::OnCookiesDeleted,
-                     weak_ptr_factory_.GetWeakPtr()));
-}
-
-void GaiaWebAuthFlow::OnCookiesDeleted(uint32_t num_deleted) {
-  web_flow_->Start();
-}
-
-void GaiaWebAuthFlow::OnAuthFlowFailure(WebAuthFlow::Failure failure) {
-  GaiaWebAuthFlow::Failure gaia_failure;
-
-  switch (failure) {
-    case WebAuthFlow::WINDOW_CLOSED:
-      gaia_failure = GaiaWebAuthFlow::WINDOW_CLOSED;
-      break;
-    case WebAuthFlow::LOAD_FAILED:
-      DVLOG(1) << "OnAuthFlowFailure LOAD_FAILED";
-      gaia_failure = GaiaWebAuthFlow::LOAD_FAILED;
-      break;
-    default:
-      NOTREACHED() << "Unexpected error from web auth flow: " << failure;
-      gaia_failure = GaiaWebAuthFlow::LOAD_FAILED;
-      break;
-  }
-
-  TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("identity", "OnAuthFlowFailure", this,
-                                      "error", gaia_failure);
-
-  delegate_->OnGaiaFlowFailure(
-      gaia_failure,
-      GoogleServiceAuthError(GoogleServiceAuthError::NONE),
-      std::string());
-}
-
-void GaiaWebAuthFlow::OnAuthFlowURLChange(const GURL& url) {
-  TRACE_EVENT_NESTABLE_ASYNC_INSTANT0("identity", "OnAuthFlowURLChange", this);
-
-  const char kOAuth2RedirectAccessTokenKey[] = "access_token";
-  const char kOAuth2RedirectErrorKey[] = "error";
-  const char kOAuth2ExpiresInKey[] = "expires_in";
-
-  // The format of the target URL is:
-  //     reversed.oauth.client.id:/extensionid#access_token=TOKEN
-
-  if (url.scheme() == redirect_scheme_ && !url.has_host() && !url.has_port() &&
-      base::StartsWith(url.GetContent(), redirect_path_prefix_,
-                       base::CompareCase::SENSITIVE) &&
-      url.has_ref()) {
-    web_flow_.release()->DetachDelegateAndDelete();
-
-    std::string fragment = url.ref();
-    base::StringPairs pairs;
-    base::SplitStringIntoKeyValuePairs(fragment, '=', '&', &pairs);
-    std::string access_token;
-    std::string error;
-    std::string expiration;
-
-    for (auto it = pairs.begin(); it != pairs.end(); ++it) {
-      if (it->first == kOAuth2RedirectAccessTokenKey)
-        access_token = it->second;
-      else if (it->first == kOAuth2RedirectErrorKey)
-        error = it->second;
-      else if (it->first == kOAuth2ExpiresInKey)
-        expiration = it->second;
-    }
-
-    if (access_token.empty() && error.empty()) {
-      delegate_->OnGaiaFlowFailure(
-          GaiaWebAuthFlow::INVALID_REDIRECT,
-          GoogleServiceAuthError(GoogleServiceAuthError::NONE),
-          std::string());
-    } else if (!error.empty()) {
-      delegate_->OnGaiaFlowFailure(
-          GaiaWebAuthFlow::OAUTH_ERROR,
-          GoogleServiceAuthError(GoogleServiceAuthError::NONE),
-          error);
-    } else {
-      delegate_->OnGaiaFlowCompleted(access_token, expiration);
-    }
-  }
-}
-
-void GaiaWebAuthFlow::OnAuthFlowTitleChange(const std::string& title) {
-  // On the final page the title will be "Loading <redirect-url>".
-  // Treat it as though we'd really been redirected to <redirect-url>.
-  const char kRedirectPrefix[] = "Loading ";
-  std::string prefix(kRedirectPrefix);
-
-  if (base::StartsWith(title, prefix, base::CompareCase::SENSITIVE)) {
-    GURL url(title.substr(prefix.length(), std::string::npos));
-    if (url.is_valid())
-      OnAuthFlowURLChange(url);
-  }
-}
-
-std::unique_ptr<WebAuthFlow> GaiaWebAuthFlow::CreateWebAuthFlow(GURL url) {
-  return std::unique_ptr<WebAuthFlow>(
-      new WebAuthFlow(this, profile_, url, WebAuthFlow::INTERACTIVE,
-                      WebAuthFlow::GET_AUTH_TOKEN));
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/extensions/api/identity/gaia_web_auth_flow.h b/chrome/browser/extensions/api/identity/gaia_web_auth_flow.h
deleted file mode 100644
index 37575c8..0000000
--- a/chrome/browser/extensions/api/identity/gaia_web_auth_flow.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_API_IDENTITY_GAIA_WEB_AUTH_FLOW_H_
-#define CHROME_BROWSER_EXTENSIONS_API_IDENTITY_GAIA_WEB_AUTH_FLOW_H_
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/extensions/api/identity/extension_token_key.h"
-#include "chrome/browser/extensions/api/identity/web_auth_flow.h"
-#include "extensions/common/manifest_handlers/oauth2_manifest_handler.h"
-#include "google_apis/gaia/google_service_auth_error.h"
-
-namespace signin {
-class UbertokenFetcher;
-}
-
-namespace extensions {
-
-// Implements a web-based OAuth2 scope approval dialog. This flow has
-// four parts:
-// 1. Fetch an ubertoken for a signed-in user.
-// 2. Use the ubertoken to get session cookies using MergeSession.
-// 3. Start the OAuth flow and wait for final redirect.
-// 4. Parse results from the fragment component of the final redirect URI.
-//
-// The OAuth flow is a special version of the OAuth2 out-of-band flow
-// where the final response page's title contains the
-// redirect_uri. The redirect URI has an unusual format to prevent its
-// use in other contexts. The scheme of the URI is a reversed version
-// of the OAuth client ID, and the path starts with the Chrome
-// extension ID. For example, an app with the OAuth client ID
-// "32610281651.apps.googleusercontent.com" and a Chrome app ID
-// "kbinjhdkhikmpjoejcfofghmjjpidcnj", would get redirected to:
-//
-// com.googleusercontent.apps.32610281651:/kbinjhdkhikmpjoejcfofghmjjpidcnj
-//
-// Arriving at this URI completes the flow. The last response from
-// gaia does a JavaScript redirect to the special URI, but also
-// includes the same URI in its title. The navigation to this URI gets
-// filtered out because of its unusual protocol scheme, so
-// GaiaWebAuthFlow pulls it out of the window title instead.
-
-class GaiaWebAuthFlow : public WebAuthFlow::Delegate {
- public:
-  enum Failure {
-    WINDOW_CLOSED,  // Window closed by user.
-    INVALID_REDIRECT,  // Redirect parse error.
-    SERVICE_AUTH_ERROR,  // Non-OAuth related authentication error
-    OAUTH_ERROR,  // Flow reached final redirect, which contained an error.
-    LOAD_FAILED  // An auth flow page failed to load.
-  };
-
-  class Delegate {
-   public:
-    // Called when the flow fails prior to the final OAuth redirect,
-    // TODO(courage): LOAD_FAILURE descriptions?
-    virtual void OnGaiaFlowFailure(Failure failure,
-                                   GoogleServiceAuthError service_error,
-                                   const std::string& oauth_error) = 0;
-    // Called when the OAuth2 flow completes.
-    virtual void OnGaiaFlowCompleted(const std::string& access_token,
-                                     const std::string& expiration) = 0;
-  };
-
-  GaiaWebAuthFlow(Delegate* delegate,
-                  Profile* profile,
-                  const ExtensionTokenKey* token_key,
-                  const std::string& oauth2_client_id,
-                  const std::string& locale);
-  ~GaiaWebAuthFlow() override;
-
-  // Starts the flow by fetching an ubertoken. Can override for testing.
-  virtual void Start();
-
-  // Ubertoken fetch completion callback.
-  void OnUbertokenFetchComplete(GoogleServiceAuthError error,
-                                const std::string& token);
-
-  // DeleteCookies completion callback.
-  void OnCookiesDeleted(uint32_t num_deleted);
-
-  // WebAuthFlow::Delegate implementation.
-  void OnAuthFlowFailure(WebAuthFlow::Failure failure) override;
-  void OnAuthFlowURLChange(const GURL& redirect_url) override;
-  void OnAuthFlowTitleChange(const std::string& title) override;
-
- private:
-  // Creates a WebAuthFlow, which will navigate to |url|. Can override
-  // for testing. Used to kick off the MergeSession (step #2).
-  virtual std::unique_ptr<WebAuthFlow> CreateWebAuthFlow(GURL url);
-
-  Delegate* delegate_;
-  Profile* profile_;
-  CoreAccountId account_id_;
-  std::string redirect_scheme_;
-  std::string redirect_path_prefix_;
-  GURL auth_url_;
-  std::unique_ptr<signin::UbertokenFetcher> ubertoken_fetcher_;
-  std::unique_ptr<WebAuthFlow> web_flow_;
-
-  base::WeakPtrFactory<GaiaWebAuthFlow> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(GaiaWebAuthFlow);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_EXTENSIONS_API_IDENTITY_GAIA_WEB_AUTH_FLOW_H_
diff --git a/chrome/browser/extensions/api/identity/gaia_web_auth_flow_unittest.cc b/chrome/browser/extensions/api/identity/gaia_web_auth_flow_unittest.cc
deleted file mode 100644
index f0bdef689..0000000
--- a/chrome/browser/extensions/api/identity/gaia_web_auth_flow_unittest.cc
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h"
-
-#include <vector>
-
-#include "base/run_loop.h"
-#include "content/public/browser/storage_partition.h"
-#include "content/public/test/browser_task_environment.h"
-#include "content/public/test/test_storage_partition.h"
-#include "services/network/test/test_cookie_manager.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace extensions {
-
-class DeleteCookiesTestCookieManager : public network::TestCookieManager {
- public:
-  void DeleteCookies(network::mojom::CookieDeletionFilterPtr filter,
-                     DeleteCookiesCallback callback) override {
-    cookies_deleted_ = true;
-    std::move(callback).Run(0U);
-  }
-  bool cookies_deleted() { return cookies_deleted_; }
-
- private:
-  bool cookies_deleted_ = false;
-};
-
-class FakeWebAuthFlow : public WebAuthFlow {
- public:
-  explicit FakeWebAuthFlow(WebAuthFlow::Delegate* delegate)
-      : WebAuthFlow(delegate,
-                    nullptr,
-                    GURL(),
-                    WebAuthFlow::INTERACTIVE,
-                    WebAuthFlow::GET_AUTH_TOKEN) {
-    storage_partition.set_cookie_manager_for_browser_process(&cookie_manager);
-  }
-
-  void Start() override { EXPECT_TRUE(cookie_manager.cookies_deleted()); }
-
-  content::StoragePartition* GetGuestPartition() override {
-    return &storage_partition;
-  }
-
- private:
-  content::TestStoragePartition storage_partition;
-  DeleteCookiesTestCookieManager cookie_manager;
-};
-
-class TestGaiaWebAuthFlow : public GaiaWebAuthFlow {
- public:
-  TestGaiaWebAuthFlow(GaiaWebAuthFlow::Delegate* delegate,
-                      const ExtensionTokenKey* token_key,
-                      const std::string oauth2_client_id,
-                      GoogleServiceAuthError::State ubertoken_error_state)
-      : GaiaWebAuthFlow(delegate, NULL, token_key, oauth2_client_id, "en-us"),
-        ubertoken_error_(ubertoken_error_state) {}
-
-  void Start() override {
-    OnUbertokenFetchComplete(
-        ubertoken_error_,
-        ubertoken_error_.state() == GoogleServiceAuthError::NONE
-            ? "fake_ubertoken"
-            : std::string());
-  }
-
- private:
-  std::unique_ptr<WebAuthFlow> CreateWebAuthFlow(GURL url) override {
-    return std::unique_ptr<WebAuthFlow>(new FakeWebAuthFlow(this));
-  }
-
-  GoogleServiceAuthError ubertoken_error_;
-};
-
-class MockGaiaWebAuthFlowDelegate : public GaiaWebAuthFlow::Delegate {
- public:
-  MOCK_METHOD3(OnGaiaFlowFailure,
-               void(GaiaWebAuthFlow::Failure failure,
-                    GoogleServiceAuthError service_error,
-                    const std::string& oauth_error));
-  MOCK_METHOD2(OnGaiaFlowCompleted,
-               void(const std::string& access_token,
-                    const std::string& expiration));
-};
-
-class IdentityGaiaWebAuthFlowTest : public testing::Test {
- public:
-  IdentityGaiaWebAuthFlowTest()
-      : ubertoken_error_state_(GoogleServiceAuthError::NONE) {}
-
-  void TearDown() override {
-    testing::Test::TearDown();
-    base::RunLoop loop;
-    loop.RunUntilIdle();  // Run tasks so FakeWebAuthFlows get deleted.
-  }
-
-  std::unique_ptr<TestGaiaWebAuthFlow> CreateTestFlow() {
-    CoreAccountInfo user_info;
-    user_info.account_id = CoreAccountId("account_id");
-    user_info.gaia = "account_id";
-    user_info.email = "email";
-
-    ExtensionTokenKey token_key("extension_id", user_info,
-                                std::set<std::string>());
-    return std::unique_ptr<TestGaiaWebAuthFlow>(new TestGaiaWebAuthFlow(
-        &delegate_, &token_key, "fake.client.id", ubertoken_error_state_));
-  }
-
-  std::string GetFinalTitle(const std::string& fragment) {
-    return std::string("Loading id.client.fake:/extension_id#") + fragment;
-  }
-
-  GoogleServiceAuthError GetNoneServiceError() {
-    return GoogleServiceAuthError(GoogleServiceAuthError::NONE);
-  }
-
-  void set_ubertoken_error(
-      GoogleServiceAuthError::State ubertoken_error_state) {
-    ubertoken_error_state_ = ubertoken_error_state;
-  }
-
- protected:
-  testing::StrictMock<MockGaiaWebAuthFlowDelegate> delegate_;
-  GoogleServiceAuthError::State ubertoken_error_state_;
-  content::BrowserTaskEnvironment task_environment_;
-};
-
-TEST_F(IdentityGaiaWebAuthFlowTest, OAuthError) {
-  std::unique_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
-  flow->Start();
-  EXPECT_CALL(delegate_, OnGaiaFlowFailure(
-          GaiaWebAuthFlow::OAUTH_ERROR,
-          GoogleServiceAuthError(GoogleServiceAuthError::NONE),
-          "access_denied"));
-  flow->OnAuthFlowTitleChange(GetFinalTitle("error=access_denied"));
-}
-
-TEST_F(IdentityGaiaWebAuthFlowTest, Token) {
-  std::unique_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
-  flow->Start();
-  EXPECT_CALL(delegate_, OnGaiaFlowCompleted("fake_access_token", ""));
-  flow->OnAuthFlowTitleChange(GetFinalTitle("access_token=fake_access_token"));
-}
-
-TEST_F(IdentityGaiaWebAuthFlowTest, TokenAndExpiration) {
-  std::unique_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
-  flow->Start();
-  EXPECT_CALL(delegate_, OnGaiaFlowCompleted("fake_access_token", "3600"));
-  flow->OnAuthFlowTitleChange(
-      GetFinalTitle("access_token=fake_access_token&expires_in=3600"));
-}
-
-TEST_F(IdentityGaiaWebAuthFlowTest, ExtraFragmentParametersSuccess) {
-  std::unique_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
-  flow->Start();
-  EXPECT_CALL(delegate_,
-              OnGaiaFlowCompleted("fake_access_token", "3600"));
-  flow->OnAuthFlowTitleChange(GetFinalTitle("chaff1=stuff&"
-                                            "expires_in=3600&"
-                                            "chaff2=and&"
-                                            "nonerror=fake_error&"
-                                            "chaff3=nonsense&"
-                                            "access_token=fake_access_token&"
-                                            "chaff4="));
-}
-
-TEST_F(IdentityGaiaWebAuthFlowTest, ExtraFragmentParametersError) {
-  std::unique_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
-  flow->Start();
-  EXPECT_CALL(delegate_, OnGaiaFlowFailure(
-          GaiaWebAuthFlow::OAUTH_ERROR,
-          GoogleServiceAuthError(GoogleServiceAuthError::NONE),
-          "fake_error"));
-  flow->OnAuthFlowTitleChange(GetFinalTitle("chaff1=stuff&"
-                                            "expires_in=3600&"
-                                            "chaff2=and&"
-                                            "error=fake_error&"
-                                            "chaff3=nonsense&"
-                                            "access_token=fake_access_token&"
-                                            "chaff4="));
-}
-
-TEST_F(IdentityGaiaWebAuthFlowTest, TitleSpam) {
-  std::unique_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
-  flow->Start();
-  flow->OnAuthFlowTitleChange(
-      "Loading https://extension_id.chromiumapp.org/#error=non_final_title");
-  flow->OnAuthFlowTitleChange("I'm feeling entitled.");
-  flow->OnAuthFlowTitleChange("");
-  flow->OnAuthFlowTitleChange(
-      "Loading id.client.fake:/bad_extension_id#error=non_final_title");
-  flow->OnAuthFlowTitleChange(
-      "Loading bad.id.client.fake:/extension_id#error=non_final_title");
-  EXPECT_CALL(delegate_, OnGaiaFlowCompleted("fake_access_token", ""));
-  flow->OnAuthFlowTitleChange(GetFinalTitle("access_token=fake_access_token"));
-}
-
-TEST_F(IdentityGaiaWebAuthFlowTest, EmptyFragment) {
-  std::unique_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
-  flow->Start();
-  EXPECT_CALL(
-      delegate_,
-      OnGaiaFlowFailure(
-          GaiaWebAuthFlow::INVALID_REDIRECT,
-          GoogleServiceAuthError(GoogleServiceAuthError::NONE),
-          ""));
-  flow->OnAuthFlowTitleChange(GetFinalTitle(""));
-}
-
-TEST_F(IdentityGaiaWebAuthFlowTest, JunkFragment) {
-  std::unique_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
-  flow->Start();
-  EXPECT_CALL(
-      delegate_,
-      OnGaiaFlowFailure(
-          GaiaWebAuthFlow::INVALID_REDIRECT,
-          GoogleServiceAuthError(GoogleServiceAuthError::NONE),
-          ""));
-  flow->OnAuthFlowTitleChange(GetFinalTitle("thisisjustabunchofjunk"));
-}
-
-TEST_F(IdentityGaiaWebAuthFlowTest, NoFragment) {
-  std::unique_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
-  flow->Start();
-  // This won't be recognized as an interesting title.
-  flow->OnAuthFlowTitleChange("Loading id.client.fake:/extension_id");
-}
-
-TEST_F(IdentityGaiaWebAuthFlowTest, Host) {
-  std::unique_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
-  flow->Start();
-  // These won't be recognized as interesting titles.
-  flow->OnAuthFlowTitleChange(
-      "Loading id.client.fake://extension_id#access_token=fake_access_token");
-  flow->OnAuthFlowTitleChange(
-      "Loading id.client.fake://extension_id/#access_token=fake_access_token");
-  flow->OnAuthFlowTitleChange(
-      "Loading "
-      "id.client.fake://host/extension_id/#access_token=fake_access_token");
-}
-
-TEST_F(IdentityGaiaWebAuthFlowTest, UbertokenFailure) {
-  set_ubertoken_error(GoogleServiceAuthError::CONNECTION_FAILED);
-  std::unique_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
-  EXPECT_CALL(
-      delegate_,
-      OnGaiaFlowFailure(
-          GaiaWebAuthFlow::SERVICE_AUTH_ERROR,
-          GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED),
-          ""));
-  flow->Start();
-}
-
-TEST_F(IdentityGaiaWebAuthFlowTest, AuthFlowFailure) {
-  std::unique_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
-  flow->Start();
-  EXPECT_CALL(
-      delegate_,
-      OnGaiaFlowFailure(
-          GaiaWebAuthFlow::WINDOW_CLOSED,
-          GoogleServiceAuthError(GoogleServiceAuthError::NONE),
-          ""));
-  flow->OnAuthFlowFailure(WebAuthFlow::WINDOW_CLOSED);
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/extensions/api/identity/identity_api.h b/chrome/browser/extensions/api/identity/identity_api.h
index 173e7c4..4144925 100644
--- a/chrome/browser/extensions/api/identity/identity_api.h
+++ b/chrome/browser/extensions/api/identity/identity_api.h
@@ -17,7 +17,6 @@
 #include "base/optional.h"
 #include "build/build_config.h"
 #include "build/buildflag.h"
-#include "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h"
 #include "chrome/browser/extensions/api/identity/identity_clear_all_cached_auth_tokens_function.h"
 #include "chrome/browser/extensions/api/identity/identity_get_accounts_function.h"
 #include "chrome/browser/extensions/api/identity/identity_get_auth_token_function.h"
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc
index 69cd838..c160e414 100644
--- a/chrome/browser/extensions/api/identity/identity_apitest.cc
+++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -24,7 +24,6 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/identity/gaia_remote_consent_flow.h"
-#include "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h"
 #include "chrome/browser/extensions/api/identity/identity_api.h"
 #include "chrome/browser/extensions/api/identity/identity_constants.h"
 #include "chrome/browser/extensions/api/identity/identity_get_accounts_function.h"
@@ -69,6 +68,7 @@
 #include "extensions/browser/api_test_utils.h"
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/extension_features.h"
+#include "extensions/common/manifest_handlers/oauth2_manifest_handler.h"
 #include "google_apis/gaia/oauth2_mint_token_flow.h"
 #include "net/cookies/cookie_util.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -219,7 +219,6 @@
 class TestOAuth2MintTokenFlow : public OAuth2MintTokenFlow {
  public:
   enum ResultType {
-    ISSUE_ADVICE_SUCCESS,
     REMOTE_CONSENT_SUCCESS,
     MINT_TOKEN_SUCCESS,
     MINT_TOKEN_FAILURE,
@@ -240,11 +239,6 @@
   void Start(scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
              const std::string& access_token) override {
     switch (result_) {
-      case ISSUE_ADVICE_SUCCESS: {
-        IssueAdviceInfo info;
-        delegate_->OnIssueAdviceSuccess(info);
-        break;
-      }
       case REMOTE_CONSENT_SUCCESS: {
         RemoteConsentResolutionData resolution_data;
         delegate_->OnRemoteConsentSuccess(resolution_data);
@@ -340,7 +334,7 @@
         login_ui_result_(true),
         scope_ui_result_(true),
         scope_ui_async_(false),
-        scope_ui_failure_(GaiaWebAuthFlow::WINDOW_CLOSED),
+        scope_ui_failure_(GaiaRemoteConsentFlow::WINDOW_CLOSED),
         login_ui_shown_(false),
         scope_ui_shown_(false) {}
 
@@ -379,23 +373,11 @@
     on_scope_ui_shown_ = std::move(on_scope_ui_shown);
   }
 
-  void set_scope_ui_failure(GaiaWebAuthFlow::Failure failure) {
+  void set_scope_ui_failure(GaiaRemoteConsentFlow::Failure failure) {
     scope_ui_result_ = false;
     scope_ui_failure_ = failure;
   }
 
-  void set_scope_ui_service_error(const GoogleServiceAuthError& service_error) {
-    scope_ui_result_ = false;
-    scope_ui_failure_ = GaiaWebAuthFlow::SERVICE_AUTH_ERROR;
-    scope_ui_service_error_ = service_error;
-  }
-
-  void set_scope_ui_oauth_error(const std::string& oauth_error) {
-    scope_ui_result_ = false;
-    scope_ui_failure_ = GaiaWebAuthFlow::OAUTH_ERROR;
-    scope_ui_oauth_error_ = oauth_error;
-  }
-
   void set_remote_consent_gaia_id(const std::string& gaia_id) {
     remote_consent_gaia_id_ = gaia_id;
   }
@@ -483,25 +465,6 @@
     }
   }
 
-  void ShowOAuthApprovalDialog(const IssueAdviceInfo& issue_advice) override {
-    scope_ui_shown_ = true;
-    if (!scope_ui_async_)
-      CompleteOAuthApprovalDialog();
-    else
-      std::move(on_scope_ui_shown_).Run();
-  }
-
-  void CompleteOAuthApprovalDialog() {
-    if (scope_ui_result_) {
-      OnGaiaFlowCompleted(kAccessToken, "3600");
-    } else if (scope_ui_failure_ == GaiaWebAuthFlow::SERVICE_AUTH_ERROR) {
-      OnGaiaFlowFailure(scope_ui_failure_, scope_ui_service_error_, "");
-    } else {
-      GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
-      OnGaiaFlowFailure(scope_ui_failure_, error, scope_ui_oauth_error_);
-    }
-  }
-
   void ShowRemoteConsentDialog(
       const RemoteConsentResolutionData& resolution_data) override {
     scope_ui_shown_ = true;
@@ -516,7 +479,7 @@
       OnGaiaRemoteConsentFlowApproved("fake_consent_result",
                                       remote_consent_gaia_id_);
     } else {
-      OnGaiaRemoteConsentFlowFailed(GaiaRemoteConsentFlow::WINDOW_CLOSED);
+      OnGaiaRemoteConsentFlowFailed(scope_ui_failure_);
     }
   }
 
@@ -549,9 +512,7 @@
   bool scope_ui_result_;
   bool scope_ui_async_;
   base::OnceClosure on_scope_ui_shown_;
-  GaiaWebAuthFlow::Failure scope_ui_failure_;
-  GoogleServiceAuthError scope_ui_service_error_;
-  std::string scope_ui_oauth_error_;
+  GaiaRemoteConsentFlow::Failure scope_ui_failure_;
   bool login_ui_shown_;
   bool scope_ui_shown_;
 
@@ -1184,19 +1145,19 @@
 }
 
 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
-                       NonInteractiveMintAdviceSuccess) {
+                       NonInteractiveRemoteConsentSuccess) {
   SignIn("primary@example.com");
   scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(extension.get());
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
   std::string error =
       utils::RunFunctionAndReturnError(func.get(), "[{}]", browser());
   EXPECT_EQ(std::string(errors::kNoGrant), error);
   EXPECT_FALSE(func->login_ui_shown());
   EXPECT_FALSE(func->scope_ui_shown());
 
-  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_ADVICE,
+  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_REMOTE_CONSENT,
             GetCachedToken(CoreAccountInfo()).status());
   histogram_tester()->ExpectUniqueSample(
       kGetAuthTokenResultHistogramName,
@@ -1284,28 +1245,6 @@
 }
 #endif
 
-IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, NoOptionsSuccess) {
-  SignIn("primary@example.com");
-  scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
-  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
-  func->set_extension(extension.get());
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS);
-
-  std::string access_token;
-  std::set<std::string> granted_scopes;
-  RunGetAuthTokenFunction(func.get(), "[{}]", browser(), &access_token,
-                          &granted_scopes);
-  EXPECT_EQ(std::string(kAccessToken), access_token);
-  EXPECT_EQ(func->GetExtensionTokenKeyForTest()->scopes, granted_scopes);
-  EXPECT_FALSE(func->login_ui_shown());
-  EXPECT_FALSE(func->scope_ui_shown());
-  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
-            GetCachedToken(CoreAccountInfo()).status());
-  histogram_tester()->ExpectUniqueSample(
-      kGetAuthTokenResultHistogramName, IdentityGetAuthTokenError::State::kNone,
-      1);
-}
-
 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, NonInteractiveSuccess) {
   SignIn("primary@example.com");
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
@@ -1448,8 +1387,8 @@
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
   func->set_login_ui_result(true);
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
-  func->set_scope_ui_failure(GaiaWebAuthFlow::WINDOW_CLOSED);
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
+  func->set_scope_ui_failure(GaiaRemoteConsentFlow::WINDOW_CLOSED);
   std::string error = utils::RunFunctionAndReturnError(
       func.get(), "[{\"interactive\": true}]", browser());
   EXPECT_EQ(std::string(errors::kUserRejected), error);
@@ -1457,7 +1396,7 @@
   EXPECT_TRUE(func->scope_ui_shown());
   histogram_tester()->ExpectUniqueSample(
       kGetAuthTokenResultHistogramName,
-      IdentityGetAuthTokenError::State::kGaiaFlowRejected, 1);
+      IdentityGetAuthTokenError::State::kRemoteConsentFlowRejected, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
@@ -1466,7 +1405,10 @@
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(extension.get());
   func->set_login_ui_result(true);
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
+  // The user signs in with the "secondary@example.com" email.
+  func->set_remote_consent_gaia_id("gaia_id_for_secondary_example.com");
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS);
 
   std::string access_token;
   std::set<std::string> granted_scopes;
@@ -1486,8 +1428,8 @@
   SignIn("primary@example.com");
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
-  func->set_scope_ui_failure(GaiaWebAuthFlow::WINDOW_CLOSED);
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
+  func->set_scope_ui_failure(GaiaRemoteConsentFlow::WINDOW_CLOSED);
   std::string error = utils::RunFunctionAndReturnError(
       func.get(), "[{\"interactive\": true}]", browser());
   EXPECT_EQ(std::string(errors::kUserRejected), error);
@@ -1495,7 +1437,7 @@
   EXPECT_TRUE(func->scope_ui_shown());
   histogram_tester()->ExpectUniqueSample(
       kGetAuthTokenResultHistogramName,
-      IdentityGetAuthTokenError::State::kGaiaFlowRejected, 1);
+      IdentityGetAuthTokenError::State::kRemoteConsentFlowRejected, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
@@ -1503,8 +1445,8 @@
   SignIn("primary@example.com");
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
-  func->set_scope_ui_failure(GaiaWebAuthFlow::LOAD_FAILED);
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
+  func->set_scope_ui_failure(GaiaRemoteConsentFlow::LOAD_FAILED);
   std::string error = utils::RunFunctionAndReturnError(
       func.get(), "[{\"interactive\": true}]", browser());
   EXPECT_EQ(std::string(errors::kPageLoadFailure), error);
@@ -1512,56 +1454,54 @@
   EXPECT_TRUE(func->scope_ui_shown());
   histogram_tester()->ExpectUniqueSample(
       kGetAuthTokenResultHistogramName,
-      IdentityGetAuthTokenError::State::kPageLoadFailure, 1);
+      IdentityGetAuthTokenError::State::kRemoteConsentPageLoadFailure, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
-                       InteractiveApprovalInvalidRedirect) {
+                       InteractiveApprovalSetAccountsInCookieFailed) {
   SignIn("primary@example.com");
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
-  func->set_scope_ui_failure(GaiaWebAuthFlow::INVALID_REDIRECT);
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
+  func->set_scope_ui_failure(
+      GaiaRemoteConsentFlow::SET_ACCOUNTS_IN_COOKIE_FAILED);
   std::string error = utils::RunFunctionAndReturnError(
       func.get(), "[{\"interactive\": true}]", browser());
-  EXPECT_EQ(std::string(errors::kInvalidRedirect), error);
+  EXPECT_EQ(std::string(errors::kSetAccountsInCookieFailure), error);
   EXPECT_FALSE(func->login_ui_shown());
   EXPECT_TRUE(func->scope_ui_shown());
   histogram_tester()->ExpectUniqueSample(
       kGetAuthTokenResultHistogramName,
-      IdentityGetAuthTokenError::State::kInvalidRedirect, 1);
+      IdentityGetAuthTokenError::State::kSetAccountsInCookieFailure, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
-                       InteractiveApprovalConnectionFailure) {
+                       InteractiveApprovalInvalidConsentResult) {
   SignIn("primary@example.com");
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
-  func->set_scope_ui_service_error(
-      GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED));
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
+  func->set_scope_ui_failure(GaiaRemoteConsentFlow::INVALID_CONSENT_RESULT);
   std::string error = utils::RunFunctionAndReturnError(
       func.get(), "[{\"interactive\": true}]", browser());
-  EXPECT_TRUE(base::StartsWith(error, errors::kAuthFailure,
+  EXPECT_TRUE(base::StartsWith(error, errors::kInvalidConsentResult,
                                base::CompareCase::INSENSITIVE_ASCII));
   EXPECT_FALSE(func->login_ui_shown());
   EXPECT_TRUE(func->scope_ui_shown());
   histogram_tester()->ExpectUniqueSample(
       kGetAuthTokenResultHistogramName,
-      IdentityGetAuthTokenError::State::kGaiaFlowAuthFailure, 1);
+      IdentityGetAuthTokenError::State::kInvalidConsentResult, 1);
 }
 
-IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
-                       InteractiveApprovalServiceErrorAccountValid) {
+IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, InteractiveApprovalNoGrant) {
   SignIn("primary@example.com");
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
-  func->set_scope_ui_service_error(
-      GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_ERROR));
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
+  func->set_scope_ui_failure(GaiaRemoteConsentFlow::NO_GRANT);
   std::string error = utils::RunFunctionAndReturnError(
       func.get(), "[{\"interactive\": true}]", browser());
-  EXPECT_TRUE(base::StartsWith(error, errors::kAuthFailure,
+  EXPECT_TRUE(base::StartsWith(error, errors::kNoGrant,
                                base::CompareCase::INSENSITIVE_ASCII));
 
   // The login UI should not be shown as the account is in a valid state.
@@ -1569,82 +1509,42 @@
   EXPECT_TRUE(func->scope_ui_shown());
   histogram_tester()->ExpectUniqueSample(
       kGetAuthTokenResultHistogramName,
-      IdentityGetAuthTokenError::State::kGaiaFlowAuthFailure, 1);
+      IdentityGetAuthTokenError::State::kNoGrant, 1);
 }
 
 // The signin flow is simply not used on ChromeOS.
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
-                       InteractiveApprovalServiceErrorShowSigninUIOnlyOnce) {
+                       InteractiveApprovalNoGrantShowSigninUIOnlyOnce) {
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_login_ui_result(true);
   func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
-  func->set_scope_ui_service_error(
-      GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_ERROR));
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
+  func->set_scope_ui_failure(GaiaRemoteConsentFlow::NO_GRANT);
 
   // The function should complete with an error, showing the signin UI only
   // once for the initial signin.
   std::string error = utils::RunFunctionAndReturnError(
       func.get(), "[{\"interactive\": true}]", browser());
-  EXPECT_TRUE(base::StartsWith(error, errors::kAuthFailure,
+  EXPECT_TRUE(base::StartsWith(error, errors::kNoGrant,
                                base::CompareCase::INSENSITIVE_ASCII));
 
   EXPECT_TRUE(func->login_ui_shown());
   EXPECT_TRUE(func->scope_ui_shown());
   histogram_tester()->ExpectUniqueSample(
       kGetAuthTokenResultHistogramName,
-      IdentityGetAuthTokenError::State::kGaiaFlowAuthFailure, 1);
+      IdentityGetAuthTokenError::State::kNoGrant, 1);
 }
 #endif
 
-IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
-                       InteractiveApprovalOAuthErrors) {
-  SignIn("primary@example.com");
-  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
-
-  struct TestCase {
-    std::string oauth_error;
-    std::string error_message;
-    IdentityGetAuthTokenError::State error_state;
-  };
-
-  std::vector<TestCase> test_cases;
-  test_cases.push_back({"access_denied", errors::kUserRejected,
-                        IdentityGetAuthTokenError::State::kOAuth2AccessDenied});
-  test_cases.push_back(
-      {"invalid_scope", errors::kInvalidScopes,
-       IdentityGetAuthTokenError::State::kOAuth2InvalidScopes});
-  test_cases.push_back({"unmapped_error",
-                        std::string(errors::kAuthFailure) + "unmapped_error",
-                        IdentityGetAuthTokenError::State::kOAuth2Failure});
-
-  for (const auto& test_case : test_cases) {
-    base::HistogramTester histogram_tester;
-    scoped_refptr<FakeGetAuthTokenFunction> func(
-        new FakeGetAuthTokenFunction());
-    func->set_extension(extension.get());
-    // Make sure we don't get a cached issue_advice result, which would cause
-    // flow to be leaked.
-    id_api()->token_cache()->EraseAllTokens();
-    func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
-    func->set_scope_ui_oauth_error(test_case.oauth_error);
-    std::string error = utils::RunFunctionAndReturnError(
-        func.get(), "[{\"interactive\": true}]", browser());
-    EXPECT_EQ(test_case.error_message, error);
-    EXPECT_FALSE(func->login_ui_shown());
-    EXPECT_TRUE(func->scope_ui_shown());
-    histogram_tester.ExpectUniqueSample(kGetAuthTokenResultHistogramName,
-                                        test_case.error_state, 1);
-  }
-}
-
 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, InteractiveApprovalSuccess) {
   SignIn("primary@example.com");
   scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(extension.get());
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
+  func->set_remote_consent_gaia_id("gaia_id_for_primary_example.com");
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS);
 
   std::string access_token;
   std::set<std::string> granted_scopes;
@@ -1663,7 +1563,8 @@
 }
 
 #if !defined(OS_MAC)
-// Test for http://crbug.com/753014
+// Test was originally written for http://crbug.com/753014 and subsequently
+// modified to use the remote consent flow.
 //
 // On macOS, closing all browsers does not shut down the browser process.
 // TODO(http://crbug.com/756462): Figure out how to shut down the browser
@@ -1673,9 +1574,8 @@
   SignIn("primary@example.com");
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
-  func->set_scope_ui_service_error(
-      GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
+  func->set_scope_ui_failure(GaiaRemoteConsentFlow::LOAD_FAILED);
   func->set_login_ui_result(false);
 
   // Closing all browsers ensures that the browser process is shutting down.
@@ -1683,12 +1583,8 @@
 
   std::string error = utils::RunFunctionAndReturnError(
       func.get(), "[{\"interactive\": true}]", browser());
-  // Check that the OAuth approval dialog is shown to ensure that the Gaia flow
-  // fails with an |SERVICE_AUTH_ERROR| error (with |INVALID_GAIA_CREDENTIALS|
-  // service error). This reproduces the crash conditions in bug
-  // http://crbug.com/753014.
-  // This condition may be fragile as it depends on the identity manager not
-  // being destroyed before the OAuth approval dialog is shown.
+  // Check that the remote consent dialog is shown to ensure that the remote
+  // consent flow fails.
   EXPECT_TRUE(func->scope_ui_shown());
 
   // The login screen should not be shown when the browser process is shutting
@@ -1696,7 +1592,7 @@
   EXPECT_FALSE(func->login_ui_shown());
   histogram_tester()->ExpectUniqueSample(
       kGetAuthTokenResultHistogramName,
-      IdentityGetAuthTokenError::State::kGaiaFlowAuthFailure, 1);
+      IdentityGetAuthTokenError::State::kRemoteConsentPageLoadFailure, 1);
 }
 #endif  // !defined(OS_MAC)
 
@@ -1754,7 +1650,9 @@
 
   // The real request will start processing, but wait in the queue behind
   // the blocker.
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
+  func->set_remote_consent_gaia_id("gaia_id_for_primary_example.com");
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS);
   RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
   // Verify that we have fetched the login token and run the first flow.
   testing::Mock::VerifyAndClearExpectations(func.get());
@@ -1793,7 +1691,7 @@
 
   // The real request will start processing, but wait in the queue behind
   // the blocker.
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
   RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
   // Verify that we have fetched the login token and run the first flow.
   testing::Mock::VerifyAndClearExpectations(func.get());
@@ -1864,7 +1762,7 @@
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(extension.get());
 
-  // pre-populate the cache with a token
+  // Pre-populate the cache with a token.
   IdentityTokenCacheValue token =
       CreateToken(kAccessToken, base::TimeDelta::FromSeconds(3600));
   SetCachedToken(token);
@@ -1904,7 +1802,7 @@
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(extension.get());
 
-  // pre-populate the cache with a token
+  // Pre-populate the cache with a token.
   IdentityTokenCacheValue token =
       CreateToken(kAccessToken, base::TimeDelta::FromSeconds(3600));
   SetCachedTokenForAccount(account_info, token);
@@ -1935,16 +1833,16 @@
 }
 
 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
-                       NonInteractiveIssueAdviceCacheHit) {
+                       NonInteractiveRemoteConsentCacheHit) {
   SignIn("primary@example.com");
   scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(extension.get());
 
-  // pre-populate the cache with advice
-  IssueAdviceInfo info;
+  // Pre-populate the cache with the remote consent resolution data.
+  RemoteConsentResolutionData resolution_data;
   IdentityTokenCacheValue token =
-      IdentityTokenCacheValue::CreateIssueAdvice(info);
+      IdentityTokenCacheValue::CreateRemoteConsent(resolution_data);
   SetCachedToken(token);
 
   // Should return an error without a GAIA request.
@@ -1958,6 +1856,33 @@
       IdentityGetAuthTokenError::State::kGaiaConsentInteractionRequired, 1);
 }
 
+IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
+                       NonInteractiveRemoteConsentApprovedCacheHit) {
+  SignIn("primary@example.com");
+  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
+  scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
+  func->set_extension(extension.get());
+
+  // Pre-populate the cache with the remote consent approved result.
+  IdentityTokenCacheValue token =
+      IdentityTokenCacheValue::CreateRemoteConsentApproved(std::string());
+  SetCachedToken(token);
+
+  // Get a token. Should not prompt for scopes.
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS);
+  std::string access_token;
+  std::set<std::string> granted_scopes;
+  RunGetAuthTokenFunction(func.get(), "[{}]", browser(), &access_token,
+                          &granted_scopes);
+  EXPECT_EQ(std::string(kAccessToken), access_token);
+  EXPECT_EQ(func->GetExtensionTokenKeyForTest()->scopes, granted_scopes);
+  EXPECT_FALSE(func->login_ui_shown());
+  EXPECT_FALSE(func->scope_ui_shown());
+  histogram_tester()->ExpectUniqueSample(
+      kGetAuthTokenResultHistogramName, IdentityGetAuthTokenError::State::kNone,
+      1);
+}
+
 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, InteractiveCacheHit) {
   SignIn("primary@example.com");
   scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
@@ -1974,7 +1899,7 @@
 
   // The real request will start processing, but wait in the queue behind
   // the blocker.
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
   RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
   base::RunLoop().RunUntilIdle();
 
@@ -2008,7 +1933,7 @@
   scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
   func->set_extension(extension.get());
 
-  // pre-populate the cache with a token
+  // Pre-populate the cache with a token.
   IdentityTokenCacheValue token =
       CreateToken(kAccessToken, base::TimeDelta::FromSeconds(3600));
   SetCachedToken(token);
@@ -2016,7 +1941,10 @@
   // Because the user is not signed in, the token will be removed,
   // and we'll hit GAIA for new tokens.
   func->set_login_ui_result(true);
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
+  // The user signs in with the "secondary@example.com" email.
+  func->set_remote_consent_gaia_id("gaia_id_for_secondary_example.com");
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS);
 
   std::string access_token;
   std::set<std::string> granted_scopes;
@@ -2034,64 +1962,6 @@
 }
 #endif
 
-IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
-                       IssueAdviceInvalidatesGaiaIdCache) {
-  SignIn("primary@example.com");
-  AccountInfo secondary_account_info =
-      identity_test_env()->MakeAccountAvailable("secondary@example.com");
-
-  scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
-  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
-  func->set_extension(extension.get());
-
-  // Pre-populate the gaia id cache.
-  SetCachedGaiaId(secondary_account_info.gaia);
-
-  // The user revoked their token and must give a consent again. Gaia disabled
-  // the new flow for the secondary account.
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
-
-  std::string access_token;
-  std::set<std::string> granted_scopes;
-  RunGetAuthTokenFunction(func.get(), "[{\"interactive\": true}]", browser(),
-                          &access_token, &granted_scopes);
-  EXPECT_EQ(std::string(kAccessToken), access_token);
-  EXPECT_EQ(func->GetExtensionTokenKeyForTest()->scopes, granted_scopes);
-  EXPECT_TRUE(func->scope_ui_shown());
-  EXPECT_FALSE(GetCachedGaiaId().has_value());
-  histogram_tester()->ExpectUniqueSample(
-      kGetAuthTokenResultHistogramName, IdentityGetAuthTokenError::State::kNone,
-      1);
-}
-
-IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
-                       IssueAdviceFailureInvalidatesGaiaIdCache) {
-  SignIn("primary@example.com");
-  AccountInfo secondary_account_info =
-      identity_test_env()->MakeAccountAvailable("secondary@example.com");
-
-  scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
-  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
-  func->set_extension(extension.get());
-
-  // Pre-populate the gaia id cache.
-  SetCachedGaiaId(secondary_account_info.gaia);
-
-  // The user revoked their token and must give a consent again. Gaia disabled
-  // the new flow for the secondary account.
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
-  func->set_scope_ui_failure(GaiaWebAuthFlow::WINDOW_CLOSED);
-
-  std::string error = utils::RunFunctionAndReturnError(
-      func.get(), "[{\"interactive\": true}]", browser());
-  EXPECT_EQ(std::string(errors::kUserRejected), error);
-  EXPECT_TRUE(func->scope_ui_shown());
-  EXPECT_FALSE(GetCachedGaiaId().has_value());
-  histogram_tester()->ExpectUniqueSample(
-      kGetAuthTokenResultHistogramName,
-      IdentityGetAuthTokenError::State::kGaiaFlowRejected, 1);
-}
-
 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ComponentWithChromeClientId) {
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->ignore_did_respond_for_testing();
@@ -2443,8 +2313,8 @@
 
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
-  func->set_scope_ui_failure(GaiaWebAuthFlow::WINDOW_CLOSED);
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
+  func->set_scope_ui_failure(GaiaRemoteConsentFlow::WINDOW_CLOSED);
   std::string error = utils::RunFunctionAndReturnError(
       func.get(),
       "[{\"account\": { \"id\": \"gaia_id_for_secondary_example.com\" }, "
@@ -2455,7 +2325,7 @@
   EXPECT_TRUE(func->scope_ui_shown());
   histogram_tester()->ExpectUniqueSample(
       kGetAuthTokenResultHistogramName,
-      IdentityGetAuthTokenError::State::kGaiaFlowRejected, 1);
+      IdentityGetAuthTokenError::State::kRemoteConsentFlowRejected, 1);
 }
 
 // Tests that Chrome remembers user's choice of an account at the end of the
@@ -2700,7 +2570,9 @@
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
   func->set_extension(extension.get());
   func->set_login_ui_result(true);
-  func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS);
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::REMOTE_CONSENT_SUCCESS);
+  func->set_remote_consent_gaia_id(secondary_account.account_id.ToString());
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS);
 
   const char kFunctionParams[] =
       "[{\"account\": { \"id\": \"gaia_id_for_secondary@example.com\" }, "
@@ -3243,13 +3115,13 @@
             GetCachedToken().status());
 }
 
-IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, Advice) {
-  IssueAdviceInfo info;
+IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, RemoteConsent) {
+  RemoteConsentResolutionData resolution_data;
   IdentityTokenCacheValue advice =
-      IdentityTokenCacheValue::CreateIssueAdvice(info);
+      IdentityTokenCacheValue::CreateRemoteConsent(resolution_data);
   SetCachedToken(advice);
   EXPECT_TRUE(InvalidateDefaultToken());
-  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_ADVICE,
+  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_REMOTE_CONSENT,
             GetCachedToken().status());
 }
 
diff --git a/chrome/browser/extensions/api/identity/identity_constants.cc b/chrome/browser/extensions/api/identity/identity_constants.cc
index 97983c6..b094a01 100644
--- a/chrome/browser/extensions/api/identity/identity_constants.cc
+++ b/chrome/browser/extensions/api/identity/identity_constants.cc
@@ -23,7 +23,7 @@
 const char kInvalidConsentResult[] = "Returned an invalid consent result.";
 const char kCanceled[] = "canceled";
 
-const int kCachedIssueAdviceTTLSeconds = 1;
+const int kCachedRemoteConsentTTLSeconds = 1;
 }  // namespace identity_constants
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/identity/identity_constants.h b/chrome/browser/extensions/api/identity/identity_constants.h
index 3c05a8a..e23ddd4 100644
--- a/chrome/browser/extensions/api/identity/identity_constants.h
+++ b/chrome/browser/extensions/api/identity/identity_constants.h
@@ -24,7 +24,7 @@
 extern const char kInvalidConsentResult[];
 extern const char kCanceled[];
 
-extern const int kCachedIssueAdviceTTLSeconds;
+extern const int kCachedRemoteConsentTTLSeconds;
 }  // namespace identity_constants
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_error.cc b/chrome/browser/extensions/api/identity/identity_get_auth_token_error.cc
index c2028c8..e89fc9e 100644
--- a/chrome/browser/extensions/api/identity/identity_get_auth_token_error.cc
+++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_error.cc
@@ -10,12 +10,6 @@
 namespace extensions {
 
 // static
-IdentityGetAuthTokenError IdentityGetAuthTokenError::FromGaiaFlowAuthError(
-    base::StringPiece error_message) {
-  return IdentityGetAuthTokenError(State::kGaiaFlowAuthFailure, error_message);
-}
-
-// static
 IdentityGetAuthTokenError IdentityGetAuthTokenError::FromMintTokenAuthError(
     base::StringPiece error_message) {
   return IdentityGetAuthTokenError(State::kMintTokenAuthFailure, error_message);
@@ -29,24 +23,6 @@
                                    error_message);
 }
 
-// static
-IdentityGetAuthTokenError IdentityGetAuthTokenError::FromOAuth2Error(
-    base::StringPiece oauth2_error) {
-  const char kOAuth2ErrorAccessDenied[] = "access_denied";
-  const char kOAuth2ErrorInvalidScope[] = "invalid_scope";
-
-  if (oauth2_error == kOAuth2ErrorAccessDenied) {
-    return IdentityGetAuthTokenError(
-        IdentityGetAuthTokenError::State::kOAuth2AccessDenied);
-  } else if (oauth2_error == kOAuth2ErrorInvalidScope) {
-    return IdentityGetAuthTokenError(
-        IdentityGetAuthTokenError::State::kOAuth2InvalidScopes);
-  } else {
-    return IdentityGetAuthTokenError(
-        IdentityGetAuthTokenError::State::kOAuth2Failure, oauth2_error);
-  }
-}
-
 IdentityGetAuthTokenError::IdentityGetAuthTokenError()
     : IdentityGetAuthTokenError(State::kNone) {}
 
@@ -64,19 +40,14 @@
     case State::kInvalidClientId:
       return identity_constants::kInvalidClientId;
     case State::kEmptyScopes:
-    case State::kOAuth2InvalidScopes:
       return identity_constants::kInvalidScopes;
-    case State::kGaiaFlowAuthFailure:
     case State::kMintTokenAuthFailure:
     case State::kGetAccessTokenAuthFailure:
-    case State::kOAuth2Failure:
       return identity_constants::kAuthFailure + error_message_;
     case State::kNoGrant:
     case State::kGaiaConsentInteractionRequired:
     case State::kGaiaConsentInteractionAlreadyRunning:
       return identity_constants::kNoGrant;
-    case State::kOAuth2AccessDenied:
-    case State::kGaiaFlowRejected:
     case State::kRemoteConsentFlowRejected:
       return identity_constants::kUserRejected;
     case State::kUserNotSignedIn:
@@ -89,11 +60,8 @@
       return identity_constants::kUserNonPrimary;
     case State::kBrowserSigninNotAllowed:
       return identity_constants::kBrowserSigninNotAllowed;
-    case State::kInvalidRedirect:
-      return identity_constants::kInvalidRedirect;
     case State::kOffTheRecord:
       return identity_constants::kOffTheRecord;
-    case State::kPageLoadFailure:
     case State::kRemoteConsentPageLoadFailure:
       return identity_constants::kPageLoadFailure;
     case State::kSetAccountsInCookieFailure:
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_error.h b/chrome/browser/extensions/api/identity/identity_get_auth_token_error.h
index e72554b..d6735dc 100644
--- a/chrome/browser/extensions/api/identity/identity_get_auth_token_error.h
+++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_error.h
@@ -19,16 +19,16 @@
     kNone = 0,
     kInvalidClientId = 1,
     kEmptyScopes = 2,
-    kOAuth2InvalidScopes = 3,
-    kGaiaFlowAuthFailure = 4,
+    // kOAuth2InvalidScopes = 3,  // Deprecated
+    // kGaiaFlowAuthFailure = 4,  // Deprecated
     kMintTokenAuthFailure = 5,
     kGetAccessTokenAuthFailure = 6,
-    kOAuth2Failure = 7,
+    // kOAuth2Failure = 7,  // Deprecated
     kNoGrant = 8,
     kGaiaConsentInteractionRequired = 9,
     kGaiaConsentInteractionAlreadyRunning = 10,
-    kOAuth2AccessDenied = 11,
-    kGaiaFlowRejected = 12,
+    // kOAuth2AccessDenied = 11,  // Deprecated
+    // kGaiaFlowRejected = 12,  // Deprecated
     kRemoteConsentFlowRejected = 13,
     kUserNotSignedIn = 14,
     kNotAllowlistedInPublicSession = 15,
@@ -37,9 +37,9 @@
     kUserNonPrimary = 18,
     kRemoteConsentUserNonPrimary = 19,
     kBrowserSigninNotAllowed = 20,
-    kInvalidRedirect = 21,
+    // kInvalidRedirect = 21,  // Deprecated
     kOffTheRecord = 22,
-    kPageLoadFailure = 23,
+    // kPageLoadFailure = 23,  // Deprecated
     kRemoteConsentPageLoadFailure = 24,
     kSetAccountsInCookieFailure = 25,
     kInvalidConsentResult = 26,
@@ -47,10 +47,6 @@
     kMaxValue = kCanceled,
   };
 
-  // Constructs a |State::kGaiaFlowAuthFailure| error with an |error_message|.
-  static IdentityGetAuthTokenError FromGaiaFlowAuthError(
-      base::StringPiece error_message);
-
   // Constructs a |State::kMintTokenAuthFailure| error with an
   // |error_message|.
   static IdentityGetAuthTokenError FromMintTokenAuthError(
@@ -61,10 +57,6 @@
   static IdentityGetAuthTokenError FromGetAccessTokenAuthError(
       base::StringPiece error_message);
 
-  // Constructs an IdentityGetAuthTokenError from |oauth2_error|.
-  static IdentityGetAuthTokenError FromOAuth2Error(
-      base::StringPiece oauth2_error);
-
   // Constructs a |State::kNone| error.
   IdentityGetAuthTokenError();
 
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
index f5721ae4..89dd0ed2 100644
--- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
+++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
@@ -39,6 +39,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "extensions/common/extension_features.h"
 #include "extensions/common/extension_l10n_util.h"
+#include "extensions/common/manifest_handlers/oauth2_manifest_handler.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 #include "google_apis/gaia/gaia_urls.h"
 
@@ -516,13 +517,6 @@
                                    cache_entry.granted_scopes());
         break;
 
-      case IdentityTokenCacheValue::CACHE_STATUS_ADVICE:
-        CompleteMintTokenFlow();
-        should_prompt_for_signin_ = false;
-        issue_advice_ = cache_entry.issue_advice();
-        StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE);
-        break;
-
       case IdentityTokenCacheValue::CACHE_STATUS_REMOTE_CONSENT:
         CompleteMintTokenFlow();
         should_prompt_for_signin_ = false;
@@ -547,9 +541,6 @@
                                    cache_entry.granted_scopes());
         break;
       case IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND:
-      case IdentityTokenCacheValue::CACHE_STATUS_ADVICE:
-        ShowOAuthApprovalDialog(issue_advice_);
-        break;
       case IdentityTokenCacheValue::CACHE_STATUS_REMOTE_CONSENT:
         ShowRemoteConsentDialog(resolution_data_);
         break;
@@ -608,27 +599,6 @@
       IdentityGetAuthTokenError::FromMintTokenAuthError(error.ToString()));
 }
 
-void IdentityGetAuthTokenFunction::OnIssueAdviceSuccess(
-    const IssueAdviceInfo& issue_advice) {
-  TRACE_EVENT_NESTABLE_ASYNC_INSTANT0("identity", "OnIssueAdviceSuccess", this);
-
-  IdentityAPI* identity_api =
-      IdentityAPI::GetFactoryInstance()->Get(GetProfile());
-  identity_api->token_cache()->SetToken(
-      token_key_, IdentityTokenCacheValue::CreateIssueAdvice(issue_advice));
-  // IssueAdvice doesn't communicate back to Chrome which account has been
-  // chosen by the user. Cached gaia id may contain incorrect information so
-  // it's better to remove it.
-  identity_api->EraseGaiaIdForExtension(token_key_.extension_id);
-  CompleteMintTokenFlow();
-
-  should_prompt_for_signin_ = false;
-  // Existing grant was revoked and we used NO_FORCE, so we got info back
-  // instead. Start a consent UI if we can.
-  issue_advice_ = issue_advice;
-  StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE);
-}
-
 void IdentityGetAuthTokenFunction::OnRemoteConsentSuccess(
     const RemoteConsentResolutionData& resolution_data) {
   TRACE_EVENT_NESTABLE_ASYNC_INSTANT0("identity", "OnRemoteConsentSuccess",
@@ -709,70 +679,6 @@
       IdentityGetAuthTokenError::State::kSignInFailed));
 }
 
-void IdentityGetAuthTokenFunction::OnGaiaFlowFailure(
-    GaiaWebAuthFlow::Failure failure,
-    GoogleServiceAuthError service_error,
-    const std::string& oauth_error) {
-  CompleteMintTokenFlow();
-  IdentityGetAuthTokenError error;
-
-  switch (failure) {
-    case GaiaWebAuthFlow::WINDOW_CLOSED:
-      error = IdentityGetAuthTokenError(
-          IdentityGetAuthTokenError::State::kGaiaFlowRejected);
-      break;
-
-    case GaiaWebAuthFlow::INVALID_REDIRECT:
-      error = IdentityGetAuthTokenError(
-          IdentityGetAuthTokenError::State::kInvalidRedirect);
-      break;
-
-    case GaiaWebAuthFlow::SERVICE_AUTH_ERROR:
-      if (TryRecoverFromServiceAuthError(service_error)) {
-        return;
-      }
-      error = IdentityGetAuthTokenError::FromGaiaFlowAuthError(
-          service_error.ToString());
-      break;
-
-    case GaiaWebAuthFlow::OAUTH_ERROR:
-      error = IdentityGetAuthTokenError::FromOAuth2Error(oauth_error);
-      break;
-
-    case GaiaWebAuthFlow::LOAD_FAILED:
-      error = IdentityGetAuthTokenError(
-          IdentityGetAuthTokenError::State::kPageLoadFailure);
-      break;
-
-    default:
-      NOTREACHED() << "Unexpected error from gaia web auth flow: " << failure;
-      error = IdentityGetAuthTokenError(
-          IdentityGetAuthTokenError::State::kInvalidRedirect);
-      break;
-  }
-
-  CompleteFunctionWithError(error);
-}
-
-void IdentityGetAuthTokenFunction::OnGaiaFlowCompleted(
-    const std::string& access_token,
-    const std::string& expiration) {
-  TRACE_EVENT_NESTABLE_ASYNC_INSTANT0("identity", "OnGaiaFlowCompleted", this);
-  int time_to_live;
-  if (!expiration.empty() && base::StringToInt(expiration, &time_to_live)) {
-    IdentityTokenCacheValue token_value = IdentityTokenCacheValue::CreateToken(
-        access_token, token_key_.scopes,
-        base::TimeDelta::FromSeconds(time_to_live));
-    IdentityAPI::GetFactoryInstance()
-        ->Get(GetProfile())
-        ->token_cache()
-        ->SetToken(token_key_, token_value);
-  }
-
-  CompleteMintTokenFlow();
-  CompleteFunctionWithResult(access_token, token_key_.scopes);
-}
-
 void IdentityGetAuthTokenFunction::OnGaiaRemoteConsentFlowFailed(
     GaiaRemoteConsentFlow::Failure failure) {
   CompleteMintTokenFlow();
@@ -919,7 +825,6 @@
 }
 
 void IdentityGetAuthTokenFunction::OnIdentityAPIShutdown() {
-  gaia_web_auth_flow_.reset();
   device_access_token_request_.reset();
   token_key_account_access_token_fetcher_.reset();
   scoped_identity_manager_observer_.RemoveAll();
@@ -1017,15 +922,6 @@
                                              email_hint);
 }
 
-void IdentityGetAuthTokenFunction::ShowOAuthApprovalDialog(
-    const IssueAdviceInfo& issue_advice) {
-  const std::string locale = extension_l10n_util::CurrentLocaleOrDefault();
-
-  gaia_web_auth_flow_.reset(new GaiaWebAuthFlow(this, GetProfile(), &token_key_,
-                                                oauth2_client_id_, locale));
-  gaia_web_auth_flow_->Start();
-}
-
 void IdentityGetAuthTokenFunction::ShowRemoteConsentDialog(
     const RemoteConsentResolutionData& resolution_data) {
   gaia_remote_consent_flow_ = std::make_unique<GaiaRemoteConsentFlow>(
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h
index ef9fe82..dc6e5138 100644
--- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h
+++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h
@@ -15,7 +15,6 @@
 #include "base/scoped_observer.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/extensions/api/identity/gaia_remote_consent_flow.h"
-#include "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h"
 #include "chrome/browser/extensions/api/identity/identity_mint_queue.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "extensions/browser/extension_function.h"
@@ -50,7 +49,6 @@
 // new login token, there is a sign-in flow. If that flow completes
 // successfully, getAuthToken proceeds to the non-interactive flow.
 class IdentityGetAuthTokenFunction : public ExtensionFunction,
-                                     public GaiaWebAuthFlow::Delegate,
                                      public GaiaRemoteConsentFlow::Delegate,
                                      public IdentityMintRequestQueue::Request,
                                      public signin::IdentityManager::Observer,
@@ -73,13 +71,6 @@
 
   void SigninFailed();
 
-  // GaiaWebAuthFlow::Delegate implementation:
-  void OnGaiaFlowFailure(GaiaWebAuthFlow::Failure failure,
-                         GoogleServiceAuthError service_error,
-                         const std::string& oauth_error) override;
-  void OnGaiaFlowCompleted(const std::string& access_token,
-                           const std::string& expiration) override;
-
   // GaiaRemoteConsentFlow::Delegate implementation:
   void OnGaiaRemoteConsentFlowFailed(
       GaiaRemoteConsentFlow::Failure failure) override;
@@ -199,7 +190,6 @@
                           const std::set<std::string>& granted_scopes,
                           int time_to_live) override;
   void OnMintTokenFailure(const GoogleServiceAuthError& error) override;
-  void OnIssueAdviceSuccess(const IssueAdviceInfo& issue_advice) override;
   void OnRemoteConsentSuccess(
       const RemoteConsentResolutionData& resolution_data) override;
 
@@ -215,7 +205,6 @@
 
   // Methods for invoking UI. Overridable for testing.
   virtual void ShowExtensionLoginPrompt();
-  virtual void ShowOAuthApprovalDialog(const IssueAdviceInfo& issue_advice);
   virtual void ShowRemoteConsentDialog(
       const RemoteConsentResolutionData& resolution_data);
 
@@ -248,9 +237,6 @@
   std::string oauth2_client_id_;
   // When launched in interactive mode, and if there is no existing grant,
   // a permissions prompt will be popped up to the user.
-  IssueAdviceInfo issue_advice_;
-  std::unique_ptr<GaiaWebAuthFlow> gaia_web_auth_flow_;
-  // The browser resolution consent flow.
   RemoteConsentResolutionData resolution_data_;
   std::unique_ptr<GaiaRemoteConsentFlow> gaia_remote_consent_flow_;
   std::string consent_result_;
diff --git a/chrome/browser/extensions/api/identity/identity_token_cache.cc b/chrome/browser/extensions/api/identity/identity_token_cache.cc
index 83530f6..2d68024 100644
--- a/chrome/browser/extensions/api/identity/identity_token_cache.cc
+++ b/chrome/browser/extensions/api/identity/identity_token_cache.cc
@@ -20,26 +20,15 @@
 IdentityTokenCacheValue::~IdentityTokenCacheValue() = default;
 
 // static
-IdentityTokenCacheValue IdentityTokenCacheValue::CreateIssueAdvice(
-    const IssueAdviceInfo& issue_advice) {
-  IdentityTokenCacheValue cache_value;
-  cache_value.status_ = CACHE_STATUS_ADVICE;
-  cache_value.issue_advice_ = issue_advice;
-  cache_value.expiration_time_ =
-      base::Time::Now() + base::TimeDelta::FromSeconds(
-                              identity_constants::kCachedIssueAdviceTTLSeconds);
-  return cache_value;
-}
-
-// static
 IdentityTokenCacheValue IdentityTokenCacheValue::CreateRemoteConsent(
     const RemoteConsentResolutionData& resolution_data) {
   IdentityTokenCacheValue cache_value;
   cache_value.status_ = CACHE_STATUS_REMOTE_CONSENT;
   cache_value.resolution_data_ = resolution_data;
   cache_value.expiration_time_ =
-      base::Time::Now() + base::TimeDelta::FromSeconds(
-                              identity_constants::kCachedIssueAdviceTTLSeconds);
+      base::Time::Now() +
+      base::TimeDelta::FromSeconds(
+          identity_constants::kCachedRemoteConsentTTLSeconds);
   return cache_value;
 }
 
@@ -50,8 +39,9 @@
   cache_value.status_ = CACHE_STATUS_REMOTE_CONSENT_APPROVED;
   cache_value.consent_result_ = consent_result;
   cache_value.expiration_time_ =
-      base::Time::Now() + base::TimeDelta::FromSeconds(
-                              identity_constants::kCachedIssueAdviceTTLSeconds);
+      base::Time::Now() +
+      base::TimeDelta::FromSeconds(
+          identity_constants::kCachedRemoteConsentTTLSeconds);
   return cache_value;
 }
 
@@ -96,10 +86,6 @@
   return expiration_time_;
 }
 
-const IssueAdviceInfo& IdentityTokenCacheValue::issue_advice() const {
-  return issue_advice_;
-}
-
 const RemoteConsentResolutionData& IdentityTokenCacheValue::resolution_data()
     const {
   return resolution_data_;
diff --git a/chrome/browser/extensions/api/identity/identity_token_cache.h b/chrome/browser/extensions/api/identity/identity_token_cache.h
index 1662baee..f858174 100644
--- a/chrome/browser/extensions/api/identity/identity_token_cache.h
+++ b/chrome/browser/extensions/api/identity/identity_token_cache.h
@@ -22,8 +22,6 @@
   IdentityTokenCacheValue& operator=(const IdentityTokenCacheValue& other);
   ~IdentityTokenCacheValue();
 
-  static IdentityTokenCacheValue CreateIssueAdvice(
-      const IssueAdviceInfo& issue_advice);
   static IdentityTokenCacheValue CreateRemoteConsent(
       const RemoteConsentResolutionData& resolution_data);
   static IdentityTokenCacheValue CreateRemoteConsentApproved(
@@ -37,7 +35,6 @@
   // entries supersede older ones in SetCachedToken.
   enum CacheValueStatus {
     CACHE_STATUS_NOTFOUND,
-    CACHE_STATUS_ADVICE,
     CACHE_STATUS_REMOTE_CONSENT,
     CACHE_STATUS_REMOTE_CONSENT_APPROVED,
     CACHE_STATUS_TOKEN
@@ -46,7 +43,6 @@
   CacheValueStatus status() const;
   const base::Time& expiration_time() const;
 
-  const IssueAdviceInfo& issue_advice() const;
   const RemoteConsentResolutionData& resolution_data() const;
   const std::string& consent_result() const;
   const std::string& token() const;
@@ -60,7 +56,6 @@
 
   // TODO(alexilin): This class holds at any given time one of the several
   // possible types. Consider rewriting using absl::variant
-  IssueAdviceInfo issue_advice_;
   RemoteConsentResolutionData resolution_data_;
   std::string consent_result_;
   std::string token_;
diff --git a/chrome/browser/extensions/default_apps_browsertest.cc b/chrome/browser/extensions/default_apps_browsertest.cc
index 970b35b9..68cecbdb 100644
--- a/chrome/browser/extensions/default_apps_browsertest.cc
+++ b/chrome/browser/extensions/default_apps_browsertest.cc
@@ -11,6 +11,7 @@
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/scoped_path_override.h"
+#include "build/branding_buildflags.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/pending_extension_manager.h"
 #include "chrome/browser/web_applications/components/external_app_install_features.h"
@@ -91,10 +92,19 @@
             ->extension_service()
             ->pending_extension_manager();
 
-    // Wait for any pending extension installations to finish.
-    while (pending_manager->HasPendingExtensions()) {
+    // If the test extension is still pending, wait for it to finish.
+    if (pending_manager->IsIdPending(kDefaultInstalledId)) {
       TestExtensionRegistryObserver(registry()).WaitForExtensionInstalled();
     }
+
+    // In Chromium builds, there shouldn't be any other pending extensions.
+    // In Google Chrome, we don't have this assertion, because we bundle a
+    // couple other default extensions (like the Chrome Apps In-Apps Payment
+    // app, or Chrome Media Router). These will never install, since they rely
+    // on being downloaded (which can't happen in browser tests).
+#if !BUILDFLAG(GOOGLE_CHROME_BRANDING)
+    EXPECT_FALSE(pending_manager->HasPendingExtensions());
+#endif
   }
 
   virtual bool ShouldEnableWebAppMigration() { return false; }
diff --git a/chrome/browser/extensions/extension_system_impl.cc b/chrome/browser/extensions/extension_system_impl.cc
index c9451146..22a91233 100644
--- a/chrome/browser/extensions/extension_system_impl.cc
+++ b/chrome/browser/extensions/extension_system_impl.cc
@@ -57,7 +57,7 @@
 #include "extensions/browser/runtime_data.h"
 #include "extensions/browser/service_worker_manager.h"
 #include "extensions/browser/state_store.h"
-#include "extensions/browser/uninstall_ping_sender.h"
+#include "extensions/browser/updater/uninstall_ping_sender.h"
 #include "extensions/browser/value_store/value_store_factory_impl.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/features/feature_channel.h"
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc b/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc
index 1c0b5b9..e10b587 100644
--- a/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc
+++ b/chrome/browser/extensions/forced_extensions/force_installed_metrics.cc
@@ -229,7 +229,7 @@
   }
   if (installation.unpacker_failure_reason) {
     base::UmaHistogramEnumeration(
-        "Extensions.ForceInstalledFailureSandboxUnpackFailureReason",
+        "Extensions.ForceInstalledFailureSandboxUnpackFailureReason2",
         installation.unpacker_failure_reason.value(),
         SandboxedUnpackerFailureReason::NUM_FAILURE_REASONS);
   }
diff --git a/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc b/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc
index 002968e..b8dc4aad 100644
--- a/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc
+++ b/chrome/browser/extensions/forced_extensions/force_installed_metrics_unittest.cc
@@ -90,7 +90,7 @@
 constexpr char kFetchRetriesManifestFetchFailedStats[] =
     "Extensions.ForceInstalledManifestFetchFailedFetchTries";
 constexpr char kSandboxUnpackFailureReason[] =
-    "Extensions.ForceInstalledFailureSandboxUnpackFailureReason";
+    "Extensions.ForceInstalledFailureSandboxUnpackFailureReason2";
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 constexpr char kFailureSessionStats[] =
     "Extensions.ForceInstalledFailureSessionType";
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index 26d82bbf..0819490 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -609,7 +609,7 @@
     "TabEngagementReportingAndroid", base::FEATURE_DISABLED_BY_DEFAULT};
 
 const base::Feature kTabGroupsAndroid{"TabGroupsAndroid",
-                                      base::FEATURE_DISABLED_BY_DEFAULT};
+                                      base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kTabGroupsContinuationAndroid{
     "TabGroupsContinuationAndroid", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -618,7 +618,7 @@
     "TabGroupsUiImprovementsAndroid", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kTabGridLayoutAndroid{"TabGridLayoutAndroid",
-                                          base::FEATURE_DISABLED_BY_DEFAULT};
+                                          base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kTabReparenting{"TabReparenting",
                                     base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/google/google_brand_code_map_chromeos.cc b/chrome/browser/google/google_brand_code_map_chromeos.cc
index b395600..df4af27 100644
--- a/chrome/browser/google/google_brand_code_map_chromeos.cc
+++ b/chrome/browser/google/google_brand_code_map_chromeos.cc
@@ -146,6 +146,7 @@
                      {"HFKU", {"ILOF", "UXKA", "JQLI"}},
                      {"HFRG", {"YGYA", "IWET", "PSFN"}},
                      {"HHRN", {"IGZW", "ICRP", "QQKJ"}},
+                     {"HIER", {"ZXKC", "BJFL", "PUBL"}},
                      {"HKGT", {"EBMG", "KDZJ", "MELG"}},
                      {"HOMH", {"BXHI", "WXYD", "VRZY"}},
                      {"HOWM", {"MJNG", "XPYN", "IRWY"}},
@@ -176,7 +177,9 @@
                      {"IXMM", {"DIJU", "LAUW", "XHLQ"}},
                      {"JBPA", {"VUZL", "XYPI", "XOWE"}},
                      {"JFZB", {"PFDC", "XJDX", "CPXX"}},
+                     {"JGVE", {"DBVB", "YATF", "XFBR"}},
                      {"JICX", {"GUZK", "TIZA", "HTUW"}},
+                     {"JLGJ", {"HAZJ", "KSWW", "QCYN"}},
                      {"JLOF", {"IWFR", "CJHY", "DOPK"}},
                      {"JLRH", {"SAMJ", "GLJZ", "SKTN"}},
                      {"JOTV", {"QBNM", "NMWE", "IDTV"}},
@@ -308,6 +311,7 @@
                      {"PRYU", {"QFZV", "TZXL", "EPRT"}},
                      {"PWFL", {"WGJQ", "KMBF", "UKJV"}},
                      {"PXDO", {"ZXCF", "TQWC", "HOAL"}},
+                     {"QACT", {"YQSO", "OFRB", "HGQL"}},
                      {"QAPN", {"EMNZ", "SJTH", "HJKU"}},
                      {"QBJC", {"WAQG", "MSEN", "FQYE"}},
                      {"QBTA", {"UDQV", "UIZV", "SGMN"}},
@@ -320,6 +324,7 @@
                      {"QQFU", {"ZUKV", "QBAU", "SIID"}},
                      {"QSIM", {"ZCML", "LEPJ", "QQEM"}},
                      {"QTMI", {"YMOW", "FZIR", "YKGT"}},
+                     {"QVKE", {"FIQU", "CVOM", "LPVD"}},
                      {"QYGU", {"FYBR", "QLFJ", "OLRV"}},
                      {"QZUX", {"HNBM", "BUJY", "FFDE"}},
                      {"RGDH", {"YWKM", "ZBAR", "RMQQ"}},
@@ -330,6 +335,7 @@
                      {"RLGE", {"NTKV", "LOTA", "MJVG"}},
                      {"RVRM", {"MZJU", "IGXP", "DSJP"}},
                      {"RXGN", {"WHNA", "DWVK", "FRWP"}},
+                     {"RYMB", {"ZITN", "TMGX", "HVCV"}},
                      {"SBGV", {"ZNIN", "ZVZV", "BPJY"}},
                      {"SHAN", {"OERN", "XNHK", "GVYX"}},
                      {"SKIW", {"CLPF", "OTYY", "ZJVP"}},
@@ -351,6 +357,7 @@
                      {"TAAB", {"ZBMY", "NYDT", "CXYZ"}},
                      {"TAAC", {"YBVP", "RXXN", "HMDY"}},
                      {"TFIY", {"RVUF", "DHKE", "GFPK"}},
+                     {"THNQ", {"XMVV", "RUHW", "WWLP"}},
                      {"TJKH", {"ZHMG", "RBXM", "VIVU"}},
                      {"TKER", {"KOSM", "IUCL", "LIIM"}},
                      {"TKZT", {"KWCM", "APLN", "STGO"}},
@@ -372,6 +379,7 @@
                      {"VGYW", {"AAXS", "SHZF", "HYJU"}},
                      {"VHUH", {"JYDF", "SFJY", "JMBU"}},
                      {"VICR", {"VNCX", "OLSV", "YCZO"}},
+                     {"VJVS", {"BVOQ", "KREV", "QRKT"}},
                      {"VRWC", {"OGMF", "GYJX", "NOBB"}},
                      {"VVUC", {"WQCU", "YUMW", "YHYC"}},
                      {"VYRC", {"VKSO", "NKTO", "ZPZX"}},
@@ -380,6 +388,7 @@
                      {"WCLL", {"DALK", "WPRA", "TPTP"}},
                      {"WFIQ", {"KKHX", "UTHS", "HDSP"}},
                      {"WJOZ", {"BASQ", "BRTL", "CQAV"}},
+                     {"WMPI", {"POXG", "VCJD", "WEGX"}},
                      {"WMVU", {"GMMR", "AVVS", "IMDF"}},
                      {"WNNA", {"ERXU", "TWMI", "ZOER"}},
                      {"WVRW", {"GJGN", "QQFA", "AGVP"}},
@@ -406,8 +415,10 @@
                      {"YVRQ", {"LBMS", "AKKB", "UFNF"}},
                      {"YXBK", {"VKAU", "HUNQ", "AFRP"}},
                      {"YXED", {"KDUD", "MTUI", "WLHI"}},
+                     {"YXMK", {"ZUSE", "TZFU", "DVKA"}},
                      {"ZBCF", {"BDTW", "MIQF", "VUNL"}},
                      {"ZDKS", {"UBRP", "AWQF", "GOVG"}},
+                     {"ZDYJ", {"JNGY", "SDRU", "YIEW"}},
                      {"ZFCZ", {"JQUA", "SEEH", "RJVV"}},
                      {"ZHKO", {"PEIC", "UYOS", "NVYS"}},
                      {"ZIWS", {"GSAE", "JJUF", "ZPRA"}},
diff --git a/chrome/browser/installable/installable_manager_browsertest.cc b/chrome/browser/installable/installable_manager_browsertest.cc
index da85be5e..fb599b5 100644
--- a/chrome/browser/installable/installable_manager_browsertest.cc
+++ b/chrome/browser/installable/installable_manager_browsertest.cc
@@ -139,8 +139,7 @@
   void OnDidFinishInstallableCheck(const InstallableData& data) {
     errors_ = data.errors;
     manifest_url_ = data.manifest_url;
-    if (data.manifest)
-      manifest_ = *data.manifest;
+    manifest_ = data.manifest;
     primary_icon_url_ = data.primary_icon_url;
     if (data.primary_icon)
       primary_icon_.reset(new SkBitmap(*data.primary_icon));
@@ -196,7 +195,7 @@
   void OnDidFinishFirstCheck(const InstallableData& data) {
     errors_ = data.errors;
     manifest_url_ = data.manifest_url;
-    manifest_ = *data.manifest;
+    manifest_ = data.manifest;
     primary_icon_url_ = data.primary_icon_url;
     if (data.primary_icon)
       primary_icon_.reset(new SkBitmap(*data.primary_icon));
@@ -215,12 +214,12 @@
     EXPECT_EQ(primary_icon_.get(), data.primary_icon);
     EXPECT_EQ(valid_manifest_, data.valid_manifest);
     EXPECT_EQ(has_worker_, data.has_worker);
-    EXPECT_EQ(manifest_.IsEmpty(), data.manifest->IsEmpty());
-    EXPECT_EQ(manifest_.start_url, data.manifest->start_url);
-    EXPECT_EQ(manifest_.display, data.manifest->display);
-    EXPECT_EQ(manifest_.name, data.manifest->name);
-    EXPECT_EQ(manifest_.short_name, data.manifest->short_name);
-    EXPECT_EQ(manifest_.display_override, data.manifest->display_override);
+    EXPECT_EQ(manifest_.IsEmpty(), data.manifest.IsEmpty());
+    EXPECT_EQ(manifest_.start_url, data.manifest.start_url);
+    EXPECT_EQ(manifest_.display, data.manifest.display);
+    EXPECT_EQ(manifest_.name, data.manifest.name);
+    EXPECT_EQ(manifest_.short_name, data.manifest.short_name);
+    EXPECT_EQ(manifest_.display_override, data.manifest.display_override);
 
     std::move(quit_closure_).Run();
   }
diff --git a/chrome/browser/long_screenshots/long_screenshots_tab_service_unittest.cc b/chrome/browser/long_screenshots/long_screenshots_tab_service_unittest.cc
index 3d274d7..29f6d8a 100644
--- a/chrome/browser/long_screenshots/long_screenshots_tab_service_unittest.cc
+++ b/chrome/browser/long_screenshots/long_screenshots_tab_service_unittest.cc
@@ -53,6 +53,7 @@
   }
 
   void BindRequest(mojo::ScopedInterfaceEndpointHandle handle) {
+    binding_.reset();
     binding_.Bind(
         mojo::PendingAssociatedReceiver<
             paint_preview::mojom::PaintPreviewRecorder>(std::move(handle)));
diff --git a/chrome/browser/media/router/media_router_feature.cc b/chrome/browser/media/router/media_router_feature.cc
index 4875422..ad3b493 100644
--- a/chrome/browser/media/router/media_router_feature.cc
+++ b/chrome/browser/media/router/media_router_feature.cc
@@ -33,18 +33,13 @@
 namespace media_router {
 
 #if !defined(OS_ANDROID)
-#if !defined(OFFICIAL_BUILD)
-// Enables the media router. Can be useful to disable for local
-// development on Mac because DIAL local discovery opens a local port
-// and triggers a permission prompt. Only toggleable for developer builds.
 const base::Feature kMediaRouter{"MediaRouter",
                                  base::FEATURE_ENABLED_BY_DEFAULT};
-#endif  // !defined(OFFICIAL_BUILD)
 // Controls if browser side DialMediaRouteProvider is enabled.
 const base::Feature kDialMediaRouteProvider{"DialMediaRouteProvider",
                                             base::FEATURE_ENABLED_BY_DEFAULT};
 const base::Feature kCastMediaRouteProvider{"CastMediaRouteProvider",
-                                            base::FEATURE_DISABLED_BY_DEFAULT};
+                                            base::FEATURE_ENABLED_BY_DEFAULT};
 const base::Feature kCastAllowAllIPsFeature{"CastAllowAllIPs",
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 const base::Feature kGlobalMediaControlsCastStartStop{
@@ -64,10 +59,10 @@
 #endif  // defined(OS_ANDROID) || BUILDFLAG(ENABLE_EXTENSIONS)
 
 bool MediaRouterEnabled(content::BrowserContext* context) {
-#if !defined(OFFICIAL_BUILD) && !defined(OS_ANDROID)
+#if !defined(OS_ANDROID)
   if (!base::FeatureList::IsEnabled(kMediaRouter))
     return false;
-#endif  // !defined(OFFICIAL_BUILD) && !defined(OS_ANDROID)
+#endif  // !defined(OS_ANDROID)
 
 #if defined(OS_ANDROID) || BUILDFLAG(ENABLE_EXTENSIONS)
   static base::NoDestructor<base::flat_map<content::BrowserContext*, bool>>
diff --git a/chrome/browser/media/router/media_router_feature.h b/chrome/browser/media/router/media_router_feature.h
index 8fbd5dc..92b21537 100644
--- a/chrome/browser/media/router/media_router_feature.h
+++ b/chrome/browser/media/router/media_router_feature.h
@@ -21,11 +21,18 @@
 
 #if !defined(OS_ANDROID)
 
+// Enables the media router. Can be disabled in tests unrelated to
+// Media Router where it interferes. Can also be useful to disable for local
+// development on Mac because DIAL local discovery opens a local port
+// and triggers a permission prompt.
+extern const base::Feature kMediaRouter;
+
 // TODO(crbug.com/1028753): Remove default-enabled kDialMediaRouteProvider after
 // tests stop disabling it.
 extern const base::Feature kDialMediaRouteProvider;
 
 extern const base::Feature kCastMediaRouteProvider;
+
 // If enabled, allows Media Router to connect to Cast devices on all IP
 // addresses, not just RFC1918/RFC4193 private addresses. Workaround for
 // https://crbug.com/813974.
diff --git a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc
index 0250c6f..7b0fca41 100644
--- a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc
+++ b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc
@@ -64,11 +64,13 @@
  protected:
   std::unique_ptr<MediaRouterMojoImpl> CreateMediaRouter() override {
     std::unique_ptr<MockCastMediaSinkService> cast_media_sink_service;
-    // We disable the DIAL MRP because initializing the DIAL MRP requires
-    // initialization of objects it depends on, which is outside the scope of
-    // this unit test. DIAL MRP initialization is covered by Media Router
-    // browser tests.
-    feature_list_.InitAndDisableFeature(kDialMediaRouteProvider);
+    // We disable the DIAL and Cast MRPs because initializing the MRPs requires
+    // initialization of objects they depend on, which is outside the scope of
+    // this unit test. MRP initialization is covered by Media Router browser
+    // tests.
+    feature_list_.InitWithFeatures(
+        {}, /* disabled_features */ {kDialMediaRouteProvider,
+                                     kCastMediaRouteProvider});
     cast_media_sink_service = std::make_unique<MockCastMediaSinkService>();
     cast_media_sink_service_ = cast_media_sink_service.get();
     media_sink_service_ =
diff --git a/chrome/browser/metrics/perf/profile_provider_unittest_main.cc b/chrome/browser/metrics/perf/profile_provider_unittest_main.cc
index 25fd072..fe06997 100644
--- a/chrome/browser/metrics/perf/profile_provider_unittest_main.cc
+++ b/chrome/browser/metrics/perf/profile_provider_unittest_main.cc
@@ -304,5 +304,5 @@
 
 int main(int argc, char* argv[]) {
   base::CommandLine::Init(argc, argv);
-  base::RunUnitTestsUsingBaseTestSuite(argc, argv);
+  return base::RunUnitTestsUsingBaseTestSuite(argc, argv);
 }
diff --git a/chrome/browser/metrics/power/power_metrics_reporter.cc b/chrome/browser/metrics/power/power_metrics_reporter.cc
index ad6e76d..ba869e5 100644
--- a/chrome/browser/metrics/power/power_metrics_reporter.cc
+++ b/chrome/browser/metrics/power/power_metrics_reporter.cc
@@ -12,10 +12,13 @@
 #include "services/metrics/public/cpp/ukm_source_id.h"
 
 PowerMetricsReporter::PowerMetricsReporter(
-    const base::WeakPtr<UsageScenarioDataStore>& data_store)
-    : data_store_(data_store) {
+    const base::WeakPtr<UsageScenarioDataStore>& data_store,
+    std::unique_ptr<BatteryLevelProvider> battery_level_provider)
+    : data_store_(data_store),
+      battery_level_provider_(std::move(battery_level_provider)) {
   DCHECK(performance_monitor::ProcessMonitor::Get());
   performance_monitor::ProcessMonitor::Get()->AddObserver(this);
+  battery_state_ = battery_level_provider_->GetBatteryState();
 }
 
 PowerMetricsReporter::~PowerMetricsReporter() {
@@ -29,13 +32,19 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   auto now = base::TimeTicks::Now();
-  ReportUKMs(metrics, now - interval_begin_);
+  base::TimeDelta interval_duration = now - interval_begin_;
   interval_begin_ = now;
+
+  auto discharge_rate =
+      GetBatteryDischargeRataDuringInterval(interval_duration);
+
+  ReportUKMs(metrics, interval_duration, discharge_rate);
 }
 
 void PowerMetricsReporter::ReportUKMs(
     const performance_monitor::ProcessMonitor::Metrics& metrics,
-    base::TimeDelta interval_duration) const {
+    base::TimeDelta interval_duration,
+    int64_t discharge_rate_during_interval) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(data_store_.MaybeValid());
 
@@ -60,8 +69,7 @@
   builder.SetIntervalDurationSeconds(interval_duration.InSeconds());
   builder.SetUptimeSeconds(ukm::GetExponentialBucketMinForUserTiming(
       usage_metrics.uptime_at_interval_end.InSeconds()));
-  // TODO(sebmarchand): Record the battery discharge rate.
-  builder.SetBatteryDischargeRate(0);
+  builder.SetBatteryDischargeRate(discharge_rate_during_interval);
   builder.SetCPUTimeMs(metrics.cpu_usage * interval_duration.InMilliseconds());
 #if defined(OS_MAC)
   builder.SetIdleWakeUps(metrics.idle_wakeups);
@@ -90,3 +98,34 @@
 
   builder.Record(ukm_recorder);
 }
+
+int64_t PowerMetricsReporter::GetBatteryDischargeRataDuringInterval(
+    base::TimeDelta interval_duration) {
+  auto previous_battery_state =
+      std::exchange(battery_state_, battery_level_provider_->GetBatteryState());
+
+  if (previous_battery_state.battery_count == 0 ||
+      battery_state_.battery_count == 0) {
+    return kNoBatteryValue;
+  }
+  if (!previous_battery_state.on_battery && !battery_state_.on_battery) {
+    return kPluggedInDischargeRateValue;
+  }
+  if (previous_battery_state.on_battery != battery_state_.on_battery) {
+    return kBatteryStateChangedValue;
+  }
+  if (!previous_battery_state.charge_level.has_value() ||
+      !battery_state_.charge_level.has_value()) {
+    return kInvalidDischargeRateValue;
+  }
+
+  // The battery discharge rate is reported per minute with 1/10000 of full
+  // charge resolution.
+  static const int64_t kDischargeRateFactor =
+      10000 * base::TimeDelta::FromMinutes(1).InSecondsF();
+
+  auto discharge_rate = (previous_battery_state.charge_level.value() -
+                         battery_state_.charge_level.value()) *
+                        kDischargeRateFactor / interval_duration.InSeconds();
+  return discharge_rate >= 0 ? discharge_rate : kInvalidDischargeRateValue;
+}
diff --git a/chrome/browser/metrics/power/power_metrics_reporter.h b/chrome/browser/metrics/power/power_metrics_reporter.h
index 5a0148e..4138248 100644
--- a/chrome/browser/metrics/power/power_metrics_reporter.h
+++ b/chrome/browser/metrics/power/power_metrics_reporter.h
@@ -5,8 +5,12 @@
 #ifndef CHROME_BROWSER_METRICS_POWER_POWER_METRICS_REPORTER_H_
 #define CHROME_BROWSER_METRICS_POWER_POWER_METRICS_REPORTER_H_
 
+#include <stdint.h>
+
 #include "base/memory/weak_ptr.h"
+#include "base/optional.h"
 #include "base/time/time.h"
+#include "chrome/browser/metrics/power/battery_level_provider.h"
 #include "chrome/browser/metrics/usage_scenario/usage_scenario_data_store.h"
 #include "chrome/browser/performance_monitor/process_monitor.h"
 
@@ -20,12 +24,23 @@
  public:
   // |data_store| will be queried at regular interval to report the metrics, it
   // needs to outlive this class.
-  explicit PowerMetricsReporter(
-      const base::WeakPtr<UsageScenarioDataStore>& data_store);
+  PowerMetricsReporter(
+      const base::WeakPtr<UsageScenarioDataStore>& data_store,
+      std::unique_ptr<BatteryLevelProvider> battery_level_provider);
   PowerMetricsReporter(const PowerMetricsReporter& rhs) = delete;
   PowerMetricsReporter& operator=(const PowerMetricsReporter& rhs) = delete;
   ~PowerMetricsReporter() override;
 
+  BatteryLevelProvider::BatteryState& battery_state_for_testing() {
+    return battery_state_;
+  }
+
+ protected:
+  static const int64_t kPluggedInDischargeRateValue = -1;
+  static const int64_t kBatteryStateChangedValue = -2;
+  static const int64_t kInvalidDischargeRateValue = -3;
+  static const int64_t kNoBatteryValue = -4;
+
  private:
   // performance_monitor::ProcessMonitor::Observer:
   void OnAggregatedMetricsSampled(
@@ -33,12 +48,23 @@
 
   // Report the UKMs for the past interval.
   void ReportUKMs(const performance_monitor::ProcessMonitor::Metrics& metrics,
-                  base::TimeDelta interval_duration) const;
+                  base::TimeDelta interval_duration,
+                  int64_t discharge_rate_during_interval) const;
+
+  // Computes the battery discharge rate during the interval and reset
+  // |battery_state_| to the current state.
+  int64_t GetBatteryDischargeRataDuringInterval(
+      base::TimeDelta interval_duration);
 
   // The data store used to get the usage scenario data, it needs to outlive
   // this class.
   base::WeakPtr<UsageScenarioDataStore> data_store_;
 
+  std::unique_ptr<BatteryLevelProvider> battery_level_provider_;
+
+  BatteryLevelProvider::BatteryState battery_state_{0, 0, base::nullopt, false,
+                                                    base::TimeTicks::Now()};
+
   // The first interval will start when this class gets created.
   base::TimeTicks interval_begin_ = base::TimeTicks::Now();
 
diff --git a/chrome/browser/metrics/power/power_metrics_reporter_unittest.cc b/chrome/browser/metrics/power/power_metrics_reporter_unittest.cc
index 420cfdf..5f267bc 100644
--- a/chrome/browser/metrics/power/power_metrics_reporter_unittest.cc
+++ b/chrome/browser/metrics/power/power_metrics_reporter_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/metrics/power/power_metrics_reporter.h"
 
+#include <memory>
+
 #include "base/test/task_environment.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
@@ -18,12 +20,42 @@
 
 using UkmEntry = ukm::builders::PowerUsageScenariosIntervalData;
 
-class TestPowerMonitor : public performance_monitor::ProcessMonitor {
+class PowerMetricsReporterAccess : public PowerMetricsReporter {
  public:
-  TestPowerMonitor() = default;
-  TestPowerMonitor(const TestPowerMonitor& rhs) = delete;
-  TestPowerMonitor& operator=(const TestPowerMonitor& rhs) = delete;
-  ~TestPowerMonitor() override = default;
+  using PowerMetricsReporter::kBatteryStateChangedValue;
+  using PowerMetricsReporter::kInvalidDischargeRateValue;
+  using PowerMetricsReporter::kNoBatteryValue;
+  using PowerMetricsReporter::kPluggedInDischargeRateValue;
+};
+
+// TODO(sebmarchand|etiennep): Move this to a test util file.
+class FakeBatteryLevelProvider : public BatteryLevelProvider {
+ public:
+  explicit FakeBatteryLevelProvider(
+      std::queue<BatteryLevelProvider::BatteryState>* battery_states)
+      : battery_states_(battery_states) {}
+
+  BatteryState GetBatteryState() override {
+    DCHECK(!battery_states_->empty());
+    BatteryLevelProvider::BatteryState state = battery_states_->front();
+    battery_states_->pop();
+    return state;
+  }
+
+ private:
+  std::vector<BatteryInterface> GetBatteryInterfaceList() override {
+    return {};
+  }
+
+  std::queue<BatteryLevelProvider::BatteryState>* battery_states_;
+};
+
+class TestProcessMonitor : public performance_monitor::ProcessMonitor {
+ public:
+  TestProcessMonitor() = default;
+  TestProcessMonitor(const TestProcessMonitor& rhs) = delete;
+  TestProcessMonitor& operator=(const TestProcessMonitor& rhs) = delete;
+  ~TestProcessMonitor() override = default;
 
   // Call OnAggregatedMetricsSampled for all the observers with |metrics| as an
   // argument.
@@ -55,15 +87,32 @@
 // and this conflicts with it.
 class PowerMetricsReporterUnitTest : public testing::Test {
  public:
-  PowerMetricsReporterUnitTest()
-      : power_metrics_reporter_(data_store_.GetWeakPtr()) {}
+  PowerMetricsReporterUnitTest() = default;
+  PowerMetricsReporterUnitTest(const PowerMetricsReporterUnitTest& rhs) =
+      delete;
+  PowerMetricsReporterUnitTest& operator=(
+      const PowerMetricsReporterUnitTest& rhs) = delete;
+  ~PowerMetricsReporterUnitTest() override = default;
+
+  void SetUp() override {
+    // Start with a full battery.
+    battery_states_.push(BatteryLevelProvider::BatteryState{
+        1, 1, 1.0, true, base::TimeTicks::Now()});
+    std::unique_ptr<BatteryLevelProvider> battery_provider =
+        std::make_unique<FakeBatteryLevelProvider>(&battery_states_);
+    battery_provider_ = battery_provider.get();
+    power_metrics_reporter_ = std::make_unique<PowerMetricsReporter>(
+        data_store_.GetWeakPtr(), std::move(battery_provider));
+  }
 
  protected:
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
-  TestPowerMonitor power_monitor_;
+  TestProcessMonitor process_monitor_;
   TestUsageScenarioDataStoreImpl data_store_;
-  PowerMetricsReporter power_metrics_reporter_;
+  std::queue<BatteryLevelProvider::BatteryState> battery_states_;
+  std::unique_ptr<PowerMetricsReporter> power_metrics_reporter_;
+  BatteryLevelProvider* battery_provider_;
   ukm::TestAutoSetUkmRecorder test_ukm_recorder_;
 };
 
@@ -88,9 +137,13 @@
   fake_interval_data.source_id_for_longest_visible_origin_duration =
       base::TimeDelta::FromSeconds(++fake_value);
 
-  const int kExpectedIntervalLengthSeconds = ++fake_value;
+  const int kExpectedIntervalLengthSeconds = 120;
   task_environment_.FastForwardBy(
       base::TimeDelta::FromSeconds(kExpectedIntervalLengthSeconds));
+  // Pretend that the battery has dropped by 50% in 2 minutes, for a rate of
+  // 25% per minute.
+  battery_states_.push(BatteryLevelProvider::BatteryState{
+      1, 1, 0.50, true, base::TimeTicks::Now()});
 
   data_store_.SetIntervalDataToReturn(fake_interval_data);
 
@@ -102,7 +155,7 @@
   fake_metrics.energy_impact = ++fake_value;
 #endif
 
-  power_monitor_.NotifyObserversForOnAggregatedMetricsSampled(fake_metrics);
+  process_monitor_.NotifyObserversForOnAggregatedMetricsSampled(fake_metrics);
 
   auto entries = test_ukm_recorder_.GetEntriesByName(
       ukm::builders::PowerUsageScenariosIntervalData::kEntryName);
@@ -112,9 +165,8 @@
       entries[0], UkmEntry::kUptimeSecondsName,
       ukm::GetExponentialBucketMinForUserTiming(
           fake_interval_data.uptime_at_interval_end.InSeconds()));
-  // TODO(sebmarchand): Update once the proper value is recorded.
-  test_ukm_recorder_.ExpectEntryMetric(entries[0],
-                                       UkmEntry::kBatteryDischargeRateName, 0);
+  test_ukm_recorder_.ExpectEntryMetric(
+      entries[0], UkmEntry::kBatteryDischargeRateName, 2500);
   test_ukm_recorder_.ExpectEntryMetric(
       entries[0], UkmEntry::kCPUTimeMsName,
       kExpectedIntervalLengthSeconds * 1000 * fake_metrics.cpu_usage);
@@ -159,3 +211,118 @@
                                        UkmEntry::kIntervalDurationSecondsName,
                                        kExpectedIntervalLengthSeconds);
 }
+
+TEST_F(PowerMetricsReporterUnitTest, UKMsPluggedIn) {
+  // Update the latest reported battery state to pretend that the system isn't
+  // running on battery.
+  power_metrics_reporter_->battery_state_for_testing().on_battery = false;
+
+  const int kExpectedIntervalLengthSeconds = 120;
+  task_environment_.FastForwardBy(
+      base::TimeDelta::FromSeconds(kExpectedIntervalLengthSeconds));
+  // Push a battery state that indicates that the system is still not running
+  // on battery.
+  battery_states_.push(BatteryLevelProvider::BatteryState{
+      1, 1, 1.0, /* on_battery - */ false, base::TimeTicks::Now()});
+
+  UsageScenarioDataStore::IntervalData fake_interval_data;
+  fake_interval_data.source_id_for_longest_visible_origin = 42;
+  data_store_.SetIntervalDataToReturn(fake_interval_data);
+  process_monitor_.NotifyObserversForOnAggregatedMetricsSampled({});
+
+  auto entries = test_ukm_recorder_.GetEntriesByName(
+      ukm::builders::PowerUsageScenariosIntervalData::kEntryName);
+  EXPECT_EQ(1u, entries.size());
+  test_ukm_recorder_.ExpectEntryMetric(
+      entries[0], UkmEntry::kBatteryDischargeRateName,
+      PowerMetricsReporterAccess::kPluggedInDischargeRateValue);
+}
+
+TEST_F(PowerMetricsReporterUnitTest, UKMsBatteryStateChanges) {
+  const int kExpectedIntervalLengthSeconds = 120;
+  task_environment_.FastForwardBy(
+      base::TimeDelta::FromSeconds(kExpectedIntervalLengthSeconds));
+  // The initial battery state indicates that the system is running on battery,
+  // pretends that this has changed.
+  battery_states_.push(BatteryLevelProvider::BatteryState{
+      1, 1, 1.0, /* on_battery - */ false, base::TimeTicks::Now()});
+
+  UsageScenarioDataStore::IntervalData fake_interval_data;
+  fake_interval_data.source_id_for_longest_visible_origin = 42;
+  data_store_.SetIntervalDataToReturn(fake_interval_data);
+  process_monitor_.NotifyObserversForOnAggregatedMetricsSampled({});
+
+  auto entries = test_ukm_recorder_.GetEntriesByName(
+      ukm::builders::PowerUsageScenariosIntervalData::kEntryName);
+  EXPECT_EQ(1u, entries.size());
+  test_ukm_recorder_.ExpectEntryMetric(
+      entries[0], UkmEntry::kBatteryDischargeRateName,
+      PowerMetricsReporterAccess::kBatteryStateChangedValue);
+}
+
+TEST_F(PowerMetricsReporterUnitTest, UKMsBatteryStateUnavailable) {
+  const int kExpectedIntervalLengthSeconds = 120;
+  task_environment_.FastForwardBy(
+      base::TimeDelta::FromSeconds(kExpectedIntervalLengthSeconds));
+  // A nullopt battery value indicates that the battery level is unavailable.
+  battery_states_.push(BatteryLevelProvider::BatteryState{
+      1, 1, base::nullopt, true, base::TimeTicks::Now()});
+
+  UsageScenarioDataStore::IntervalData fake_interval_data;
+  fake_interval_data.source_id_for_longest_visible_origin = 42;
+  data_store_.SetIntervalDataToReturn(fake_interval_data);
+  process_monitor_.NotifyObserversForOnAggregatedMetricsSampled({});
+
+  auto entries = test_ukm_recorder_.GetEntriesByName(
+      ukm::builders::PowerUsageScenariosIntervalData::kEntryName);
+  EXPECT_EQ(1u, entries.size());
+  test_ukm_recorder_.ExpectEntryMetric(
+      entries[0], UkmEntry::kBatteryDischargeRateName,
+      PowerMetricsReporterAccess::kInvalidDischargeRateValue);
+}
+
+TEST_F(PowerMetricsReporterUnitTest, UKMsNoBattery) {
+  const int kExpectedIntervalLengthSeconds = 120;
+  task_environment_.FastForwardBy(
+      base::TimeDelta::FromSeconds(kExpectedIntervalLengthSeconds));
+  // Indicates that the system has no battery interface.
+  battery_states_.push(BatteryLevelProvider::BatteryState{
+      0, 0, 1.0, false, base::TimeTicks::Now()});
+
+  UsageScenarioDataStore::IntervalData fake_interval_data;
+  fake_interval_data.source_id_for_longest_visible_origin = 42;
+  data_store_.SetIntervalDataToReturn(fake_interval_data);
+  process_monitor_.NotifyObserversForOnAggregatedMetricsSampled({});
+
+  auto entries = test_ukm_recorder_.GetEntriesByName(
+      ukm::builders::PowerUsageScenariosIntervalData::kEntryName);
+  EXPECT_EQ(1u, entries.size());
+  test_ukm_recorder_.ExpectEntryMetric(
+      entries[0], UkmEntry::kBatteryDischargeRateName,
+      PowerMetricsReporterAccess::kNoBatteryValue);
+}
+
+TEST_F(PowerMetricsReporterUnitTest, UKMsBatteryStateIncrease) {
+  // Set the initial battery level at 50%.
+  power_metrics_reporter_->battery_state_for_testing().charge_level = 0.5;
+
+  const int kExpectedIntervalLengthSeconds = 120;
+  task_environment_.FastForwardBy(
+      base::TimeDelta::FromSeconds(kExpectedIntervalLengthSeconds));
+  // Set the new battery state at 100%.
+  battery_states_.push(BatteryLevelProvider::BatteryState{
+      1, 1, 1.0, true, base::TimeTicks::Now()});
+
+  UsageScenarioDataStore::IntervalData fake_interval_data;
+  fake_interval_data.source_id_for_longest_visible_origin = 42;
+  data_store_.SetIntervalDataToReturn(fake_interval_data);
+  process_monitor_.NotifyObserversForOnAggregatedMetricsSampled({});
+
+  auto entries = test_ukm_recorder_.GetEntriesByName(
+      ukm::builders::PowerUsageScenariosIntervalData::kEntryName);
+  EXPECT_EQ(1u, entries.size());
+  // An increase in charge level is reported as an invalid discharge rate.
+  test_ukm_recorder_.ExpectEntryMetric(
+      entries[0], UkmEntry::kBatteryDischargeRateName,
+      PowerMetricsReporterAccess::kInvalidDischargeRateValue);
+}
diff --git a/chrome/browser/net/websocket_browsertest.cc b/chrome/browser/net/websocket_browsertest.cc
index 5423ce41..741d9fe 100644
--- a/chrome/browser/net/websocket_browsertest.cc
+++ b/chrome/browser/net/websocket_browsertest.cc
@@ -115,10 +115,14 @@
 
     process->GetStoragePartition()->GetNetworkContext()->CreateWebSocket(
         url, requested_protocols, site_for_cookies, isolation_info,
-        std::move(additional_headers), process->GetID(), frame->GetRoutingID(),
-        origin, network::mojom::kWebSocketOptionNone,
+        std::move(additional_headers), process->GetID(), origin,
+        network::mojom::kWebSocketOptionNone,
         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
-        std::move(handshake_client), mojo::NullRemote(), mojo::NullRemote());
+        std::move(handshake_client),
+        process->GetStoragePartition()->CreateAuthAndCertObserverForFrame(
+            process->GetID(), frame->GetRoutingID()),
+        /*auth_handler=*/mojo::NullRemote(),
+        /*header_client=*/mojo::NullRemote());
   }
 
   net::SpawnedTestServer ws_server_;
diff --git a/chrome/browser/notifications/DEPS b/chrome/browser/notifications/DEPS
index 795e3dd..30954b8 100644
--- a/chrome/browser/notifications/DEPS
+++ b/chrome/browser/notifications/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
+  "+chrome/services/mac_notifications/public",
   "+dbus",
   "+ui/message_center",
 ]
diff --git a/chrome/browser/notifications/alert_dispatcher_mojo.h b/chrome/browser/notifications/alert_dispatcher_mojo.h
new file mode 100644
index 0000000..24582afd
--- /dev/null
+++ b/chrome/browser/notifications/alert_dispatcher_mojo.h
@@ -0,0 +1,17 @@
+// 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_NOTIFICATIONS_ALERT_DISPATCHER_MOJO_H_
+#define CHROME_BROWSER_NOTIFICATIONS_ALERT_DISPATCHER_MOJO_H_
+
+#import <Foundation/Foundation.h>
+
+#import "chrome/browser/notifications/alert_dispatcher_mac.h"
+
+// Implementation of the AlertDispatcher interface to display notifications via
+// a Mojo Service running in a helper process.
+@interface AlertDispatcherMojo : NSObject <AlertDispatcher>
+@end
+
+#endif  // CHROME_BROWSER_NOTIFICATIONS_ALERT_DISPATCHER_MOJO_H_
diff --git a/chrome/browser/notifications/alert_dispatcher_mojo.mm b/chrome/browser/notifications/alert_dispatcher_mojo.mm
new file mode 100644
index 0000000..ebf6aeb
--- /dev/null
+++ b/chrome/browser/notifications/alert_dispatcher_mojo.mm
@@ -0,0 +1,62 @@
+// 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/browser/notifications/alert_dispatcher_mojo.h"
+
+#include <set>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/containers/flat_set.h"
+#include "base/mac/scoped_nsobject.h"
+#import "chrome/browser/notifications/notification_alert_service_bridge.h"
+
+@implementation AlertDispatcherMojo {
+  base::scoped_nsobject<NotificationAlertServiceBridge> _mojoService;
+}
+
+- (void)dispatchNotification:(NSDictionary*)data {
+  // TODO(knollr): Implement.
+}
+
+- (void)closeNotificationWithId:(NSString*)notificationId
+                      profileId:(NSString*)profileId
+                      incognito:(BOOL)incognito {
+  // TODO(knollr): Implement.
+}
+
+- (void)closeAllNotifications {
+  [[self serviceProxy] closeAllNotifications];
+}
+
+- (void)getDisplayedAlertsForProfileId:(NSString*)profileId
+                             incognito:(BOOL)incognito
+                              callback:
+                                  (GetDisplayedNotificationsCallback)callback {
+  // TODO(knollr): Implement.
+  std::move(callback).Run(/*alerts=*/{}, /*supports_synchronization=*/false);
+}
+
+- (void)getAllDisplayedAlertsWithCallback:
+    (GetAllDisplayedNotificationsCallback)callback {
+  // TODO(knollr): Implement.
+  std::move(callback).Run(/*alerts=*/{});
+}
+
+- (id<NotificationDelivery>)serviceProxy {
+  if (!_mojoService) {
+    auto onDisconnect = base::BindOnce(
+        [](base::scoped_nsobject<NotificationAlertServiceBridge>* ptr) {
+          // Reset the bridge when the mojo connection disconnects.
+          ptr->reset();
+        },
+        base::Unretained(&_mojoService));
+    _mojoService.reset([[NotificationAlertServiceBridge alloc]
+        initWithDisconnectHandler:std::move(onDisconnect)]);
+  }
+  return _mojoService.get();
+}
+
+@end
diff --git a/chrome/browser/notifications/notification_alert_service_bridge.h b/chrome/browser/notifications/notification_alert_service_bridge.h
new file mode 100644
index 0000000..172644d
--- /dev/null
+++ b/chrome/browser/notifications/notification_alert_service_bridge.h
@@ -0,0 +1,32 @@
+// 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_NOTIFICATIONS_NOTIFICATION_ALERT_SERVICE_BRIDGE_H_
+#define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_ALERT_SERVICE_BRIDGE_H_
+
+#import <Foundation/Foundation.h>
+
+#include "base/callback_forward.h"
+#import "chrome/browser/ui/cocoa/notifications/notification_delivery.h"
+#include "chrome/services/mac_notifications/public/mojom/mac_notifications.mojom.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+
+// Class that implements the NotificationDelivery protocol and forwards it to
+// the mojo service-backed implementation. The lifetime of this class is tied to
+// the lifetime of the utility process connected via mojo.
+@interface NotificationAlertServiceBridge : NSObject <NotificationDelivery>
+
+- (instancetype)initWithDisconnectHandler:(base::OnceClosure)onDisconect;
+
+// This init method is available to pass a custom |provider| in tests.
+- (instancetype)
+    initWithDisconnectHandler:(base::OnceClosure)onDisconect
+                     provider:
+                         (mojo::PendingRemote<
+                             notifications::mojom::MacNotificationProvider>)
+                             provider;
+
+@end
+
+#endif  // CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_ALERT_SERVICE_BRIDGE_H_
diff --git a/chrome/browser/notifications/notification_alert_service_bridge.mm b/chrome/browser/notifications/notification_alert_service_bridge.mm
new file mode 100644
index 0000000..595a44c
--- /dev/null
+++ b/chrome/browser/notifications/notification_alert_service_bridge.mm
@@ -0,0 +1,116 @@
+// 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/browser/notifications/notification_alert_service_bridge.h"
+
+#include <vector>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/notreached.h"
+#include "base/strings/sys_string_conversions.h"
+#include "chrome/browser/notifications/notification_platform_bridge_mac_utils.h"
+#include "chrome/browser/service_sandbox_type.h"
+#include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h"
+#include "content/public/browser/service_process_host.h"
+#include "content/public/common/content_switches.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+namespace {
+
+class MacNotificationActionHandlerImpl
+    : public notifications::mojom::MacNotificationActionHandler {
+ public:
+  // notifications::mojom::MacNotificationActionHandler:
+  void OnNotificationAction(
+      notifications::mojom::NotificationActionInfoPtr info) override {
+    NSDictionary* dict = nil;
+    // TODO(knollr): Get all properties from |info| into |dict|.
+    ProcessMacNotificationResponse(dict);
+  }
+
+  mojo::PendingRemote<notifications::mojom::MacNotificationActionHandler>
+  BindRemote() {
+    return binding_.BindNewPipeAndPassRemote();
+  }
+
+ private:
+  mojo::Receiver<notifications::mojom::MacNotificationActionHandler> binding_{
+      this};
+};
+
+}  // namespace
+
+@implementation NotificationAlertServiceBridge {
+  mojo::Remote<notifications::mojom::MacNotificationProvider> _provider;
+  mojo::Remote<notifications::mojom::MacNotificationService> _service;
+  MacNotificationActionHandlerImpl _handler;
+}
+
+- (instancetype)initWithDisconnectHandler:(base::OnceClosure)onDisconect {
+  if ((self = [super init])) {
+    // Launches a new helper process and sets up a mojo connection to it. If the
+    // mojo connection disconnects we call |onDisconnect| which will destroy
+    // |this| and terminate the process if it hasn't been already.
+    _provider = content::ServiceProcessHost::Launch<
+        notifications::mojom::MacNotificationProvider>(
+        content::ServiceProcessHost::Options()
+            .WithExtraCommandLineSwitches({switches::kMessageLoopTypeUi})
+            // TODO(knollr): Set the correct flags so the helper launches via
+            // the app which has set the alert notifications style:
+            //.WithChildFlags(chrome::kChildProcessHelperAlerts)
+            .Pass());
+    _provider.set_disconnect_handler(std::move(onDisconect));
+    _provider->BindNotificationService(_service.BindNewPipeAndPassReceiver(),
+                                       _handler.BindRemote());
+  }
+  return self;
+}
+
+- (instancetype)
+    initWithDisconnectHandler:(base::OnceClosure)onDisconect
+                     provider:
+                         (mojo::PendingRemote<
+                             notifications::mojom::MacNotificationProvider>)
+                             provider {
+  if ((self = [super init])) {
+    _provider.Bind(std::move(provider));
+    _provider.set_disconnect_handler(std::move(onDisconect));
+    _provider->BindNotificationService(_service.BindNewPipeAndPassReceiver(),
+                                       _handler.BindRemote());
+  }
+  return self;
+}
+
+- (void)setUseUNNotification:(BOOL)useUNNotification
+           machExceptionPort:(CrXPCMachPort*)port {
+  NOTREACHED();
+}
+
+- (void)deliverNotification:(NSDictionary*)notificationData {
+  // TODO(knollr): implement.
+}
+
+- (void)closeNotificationWithId:(NSString*)notificationId
+                      profileId:(NSString*)profileId
+                      incognito:(BOOL)incognito {
+  // TODO(knollr): implement.
+}
+
+- (void)closeAllNotifications {
+  _service->CloseAllNotifications();
+}
+
+- (void)getDisplayedAlertsForProfileId:(NSString*)profileId
+                             incognito:(BOOL)incognito
+                                 reply:(void (^)(NSArray*))reply {
+  // TODO(knollr): implement.
+}
+
+- (void)getAllDisplayedAlertsWithReply:(void (^)(NSArray*))reply {
+  // TODO(knollr): implement.
+}
+
+@end
diff --git a/chrome/browser/notifications/notification_alert_service_bridge_unittest.mm b/chrome/browser/notifications/notification_alert_service_bridge_unittest.mm
new file mode 100644
index 0000000..a8ca3cf9
--- /dev/null
+++ b/chrome/browser/notifications/notification_alert_service_bridge_unittest.mm
@@ -0,0 +1,99 @@
+// 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/browser/notifications/notification_alert_service_bridge.h"
+#include "base/mac/scoped_nsobject.h"
+#include "base/run_loop.h"
+#include "base/test/mock_callback.h"
+#include "chrome/services/mac_notifications/public/mojom/mac_notifications.mojom.h"
+#include "content/public/test/browser_task_environment.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gtest_mac.h"
+
+namespace {
+
+class MockNotificationService
+    : public notifications::mojom::MacNotificationService {
+ public:
+  MOCK_METHOD(void, CloseAllNotifications, (), (override));
+};
+
+class MockNotificationProvider
+    : public notifications::mojom::MacNotificationProvider {
+ public:
+  MOCK_METHOD(
+      void,
+      BindNotificationService,
+      (mojo::PendingReceiver<notifications::mojom::MacNotificationService>,
+       mojo::PendingRemote<notifications::mojom::MacNotificationActionHandler>),
+      (override));
+};
+
+}  // namespace
+
+class NotificationAlertServiceBridgeTest : public testing::Test {
+ public:
+  NotificationAlertServiceBridgeTest() {
+    base::RunLoop run_loop;
+    EXPECT_CALL(mock_provider_, BindNotificationService)
+        .WillOnce([&](mojo::PendingReceiver<
+                          notifications::mojom::MacNotificationService>
+                          service_receiver,
+                      mojo::PendingRemote<
+                          notifications::mojom::MacNotificationActionHandler>
+                          handler_remote) {
+          service_receiver_.Bind(std::move(service_receiver));
+          handler_remote_.Bind(std::move(handler_remote));
+          run_loop.Quit();
+        });
+    bridge_.reset([[NotificationAlertServiceBridge alloc]
+        initWithDisconnectHandler:on_disconnect_.Get()
+                         provider:provider_receiver_
+                                      .BindNewPipeAndPassRemote()]);
+    run_loop.Run();
+  }
+
+  ~NotificationAlertServiceBridgeTest() override = default;
+
+ protected:
+  content::BrowserTaskEnvironment task_environment_;
+  base::MockOnceClosure on_disconnect_;
+  MockNotificationService mock_service_;
+  mojo::Receiver<notifications::mojom::MacNotificationService>
+      service_receiver_{&mock_service_};
+  mojo::Remote<notifications::mojom::MacNotificationActionHandler>
+      handler_remote_;
+  MockNotificationProvider mock_provider_;
+  mojo::Receiver<notifications::mojom::MacNotificationProvider>
+      provider_receiver_{&mock_provider_};
+  base::scoped_nsobject<NotificationAlertServiceBridge> bridge_;
+};
+
+TEST_F(NotificationAlertServiceBridgeTest, DisconnectHandler) {
+  base::RunLoop run_loop;
+  EXPECT_CALL(on_disconnect_, Run).WillOnce([&]() { run_loop.Quit(); });
+  provider_receiver_.reset();
+  run_loop.Run();
+}
+
+TEST_F(NotificationAlertServiceBridgeTest, CloseAllNotifications) {
+  base::RunLoop run_loop;
+  EXPECT_CALL(mock_service_, CloseAllNotifications).WillOnce([&]() {
+    run_loop.Quit();
+  });
+  [bridge_ closeAllNotifications];
+  run_loop.Run();
+}
+
+TEST_F(NotificationAlertServiceBridgeTest, OnNotificationAction) {
+  // TODO(knollr): pass and verify expected notification action data.
+  handler_remote_->OnNotificationAction(
+      notifications::mojom::NotificationActionInfo::New());
+  // Wait until the action has been handled.
+  task_environment_.RunUntilIdle();
+}
diff --git a/chrome/browser/notifications/notification_platform_bridge_mac.mm b/chrome/browser/notifications/notification_platform_bridge_mac.mm
index 8987351..d91d14ad 100644
--- a/chrome/browser/notifications/notification_platform_bridge_mac.mm
+++ b/chrome/browser/notifications/notification_platform_bridge_mac.mm
@@ -22,8 +22,8 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/browser_features.h"
-#include "chrome/browser/notifications/alert_dispatcher_xpc.h"
+#import "chrome/browser/notifications/alert_dispatcher_mojo.h"
+#import "chrome/browser/notifications/alert_dispatcher_xpc.h"
 #include "chrome/browser/notifications/notification_common.h"
 #include "chrome/browser/notifications/notification_display_service_impl.h"
 #include "chrome/browser/notifications/notification_platform_bridge_mac_utils.h"
@@ -32,6 +32,7 @@
 #include "chrome/browser/ui/cocoa/notifications/notification_builder_mac.h"
 #include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h"
 #import "chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/grit/generated_resources.h"
 #include "third_party/blink/public/common/notifications/notification_constants.h"
 #include "ui/base/l10n/l10n_util_mac.h"
@@ -85,9 +86,10 @@
 // static
 std::unique_ptr<NotificationPlatformBridge>
 NotificationPlatformBridge::Create() {
-  // TODO(crbug.com/1170731): Use a helper app to display alerts.
   base::scoped_nsobject<NSObject<AlertDispatcher>> alert_dispatcher(
-      [[AlertDispatcherXPC alloc] init]);
+      base::FeatureList::IsEnabled(features::kNotificationsViaHelperApp)
+          ? [[AlertDispatcherMojo alloc] init]
+          : [[AlertDispatcherXPC alloc] init]);
 
   if (@available(macOS 10.14, *)) {
     if (base::FeatureList::IsEnabled(features::kNewMacNotificationAPI)) {
diff --git a/chrome/browser/notifications/notification_platform_bridge_mac_utils.mm b/chrome/browser/notifications/notification_platform_bridge_mac_utils.mm
index 7e696c22..5123ea70 100644
--- a/chrome/browser/notifications/notification_platform_bridge_mac_utils.mm
+++ b/chrome/browser/notifications/notification_platform_bridge_mac_utils.mm
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/notifications/notification_platform_bridge_mac_utils.h"
 
+#include "base/feature_list.h"
 #include "base/i18n/number_formatting.h"
 #include "base/optional.h"
 #include "base/strings/strcat.h"
@@ -14,6 +15,7 @@
 #include "chrome/browser/notifications/notification_display_service_impl.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h"
+#include "chrome/common/chrome_features.h"
 #include "components/url_formatter/elide_url.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -251,9 +253,10 @@
 }
 
 bool IsAlertNotificationMac(const message_center::Notification& notification) {
-  // We show alerts via an XPC service, check if that's possible.
-  // TODO(crbug.com/1127306): Don't check this once we use the helper app.
-  if (!MacOSSupportsXPCAlerts())
+  // If we show alerts via an XPC service, check if that's possible.
+  bool should_use_xpc =
+      !base::FeatureList::IsEnabled(features::kNotificationsViaHelperApp);
+  if (should_use_xpc && !MacOSSupportsXPCAlerts())
     return false;
 
   // Check if the |notification| should be shown as alert.
diff --git a/chrome/browser/paint_preview/services/paint_preview_tab_service_unittest.cc b/chrome/browser/paint_preview/services/paint_preview_tab_service_unittest.cc
index 86f4683..e796ed3 100644
--- a/chrome/browser/paint_preview/services/paint_preview_tab_service_unittest.cc
+++ b/chrome/browser/paint_preview/services/paint_preview_tab_service_unittest.cc
@@ -46,6 +46,7 @@
   void SetResponse(mojom::PaintPreviewStatus status) { status_ = status; }
 
   void BindRequest(mojo::ScopedInterfaceEndpointHandle handle) {
+    binding_.reset();
     binding_.Bind(mojo::PendingAssociatedReceiver<mojom::PaintPreviewRecorder>(
         std::move(handle)));
   }
diff --git a/chrome/browser/password_check/android/password_check_manager.cc b/chrome/browser/password_check/android/password_check_manager.cc
index 24f15d9a..ca0797db 100644
--- a/chrome/browser/password_check/android/password_check_manager.cc
+++ b/chrome/browser/password_check/android/password_check_manager.cc
@@ -310,8 +310,21 @@
 bool PasswordCheckManager::CanUseAccountCheck() const {
   SyncState sync_state = password_manager_util::GetPasswordSyncState(
       ProfileSyncServiceFactory::GetForProfile(profile_));
-  return sync_state == SyncState::SYNCING_NORMAL_ENCRYPTION ||
-         sync_state == SyncState::ACCOUNT_PASSWORDS_ACTIVE_NORMAL_ENCRYPTION;
+  switch (sync_state) {
+    case SyncState::NOT_SYNCING:
+      ABSL_FALLTHROUGH_INTENDED;
+    case SyncState::SYNCING_WITH_CUSTOM_PASSPHRASE:
+      return false;
+
+    case SyncState::SYNCING_NORMAL_ENCRYPTION:
+      ABSL_FALLTHROUGH_INTENDED;
+    case SyncState::ACCOUNT_PASSWORDS_ACTIVE_NORMAL_ENCRYPTION:
+      return true;
+
+    default:
+      NOTREACHED();
+      return false;
+  }
 }
 
 bool PasswordCheckManager::AreScriptsRefreshed() const {
@@ -347,12 +360,22 @@
 
   // Password change scripts are using password generation, so automatic
   // password change should not be offered to non sync users.
-  if (sync_state == password_manager::NOT_SYNCING) {
-    return false;
-  }
+  switch (sync_state) {
+    case SyncState::NOT_SYNCING:
+      return false;
 
-  return base::FeatureList::IsEnabled(
-      password_manager::features::kPasswordScriptsFetching);
+    case SyncState::SYNCING_WITH_CUSTOM_PASSPHRASE:
+      ABSL_FALLTHROUGH_INTENDED;
+    case SyncState::SYNCING_NORMAL_ENCRYPTION:
+      ABSL_FALLTHROUGH_INTENDED;
+    case SyncState::ACCOUNT_PASSWORDS_ACTIVE_NORMAL_ENCRYPTION:
+      return base::FeatureList::IsEnabled(
+          password_manager::features::kPasswordScriptsFetching);
+
+    default:
+      NOTREACHED();
+      return false;
+  }
 }
 
 bool PasswordCheckManager::IsPreconditionFulfilled(
diff --git a/chrome/browser/password_entry_edit/android/credential_edit_bridge.cc b/chrome/browser/password_entry_edit/android/credential_edit_bridge.cc
index 743adec..c7b2d97 100644
--- a/chrome/browser/password_entry_edit/android/credential_edit_bridge.cc
+++ b/chrome/browser/password_entry_edit/android/credential_edit_bridge.cc
@@ -5,9 +5,12 @@
 #include "chrome/browser/password_entry_edit/android/credential_edit_bridge.h"
 
 #include <jni.h>
+#include <memory>
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/memory/ptr_util.h"
 #include "chrome/browser/password_entry_edit/android/jni_headers/CredentialEditBridge_jni.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h"
@@ -15,14 +18,34 @@
 #include "components/url_formatter/url_formatter.h"
 #include "ui/base/l10n/l10n_util.h"
 
+std::unique_ptr<CredentialEditBridge> CredentialEditBridge::MaybeCreate(
+    const password_manager::PasswordForm* credential,
+    base::OnceClosure dismissal_callback,
+    const base::android::JavaRef<jobject>& context,
+    const base::android::JavaRef<jobject>& settings_launcher) {
+  base::android::ScopedJavaGlobalRef<jobject> java_bridge;
+  java_bridge.Reset(Java_CredentialEditBridge_maybeCreate(
+      base::android::AttachCurrentThread()));
+  if (!java_bridge) {
+    return nullptr;
+  }
+  return base::WrapUnique(new CredentialEditBridge(
+      credential, std::move(dismissal_callback), context, settings_launcher,
+      std::move(java_bridge)));
+}
+
 CredentialEditBridge::CredentialEditBridge(
     const password_manager::PasswordForm* credential,
+    base::OnceClosure dismissal_callback,
     const base::android::JavaRef<jobject>& context,
-    const base::android::JavaRef<jobject>& settings_launcher)
-    : credential_(credential) {
-  java_bridge_.Reset(Java_CredentialEditBridge_create(
-      base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this),
-      context, settings_launcher));
+    const base::android::JavaRef<jobject>& settings_launcher,
+    base::android::ScopedJavaGlobalRef<jobject> java_bridge)
+    : credential_(credential),
+      dismissal_callback_(std::move(dismissal_callback)),
+      java_bridge_(java_bridge) {
+  Java_CredentialEditBridge_initAndLaunchUi(
+      base::android::AttachCurrentThread(), java_bridge_,
+      reinterpret_cast<intptr_t>(this), context, settings_launcher);
 }
 
 CredentialEditBridge::~CredentialEditBridge() {
@@ -40,6 +63,10 @@
                                               GetDisplayFederationOrigin()));
 }
 
+void CredentialEditBridge::OnUIDismissed(JNIEnv* env) {
+  std::move(dismissal_callback_).Run();
+}
+
 base::string16 CredentialEditBridge::GetDisplayURLOrAppName() {
   auto facet = password_manager::FacetURI::FromPotentiallyInvalidSpec(
       credential_->signon_realm);
diff --git a/chrome/browser/password_entry_edit/android/credential_edit_bridge.h b/chrome/browser/password_entry_edit/android/credential_edit_bridge.h
index c4e76c1..e0aa36a 100644
--- a/chrome/browser/password_entry_edit/android/credential_edit_bridge.h
+++ b/chrome/browser/password_entry_edit/android/credential_edit_bridge.h
@@ -8,6 +8,7 @@
 #include <jni.h>
 
 #include "base/android/scoped_java_ref.h"
+#include "base/callback_forward.h"
 #include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/ui/insecure_credentials_manager.h"
 
@@ -15,8 +16,12 @@
 // in order to launch or dismiss the edit UI.
 class CredentialEditBridge {
  public:
-  CredentialEditBridge(
+  // Returns a new bridge if none exists. If a bridge already exitst, it returns
+  // null, since that means the edit UI is already open and it should not be
+  // shared.
+  static std::unique_ptr<CredentialEditBridge> MaybeCreate(
       const password_manager::PasswordForm* credential,
+      base::OnceClosure dismissal_callback,
       const base::android::JavaRef<jobject>& context,
       const base::android::JavaRef<jobject>& settings_launcher);
   ~CredentialEditBridge();
@@ -27,7 +32,16 @@
   // Called by Java to get the credential to be edited.
   void GetCredential(JNIEnv* env);
 
+  // Called by Java to signal that the UI was dismissed.
+  void OnUIDismissed(JNIEnv* env);
+
  private:
+  CredentialEditBridge(const password_manager::PasswordForm* credential,
+                       base::OnceClosure dismissal_callback,
+                       const base::android::JavaRef<jobject>& context,
+                       const base::android::JavaRef<jobject>& settings_launcher,
+                       base::android::ScopedJavaGlobalRef<jobject> java_bridge);
+
   // Returns the URL or app for which the credential was saved, formatted
   // for display.
   base::string16 GetDisplayURLOrAppName();
@@ -38,7 +52,10 @@
   base::string16 GetDisplayFederationOrigin();
 
   // The credential to be edited.
-  const password_manager::PasswordForm* credential_;
+  const password_manager::PasswordForm* credential_ = nullptr;
+
+  // Callback invoked when the UI is being dismissed from the Java side.
+  base::OnceClosure dismissal_callback_;
 
   // The corresponding java object.
   base::android::ScopedJavaGlobalRef<jobject> java_bridge_;
diff --git a/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditBridge.java b/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditBridge.java
index f46ea75..80c96957 100644
--- a/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditBridge.java
+++ b/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditBridge.java
@@ -6,6 +6,8 @@
 
 import android.content.Context;
 
+import androidx.annotation.Nullable;
+
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.components.browser_ui.settings.SettingsLauncher;
@@ -15,18 +17,30 @@
  * for saving the changes.
  */
 class CredentialEditBridge {
+    private static CredentialEditBridge sCredentialEditBridge;
+
     private long mNativeCredentialEditBridge;
 
-    private CredentialEditBridge(
-            long nativeCredentialEditBridge, Context context, SettingsLauncher settingsLauncher) {
-        mNativeCredentialEditBridge = nativeCredentialEditBridge;
-        settingsLauncher.launchSettingsActivity(context, CredentialEditFragmentView.class);
+    @Nullable
+    static CredentialEditBridge get() {
+        return sCredentialEditBridge;
+    }
+
+    private CredentialEditBridge() {}
+
+    @CalledByNative
+    static @Nullable CredentialEditBridge maybeCreate() {
+        // There can only be one bridge at a time and it shouldn't be shared.
+        if (sCredentialEditBridge != null) return null;
+        sCredentialEditBridge = new CredentialEditBridge();
+        return sCredentialEditBridge;
     }
 
     @CalledByNative
-    static CredentialEditBridge create(
+    void initAndLaunchUi(
             long nativeCredentialEditBridge, Context context, SettingsLauncher settingsLauncher) {
-        return new CredentialEditBridge(nativeCredentialEditBridge, context, settingsLauncher);
+        mNativeCredentialEditBridge = nativeCredentialEditBridge;
+        settingsLauncher.launchSettingsActivity(context, CredentialEditFragmentView.class);
     }
 
     @CalledByNative
@@ -35,13 +49,26 @@
         // TODO(crbug.com/1170289): Pass the credential data to the UI to be displayed.
     }
 
+    // This can be called either before or after the native counterpart has gone away, depending
+    // on where the edit component is being destroyed from.
+    void onUiDismissed() {
+        if (mNativeCredentialEditBridge != 0) {
+            CredentialEditBridgeJni.get().onUIDismissed(mNativeCredentialEditBridge);
+        }
+        mNativeCredentialEditBridge = 0;
+        sCredentialEditBridge = null;
+    }
+
     @CalledByNative
     void destroy() {
+        // TODO(crbug.com/1175785): Dismiss the UI, if it wasn't dismissed already.
         mNativeCredentialEditBridge = 0;
+        sCredentialEditBridge = null;
     }
 
     @NativeMethods
     interface Natives {
         void getCredential(long nativeCredentialEditBridge);
+        void onUIDismissed(long nativeCredentialEditBridge);
     }
 }
diff --git a/chrome/browser/password_manager/android/password_ui_view_android.cc b/chrome/browser/password_manager/android/password_ui_view_android.cc
index b1b5d49..73979e1 100644
--- a/chrome/browser/password_manager/android/password_ui_view_android.cc
+++ b/chrome/browser/password_manager/android/password_ui_view_android.cc
@@ -214,12 +214,19 @@
     const JavaParamRef<jobject>& obj) {
   const password_manager::PasswordForm* form =
       password_manager_presenter_.GetPassword(index);
-  if (form) {
-    credential_edit_bridge_.reset(
-        new CredentialEditBridge(form, context, settings_launcher));
+  if (form && !credential_edit_bridge_) {
+    credential_edit_bridge_ = CredentialEditBridge::MaybeCreate(
+        form,
+        base::BindOnce(&PasswordUIViewAndroid::OnEditUIDismissed,
+                       base::Unretained(this)),
+        context, settings_launcher);
   }
 }
 
+void PasswordUIViewAndroid::OnEditUIDismissed() {
+  credential_edit_bridge_.reset();
+}
+
 ScopedJavaLocalRef<jstring> JNI_PasswordUIView_GetAccountDashboardURL(
     JNIEnv* env) {
   return ConvertUTF16ToJavaString(
diff --git a/chrome/browser/password_manager/android/password_ui_view_android.h b/chrome/browser/password_manager/android/password_ui_view_android.h
index c2720160..1bf732b 100644
--- a/chrome/browser/password_manager/android/password_ui_view_android.h
+++ b/chrome/browser/password_manager/android/password_ui_view_android.h
@@ -92,6 +92,8 @@
   // Destroy the native implementation.
   void Destroy(JNIEnv*, const base::android::JavaRef<jobject>&);
 
+  void OnEditUIDismissed();
+
   void set_export_target_for_testing(
       SerializationResult* export_target_for_testing) {
     export_target_for_testing_ = export_target_for_testing;
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc
index e4e4514..97d9840 100644
--- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc
+++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc
@@ -2139,9 +2139,9 @@
   GURL eligible_link = https_expired_server.GetURL("b.test", "/simple.html");
 
   TestTabHelperObserver tab_helper_observer(tab_helper);
-  // |ERR_ABORTED| is set by the PrefetchProxyNetworkContextClient.
+  // |ERR_INSECURE_RESPONSE| is set by the URLLoader.
   tab_helper_observer.SetExpectedPrefetchErrors(
-      {{eligible_link, net::ERR_ABORTED}});
+      {{eligible_link, net::ERR_INSECURE_RESPONSE}});
 
   base::RunLoop prefetch_run_loop;
   tab_helper_observer.SetOnPrefetchErrorClosure(
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.cc b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.cc
index e39169b6..e456077 100644
--- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.cc
+++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.cc
@@ -43,17 +43,6 @@
   cert_responder->CancelRequest();
 }
 
-void PrefetchProxyNetworkContextClient::OnSSLCertificateError(
-    int32_t process_id,
-    int32_t routing_id,
-    const GURL& url,
-    int net_error,
-    const net::SSLInfo& ssl_info,
-    bool fatal,
-    OnSSLCertificateErrorCallback response) {
-  std::move(response).Run(net::ERR_ABORTED);
-}
-
 void PrefetchProxyNetworkContextClient::OnFileUploadRequested(
     int32_t process_id,
     bool async,
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.h b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.h
index 0e1e30f..4fdff46 100644
--- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.h
+++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.h
@@ -39,13 +39,6 @@
       const scoped_refptr<net::SSLCertRequestInfo>& cert_info,
       mojo::PendingRemote<network::mojom::ClientCertificateResponder>
           cert_responder) override;
-  void OnSSLCertificateError(int32_t process_id,
-                             int32_t routing_id,
-                             const GURL& url,
-                             int net_error,
-                             const net::SSLInfo& ssl_info,
-                             bool fatal,
-                             OnSSLCertificateErrorCallback response) override;
   void OnFileUploadRequested(int32_t process_id,
                              bool async,
                              const std::vector<base::FilePath>& file_paths,
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 2f127cd..ee40dc6e 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -1333,6 +1333,11 @@
   profile_prefs->ClearPref(kDataReductionProxyLastConfigRetrievalTime);
   profile_prefs->ClearPref(kDataReductionProxyConfig);
 
+#if defined(OS_ANDROID)
+  // Added 02/2021
+  feed::MigrateObsoleteProfilePrefsFeb_2021(profile_prefs);
+#endif  // defined(OS_ANDROID)
+
   // Please don't delete the following line. It is used by PRESUBMIT.py.
   // END_MIGRATE_OBSOLETE_PROFILE_PREFS
 }
diff --git a/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxBridge.java b/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxBridge.java
index 621e161..09c700e 100644
--- a/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxBridge.java
+++ b/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxBridge.java
@@ -8,6 +8,10 @@
 
 /** Bridge, providing access to the native-side Privacy Sandbox configuration. */
 public class PrivacySandboxBridge {
+    public static boolean isPrivacySandboxFunctional() {
+        return PrivacySandboxBridgeJni.get().isPrivacySandboxFunctional();
+    }
+
     public static boolean isPrivacySandboxEnabled() {
         return PrivacySandboxBridgeJni.get().isPrivacySandboxEnabled();
     }
@@ -22,6 +26,7 @@
 
     @NativeMethods
     interface Natives {
+        boolean isPrivacySandboxFunctional();
         boolean isPrivacySandboxEnabled();
         boolean isPrivacySandboxManaged();
         void setPrivacySandboxEnabled(boolean enabled);
diff --git a/chrome/browser/privacy_sandbox/android/privacy_sandbox_bridge.cc b/chrome/browser/privacy_sandbox/android/privacy_sandbox_bridge.cc
index 6b4f2eb..a128a5b 100644
--- a/chrome/browser/privacy_sandbox/android/privacy_sandbox_bridge.cc
+++ b/chrome/browser/privacy_sandbox/android/privacy_sandbox_bridge.cc
@@ -7,6 +7,13 @@
 #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.h"
 #include "chrome/browser/profiles/profile_manager.h"
 
+static jboolean JNI_PrivacySandboxBridge_IsPrivacySandboxFunctional(
+    JNIEnv* env) {
+  return PrivacySandboxSettingsFactory::GetForProfile(
+             ProfileManager::GetActiveUserProfile())
+      ->PrivacySandboxSettingsFunctional();
+}
+
 static jboolean JNI_PrivacySandboxBridge_IsPrivacySandboxEnabled(JNIEnv* env) {
   return PrivacySandboxSettingsFactory::GetForProfile(
              ProfileManager::GetActiveUserProfile())
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc
index 31da191..c7307ed 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc
@@ -5,6 +5,9 @@
 #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings.h"
 
 #include "base/feature_list.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/user_metrics.h"
 #include "base/time/time.h"
 #include "chrome/common/chrome_features.h"
 #include "components/content_settings/core/browser/cookie_settings.h"
@@ -315,8 +318,10 @@
     return;
 
   // No need to reconcile preferences if it has already happened.
-  if (pref_service_->GetBoolean(prefs::kPrivacySandboxPreferencesReconciled))
+  if (pref_service_->GetBoolean(prefs::kPrivacySandboxPreferencesReconciled)) {
+    LogPrivacySandboxState();
     return;
+  }
 
   // If all or 3P cookies are disabled by policy, this will be reflected
   // directly in the Privacy Sandbox preference at the policy level. No attempt
@@ -330,6 +335,7 @@
     if (!policy_service_observed_) {
       policy_service_->AddObserver(policy::POLICY_DOMAIN_CHROME, this);
       policy_service_observed_ = true;
+      LogPrivacySandboxState();
     }
     return;
   }
@@ -401,6 +407,7 @@
   // If observers were setup they are no longer required after reconciliation
   // has occurred.
   StopObserving();
+  LogPrivacySandboxState();
 }
 
 void PrivacySandboxSettings::StopObserving() {
@@ -412,3 +419,74 @@
     policy_service_observed_ = false;
   }
 }
+
+void PrivacySandboxSettings::RecordPrivacySandboxHistogram(
+    PrivacySandboxSettings::SettingsPrivacySandboxEnabled state) {
+  base::UmaHistogramEnumeration("Settings.PrivacySandbox.Enabled", state);
+}
+
+void PrivacySandboxSettings::LogPrivacySandboxState() {
+  // Check policy status first.
+  std::string default_cookie_setting_provider;
+  auto default_cookie_setting = cookie_settings_->GetDefaultCookieSetting(
+      &default_cookie_setting_provider);
+  auto default_cookie_setting_source =
+      HostContentSettingsMap::GetSettingSourceFromProviderName(
+          default_cookie_setting_provider);
+
+  if (default_cookie_setting_source ==
+          content_settings::SettingSource::SETTING_SOURCE_POLICY &&
+      default_cookie_setting == ContentSetting::CONTENT_SETTING_BLOCK) {
+    RecordPrivacySandboxHistogram(
+        PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+            kPSDisabledPolicyBlockAll);
+    return;
+  }
+
+  auto* cookie_controls_mode_pref =
+      pref_service_->FindPreference(prefs::kCookieControlsMode);
+  auto cookie_controls_mode_value =
+      static_cast<content_settings::CookieControlsMode>(
+          cookie_controls_mode_pref->GetValue()->GetInt());
+
+  if (cookie_controls_mode_pref->IsManaged() &&
+      cookie_controls_mode_value ==
+          content_settings::CookieControlsMode::kBlockThirdParty) {
+    RecordPrivacySandboxHistogram(
+        PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+            kPSDisabledPolicyBlock3P);
+    return;
+  }
+
+  if (pref_service_->GetBoolean(prefs::kPrivacySandboxApisEnabled)) {
+    if (default_cookie_setting == ContentSetting::CONTENT_SETTING_BLOCK) {
+      RecordPrivacySandboxHistogram(
+          PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+              kPSEnabledBlockAll);
+    } else if (cookie_controls_mode_value ==
+               content_settings::CookieControlsMode::kBlockThirdParty) {
+      RecordPrivacySandboxHistogram(
+          PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+              kPSEnabledBlock3P);
+    } else {
+      RecordPrivacySandboxHistogram(
+          PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+              kPSEnabledAllowAll);
+    }
+  } else {
+    if (default_cookie_setting == ContentSetting::CONTENT_SETTING_BLOCK) {
+      RecordPrivacySandboxHistogram(
+          PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+              kPSDisabledBlockAll);
+    } else if (cookie_controls_mode_value ==
+               content_settings::CookieControlsMode::kBlockThirdParty) {
+      RecordPrivacySandboxHistogram(
+          PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+              kPSDisabledBlock3P);
+    } else {
+      RecordPrivacySandboxHistogram(
+          PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+              kPSDisabledAllowAll);
+    }
+  }
+}
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.h b/chrome/browser/privacy_sandbox/privacy_sandbox_settings.h
index 5b8c000c..ac6c48b 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.h
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings.h
@@ -154,6 +154,31 @@
                            NoReconciliationAlreadyRun);
   FRIEND_TEST_ALL_PREFIXES(PrivacySandboxSettingsTest,
                            NoReconciliationSandboxSettingsDisabled);
+  FRIEND_TEST_ALL_PREFIXES(PrivacySandboxSettingsTest,
+                           MetricsLoggingOccursCorrectly);
+
+  /**
+   * Contains all possible privacy sandbox states, recorded on startup.
+   *
+   * These values are persisted to logs. Entries should not be renumbered and
+   * numeric values should never be reused.
+   *
+   * Must be kept in sync with the SettingsPrivacySandboxEnabled enum in
+   * histograms/enums.xml and privacy_sandbox_settings_unittest.cc.
+   */
+  enum class SettingsPrivacySandboxEnabled {
+    kPSEnabledAllowAll = 0,
+    kPSEnabledBlock3P = 1,
+    kPSEnabledBlockAll = 2,
+    kPSDisabledAllowAll = 3,
+    kPSDisabledBlock3P = 4,
+    kPSDisabledBlockAll = 5,
+    kPSDisabledPolicyBlock3P = 6,
+    kPSDisabledPolicyBlockAll = 7,
+    // Add values above this line with a corresponding label in
+    // tools/metrics/histograms/enums.xml
+    kMaxValue = kPSDisabledPolicyBlockAll,
+  };
 
   // Determines based on the current features, preferences and provided
   // |cookie_settings| whether Privacy Sandbox APIs are generally allowable for
@@ -180,6 +205,14 @@
   // Stops any observation of services being performed by this class.
   void StopObserving();
 
+  // Helper function to actually make the metrics call for
+  // LogPrivacySandboxState.
+  void RecordPrivacySandboxHistogram(SettingsPrivacySandboxEnabled state);
+
+  // Logs the state of the privacy sandbox and cookie settings. Called once per
+  // profile startup.
+  void LogPrivacySandboxState();
+
  private:
   base::ObserverList<Observer>::Unchecked observers_;
 
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc
index 22feccec..c0409fc7 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings.h"
 
 #include "base/test/gtest_util.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/util/values/values_util.h"
 #include "chrome/browser/content_settings/cookie_settings_factory.h"
@@ -995,6 +996,189 @@
       prefs::kPrivacySandboxPreferencesReconciled));
 }
 
+TEST_F(PrivacySandboxSettingsTest, MetricsLoggingOccursCorrectly) {
+  base::HistogramTester histograms;
+  const std::string histogram_name = "Settings.PrivacySandbox.Enabled";
+
+  // The histogram should start off empty.
+  histograms.ExpectTotalCount(histogram_name, 0);
+
+  SetupTestState(
+      /*privacy_sandbox_available=*/true,
+      /*privacy_sandbox_enabled=*/true,
+      /*block_third_party_cookies=*/false,
+      /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW,
+      /*user_cookie_exceptions=*/{},
+      /*managed_cookie_setting=*/kNoSetting,
+      /*managed_cookie_exceptions=*/{});
+
+  privacy_sandbox_settings()->MaybeReconcilePrivacySandboxPref();
+
+  histograms.ExpectTotalCount(histogram_name, 1);
+  histograms.ExpectBucketCount(
+      histogram_name,
+      static_cast<int>(PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+                           kPSEnabledAllowAll),
+      1);
+
+  SetupTestState(
+      /*privacy_sandbox_available=*/true,
+      /*privacy_sandbox_enabled=*/true,
+      /*block_third_party_cookies=*/true,
+      /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW,
+      /*user_cookie_exceptions=*/{},
+      /*managed_cookie_setting=*/kNoSetting,
+      /*managed_cookie_exceptions=*/{});
+
+  privacy_sandbox_settings()->MaybeReconcilePrivacySandboxPref();
+
+  histograms.ExpectTotalCount(histogram_name, 2);
+  histograms.ExpectBucketCount(
+      histogram_name,
+      static_cast<int>(PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+                           kPSEnabledBlock3P),
+      1);
+
+  SetupTestState(
+      /*privacy_sandbox_available=*/true,
+      /*privacy_sandbox_enabled=*/true,
+      /*block_third_party_cookies=*/true,
+      /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_BLOCK,
+      /*user_cookie_exceptions=*/{},
+      /*managed_cookie_setting=*/kNoSetting,
+      /*managed_cookie_exceptions=*/{});
+
+  privacy_sandbox_settings()->MaybeReconcilePrivacySandboxPref();
+
+  histograms.ExpectTotalCount(histogram_name, 3);
+  histograms.ExpectBucketCount(
+      histogram_name,
+      static_cast<int>(PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+                           kPSEnabledBlockAll),
+      1);
+
+  profile()->GetTestingPrefService()->SetUserPref(
+      prefs::kPrivacySandboxPreferencesReconciled,
+      std::make_unique<base::Value>(false));
+  SetupTestState(
+      /*privacy_sandbox_available=*/true,
+      /*privacy_sandbox_enabled=*/false,
+      /*block_third_party_cookies=*/false,
+      /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW,
+      /*user_cookie_exceptions=*/{},
+      /*managed_cookie_setting=*/kNoSetting,
+      /*managed_cookie_exceptions=*/{});
+
+  privacy_sandbox_settings()->MaybeReconcilePrivacySandboxPref();
+
+  histograms.ExpectTotalCount(histogram_name, 4);
+  histograms.ExpectBucketCount(
+      histogram_name,
+      static_cast<int>(PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+                           kPSDisabledAllowAll),
+      1);
+
+  profile()->GetTestingPrefService()->SetUserPref(
+      prefs::kPrivacySandboxPreferencesReconciled,
+      std::make_unique<base::Value>(false));
+  SetupTestState(
+      /*privacy_sandbox_available=*/true,
+      /*privacy_sandbox_enabled=*/false,
+      /*block_third_party_cookies=*/true,
+      /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW,
+      /*user_cookie_exceptions=*/{},
+      /*managed_cookie_setting=*/kNoSetting,
+      /*managed_cookie_exceptions=*/{});
+
+  privacy_sandbox_settings()->MaybeReconcilePrivacySandboxPref();
+
+  histograms.ExpectTotalCount(histogram_name, 5);
+  histograms.ExpectBucketCount(
+      histogram_name,
+      static_cast<int>(PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+                           kPSDisabledBlock3P),
+      1);
+
+  profile()->GetTestingPrefService()->SetUserPref(
+      prefs::kPrivacySandboxPreferencesReconciled,
+      std::make_unique<base::Value>(false));
+  SetupTestState(
+      /*privacy_sandbox_available=*/true,
+      /*privacy_sandbox_enabled=*/false,
+      /*block_third_party_cookies=*/true,
+      /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_BLOCK,
+      /*user_cookie_exceptions=*/{},
+      /*managed_cookie_setting=*/kNoSetting,
+      /*managed_cookie_exceptions=*/{});
+
+  privacy_sandbox_settings()->MaybeReconcilePrivacySandboxPref();
+
+  histograms.ExpectTotalCount(histogram_name, 6);
+  histograms.ExpectBucketCount(
+      histogram_name,
+      static_cast<int>(PrivacySandboxSettings::PrivacySandboxSettings::
+                           SettingsPrivacySandboxEnabled::kPSDisabledBlockAll),
+      1);
+
+  // Verify that delayed reconciliation still logs properly.
+  profile()->GetTestingPrefService()->SetUserPref(
+      prefs::kPrivacySandboxPreferencesReconciled,
+      std::make_unique<base::Value>(false));
+  SetupTestState(
+      /*privacy_sandbox_available=*/true,
+      /*privacy_sandbox_enabled=*/true,
+      /*block_third_party_cookies=*/true,
+      /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_BLOCK,
+      /*user_cookie_exceptions=*/{},
+      /*managed_cookie_setting=*/kNoSetting,
+      /*managed_cookie_exceptions=*/{});
+
+  sync_service()->SetEmptyLastCycleSnapshot();
+
+  privacy_sandbox_settings()->MaybeReconcilePrivacySandboxPref();
+
+  EXPECT_FALSE(profile()->GetTestingPrefService()->GetBoolean(
+      prefs::kPrivacySandboxPreferencesReconciled));
+
+  histograms.ExpectTotalCount(histogram_name, 6);
+  histograms.ExpectBucketCount(
+      histogram_name,
+      static_cast<int>(PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+                           kPSDisabledBlockAll),
+      1);
+
+  sync_service()->SetNonEmptyLastCycleSnapshot();
+  sync_service()->FireSyncCycleCompleted();
+
+  histograms.ExpectTotalCount(histogram_name, 7);
+  histograms.ExpectBucketCount(
+      histogram_name,
+      static_cast<int>(PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+                           kPSDisabledBlockAll),
+      2);
+
+  profile()->GetTestingPrefService()->SetUserPref(
+      prefs::kPrivacySandboxPreferencesReconciled,
+      std::make_unique<base::Value>(false));
+  SetupTestState(
+      /*privacy_sandbox_available=*/true,
+      /*privacy_sandbox_enabled=*/false,
+      /*block_third_party_cookies=*/true,
+      /*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_BLOCK,
+      /*user_cookie_exceptions=*/{},
+      /*managed_cookie_setting=*/ContentSetting::CONTENT_SETTING_BLOCK,
+      /*managed_cookie_exceptions=*/{});
+
+  privacy_sandbox_settings()->MaybeReconcilePrivacySandboxPref();
+
+  histograms.ExpectTotalCount(histogram_name, 8);
+  histograms.ExpectBucketCount(
+      histogram_name,
+      static_cast<int>(PrivacySandboxSettings::SettingsPrivacySandboxEnabled::
+                           kPSDisabledPolicyBlockAll),
+      1);
+}
+
 class PrivacySandboxSettingsTestCookiesClearOnExitTurnedOff
     : public PrivacySandboxSettingsTest {
  public:
diff --git a/chrome/browser/profiles/android/profile_downloader_android.cc b/chrome/browser/profiles/android/profile_downloader_android.cc
deleted file mode 100644
index 1be400b2..0000000
--- a/chrome/browser/profiles/android/profile_downloader_android.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stddef.h>
-
-#include "base/android/jni_android.h"
-#include "base/android/jni_string.h"
-#include "base/macros.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/profiles/profile_android.h"
-#include "chrome/browser/profiles/profile_avatar_icon_util.h"
-#include "chrome/browser/profiles/profile_downloader.h"
-#include "chrome/browser/profiles/profile_downloader_delegate.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/signin/services/android/jni_headers/ProfileDownloader_jni.h"
-#include "components/signin/public/identity_manager/identity_manager.h"
-#include "content/public/browser/storage_partition.h"
-#include "ui/gfx/android/java_bitmap.h"
-
-using base::android::JavaParamRef;
-using base::android::ScopedJavaLocalRef;
-
-namespace {
-
-// An account fetcher callback.
-class AccountInfoRetriever : public ProfileDownloaderDelegate {
- public:
-  AccountInfoRetriever(Profile* profile,
-                       const CoreAccountInfo& core_account_info,
-                       const int desired_image_side_pixels)
-      : profile_(profile),
-        core_account_info_(core_account_info),
-        desired_image_side_pixels_(desired_image_side_pixels) {}
-
-  void Start() {
-    profile_image_downloader_.reset(new ProfileDownloader(this));
-    profile_image_downloader_->StartForAccount(core_account_info_.account_id);
-  }
-
- private:
-  void Shutdown() {
-    profile_image_downloader_.reset();
-    delete this;
-  }
-
-  // ProfileDownloaderDelegate implementation:
-  bool NeedsProfilePicture() const override {
-    return desired_image_side_pixels_ > 0;
-  }
-
-  int GetDesiredImageSideLength() const override {
-    return desired_image_side_pixels_;
-  }
-
-  signin::IdentityManager* GetIdentityManager() override {
-    return IdentityManagerFactory::GetForProfile(profile_);
-  }
-
-  network::mojom::URLLoaderFactory* GetURLLoaderFactory() override {
-    return content::BrowserContext::GetDefaultStoragePartition(profile_)
-        ->GetURLLoaderFactoryForBrowserProcess()
-        .get();
-  }
-
-  std::string GetCachedPictureURL() const override { return std::string(); }
-
-  bool IsPreSignin() const override { return true; }
-
-  void OnProfileDownloadSuccess(ProfileDownloader* downloader) override {
-    base::string16 full_name = downloader->GetProfileFullName();
-    base::string16 given_name = downloader->GetProfileGivenName();
-    SkBitmap bitmap = downloader->GetProfilePicture();
-    ScopedJavaLocalRef<jobject> jbitmap;
-    if (!bitmap.isNull() && bitmap.bytesPerPixel() != 0)
-      jbitmap = gfx::ConvertToJavaBitmap(bitmap);
-
-    JNIEnv* env = base::android::AttachCurrentThread();
-    Java_ProfileDownloader_onProfileDownloadSuccess(
-        env,
-        base::android::ConvertUTF8ToJavaString(env, core_account_info_.email),
-        base::android::ConvertUTF16ToJavaString(env, full_name),
-        base::android::ConvertUTF16ToJavaString(env, given_name), jbitmap);
-    Shutdown();
-  }
-
-  void OnProfileDownloadFailure(
-      ProfileDownloader* downloader,
-      ProfileDownloaderDelegate::FailureReason reason) override {
-    LOG(ERROR) << "Failed to download the profile information: " << reason;
-    Shutdown();
-  }
-
-  // The profile image downloader instance.
-  std::unique_ptr<ProfileDownloader> profile_image_downloader_;
-
-  // The browser profile associated with this download request.
-  Profile* profile_;
-
-  // The account info of account to be loaded.
-  const CoreAccountInfo core_account_info_;
-
-  // Desired side length of the profile image (in pixels).
-  const int desired_image_side_pixels_;
-
-  DISALLOW_COPY_AND_ASSIGN(AccountInfoRetriever);
-};
-
-}  // namespace
-
-// static
-void JNI_ProfileDownloader_StartFetchingAccountInfoFor(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& jprofile,
-    const JavaParamRef<jobject>& jcore_account_info,
-    jint image_side_pixels) {
-  AccountInfoRetriever* retriever = new AccountInfoRetriever(
-      ProfileAndroid::FromProfileAndroid(jprofile),
-      ConvertFromJavaCoreAccountInfo(env, jcore_account_info),
-      image_side_pixels);
-  retriever->Start();
-}
diff --git a/chrome/browser/profiles/profile_downloader.cc b/chrome/browser/profiles/profile_downloader.cc
index 75b524d..259ffd5 100644
--- a/chrome/browser/profiles/profile_downloader.cc
+++ b/chrome/browser/profiles/profile_downloader.cc
@@ -115,11 +115,6 @@
   if (maybe_account_info.has_value())
     account_info_ = maybe_account_info.value();
 
-#if defined(OS_ANDROID)
-  if (delegate_->IsPreSignin())
-    identity_manager_->ForceRefreshOfExtendedAccountInfo(account_id_);
-#endif
-
   if (account_info_.IsValid()) {
     // FetchImageData might call the delegate's OnProfileDownloadSuccess
     // synchronously, causing |this| to be deleted so there should not be more
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 188a502..e3de5620 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -1952,8 +1952,10 @@
       storage.GetProfileAttributesWithPath(profile->GetPath());
   DCHECK(entry);
 
-  if (profile->IsEphemeralGuestProfile())
+  if (profile->IsEphemeralGuestProfile()) {
     entry->SetIsGuest(true);
+    entry->SetIsOmitted(true);
+  }
 
   if (IsEphemeral(profile))
     entry->SetIsEphemeral(true);
diff --git a/chrome/browser/profiles/profile_manager_browsertest.cc b/chrome/browser/profiles/profile_manager_browsertest.cc
index 526658b..6ea5ab8 100644
--- a/chrome/browser/profiles/profile_manager_browsertest.cc
+++ b/chrome/browser/profiles/profile_manager_browsertest.cc
@@ -880,6 +880,7 @@
   ASSERT_NE(entry, nullptr);
   EXPECT_TRUE(entry->IsGuest());
   EXPECT_TRUE(entry->IsEphemeral());
+  EXPECT_TRUE(entry->IsOmitted());
 }
 
 INSTANTIATE_TEST_SUITE_P(AllGuestProfileTypes,
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc
index 08f17fc..543e40108 100644
--- a/chrome/browser/profiles/profile_manager_unittest.cc
+++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -628,15 +628,17 @@
   ASSERT_TRUE(profile);
   if (IsEphemeral()) {
     EXPECT_TRUE(profile->IsEphemeralGuestProfile());
+    EXPECT_FALSE(profile->IsGuestSession());
     EXPECT_FALSE(profile->IsOffTheRecord());
   } else {
     EXPECT_TRUE(profile->IsGuestSession());
+    EXPECT_FALSE(profile->IsEphemeralGuestProfile());
     EXPECT_TRUE(profile->IsOffTheRecord());
   }
 }
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-TEST_P(ProfileManagerGuestTest, GuestProfileIngonito) {
+TEST_P(ProfileManagerGuestTest, GuestProfileIncognito) {
   Profile* primary_profile = ProfileManager::GetPrimaryUserProfile();
   EXPECT_TRUE(primary_profile->IsOffTheRecord());
 
@@ -666,6 +668,22 @@
   EXPECT_EQ(expected_path, guest_path);
 }
 
+TEST_P(ProfileManagerGuestTest, GuestProfileAttributes) {
+  // In these tests, the primary profile is a guest one.
+  Profile* primary_profile = ProfileManager::GetPrimaryUserProfile();
+  ProfileAttributesEntry* entry =
+      g_browser_process->profile_manager()
+          ->GetProfileAttributesStorage()
+          .GetProfileAttributesWithPath(primary_profile->GetPath());
+  if (IsEphemeral()) {
+    ASSERT_NE(entry, nullptr);
+    EXPECT_TRUE(entry->IsEphemeral());
+    EXPECT_TRUE(entry->IsOmitted());
+  } else {
+    EXPECT_EQ(entry, nullptr);
+  }
+}
+
 INSTANTIATE_TEST_SUITE_P(All,
                          ProfileManagerGuestTest,
                          /*is_ephemeral=*/testing::Bool());
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn
index 276b445..5bba374 100644
--- a/chrome/browser/resources/BUILD.gn
+++ b/chrome/browser/resources/BUILD.gn
@@ -46,6 +46,7 @@
       "chromeos/accessibility:build",
       "chromeos/emoji_picker:resources",
       "chromeos/multidevice_internals:resources",
+      "chromeos/network_ui:resources",
       "nearby_internals:resources",
       "nearby_share:resources",
       "settings/chromeos:resources",
diff --git a/chrome/browser/resources/bluetooth_internals/adapter_broker.js b/chrome/browser/resources/bluetooth_internals/adapter_broker.js
index b013940..bdd14ea 100644
--- a/chrome/browser/resources/bluetooth_internals/adapter_broker.js
+++ b/chrome/browser/resources/bluetooth_internals/adapter_broker.js
@@ -14,174 +14,174 @@
  * Javascript for AdapterBroker, served from
  *     chrome://bluetooth-internals/.
  */
-  /** @typedef {bluetooth.mojom.AdapterRemote} */
-  let AdapterRemote;
-  /** @typedef {bluetooth.mojom.DeviceRemote} */
-  let DeviceRemote;
-  /** @typedef {bluetooth.mojom.DiscoverySessionRemote} */
-  let DiscoverySessionRemote;
+/** @typedef {bluetooth.mojom.AdapterRemote} */
+let AdapterRemote;
+/** @typedef {bluetooth.mojom.DeviceRemote} */
+let DeviceRemote;
+/** @typedef {bluetooth.mojom.DiscoverySessionRemote} */
+let DiscoverySessionRemote;
 
-  /**
-   * Enum of adapter property names. Used for adapterchanged events.
-   * @enum {string}
-   */
-  export const AdapterProperty = {
-    DISCOVERABLE: 'discoverable',
-    DISCOVERING: 'discovering',
-    POWERED: 'powered',
-    PRESENT: 'present',
-  };
+/**
+ * Enum of adapter property names. Used for adapterchanged events.
+ * @enum {string}
+ */
+export const AdapterProperty = {
+  DISCOVERABLE: 'discoverable',
+  DISCOVERING: 'discovering',
+  POWERED: 'powered',
+  PRESENT: 'present',
+};
 
-  /**
-   * The proxy class of an adapter and router of adapter events.
-   * Exposes an EventTarget interface that allows other object to subscribe to
-   * to specific AdapterObserver events.
-   * Provides remote access to Adapter functions. Converts parameters to Mojo
-   * handles and back when necessary.
-   *
-   * @implements {bluetooth.mojom.AdapterObserverInterface}
-   */
-  export class AdapterBroker extends EventTarget {
-    /** @param {!AdapterRemote} adapter */
-    constructor(adapter) {
-      super();
-      this.adapterObserverReceiver_ =
-          new bluetooth.mojom.AdapterObserverReceiver(this);
-      this.adapter_ = adapter;
-      this.adapter_.addObserver(
-          this.adapterObserverReceiver_.$.bindNewPipeAndPassRemote());
-    }
-
-    presentChanged(present) {
-      this.dispatchEvent(new CustomEvent('adapterchanged', {
-        detail: {
-          property: AdapterProperty.PRESENT,
-          value: present,
-        }
-      }));
-    }
-
-    poweredChanged(powered) {
-      this.dispatchEvent(new CustomEvent('adapterchanged', {
-        detail: {
-          property: AdapterProperty.POWERED,
-          value: powered,
-        }
-      }));
-    }
-
-    discoverableChanged(discoverable) {
-      this.dispatchEvent(new CustomEvent('adapterchanged', {
-        detail: {
-          property: AdapterProperty.DISCOVERABLE,
-          value: discoverable,
-        }
-      }));
-    }
-
-    discoveringChanged(discovering) {
-      this.dispatchEvent(new CustomEvent('adapterchanged', {
-        detail: {
-          property: AdapterProperty.DISCOVERING,
-          value: discovering,
-        }
-      }));
-    }
-
-    deviceAdded(device) {
-      this.dispatchEvent(
-          new CustomEvent('deviceadded', {detail: {deviceInfo: device}}));
-    }
-
-    deviceChanged(device) {
-      this.dispatchEvent(
-          new CustomEvent('devicechanged', {detail: {deviceInfo: device}}));
-    }
-
-    deviceRemoved(device) {
-      this.dispatchEvent(
-          new CustomEvent('deviceremoved', {detail: {deviceInfo: device}}));
-    }
-
-    /**
-     * Creates a GATT connection to the device with |address|.
-     * @param {string} address
-     * @return {!Promise<!bluetooth.mojom.Device>}
-     */
-    connectToDevice(address) {
-      return this.adapter_.connectToDevice(address).then(function(response) {
-        if (response.result != bluetooth.mojom.ConnectResult.SUCCESS) {
-          // TODO(crbug.com/663394): Replace with more descriptive error
-          // messages.
-          const ConnectResult = bluetooth.mojom.ConnectResult;
-          const errorString = Object.keys(ConnectResult).find(function(key) {
-            return ConnectResult[key] === response.result;
-          });
-
-          throw new Error(errorString);
-        }
-
-        return response.device;
-      });
-    }
-
-    /**
-     * Gets an array of currently detectable devices from the Adapter service.
-     * @return {Promise<{devices: Array<!bluetooth.mojom.DeviceInfo>}>}
-     */
-    getDevices() {
-      return this.adapter_.getDevices();
-    }
-
-    /**
-     * Gets the current state of the Adapter.
-     * @return {Promise<{info: bluetooth.mojom.AdapterInfo}>}
-     */
-    getInfo() {
-      return this.adapter_.getInfo();
-    }
-
-
-    /**
-     * Requests the adapter to start a new discovery session.
-     * @return {!Promise<!bluetooth.mojom.DiscoverySessionRemote>}
-     */
-    startDiscoverySession() {
-      return this.adapter_.startDiscoverySession().then(function(response) {
-        if (!response.session) {
-          throw new Error('Discovery session failed to start');
-        }
-
-        return response.session;
-      });
-    }
+/**
+ * The proxy class of an adapter and router of adapter events.
+ * Exposes an EventTarget interface that allows other object to subscribe to
+ * to specific AdapterObserver events.
+ * Provides remote access to Adapter functions. Converts parameters to Mojo
+ * handles and back when necessary.
+ *
+ * @implements {bluetooth.mojom.AdapterObserverInterface}
+ */
+export class AdapterBroker extends EventTarget {
+  /** @param {!AdapterRemote} adapter */
+  constructor(adapter) {
+    super();
+    this.adapterObserverReceiver_ =
+        new bluetooth.mojom.AdapterObserverReceiver(this);
+    this.adapter_ = adapter;
+    this.adapter_.addObserver(
+        this.adapterObserverReceiver_.$.bindNewPipeAndPassRemote());
   }
 
-  let adapterBroker = null;
+  presentChanged(present) {
+    this.dispatchEvent(new CustomEvent('adapterchanged', {
+      detail: {
+        property: AdapterProperty.PRESENT,
+        value: present,
+      }
+    }));
+  }
+
+  poweredChanged(powered) {
+    this.dispatchEvent(new CustomEvent('adapterchanged', {
+      detail: {
+        property: AdapterProperty.POWERED,
+        value: powered,
+      }
+    }));
+  }
+
+  discoverableChanged(discoverable) {
+    this.dispatchEvent(new CustomEvent('adapterchanged', {
+      detail: {
+        property: AdapterProperty.DISCOVERABLE,
+        value: discoverable,
+      }
+    }));
+  }
+
+  discoveringChanged(discovering) {
+    this.dispatchEvent(new CustomEvent('adapterchanged', {
+      detail: {
+        property: AdapterProperty.DISCOVERING,
+        value: discovering,
+      }
+    }));
+  }
+
+  deviceAdded(device) {
+    this.dispatchEvent(
+        new CustomEvent('deviceadded', {detail: {deviceInfo: device}}));
+  }
+
+  deviceChanged(device) {
+    this.dispatchEvent(
+        new CustomEvent('devicechanged', {detail: {deviceInfo: device}}));
+  }
+
+  deviceRemoved(device) {
+    this.dispatchEvent(
+        new CustomEvent('deviceremoved', {detail: {deviceInfo: device}}));
+  }
 
   /**
-   * Initializes an AdapterBroker if one doesn't exist.
-   * @param {!mojom.BluetoothInternalsHandlerRemote=}
-   *     opt_bluetoothInternalsHandler
-   * @return {!Promise<!AdapterBroker>} resolves with
-   *     AdapterBroker, rejects if Bluetooth is not supported.
+   * Creates a GATT connection to the device with |address|.
+   * @param {string} address
+   * @return {!Promise<!bluetooth.mojom.Device>}
    */
-  export function getAdapterBroker(opt_bluetoothInternalsHandler) {
-    if (adapterBroker) {
-      return Promise.resolve(adapterBroker);
-    }
+  connectToDevice(address) {
+    return this.adapter_.connectToDevice(address).then(function(response) {
+      if (response.result != bluetooth.mojom.ConnectResult.SUCCESS) {
+        // TODO(crbug.com/663394): Replace with more descriptive error
+        // messages.
+        const ConnectResult = bluetooth.mojom.ConnectResult;
+        const errorString = Object.keys(ConnectResult).find(function(key) {
+          return ConnectResult[key] === response.result;
+        });
 
-    const bluetoothInternalsHandler = opt_bluetoothInternalsHandler ?
-        opt_bluetoothInternalsHandler :
-        mojom.BluetoothInternalsHandler.getRemote();
-
-    // Get an Adapter service.
-    return bluetoothInternalsHandler.getAdapter().then(function(response) {
-      if (!response.adapter) {
-        throw new Error('Bluetooth Not Supported on this platform.');
+        throw new Error(errorString);
       }
 
-      adapterBroker = new AdapterBroker(response.adapter);
-      return adapterBroker;
+      return response.device;
     });
   }
+
+  /**
+   * Gets an array of currently detectable devices from the Adapter service.
+   * @return {Promise<{devices: Array<!bluetooth.mojom.DeviceInfo>}>}
+   */
+  getDevices() {
+    return this.adapter_.getDevices();
+  }
+
+  /**
+   * Gets the current state of the Adapter.
+   * @return {Promise<{info: bluetooth.mojom.AdapterInfo}>}
+   */
+  getInfo() {
+    return this.adapter_.getInfo();
+  }
+
+
+  /**
+   * Requests the adapter to start a new discovery session.
+   * @return {!Promise<!bluetooth.mojom.DiscoverySessionRemote>}
+   */
+  startDiscoverySession() {
+    return this.adapter_.startDiscoverySession().then(function(response) {
+      if (!response.session) {
+        throw new Error('Discovery session failed to start');
+      }
+
+      return response.session;
+    });
+  }
+}
+
+let adapterBroker = null;
+
+/**
+ * Initializes an AdapterBroker if one doesn't exist.
+ * @param {!mojom.BluetoothInternalsHandlerRemote=}
+ *     opt_bluetoothInternalsHandler
+ * @return {!Promise<!AdapterBroker>} resolves with
+ *     AdapterBroker, rejects if Bluetooth is not supported.
+ */
+export function getAdapterBroker(opt_bluetoothInternalsHandler) {
+  if (adapterBroker) {
+    return Promise.resolve(adapterBroker);
+  }
+
+  const bluetoothInternalsHandler = opt_bluetoothInternalsHandler ?
+      opt_bluetoothInternalsHandler :
+      mojom.BluetoothInternalsHandler.getRemote();
+
+  // Get an Adapter service.
+  return bluetoothInternalsHandler.getAdapter().then(function(response) {
+    if (!response.adapter) {
+      throw new Error('Bluetooth Not Supported on this platform.');
+    }
+
+    adapterBroker = new AdapterBroker(response.adapter);
+    return adapterBroker;
+  });
+}
diff --git a/chrome/browser/resources/bluetooth_internals/adapter_page.js b/chrome/browser/resources/bluetooth_internals/adapter_page.js
index b142120..4fd9fb8 100644
--- a/chrome/browser/resources/bluetooth_internals/adapter_page.js
+++ b/chrome/browser/resources/bluetooth_internals/adapter_page.js
@@ -10,55 +10,55 @@
 import {ObjectFieldSet} from './object_fieldset.js';
 import {Page} from './page.js';
 
-  const PROPERTY_NAMES = {
-    address: 'Address',
-    name: 'Name',
-    systemName: 'System Name',
-    initialized: 'Initialized',
-    present: 'Present',
-    powered: 'Powered',
-    discoverable: 'Discoverable',
-    discovering: 'Discovering',
-  };
+const PROPERTY_NAMES = {
+  address: 'Address',
+  name: 'Name',
+  systemName: 'System Name',
+  initialized: 'Initialized',
+  present: 'Present',
+  powered: 'Powered',
+  discoverable: 'Discoverable',
+  discovering: 'Discovering',
+};
+
+/**
+ * Page that contains an ObjectFieldSet that displays the latest AdapterInfo.
+ */
+export class AdapterPage extends Page {
+  constructor() {
+    super('adapter', 'Adapter', 'adapter');
+
+    this.adapterFieldSet = new ObjectFieldSet();
+    this.adapterFieldSet.setPropertyDisplayNames(PROPERTY_NAMES);
+    this.pageDiv.appendChild(this.adapterFieldSet);
+
+    this.refreshBtn_ = $('adapter-refresh-btn');
+    this.refreshBtn_.addEventListener('click', event => {
+      this.refreshBtn_.disabled = true;
+      this.pageDiv.dispatchEvent(new CustomEvent('refreshpressed'));
+    });
+  }
 
   /**
-   * Page that contains an ObjectFieldSet that displays the latest AdapterInfo.
+   * Sets the information to display in fieldset.
+   * @param {!bluetooth.mojom.AdapterInfo} info
    */
-  export class AdapterPage extends Page {
-    constructor() {
-      super('adapter', 'Adapter', 'adapter');
-
-      this.adapterFieldSet = new ObjectFieldSet();
-      this.adapterFieldSet.setPropertyDisplayNames(PROPERTY_NAMES);
-      this.pageDiv.appendChild(this.adapterFieldSet);
-
-      this.refreshBtn_ = $('adapter-refresh-btn');
-      this.refreshBtn_.addEventListener('click', event => {
-        this.refreshBtn_.disabled = true;
-        this.pageDiv.dispatchEvent(new CustomEvent('refreshpressed'));
-      });
+  setAdapterInfo(info) {
+    if (info.hasOwnProperty('systemName') && !info.systemName) {
+      // The adapter might not implement 'systemName'. In that case, delete
+      // this property so that it's not displayed on adapterFieldSet.
+      delete info.systemName;
     }
 
-    /**
-     * Sets the information to display in fieldset.
-     * @param {!bluetooth.mojom.AdapterInfo} info
-     */
-    setAdapterInfo(info) {
-      if (info.hasOwnProperty('systemName') && !info.systemName) {
-        // The adapter might not implement 'systemName'. In that case, delete
-        // this property so that it's not displayed on adapterFieldSet.
-        delete info.systemName;
-      }
-
-      this.adapterFieldSet.setObject(info);
-      this.refreshBtn_.disabled = false;
-    }
-
-    /**
-     * Redraws the fieldset displaying the adapter info.
-     */
-    redraw() {
-      this.adapterFieldSet.redraw();
-      this.refreshBtn_.disabled = false;
-    }
+    this.adapterFieldSet.setObject(info);
+    this.refreshBtn_.disabled = false;
   }
+
+  /**
+   * Redraws the fieldset displaying the adapter info.
+   */
+  redraw() {
+    this.adapterFieldSet.redraw();
+    this.refreshBtn_.disabled = false;
+  }
+}
diff --git a/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js b/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
index d2e7558..342fae0 100644
--- a/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
+++ b/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
@@ -12,19 +12,21 @@
 import './device.mojom-lite.js';
 import './adapter.mojom-lite.js';
 import './bluetooth_internals.mojom-lite.js';
-import {$} from 'chrome://resources/js/util.m.js';
-import {assert} from 'chrome://resources/js/assert.m.js';
 
-import {getAdapterBroker, AdapterBroker, AdapterProperty} from './adapter_broker.js';
-import {DeviceCollection} from './device_collection.js';
-import {Sidebar} from './sidebar.js';
+import {assert} from 'chrome://resources/js/assert.m.js';
+import {$} from 'chrome://resources/js/util.m.js';
+
+import {AdapterBroker, AdapterProperty, getAdapterBroker} from './adapter_broker.js';
 import {AdapterPage} from './adapter_page.js';
+import {DebugLogPage} from './debug_log_page.js';
+import {DeviceCollection} from './device_collection.js';
 import {DeviceDetailsPage} from './device_details_page.js';
 import {DevicesPage, ScanStatus} from './devices_page.js';
-import {DebugLogPage} from './debug_log_page.js';
 import {PageManager, PageManagerObserver} from './page_manager.js';
+import {Sidebar} from './sidebar.js';
 import {Snackbar, SnackbarType} from './snackbar.js';
 
+
 // Expose for testing.
 /** @type {AdapterBroker} */
 export let adapterBroker = null;
@@ -38,280 +40,278 @@
 /** @type {PageManager} */
 export const pageManager = PageManager.getInstance();
 
-  devices = new DeviceCollection([]);
+devices = new DeviceCollection([]);
 
-  /** @type {AdapterPage} */
-  let adapterPage = null;
-  /** @type {DevicesPage} */
-  let devicesPage = null;
-  /** @type {DebugLogPage} */
-  let debugLogPage = null;
+/** @type {AdapterPage} */
+let adapterPage = null;
+/** @type {DevicesPage} */
+let devicesPage = null;
+/** @type {DebugLogPage} */
+let debugLogPage = null;
 
-  /** @type {bluetooth.mojom.DiscoverySessionRemote} */
-  let discoverySession = null;
+/** @type {bluetooth.mojom.DiscoverySessionRemote} */
+let discoverySession = null;
 
-  /** @type {boolean} */
-  let userRequestedScanStop = false;
+/** @type {boolean} */
+let userRequestedScanStop = false;
 
-  /** @type {!mojom.BluetoothInternalsHandlerRemote} */
-  const bluetoothInternalsHandler = mojom.BluetoothInternalsHandler.getRemote();
+/** @type {!mojom.BluetoothInternalsHandlerRemote} */
+const bluetoothInternalsHandler = mojom.BluetoothInternalsHandler.getRemote();
 
-  /**
-   * Observer for page changes. Used to update page title header.
-   */
-  const PageObserver = class extends PageManagerObserver {
-    updateHistory(path) {
-      window.location.hash = '#' + path;
-    }
-
-    /**
-     * Sets the page title. Called by PageManager.
-     * @override
-     * @param {string} title
-     */
-    updateTitle(title) {
-      document.querySelector('.page-title').textContent = title;
-    }
-  };
-
-  /**
-   * Removes DeviceDetailsPage with matching device |address|. The associated
-   * sidebar item is also removed.
-   * @param {string} address
-   */
-  function removeDeviceDetailsPage(address) {
-    const id = 'devices/' + address.toLowerCase();
-    sidebarObj.removeItem(id);
-
-    const deviceDetailsPage =
-        /** @type {!DeviceDetailsPage} */ (
-            pageManager.registeredPages.get(id));
-    assert(deviceDetailsPage, 'Device Details page must exist');
-
-    deviceDetailsPage.disconnect();
-    deviceDetailsPage.pageDiv.parentNode.removeChild(deviceDetailsPage.pageDiv);
-
-    // Inform the devices page that the user is inspecting this device.
-    // This will update the links in the device table.
-    devicesPage.setInspecting(
-        deviceDetailsPage.deviceInfo, false /* isInspecting */);
-
-    pageManager.unregister(deviceDetailsPage);
+/**
+ * Observer for page changes. Used to update page title header.
+ */
+const PageObserver = class extends PageManagerObserver {
+  updateHistory(path) {
+    window.location.hash = '#' + path;
   }
 
   /**
-   * Creates a DeviceDetailsPage with the given |deviceInfo|, appends it to
-   * '#page-container', and adds a sidebar item to show the new page. If a
-   * page exists that matches |deviceInfo.address|, nothing is created and the
-   * existing page is returned.
-   * @param {!bluetooth.mojom.DeviceInfo} deviceInfo
-   * @return {!DeviceDetailsPage}
+   * Sets the page title. Called by PageManager.
+   * @override
+   * @param {string} title
    */
-  function makeDeviceDetailsPage(deviceInfo) {
-    const deviceDetailsPageId = 'devices/' + deviceInfo.address.toLowerCase();
-    let deviceDetailsPage =
-        /** @type {?DeviceDetailsPage} */ (
-            pageManager.registeredPages.get(deviceDetailsPageId));
-    if (deviceDetailsPage) {
-      return deviceDetailsPage;
-    }
+  updateTitle(title) {
+    document.querySelector('.page-title').textContent = title;
+  }
+};
 
-    const pageSection = document.createElement('section');
-    pageSection.hidden = true;
-    pageSection.id = deviceDetailsPageId;
-    $('page-container').appendChild(pageSection);
+/**
+ * Removes DeviceDetailsPage with matching device |address|. The associated
+ * sidebar item is also removed.
+ * @param {string} address
+ */
+function removeDeviceDetailsPage(address) {
+  const id = 'devices/' + address.toLowerCase();
+  sidebarObj.removeItem(id);
 
-    deviceDetailsPage = new DeviceDetailsPage(deviceDetailsPageId, deviceInfo);
+  const deviceDetailsPage =
+      /** @type {!DeviceDetailsPage} */ (pageManager.registeredPages.get(id));
+  assert(deviceDetailsPage, 'Device Details page must exist');
 
-    deviceDetailsPage.pageDiv.addEventListener('infochanged', function(event) {
-      devices.addOrUpdate(event.detail.info);
-    });
+  deviceDetailsPage.disconnect();
+  deviceDetailsPage.pageDiv.parentNode.removeChild(deviceDetailsPage.pageDiv);
 
-    deviceDetailsPage.pageDiv.addEventListener(
-        'forgetpressed', function(event) {
-          pageManager.showPageByName(devicesPage.name);
-          removeDeviceDetailsPage(event.detail.address);
-        });
+  // Inform the devices page that the user is inspecting this device.
+  // This will update the links in the device table.
+  devicesPage.setInspecting(
+      deviceDetailsPage.deviceInfo, false /* isInspecting */);
 
-    // Inform the devices page that the user is inspecting this device.
-    // This will update the links in the device table.
-    devicesPage.setInspecting(deviceInfo, true /* isInspecting */);
-    pageManager.register(deviceDetailsPage);
+  pageManager.unregister(deviceDetailsPage);
+}
 
-    sidebarObj.addItem({
-      pageName: deviceDetailsPageId,
-      text: deviceInfo.nameForDisplay,
-    });
-
-    deviceDetailsPage.connect();
+/**
+ * Creates a DeviceDetailsPage with the given |deviceInfo|, appends it to
+ * '#page-container', and adds a sidebar item to show the new page. If a
+ * page exists that matches |deviceInfo.address|, nothing is created and the
+ * existing page is returned.
+ * @param {!bluetooth.mojom.DeviceInfo} deviceInfo
+ * @return {!DeviceDetailsPage}
+ */
+function makeDeviceDetailsPage(deviceInfo) {
+  const deviceDetailsPageId = 'devices/' + deviceInfo.address.toLowerCase();
+  let deviceDetailsPage =
+      /** @type {?DeviceDetailsPage} */ (
+          pageManager.registeredPages.get(deviceDetailsPageId));
+  if (deviceDetailsPage) {
     return deviceDetailsPage;
   }
 
-  /**
-   * Updates the DeviceDetailsPage with the matching device |address| and
-   * redraws it.
-   * @param {string} address
-   */
-  function updateDeviceDetailsPage(address) {
-    const detailPageId = 'devices/' + address.toLowerCase();
-    const page = pageManager.registeredPages.get(detailPageId);
-    if (page) {
-      /** @type {!DeviceDetailsPage} */ (page).redraw();
+  const pageSection = document.createElement('section');
+  pageSection.hidden = true;
+  pageSection.id = deviceDetailsPageId;
+  $('page-container').appendChild(pageSection);
+
+  deviceDetailsPage = new DeviceDetailsPage(deviceDetailsPageId, deviceInfo);
+
+  deviceDetailsPage.pageDiv.addEventListener('infochanged', function(event) {
+    devices.addOrUpdate(event.detail.info);
+  });
+
+  deviceDetailsPage.pageDiv.addEventListener('forgetpressed', function(event) {
+    pageManager.showPageByName(devicesPage.name);
+    removeDeviceDetailsPage(event.detail.address);
+  });
+
+  // Inform the devices page that the user is inspecting this device.
+  // This will update the links in the device table.
+  devicesPage.setInspecting(deviceInfo, true /* isInspecting */);
+  pageManager.register(deviceDetailsPage);
+
+  sidebarObj.addItem({
+    pageName: deviceDetailsPageId,
+    text: deviceInfo.nameForDisplay,
+  });
+
+  deviceDetailsPage.connect();
+  return deviceDetailsPage;
+}
+
+/**
+ * Updates the DeviceDetailsPage with the matching device |address| and
+ * redraws it.
+ * @param {string} address
+ */
+function updateDeviceDetailsPage(address) {
+  const detailPageId = 'devices/' + address.toLowerCase();
+  const page = pageManager.registeredPages.get(detailPageId);
+  if (page) {
+    /** @type {!DeviceDetailsPage} */ (page).redraw();
+  }
+}
+
+function updateStoppedDiscoverySession() {
+  devicesPage.setScanStatus(ScanStatus.OFF);
+  discoverySession = null;
+}
+
+function setupAdapterSystem(response) {
+  adapterBroker.addEventListener('adapterchanged', function(event) {
+    adapterPage.adapterFieldSet.value[event.detail.property] =
+        event.detail.value;
+    adapterPage.redraw();
+
+    if (event.detail.property == AdapterProperty.DISCOVERING &&
+        !event.detail.value && !userRequestedScanStop && discoverySession) {
+      updateStoppedDiscoverySession();
+      Snackbar.show(
+          'Discovery session ended unexpectedly', SnackbarType.WARNING);
     }
-  }
+  });
 
-  function updateStoppedDiscoverySession() {
-    devicesPage.setScanStatus(ScanStatus.OFF);
-    discoverySession = null;
-  }
+  adapterPage.setAdapterInfo(response.info);
 
-  function setupAdapterSystem(response) {
-    adapterBroker.addEventListener('adapterchanged', function(event) {
-      adapterPage.adapterFieldSet.value[event.detail.property] =
-          event.detail.value;
-      adapterPage.redraw();
-
-      if (event.detail.property == AdapterProperty.DISCOVERING &&
-          !event.detail.value && !userRequestedScanStop && discoverySession) {
-        updateStoppedDiscoverySession();
-        Snackbar.show(
-            'Discovery session ended unexpectedly', SnackbarType.WARNING);
+  adapterPage.pageDiv.addEventListener('refreshpressed', function() {
+    adapterBroker.getInfo().then(function(response) {
+      if (response && response.info) {
+        adapterPage.setAdapterInfo(response.info);
+      } else {
+        console.error('Failed to fetch adapter info.');
       }
     });
+  });
+}
 
-    adapterPage.setAdapterInfo(response.info);
+function setupDeviceSystem(response) {
+  // Hook up device collection events.
+  adapterBroker.addEventListener('deviceadded', function(event) {
+    devices.addOrUpdate(event.detail.deviceInfo);
+    updateDeviceDetailsPage(event.detail.deviceInfo.address);
+  });
+  adapterBroker.addEventListener('devicechanged', function(event) {
+    devices.addOrUpdate(event.detail.deviceInfo);
+    updateDeviceDetailsPage(event.detail.deviceInfo.address);
+  });
+  adapterBroker.addEventListener('deviceremoved', function(event) {
+    devices.remove(event.detail.deviceInfo);
+    updateDeviceDetailsPage(event.detail.deviceInfo.address);
+  });
 
-    adapterPage.pageDiv.addEventListener('refreshpressed', function() {
-      adapterBroker.getInfo().then(function(response) {
-        if (response && response.info) {
-          adapterPage.setAdapterInfo(response.info);
-        } else {
-          console.error('Failed to fetch adapter info.');
-        }
-      });
-    });
-  }
+  response.devices.forEach(devices.addOrUpdate, devices /* this */);
 
-  function setupDeviceSystem(response) {
-    // Hook up device collection events.
-    adapterBroker.addEventListener('deviceadded', function(event) {
-      devices.addOrUpdate(event.detail.deviceInfo);
-      updateDeviceDetailsPage(event.detail.deviceInfo.address);
-    });
-    adapterBroker.addEventListener('devicechanged', function(event) {
-      devices.addOrUpdate(event.detail.deviceInfo);
-      updateDeviceDetailsPage(event.detail.deviceInfo.address);
-    });
-    adapterBroker.addEventListener('deviceremoved', function(event) {
-      devices.remove(event.detail.deviceInfo);
-      updateDeviceDetailsPage(event.detail.deviceInfo.address);
-    });
+  devicesPage.setDevices(devices);
 
-    response.devices.forEach(devices.addOrUpdate, devices /* this */);
+  devicesPage.pageDiv.addEventListener('inspectpressed', function(event) {
+    const detailsPage =
+        makeDeviceDetailsPage(devices.getByAddress(event.detail.address));
+    pageManager.showPageByName(detailsPage.name);
+  });
 
-    devicesPage.setDevices(devices);
+  devicesPage.pageDiv.addEventListener('forgetpressed', function(event) {
+    pageManager.showPageByName(devicesPage.name);
+    removeDeviceDetailsPage(event.detail.address);
+  });
 
-    devicesPage.pageDiv.addEventListener('inspectpressed', function(event) {
-      const detailsPage =
-          makeDeviceDetailsPage(devices.getByAddress(event.detail.address));
-      pageManager.showPageByName(detailsPage.name);
-    });
+  devicesPage.pageDiv.addEventListener('scanpressed', function(event) {
+    if (discoverySession) {
+      userRequestedScanStop = true;
+      devicesPage.setScanStatus(ScanStatus.STOPPING);
 
-    devicesPage.pageDiv.addEventListener('forgetpressed', function(event) {
-      pageManager.showPageByName(devicesPage.name);
-      removeDeviceDetailsPage(event.detail.address);
-    });
-
-    devicesPage.pageDiv.addEventListener('scanpressed', function(event) {
-      if (discoverySession) {
-        userRequestedScanStop = true;
-        devicesPage.setScanStatus(ScanStatus.STOPPING);
-
-        discoverySession.stop().then(function(response) {
-          if (response.success) {
-            updateStoppedDiscoverySession();
-            userRequestedScanStop = false;
-            return;
-          }
-
-          devicesPage.setScanStatus(ScanStatus.ON);
-          Snackbar.show('Failed to stop discovery session', SnackbarType.ERROR);
+      discoverySession.stop().then(function(response) {
+        if (response.success) {
+          updateStoppedDiscoverySession();
           userRequestedScanStop = false;
-        });
+          return;
+        }
 
-        return;
-      }
+        devicesPage.setScanStatus(ScanStatus.ON);
+        Snackbar.show('Failed to stop discovery session', SnackbarType.ERROR);
+        userRequestedScanStop = false;
+      });
 
-      devicesPage.setScanStatus(ScanStatus.STARTING);
-      adapterBroker.startDiscoverySession()
-          .then(function(session) {
-            discoverySession = assert(session);
-
-            discoverySession.onConnectionError.addListener(() => {
-              updateStoppedDiscoverySession();
-              Snackbar.show('Discovery session ended', SnackbarType.WARNING);
-            });
-
-            devicesPage.setScanStatus(ScanStatus.ON);
-          })
-          .catch(function(error) {
-            devicesPage.setScanStatus(ScanStatus.OFF);
-            Snackbar.show(
-                'Failed to start discovery session', SnackbarType.ERROR);
-            console.error(error);
-          });
-    });
-  }
-
-  function setupPages() {
-    sidebarObj = new Sidebar(/** @type {!HTMLElement} */ ($('sidebar')));
-    $('menu-btn').addEventListener('click', function() {
-      sidebarObj.open();
-    });
-    pageManager.addObserver(sidebarObj);
-    pageManager.addObserver(new PageObserver());
-
-    devicesPage = new DevicesPage();
-    pageManager.register(devicesPage);
-    adapterPage = new AdapterPage();
-    pageManager.register(adapterPage);
-    debugLogPage = new DebugLogPage(bluetoothInternalsHandler);
-    pageManager.register(debugLogPage);
-
-    // Set up hash-based navigation.
-    window.addEventListener('hashchange', function() {
-      // If a user navigates and the page doesn't exist, do nothing.
-      const pageName = window.location.hash.substr(1);
-      if ($(pageName)) {
-        pageManager.showPageByName(pageName);
-      }
-    });
-
-    if (!window.location.hash) {
-      pageManager.showPageByName(adapterPage.name);
       return;
     }
 
-    // Only the root pages are available on page load.
-    pageManager.showPageByName(window.location.hash.split('/')[0].substr(1));
-  }
+    devicesPage.setScanStatus(ScanStatus.STARTING);
+    adapterBroker.startDiscoverySession()
+        .then(function(session) {
+          discoverySession = assert(session);
 
-  export function initializeViews() {
-    setupPages();
-    return getAdapterBroker()
-        .then(function(broker) {
-          adapterBroker = broker;
+          discoverySession.onConnectionError.addListener(() => {
+            updateStoppedDiscoverySession();
+            Snackbar.show('Discovery session ended', SnackbarType.WARNING);
+          });
+
+          devicesPage.setScanStatus(ScanStatus.ON);
         })
-        .then(function() {
-          return adapterBroker.getInfo();
-        })
-        .then(setupAdapterSystem)
-        .then(function() {
-          return adapterBroker.getDevices();
-        })
-        .then(setupDeviceSystem)
         .catch(function(error) {
-          Snackbar.show(error.message, SnackbarType.ERROR);
+          devicesPage.setScanStatus(ScanStatus.OFF);
+          Snackbar.show(
+              'Failed to start discovery session', SnackbarType.ERROR);
           console.error(error);
         });
+  });
+}
+
+function setupPages() {
+  sidebarObj = new Sidebar(/** @type {!HTMLElement} */ ($('sidebar')));
+  $('menu-btn').addEventListener('click', function() {
+    sidebarObj.open();
+  });
+  pageManager.addObserver(sidebarObj);
+  pageManager.addObserver(new PageObserver());
+
+  devicesPage = new DevicesPage();
+  pageManager.register(devicesPage);
+  adapterPage = new AdapterPage();
+  pageManager.register(adapterPage);
+  debugLogPage = new DebugLogPage(bluetoothInternalsHandler);
+  pageManager.register(debugLogPage);
+
+  // Set up hash-based navigation.
+  window.addEventListener('hashchange', function() {
+    // If a user navigates and the page doesn't exist, do nothing.
+    const pageName = window.location.hash.substr(1);
+    if ($(pageName)) {
+      pageManager.showPageByName(pageName);
+    }
+  });
+
+  if (!window.location.hash) {
+    pageManager.showPageByName(adapterPage.name);
+    return;
   }
+
+  // Only the root pages are available on page load.
+  pageManager.showPageByName(window.location.hash.split('/')[0].substr(1));
+}
+
+export function initializeViews() {
+  setupPages();
+  return getAdapterBroker()
+      .then(function(broker) {
+        adapterBroker = broker;
+      })
+      .then(function() {
+        return adapterBroker.getInfo();
+      })
+      .then(setupAdapterSystem)
+      .then(function() {
+        return adapterBroker.getDevices();
+      })
+      .then(setupDeviceSystem)
+      .catch(function(error) {
+        Snackbar.show(error.message, SnackbarType.ERROR);
+        console.error(error);
+      });
+}
diff --git a/chrome/browser/resources/bluetooth_internals/characteristic_list.js b/chrome/browser/resources/bluetooth_internals/characteristic_list.js
index d8a379a..74a19ec 100644
--- a/chrome/browser/resources/bluetooth_internals/characteristic_list.js
+++ b/chrome/browser/resources/bluetooth_internals/characteristic_list.js
@@ -10,255 +10,255 @@
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {define as crUiDefine} from 'chrome://resources/js/cr/ui.m.js';
 import {ArrayDataModel} from 'chrome://resources/js/cr/ui/array_data_model.m.js';
+
+import {DescriptorList} from './descriptor_list.js';
 import {connectToDevice} from './device_broker.js';
-import {Snackbar, SnackbarType} from './snackbar.js';
 import {ExpandableList, ExpandableListItem} from './expandable_list.js';
 import {ObjectFieldSet} from './object_fieldset.js';
+import {Snackbar, SnackbarType} from './snackbar.js';
 import {ValueControl} from './value_control.js';
-import {DescriptorList} from './descriptor_list.js';
 
 
-  /** Property names for the CharacteristicInfo fieldset */
-  const INFO_PROPERTY_NAMES = {
-    id: 'ID',
-    'uuid.uuid': 'UUID',
-  };
+/** Property names for the CharacteristicInfo fieldset */
+const INFO_PROPERTY_NAMES = {
+  id: 'ID',
+  'uuid.uuid': 'UUID',
+};
 
-  /** Property names for the Properties fieldset. */
-  const PROPERTIES_PROPERTY_NAMES = {
-    broadcast: 'Broadcast',
-    read: 'Read',
-    write_without_response: 'Write Without Response',
-    write: 'Write',
-    notify: 'Notify',
-    indicate: 'Indicate',
-    authenticated_signed_writes: 'Authenticated Signed Writes',
-    extended_properties: 'Extended Properties',
-    reliable_write: 'Reliable Write',
-    writable_auxiliaries: 'Writable Auxiliaries',
-    read_encrypted: 'Read Encrypted',
-    write_encrypted: 'Write Encrypted',
-    read_encrypted_authenticated: 'Read Encrypted Authenticated',
-    write_encrypted_authenticated: 'Write Encrypted Authenticated',
-  };
+/** Property names for the Properties fieldset. */
+const PROPERTIES_PROPERTY_NAMES = {
+  broadcast: 'Broadcast',
+  read: 'Read',
+  write_without_response: 'Write Without Response',
+  write: 'Write',
+  notify: 'Notify',
+  indicate: 'Indicate',
+  authenticated_signed_writes: 'Authenticated Signed Writes',
+  extended_properties: 'Extended Properties',
+  reliable_write: 'Reliable Write',
+  writable_auxiliaries: 'Writable Auxiliaries',
+  read_encrypted: 'Read Encrypted',
+  write_encrypted: 'Write Encrypted',
+  read_encrypted_authenticated: 'Read Encrypted Authenticated',
+  write_encrypted_authenticated: 'Write Encrypted Authenticated',
+};
+
+/**
+ * A list item that displays the properties of a CharacteristicInfo object.
+ * Two fieldsets are created within the element: one for the primitive
+ * properties, 'id' and 'uuid', and one for the 'properties' bitfield in the
+ * CharacteristicInfo object.
+ * @constructor
+ * @param {!bluetooth.mojom.CharacteristicInfo} characteristicInfo
+ * @param {string} deviceAddress
+ * @param {string} serviceId
+ * @extends {ExpandableListItem}
+ */
+export function CharacteristicListItem(
+    characteristicInfo, deviceAddress, serviceId) {
+  const listItem = new ExpandableListItem();
+  listItem.__proto__ = CharacteristicListItem.prototype;
+
+  /** @type {!bluetooth.mojom.CharacteristicInfo} */
+  listItem.info = characteristicInfo;
+  /** @private {string} */
+  listItem.deviceAddress_ = deviceAddress;
+  /** @private {string} */
+  listItem.serviceId_ = serviceId;
+
+  listItem.decorate();
+  return listItem;
+}
+
+CharacteristicListItem.prototype = {
+  __proto__: ExpandableListItem.prototype,
 
   /**
-   * A list item that displays the properties of a CharacteristicInfo object.
-   * Two fieldsets are created within the element: one for the primitive
-   * properties, 'id' and 'uuid', and one for the 'properties' bitfield in the
-   * CharacteristicInfo object.
-   * @constructor
-   * @param {!bluetooth.mojom.CharacteristicInfo} characteristicInfo
+   * Decorates the element as a characteristic list item. Creates and caches
+   * two fieldsets for displaying property values.
+   * @override
+   */
+  decorate() {
+    this.classList.add('characteristic-list-item');
+
+    /** @private {!ObjectFieldSet} */
+    this.characteristicFieldSet_ = new ObjectFieldSet();
+    this.characteristicFieldSet_.setPropertyDisplayNames(INFO_PROPERTY_NAMES);
+    this.characteristicFieldSet_.setObject({
+      id: this.info.id,
+      'uuid.uuid': this.info.uuid.uuid,
+    });
+
+    /** @private {!ObjectFieldSet} */
+    this.propertiesFieldSet_ = new ObjectFieldSet();
+    this.propertiesFieldSet_.setPropertyDisplayNames(PROPERTIES_PROPERTY_NAMES);
+    const Property = bluetooth.mojom.Property;
+    this.propertiesFieldSet_.showAll = false;
+    this.propertiesFieldSet_.setObject({
+      broadcast: (this.info.properties & Property.BROADCAST) > 0,
+      read: (this.info.properties & Property.READ) > 0,
+      write_without_response:
+          (this.info.properties & Property.WRITE_WITHOUT_RESPONSE) > 0,
+      write: (this.info.properties & Property.WRITE) > 0,
+      notify: (this.info.properties & Property.NOTIFY) > 0,
+      indicate: (this.info.properties & Property.INDICATE) > 0,
+      authenticated_signed_writes:
+          (this.info.properties & Property.AUTHENTICATED_SIGNED_WRITES) > 0,
+      extended_properties:
+          (this.info.properties & Property.EXTENDED_PROPERTIES) > 0,
+      reliable_write: (this.info.properties & Property.RELIABLE_WRITE) > 0,
+      writable_auxiliaries:
+          (this.info.properties & Property.WRITABLE_AUXILIARIES) > 0,
+      read_encrypted: (this.info.properties & Property.READ_ENCRYPTED) > 0,
+      write_encrypted: (this.info.properties & Property.WRITE_ENCRYPTED) > 0,
+      read_encrypted_authenticated:
+          (this.info.properties & Property.READ_ENCRYPTED_AUTHENTICATED) > 0,
+      write_encrypted_authenticated:
+          (this.info.properties & Property.WRITE_ENCRYPTED_AUTHENTICATED) > 0,
+    });
+
+    /** @private {!ValueControl} */
+    this.valueControl_ = new ValueControl();
+
+    this.valueControl_.load({
+      deviceAddress: this.deviceAddress_,
+      serviceId: this.serviceId_,
+      characteristicId: this.info.id,
+      properties: this.info.properties,
+    });
+    this.valueControl_.setValue(this.info.lastKnownValue);
+
+    /** @private {!DescriptorList} */
+    this.descriptorList_ = new DescriptorList();
+
+    // Create content for display in brief content container.
+    const characteristicHeaderText = document.createElement('div');
+    characteristicHeaderText.textContent = 'Characteristic:';
+
+    const characteristicHeaderValue = document.createElement('div');
+    characteristicHeaderValue.textContent = this.info.uuid.uuid;
+
+    const characteristicHeader = document.createElement('div');
+    characteristicHeader.appendChild(characteristicHeaderText);
+    characteristicHeader.appendChild(characteristicHeaderValue);
+    this.briefContent_.appendChild(characteristicHeader);
+
+    // Create content for display in expanded content container.
+    const characteristicInfoHeader = document.createElement('h4');
+    characteristicInfoHeader.textContent = 'Characteristic Info';
+
+    const characteristicDiv = document.createElement('div');
+    characteristicDiv.classList.add('flex');
+    characteristicDiv.appendChild(this.characteristicFieldSet_);
+
+    const propertiesHeader = document.createElement('h4');
+    propertiesHeader.textContent = 'Properties';
+
+    const propertiesBtn = document.createElement('button');
+    propertiesBtn.textContent = 'Show All';
+    propertiesBtn.classList.add('show-all-properties');
+    propertiesBtn.addEventListener('click', () => {
+      this.propertiesFieldSet_.showAll = !this.propertiesFieldSet_.showAll;
+      propertiesBtn.textContent =
+          this.propertiesFieldSet_.showAll ? 'Hide' : 'Show all';
+      this.propertiesFieldSet_.redraw();
+    });
+    propertiesHeader.appendChild(propertiesBtn);
+
+    const propertiesDiv = document.createElement('div');
+    propertiesDiv.classList.add('flex');
+    propertiesDiv.appendChild(this.propertiesFieldSet_);
+
+    const descriptorsHeader = document.createElement('h4');
+    descriptorsHeader.textContent = 'Descriptors';
+
+    const infoDiv = document.createElement('div');
+    infoDiv.classList.add('info-container');
+
+    const valueHeader = document.createElement('h4');
+    valueHeader.textContent = 'Value';
+
+    infoDiv.appendChild(characteristicInfoHeader);
+    infoDiv.appendChild(characteristicDiv);
+    infoDiv.appendChild(propertiesHeader);
+    infoDiv.appendChild(propertiesDiv);
+    infoDiv.appendChild(valueHeader);
+    infoDiv.appendChild(this.valueControl_);
+    infoDiv.appendChild(descriptorsHeader);
+    infoDiv.appendChild(this.descriptorList_);
+
+    this.expandedContent_.appendChild(infoDiv);
+  },
+
+  /** @override */
+  onExpandInternal(expanded) {
+    this.descriptorList_.load(
+        this.deviceAddress_, this.serviceId_, this.info.id);
+  },
+};
+
+/**
+ * A list that displays CharacteristicListItems.
+ * @constructor
+ * @extends {ExpandableList}
+ */
+export const CharacteristicList = crUiDefine('list');
+
+CharacteristicList.prototype = {
+  __proto__: ExpandableList.prototype,
+
+  /** @override */
+  decorate() {
+    ExpandableList.prototype.decorate.call(this);
+
+    /** @private {?string} */
+    this.deviceAddress_ = null;
+    /** @private {?string} */
+    this.serviceId_ = null;
+    /** @private {boolean} */
+    this.characteristicsRequested_ = false;
+
+    this.classList.add('characteristic-list');
+    this.setEmptyMessage('No Characteristics Found');
+  },
+
+  createItem(data) {
+    return new CharacteristicListItem(
+        data, assert(this.deviceAddress_), assert(this.serviceId_));
+  },
+
+  /**
+   * Loads the characteristic list with an array of CharacteristicInfo from
+   * the device with |deviceAddress| and service with |serviceId|. If no
+   * active connection to the device exists, one is created.
    * @param {string} deviceAddress
    * @param {string} serviceId
-   * @extends {ExpandableListItem}
    */
-  export function CharacteristicListItem(
-      characteristicInfo, deviceAddress, serviceId) {
-    const listItem = new ExpandableListItem();
-    listItem.__proto__ = CharacteristicListItem.prototype;
+  load(deviceAddress, serviceId) {
+    if (this.characteristicsRequested_ || !this.isSpinnerShowing()) {
+      return;
+    }
 
-    /** @type {!bluetooth.mojom.CharacteristicInfo} */
-    listItem.info = characteristicInfo;
-    /** @private {string} */
-    listItem.deviceAddress_ = deviceAddress;
-    /** @private {string} */
-    listItem.serviceId_ = serviceId;
+    this.deviceAddress_ = deviceAddress;
+    this.serviceId_ = serviceId;
+    this.characteristicsRequested_ = true;
 
-    listItem.decorate();
-    return listItem;
-  }
-
-  CharacteristicListItem.prototype = {
-    __proto__: ExpandableListItem.prototype,
-
-    /**
-     * Decorates the element as a characteristic list item. Creates and caches
-     * two fieldsets for displaying property values.
-     * @override
-     */
-    decorate() {
-      this.classList.add('characteristic-list-item');
-
-      /** @private {!ObjectFieldSet} */
-      this.characteristicFieldSet_ = new ObjectFieldSet();
-      this.characteristicFieldSet_.setPropertyDisplayNames(INFO_PROPERTY_NAMES);
-      this.characteristicFieldSet_.setObject({
-        id: this.info.id,
-        'uuid.uuid': this.info.uuid.uuid,
-      });
-
-      /** @private {!ObjectFieldSet} */
-      this.propertiesFieldSet_ = new ObjectFieldSet();
-      this.propertiesFieldSet_.setPropertyDisplayNames(
-          PROPERTIES_PROPERTY_NAMES);
-      const Property = bluetooth.mojom.Property;
-      this.propertiesFieldSet_.showAll = false;
-      this.propertiesFieldSet_.setObject({
-        broadcast: (this.info.properties & Property.BROADCAST) > 0,
-        read: (this.info.properties & Property.READ) > 0,
-        write_without_response:
-            (this.info.properties & Property.WRITE_WITHOUT_RESPONSE) > 0,
-        write: (this.info.properties & Property.WRITE) > 0,
-        notify: (this.info.properties & Property.NOTIFY) > 0,
-        indicate: (this.info.properties & Property.INDICATE) > 0,
-        authenticated_signed_writes:
-            (this.info.properties & Property.AUTHENTICATED_SIGNED_WRITES) > 0,
-        extended_properties:
-            (this.info.properties & Property.EXTENDED_PROPERTIES) > 0,
-        reliable_write: (this.info.properties & Property.RELIABLE_WRITE) > 0,
-        writable_auxiliaries:
-            (this.info.properties & Property.WRITABLE_AUXILIARIES) > 0,
-        read_encrypted: (this.info.properties & Property.READ_ENCRYPTED) > 0,
-        write_encrypted: (this.info.properties & Property.WRITE_ENCRYPTED) > 0,
-        read_encrypted_authenticated:
-            (this.info.properties & Property.READ_ENCRYPTED_AUTHENTICATED) > 0,
-        write_encrypted_authenticated:
-            (this.info.properties & Property.WRITE_ENCRYPTED_AUTHENTICATED) > 0,
-      });
-
-      /** @private {!ValueControl} */
-      this.valueControl_ = new ValueControl();
-
-      this.valueControl_.load({
-        deviceAddress: this.deviceAddress_,
-        serviceId: this.serviceId_,
-        characteristicId: this.info.id,
-        properties: this.info.properties,
-      });
-      this.valueControl_.setValue(this.info.lastKnownValue);
-
-      /** @private {!DescriptorList} */
-      this.descriptorList_ = new DescriptorList();
-
-      // Create content for display in brief content container.
-      const characteristicHeaderText = document.createElement('div');
-      characteristicHeaderText.textContent = 'Characteristic:';
-
-      const characteristicHeaderValue = document.createElement('div');
-      characteristicHeaderValue.textContent = this.info.uuid.uuid;
-
-      const characteristicHeader = document.createElement('div');
-      characteristicHeader.appendChild(characteristicHeaderText);
-      characteristicHeader.appendChild(characteristicHeaderValue);
-      this.briefContent_.appendChild(characteristicHeader);
-
-      // Create content for display in expanded content container.
-      const characteristicInfoHeader = document.createElement('h4');
-      characteristicInfoHeader.textContent = 'Characteristic Info';
-
-      const characteristicDiv = document.createElement('div');
-      characteristicDiv.classList.add('flex');
-      characteristicDiv.appendChild(this.characteristicFieldSet_);
-
-      const propertiesHeader = document.createElement('h4');
-      propertiesHeader.textContent = 'Properties';
-
-      const propertiesBtn = document.createElement('button');
-      propertiesBtn.textContent = 'Show All';
-      propertiesBtn.classList.add('show-all-properties');
-      propertiesBtn.addEventListener('click', () => {
-        this.propertiesFieldSet_.showAll = !this.propertiesFieldSet_.showAll;
-        propertiesBtn.textContent =
-            this.propertiesFieldSet_.showAll ? 'Hide' : 'Show all';
-        this.propertiesFieldSet_.redraw();
-      });
-      propertiesHeader.appendChild(propertiesBtn);
-
-      const propertiesDiv = document.createElement('div');
-      propertiesDiv.classList.add('flex');
-      propertiesDiv.appendChild(this.propertiesFieldSet_);
-
-      const descriptorsHeader = document.createElement('h4');
-      descriptorsHeader.textContent = 'Descriptors';
-
-      const infoDiv = document.createElement('div');
-      infoDiv.classList.add('info-container');
-
-      const valueHeader = document.createElement('h4');
-      valueHeader.textContent = 'Value';
-
-      infoDiv.appendChild(characteristicInfoHeader);
-      infoDiv.appendChild(characteristicDiv);
-      infoDiv.appendChild(propertiesHeader);
-      infoDiv.appendChild(propertiesDiv);
-      infoDiv.appendChild(valueHeader);
-      infoDiv.appendChild(this.valueControl_);
-      infoDiv.appendChild(descriptorsHeader);
-      infoDiv.appendChild(this.descriptorList_);
-
-      this.expandedContent_.appendChild(infoDiv);
-    },
-
-    /** @override */
-    onExpandInternal(expanded) {
-      this.descriptorList_.load(
-          this.deviceAddress_, this.serviceId_, this.info.id);
-    },
-  };
-
-  /**
-   * A list that displays CharacteristicListItems.
-   * @constructor
-   * @extends {ExpandableList}
-   */
-  export const CharacteristicList = crUiDefine('list');
-
-  CharacteristicList.prototype = {
-    __proto__: ExpandableList.prototype,
-
-    /** @override */
-    decorate() {
-      ExpandableList.prototype.decorate.call(this);
-
-      /** @private {?string} */
-      this.deviceAddress_ = null;
-      /** @private {?string} */
-      this.serviceId_ = null;
-      /** @private {boolean} */
-      this.characteristicsRequested_ = false;
-
-      this.classList.add('characteristic-list');
-      this.setEmptyMessage('No Characteristics Found');
-    },
-
-    createItem(data) {
-      return new CharacteristicListItem(
-          data, assert(this.deviceAddress_), assert(this.serviceId_));
-    },
-
-    /**
-     * Loads the characteristic list with an array of CharacteristicInfo from
-     * the device with |deviceAddress| and service with |serviceId|. If no
-     * active connection to the device exists, one is created.
-     * @param {string} deviceAddress
-     * @param {string} serviceId
-     */
-    load(deviceAddress, serviceId) {
-      if (this.characteristicsRequested_ || !this.isSpinnerShowing()) {
-        return;
-      }
-
-      this.deviceAddress_ = deviceAddress;
-      this.serviceId_ = serviceId;
-      this.characteristicsRequested_ = true;
-
-      connectToDevice(deviceAddress)
-          .then(function(device) {
-            return device.getCharacteristics(serviceId);
-          }.bind(this))
-          .then(function(response) {
-            this.setData(new ArrayDataModel(response.characteristics || []));
-            this.setSpinnerShowing(false);
-            this.characteristicsRequested_ = false;
-          }.bind(this))
-          .catch(function(error) {
-            this.characteristicsRequested_ = false;
-            Snackbar.show(
-                deviceAddress + ': ' + error.message, SnackbarType.ERROR,
-                'Retry', function() {
-                  this.load(deviceAddress, serviceId);
-                }.bind(this));
-          }.bind(this));
-    },
-  };
+    connectToDevice(deviceAddress)
+        .then(function(device) {
+          return device.getCharacteristics(serviceId);
+        }.bind(this))
+        .then(function(response) {
+          this.setData(new ArrayDataModel(response.characteristics || []));
+          this.setSpinnerShowing(false);
+          this.characteristicsRequested_ = false;
+        }.bind(this))
+        .catch(function(error) {
+          this.characteristicsRequested_ = false;
+          Snackbar.show(
+              deviceAddress + ': ' + error.message, SnackbarType.ERROR, 'Retry',
+              function() {
+                this.load(deviceAddress, serviceId);
+              }.bind(this));
+        }.bind(this));
+  },
+};
diff --git a/chrome/browser/resources/bluetooth_internals/debug_log_page.js b/chrome/browser/resources/bluetooth_internals/debug_log_page.js
index 185cfd1..3b924a4 100644
--- a/chrome/browser/resources/bluetooth_internals/debug_log_page.js
+++ b/chrome/browser/resources/bluetooth_internals/debug_log_page.js
@@ -2,67 +2,68 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {$} from 'chrome://resources/js/util.m.js';
-
 import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
 import './uuid.mojom-lite.js';
 import './device.mojom-lite.js';
 import './adapter.mojom-lite.js';
 import './bluetooth_internals.mojom-lite.js';
+
+import {$} from 'chrome://resources/js/util.m.js';
+
 import {Page} from './page.js';
 
-  /** @const {string} */
-  const LOGS_NOT_SUPPORTED_STRING = 'Debug logs not supported';
+/** @const {string} */
+const LOGS_NOT_SUPPORTED_STRING = 'Debug logs not supported';
+
+/**
+ * Page that allows user to enable/disable debug logs.
+ */
+export class DebugLogPage extends Page {
+  /**
+   * @param {!mojom.BluetoothInternalsHandlerRemote} bluetoothInternalsHandler
+   */
+  constructor(bluetoothInternalsHandler) {
+    super('debug', 'Debug Logs', 'debug');
+
+    /**
+     * @private {?mojom.DebugLogsChangeHandlerRemote}
+     */
+    this.debugLogsChangeHandler_ = null;
+
+    /** @private {?HTMLInputElement} */
+    this.inputElement_ = null;
+
+    /** @private {!HTMLDivElement} */
+    this.debugContainer_ =
+        /** @type {!HTMLDivElement} */ ($('debug-container'));
+
+    bluetoothInternalsHandler.getDebugLogsChangeHandler().then((params) => {
+      if (params.handler) {
+        this.setUpInput(params.handler, params.initialToggleValue);
+      } else {
+        this.debugContainer_.textContent = LOGS_NOT_SUPPORTED_STRING;
+      }
+    });
+  }
 
   /**
-   * Page that allows user to enable/disable debug logs.
+   * @param {!mojom.DebugLogsChangeHandlerRemote} handler
+   * @param {boolean} initialInputValue
    */
-  export class DebugLogPage extends Page {
-    /**
-     * @param {!mojom.BluetoothInternalsHandlerRemote} bluetoothInternalsHandler
-     */
-    constructor(bluetoothInternalsHandler) {
-      super('debug', 'Debug Logs', 'debug');
+  setUpInput(handler, initialInputValue) {
+    this.debugLogsChangeHandler_ = handler;
 
-      /**
-       * @private {?mojom.DebugLogsChangeHandlerRemote}
-       */
-      this.debugLogsChangeHandler_ = null;
-
-      /** @private {?HTMLInputElement} */
-      this.inputElement_ = null;
-
-      /** @private {!HTMLDivElement} */
-      this.debugContainer_ =
-          /** @type {!HTMLDivElement} */ ($('debug-container'));
-
-      bluetoothInternalsHandler.getDebugLogsChangeHandler().then((params) => {
-        if (params.handler) {
-          this.setUpInput(params.handler, params.initialToggleValue);
-        } else {
-          this.debugContainer_.textContent = LOGS_NOT_SUPPORTED_STRING;
-        }
-      });
-    }
-
-    /**
-     * @param {!mojom.DebugLogsChangeHandlerRemote} handler
-     * @param {boolean} initialInputValue
-     */
-    setUpInput(handler, initialInputValue) {
-      this.debugLogsChangeHandler_ = handler;
-
-      this.inputElement_ =
-          /** @type {!HTMLInputElement} */ (document.createElement('input'));
-      this.inputElement_.setAttribute('type', 'checkbox');
-      this.inputElement_.checked = initialInputValue;
-      this.inputElement_.addEventListener(
-          'change', this.onToggleChange.bind(this));
-      this.debugContainer_.appendChild(this.inputElement_);
-    }
-
-    onToggleChange() {
-      this.debugLogsChangeHandler_.changeDebugLogsState(
-          this.inputElement_.checked);
-    }
+    this.inputElement_ =
+        /** @type {!HTMLInputElement} */ (document.createElement('input'));
+    this.inputElement_.setAttribute('type', 'checkbox');
+    this.inputElement_.checked = initialInputValue;
+    this.inputElement_.addEventListener(
+        'change', this.onToggleChange.bind(this));
+    this.debugContainer_.appendChild(this.inputElement_);
   }
+
+  onToggleChange() {
+    this.debugLogsChangeHandler_.changeDebugLogsState(
+        this.inputElement_.checked);
+  }
+}
diff --git a/chrome/browser/resources/bluetooth_internals/descriptor_list.js b/chrome/browser/resources/bluetooth_internals/descriptor_list.js
index 4129e6a3..62ecb61 100644
--- a/chrome/browser/resources/bluetooth_internals/descriptor_list.js
+++ b/chrome/browser/resources/bluetooth_internals/descriptor_list.js
@@ -8,179 +8,180 @@
  */
 
 import {assert} from 'chrome://resources/js/assert.m.js';
-import {connectToDevice} from './device_broker.js';
 import {define as crUiDefine} from 'chrome://resources/js/cr/ui.m.js';
-import {Snackbar, SnackbarType} from './snackbar.js';
-import {ExpandableList, ExpandableListItem} from './expandable_list.js';
 import {ArrayDataModel} from 'chrome://resources/js/cr/ui/array_data_model.m.js';
+
+import {connectToDevice} from './device_broker.js';
+import {ExpandableList, ExpandableListItem} from './expandable_list.js';
 import {ObjectFieldSet} from './object_fieldset.js';
+import {Snackbar, SnackbarType} from './snackbar.js';
 import {ValueControl} from './value_control.js';
 
-  /** Property names for the DescriptorInfo fieldset */
-  const INFO_PROPERTY_NAMES = {
-    id: 'ID',
-    'uuid.uuid': 'UUID',
-  };
+/** Property names for the DescriptorInfo fieldset */
+const INFO_PROPERTY_NAMES = {
+  id: 'ID',
+  'uuid.uuid': 'UUID',
+};
+
+/**
+ * A list item that displays the properties of a DescriptorInfo object.
+ * A fieldset is created within the element for the primitive
+ * properties, 'id' and 'uuid' within the DescriptorInfo object.
+ * @constructor
+ * @param {!bluetooth.mojom.DescriptorInfo} descriptorInfo
+ * @param {string} deviceAddress
+ * @param {string} serviceId
+ * @param {string} characteristicId
+ * @extends {ExpandableListItem}
+ */
+export function DescriptorListItem(
+    descriptorInfo, deviceAddress, serviceId, characteristicId) {
+  const listItem = new ExpandableListItem();
+  listItem.__proto__ = DescriptorListItem.prototype;
+
+  /** @type {!bluetooth.mojom.DescriptorInfo} */
+  listItem.info = descriptorInfo;
+  /** @private {string} */
+  listItem.deviceAddress_ = deviceAddress;
+  /** @private {string} */
+  listItem.serviceId_ = serviceId;
+  /** @private {string} */
+  listItem.characteristicId_ = characteristicId;
+
+  listItem.decorate();
+  return listItem;
+}
+
+DescriptorListItem.prototype = {
+  __proto__: ExpandableListItem.prototype,
 
   /**
-   * A list item that displays the properties of a DescriptorInfo object.
-   * A fieldset is created within the element for the primitive
-   * properties, 'id' and 'uuid' within the DescriptorInfo object.
-   * @constructor
-   * @param {!bluetooth.mojom.DescriptorInfo} descriptorInfo
+   * Decorates the element as a descriptor list item. Creates and caches
+   * a fieldset for displaying property values.
+   * @override
+   */
+  decorate() {
+    this.classList.add('descriptor-list-item');
+
+    /** @private {!ObjectFieldSet} */
+    this.descriptorFieldSet_ = new ObjectFieldSet();
+    this.descriptorFieldSet_.setPropertyDisplayNames(INFO_PROPERTY_NAMES);
+    this.descriptorFieldSet_.setObject({
+      id: this.info.id,
+      'uuid.uuid': this.info.uuid.uuid,
+    });
+
+    /** @private {!ValueControl} */
+    this.valueControl_ = new ValueControl();
+    this.valueControl_.load({
+      deviceAddress: this.deviceAddress_,
+      serviceId: this.serviceId_,
+      characteristicId: this.characteristicId_,
+      descriptorId: this.info.id,
+    });
+
+    // Create content for display in brief content container.
+    const descriptorHeaderText = document.createElement('div');
+    descriptorHeaderText.textContent = 'Descriptor:';
+
+    const descriptorHeaderValue = document.createElement('div');
+    descriptorHeaderValue.textContent = this.info.uuid.uuid;
+
+    const descriptorHeader = document.createElement('div');
+    descriptorHeader.appendChild(descriptorHeaderText);
+    descriptorHeader.appendChild(descriptorHeaderValue);
+    this.briefContent_.appendChild(descriptorHeader);
+
+    // Create content for display in expanded content container.
+    const descriptorInfoHeader = document.createElement('h4');
+    descriptorInfoHeader.textContent = 'Descriptor Info';
+
+    const descriptorDiv = document.createElement('div');
+    descriptorDiv.classList.add('flex');
+    descriptorDiv.appendChild(this.descriptorFieldSet_);
+
+    const valueHeader = document.createElement('h4');
+    valueHeader.textContent = 'Value';
+
+    const infoDiv = document.createElement('div');
+    infoDiv.classList.add('info-container');
+    infoDiv.appendChild(descriptorInfoHeader);
+    infoDiv.appendChild(descriptorDiv);
+    infoDiv.appendChild(valueHeader);
+    infoDiv.appendChild(this.valueControl_);
+
+    this.expandedContent_.appendChild(infoDiv);
+  },
+};
+
+/**
+ * A list that displays DescriptorListItems.
+ * @constructor
+ * @extends {ExpandableList}
+ */
+export const DescriptorList = crUiDefine('list');
+
+DescriptorList.prototype = {
+  __proto__: ExpandableList.prototype,
+
+  /** @override */
+  decorate() {
+    ExpandableList.prototype.decorate.call(this);
+
+    /** @private {?string} */
+    this.deviceAddress_ = null;
+    /** @private {?string} */
+    this.serviceId_ = null;
+    /** @private {?string} */
+    this.characteristicId_ = null;
+    /** @private {boolean} */
+    this.descriptorsRequested_ = false;
+
+    this.classList.add('descriptor-list');
+    this.setEmptyMessage('No Descriptors Found');
+  },
+
+  createItem(data) {
+    return new DescriptorListItem(
+        data, assert(this.deviceAddress_), assert(this.serviceId_),
+        assert(this.characteristicId_));
+  },
+
+  /**
+   * Loads the descriptor list with an array of DescriptorInfo from
+   * the device with |deviceAddress|, service with |serviceId|, and
+   * characteristic with |characteristicId|. If no active connection to the
+   * device exists, one is created.
    * @param {string} deviceAddress
    * @param {string} serviceId
    * @param {string} characteristicId
-   * @extends {ExpandableListItem}
    */
-  export function DescriptorListItem(
-      descriptorInfo, deviceAddress, serviceId, characteristicId) {
-    const listItem = new ExpandableListItem();
-    listItem.__proto__ = DescriptorListItem.prototype;
+  load(deviceAddress, serviceId, characteristicId) {
+    if (this.descriptorsRequested_ || !this.isSpinnerShowing()) {
+      return;
+    }
 
-    /** @type {!bluetooth.mojom.DescriptorInfo} */
-    listItem.info = descriptorInfo;
-    /** @private {string} */
-    listItem.deviceAddress_ = deviceAddress;
-    /** @private {string} */
-    listItem.serviceId_ = serviceId;
-    /** @private {string} */
-    listItem.characteristicId_ = characteristicId;
+    this.deviceAddress_ = deviceAddress;
+    this.serviceId_ = serviceId;
+    this.characteristicId_ = characteristicId;
+    this.descriptorsRequested_ = true;
 
-    listItem.decorate();
-    return listItem;
-  }
-
-  DescriptorListItem.prototype = {
-    __proto__: ExpandableListItem.prototype,
-
-    /**
-     * Decorates the element as a descriptor list item. Creates and caches
-     * a fieldset for displaying property values.
-     * @override
-     */
-    decorate() {
-      this.classList.add('descriptor-list-item');
-
-      /** @private {!ObjectFieldSet} */
-      this.descriptorFieldSet_ = new ObjectFieldSet();
-      this.descriptorFieldSet_.setPropertyDisplayNames(INFO_PROPERTY_NAMES);
-      this.descriptorFieldSet_.setObject({
-        id: this.info.id,
-        'uuid.uuid': this.info.uuid.uuid,
-      });
-
-      /** @private {!ValueControl} */
-      this.valueControl_ = new ValueControl();
-      this.valueControl_.load({
-        deviceAddress: this.deviceAddress_,
-        serviceId: this.serviceId_,
-        characteristicId: this.characteristicId_,
-        descriptorId: this.info.id,
-      });
-
-      // Create content for display in brief content container.
-      const descriptorHeaderText = document.createElement('div');
-      descriptorHeaderText.textContent = 'Descriptor:';
-
-      const descriptorHeaderValue = document.createElement('div');
-      descriptorHeaderValue.textContent = this.info.uuid.uuid;
-
-      const descriptorHeader = document.createElement('div');
-      descriptorHeader.appendChild(descriptorHeaderText);
-      descriptorHeader.appendChild(descriptorHeaderValue);
-      this.briefContent_.appendChild(descriptorHeader);
-
-      // Create content for display in expanded content container.
-      const descriptorInfoHeader = document.createElement('h4');
-      descriptorInfoHeader.textContent = 'Descriptor Info';
-
-      const descriptorDiv = document.createElement('div');
-      descriptorDiv.classList.add('flex');
-      descriptorDiv.appendChild(this.descriptorFieldSet_);
-
-      const valueHeader = document.createElement('h4');
-      valueHeader.textContent = 'Value';
-
-      const infoDiv = document.createElement('div');
-      infoDiv.classList.add('info-container');
-      infoDiv.appendChild(descriptorInfoHeader);
-      infoDiv.appendChild(descriptorDiv);
-      infoDiv.appendChild(valueHeader);
-      infoDiv.appendChild(this.valueControl_);
-
-      this.expandedContent_.appendChild(infoDiv);
-    },
-  };
-
-  /**
-   * A list that displays DescriptorListItems.
-   * @constructor
-   * @extends {ExpandableList}
-   */
-  export const DescriptorList = crUiDefine('list');
-
-  DescriptorList.prototype = {
-    __proto__: ExpandableList.prototype,
-
-    /** @override */
-    decorate() {
-      ExpandableList.prototype.decorate.call(this);
-
-      /** @private {?string} */
-      this.deviceAddress_ = null;
-      /** @private {?string} */
-      this.serviceId_ = null;
-      /** @private {?string} */
-      this.characteristicId_ = null;
-      /** @private {boolean} */
-      this.descriptorsRequested_ = false;
-
-      this.classList.add('descriptor-list');
-      this.setEmptyMessage('No Descriptors Found');
-    },
-
-    createItem(data) {
-      return new DescriptorListItem(
-          data, assert(this.deviceAddress_), assert(this.serviceId_),
-          assert(this.characteristicId_));
-    },
-
-    /**
-     * Loads the descriptor list with an array of DescriptorInfo from
-     * the device with |deviceAddress|, service with |serviceId|, and
-     * characteristic with |characteristicId|. If no active connection to the
-     * device exists, one is created.
-     * @param {string} deviceAddress
-     * @param {string} serviceId
-     * @param {string} characteristicId
-     */
-    load(deviceAddress, serviceId, characteristicId) {
-      if (this.descriptorsRequested_ || !this.isSpinnerShowing()) {
-        return;
-      }
-
-      this.deviceAddress_ = deviceAddress;
-      this.serviceId_ = serviceId;
-      this.characteristicId_ = characteristicId;
-      this.descriptorsRequested_ = true;
-
-      connectToDevice(deviceAddress)
-          .then(function(device) {
-            return device.getDescriptors(serviceId, characteristicId);
-          }.bind(this))
-          .then(function(response) {
-            this.setData(new ArrayDataModel(response.descriptors || []));
-            this.setSpinnerShowing(false);
-            this.descriptorsRequested_ = false;
-          }.bind(this))
-          .catch(function(error) {
-            this.descriptorsRequested_ = false;
-            Snackbar.show(
-                deviceAddress + ': ' + error.message, SnackbarType.ERROR,
-                'Retry', function() {
-                  this.load(deviceAddress, serviceId, characteristicId);
-                }.bind(this));
-          }.bind(this));
-    },
-  };
+    connectToDevice(deviceAddress)
+        .then(function(device) {
+          return device.getDescriptors(serviceId, characteristicId);
+        }.bind(this))
+        .then(function(response) {
+          this.setData(new ArrayDataModel(response.descriptors || []));
+          this.setSpinnerShowing(false);
+          this.descriptorsRequested_ = false;
+        }.bind(this))
+        .catch(function(error) {
+          this.descriptorsRequested_ = false;
+          Snackbar.show(
+              deviceAddress + ': ' + error.message, SnackbarType.ERROR, 'Retry',
+              function() {
+                this.load(deviceAddress, serviceId, characteristicId);
+              }.bind(this));
+        }.bind(this));
+  },
+};
diff --git a/chrome/browser/resources/bluetooth_internals/device_broker.js b/chrome/browser/resources/bluetooth_internals/device_broker.js
index 6658f06..999df13e 100644
--- a/chrome/browser/resources/bluetooth_internals/device_broker.js
+++ b/chrome/browser/resources/bluetooth_internals/device_broker.js
@@ -20,38 +20,38 @@
  */
 export const connectedDevices = new Map();
 
-  /**
-   * Creates a GATT connection to the device with |address|. If a connection to
-   * the device already exists, the promise is resolved with the existing
-   * DeviceRemote. If a connection is in progress, the promise resolves when
-   * the existing connection request promise is fulfilled.
-   * @param {string} address
-   * @return {!Promise<!bluetooth.mojom.DeviceRemote>}
-   */
-  export function connectToDevice(address) {
-    const deviceOrPromise = connectedDevices.get(address) || null;
-    if (deviceOrPromise !== null) {
-      return Promise.resolve(deviceOrPromise);
-    }
-
-    const promise = /** @type {!Promise<!bluetooth.mojom.DeviceRemote>} */ (
-        getAdapterBroker()
-            .then(function(adapterBroker) {
-              return adapterBroker.connectToDevice(address);
-            })
-            .then(function(device) {
-              connectedDevices.set(address, device);
-
-              device.onConnectionError.addListener(
-                  () => connectedDevices.delete(address));
-
-              return device;
-            })
-            .catch(function(error) {
-              connectedDevices.delete(address);
-              throw error;
-            }));
-
-    connectedDevices.set(address, promise);
-    return promise;
+/**
+ * Creates a GATT connection to the device with |address|. If a connection to
+ * the device already exists, the promise is resolved with the existing
+ * DeviceRemote. If a connection is in progress, the promise resolves when
+ * the existing connection request promise is fulfilled.
+ * @param {string} address
+ * @return {!Promise<!bluetooth.mojom.DeviceRemote>}
+ */
+export function connectToDevice(address) {
+  const deviceOrPromise = connectedDevices.get(address) || null;
+  if (deviceOrPromise !== null) {
+    return Promise.resolve(deviceOrPromise);
   }
+
+  const promise = /** @type {!Promise<!bluetooth.mojom.DeviceRemote>} */ (
+      getAdapterBroker()
+          .then(function(adapterBroker) {
+            return adapterBroker.connectToDevice(address);
+          })
+          .then(function(device) {
+            connectedDevices.set(address, device);
+
+            device.onConnectionError.addListener(
+                () => connectedDevices.delete(address));
+
+            return device;
+          })
+          .catch(function(error) {
+            connectedDevices.delete(address);
+            throw error;
+          }));
+
+  connectedDevices.set(address, promise);
+  return promise;
+}
diff --git a/chrome/browser/resources/bluetooth_internals/device_collection.js b/chrome/browser/resources/bluetooth_internals/device_collection.js
index 3234b0d..086350ad 100644
--- a/chrome/browser/resources/bluetooth_internals/device_collection.js
+++ b/chrome/browser/resources/bluetooth_internals/device_collection.js
@@ -12,87 +12,87 @@
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {ArrayDataModel} from 'chrome://resources/js/cr/ui/array_data_model.m.js';
 
+/**
+ * Enum of connection status for a device.
+ * @enum {number}
+ */
+export const ConnectionStatus = {
+  DISCONNECTED: 0,
+  CONNECTING: 1,
+  CONNECTED: 2,
+};
+
+/**
+ * Collection of devices. Extends ArrayDataModel which provides a set of
+ * functions and events that notifies observers when the collection changes.
+ */
+export class DeviceCollection extends ArrayDataModel {
   /**
-   * Enum of connection status for a device.
-   * @enum {number}
+   * @param {!Array<!bluetooth.mojom.DeviceInfo>} array The starting
+   *     collection of devices.
    */
-  export const ConnectionStatus = {
-    DISCONNECTED: 0,
-    CONNECTING: 1,
-    CONNECTED: 2,
-  };
+  constructor(array) {
+    super(array);
+
+    // Keep track of MAC addresses which were previously found via scan, but
+    // are no longer being advertised or nearby. Used to inform isRemoved().
+    /** @private {!Object<string, boolean>} */
+    this.removedDevices_ = {};
+  }
 
   /**
-   * Collection of devices. Extends ArrayDataModel which provides a set of
-   * functions and events that notifies observers when the collection changes.
+   * Finds the Device in the collection with the matching address.
+   * @param {string} address
    */
-  export class DeviceCollection extends ArrayDataModel {
-    /**
-     * @param {!Array<!bluetooth.mojom.DeviceInfo>} array The starting
-     *     collection of devices.
-     */
-    constructor(array) {
-      super(array);
-
-      // Keep track of MAC addresses which were previously found via scan, but
-      // are no longer being advertised or nearby. Used to inform isRemoved().
-      /** @private {!Object<string, boolean>} */
-      this.removedDevices_ = {};
-    }
-
-    /**
-     * Finds the Device in the collection with the matching address.
-     * @param {string} address
-     */
-    getByAddress(address) {
-      for (let i = 0; i < this.length; i++) {
-        const device = this.item(i);
-        if (address == device.address) {
-          return device;
-        }
-      }
-      return null;
-    }
-
-    /**
-     * Adds or updates a Device with new DeviceInfo.
-     * @param {!bluetooth.mojom.DeviceInfo} deviceInfo
-     */
-    addOrUpdate(deviceInfo) {
-      this.removedDevices_[deviceInfo.address] = false;
-      const oldDeviceInfo = this.getByAddress(deviceInfo.address);
-
-      if (oldDeviceInfo) {
-        // Update rssi if it's valid
-        const rssi = (deviceInfo.rssi && deviceInfo.rssi.value) ||
-            (oldDeviceInfo.rssi && oldDeviceInfo.rssi.value);
-
-        // The rssi property may be null, so it must be re-assigned.
-        Object.assign(oldDeviceInfo, deviceInfo);
-        oldDeviceInfo.rssi = {value: rssi};
-        this.updateIndex(this.indexOf(oldDeviceInfo));
-      } else {
-        this.push(deviceInfo);
+  getByAddress(address) {
+    for (let i = 0; i < this.length; i++) {
+      const device = this.item(i);
+      if (address == device.address) {
+        return device;
       }
     }
+    return null;
+  }
 
-    /**
-     * Marks the Device as removed.
-     * @param {!bluetooth.mojom.DeviceInfo} deviceInfo
-     */
-    remove(deviceInfo) {
-      const device = this.getByAddress(deviceInfo.address);
-      assert(device, 'Device does not exist.');
-      this.removedDevices_[deviceInfo.address] = true;
-      this.updateIndex(this.indexOf(device));
-    }
+  /**
+   * Adds or updates a Device with new DeviceInfo.
+   * @param {!bluetooth.mojom.DeviceInfo} deviceInfo
+   */
+  addOrUpdate(deviceInfo) {
+    this.removedDevices_[deviceInfo.address] = false;
+    const oldDeviceInfo = this.getByAddress(deviceInfo.address);
 
-    /**
-     * Return true if device was "removed" -- previously found via scan but
-     * either no longer advertising or no longer nearby.
-     * @param {!bluetooth.mojom.DeviceInfo} deviceInfo
-     */
-    isRemoved(deviceInfo) {
-      return !!this.removedDevices_[deviceInfo.address];
+    if (oldDeviceInfo) {
+      // Update rssi if it's valid
+      const rssi = (deviceInfo.rssi && deviceInfo.rssi.value) ||
+          (oldDeviceInfo.rssi && oldDeviceInfo.rssi.value);
+
+      // The rssi property may be null, so it must be re-assigned.
+      Object.assign(oldDeviceInfo, deviceInfo);
+      oldDeviceInfo.rssi = {value: rssi};
+      this.updateIndex(this.indexOf(oldDeviceInfo));
+    } else {
+      this.push(deviceInfo);
     }
   }
+
+  /**
+   * Marks the Device as removed.
+   * @param {!bluetooth.mojom.DeviceInfo} deviceInfo
+   */
+  remove(deviceInfo) {
+    const device = this.getByAddress(deviceInfo.address);
+    assert(device, 'Device does not exist.');
+    this.removedDevices_[deviceInfo.address] = true;
+    this.updateIndex(this.indexOf(device));
+  }
+
+  /**
+   * Return true if device was "removed" -- previously found via scan but
+   * either no longer advertising or no longer nearby.
+   * @param {!bluetooth.mojom.DeviceInfo} deviceInfo
+   */
+  isRemoved(deviceInfo) {
+    return !!this.removedDevices_[deviceInfo.address];
+  }
+}
diff --git a/chrome/browser/resources/bluetooth_internals/device_details_page.js b/chrome/browser/resources/bluetooth_internals/device_details_page.js
index ff45ceb8..6f84faf 100644
--- a/chrome/browser/resources/bluetooth_internals/device_details_page.js
+++ b/chrome/browser/resources/bluetooth_internals/device_details_page.js
@@ -9,231 +9,227 @@
  */
 
 import {$} from 'chrome://resources/js/util.m.js';
+
 import {connectToDevice} from './device_broker.js';
 import {ConnectionStatus} from './device_collection.js';
-import {Page} from './page.js';
-import {Snackbar, SnackbarType} from './snackbar.js';
 import {ObjectFieldSet} from './object_fieldset.js';
+import {Page} from './page.js';
 import {ServiceList} from './service_list.js';
+import {Snackbar, SnackbarType} from './snackbar.js';
 
+/**
+ * Property names that will be displayed in the ObjectFieldSet which contains
+ * the DeviceInfo object.
+ */
+const PROPERTY_NAMES = {
+  name: 'Name',
+  address: 'Address',
+  isGattConnected: 'GATT Connected',
+  'rssi.value': 'Latest RSSI',
+  'services.length': 'Services',
+};
+
+/**
+ * Page that displays all of the details of a device. This page is generated
+ * and managed dynamically in bluetooth_internals. The page contains two
+ * sections: Status and Services. The Status section displays information from
+ * the DeviceInfo object and the Services section contains a ServiceList
+ * compononent that lists all of the active services on the device.
+ */
+export class DeviceDetailsPage extends Page {
   /**
-   * Property names that will be displayed in the ObjectFieldSet which contains
-   * the DeviceInfo object.
+   * @param {string} id
+   * @param {!bluetooth.mojom.DeviceInfo} deviceInfo
    */
-  const PROPERTY_NAMES = {
-    name: 'Name',
-    address: 'Address',
-    isGattConnected: 'GATT Connected',
-    'rssi.value': 'Latest RSSI',
-    'services.length': 'Services',
-  };
+  constructor(id, deviceInfo) {
+    super(id, deviceInfo.nameForDisplay, id);
 
-  /**
-   * Page that displays all of the details of a device. This page is generated
-   * and managed dynamically in bluetooth_internals. The page contains two
-   * sections: Status and Services. The Status section displays information from
-   * the DeviceInfo object and the Services section contains a ServiceList
-   * compononent that lists all of the active services on the device.
-   */
-  export class DeviceDetailsPage extends Page {
-    /**
-     * @param {string} id
-     * @param {!bluetooth.mojom.DeviceInfo} deviceInfo
-     */
-    constructor(id, deviceInfo) {
-      super(id, deviceInfo.nameForDisplay, id);
+    /** @type {!bluetooth.mojom.DeviceInfo} */
+    this.deviceInfo = deviceInfo;
 
-      /** @type {!bluetooth.mojom.DeviceInfo} */
-      this.deviceInfo = deviceInfo;
+    /** @type {?Array<bluetooth.mojom.ServiceInfo>} */
+    this.services = null;
 
-      /** @type {?Array<bluetooth.mojom.ServiceInfo>} */
-      this.services = null;
+    /** @private {?bluetooth.mojom.DeviceRemote} */
+    this.device_ = null;
 
-      /** @private {?bluetooth.mojom.DeviceRemote} */
-      this.device_ = null;
+    /** @private {!ObjectFieldSet} */
+    this.deviceFieldSet_ = new ObjectFieldSet();
+    this.deviceFieldSet_.setPropertyDisplayNames(PROPERTY_NAMES);
 
-      /** @private {!ObjectFieldSet} */
-      this.deviceFieldSet_ = new ObjectFieldSet();
-      this.deviceFieldSet_.setPropertyDisplayNames(PROPERTY_NAMES);
+    /** @private {!ServiceList} */
+    this.serviceList_ = new ServiceList();
 
-      /** @private {!ServiceList} */
-      this.serviceList_ = new ServiceList();
+    /** @private {!ConnectionStatus} */
+    this.status_ = ConnectionStatus.DISCONNECTED;
 
-      /** @private {!ConnectionStatus} */
-      this.status_ = ConnectionStatus.DISCONNECTED;
+    /** @private {?Element} */
+    this.connectBtn_ = null;
 
-      /** @private {?Element} */
-      this.connectBtn_ = null;
+    this.pageDiv.appendChild(document.importNode(
+        $('device-details-template').content, true /* deep */));
 
-      this.pageDiv.appendChild(document.importNode(
-          $('device-details-template').content, true /* deep */));
+    this.pageDiv.querySelector('.device-details')
+        .appendChild(this.deviceFieldSet_);
+    this.pageDiv.querySelector('.services').appendChild(this.serviceList_);
 
-      this.pageDiv.querySelector('.device-details')
-          .appendChild(this.deviceFieldSet_);
-      this.pageDiv.querySelector('.services').appendChild(this.serviceList_);
-
-      this.pageDiv.querySelector('.forget').addEventListener(
-          'click', function() {
-            this.disconnect();
-            this.pageDiv.dispatchEvent(new CustomEvent('forgetpressed', {
-              detail: {
-                address: this.deviceInfo.address,
-              },
-            }));
-          }.bind(this));
-
-      this.connectBtn_ = this.pageDiv.querySelector('.disconnect');
-      this.connectBtn_.addEventListener('click', function() {
-        this.device_ !== null ? this.disconnect() : this.connect();
-      }.bind(this));
-
-      this.redraw();
-    }
-
-    /** Creates a connection to the Bluetooth device. */
-    connect() {
-      if (this.status_ !== ConnectionStatus.DISCONNECTED) {
-        return;
-      }
-
-      this.updateConnectionStatus_(
-          ConnectionStatus.CONNECTING);
-
-      connectToDevice(this.deviceInfo.address)
-          .then(function(device) {
-            this.device_ = device;
-
-            this.updateConnectionStatus_(
-                ConnectionStatus.CONNECTED);
-
-            // Fetch services asynchronously.
-            return this.device_.getServices();
-          }.bind(this))
-          .then(function(response) {
-            this.services = response.services;
-            this.serviceList_.load(this.deviceInfo.address);
-            this.redraw();
-            this.fireDeviceInfoChanged_();
-          }.bind(this))
-          .catch(function(error) {
-            // If a connection error occurs while fetching the services, the
-            // DeviceRemote reference must be removed.
-            if (this.device_) {
-              this.device_.disconnect();
-              this.device_ = null;
-            }
-
-            Snackbar.show(
-                this.deviceInfo.nameForDisplay + ': ' + error.message,
-                SnackbarType.ERROR, 'Retry', this.connect.bind(this));
-
-            this.updateConnectionStatus_(
-                ConnectionStatus.DISCONNECTED);
-          }.bind(this));
-    }
-
-    /** Disconnects the page from the Bluetooth device. */
-    disconnect() {
-      if (!this.device_) {
-        return;
-      }
-
-      this.device_.disconnect();
-      this.device_ = null;
-      this.updateConnectionStatus_(
-          ConnectionStatus.DISCONNECTED);
-    }
-
-    /** Redraws the contents of the page with the current |deviceInfo|. */
-    redraw() {
-      const isConnected = this.deviceInfo.isGattConnected;
-
-      // Update status if connection has changed.
-      if (isConnected) {
-        this.connect();
-      } else {
-        this.disconnect();
-      }
-
-      const connectedText = isConnected ? 'Connected' : 'Not Connected';
-
-      const rssi = this.deviceInfo.rssi || {};
-      const services = this.services;
-
-      let rssiValue = 'Unknown';
-      if (rssi.value != null && rssi.value <= 0) {
-        rssiValue = rssi.value;
-      }
-
-      let serviceCount = 'Unknown';
-      if (services != null && services.length >= 0) {
-        serviceCount = services.length;
-      }
-
-      const deviceViewObj = {
-        name: this.deviceInfo.nameForDisplay,
-        address: this.deviceInfo.address,
-        isGattConnected: connectedText,
-        'rssi.value': rssiValue,
-        'services.length': serviceCount,
-      };
-
-      this.deviceFieldSet_.setObject(deviceViewObj);
-      this.serviceList_.redraw();
-    }
-
-    /**
-     * Sets the page's device info and forces a redraw.
-     * @param {!bluetooth.mojom.DeviceInfo} info
-     */
-    setDeviceInfo(info) {
-      this.deviceInfo = info;
-      this.redraw();
-    }
-
-    /**
-     * Fires an 'infochanged' event with the current |deviceInfo|
-     * @private
-     */
-    fireDeviceInfoChanged_() {
-      this.pageDiv.dispatchEvent(new CustomEvent('infochanged', {
-        bubbles: true,
-        detail: {
-          info: this.deviceInfo,
-        },
-      }));
-    }
-
-    /**
-     * Updates the current connection status. Caches the latest status, updates
-     * the connection button message, and fires a 'connectionchanged' event when
-     * finished.
-     * @param {!ConnectionStatus} status
-     * @private
-     */
-    updateConnectionStatus_(status) {
-      if (this.status_ === status) {
-        return;
-      }
-
-      this.status_ = status;
-      if (status === ConnectionStatus.DISCONNECTED) {
-        this.connectBtn_.textContent = 'Connect';
-        this.connectBtn_.disabled = false;
-      } else if (status === ConnectionStatus.CONNECTING) {
-        this.connectBtn_.textContent = 'Connecting';
-        this.connectBtn_.disabled = true;
-      } else {
-        this.connectBtn_.textContent = 'Disconnect';
-        this.connectBtn_.disabled = false;
-      }
-
-      this.pageDiv.dispatchEvent(new CustomEvent('connectionchanged', {
-        bubbles: true,
+    this.pageDiv.querySelector('.forget').addEventListener('click', function() {
+      this.disconnect();
+      this.pageDiv.dispatchEvent(new CustomEvent('forgetpressed', {
         detail: {
           address: this.deviceInfo.address,
-          status: status,
-        }
+        },
       }));
-    }
+    }.bind(this));
+
+    this.connectBtn_ = this.pageDiv.querySelector('.disconnect');
+    this.connectBtn_.addEventListener('click', function() {
+      this.device_ !== null ? this.disconnect() : this.connect();
+    }.bind(this));
+
+    this.redraw();
   }
+
+  /** Creates a connection to the Bluetooth device. */
+  connect() {
+    if (this.status_ !== ConnectionStatus.DISCONNECTED) {
+      return;
+    }
+
+    this.updateConnectionStatus_(ConnectionStatus.CONNECTING);
+
+    connectToDevice(this.deviceInfo.address)
+        .then(function(device) {
+          this.device_ = device;
+
+          this.updateConnectionStatus_(ConnectionStatus.CONNECTED);
+
+          // Fetch services asynchronously.
+          return this.device_.getServices();
+        }.bind(this))
+        .then(function(response) {
+          this.services = response.services;
+          this.serviceList_.load(this.deviceInfo.address);
+          this.redraw();
+          this.fireDeviceInfoChanged_();
+        }.bind(this))
+        .catch(function(error) {
+          // If a connection error occurs while fetching the services, the
+          // DeviceRemote reference must be removed.
+          if (this.device_) {
+            this.device_.disconnect();
+            this.device_ = null;
+          }
+
+          Snackbar.show(
+              this.deviceInfo.nameForDisplay + ': ' + error.message,
+              SnackbarType.ERROR, 'Retry', this.connect.bind(this));
+
+          this.updateConnectionStatus_(ConnectionStatus.DISCONNECTED);
+        }.bind(this));
+  }
+
+  /** Disconnects the page from the Bluetooth device. */
+  disconnect() {
+    if (!this.device_) {
+      return;
+    }
+
+    this.device_.disconnect();
+    this.device_ = null;
+    this.updateConnectionStatus_(ConnectionStatus.DISCONNECTED);
+  }
+
+  /** Redraws the contents of the page with the current |deviceInfo|. */
+  redraw() {
+    const isConnected = this.deviceInfo.isGattConnected;
+
+    // Update status if connection has changed.
+    if (isConnected) {
+      this.connect();
+    } else {
+      this.disconnect();
+    }
+
+    const connectedText = isConnected ? 'Connected' : 'Not Connected';
+
+    const rssi = this.deviceInfo.rssi || {};
+    const services = this.services;
+
+    let rssiValue = 'Unknown';
+    if (rssi.value != null && rssi.value <= 0) {
+      rssiValue = rssi.value;
+    }
+
+    let serviceCount = 'Unknown';
+    if (services != null && services.length >= 0) {
+      serviceCount = services.length;
+    }
+
+    const deviceViewObj = {
+      name: this.deviceInfo.nameForDisplay,
+      address: this.deviceInfo.address,
+      isGattConnected: connectedText,
+      'rssi.value': rssiValue,
+      'services.length': serviceCount,
+    };
+
+    this.deviceFieldSet_.setObject(deviceViewObj);
+    this.serviceList_.redraw();
+  }
+
+  /**
+   * Sets the page's device info and forces a redraw.
+   * @param {!bluetooth.mojom.DeviceInfo} info
+   */
+  setDeviceInfo(info) {
+    this.deviceInfo = info;
+    this.redraw();
+  }
+
+  /**
+   * Fires an 'infochanged' event with the current |deviceInfo|
+   * @private
+   */
+  fireDeviceInfoChanged_() {
+    this.pageDiv.dispatchEvent(new CustomEvent('infochanged', {
+      bubbles: true,
+      detail: {
+        info: this.deviceInfo,
+      },
+    }));
+  }
+
+  /**
+   * Updates the current connection status. Caches the latest status, updates
+   * the connection button message, and fires a 'connectionchanged' event when
+   * finished.
+   * @param {!ConnectionStatus} status
+   * @private
+   */
+  updateConnectionStatus_(status) {
+    if (this.status_ === status) {
+      return;
+    }
+
+    this.status_ = status;
+    if (status === ConnectionStatus.DISCONNECTED) {
+      this.connectBtn_.textContent = 'Connect';
+      this.connectBtn_.disabled = false;
+    } else if (status === ConnectionStatus.CONNECTING) {
+      this.connectBtn_.textContent = 'Connecting';
+      this.connectBtn_.disabled = true;
+    } else {
+      this.connectBtn_.textContent = 'Disconnect';
+      this.connectBtn_.disabled = false;
+    }
+
+    this.pageDiv.dispatchEvent(new CustomEvent('connectionchanged', {
+      bubbles: true,
+      detail: {
+        address: this.deviceInfo.address,
+        status: status,
+      }
+    }));
+  }
+}
diff --git a/chrome/browser/resources/bluetooth_internals/device_table.js b/chrome/browser/resources/bluetooth_internals/device_table.js
index 49547ed..ad11e92da 100644
--- a/chrome/browser/resources/bluetooth_internals/device_table.js
+++ b/chrome/browser/resources/bluetooth_internals/device_table.js
@@ -11,230 +11,230 @@
 
 import {DeviceCollection} from './device_collection.js';
 
-  const COLUMNS = {
-    NAME: 0,
-    ADDRESS: 1,
-    RSSI: 2,
-    SERVICES: 3,
-    CONNECTION_STATE: 4,
-    LINKS: 5,
-  };
+const COLUMNS = {
+  NAME: 0,
+  ADDRESS: 1,
+  RSSI: 2,
+  SERVICES: 3,
+  CONNECTION_STATE: 4,
+  LINKS: 5,
+};
+
+/**
+ * A table that lists the devices and responds to changes in the given
+ * DeviceCollection. Fires events for inspection requests from listed
+ * devices.
+ * @constructor
+ * @extends {HTMLTableElement}
+ */
+export const DeviceTable = crUiDefine(function() {
+  return document.importNode($('table-template').content.children[0], true);
+});
+
+DeviceTable.prototype = {
+  __proto__: HTMLTableElement.prototype,
+
+  /** @private {?DeviceCollection} */
+  devices_: null,
 
   /**
-   * A table that lists the devices and responds to changes in the given
-   * DeviceCollection. Fires events for inspection requests from listed
-   * devices.
-   * @constructor
-   * @extends {HTMLTableElement}
+   * Decorates an element as a UI element class. Caches references to the
+   *    table body and headers.
    */
-  export const DeviceTable = crUiDefine(function() {
-    return document.importNode($('table-template').content.children[0], true);
-  });
+  decorate() {
+    /** @private */
+    this.body_ = this.tBodies[0];
+    /** @private */
+    this.headers_ = this.tHead.rows[0].cells;
+    /** @private {!Map<!bluetooth.mojom.DeviceInfo, boolean>} */
+    this.inspectionMap_ = new Map();
+  },
 
-  DeviceTable.prototype = {
-    __proto__: HTMLTableElement.prototype,
+  /**
+   * Sets the tables device collection.
+   * @param {!DeviceCollection} deviceCollection
+   */
+  setDevices(deviceCollection) {
+    assert(!this.devices_, 'Devices can only be set once.');
 
-    /** @private {?DeviceCollection} */
-    devices_: null,
+    this.devices_ = deviceCollection;
+    this.devices_.addEventListener('sorted', this.redraw_.bind(this));
+    this.devices_.addEventListener('change', this.handleChange_.bind(this));
+    this.devices_.addEventListener('splice', this.handleSplice_.bind(this));
 
-    /**
-     * Decorates an element as a UI element class. Caches references to the
-     *    table body and headers.
-     */
-    decorate() {
-      /** @private */
-      this.body_ = this.tBodies[0];
-      /** @private */
-      this.headers_ = this.tHead.rows[0].cells;
-      /** @private {!Map<!bluetooth.mojom.DeviceInfo, boolean>} */
-      this.inspectionMap_ = new Map();
-    },
+    this.redraw_();
+  },
 
-    /**
-     * Sets the tables device collection.
-     * @param {!DeviceCollection} deviceCollection
-     */
-    setDevices(deviceCollection) {
-      assert(!this.devices_, 'Devices can only be set once.');
+  /**
+   * Updates the inspect status of the row matching the given |deviceInfo|.
+   * If |isInspecting| is true, the forget link is enabled otherwise it's
+   * disabled.
+   * @param {!bluetooth.mojom.DeviceInfo} deviceInfo
+   * @param {boolean} isInspecting
+   */
+  setInspecting(deviceInfo, isInspecting) {
+    this.inspectionMap_.set(deviceInfo, isInspecting);
+    this.updateRow_(deviceInfo, this.devices_.indexOf(deviceInfo));
+  },
 
-      this.devices_ = deviceCollection;
-      this.devices_.addEventListener('sorted', this.redraw_.bind(this));
-      this.devices_.addEventListener('change', this.handleChange_.bind(this));
-      this.devices_.addEventListener('splice', this.handleSplice_.bind(this));
+  /**
+   * Fires a forget pressed event for the row |index|.
+   * @param {number} index
+   * @private
+   */
+  handleForgetClick_(index) {
+    const event = new CustomEvent('forgetpressed', {
+      bubbles: true,
+      detail: {
+        address: this.devices_.item(index).address,
+      }
+    });
+    this.dispatchEvent(event);
+  },
 
-      this.redraw_();
-    },
+  /**
+   * Updates table row on change event of the device collection.
+   * @param {!Event} event
+   * @private
+   */
+  handleChange_(event) {
+    this.updateRow_(
+        /** @type {!bluetooth.mojom.DeviceInfo} */ (
+            this.devices_.item(event.index)),
+        event.index);
+  },
 
-    /**
-     * Updates the inspect status of the row matching the given |deviceInfo|.
-     * If |isInspecting| is true, the forget link is enabled otherwise it's
-     * disabled.
-     * @param {!bluetooth.mojom.DeviceInfo} deviceInfo
-     * @param {boolean} isInspecting
-     */
-    setInspecting(deviceInfo, isInspecting) {
-      this.inspectionMap_.set(deviceInfo, isInspecting);
-      this.updateRow_(deviceInfo, this.devices_.indexOf(deviceInfo));
-    },
+  /**
+   * Fires an inspect pressed event for the row |index|.
+   * @param {number} index
+   * @private
+   */
+  handleInspectClick_(index) {
+    const event = new CustomEvent('inspectpressed', {
+      bubbles: true,
+      detail: {
+        address: this.devices_.item(index).address,
+      }
+    });
+    this.dispatchEvent(event);
+  },
 
-    /**
-     * Fires a forget pressed event for the row |index|.
-     * @param {number} index
-     * @private
-     */
-    handleForgetClick_(index) {
-      const event = new CustomEvent('forgetpressed', {
-        bubbles: true,
-        detail: {
-          address: this.devices_.item(index).address,
-        }
-      });
-      this.dispatchEvent(event);
-    },
+  /**
+   * Updates table row on splice event of the device collection.
+   * @param {!Event} event
+   * @private
+   */
+  handleSplice_(event) {
+    event.removed.forEach(function() {
+      this.body_.deleteRow(event.index);
+    }, this);
 
-    /**
-     * Updates table row on change event of the device collection.
-     * @param {!Event} event
-     * @private
-     */
-    handleChange_(event) {
-      this.updateRow_(
-          /** @type {!bluetooth.mojom.DeviceInfo} */ (
-              this.devices_.item(event.index)),
-          event.index);
-    },
+    event.added.forEach(function(device, index) {
+      this.insertRow_(device, event.index + index);
+    }, this);
+  },
 
-    /**
-     * Fires an inspect pressed event for the row |index|.
-     * @param {number} index
-     * @private
-     */
-    handleInspectClick_(index) {
-      const event = new CustomEvent('inspectpressed', {
-        bubbles: true,
-        detail: {
-          address: this.devices_.item(index).address,
-        }
-      });
-      this.dispatchEvent(event);
-    },
+  /**
+   * Inserts a new row at |index| and updates it with info from |device|.
+   * @param {!bluetooth.mojom.DeviceInfo} device
+   * @param {?number} index
+   * @private
+   */
+  insertRow_(device, index) {
+    const row = this.body_.insertRow(index);
+    row.id = device.address;
 
-    /**
-     * Updates table row on splice event of the device collection.
-     * @param {!Event} event
-     * @private
-     */
-    handleSplice_(event) {
-      event.removed.forEach(function() {
-        this.body_.deleteRow(event.index);
-      }, this);
+    for (let i = 0; i < this.headers_.length; i++) {
+      // Skip the LINKS column. It has no data-field attribute.
+      if (i === COLUMNS.LINKS) {
+        continue;
+      }
+      row.insertCell();
+    }
 
-      event.added.forEach(function(device, index) {
-        this.insertRow_(device, event.index + index);
-      }, this);
-    },
+    // Make two extra cells for the inspect link and connect errors.
+    const inspectCell = row.insertCell();
 
-    /**
-     * Inserts a new row at |index| and updates it with info from |device|.
-     * @param {!bluetooth.mojom.DeviceInfo} device
-     * @param {?number} index
-     * @private
-     */
-    insertRow_(device, index) {
-      const row = this.body_.insertRow(index);
-      row.id = device.address;
+    const inspectLink = document.createElement('a', {is: 'action-link'});
+    inspectLink.setAttribute('is', 'action-link');
+    inspectLink.textContent = 'Inspect';
+    inspectCell.appendChild(inspectLink);
+    inspectLink.addEventListener('click', function() {
+      this.handleInspectClick_(row.sectionRowIndex);
+    }.bind(this));
 
-      for (let i = 0; i < this.headers_.length; i++) {
-        // Skip the LINKS column. It has no data-field attribute.
-        if (i === COLUMNS.LINKS) {
-          continue;
-        }
-        row.insertCell();
+    const forgetLink = document.createElement('a', {is: 'action-link'});
+    forgetLink.setAttribute('is', 'action-link');
+    forgetLink.textContent = 'Forget';
+    inspectCell.appendChild(forgetLink);
+    forgetLink.addEventListener('click', function() {
+      this.handleForgetClick_(row.sectionRowIndex);
+    }.bind(this));
+
+    this.updateRow_(device, row.sectionRowIndex);
+  },
+
+  /**
+   * Deletes and recreates the table using the cached |devices_|.
+   * @private
+   */
+  redraw_() {
+    this.removeChild(this.body_);
+    this.appendChild(document.createElement('tbody'));
+    this.body_ = this.querySelector('tbody');
+    this.body_.classList.add('table-body');
+
+    for (let i = 0; i < this.devices_.length; i++) {
+      this.insertRow_(
+          /** @type {!bluetooth.mojom.DeviceInfo} */ (this.devices_.item(i)),
+          null);
+    }
+  },
+
+  /**
+   * Updates the row at |index| with the info from |device|.
+   * @param {!bluetooth.mojom.DeviceInfo} device
+   * @param {number} index
+   * @private
+   */
+  updateRow_(device, index) {
+    const row = this.body_.rows[index];
+    assert(row, 'Row ' + index + ' is not in the table.');
+
+    row.classList.toggle('removed', this.devices_.isRemoved(device));
+
+    const forgetLink = row.cells[COLUMNS.LINKS].children[1];
+
+    if (this.inspectionMap_.has(device)) {
+      forgetLink.disabled = !this.inspectionMap_.get(device);
+    } else {
+      forgetLink.disabled = true;
+    }
+
+    // Update the properties based on the header field path.
+    for (let i = 0; i < this.headers_.length; i++) {
+      // Skip the LINKS column. It has no data-field attribute.
+      if (i === COLUMNS.LINKS) {
+        continue;
       }
 
-      // Make two extra cells for the inspect link and connect errors.
-      const inspectCell = row.insertCell();
+      const header = this.headers_[i];
+      const propName = header.dataset.field;
 
-      const inspectLink = document.createElement('a', {is: 'action-link'});
-      inspectLink.setAttribute('is', 'action-link');
-      inspectLink.textContent = 'Inspect';
-      inspectCell.appendChild(inspectLink);
-      inspectLink.addEventListener('click', function() {
-        this.handleInspectClick_(row.sectionRowIndex);
-      }.bind(this));
-
-      const forgetLink = document.createElement('a', {is: 'action-link'});
-      forgetLink.setAttribute('is', 'action-link');
-      forgetLink.textContent = 'Forget';
-      inspectCell.appendChild(forgetLink);
-      forgetLink.addEventListener('click', function() {
-        this.handleForgetClick_(row.sectionRowIndex);
-      }.bind(this));
-
-      this.updateRow_(device, row.sectionRowIndex);
-    },
-
-    /**
-     * Deletes and recreates the table using the cached |devices_|.
-     * @private
-     */
-    redraw_() {
-      this.removeChild(this.body_);
-      this.appendChild(document.createElement('tbody'));
-      this.body_ = this.querySelector('tbody');
-      this.body_.classList.add('table-body');
-
-      for (let i = 0; i < this.devices_.length; i++) {
-        this.insertRow_(
-            /** @type {!bluetooth.mojom.DeviceInfo} */ (this.devices_.item(i)),
-            null);
-      }
-    },
-
-    /**
-     * Updates the row at |index| with the info from |device|.
-     * @param {!bluetooth.mojom.DeviceInfo} device
-     * @param {number} index
-     * @private
-     */
-    updateRow_(device, index) {
-      const row = this.body_.rows[index];
-      assert(row, 'Row ' + index + ' is not in the table.');
-
-      row.classList.toggle('removed', this.devices_.isRemoved(device));
-
-      const forgetLink = row.cells[COLUMNS.LINKS].children[1];
-
-      if (this.inspectionMap_.has(device)) {
-        forgetLink.disabled = !this.inspectionMap_.get(device);
-      } else {
-        forgetLink.disabled = true;
+      const parts = propName.split('.');
+      let obj = device;
+      while (obj != null && parts.length > 0) {
+        const part = parts.shift();
+        obj = obj[part];
       }
 
-      // Update the properties based on the header field path.
-      for (let i = 0; i < this.headers_.length; i++) {
-        // Skip the LINKS column. It has no data-field attribute.
-        if (i === COLUMNS.LINKS) {
-          continue;
-        }
-
-        const header = this.headers_[i];
-        const propName = header.dataset.field;
-
-        const parts = propName.split('.');
-        let obj = device;
-        while (obj != null && parts.length > 0) {
-          const part = parts.shift();
-          obj = obj[part];
-        }
-
-        if (propName == 'isGattConnected') {
-          obj = obj ? 'Connected' : 'Not Connected';
-        }
-
-        const cell = row.cells[i];
-        cell.textContent = obj == null ? 'Unknown' : obj;
-        cell.dataset.label = header.textContent;
+      if (propName == 'isGattConnected') {
+        obj = obj ? 'Connected' : 'Not Connected';
       }
-    },
-  };
+
+      const cell = row.cells[i];
+      cell.textContent = obj == null ? 'Unknown' : obj;
+      cell.dataset.label = header.textContent;
+    }
+  },
+};
diff --git a/chrome/browser/resources/bluetooth_internals/devices_page.js b/chrome/browser/resources/bluetooth_internals/devices_page.js
index 6931eca2..dd15e71 100644
--- a/chrome/browser/resources/bluetooth_internals/devices_page.js
+++ b/chrome/browser/resources/bluetooth_internals/devices_page.js
@@ -7,72 +7,72 @@
  *     chrome://bluetooth-internals/.
  */
 
-import {Page} from './page.js';
 import {DeviceCollection} from './device_collection.js';
 import {DeviceTable} from './device_table.js';
+import {Page} from './page.js';
+
+/**
+ * Enum of scan status for the devices page.
+ * @enum {number}
+ */
+export const ScanStatus = {
+  OFF: 0,
+  STARTING: 1,
+  ON: 2,
+  STOPPING: 3,
+};
+
+
+/**
+ * Page that contains a header and a DevicesView.
+ */
+export class DevicesPage extends Page {
+  constructor() {
+    super('devices', 'Devices', 'devices');
+
+    this.deviceTable = new DeviceTable();
+    this.pageDiv.appendChild(this.deviceTable);
+    this.scanBtn_ = this.pageDiv.querySelector('#scan-btn');
+    this.scanBtn_.addEventListener('click', event => {
+      this.pageDiv.dispatchEvent(new CustomEvent('scanpressed'));
+    });
+  }
 
   /**
-   * Enum of scan status for the devices page.
-   * @enum {number}
+   * Sets the device collection for the page's device table.
+   * @param {!DeviceCollection} devices
    */
-  export const ScanStatus = {
-    OFF: 0,
-    STARTING: 1,
-    ON: 2,
-    STOPPING: 3,
-  };
-
+  setDevices(devices) {
+    this.deviceTable.setDevices(devices);
+  }
 
   /**
-   * Page that contains a header and a DevicesView.
+   * Updates the inspect status of the given |deviceInfo| in the device table.
+   * @param {!bluetooth.mojom.DeviceInfo} deviceInfo
+   * @param {boolean} isInspecting
    */
-  export class DevicesPage extends Page {
-    constructor() {
-      super('devices', 'Devices', 'devices');
+  setInspecting(deviceInfo, isInspecting) {
+    this.deviceTable.setInspecting(deviceInfo, isInspecting);
+  }
 
-      this.deviceTable = new DeviceTable();
-      this.pageDiv.appendChild(this.deviceTable);
-      this.scanBtn_ = this.pageDiv.querySelector('#scan-btn');
-      this.scanBtn_.addEventListener('click', event => {
-        this.pageDiv.dispatchEvent(new CustomEvent('scanpressed'));
-      });
-    }
-
-    /**
-     * Sets the device collection for the page's device table.
-     * @param {!DeviceCollection} devices
-     */
-    setDevices(devices) {
-      this.deviceTable.setDevices(devices);
-    }
-
-    /**
-     * Updates the inspect status of the given |deviceInfo| in the device table.
-     * @param {!bluetooth.mojom.DeviceInfo} deviceInfo
-     * @param {boolean} isInspecting
-     */
-    setInspecting(deviceInfo, isInspecting) {
-      this.deviceTable.setInspecting(deviceInfo, isInspecting);
-    }
-
-    setScanStatus(status) {
-      switch (status) {
-        case ScanStatus.OFF:
-          this.scanBtn_.disabled = false;
-          this.scanBtn_.textContent = 'Start Scan';
-          break;
-        case ScanStatus.STARTING:
-          this.scanBtn_.disabled = true;
-          this.scanBtn_.textContent = 'Starting...';
-          break;
-        case ScanStatus.ON:
-          this.scanBtn_.disabled = false;
-          this.scanBtn_.textContent = 'Stop Scan';
-          break;
-        case ScanStatus.STOPPING:
-          this.scanBtn_.disabled = true;
-          this.scanBtn_.textContent = 'Stopping...';
-          break;
-      }
+  setScanStatus(status) {
+    switch (status) {
+      case ScanStatus.OFF:
+        this.scanBtn_.disabled = false;
+        this.scanBtn_.textContent = 'Start Scan';
+        break;
+      case ScanStatus.STARTING:
+        this.scanBtn_.disabled = true;
+        this.scanBtn_.textContent = 'Starting...';
+        break;
+      case ScanStatus.ON:
+        this.scanBtn_.disabled = false;
+        this.scanBtn_.textContent = 'Stop Scan';
+        break;
+      case ScanStatus.STOPPING:
+        this.scanBtn_.disabled = true;
+        this.scanBtn_.textContent = 'Stopping...';
+        break;
     }
   }
+}
diff --git a/chrome/browser/resources/bluetooth_internals/expandable_list.js b/chrome/browser/resources/bluetooth_internals/expandable_list.js
index 597073b..7090723 100644
--- a/chrome/browser/resources/bluetooth_internals/expandable_list.js
+++ b/chrome/browser/resources/bluetooth_internals/expandable_list.js
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {ArrayDataModel} from 'chrome://resources/js/cr/ui/array_data_model.m.js';
 import {define as crUiDefine} from 'chrome://resources/js/cr/ui.m.js';
+import {ArrayDataModel} from 'chrome://resources/js/cr/ui/array_data_model.m.js';
 import {List} from 'chrome://resources/js/cr/ui/list.m.js';
 import {ListItem} from 'chrome://resources/js/cr/ui/list_item.m.js';
 
@@ -12,126 +12,126 @@
  *     chrome://bluetooth-internals/.
  */
 
-  /**
-   * A list item that has expandable content that toggles when the item is
-   * clicked.
-   * @constructor
-   * @extends {ListItem}
-   */
-  export const ExpandableListItem = crUiDefine('li');
+/**
+ * A list item that has expandable content that toggles when the item is
+ * clicked.
+ * @constructor
+ * @extends {ListItem}
+ */
+export const ExpandableListItem = crUiDefine('li');
 
-  ExpandableListItem.prototype = {
-    __proto__: ListItem.prototype,
-
-    /**
-     * Decorates the element as an expandable list item and caches the created
-     * content holders for implementations.
-     * @override
-     */
-    decorate() {
-      this.classList.add('expandable-list-item');
-      this.briefContent_ = document.createElement('div');
-      this.briefContent_.classList.add('brief-content');
-      this.briefContent_.addEventListener('click', this.onExpand_.bind(this));
-      this.appendChild(this.briefContent_);
-
-      this.expandedContent_ = document.createElement('div');
-      this.expandedContent_.classList.add('expanded-content');
-      this.appendChild(this.expandedContent_);
-    },
-
-    /**
-     * Called when the list item is expanded or collapsed.
-     * @param {boolean} expanded
-     */
-    onExpandInternal(expanded) {},
-
-    /**
-     * Toggles the expanded class on the item.
-     * @private
-     */
-    onExpand_() {
-      this.onExpandInternal(this.classList.toggle('expanded'));
-    },
-  };
+ExpandableListItem.prototype = {
+  __proto__: ListItem.prototype,
 
   /**
-   * A list that contains expandable list items.
-   * @constructor
-   * @extends {List}
+   * Decorates the element as an expandable list item and caches the created
+   * content holders for implementations.
+   * @override
    */
-  export const ExpandableList = crUiDefine('list');
+  decorate() {
+    this.classList.add('expandable-list-item');
+    this.briefContent_ = document.createElement('div');
+    this.briefContent_.classList.add('brief-content');
+    this.briefContent_.addEventListener('click', this.onExpand_.bind(this));
+    this.appendChild(this.briefContent_);
 
-  ExpandableList.prototype = {
-    __proto__: List.prototype,
+    this.expandedContent_ = document.createElement('div');
+    this.expandedContent_.classList.add('expanded-content');
+    this.appendChild(this.expandedContent_);
+  },
 
-    /**
-     * Decorates element as an expandable list and caches references to layout
-     * elements.
-     * @override
-     */
-    decorate() {
-      List.prototype.decorate.call(this);
-      this.classList.add('expandable-list');
+  /**
+   * Called when the list item is expanded or collapsed.
+   * @param {boolean} expanded
+   */
+  onExpandInternal(expanded) {},
 
-      this.emptyMessage_ = document.createElement('h3');
-      this.emptyMessage_.classList.add('empty-message');
-      this.emptyMessage_.hidden = true;
-      this.insertBefore(this.emptyMessage_, this.firstChild);
+  /**
+   * Toggles the expanded class on the item.
+   * @private
+   */
+  onExpand_() {
+    this.onExpandInternal(this.classList.toggle('expanded'));
+  },
+};
 
-      this.spinner_ = document.createElement('div');
-      this.spinner_.classList.add('spinner');
-      this.insertBefore(this.spinner_, this.firstChild);
+/**
+ * A list that contains expandable list items.
+ * @constructor
+ * @extends {List}
+ */
+export const ExpandableList = crUiDefine('list');
 
-      this.autoExpands = true;
-      this.boundUpdateMessage_ = this.updateMessageDisplay_.bind(this);
-      this.setSpinnerShowing(true);
-    },
+ExpandableList.prototype = {
+  __proto__: List.prototype,
 
-    /**
-     * Sets the data model of the list.
-     * @param {ArrayDataModel} data
-     */
-    setData(data) {
-      if (this.dataModel) {
-        this.dataModel.removeEventListener('splice', this.boundUpdateMessage_);
-      }
+  /**
+   * Decorates element as an expandable list and caches references to layout
+   * elements.
+   * @override
+   */
+  decorate() {
+    List.prototype.decorate.call(this);
+    this.classList.add('expandable-list');
 
-      this.dataModel = data;
-      this.dataModel.addEventListener('splice', this.boundUpdateMessage_);
-      this.updateMessageDisplay_();
-    },
+    this.emptyMessage_ = document.createElement('h3');
+    this.emptyMessage_.classList.add('empty-message');
+    this.emptyMessage_.hidden = true;
+    this.insertBefore(this.emptyMessage_, this.firstChild);
 
-    /**
-     * Sets the empty message text.
-     * @param {string} message
-     */
-    setEmptyMessage(message) {
-      this.emptyMessage_.textContent = message;
-    },
+    this.spinner_ = document.createElement('div');
+    this.spinner_.classList.add('spinner');
+    this.insertBefore(this.spinner_, this.firstChild);
 
-    /**
-     * Sets the spinner display state. If |showing| is true, the loading
-     * spinner is dispayed.
-     * @param {boolean} showing
-     */
-    setSpinnerShowing(showing) {
-      this.spinner_.hidden = !showing;
-    },
+    this.autoExpands = true;
+    this.boundUpdateMessage_ = this.updateMessageDisplay_.bind(this);
+    this.setSpinnerShowing(true);
+  },
 
-    /**
-     * Gets the spinner display state. Returns true if the spinner is showing.
-     * @return {boolean}
-     */
-    isSpinnerShowing() {
-      return !this.spinner_.hidden;
-    },
+  /**
+   * Sets the data model of the list.
+   * @param {ArrayDataModel} data
+   */
+  setData(data) {
+    if (this.dataModel) {
+      this.dataModel.removeEventListener('splice', this.boundUpdateMessage_);
+    }
 
-    /**
-     * Updates the display state of the empty message. If there are no items in
-     * the data model, the empty message is displayed.
-     */
-    updateMessageDisplay_() {
-      this.emptyMessage_.hidden = this.dataModel.length > 0;
-    },
-  };
+    this.dataModel = data;
+    this.dataModel.addEventListener('splice', this.boundUpdateMessage_);
+    this.updateMessageDisplay_();
+  },
+
+  /**
+   * Sets the empty message text.
+   * @param {string} message
+   */
+  setEmptyMessage(message) {
+    this.emptyMessage_.textContent = message;
+  },
+
+  /**
+   * Sets the spinner display state. If |showing| is true, the loading
+   * spinner is dispayed.
+   * @param {boolean} showing
+   */
+  setSpinnerShowing(showing) {
+    this.spinner_.hidden = !showing;
+  },
+
+  /**
+   * Gets the spinner display state. Returns true if the spinner is showing.
+   * @return {boolean}
+   */
+  isSpinnerShowing() {
+    return !this.spinner_.hidden;
+  },
+
+  /**
+   * Updates the display state of the empty message. If there are no items in
+   * the data model, the empty message is displayed.
+   */
+  updateMessageDisplay_() {
+    this.emptyMessage_.hidden = this.dataModel.length > 0;
+  },
+};
diff --git a/chrome/browser/resources/bluetooth_internals/object_fieldset.js b/chrome/browser/resources/bluetooth_internals/object_fieldset.js
index acb82ed..d5203eb 100644
--- a/chrome/browser/resources/bluetooth_internals/object_fieldset.js
+++ b/chrome/browser/resources/bluetooth_internals/object_fieldset.js
@@ -12,92 +12,92 @@
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {define as crUiDefine} from 'chrome://resources/js/cr/ui.m.js';
 
+/**
+ * A fieldset that lists the properties of a given object. These properties
+ * are displayed as a series of rows for each key-value pair.
+ * Only the object's own properties are displayed. Boolean values are
+ * displayed using images: a green check for 'true', and a red cancel 'x' for
+ * 'false'. All other types are converted to their string representation for
+ * display.
+ * @constructor
+ * @extends {HTMLFieldSetElement}
+ */
+export const ObjectFieldSet = crUiDefine('fieldset');
+
+ObjectFieldSet.prototype = {
+  __proto__: HTMLFieldSetElement.prototype,
+
+  set showAll(showAll) {
+    this.showAll_ = showAll;
+  },
+
+  get showAll() {
+    return this.showAll_;
+  },
+
   /**
-   * A fieldset that lists the properties of a given object. These properties
-   * are displayed as a series of rows for each key-value pair.
-   * Only the object's own properties are displayed. Boolean values are
-   * displayed using images: a green check for 'true', and a red cancel 'x' for
-   * 'false'. All other types are converted to their string representation for
-   * display.
-   * @constructor
-   * @extends {HTMLFieldSetElement}
+   * Decorates the element as an ObjectFieldset.
    */
-  export const ObjectFieldSet = crUiDefine('fieldset');
+  decorate() {
+    this.classList.add('object-fieldset');
 
-  ObjectFieldSet.prototype = {
-    __proto__: HTMLFieldSetElement.prototype,
+    /** @type {?Object} */
+    this.value = null;
+    /** @private {?Object<string, string>} */
+    this.nameMap_ = null;
+    this.showAll_ = true;
+  },
 
-    set showAll(showAll) {
-      this.showAll_ = showAll;
-    },
+  /**
+   * Sets the object data to be displayed in the fieldset.
+   * @param {!Object} value
+   */
+  setObject(value) {
+    this.value = value;
+    this.redraw();
+  },
 
-    get showAll() {
-      return this.showAll_;
-    },
+  /**
+   * Sets the object used to map property names to display names. If a display
+   * name is not provided, the default property name will be used.
+   * @param {!Object<string, string>} nameMap
+   */
+  setPropertyDisplayNames(nameMap) {
+    this.nameMap_ = nameMap;
+  },
 
-    /**
-     * Decorates the element as an ObjectFieldset.
-     */
-    decorate() {
-      this.classList.add('object-fieldset');
+  /**
+   * Deletes and recreates the table structure with current object data.
+   */
+  redraw() {
+    this.innerHTML = trustedTypes.emptyHTML;
 
-      /** @type {?Object} */
-      this.value = null;
-      /** @private {?Object<string, string>} */
-      this.nameMap_ = null;
-      this.showAll_ = true;
-    },
+    Object.keys(assert(this.value)).forEach(function(propName) {
+      const value = this.value[propName];
+      if (value === false && !this.showAll_) {
+        return;
+      }
 
-    /**
-     * Sets the object data to be displayed in the fieldset.
-     * @param {!Object} value
-     */
-    setObject(value) {
-      this.value = value;
-      this.redraw();
-    },
+      const name = this.nameMap_[propName] || propName;
+      const newField = document.createElement('div');
+      newField.classList.add('status');
 
-    /**
-     * Sets the object used to map property names to display names. If a display
-     * name is not provided, the default property name will be used.
-     * @param {!Object<string, string>} nameMap
-     */
-    setPropertyDisplayNames(nameMap) {
-      this.nameMap_ = nameMap;
-    },
+      const nameDiv = document.createElement('div');
+      nameDiv.textContent = name + ':';
+      newField.appendChild(nameDiv);
 
-    /**
-     * Deletes and recreates the table structure with current object data.
-     */
-    redraw() {
-      this.innerHTML = trustedTypes.emptyHTML;
+      const valueDiv = document.createElement('div');
+      valueDiv.dataset.field = propName;
 
-      Object.keys(assert(this.value)).forEach(function(propName) {
-        const value = this.value[propName];
-        if (value === false && !this.showAll_) {
-          return;
-        }
+      if (typeof (value) === 'boolean') {
+        valueDiv.classList.add('toggle-status');
+        valueDiv.classList.toggle('checked', value);
+      } else {
+        valueDiv.textContent = String(value);
+      }
 
-        const name = this.nameMap_[propName] || propName;
-        const newField = document.createElement('div');
-        newField.classList.add('status');
-
-        const nameDiv = document.createElement('div');
-        nameDiv.textContent = name + ':';
-        newField.appendChild(nameDiv);
-
-        const valueDiv = document.createElement('div');
-        valueDiv.dataset.field = propName;
-
-        if (typeof(value) === 'boolean') {
-          valueDiv.classList.add('toggle-status');
-          valueDiv.classList.toggle('checked', value);
-        } else {
-          valueDiv.textContent = String(value);
-        }
-
-        newField.appendChild(valueDiv);
-        this.appendChild(newField);
-      }, this);
-    },
-  };
+      newField.appendChild(valueDiv);
+      this.appendChild(newField);
+    }, this);
+  },
+};
diff --git a/chrome/browser/resources/bluetooth_internals/page.js b/chrome/browser/resources/bluetooth_internals/page.js
index 839e703..f8e5da2 100644
--- a/chrome/browser/resources/bluetooth_internals/page.js
+++ b/chrome/browser/resources/bluetooth_internals/page.js
@@ -6,149 +6,149 @@
 import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js';
 import {getRequiredElement} from 'chrome://resources/js/util.m.js';
 
+/**
+ * Finds a good place to set initial focus. Generally called when UI is shown.
+ * @param {!Element} root Where to start looking for focusable controls.
+ */
+function setInitialFocus(root) {
+  // Do not change focus if any element in |root| is already focused.
+  if (root.contains(document.activeElement)) {
+    return;
+  }
+
+  const elements =
+      root.querySelectorAll('input, list, select, textarea, button');
+  for (let i = 0; i < elements.length; i++) {
+    const element = elements[i];
+    element.focus();
+    // .focus() isn't guaranteed to work. Continue until it does.
+    if (document.activeElement == element) {
+      return;
+    }
+  }
+}
+
+/**
+ * Base class for pages that can be shown and hidden by PageManager. Each Page
+ * is like a node in a forest, corresponding to a particular div. At any
+ * point, one root Page is visible, and any visible Page can show a child Page
+ * as an overlay. The host of the root Page(s) should provide a container div
+ * for each nested level to enforce the stack order of overlays.
+ */
+export class Page extends EventTarget {
   /**
-   * Finds a good place to set initial focus. Generally called when UI is shown.
-   * @param {!Element} root Where to start looking for focusable controls.
+   * @param {string} name Page name.
+   * @param {string} title Page title, used for history.
+   * @param {string} pageDivName ID of the div corresponding to the page.
    */
-  function setInitialFocus(root) {
-    // Do not change focus if any element in |root| is already focused.
-    if (root.contains(document.activeElement)) {
+  constructor(name, title, pageDivName) {
+    super();
+
+    this.name = name;
+    this.title = title;
+    this.pageDivName = pageDivName;
+    this.pageDiv = getRequiredElement(this.pageDivName);
+    // |pageDiv.page| is set to the page object (this) when the page is
+    // visible to track which page is being shown when multiple pages can
+    // share the same underlying div.
+    this.pageDiv.page = null;
+    this.tab = null;
+    this.lastFocusedElement = null;
+    this.hash = '';
+
+    /**
+     * The parent page of this page; or null for root pages.
+     * @type {Page}
+     */
+    this.parentPage = null;
+
+    /**
+     * The section on the parent page that is associated with this page.
+     * Can be null.
+     * @type {Element}
+     */
+    this.associatedSection = null;
+
+    /**
+     * An array of controls that are associated with this page. The first
+     * control should be located on a root page.
+     * @type {Array<Element>}
+     */
+    this.associatedControls = null;
+  }
+
+  /**
+   * Initializes page content.
+   */
+  initializePage() {}
+
+  /**
+   * Called by the PageManager when this.hash changes while the page is
+   * already visible. This is analogous to the hashchange DOM event.
+   */
+  didChangeHash() {}
+
+  /**
+   * Sets focus on the first focusable element. Override for a custom focus
+   * strategy.
+   */
+  focus() {
+    setInitialFocus(this.pageDiv);
+  }
+
+  /**
+   * Updates the hash of the current page. If the page is topmost, the history
+   * state is updated.
+   * @param {string} hash The new hash value. Like location.hash, this
+   *     should include the leading '#' if not empty.
+   */
+  setHash(hash) {
+    if (this.hash == hash) {
+      return;
+    }
+    this.hash = hash;
+    this.dispatchEvent(new CustomEvent('page-hash-changed'));
+  }
+
+  /**
+   * Called after the page has been shown.
+   */
+  didShowPage() {}
+
+  /**
+   * Called before the page will be hidden, e.g., when a different root page
+   * will be shown.
+   */
+  willHidePage() {}
+
+  /**
+   * Called after the overlay has been closed.
+   */
+  didClosePage() {}
+
+  /**
+   * Gets page visibility state.
+   * @type {boolean}
+   */
+  get visible() {
+    if (this.pageDiv.hidden) {
+      return false;
+    }
+    return this.pageDiv.page == this;
+  }
+
+  /**
+   * Sets page visibility.
+   * @type {boolean}
+   */
+  set visible(visible) {
+    if ((this.visible && visible) || (!this.visible && !visible)) {
       return;
     }
 
-    const elements =
-        root.querySelectorAll('input, list, select, textarea, button');
-    for (let i = 0; i < elements.length; i++) {
-      const element = elements[i];
-      element.focus();
-      // .focus() isn't guaranteed to work. Continue until it does.
-      if (document.activeElement == element) {
-        return;
-      }
-    }
+    this.pageDiv.page = this;
+    this.pageDiv.hidden = !visible;
+
+    dispatchPropertyChange(this, 'visible', visible, !visible);
   }
-
-  /**
-   * Base class for pages that can be shown and hidden by PageManager. Each Page
-   * is like a node in a forest, corresponding to a particular div. At any
-   * point, one root Page is visible, and any visible Page can show a child Page
-   * as an overlay. The host of the root Page(s) should provide a container div
-   * for each nested level to enforce the stack order of overlays.
-   */
-  export class Page extends EventTarget {
-    /**
-     * @param {string} name Page name.
-     * @param {string} title Page title, used for history.
-     * @param {string} pageDivName ID of the div corresponding to the page.
-     */
-    constructor(name, title, pageDivName) {
-      super();
-
-      this.name = name;
-      this.title = title;
-      this.pageDivName = pageDivName;
-      this.pageDiv = getRequiredElement(this.pageDivName);
-      // |pageDiv.page| is set to the page object (this) when the page is
-      // visible to track which page is being shown when multiple pages can
-      // share the same underlying div.
-      this.pageDiv.page = null;
-      this.tab = null;
-      this.lastFocusedElement = null;
-      this.hash = '';
-
-      /**
-       * The parent page of this page; or null for root pages.
-       * @type {Page}
-       */
-      this.parentPage = null;
-
-      /**
-       * The section on the parent page that is associated with this page.
-       * Can be null.
-       * @type {Element}
-       */
-      this.associatedSection = null;
-
-      /**
-       * An array of controls that are associated with this page. The first
-       * control should be located on a root page.
-       * @type {Array<Element>}
-       */
-      this.associatedControls = null;
-    }
-
-    /**
-     * Initializes page content.
-     */
-    initializePage() {}
-
-    /**
-     * Called by the PageManager when this.hash changes while the page is
-     * already visible. This is analogous to the hashchange DOM event.
-     */
-    didChangeHash() {}
-
-    /**
-     * Sets focus on the first focusable element. Override for a custom focus
-     * strategy.
-     */
-    focus() {
-      setInitialFocus(this.pageDiv);
-    }
-
-    /**
-     * Updates the hash of the current page. If the page is topmost, the history
-     * state is updated.
-     * @param {string} hash The new hash value. Like location.hash, this
-     *     should include the leading '#' if not empty.
-     */
-    setHash(hash) {
-      if (this.hash == hash) {
-        return;
-      }
-      this.hash = hash;
-      this.dispatchEvent(new CustomEvent('page-hash-changed'));
-    }
-
-    /**
-     * Called after the page has been shown.
-     */
-    didShowPage() {}
-
-    /**
-     * Called before the page will be hidden, e.g., when a different root page
-     * will be shown.
-     */
-    willHidePage() {}
-
-    /**
-     * Called after the overlay has been closed.
-     */
-    didClosePage() {}
-
-    /**
-     * Gets page visibility state.
-     * @type {boolean}
-     */
-    get visible() {
-      if (this.pageDiv.hidden) {
-        return false;
-      }
-      return this.pageDiv.page == this;
-    }
-
-    /**
-     * Sets page visibility.
-     * @type {boolean}
-     */
-    set visible(visible) {
-      if ((this.visible && visible) || (!this.visible && !visible)) {
-        return;
-      }
-
-      this.pageDiv.page = this;
-      this.pageDiv.hidden = !visible;
-
-      dispatchPropertyChange(this, 'visible', visible, !visible);
-    }
-  }
+}
diff --git a/chrome/browser/resources/bluetooth_internals/page_manager.js b/chrome/browser/resources/bluetooth_internals/page_manager.js
index 3f89c0e..af922f0 100644
--- a/chrome/browser/resources/bluetooth_internals/page_manager.js
+++ b/chrome/browser/resources/bluetooth_internals/page_manager.js
@@ -3,309 +3,309 @@
 // found in the LICENSE file.
 
 import {assert} from 'chrome://resources/js/assert.m.js';
-import {Page} from './page.js';
-import {FocusOutlineManager} from 'chrome://resources/js/cr/ui/focus_outline_manager.m.js';
 import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
+import {FocusOutlineManager} from 'chrome://resources/js/cr/ui/focus_outline_manager.m.js';
+
+import {Page} from './page.js';
+
+/**
+ * PageManager contains a list of root Page objects and handles "navigation"
+ * by showing and hiding these pages. On initial load, PageManager can use
+ * the path to open the correct hierarchy of pages.
+ */
+export class PageManager {
+  constructor() {
+    /**
+     * True if page is served from a dialog.
+     * @type {boolean}
+     */
+    this.isDialog = false;
+
+    /**
+     * Root pages. Maps lower-case page names to the respective page object.
+     * @type {!Map<string, !Page>}
+     */
+    this.registeredPages = new Map();
+
+    /**
+     * Observers will be notified when opening and closing overlays.
+     * @private {!Array<!PageManagerObserver>}
+     */
+    this.observers_ = [];
+
+    /** @private {?Page} */
+    this.defaultPage_ = null;
+  }
 
   /**
-   * PageManager contains a list of root Page objects and handles "navigation"
-   * by showing and hiding these pages. On initial load, PageManager can use
-   * the path to open the correct hierarchy of pages.
+   * Initializes the complete page.
+   * @param {Page} defaultPage The page to be shown when no
+   *     page is specified in the path.
    */
-  export class PageManager {
-    constructor() {
-      /**
-       * True if page is served from a dialog.
-       * @type {boolean}
-       */
-      this.isDialog = false;
+  initialize(defaultPage) {
+    this.defaultPage_ = defaultPage;
 
-      /**
-       * Root pages. Maps lower-case page names to the respective page object.
-       * @type {!Map<string, !Page>}
-       */
-      this.registeredPages = new Map();
+    FocusOutlineManager.forDocument(document);
+  }
 
-      /**
-       * Observers will be notified when opening and closing overlays.
-       * @private {!Array<!PageManagerObserver>}
-       */
-      this.observers_ = [];
+  /**
+   * Registers new page.
+   * @param {!Page} page Page to register.
+   */
+  register(page) {
+    this.registeredPages.set(page.name.toLowerCase(), page);
+    page.addEventListener(
+        'page-hash-changed',
+        e => this.onPageHashChanged_(/** @type {!CustomEvent} */ (e)));
+    page.initializePage();
+  }
 
-      /** @private {?Page} */
-      this.defaultPage_ = null;
-    }
+  /**
+   * Unregisters an existing page.
+   * @param {!Page} page Page to unregister.
+   */
+  unregister(page) {
+    this.registeredPages.delete(page.name.toLowerCase());
+  }
 
-    /**
-     * Initializes the complete page.
-     * @param {Page} defaultPage The page to be shown when no
-     *     page is specified in the path.
-     */
-    initialize(defaultPage) {
-      this.defaultPage_ = defaultPage;
+  /**
+   * Shows the default page.
+   * @param {boolean=} opt_updateHistory If we should update the history after
+   *     showing the page (defaults to true).
+   */
+  showDefaultPage(opt_updateHistory) {
+    assert(
+        this.defaultPage_ instanceof Page,
+        'PageManager must be initialized with a default page.');
+    this.showPageByName(this.defaultPage_.name, opt_updateHistory);
+  }
 
-      FocusOutlineManager.forDocument(document);
-    }
+  /**
+   * Shows a registered page.
+   * @param {string} pageName Page name.
+   * @param {boolean=} opt_updateHistory If we should update the history after
+   *     showing the page (defaults to true).
+   * @param {Object=} opt_propertyBag An optional bag of properties including
+   *     replaceState (if history state should be replaced instead of pushed).
+   *     hash (a hash state to attach to the page).
+   */
+  showPageByName(pageName, opt_updateHistory, opt_propertyBag) {
+    opt_updateHistory = opt_updateHistory !== false;
+    opt_propertyBag = opt_propertyBag || {};
 
-    /**
-     * Registers new page.
-     * @param {!Page} page Page to register.
-     */
-    register(page) {
-      this.registeredPages.set(page.name.toLowerCase(), page);
-      page.addEventListener(
-          'page-hash-changed',
-          e => this.onPageHashChanged_(/** @type {!CustomEvent} */ (e)));
-      page.initializePage();
-    }
-
-    /**
-     * Unregisters an existing page.
-     * @param {!Page} page Page to unregister.
-     */
-    unregister(page) {
-      this.registeredPages.delete(page.name.toLowerCase());
-    }
-
-    /**
-     * Shows the default page.
-     * @param {boolean=} opt_updateHistory If we should update the history after
-     *     showing the page (defaults to true).
-     */
-    showDefaultPage(opt_updateHistory) {
-      assert(
-          this.defaultPage_ instanceof Page,
-          'PageManager must be initialized with a default page.');
-      this.showPageByName(this.defaultPage_.name, opt_updateHistory);
-    }
-
-    /**
-     * Shows a registered page.
-     * @param {string} pageName Page name.
-     * @param {boolean=} opt_updateHistory If we should update the history after
-     *     showing the page (defaults to true).
-     * @param {Object=} opt_propertyBag An optional bag of properties including
-     *     replaceState (if history state should be replaced instead of pushed).
-     *     hash (a hash state to attach to the page).
-     */
-    showPageByName(pageName, opt_updateHistory, opt_propertyBag) {
-      opt_updateHistory = opt_updateHistory !== false;
-      opt_propertyBag = opt_propertyBag || {};
-
-      // Find the currently visible root-level page.
-      let rootPage = null;
-      for (const page of this.registeredPages.values()) {
-        if (page.visible && !page.parentPage) {
-          rootPage = page;
-          break;
-        }
-      }
-
-      // Find the target page.
-      let targetPage = this.registeredPages.get(pageName.toLowerCase());
-      if (!targetPage) {
-        targetPage = this.defaultPage_;
-      }
-
-      pageName = targetPage.name.toLowerCase();
-      const targetPageWasVisible = targetPage.visible;
-
-      // Notify pages if they will be hidden.
-      this.registeredPages.forEach(page => {
-        if (page.name != pageName && !this.isAncestorOfPage(page, targetPage)) {
-          page.willHidePage();
-        }
-      });
-
-      // Update the page's hash.
-      targetPage.hash = opt_propertyBag.hash || '';
-
-      // Update visibilities to show only the hierarchy of the target page.
-      this.registeredPages.forEach(page => {
-        page.visible =
-            page.name == pageName || this.isAncestorOfPage(page, targetPage);
-      });
-
-      // Update the history and current location.
-      if (opt_updateHistory) {
-        this.updateHistoryState_(!!opt_propertyBag.replaceState);
-      }
-
-      // Update focus if any other control was focused on the previous page,
-      // or the previous page is not known.
-      if (document.activeElement != document.body &&
-          (!rootPage || rootPage.pageDiv.contains(document.activeElement))) {
-        targetPage.focus();
-      }
-
-      // Notify pages if they were shown.
-      this.registeredPages.forEach(page => {
-        if (!targetPageWasVisible &&
-            (page.name == pageName ||
-             this.isAncestorOfPage(page, targetPage))) {
-          page.didShowPage();
-        }
-      });
-
-      // If the target page was already visible, notify it that its hash
-      // changed externally.
-      if (targetPageWasVisible) {
-        targetPage.didChangeHash();
-      }
-
-      // Update the document title. Do this after didShowPage was called, in
-      // case a page decides to change its title.
-      this.updateTitle_();
-    }
-
-    /**
-     * Returns the name of the page from the current path.
-     * @return {string} Name of the page specified by the current path.
-     */
-    getPageNameFromPath() {
-      const path = location.pathname;
-      if (path.length <= 1) {
-        return this.defaultPage_.name;
-      }
-
-      // Skip starting slash and remove trailing slash (if any).
-      return path.slice(1).replace(/\/$/, '');
-    }
-
-    /**
-     * Gets the level of the page. Root pages (e.g., BrowserOptions) are at
-     * level 0.
-     * @return {number} How far down this page is from the root page.
-     */
-    getNestingLevel(page) {
-      let level = 0;
-      let parent = page.parentPage;
-      while (parent) {
-        level++;
-        parent = parent.parentPage;
-      }
-      return level;
-    }
-
-    /**
-     * Checks whether one page is an ancestor of the other page in terms of
-     * subpage nesting.
-     * @param {Page} potentialAncestor Potential ancestor.
-     * @param {Page} potentialDescendent Potential descendent.
-     * @return {boolean} True if |potentialDescendent| is nested under
-     *     |potentialAncestor|.
-     */
-    isAncestorOfPage(potentialAncestor, potentialDescendent) {
-      let parent = potentialDescendent.parentPage;
-      while (parent) {
-        if (parent == potentialAncestor) {
-          return true;
-        }
-        parent = parent.parentPage;
-      }
-      return false;
-    }
-
-    /**
-     * Called when a page's hash changes. If the page is the topmost visible
-     * page, the history state is updated.
-     * @param {!CustomEvent} e
-     */
-    onPageHashChanged_(e) {
-      const page = /** @type {!Page} */ (e.target);
-      if (page == this.getTopmostVisiblePage()) {
-        this.updateHistoryState_(false);
+    // Find the currently visible root-level page.
+    let rootPage = null;
+    for (const page of this.registeredPages.values()) {
+      if (page.visible && !page.parentPage) {
+        rootPage = page;
+        break;
       }
     }
 
-    /**
-     * @param {!PageManagerObserver} observer The observer to register.
-     */
-    addObserver(observer) {
-      this.observers_.push(observer);
+    // Find the target page.
+    let targetPage = this.registeredPages.get(pageName.toLowerCase());
+    if (!targetPage) {
+      targetPage = this.defaultPage_;
     }
 
-    /**
-     * Returns the topmost visible page.
-     * @return {Page}
-     * @private
-     */
-    getTopmostVisiblePage() {
-      for (const page of this.registeredPages.values()) {
-        if (page.visible) {
-          return page;
-        }
-      }
+    pageName = targetPage.name.toLowerCase();
+    const targetPageWasVisible = targetPage.visible;
 
-      return null;
+    // Notify pages if they will be hidden.
+    this.registeredPages.forEach(page => {
+      if (page.name != pageName && !this.isAncestorOfPage(page, targetPage)) {
+        page.willHidePage();
+      }
+    });
+
+    // Update the page's hash.
+    targetPage.hash = opt_propertyBag.hash || '';
+
+    // Update visibilities to show only the hierarchy of the target page.
+    this.registeredPages.forEach(page => {
+      page.visible =
+          page.name == pageName || this.isAncestorOfPage(page, targetPage);
+    });
+
+    // Update the history and current location.
+    if (opt_updateHistory) {
+      this.updateHistoryState_(!!opt_propertyBag.replaceState);
     }
 
-    /**
-     * Updates the title to the title of the current page, or of the topmost
-     * visible page with a non-empty title.
-     * @private
-     */
-    updateTitle_() {
-      let page = this.getTopmostVisiblePage();
-      while (page) {
-        if (page.title) {
-          for (let i = 0; i < this.observers_.length; ++i) {
-            this.observers_[i].updateTitle(page.title);
-          }
-          return;
-        }
-        page = page.parentPage;
-      }
+    // Update focus if any other control was focused on the previous page,
+    // or the previous page is not known.
+    if (document.activeElement != document.body &&
+        (!rootPage || rootPage.pageDiv.contains(document.activeElement))) {
+      targetPage.focus();
     }
 
-    /**
-     * Constructs a new path to push onto the history stack, using observers
-     * to update the history.
-     * @param {boolean} replace If true, handlers should replace the current
-     *     history event rather than create new ones.
-     * @private
-     */
-    updateHistoryState_(replace) {
-      if (this.isDialog) {
-        return;
+    // Notify pages if they were shown.
+    this.registeredPages.forEach(page => {
+      if (!targetPageWasVisible &&
+          (page.name == pageName || this.isAncestorOfPage(page, targetPage))) {
+        page.didShowPage();
       }
+    });
 
-      const page = this.getTopmostVisiblePage();
-      let path = window.location.pathname + window.location.hash;
-      if (path) {
-        // Remove trailing slash.
-        path = path.slice(1).replace(/\/(?:#|$)/, '');
-      }
+    // If the target page was already visible, notify it that its hash
+    // changed externally.
+    if (targetPageWasVisible) {
+      targetPage.didChangeHash();
+    }
 
-      // If the page is already in history (the user may have clicked the same
-      // link twice, or this is the initial load), do nothing.
-      const newPath = (page == this.defaultPage_ ? '' : page.name) + page.hash;
-      if (path == newPath) {
-        return;
-      }
+    // Update the document title. Do this after didShowPage was called, in
+    // case a page decides to change its title.
+    this.updateTitle_();
+  }
 
-      for (let i = 0; i < this.observers_.length; ++i) {
-        this.observers_[i].updateHistory(newPath, replace);
+  /**
+   * Returns the name of the page from the current path.
+   * @return {string} Name of the page specified by the current path.
+   */
+  getPageNameFromPath() {
+    const path = location.pathname;
+    if (path.length <= 1) {
+      return this.defaultPage_.name;
+    }
+
+    // Skip starting slash and remove trailing slash (if any).
+    return path.slice(1).replace(/\/$/, '');
+  }
+
+  /**
+   * Gets the level of the page. Root pages (e.g., BrowserOptions) are at
+   * level 0.
+   * @return {number} How far down this page is from the root page.
+   */
+  getNestingLevel(page) {
+    let level = 0;
+    let parent = page.parentPage;
+    while (parent) {
+      level++;
+      parent = parent.parentPage;
+    }
+    return level;
+  }
+
+  /**
+   * Checks whether one page is an ancestor of the other page in terms of
+   * subpage nesting.
+   * @param {Page} potentialAncestor Potential ancestor.
+   * @param {Page} potentialDescendent Potential descendent.
+   * @return {boolean} True if |potentialDescendent| is nested under
+   *     |potentialAncestor|.
+   */
+  isAncestorOfPage(potentialAncestor, potentialDescendent) {
+    let parent = potentialDescendent.parentPage;
+    while (parent) {
+      if (parent == potentialAncestor) {
+        return true;
       }
+      parent = parent.parentPage;
+    }
+    return false;
+  }
+
+  /**
+   * Called when a page's hash changes. If the page is the topmost visible
+   * page, the history state is updated.
+   * @param {!CustomEvent} e
+   */
+  onPageHashChanged_(e) {
+    const page = /** @type {!Page} */ (e.target);
+    if (page == this.getTopmostVisiblePage()) {
+      this.updateHistoryState_(false);
     }
   }
 
   /**
-   * An observer of PageManager.
+   * @param {!PageManagerObserver} observer The observer to register.
    */
-  export class PageManagerObserver {
-    /**
-     * Called when a new title should be set.
-     * @param {string} title The title to set.
-     */
-    updateTitle(title) {}
-
-    /**
-     * Called when a page is navigated to.
-     * @param {string} path The path of the page being visited.
-     * @param {boolean} replace If true, allow no history events to be created.
-     */
-    updateHistory(path, replace) {}
+  addObserver(observer) {
+    this.observers_.push(observer);
   }
 
+  /**
+   * Returns the topmost visible page.
+   * @return {Page}
+   * @private
+   */
+  getTopmostVisiblePage() {
+    for (const page of this.registeredPages.values()) {
+      if (page.visible) {
+        return page;
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * Updates the title to the title of the current page, or of the topmost
+   * visible page with a non-empty title.
+   * @private
+   */
+  updateTitle_() {
+    let page = this.getTopmostVisiblePage();
+    while (page) {
+      if (page.title) {
+        for (let i = 0; i < this.observers_.length; ++i) {
+          this.observers_[i].updateTitle(page.title);
+        }
+        return;
+      }
+      page = page.parentPage;
+    }
+  }
+
+  /**
+   * Constructs a new path to push onto the history stack, using observers
+   * to update the history.
+   * @param {boolean} replace If true, handlers should replace the current
+   *     history event rather than create new ones.
+   * @private
+   */
+  updateHistoryState_(replace) {
+    if (this.isDialog) {
+      return;
+    }
+
+    const page = this.getTopmostVisiblePage();
+    let path = window.location.pathname + window.location.hash;
+    if (path) {
+      // Remove trailing slash.
+      path = path.slice(1).replace(/\/(?:#|$)/, '');
+    }
+
+    // If the page is already in history (the user may have clicked the same
+    // link twice, or this is the initial load), do nothing.
+    const newPath = (page == this.defaultPage_ ? '' : page.name) + page.hash;
+    if (path == newPath) {
+      return;
+    }
+
+    for (let i = 0; i < this.observers_.length; ++i) {
+      this.observers_[i].updateHistory(newPath, replace);
+    }
+  }
+}
+
+/**
+ * An observer of PageManager.
+ */
+export class PageManagerObserver {
+  /**
+   * Called when a new title should be set.
+   * @param {string} title The title to set.
+   */
+  updateTitle(title) {}
+
+  /**
+   * Called when a page is navigated to.
+   * @param {string} path The path of the page being visited.
+   * @param {boolean} replace If true, allow no history events to be created.
+   */
+  updateHistory(path, replace) {}
+}
+
 addSingletonGetter(PageManager);
diff --git a/chrome/browser/resources/bluetooth_internals/service_list.js b/chrome/browser/resources/bluetooth_internals/service_list.js
index 43f9a0f..12650bad 100644
--- a/chrome/browser/resources/bluetooth_internals/service_list.js
+++ b/chrome/browser/resources/bluetooth_internals/service_list.js
@@ -6,169 +6,169 @@
 import {define as crUiDefine} from 'chrome://resources/js/cr/ui.m.js';
 import {ArrayDataModel} from 'chrome://resources/js/cr/ui/array_data_model.m.js';
 
-import {connectToDevice} from './device_broker.js';
 import {CharacteristicList} from './characteristic_list.js';
-import {Snackbar, SnackbarType} from './snackbar.js';
+import {connectToDevice} from './device_broker.js';
 import {ExpandableList, ExpandableListItem} from './expandable_list.js';
 import {ObjectFieldSet} from './object_fieldset.js';
+import {Snackbar, SnackbarType} from './snackbar.js';
 
 /**
  * Javascript for ServiceList and ServiceListItem, served from
  *     chrome://bluetooth-internals/.
  */
 
-  /**
-   * Property names that will be displayed in the ObjectFieldSet which contains
-   * the ServiceInfo object.
-   */
-  const PROPERTY_NAMES = {
-    id: 'ID',
-    'uuid.uuid': 'UUID',
-    isPrimary: 'Type',
-  };
+/**
+ * Property names that will be displayed in the ObjectFieldSet which contains
+ * the ServiceInfo object.
+ */
+const PROPERTY_NAMES = {
+  id: 'ID',
+  'uuid.uuid': 'UUID',
+  isPrimary: 'Type',
+};
+
+/**
+ * A list item that displays the data in a ServiceInfo object. The brief
+ * section contains the UUID of the given |serviceInfo|. The expanded section
+ * contains an ObjectFieldSet that displays all of the properties in the
+ * given |serviceInfo|. Data is not loaded until the ServiceListItem is
+ * expanded for the first time.
+ * @param {!bluetooth.mojom.ServiceInfo} serviceInfo
+ * @param {string} deviceAddress
+ * @extends {ExpandableListItem}
+ * @constructor
+ */
+export function ServiceListItem(serviceInfo, deviceAddress) {
+  const listItem = new ExpandableListItem();
+  listItem.__proto__ = ServiceListItem.prototype;
+
+  /** @type {!bluetooth.mojom.ServiceInfo} */
+  listItem.info = serviceInfo;
+  /** @private {string} */
+  listItem.deviceAddress_ = deviceAddress;
+
+  listItem.decorate();
+  return listItem;
+}
+
+ServiceListItem.prototype = {
+  __proto__: ExpandableListItem.prototype,
 
   /**
-   * A list item that displays the data in a ServiceInfo object. The brief
-   * section contains the UUID of the given |serviceInfo|. The expanded section
-   * contains an ObjectFieldSet that displays all of the properties in the
-   * given |serviceInfo|. Data is not loaded until the ServiceListItem is
-   * expanded for the first time.
-   * @param {!bluetooth.mojom.ServiceInfo} serviceInfo
+   * Decorates the element as a service list item. Creates layout and caches
+   * references to the created header and fieldset.
+   * @override
+   */
+  decorate() {
+    this.classList.add('service-list-item');
+
+    /** @private {!ObjectFieldSet} */
+    this.serviceFieldSet_ = new ObjectFieldSet();
+    this.serviceFieldSet_.setPropertyDisplayNames(PROPERTY_NAMES);
+    this.serviceFieldSet_.setObject({
+      id: this.info.id,
+      'uuid.uuid': this.info.uuid.uuid,
+      isPrimary: this.info.isPrimary ? 'Primary' : 'Secondary',
+    });
+
+    // Create content for display in brief content container.
+    const serviceHeaderText = document.createElement('div');
+    serviceHeaderText.textContent = 'Service:';
+
+    const serviceHeaderValue = document.createElement('div');
+    serviceHeaderValue.textContent = this.info.uuid.uuid;
+
+    const serviceHeader = document.createElement('div');
+    serviceHeader.appendChild(serviceHeaderText);
+    serviceHeader.appendChild(serviceHeaderValue);
+    this.briefContent_.appendChild(serviceHeader);
+
+    // Create content for display in expanded content container.
+    const serviceInfoHeader = document.createElement('h4');
+    serviceInfoHeader.textContent = 'Service Info';
+
+    const serviceDiv = document.createElement('div');
+    serviceDiv.classList.add('flex');
+    serviceDiv.appendChild(this.serviceFieldSet_);
+
+    const characteristicsListHeader = document.createElement('h4');
+    characteristicsListHeader.textContent = 'Characteristics';
+    this.characteristicList_ = new CharacteristicList();
+
+    const infoDiv = document.createElement('div');
+    infoDiv.classList.add('info-container');
+    infoDiv.appendChild(serviceInfoHeader);
+    infoDiv.appendChild(serviceDiv);
+    infoDiv.appendChild(characteristicsListHeader);
+    infoDiv.appendChild(this.characteristicList_);
+
+    this.expandedContent_.appendChild(infoDiv);
+  },
+
+  /** @override */
+  onExpandInternal(expanded) {
+    this.characteristicList_.load(this.deviceAddress_, this.info.id);
+  },
+};
+
+/**
+ * A list that displays ServiceListItems.
+ * @constructor
+ * @extends {ExpandableList}
+ */
+export const ServiceList = crUiDefine('list');
+
+ServiceList.prototype = {
+  __proto__: ExpandableList.prototype,
+
+  /** @override */
+  decorate() {
+    ExpandableList.prototype.decorate.call(this);
+
+    /** @private {?string} */
+    this.deviceAddress_ = null;
+    /** @private {boolean} */
+    this.servicesRequested_ = false;
+
+    this.classList.add('service-list');
+    this.setEmptyMessage('No Services Found');
+  },
+
+  /** @override */
+  createItem(data) {
+    return new ServiceListItem(data, assert(this.deviceAddress_));
+  },
+
+  /**
+   * Loads the service list with an array of ServiceInfo from the
+   * device with |deviceAddress|. If no active connection to the device
+   * exists, one is created.
    * @param {string} deviceAddress
-   * @extends {ExpandableListItem}
-   * @constructor
    */
-  export function ServiceListItem(serviceInfo, deviceAddress) {
-    const listItem = new ExpandableListItem();
-    listItem.__proto__ = ServiceListItem.prototype;
+  load(deviceAddress) {
+    if (this.servicesRequested_ || !this.isSpinnerShowing()) {
+      return;
+    }
 
-    /** @type {!bluetooth.mojom.ServiceInfo} */
-    listItem.info = serviceInfo;
-    /** @private {string} */
-    listItem.deviceAddress_ = deviceAddress;
+    this.deviceAddress_ = deviceAddress;
+    this.servicesRequested_ = true;
 
-    listItem.decorate();
-    return listItem;
-  }
-
-  ServiceListItem.prototype = {
-    __proto__: ExpandableListItem.prototype,
-
-    /**
-     * Decorates the element as a service list item. Creates layout and caches
-     * references to the created header and fieldset.
-     * @override
-     */
-    decorate() {
-      this.classList.add('service-list-item');
-
-      /** @private {!ObjectFieldSet} */
-      this.serviceFieldSet_ = new ObjectFieldSet();
-      this.serviceFieldSet_.setPropertyDisplayNames(PROPERTY_NAMES);
-      this.serviceFieldSet_.setObject({
-        id: this.info.id,
-        'uuid.uuid': this.info.uuid.uuid,
-        isPrimary: this.info.isPrimary ? 'Primary' : 'Secondary',
-      });
-
-      // Create content for display in brief content container.
-      const serviceHeaderText = document.createElement('div');
-      serviceHeaderText.textContent = 'Service:';
-
-      const serviceHeaderValue = document.createElement('div');
-      serviceHeaderValue.textContent = this.info.uuid.uuid;
-
-      const serviceHeader = document.createElement('div');
-      serviceHeader.appendChild(serviceHeaderText);
-      serviceHeader.appendChild(serviceHeaderValue);
-      this.briefContent_.appendChild(serviceHeader);
-
-      // Create content for display in expanded content container.
-      const serviceInfoHeader = document.createElement('h4');
-      serviceInfoHeader.textContent = 'Service Info';
-
-      const serviceDiv = document.createElement('div');
-      serviceDiv.classList.add('flex');
-      serviceDiv.appendChild(this.serviceFieldSet_);
-
-      const characteristicsListHeader = document.createElement('h4');
-      characteristicsListHeader.textContent = 'Characteristics';
-      this.characteristicList_ = new CharacteristicList();
-
-      const infoDiv = document.createElement('div');
-      infoDiv.classList.add('info-container');
-      infoDiv.appendChild(serviceInfoHeader);
-      infoDiv.appendChild(serviceDiv);
-      infoDiv.appendChild(characteristicsListHeader);
-      infoDiv.appendChild(this.characteristicList_);
-
-      this.expandedContent_.appendChild(infoDiv);
-    },
-
-    /** @override */
-    onExpandInternal(expanded) {
-      this.characteristicList_.load(this.deviceAddress_, this.info.id);
-    },
-  };
-
-  /**
-   * A list that displays ServiceListItems.
-   * @constructor
-   * @extends {ExpandableList}
-   */
-  export const ServiceList = crUiDefine('list');
-
-  ServiceList.prototype = {
-    __proto__: ExpandableList.prototype,
-
-    /** @override */
-    decorate() {
-      ExpandableList.prototype.decorate.call(this);
-
-      /** @private {?string} */
-      this.deviceAddress_ = null;
-      /** @private {boolean} */
-      this.servicesRequested_ = false;
-
-      this.classList.add('service-list');
-      this.setEmptyMessage('No Services Found');
-    },
-
-    /** @override */
-    createItem(data) {
-      return new ServiceListItem(data, assert(this.deviceAddress_));
-    },
-
-    /**
-     * Loads the service list with an array of ServiceInfo from the
-     * device with |deviceAddress|. If no active connection to the device
-     * exists, one is created.
-     * @param {string} deviceAddress
-     */
-    load(deviceAddress) {
-      if (this.servicesRequested_ || !this.isSpinnerShowing()) {
-        return;
-      }
-
-      this.deviceAddress_ = deviceAddress;
-      this.servicesRequested_ = true;
-
-      connectToDevice(this.deviceAddress_)
-          .then(function(device) {
-            return device.getServices();
-          }.bind(this))
-          .then(function(response) {
-            this.setData(new ArrayDataModel(response.services));
-            this.setSpinnerShowing(false);
-            this.servicesRequested_ = false;
-          }.bind(this))
-          .catch(function(error) {
-            this.servicesRequested_ = false;
-            Snackbar.show(
-                deviceAddress + ': ' + error.message, SnackbarType.ERROR,
-                'Retry', function() {
-                  this.load(deviceAddress);
-                }.bind(this));
-          }.bind(this));
-    },
-  };
+    connectToDevice(this.deviceAddress_)
+        .then(function(device) {
+          return device.getServices();
+        }.bind(this))
+        .then(function(response) {
+          this.setData(new ArrayDataModel(response.services));
+          this.setSpinnerShowing(false);
+          this.servicesRequested_ = false;
+        }.bind(this))
+        .catch(function(error) {
+          this.servicesRequested_ = false;
+          Snackbar.show(
+              deviceAddress + ': ' + error.message, SnackbarType.ERROR, 'Retry',
+              function() {
+                this.load(deviceAddress);
+              }.bind(this));
+        }.bind(this));
+  },
+};
diff --git a/chrome/browser/resources/bluetooth_internals/sidebar.js b/chrome/browser/resources/bluetooth_internals/sidebar.js
index f5baa64..3a5f67aa 100644
--- a/chrome/browser/resources/bluetooth_internals/sidebar.js
+++ b/chrome/browser/resources/bluetooth_internals/sidebar.js
@@ -9,104 +9,104 @@
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {PageManager, PageManagerObserver} from './page_manager.js';
 
-  /** @typedef {{pageName: string, text: string}} */
-  let SidebarItem;
+/** @typedef {{pageName: string, text: string}} */
+let SidebarItem;
+
+/**
+ * A side menu that lists the currently navigable pages.
+ */
+export class Sidebar extends PageManagerObserver {
+  /** @param {!Element} sidebarDiv The div corresponding to the sidebar. */
+  constructor(sidebarDiv) {
+    super();
+    /** @private {!Element} */
+    this.sidebarDiv_ = sidebarDiv;
+    /** @private {!Element} */
+    this.sidebarContent_ =
+        assert(this.sidebarDiv_.querySelector('.sidebar-content'));
+    /** @private {!Element} */
+    this.sidebarList_ = assert(this.sidebarContent_.querySelector('ul'));
+
+    this.sidebarList_.querySelectorAll('li button').forEach(function(item) {
+      item.addEventListener('click', this.onItemClick_.bind(this));
+    }, this);
+
+    /** @private {!Element} */
+    this.overlayDiv_ = assert(this.sidebarDiv_.querySelector('.overlay'));
+    this.overlayDiv_.addEventListener('click', this.close.bind(this));
+
+    window.matchMedia('screen and (max-width: 600px)')
+        .addListener(function(query) {
+          if (!query.matches) {
+            this.close();
+          }
+        }.bind(this));
+  }
 
   /**
-   * A side menu that lists the currently navigable pages.
+   * Adds a new list item to the sidebar using the given |item|.
+   * @param {!SidebarItem} item
    */
-  export class Sidebar extends PageManagerObserver {
-    /** @param {!Element} sidebarDiv The div corresponding to the sidebar. */
-    constructor(sidebarDiv) {
-      super();
-      /** @private {!Element} */
-      this.sidebarDiv_ = sidebarDiv;
-      /** @private {!Element} */
-      this.sidebarContent_ =
-          assert(this.sidebarDiv_.querySelector('.sidebar-content'));
-      /** @private {!Element} */
-      this.sidebarList_ = assert(this.sidebarContent_.querySelector('ul'));
+  addItem(item) {
+    const sidebarItem = document.createElement('li');
+    sidebarItem.dataset.pageName = item.pageName.toLowerCase();
 
-      this.sidebarList_.querySelectorAll('li button').forEach(function(item) {
-        item.addEventListener('click', this.onItemClick_.bind(this));
-      }, this);
+    const button = document.createElement('button');
+    button.classList.add('custom-appearance');
+    button.textContent = item.text;
+    button.addEventListener('click', this.onItemClick_.bind(this));
+    sidebarItem.appendChild(button);
 
-      /** @private {!Element} */
-      this.overlayDiv_ = assert(this.sidebarDiv_.querySelector('.overlay'));
-      this.overlayDiv_.addEventListener('click', this.close.bind(this));
-
-      window.matchMedia('screen and (max-width: 600px)')
-          .addListener(function(query) {
-            if (!query.matches) {
-              this.close();
-            }
-          }.bind(this));
-    }
-
-    /**
-     * Adds a new list item to the sidebar using the given |item|.
-     * @param {!SidebarItem} item
-     */
-    addItem(item) {
-      const sidebarItem = document.createElement('li');
-      sidebarItem.dataset.pageName = item.pageName.toLowerCase();
-
-      const button = document.createElement('button');
-      button.classList.add('custom-appearance');
-      button.textContent = item.text;
-      button.addEventListener('click', this.onItemClick_.bind(this));
-      sidebarItem.appendChild(button);
-
-      this.sidebarList_.appendChild(sidebarItem);
-    }
-
-    /**
-     * Closes the sidebar. Only applies to layouts with window width <= 600px.
-     */
-    close() {
-      this.sidebarDiv_.classList.remove('open');
-      document.body.style.overflow = '';
-      document.dispatchEvent(new CustomEvent('contentfocus'));
-    }
-
-    /**
-     * Opens the sidebar. Only applies to layouts with window width <= 600px.
-     */
-    open() {
-      document.body.style.overflow = 'hidden';
-      this.sidebarDiv_.classList.add('open');
-      document.dispatchEvent(new CustomEvent('contentblur'));
-    }
-
-    /**
-     * Removes a sidebar item where |pageName| matches the item's pageName.
-     * @param {string} pageName
-     */
-    removeItem(pageName) {
-      pageName = pageName.toLowerCase();
-      const query = 'li[data-page-name="' + pageName + '"]';
-      this.sidebarList_.removeChild(this.sidebarList_.querySelector(query));
-    }
-
-    /**
-     * Called when a page is navigated to.
-     * @override
-     * @param {string} path The path of the page being visited.
-     */
-    updateHistory(path) {
-      this.sidebarContent_.querySelectorAll('li').forEach(function(item) {
-        item.classList.toggle('selected', item.dataset.pageName === path);
-      });
-    }
-
-    /**
-     * Switches the page based on which sidebar list button was clicked.
-     * @param {!Event} event
-     * @private
-     */
-    onItemClick_(event) {
-      this.close();
-      PageManager.getInstance().showPageByName(
-          event.target.parentNode.dataset.pageName);
-    }
+    this.sidebarList_.appendChild(sidebarItem);
   }
+
+  /**
+   * Closes the sidebar. Only applies to layouts with window width <= 600px.
+   */
+  close() {
+    this.sidebarDiv_.classList.remove('open');
+    document.body.style.overflow = '';
+    document.dispatchEvent(new CustomEvent('contentfocus'));
+  }
+
+  /**
+   * Opens the sidebar. Only applies to layouts with window width <= 600px.
+   */
+  open() {
+    document.body.style.overflow = 'hidden';
+    this.sidebarDiv_.classList.add('open');
+    document.dispatchEvent(new CustomEvent('contentblur'));
+  }
+
+  /**
+   * Removes a sidebar item where |pageName| matches the item's pageName.
+   * @param {string} pageName
+   */
+  removeItem(pageName) {
+    pageName = pageName.toLowerCase();
+    const query = 'li[data-page-name="' + pageName + '"]';
+    this.sidebarList_.removeChild(this.sidebarList_.querySelector(query));
+  }
+
+  /**
+   * Called when a page is navigated to.
+   * @override
+   * @param {string} path The path of the page being visited.
+   */
+  updateHistory(path) {
+    this.sidebarContent_.querySelectorAll('li').forEach(function(item) {
+      item.classList.toggle('selected', item.dataset.pageName === path);
+    });
+  }
+
+  /**
+   * Switches the page based on which sidebar list button was clicked.
+   * @param {!Event} event
+   * @private
+   */
+  onItemClick_(event) {
+    this.close();
+    PageManager.getInstance().showPageByName(
+        event.target.parentNode.dataset.pageName);
+  }
+}
diff --git a/chrome/browser/resources/bluetooth_internals/snackbar.js b/chrome/browser/resources/bluetooth_internals/snackbar.js
index c6e4eba..df7021a 100644
--- a/chrome/browser/resources/bluetooth_internals/snackbar.js
+++ b/chrome/browser/resources/bluetooth_internals/snackbar.js
@@ -9,238 +9,239 @@
  * Javascript for Snackbar controls, served from chrome://bluetooth-internals/.
  */
 
-  /** @typedef {{
-   *    message: string,
-   *    type: string,
-   *    actionText: (string|undefined),
-   *    action: (function()|undefined)
-   *  }}
-   */
-  let SnackbarOptions;
+/**
+ * @typedef {{
+ *    message: string,
+ *    type: string,
+ *    actionText: (string|undefined),
+ *    action: (function()|undefined)
+ *  }}
+ */
+let SnackbarOptions;
 
-  /** @type {number} */ const SHOW_DURATION = 5000;
-  /** @type {number} */ const TRANSITION_DURATION = 225;
+/** @type {number} */ const SHOW_DURATION = 5000;
+/** @type {number} */ const TRANSITION_DURATION = 225;
+
+/**
+ * Enum of Snackbar types. Used by Snackbar to determine the styling for the
+ * Snackbar.
+ * @enum {string}
+ */
+export const SnackbarType = {
+  INFO: 'info',
+  SUCCESS: 'success',
+  WARNING: 'warning',
+  ERROR: 'error',
+};
+
+/**
+ * Notification bar for displaying a simple message with an action link.
+ * This element should not be instantiated directly. Instead, users should
+ * use the Snackbar.show and Snackbar.dismiss functions to ensure proper
+ * queuing of messages.
+ * @constructor
+ * @extends {HTMLDivElement}
+ */
+export const Snackbar = crUiDefine('div');
+
+Snackbar.prototype = {
+  __proto__: HTMLDivElement.prototype,
 
   /**
-   * Enum of Snackbar types. Used by Snackbar to determine the styling for the
-   * Snackbar.
-   * @enum {string}
+   * Decorates an element as a UI element class. Creates the message div and
+   * action link for the new Snackbar.
    */
-  export const SnackbarType = {
-    INFO: 'info',
-    SUCCESS: 'success',
-    WARNING: 'warning',
-    ERROR: 'error',
-  };
+  decorate() {
+    this.classList.add('snackbar');
+    this.messageDiv_ = document.createElement('div');
+    this.appendChild(this.messageDiv_);
+    this.actionLink_ = document.createElement('a', {is: 'action-link'});
+    this.actionLink_.setAttribute('is', 'action-link');
+    this.appendChild(this.actionLink_);
+
+    this.boundStartTimeout_ = this.startTimeout_.bind(this);
+    this.boundStopTimeout_ = this.stopTimeout_.bind(this);
+    this.addEventListener('mouseleave', this.boundStartTimeout_);
+    this.addEventListener('mouseenter', this.boundStopTimeout_);
+
+    this.timeoutId_ = null;
+  },
 
   /**
-   * Notification bar for displaying a simple message with an action link.
-   * This element should not be instantiated directly. Instead, users should
-   * use the Snackbar.show and Snackbar.dismiss functions to ensure proper
-   * queuing of messages.
-   * @constructor
-   * @extends {HTMLDivElement}
+   * Initializes the content of the Snackbar with the given |options|
+   * including the message, action link text, and click action of the link.
+   * @param {!SnackbarOptions} options
    */
-  export const Snackbar = crUiDefine('div');
+  initialize(options) {
+    this.messageDiv_.textContent = options.message;
+    this.classList.add(options.type);
+    this.actionLink_.textContent = options.actionText || 'Dismiss';
 
-  Snackbar.prototype = {
-    __proto__: HTMLDivElement.prototype,
-
-    /**
-     * Decorates an element as a UI element class. Creates the message div and
-     * action link for the new Snackbar.
-     */
-    decorate() {
-      this.classList.add('snackbar');
-      this.messageDiv_ = document.createElement('div');
-      this.appendChild(this.messageDiv_);
-      this.actionLink_ = document.createElement('a', {is: 'action-link'});
-      this.actionLink_.setAttribute('is', 'action-link');
-      this.appendChild(this.actionLink_);
-
-      this.boundStartTimeout_ = this.startTimeout_.bind(this);
-      this.boundStopTimeout_ = this.stopTimeout_.bind(this);
-      this.addEventListener('mouseleave', this.boundStartTimeout_);
-      this.addEventListener('mouseenter', this.boundStopTimeout_);
-
-      this.timeoutId_ = null;
-    },
-
-    /**
-     * Initializes the content of the Snackbar with the given |options|
-     * including the message, action link text, and click action of the link.
-     * @param {!SnackbarOptions} options
-     */
-    initialize(options) {
-      this.messageDiv_.textContent = options.message;
-      this.classList.add(options.type);
-      this.actionLink_.textContent = options.actionText || 'Dismiss';
-
-      this.actionLink_.addEventListener('click', function() {
-        if (options.action) {
-          options.action();
-        }
-        this.dismiss();
-      }.bind(this));
-    },
-
-    /**
-     * Shows the Snackbar and dispatches the 'showed' event.
-     */
-    show() {
-      this.classList.add('open');
-      if (Snackbar.hasContentFocus_) {
-        this.startTimeout_();
-      } else {
-        this.stopTimeout_();
+    this.actionLink_.addEventListener('click', function() {
+      if (options.action) {
+        options.action();
       }
-
-      document.addEventListener('contentfocus', this.boundStartTimeout_);
-      document.addEventListener('contentblur', this.boundStopTimeout_);
-      this.dispatchEvent(new CustomEvent('showed'));
-    },
-
-    /**
-     * Dismisses the Snackbar. Once the Snackbar is completely hidden, the
-     * 'dismissed' event is fired and the returned Promise is resolved. If the
-     * snackbar is already hidden, a resolved Promise is returned.
-     * @return {!Promise}
-     */
-    dismiss() {
-      this.stopTimeout_();
-
-      if (!this.classList.contains('open')) {
-        return Promise.resolve();
-      }
-
-      return new Promise(function(resolve) {
-        listenOnce(this, 'transitionend', function() {
-          this.dispatchEvent(new CustomEvent('dismissed'));
-          resolve();
-        }.bind(this));
-
-        ensureTransitionEndEvent(this, TRANSITION_DURATION);
-        this.classList.remove('open');
-
-        document.removeEventListener('contentfocus', this.boundStartTimeout_);
-        document.removeEventListener('contentblur', this.boundStopTimeout_);
-      }.bind(this));
-    },
-
-    /**
-     * Starts the timeout for dismissing the Snackbar.
-     * @private
-     */
-    startTimeout_() {
-      this.timeoutId_ = setTimeout(function() {
-        this.dismiss();
-      }.bind(this), SHOW_DURATION);
-    },
-
-    /**
-     * Stops the timeout for dismissing the Snackbar. Only clears the timeout
-     * when the Snackbar is open.
-     * @private
-     */
-    stopTimeout_() {
-      if (this.classList.contains('open')) {
-        clearTimeout(this.timeoutId_);
-        this.timeoutId_ = null;
-      }
-    },
-  };
-
-  /** @private {?Snackbar} */
-  Snackbar.current_ = null;
-
-  /** @private {!Array<!Snackbar>} */
-  Snackbar.queue_ = [];
-
-  /** @private {boolean} */
-  Snackbar.hasContentFocus_ = true;
-
-  // There is a chance where the snackbar is shown but the content doesn't have
-  // focus. In this case, the current focus state must be tracked so the
-  // snackbar can pause the dismiss timeout.
-  document.addEventListener('contentfocus', function() {
-    Snackbar.hasContentFocus_ = true;
-  });
-  document.addEventListener('contentblur', function() {
-    Snackbar.hasContentFocus_ = false;
-  });
+      this.dismiss();
+    }.bind(this));
+  },
 
   /**
-   * TODO(crbug.com/675299): Add ability to specify parent element to Snackbar.
-   * Creates a Snackbar and shows it if one is not showing already. If a
-   * Snackbar is already active, the next Snackbar is queued.
-   * @param {string} message The message to display in the Snackbar.
-   * @param {string=} opt_type A string determining the Snackbar type: info,
-   *     success, warning, error. If not provided, info type is used.
-   * @param {string=} opt_actionText The text to display for the action link.
-   * @param {function()=} opt_action A function to be called when the user
-   *     presses the action link.
-   * @return {!Snackbar}
+   * Shows the Snackbar and dispatches the 'showed' event.
    */
-  Snackbar.show = function(message, opt_type, opt_actionText, opt_action) {
-    const options = {
-      message: message,
-      type: opt_type || SnackbarType.INFO,
-      actionText: opt_actionText,
-      action: opt_action,
-    };
-
-    const newSnackbar = new Snackbar();
-    newSnackbar.initialize(options);
-
-    if (Snackbar.current_) {
-      Snackbar.queue_.push(newSnackbar);
+  show() {
+    this.classList.add('open');
+    if (Snackbar.hasContentFocus_) {
+      this.startTimeout_();
     } else {
-      Snackbar.show_(newSnackbar);
+      this.stopTimeout_();
     }
 
-    return newSnackbar;
-  };
+    document.addEventListener('contentfocus', this.boundStartTimeout_);
+    document.addEventListener('contentblur', this.boundStopTimeout_);
+    this.dispatchEvent(new CustomEvent('showed'));
+  },
 
   /**
-   * TODO(crbug.com/675299): Add ability to specify parent element to Snackbar.
-   * Creates a Snackbar and sets events for queuing the next Snackbar to show.
-   * @param {!Snackbar} newSnackbar
+   * Dismisses the Snackbar. Once the Snackbar is completely hidden, the
+   * 'dismissed' event is fired and the returned Promise is resolved. If the
+   * snackbar is already hidden, a resolved Promise is returned.
+   * @return {!Promise}
+   */
+  dismiss() {
+    this.stopTimeout_();
+
+    if (!this.classList.contains('open')) {
+      return Promise.resolve();
+    }
+
+    return new Promise(function(resolve) {
+      listenOnce(this, 'transitionend', function() {
+        this.dispatchEvent(new CustomEvent('dismissed'));
+        resolve();
+      }.bind(this));
+
+      ensureTransitionEndEvent(this, TRANSITION_DURATION);
+      this.classList.remove('open');
+
+      document.removeEventListener('contentfocus', this.boundStartTimeout_);
+      document.removeEventListener('contentblur', this.boundStopTimeout_);
+    }.bind(this));
+  },
+
+  /**
+   * Starts the timeout for dismissing the Snackbar.
    * @private
    */
-  Snackbar.show_ = function(newSnackbar) {
-    $('snackbar-container').appendChild(newSnackbar);
-
-    newSnackbar.addEventListener('dismissed', function() {
-      $('snackbar-container').removeChild(Snackbar.current_);
-
-      const newSnackbar = Snackbar.queue_.shift();
-      if (newSnackbar) {
-        Snackbar.show_(newSnackbar);
-        return;
-      }
-
-      Snackbar.current_ = null;
-    });
-
-    Snackbar.current_ = newSnackbar;
-
-    // Show the Snackbar after a slight delay to allow for a layout reflow.
-    setTimeout(function() {
-      newSnackbar.show();
-    }, 10);
-  };
+  startTimeout_() {
+    this.timeoutId_ = setTimeout(function() {
+      this.dismiss();
+    }.bind(this), SHOW_DURATION);
+  },
 
   /**
-   * Dismisses the Snackbar currently showing.
-   * @param {boolean} clearQueue If true, clears the Snackbar queue before
-   *     dismissing.
+   * Stops the timeout for dismissing the Snackbar. Only clears the timeout
+   * when the Snackbar is open.
+   * @private
    */
-  Snackbar.dismiss = function(clearQueue) {
-    if (clearQueue) {
-      Snackbar.queue_ = [];
+  stopTimeout_() {
+    if (this.classList.contains('open')) {
+      clearTimeout(this.timeoutId_);
+      this.timeoutId_ = null;
     }
-    if (Snackbar.current_) {
-      return Snackbar.current_.dismiss();
-    }
-    return Promise.resolve();
+  },
+};
+
+/** @private {?Snackbar} */
+Snackbar.current_ = null;
+
+/** @private {!Array<!Snackbar>} */
+Snackbar.queue_ = [];
+
+/** @private {boolean} */
+Snackbar.hasContentFocus_ = true;
+
+// There is a chance where the snackbar is shown but the content doesn't have
+// focus. In this case, the current focus state must be tracked so the
+// snackbar can pause the dismiss timeout.
+document.addEventListener('contentfocus', function() {
+  Snackbar.hasContentFocus_ = true;
+});
+document.addEventListener('contentblur', function() {
+  Snackbar.hasContentFocus_ = false;
+});
+
+/**
+ * TODO(crbug.com/675299): Add ability to specify parent element to Snackbar.
+ * Creates a Snackbar and shows it if one is not showing already. If a
+ * Snackbar is already active, the next Snackbar is queued.
+ * @param {string} message The message to display in the Snackbar.
+ * @param {string=} opt_type A string determining the Snackbar type: info,
+ *     success, warning, error. If not provided, info type is used.
+ * @param {string=} opt_actionText The text to display for the action link.
+ * @param {function()=} opt_action A function to be called when the user
+ *     presses the action link.
+ * @return {!Snackbar}
+ */
+Snackbar.show = function(message, opt_type, opt_actionText, opt_action) {
+  const options = {
+    message: message,
+    type: opt_type || SnackbarType.INFO,
+    actionText: opt_actionText,
+    action: opt_action,
   };
+
+  const newSnackbar = new Snackbar();
+  newSnackbar.initialize(options);
+
+  if (Snackbar.current_) {
+    Snackbar.queue_.push(newSnackbar);
+  } else {
+    Snackbar.show_(newSnackbar);
+  }
+
+  return newSnackbar;
+};
+
+/**
+ * TODO(crbug.com/675299): Add ability to specify parent element to Snackbar.
+ * Creates a Snackbar and sets events for queuing the next Snackbar to show.
+ * @param {!Snackbar} newSnackbar
+ * @private
+ */
+Snackbar.show_ = function(newSnackbar) {
+  $('snackbar-container').appendChild(newSnackbar);
+
+  newSnackbar.addEventListener('dismissed', function() {
+    $('snackbar-container').removeChild(Snackbar.current_);
+
+    const newSnackbar = Snackbar.queue_.shift();
+    if (newSnackbar) {
+      Snackbar.show_(newSnackbar);
+      return;
+    }
+
+    Snackbar.current_ = null;
+  });
+
+  Snackbar.current_ = newSnackbar;
+
+  // Show the Snackbar after a slight delay to allow for a layout reflow.
+  setTimeout(function() {
+    newSnackbar.show();
+  }, 10);
+};
+
+/**
+ * Dismisses the Snackbar currently showing.
+ * @param {boolean} clearQueue If true, clears the Snackbar queue before
+ *     dismissing.
+ */
+Snackbar.dismiss = function(clearQueue) {
+  if (clearQueue) {
+    Snackbar.queue_ = [];
+  }
+  if (Snackbar.current_) {
+    return Snackbar.current_.dismiss();
+  }
+  return Promise.resolve();
+};
diff --git a/chrome/browser/resources/bluetooth_internals/value_control.js b/chrome/browser/resources/bluetooth_internals/value_control.js
index 09532e7..a90529e4 100644
--- a/chrome/browser/resources/bluetooth_internals/value_control.js
+++ b/chrome/browser/resources/bluetooth_internals/value_control.js
@@ -7,414 +7,413 @@
  */
 
 import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js';
-import {connectToDevice} from './device_broker.js';
 import {define as crUiDefine} from 'chrome://resources/js/cr/ui.m.js';
+
+import {connectToDevice} from './device_broker.js';
 import {Snackbar, SnackbarType} from './snackbar.js';
 
-  /**
-   * @typedef {{
-   *    deviceAddress: string,
-   *    serviceId: string,
-   *    characteristicId: string,
-   *    descriptorId: (string|undefined),
-   *    properties: (number|undefined),
-   *  }}
-   */
-  let ValueLoadOptions;
+/**
+ * @typedef {{
+ *    deviceAddress: string,
+ *    serviceId: string,
+ *    characteristicId: string,
+ *    descriptorId: (string|undefined),
+ *    properties: (number|undefined),
+ *  }}
+ */
+let ValueLoadOptions;
 
-  /** @enum {string}  */
-  export const ValueDataType = {
-    HEXADECIMAL: 'Hexadecimal',
-    UTF8: 'UTF-8',
-    DECIMAL: 'Decimal',
-  };
+/** @enum {string}  */
+export const ValueDataType = {
+  HEXADECIMAL: 'Hexadecimal',
+  UTF8: 'UTF-8',
+  DECIMAL: 'Decimal',
+};
+
+/**
+ * A container for an array value that needs to be converted to multiple
+ * display formats. Internally, the value is stored as an array and converted
+ * to the needed display type at runtime.
+ */
+export class Value {
+  /** @param {!Array<number>} initialValue */
+  constructor(initialValue) {
+    /** @private {!Array<number>} */
+    this.value_ = initialValue;
+  }
 
   /**
-   * A container for an array value that needs to be converted to multiple
-   * display formats. Internally, the value is stored as an array and converted
-   * to the needed display type at runtime.
+   * Gets the backing array value.
+   * @return {!Array<number>}
    */
-  export class Value {
-    /** @param {!Array<number>} initialValue */
-    constructor(initialValue) {
-      /** @private {!Array<number>} */
-      this.value_ = initialValue;
-    }
+  getArray() {
+    return this.value_;
+  }
 
-    /**
-     * Gets the backing array value.
-     * @return {!Array<number>}
-     */
-    getArray() {
-      return this.value_;
-    }
+  /**
+   * Sets the backing array value.
+   * @param {!Array<number>} newValue
+   */
+  setArray(newValue) {
+    this.value_ = newValue;
+  }
 
-    /**
-     * Sets the backing array value.
-     * @param {!Array<number>} newValue
-     */
-    setArray(newValue) {
-      this.value_ = newValue;
-    }
+  /**
+   * Sets the value by converting the |newValue| string using the formatting
+   * specified by |valueDataType|.
+   * @param {!ValueDataType} valueDataType
+   * @param {string} newValue
+   */
+  setAs(valueDataType, newValue) {
+    switch (valueDataType) {
+      case ValueDataType.HEXADECIMAL:
+        this.setValueFromHex_(newValue);
+        break;
 
-    /**
-     * Sets the value by converting the |newValue| string using the formatting
-     * specified by |valueDataType|.
-     * @param {!ValueDataType} valueDataType
-     * @param {string} newValue
-     */
-    setAs(valueDataType, newValue) {
-      switch (valueDataType) {
-        case ValueDataType.HEXADECIMAL:
-          this.setValueFromHex_(newValue);
-          break;
+      case ValueDataType.UTF8:
+        this.setValueFromUTF8_(newValue);
+        break;
 
-        case ValueDataType.UTF8:
-          this.setValueFromUTF8_(newValue);
-          break;
-
-        case ValueDataType.DECIMAL:
-          this.setValueFromDecimal_(newValue);
-          break;
-      }
-    }
-
-    /**
-     * Gets the value as a string representing the given |valueDataType|.
-     * @param {!ValueDataType} valueDataType
-     * @return {string}
-     */
-    getAs(valueDataType) {
-      switch (valueDataType) {
-        case ValueDataType.HEXADECIMAL:
-          return this.toHex_();
-
-        case ValueDataType.UTF8:
-          return this.toUTF8_();
-
-        case ValueDataType.DECIMAL:
-          return this.toDecimal_();
-      }
-      assertNotReached();
-      return '';
-    }
-
-    /**
-     * Converts the value to a hex string.
-     * @return {string}
-     * @private
-     */
-    toHex_() {
-      if (this.value_.length == 0) {
-        return '';
-      }
-
-      return this.value_.reduce(function(result, value, index) {
-        return result + ('0' + value.toString(16)).substr(-2);
-      }, '0x');
-    }
-
-    /**
-     * Sets the value from a hex string.
-     * @param {string} newValue
-     * @private
-     */
-    setValueFromHex_(newValue) {
-      if (!newValue) {
-        this.value_ = [];
-        return;
-      }
-
-      if (!newValue.startsWith('0x')) {
-        throw new Error('Expected new value to start with "0x".');
-      }
-
-      const result = [];
-      for (let i = 2; i < newValue.length; i += 2) {
-        result.push(parseInt(newValue.substr(i, 2), 16));
-      }
-
-      this.value_ = result;
-    }
-
-    /**
-     * Converts the value to a UTF-8 encoded text string.
-     * @return {string}
-     * @private
-     */
-    toUTF8_() {
-      return this.value_.reduce(function(result, value) {
-        return result + String.fromCharCode(value);
-      }, '');
-    }
-
-    /**
-     * Sets the value from a UTF-8 encoded text string.
-     * @param {string} newValue
-     * @private
-     */
-    setValueFromUTF8_(newValue) {
-      if (!newValue) {
-        this.value_ = [];
-        return;
-      }
-
-      this.value_ = Array.from(newValue).map(function(char) {
-        return char.charCodeAt(0);
-      });
-    }
-
-    /**
-     * Converts the value to a decimal string with numbers delimited by '-'.
-     * @return {string}
-     * @private
-     */
-    toDecimal_() {
-      return this.value_.join('-');
-    }
-
-    /**
-     * Sets the value from a decimal string delimited by '-'.
-     * @param {string} newValue
-     * @private
-     */
-    setValueFromDecimal_(newValue) {
-      if (!newValue) {
-        this.value_ = [];
-        return;
-      }
-
-      if (!/^[0-9\-]*$/.test(newValue)) {
-        throw new Error('New value can only contain numbers and hyphens.');
-      }
-
-      this.value_ = newValue.split('-').map(function(val) {
-        return parseInt(val, 10);
-      });
+      case ValueDataType.DECIMAL:
+        this.setValueFromDecimal_(newValue);
+        break;
     }
   }
 
   /**
-   * A set of inputs that allow a user to request reads and writes of values.
-   * This control allows the value to be displayed in multiple forms
-   * as defined by the |ValueDataType| array. Values must be written
-   * in these formats. Read and write capability is controlled by a
-   * 'properties' bitfield provided by the characteristic.
-   * @constructor
-   * @extends {HTMLDivElement}
+   * Gets the value as a string representing the given |valueDataType|.
+   * @param {!ValueDataType} valueDataType
+   * @return {string}
    */
-  export const ValueControl = crUiDefine('div');
+  getAs(valueDataType) {
+    switch (valueDataType) {
+      case ValueDataType.HEXADECIMAL:
+        return this.toHex_();
 
-  ValueControl.prototype = {
-    __proto__: HTMLDivElement.prototype,
+      case ValueDataType.UTF8:
+        return this.toUTF8_();
 
-    /**
-     * Decorates the element as a ValueControl. Creates the layout for the value
-     * control by creating a text input, select element, and two buttons for
-     * read/write requests. Event handlers are attached and references to these
-     * elements are stored for later use.
-     */
-    decorate() {
-      this.classList.add('value-control');
+      case ValueDataType.DECIMAL:
+        return this.toDecimal_();
+    }
+    assertNotReached();
+    return '';
+  }
 
-      /** @private {!Value} */
-      this.value_ = new Value([]);
-      /** @private {?string} */
-      this.deviceAddress_ = null;
-      /** @private {?string} */
-      this.serviceId_ = null;
-      /** @private {?string} */
-      this.characteristicId_ = null;
-      /** @private {?string|undefined} */
-      this.descriptorId_ = null;
-      /** @private {number} */
-      this.properties_ = Number.MAX_SAFE_INTEGER;
+  /**
+   * Converts the value to a hex string.
+   * @return {string}
+   * @private
+   */
+  toHex_() {
+    if (this.value_.length == 0) {
+      return '';
+    }
 
-      this.unavailableMessage_ = document.createElement('h3');
-      this.unavailableMessage_.textContent = 'Value cannot be read or written.';
+    return this.value_.reduce(function(result, value, index) {
+      return result + ('0' + value.toString(16)).substr(-2);
+    }, '0x');
+  }
 
-      this.valueInput_ = document.createElement('input');
-      this.valueInput_.addEventListener('change', function() {
-        try {
-          this.value_.setAs(this.typeSelect_.value, this.valueInput_.value);
-        } catch (e) {
-          Snackbar.show(e.message, SnackbarType.ERROR);
-        }
-      }.bind(this));
+  /**
+   * Sets the value from a hex string.
+   * @param {string} newValue
+   * @private
+   */
+  setValueFromHex_(newValue) {
+    if (!newValue) {
+      this.value_ = [];
+      return;
+    }
 
-      this.typeSelect_ = document.createElement('select');
+    if (!newValue.startsWith('0x')) {
+      throw new Error('Expected new value to start with "0x".');
+    }
 
-      Object.keys(ValueDataType).forEach(function(key) {
-        const type = ValueDataType[key];
-        const option = document.createElement('option');
-        option.value = type;
-        option.text = type;
-        this.typeSelect_.add(option);
-      }, this);
+    const result = [];
+    for (let i = 2; i < newValue.length; i += 2) {
+      result.push(parseInt(newValue.substr(i, 2), 16));
+    }
 
-      this.typeSelect_.addEventListener('change', this.redraw.bind(this));
+    this.value_ = result;
+  }
 
-      const inputDiv = document.createElement('div');
-      inputDiv.appendChild(this.valueInput_);
-      inputDiv.appendChild(this.typeSelect_);
+  /**
+   * Converts the value to a UTF-8 encoded text string.
+   * @return {string}
+   * @private
+   */
+  toUTF8_() {
+    return this.value_.reduce(function(result, value) {
+      return result + String.fromCharCode(value);
+    }, '');
+  }
 
-      this.readBtn_ = document.createElement('button');
-      this.readBtn_.textContent = 'Read';
-      this.readBtn_.addEventListener('click', this.readValue_.bind(this));
+  /**
+   * Sets the value from a UTF-8 encoded text string.
+   * @param {string} newValue
+   * @private
+   */
+  setValueFromUTF8_(newValue) {
+    if (!newValue) {
+      this.value_ = [];
+      return;
+    }
 
-      this.writeBtn_ = document.createElement('button');
-      this.writeBtn_.textContent = 'Write';
-      this.writeBtn_.addEventListener('click', this.writeValue_.bind(this));
+    this.value_ = Array.from(newValue).map(function(char) {
+      return char.charCodeAt(0);
+    });
+  }
 
-      const buttonsDiv = document.createElement('div');
-      buttonsDiv.appendChild(this.readBtn_);
-      buttonsDiv.appendChild(this.writeBtn_);
+  /**
+   * Converts the value to a decimal string with numbers delimited by '-'.
+   * @return {string}
+   * @private
+   */
+  toDecimal_() {
+    return this.value_.join('-');
+  }
 
-      this.appendChild(this.unavailableMessage_);
-      this.appendChild(inputDiv);
-      this.appendChild(buttonsDiv);
-    },
+  /**
+   * Sets the value from a decimal string delimited by '-'.
+   * @param {string} newValue
+   * @private
+   */
+  setValueFromDecimal_(newValue) {
+    if (!newValue) {
+      this.value_ = [];
+      return;
+    }
 
-    /**
-     * Sets the settings used by the value control and redraws the control to
-     * match the read/write settings in |options.properties|. If properties
-     * are not provided, no restrictions on reading/writing are applied.
-     * @param {!ValueLoadOptions} options
-     */
-    load(options) {
-      this.deviceAddress_ = options.deviceAddress;
-      this.serviceId_ = options.serviceId;
-      this.characteristicId_ = options.characteristicId;
-      this.descriptorId_ = options.descriptorId;
+    if (!/^[0-9\-]*$/.test(newValue)) {
+      throw new Error('New value can only contain numbers and hyphens.');
+    }
 
-      if (options.properties) {
-        this.properties_ = options.properties;
+    this.value_ = newValue.split('-').map(function(val) {
+      return parseInt(val, 10);
+    });
+  }
+}
+
+/**
+ * A set of inputs that allow a user to request reads and writes of values.
+ * This control allows the value to be displayed in multiple forms
+ * as defined by the |ValueDataType| array. Values must be written
+ * in these formats. Read and write capability is controlled by a
+ * 'properties' bitfield provided by the characteristic.
+ * @constructor
+ * @extends {HTMLDivElement}
+ */
+export const ValueControl = crUiDefine('div');
+
+ValueControl.prototype = {
+  __proto__: HTMLDivElement.prototype,
+
+  /**
+   * Decorates the element as a ValueControl. Creates the layout for the value
+   * control by creating a text input, select element, and two buttons for
+   * read/write requests. Event handlers are attached and references to these
+   * elements are stored for later use.
+   */
+  decorate() {
+    this.classList.add('value-control');
+
+    /** @private {!Value} */
+    this.value_ = new Value([]);
+    /** @private {?string} */
+    this.deviceAddress_ = null;
+    /** @private {?string} */
+    this.serviceId_ = null;
+    /** @private {?string} */
+    this.characteristicId_ = null;
+    /** @private {?string|undefined} */
+    this.descriptorId_ = null;
+    /** @private {number} */
+    this.properties_ = Number.MAX_SAFE_INTEGER;
+
+    this.unavailableMessage_ = document.createElement('h3');
+    this.unavailableMessage_.textContent = 'Value cannot be read or written.';
+
+    this.valueInput_ = document.createElement('input');
+    this.valueInput_.addEventListener('change', function() {
+      try {
+        this.value_.setAs(this.typeSelect_.value, this.valueInput_.value);
+      } catch (e) {
+        Snackbar.show(e.message, SnackbarType.ERROR);
       }
+    }.bind(this));
 
-      this.redraw();
-    },
+    this.typeSelect_ = document.createElement('select');
 
-    /**
-     * Redraws the value control with updated layout depending on the
-     * availability of reads and writes and the current cached value.
-     */
-    redraw() {
-      this.readBtn_.hidden =
-          (this.properties_ & bluetooth.mojom.Property.READ) === 0;
-      this.writeBtn_.hidden =
-          (this.properties_ & bluetooth.mojom.Property.WRITE) === 0 &&
-          (this.properties_ &
-           bluetooth.mojom.Property.WRITE_WITHOUT_RESPONSE) === 0;
+    Object.keys(ValueDataType).forEach(function(key) {
+      const type = ValueDataType[key];
+      const option = document.createElement('option');
+      option.value = type;
+      option.text = type;
+      this.typeSelect_.add(option);
+    }, this);
 
-      const isAvailable = !this.readBtn_.hidden || !this.writeBtn_.hidden;
-      this.unavailableMessage_.hidden = isAvailable;
-      this.valueInput_.hidden = !isAvailable;
-      this.typeSelect_.hidden = !isAvailable;
+    this.typeSelect_.addEventListener('change', this.redraw.bind(this));
 
-      if (!isAvailable) {
-        return;
-      }
+    const inputDiv = document.createElement('div');
+    inputDiv.appendChild(this.valueInput_);
+    inputDiv.appendChild(this.typeSelect_);
 
-      this.valueInput_.value = this.value_.getAs(this.typeSelect_.value);
-    },
+    this.readBtn_ = document.createElement('button');
+    this.readBtn_.textContent = 'Read';
+    this.readBtn_.addEventListener('click', this.readValue_.bind(this));
 
-    /**
-     * Sets the value of the control.
-     * @param {!Array<number>} value
-     */
-    setValue(value) {
-      this.value_.setArray(value);
-      this.redraw();
-    },
+    this.writeBtn_ = document.createElement('button');
+    this.writeBtn_.textContent = 'Write';
+    this.writeBtn_.addEventListener('click', this.writeValue_.bind(this));
 
-    /**
-     * Gets an error string describing the given |result| code.
-     * @param {!bluetooth.mojom.GattResult} result
-     * @private
-     */
-    getErrorString_(result) {
-      // TODO(crbug.com/663394): Replace with more descriptive error
-      // messages.
-      const GattResult = bluetooth.mojom.GattResult;
-      return Object.keys(GattResult).find(function(key) {
-        return GattResult[key] === result;
-      });
-    },
+    const buttonsDiv = document.createElement('div');
+    buttonsDiv.appendChild(this.readBtn_);
+    buttonsDiv.appendChild(this.writeBtn_);
 
-    /**
-     * Called when the read button is pressed. Connects to the device and
-     * retrieves the current value of the characteristic in the |service_id|
-     * with id |characteristic_id|. If |descriptor_id| is defined,  the
-     * descriptor value with |descriptor_id| is read instead.
-     * @private
-     */
-    readValue_() {
-      this.readBtn_.disabled = true;
+    this.appendChild(this.unavailableMessage_);
+    this.appendChild(inputDiv);
+    this.appendChild(buttonsDiv);
+  },
 
-      connectToDevice(assert(this.deviceAddress_))
-          .then(function(device) {
-            if (this.descriptorId_) {
-              return device.readValueForDescriptor(
-                  this.serviceId_, this.characteristicId_, this.descriptorId_);
-            }
+  /**
+   * Sets the settings used by the value control and redraws the control to
+   * match the read/write settings in |options.properties|. If properties
+   * are not provided, no restrictions on reading/writing are applied.
+   * @param {!ValueLoadOptions} options
+   */
+  load(options) {
+    this.deviceAddress_ = options.deviceAddress;
+    this.serviceId_ = options.serviceId;
+    this.characteristicId_ = options.characteristicId;
+    this.descriptorId_ = options.descriptorId;
 
-            return device.readValueForCharacteristic(
-                this.serviceId_, this.characteristicId_);
-          }.bind(this))
-          .then(function(response) {
-            this.readBtn_.disabled = false;
+    if (options.properties) {
+      this.properties_ = options.properties;
+    }
 
-            if (response.result === bluetooth.mojom.GattResult.SUCCESS) {
-              this.setValue(response.value);
-              Snackbar.show(
-                  this.deviceAddress_ + ': Read succeeded',
-                  SnackbarType.SUCCESS);
-              return;
-            }
+    this.redraw();
+  },
 
-            const errorString = this.getErrorString_(response.result);
+  /**
+   * Redraws the value control with updated layout depending on the
+   * availability of reads and writes and the current cached value.
+   */
+  redraw() {
+    this.readBtn_.hidden =
+        (this.properties_ & bluetooth.mojom.Property.READ) === 0;
+    this.writeBtn_.hidden =
+        (this.properties_ & bluetooth.mojom.Property.WRITE) === 0 &&
+        (this.properties_ & bluetooth.mojom.Property.WRITE_WITHOUT_RESPONSE) ===
+            0;
+
+    const isAvailable = !this.readBtn_.hidden || !this.writeBtn_.hidden;
+    this.unavailableMessage_.hidden = isAvailable;
+    this.valueInput_.hidden = !isAvailable;
+    this.typeSelect_.hidden = !isAvailable;
+
+    if (!isAvailable) {
+      return;
+    }
+
+    this.valueInput_.value = this.value_.getAs(this.typeSelect_.value);
+  },
+
+  /**
+   * Sets the value of the control.
+   * @param {!Array<number>} value
+   */
+  setValue(value) {
+    this.value_.setArray(value);
+    this.redraw();
+  },
+
+  /**
+   * Gets an error string describing the given |result| code.
+   * @param {!bluetooth.mojom.GattResult} result
+   * @private
+   */
+  getErrorString_(result) {
+    // TODO(crbug.com/663394): Replace with more descriptive error
+    // messages.
+    const GattResult = bluetooth.mojom.GattResult;
+    return Object.keys(GattResult).find(function(key) {
+      return GattResult[key] === result;
+    });
+  },
+
+  /**
+   * Called when the read button is pressed. Connects to the device and
+   * retrieves the current value of the characteristic in the |service_id|
+   * with id |characteristic_id|. If |descriptor_id| is defined,  the
+   * descriptor value with |descriptor_id| is read instead.
+   * @private
+   */
+  readValue_() {
+    this.readBtn_.disabled = true;
+
+    connectToDevice(assert(this.deviceAddress_))
+        .then(function(device) {
+          if (this.descriptorId_) {
+            return device.readValueForDescriptor(
+                this.serviceId_, this.characteristicId_, this.descriptorId_);
+          }
+
+          return device.readValueForCharacteristic(
+              this.serviceId_, this.characteristicId_);
+        }.bind(this))
+        .then(function(response) {
+          this.readBtn_.disabled = false;
+
+          if (response.result === bluetooth.mojom.GattResult.SUCCESS) {
+            this.setValue(response.value);
             Snackbar.show(
-                this.deviceAddress_ + ': ' + errorString, SnackbarType.ERROR,
-                'Retry', this.readValue_.bind(this));
-          }.bind(this));
-    },
+                this.deviceAddress_ + ': Read succeeded', SnackbarType.SUCCESS);
+            return;
+          }
 
-    /**
-     * Called when the write button is pressed. Connects to the device and
-     * retrieves the current value of the characteristic in the
-     * |service_id| with id |characteristic_id|. If |descriptor_id| is defined,
-     * the descriptor value with |descriptor_id| is written instead.
-     * @private
-     */
-    writeValue_() {
-      this.writeBtn_.disabled = true;
+          const errorString = this.getErrorString_(response.result);
+          Snackbar.show(
+              this.deviceAddress_ + ': ' + errorString, SnackbarType.ERROR,
+              'Retry', this.readValue_.bind(this));
+        }.bind(this));
+  },
 
-      connectToDevice(assert(this.deviceAddress_))
-          .then(function(device) {
-            if (this.descriptorId_) {
-              return device.writeValueForDescriptor(
-                  this.serviceId_, this.characteristicId_, this.descriptorId_,
-                  this.value_.getArray());
-            }
+  /**
+   * Called when the write button is pressed. Connects to the device and
+   * retrieves the current value of the characteristic in the
+   * |service_id| with id |characteristic_id|. If |descriptor_id| is defined,
+   * the descriptor value with |descriptor_id| is written instead.
+   * @private
+   */
+  writeValue_() {
+    this.writeBtn_.disabled = true;
 
-            return device.writeValueForCharacteristic(
-                this.serviceId_, this.characteristicId_,
+    connectToDevice(assert(this.deviceAddress_))
+        .then(function(device) {
+          if (this.descriptorId_) {
+            return device.writeValueForDescriptor(
+                this.serviceId_, this.characteristicId_, this.descriptorId_,
                 this.value_.getArray());
-          }.bind(this))
-          .then(function(response) {
-            this.writeBtn_.disabled = false;
+          }
 
-            if (response.result === bluetooth.mojom.GattResult.SUCCESS) {
-              Snackbar.show(
-                  this.deviceAddress_ + ': Write succeeded',
-                  SnackbarType.SUCCESS);
-              return;
-            }
+          return device.writeValueForCharacteristic(
+              this.serviceId_, this.characteristicId_, this.value_.getArray());
+        }.bind(this))
+        .then(function(response) {
+          this.writeBtn_.disabled = false;
 
-            const errorString = this.getErrorString_(response.result);
+          if (response.result === bluetooth.mojom.GattResult.SUCCESS) {
             Snackbar.show(
-                this.deviceAddress_ + ': ' + errorString, SnackbarType.ERROR,
-                'Retry', this.writeValue_.bind(this));
-          }.bind(this));
-    },
-  };
+                this.deviceAddress_ + ': Write succeeded',
+                SnackbarType.SUCCESS);
+            return;
+          }
+
+          const errorString = this.getErrorString_(response.result);
+          Snackbar.show(
+              this.deviceAddress_ + ': ' + errorString, SnackbarType.ERROR,
+              'Retry', this.writeValue_.bind(this));
+        }.bind(this));
+  },
+};
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_bs.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_bs.xtb
index 393ccd9c..22d597b 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_bs.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_bs.xtb
@@ -286,7 +286,7 @@
 <translation id="307516670110542567">Brza orijentacija</translation>
 <translation id="3078345202707391975">Sljedeći naslov 2. nivoa</translation>
 <translation id="3078740164268491126">tabela</translation>
-<translation id="3082249673510793544">Pomicanje unazad</translation>
+<translation id="3082249673510793544">Pomjeranje unazad</translation>
 <translation id="3084806535845658316">nema odjeka tipkanja</translation>
 <translation id="3086746722712840547">bilješka</translation>
 <translation id="3090227230165225418">Objavi obavještenja o preuzimanju</translation>
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_get_more.html b/chrome/browser/resources/chromeos/assistant_optin/assistant_get_more.html
index dc3bf5c..dacbf8d7 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/assistant_get_more.html
+++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_get_more.html
@@ -24,7 +24,7 @@
       <div slot="subtitle">
         [[i18nDynamic(locale, 'assistantReadyMessage')]]
       </div>
-      <div slot="content">
+      <div slot="content" class="container">
         <div class="flex layout horizontal center">
           <div id="ready-image-container">
             <img id="ready-img" class="oobe-illustration" aria-hidden="true"
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_optin_flow.js b/chrome/browser/resources/chromeos/assistant_optin/assistant_optin_flow.js
index 1b776ef0..16fd3bc 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/assistant_optin_flow.js
+++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_optin_flow.js
@@ -77,6 +77,9 @@
     this.style.setProperty('--caption-bar-height', captionBarHeight);
 
     if (oobeDialogHeight && oobeDialogWidth) {
+      // Below code is also used to set the dialog size for display manager and
+      // in-session multidevice setup flow. Please make sure code changes are
+      // applied to all places.
       document.documentElement.style.setProperty(
           '--oobe-oobe-dialog-height-base', oobeDialogHeight + 'px');
       document.documentElement.style.setProperty(
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_related_info.html b/chrome/browser/resources/chromeos/assistant_optin/assistant_related_info.html
index 1bbe485..5deac98 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/assistant_related_info.html
+++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_related_info.html
@@ -14,10 +14,6 @@
       padding-bottom: 16px;
     }
 
-    :host-context(html:not([new-layout])) #relatedInfoLottie {
-      display: none;
-    }
-
     :host-context(html:not([new-layout])) #relatedInfoImg {
         max-height: 240px;
       }
@@ -46,7 +42,7 @@
           srcset="assistant_related_info_1x.svg 1x,
           assistant_related_info_2x.svg 2x">
     </div>
-    <div slot="content" hidden$="[[!skipActivityControl_]]">
+    <div slot="content" class="container" hidden$="[[!skipActivityControl_]]">
       <div id="intro-text" class="content">
         [[i18nDynamic(locale, 'assistantRelatedInfoReturnedUserMessage')]]
       </div>
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_shared_styles.css b/chrome/browser/resources/chromeos/assistant_optin/assistant_shared_styles.css
index 8cd0bbe1..3acc4ca5 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/assistant_shared_styles.css
+++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_shared_styles.css
@@ -49,3 +49,9 @@
 #next-button {
   margin-inline-end: 0;
 }
+
+@media screen and (orientation: landscape) {
+  :host-context(html[new-layout]) .container {
+    padding-top: 72px;
+  }
+}
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.html b/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.html
index d7395a8..c8ad26e 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.html
+++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.html
@@ -18,7 +18,7 @@
           aria-label$="[[i18nDynamic(locale, 'assistantLogo')]]">
       </hd-iron-icon>
       <h1 slot="title" id="title-text"></h1>
-      <div slot="content">
+      <div slot="content" class="container">
         <div class="line"></div>
         <div id="insertion-point"></div>
         <div class="sub-title" id="footer-text"></div>
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html
index 153c3df..61f479a 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html
+++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html
@@ -63,7 +63,7 @@
       <div slot="subtitle">
         [[i18nDynamic(locale, 'assistantVoiceMatchFooter')]]
       </div>
-      <div slot="content">
+      <div slot="content" class="container">
         <div id="voice-match-entries">
           <voice-match-entry id="voice-entry-0">
             <div slot="entry-content">
diff --git a/chrome/browser/resources/chromeos/login/BUILD.gn b/chrome/browser/resources/chromeos/login/BUILD.gn
index a480dff5..ceb1802 100644
--- a/chrome/browser/resources/chromeos/login/BUILD.gn
+++ b/chrome/browser/resources/chromeos/login/BUILD.gn
@@ -21,6 +21,7 @@
     ":arc_terms_of_service",
     ":demo_preferences",
     ":demo_setup",
+    ":device_disabled",
     ":encryption_migration",
     ":family_link_notice",
     ":fingerprint_setup",
@@ -149,6 +150,15 @@
   ]
 }
 
+js_library("device_disabled") {
+  deps = [
+    "components:login_screen_behavior",
+    "components/oobe_adaptive_dialog:oobe_adaptive_dialog",
+    "components/oobe_dialog_host_behavior:oobe_dialog_host_behavior",
+    "components/oobe_i18n_behavior:oobe_i18n_behavior",
+  ]
+}
+
 js_library("encryption_migration") {
   deps = [
     "components:login_screen_behavior",
@@ -162,7 +172,7 @@
 js_library("family_link_notice") {
   deps = [
     "components:login_screen_behavior",
-    "components/oobe_dialog:oobe_dialog",
+    "components/oobe_adaptive_dialog:oobe_adaptive_dialog",
     "components/oobe_dialog_host_behavior:oobe_dialog_host_behavior",
     "components/oobe_i18n_behavior:oobe_i18n_behavior",
   ]
@@ -289,7 +299,8 @@
 
 js_library("oobe_network") {
   deps = [
-    "components/oobe_dialog:oobe_dialog",
+    ":network_select_login",
+    "components/oobe_adaptive_dialog:oobe_adaptive_dialog",
     "components/oobe_dialog_host_behavior:oobe_dialog_host_behavior",
     "components/oobe_i18n_behavior:oobe_i18n_behavior",
   ]
diff --git a/chrome/browser/resources/chromeos/login/components/oobe_adaptive_dialog/oobe_adaptive_dialog.html b/chrome/browser/resources/chromeos/login/components/oobe_adaptive_dialog/oobe_adaptive_dialog.html
index fc581ef..bcc24e8 100644
--- a/chrome/browser/resources/chromeos/login/components/oobe_adaptive_dialog/oobe_adaptive_dialog.html
+++ b/chrome/browser/resources/chromeos/login/components/oobe_adaptive_dialog/oobe_adaptive_dialog.html
@@ -57,6 +57,10 @@
 -->
 <dom-module id="oobe-adaptive-dialog">
   <template>
+    <!--
+      Below code is duplicated in ui-page element in multidevice setup flow.
+      Please make sure code changed are applied to both places.
+    -->
     <style include="oobe-dialog-host cr-shared-style">
       :host {
         height: var(--oobe-adaptive-dialog-height);
diff --git a/chrome/browser/resources/chromeos/login/components/oobe_types.js b/chrome/browser/resources/chromeos/login/components/oobe_types.js
index 8fd3fdc7..e2a9442a 100644
--- a/chrome/browser/resources/chromeos/login/components/oobe_types.js
+++ b/chrome/browser/resources/chromeos/login/components/oobe_types.js
@@ -108,34 +108,8 @@
 OobeTypes.PinSetupScreenParameters;
 
 /**
- * Specifies the type of the information that is requested by the security token
- * PIN dialog.
- * Must be kept in sync with chromeos/constants/security_token_pin_types.h.
- * @enum {number}
- */
-OobeTypes.SecurityTokenPinDialogType = {
-  PIN: 0,
-  PUK: 1,
-};
-
-/**
- * Specifies the type of the error that is displayed in the security token PIN
- * dialog.
- * Must be kept in sync with chromeos/constants/security_token_pin_types.h.
- * @enum {number}
- */
-OobeTypes.SecurityTokenPinDialogErrorType = {
-  NONE: 0,
-  UNKNOWN: 1,
-  INVALID_PIN: 2,
-  INVALID_PUK: 3,
-  MAX_ATTEMPTS_EXCEEDED: 4,
-};
-
-/**
  * Configuration of the security token PIN dialog.
  * @typedef {{
- *   codeType: OobeTypes.SecurityTokenPinDialogType,
  *   enableUserInput: boolean,
  *   attemptsLeft: number,
  *   hasError: boolean,
diff --git a/chrome/browser/resources/chromeos/login/device_disabled.html b/chrome/browser/resources/chromeos/login/device_disabled.html
index 227011e..be426b07 100644
--- a/chrome/browser/resources/chromeos/login/device_disabled.html
+++ b/chrome/browser/resources/chromeos/login/device_disabled.html
@@ -6,7 +6,7 @@
 
 <link rel="import" href="/components/common_styles.html">
 <link rel="import" href="/components/hd_iron_icon.html">
-<link rel="import" href="/components/oobe_dialog.html">
+<link rel="import" href="/components/oobe_adaptive_dialog.html">
 <link rel="import" href="/components/oobe_i18n_behavior.html">
 <link rel="import" href="/components/oobe_dialog_host_behavior.html">
 
@@ -23,20 +23,24 @@
       }
     </style>
 
-    <oobe-dialog title-key="deviceDisabledHeading" id="dialog"
+    <oobe-adaptive-dialog title-key="deviceDisabledHeading" id="dialog"
+        role="dialog"
         aria-label$="[[i18nDynamic(locale, 'deviceDisabledHeading')]]">
-      <hd-iron-icon slot="oobe-icon"
+      <hd-iron-icon slot="icon"
         icon1x="oobe-32:warning" icon2x="oobe-64:warning">
       </hd-iron-icon>
+      <h1 slot="title">
+        [[i18nDynamic(locale, 'deviceDisabledHeading')]]
+      </h1>
       <div slot="subtitle">
         [[disabledText_(locale, serial_, enrollmentDomain_)]]
       </div>
-      <div slot="footer" class="flex layout vertical center center-justified">
+      <div slot="content" class="flex layout vertical center center-justified">
         <div id="message">[[message_]]</div>
         <img class="oobe-illustration flex"
              srcset="images/1x/device-disabled.svg 1x,
                      images/2x/device-disabled.svg 2x">
       </div>
-    </oobe-dialog>
+    </oobe-adaptive-dialog>
   </template>
 </dom-module>
diff --git a/chrome/browser/resources/chromeos/login/device_disabled.js b/chrome/browser/resources/chromeos/login/device_disabled.js
index 8aa60fe..7f4fef3 100644
--- a/chrome/browser/resources/chromeos/login/device_disabled.js
+++ b/chrome/browser/resources/chromeos/login/device_disabled.js
@@ -60,10 +60,17 @@
     return this.$.dialog;
   },
 
+  /**
+   * Event handler that is invoked just before the frame is shown.
+   * @param {Object} data Screen init payload
+   */
   onBeforeShow(data) {
-    this.serial_ = data.serial;
-    this.enrollmentDomain_ = data.domain;
-    this.message_ = data.message;
+    if ('serial' in data)
+      this.serial_ = data.serial;
+    if ('domain' in data)
+      this.enrollmentDomain_ = data.domain;
+    if ('message' in data)
+      this.message_ = data.message;
   },
 
   /**
diff --git a/chrome/browser/resources/chromeos/login/family_link_notice.html b/chrome/browser/resources/chromeos/login/family_link_notice.html
index efe3b40..2d7d48a 100644
--- a/chrome/browser/resources/chromeos/login/family_link_notice.html
+++ b/chrome/browser/resources/chromeos/login/family_link_notice.html
@@ -9,32 +9,31 @@
 
 <link rel="import" href="/components/common_styles.html">
 <link rel="import" href="/components/hd_iron_icon.html">
-<link rel="import" href="/components/oobe_dialog.html">
+<link rel="import" href="/components/oobe_adaptive_dialog.html">
 <link rel="import" href="/components/oobe_i18n_behavior.html">
 <link rel="import" href="/components/oobe_dialog_host_behavior.html">
 
 <dom-module id="family-link-notice-element">
   <template>
     <style include="oobe-dialog-host"></style>
-    <oobe-dialog id="familyLinkDialog" role="dialog" has-buttons
+    <oobe-adaptive-dialog id="familyLinkDialog" role="dialog"
         aria-label$="[[getDialogTitle_(locale, email_, domain_)]]">
-      <hd-iron-icon slot="oobe-icon"
-          icon1x="oobe-32:family" icon2x="oobe-64:family">
+      <hd-iron-icon slot="icon" icon1x="oobe-32:family" icon2x="oobe-64:family">
       </hd-iron-icon>
       <h1 slot="title">[[getDialogTitle_(locale, email_, domain_)]]</h1>
       <div slot="subtitle">
         [[getDialogSubtitle_(locale, isNewGaiaAccount_, email_, domain_)]]
       </div>
-      <div slot="footer" class="flex layout vertical center center-justified">
+      <div slot="content" class="flex layout vertical center center-justified">
         <img srcset="images/1x/parental_control.svg 1x,
             images/2x/parental_control.svg 2x" class="oobe-illustration"
             alt$="[[i18nDynamic(locale, 'familyLinkDialogTitle')]]">
       </div>
-      <div slot="bottom-buttons" class="layout horizontal end-justified">
+      <div slot="bottom-buttons">
         <oobe-next-button id="continueButton"
             text-key="familyLinkContinueButton" class="focus-on-show"
             inverse on-click="onContinueButtonPressed_"></oobe-next-button>
       </div>
-    </oobe-dialog>
+    </oobe-adaptive-dialog>
   </template>
 </dom-module>
diff --git a/chrome/browser/resources/chromeos/login/oobe_network.html b/chrome/browser/resources/chromeos/login/oobe_network.html
index b59f985..c401dee 100644
--- a/chrome/browser/resources/chromeos/login/oobe_network.html
+++ b/chrome/browser/resources/chromeos/login/oobe_network.html
@@ -4,25 +4,27 @@
 
 <link rel="import" href="/components/common_styles.html">
 <link rel="import" href="/components/hd_iron_icon.html">
+<link rel="import" href="/components/oobe_adaptive_dialog.html">
 <link rel="import" href="/components/oobe_i18n_behavior.html">
-<link rel="import" href="/components/oobe_dialog.html">
 <link rel="import" href="/components/oobe_dialog_host_behavior.html">
 
 <dom-module id="oobe-network-element">
   <template>
     <style include="oobe-dialog-host"></style>
-    <oobe-dialog id="networkDialog" role="dialog" on-show-dialog="onShown_"
-        title-key="networkSectionTitle"
-        aria-label$="[[i18nDynamic(locale, 'networkSectionTitle')]]"
-        has-buttons>
-      <hd-iron-icon slot="oobe-icon"
+    <oobe-adaptive-dialog id="networkDialog" role="dialog"
+        on-show-dialog="onShown_"
+        aria-label$="[[i18nDynamic(locale, 'networkSectionTitle')]]">
+      <hd-iron-icon slot="icon"
           icon1x="oobe-network-32:dialog-icon-wifi"
           icon2x="oobe-network-64:dialog-icon-wifi">
       </hd-iron-icon>
+      <h1 slot="title">
+        [[i18nDynamic(locale, 'networkSectionTitle')]]
+      </h1>
       <div slot="subtitle" hidden$="[[isDemoModeSetup]]">
         [[i18nDynamic(locale, 'networkSectionHint')]]
       </div>
-      <div slot="footer" class="layout vertical">
+      <div slot="content" class="layout vertical">
         <network-select-login id="networkSelectLogin"
             on-selected-network-connected="onNetworkConnected_"
             is-network-connected="{{isConnected_}}">
@@ -36,6 +38,6 @@
         <oobe-next-button id="nextButton" disabled="[[!isConnected_]]"
             on-click="onNextClicked_"></oobe-next-button>
       </div>
-    </oobe-dialog>
+    </oobe-adaptive-dialog>
   </template>
 </dom-module>
diff --git a/chrome/browser/resources/chromeos/login/screen_multidevice_setup.js b/chrome/browser/resources/chromeos/login/screen_multidevice_setup.js
index 9877a373..4423102 100644
--- a/chrome/browser/resources/chromeos/login/screen_multidevice_setup.js
+++ b/chrome/browser/resources/chromeos/login/screen_multidevice_setup.js
@@ -15,7 +15,6 @@
     this.initializeLoginScreen('MultiDeviceSetupScreen', {});
   },
 
-
   get defaultControl() {
     return this.$.impl;
   },
@@ -23,4 +22,13 @@
   updateLocalizedContent() {
     this.$.impl.updateLocalizedContent();
   },
+
+  onBeforeShow() {
+    if (loadTimeData.valueExists('newLayoutEnabled') &&
+        loadTimeData.getBoolean('newLayoutEnabled')) {
+      document.documentElement.setAttribute('new-layout', '');
+    } else {
+      document.documentElement.removeAttribute('new-layout');
+    }
+  },
 });
diff --git a/chrome/browser/resources/chromeos/login/security_token_pin.js b/chrome/browser/resources/chromeos/login/security_token_pin.js
index f3c7542..6802f1d 100644
--- a/chrome/browser/resources/chromeos/login/security_token_pin.js
+++ b/chrome/browser/resources/chromeos/login/security_token_pin.js
@@ -9,12 +9,6 @@
 
 (function() {
 
-// Only inform the user about the number of attempts left if it's smaller or
-// equal to this constant. (This is a pure UX heuristic.)
-// Please keep this constant in sync with the one in
-// //chromeos/components/security_token_pin/error_generator.cc.
-const ATTEMPTS_LEFT_THRESHOLD = 3;
-
 Polymer({
   is: 'security-token-pin',
 
@@ -178,8 +172,7 @@
    * @private
    */
   isAttemptsLeftVisible_(parameters) {
-    return parameters && parameters.attemptsLeft >= 0 &&
-        parameters.attemptsLeft <= ATTEMPTS_LEFT_THRESHOLD;
+    return parameters && parameters.formattedAttemptsLeft !== '';
   },
 
   /**
diff --git a/chrome/browser/resources/chromeos/login/security_token_pin_browsertest.js b/chrome/browser/resources/chromeos/login/security_token_pin_browsertest.js
index 5175ca3..1a038c4 100644
--- a/chrome/browser/resources/chromeos/login/security_token_pin_browsertest.js
+++ b/chrome/browser/resources/chromeos/login/security_token_pin_browsertest.js
@@ -34,9 +34,7 @@
 
 TEST_F('PolymerSecurityTokenPinTest', 'All', function() {
   const DEFAULT_PARAMETERS = {
-    codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
     enableUserInput: true,
-    attemptsLeft: -1,
     hasError: false,
     formattedError: '',
     formattedAttemptsLeft: ''
@@ -109,9 +107,7 @@
 
     // The response arrives, requesting to prompt for the PIN again.
     securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
       enableUserInput: true,
-      attemptsLeft: -1,
       hasError: true,
       formattedError: '',
       formattedAttemptsLeft: ''
@@ -177,9 +173,7 @@
     pinInput.value = '123';
     submitElement.click();
     securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
       enableUserInput: true,
-      attemptsLeft: -1,
       hasError: true,
       formattedError: '',
       formattedAttemptsLeft: ''
@@ -191,9 +185,7 @@
     pinInput.value = '456';
     submitElement.click();
     securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
       enableUserInput: false,
-      attemptsLeft: 0,
       hasError: true,
       formattedError: '',
       formattedAttemptsLeft: ''
@@ -211,9 +203,7 @@
     // The input gets cleared.
     submitElement.click();
     securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
       enableUserInput: true,
-      attemptsLeft: -1,
       hasError: true,
       formattedError: '',
       formattedAttemptsLeft: ''
@@ -235,9 +225,7 @@
     // and that the user input isn't requested anymore. The input gets cleared.
     submitElement.click();
     securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
       enableUserInput: false,
-      attemptsLeft: 0,
       hasError: true,
       formattedError: '',
       formattedAttemptsLeft: ''
@@ -283,9 +271,7 @@
     pinInput.value = '123';
     submitElement.click();
     securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
       enableUserInput: true,
-      attemptsLeft: -1,
       hasError: true,
       formattedError: '',
       formattedAttemptsLeft: ''
@@ -299,153 +285,38 @@
     expectFalse(pinInput.hasAttribute('invalid'));
   });
 
-  // Test the text of the label for the |INVALID_PIN| error.
+  // Test the text of the error label.
   test('label text: invalid PIN', () => {
     securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
       enableUserInput: true,
-      attemptsLeft: -1,
       hasError: true,
-      formattedError:
-          loadTimeData.getString('securityTokenPinDialogUnknownInvalidPin'),
+      formattedError: 'Invalid PIN.',
       formattedAttemptsLeft: ''
     };
-    expectEquals(
-        errorElement.textContent,
-        loadTimeData.getString('securityTokenPinDialogUnknownInvalidPin'));
+    expectEquals(errorElement.textContent, 'Invalid PIN.');
   });
 
-  // Test the text of the label for the |INVALID_PUK| error.
-  test('label text: invalid PUK', () => {
-    securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PUK,
-      enableUserInput: true,
-      attemptsLeft: -1,
-      hasError: true,
-      formattedError:
-          loadTimeData.getString('securityTokenPinDialogUnknownInvalidPuk'),
-      formattedAttemptsLeft: ''
-    };
-    expectEquals(
-        errorElement.textContent,
-        loadTimeData.getString('securityTokenPinDialogUnknownInvalidPuk'));
-  });
-
-  // Test the text of the label for the |MAX_ATTEMPTS_EXCEEDED| error.
+  // Test the text of the error label when the user input is disabled.
   test('label text: max attempts exceeded', () => {
     securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
       enableUserInput: false,
-      attemptsLeft: 0,
       hasError: true,
-      formattedError: loadTimeData.getString(
-          'securityTokenPinDialogUnknownMaxAttemptsExceeded'),
+      formattedError: 'Maximum allowed attempts exceeded.',
       formattedAttemptsLeft: ''
     };
     expectEquals(
-        errorElement.textContent,
-        loadTimeData.getString(
-            'securityTokenPinDialogUnknownMaxAttemptsExceeded'));
-  });
-
-  // Test the text of the label for the |UNKNOWN| error.
-  test('label text: unknown error', () => {
-    securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
-      enableUserInput: true,
-      attemptsLeft: -1,
-      hasError: true,
-      formattedError:
-          loadTimeData.getString('securityTokenPinDialogUnknownError'),
-      formattedAttemptsLeft: ''
-    };
-    expectEquals(
-        errorElement.textContent,
-        loadTimeData.getString('securityTokenPinDialogUnknownError'));
+        errorElement.textContent, 'Maximum allowed attempts exceeded.');
   });
 
   // Test the text of the label when the number of attempts left is given.
   test('label text: attempts number', () => {
-    const ATTEMPTS_LEFT = 3;
     securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
       enableUserInput: true,
-      attemptsLeft: ATTEMPTS_LEFT,
       hasError: false,
       formattedError: '',
       formattedAttemptsLeft: '3 attempts left'
     };
     expectEquals(errorElement.textContent, '3 attempts left');
-
-    const ONE_ATTEMPT_LEFT = 1;
-    securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
-      enableUserInput: true,
-      attemptsLeft: ONE_ATTEMPT_LEFT,
-      hasError: false,
-      formattedError: '',
-      formattedAttemptsLeft: '1 attempt left'
-    };
-    expectEquals(errorElement.textContent, '1 attempt left');
-  });
-
-  // Test that the label is empty when the number of attempts is, heuristically,
-  // too big to be displayed for the user.
-  test('label text: hidden attempts number', () => {
-    const BIG_ATTEMPTS_LEFT = 4;
-    securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
-      enableUserInput: true,
-      attemptsLeft: BIG_ATTEMPTS_LEFT,
-      hasError: false,
-      formattedError: '',
-      formattedAttemptsLeft: ''
-    };
-    expectEquals(errorElement.textContent, '');
-  });
-
-  // Test the text of the label for the |INVALID_PIN| error when the number of
-  // attempts left is given.
-  test('label text: invalid PIN with attempts number', () => {
-    const ATTEMPTS_LEFT = 3;
-    securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
-      enableUserInput: true,
-      attemptsLeft: ATTEMPTS_LEFT,
-      hasError: true,
-      formattedError: 'Invalid PIN. 3 attempts left',
-      formattedAttemptsLeft: ''
-    };
-    expectEquals(errorElement.textContent, 'Invalid PIN. 3 attempts left');
-
-    const ONE_ATTEMPT_LEFT = 1;
-    securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
-      enableUserInput: true,
-      attemptsLeft: ONE_ATTEMPT_LEFT,
-      hasError: true,
-      formattedError: 'Invalid PIN. 1 attempt left',
-      formattedAttemptsLeft: ''
-    };
-    expectEquals(errorElement.textContent, 'Invalid PIN. 1 attempt left');
-  });
-
-  // Test the text of the label for the |INVALID_PIN| error when the number of
-  // attempts left is, heuristically, too big to be displayed for the user.
-  test('label text: invalid PIN with hidden attempts number', () => {
-    const BIG_ATTEMPTS_LEFT = 4;
-    securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
-      enableUserInput: true,
-      attemptsLeft: BIG_ATTEMPTS_LEFT,
-      hasError: true,
-      formattedError:
-          loadTimeData.getString('securityTokenPinDialogUnknownInvalidPin'),
-      formattedAttemptsLeft: ''
-    };
-    expectEquals(
-        errorElement.textContent,
-        loadTimeData.getString('securityTokenPinDialogUnknownInvalidPin'));
   });
 
   // Test that no scrolling is necessary in order to see all dots after entering
@@ -488,9 +359,7 @@
 
     // The response arrives, requesting to prompt for the PIN again.
     securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
       enableUserInput: true,
-      attemptsLeft: -1,
       hasError: true,
       formattedError: '',
       formattedAttemptsLeft: ''
@@ -519,9 +388,7 @@
 
     // The response arrives, requesting to prompt for the PIN again.
     securityTokenPin.parameters = {
-      codeType: OobeTypes.SecurityTokenPinDialogType.PIN,
       enableUserInput: true,
-      attemptsLeft: -1,
       hasError: true,
       formattedError: '',
       formattedAttemptsLeft: ''
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup_post_oobe.js b/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup_post_oobe.js
index b80c392..ad6b1c56 100644
--- a/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup_post_oobe.js
+++ b/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup_post_oobe.js
@@ -69,6 +69,27 @@
   behaviors: [I18nBehavior],
 
   /** @override */
+  ready() {
+    var url = new URL(document.URL);
+    var dialogHeight = url.searchParams.get('dialog-height');
+    var dialogWidth = url.searchParams.get('dialog-width');
+    if (dialogHeight && dialogWidth) {
+      // Below code is also used to set the dialog size for display manager and
+      // in-session assistant onboarding flow. Please make sure code changes are
+      // applied to all places.
+      document.documentElement.style.setProperty(
+          '--oobe-oobe-dialog-height-base', dialogHeight + 'px');
+      document.documentElement.style.setProperty(
+          '--oobe-oobe-dialog-width-base', dialogWidth + 'px');
+      if (parseInt(dialogWidth, 10) > parseInt(dialogHeight, 10)) {
+        document.documentElement.setAttribute('orientation', 'horizontal');
+      } else {
+        document.documentElement.setAttribute('orientation', 'vertical');
+      }
+    }
+  },
+
+  /** @override */
   attached() {
     this.delegate_ = new multidevice_setup.PostOobeDelegate();
     this.$$('multidevice-setup').initializeSetupFlow();
diff --git a/chrome/browser/resources/chromeos/network_ui/BUILD.gn b/chrome/browser/resources/chromeos/network_ui/BUILD.gn
index 2d13d26..a43cfa7 100644
--- a/chrome/browser/resources/chromeos/network_ui/BUILD.gn
+++ b/chrome/browser/resources/chromeos/network_ui/BUILD.gn
@@ -2,10 +2,71 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//chrome/common/features.gni")
 import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/grit/grit_rule.gni")
+import("//tools/grit/preprocess_if_expr.gni")
+import("//tools/polymer/html_to_js.gni")
+import("//ui/webui/resources/tools/generate_grd.gni")
+
+preprocess_folder = "preprocessed"
+preprocess_manifest = "preprocessed_manifest.json"
+preprocess_gen_manifest = "preprocessed_gen_manifest.json"
+
+generate_grd("build_grd") {
+  grd_prefix = "network_ui"
+  out_grd = "$target_gen_dir/${grd_prefix}_resources.grd"
+  input_files = [ "network.html" ]
+  input_files_base_dir = rebase_path(".", "//")
+
+  deps = [
+    ":preprocess",
+    ":preprocess_generated",
+  ]
+  manifest_files = [
+    "$target_gen_dir/$preprocess_manifest",
+    "$target_gen_dir/$preprocess_gen_manifest",
+  ]
+}
+
+preprocess_if_expr("preprocess") {
+  in_folder = "./"
+  out_folder = "$target_gen_dir/$preprocess_folder"
+  out_manifest = "$target_gen_dir/$preprocess_manifest"
+  in_files = [ "network_ui_browser_proxy.js" ]
+}
+
+preprocess_if_expr("preprocess_generated") {
+  deps = [ ":web_components" ]
+  in_folder = target_gen_dir
+  out_folder = "$target_gen_dir/$preprocess_folder"
+  out_manifest = "$target_gen_dir/$preprocess_gen_manifest"
+  in_files = [
+    "network_logs_ui.js",
+    "network_state_ui.js",
+    "network_ui.js",
+  ]
+}
+
+grit("resources") {
+  defines = chrome_grit_defines
+
+  # These arguments are needed since the grd is generated at build time.
+  enable_input_discovery_for_gn_analyze = false
+  source = "$target_gen_dir/network_ui_resources.grd"
+  deps = [ ":build_grd" ]
+
+  outputs = [
+    "grit/network_ui_resources.h",
+    "grit/network_ui_resources_map.cc",
+    "grit/network_ui_resources_map.h",
+    "network_ui_resources.pak",
+  ]
+  output_dir = "$root_gen_dir/chrome"
+}
 
 js_type_check("closure_compile") {
-  uses_legacy_modules = true
+  is_polymer3 = true
   deps = [
     ":network_logs_ui",
     ":network_state_ui",
@@ -17,17 +78,17 @@
 js_library("network_ui") {
   deps = [
     ":network_ui_browser_proxy",
-    "//ui/webui/resources/cr_components/chromeos/network:onc_mojo",
-    "//ui/webui/resources/cr_components/chromeos/network_health:network_diagnostics",
-    "//ui/webui/resources/js:i18n_behavior",
-    "//ui/webui/resources/js:load_time_data",
+    "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
+    "//ui/webui/resources/cr_components/chromeos/network_health:network_diagnostics.m",
+    "//ui/webui/resources/js:i18n_behavior.m",
+    "//ui/webui/resources/js:load_time_data.m",
   ]
 }
 
 js_library("network_logs_ui") {
   deps = [
     ":network_ui_browser_proxy",
-    "//ui/webui/resources/js:i18n_behavior",
+    "//ui/webui/resources/js:i18n_behavior.m",
   ]
 }
 
@@ -35,15 +96,23 @@
   deps = [
     ":network_ui_browser_proxy",
     "//chromeos/services/network_config/public/mojom:mojom_js_library_for_compile",
-    "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider",
-    "//ui/webui/resources/cr_components/chromeos/network:network_icon",
-    "//ui/webui/resources/cr_components/chromeos/network:network_list",
-    "//ui/webui/resources/cr_components/chromeos/network:onc_mojo",
+    "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider.m",
+    "//ui/webui/resources/cr_components/chromeos/network:network_icon.m",
+    "//ui/webui/resources/cr_components/chromeos/network:network_list.m",
+    "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
   ]
   externs_list = chrome_extension_public_externs +
                  [ "$externs_path/networking_private.js" ]
 }
 
 js_library("network_ui_browser_proxy") {
-  deps = [ "//ui/webui/resources/js:cr" ]
+  deps = [ "//ui/webui/resources/js:cr.m" ]
+}
+
+html_to_js("web_components") {
+  js_files = [
+    "network_logs_ui.js",
+    "network_state_ui.js",
+    "network_ui.js",
+  ]
 }
diff --git a/chrome/browser/resources/chromeos/network_ui/network.html b/chrome/browser/resources/chromeos/network_ui/network.html
index df1592f..22fa2c1 100644
--- a/chrome/browser/resources/chromeos/network_ui/network.html
+++ b/chrome/browser/resources/chromeos/network_ui/network.html
@@ -6,17 +6,11 @@
   <title>$i18n{titleText}</title>
 
   <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-
-  <link rel="import" href="network_ui.html">
-
-  <script src="chrome://resources/js/cr.js"></script>
-  <script src="chrome://resources/js/load_time_data.js"></script>
-
-  <script src="strings.js"></script>
 </head>
 
 <body>
   <network-ui></network-ui>
+  <script type="module" src="network_ui.js"></script>
 </body>
 
 </html>
diff --git a/chrome/browser/resources/chromeos/network_ui/network_logs_ui.html b/chrome/browser/resources/chromeos/network_ui/network_logs_ui.html
index dbebd3b8..24eaaf7 100644
--- a/chrome/browser/resources/chromeos/network_ui/network_logs_ui.html
+++ b/chrome/browser/resources/chromeos/network_ui/network_logs_ui.html
@@ -1,91 +1,77 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="cr-shared-style">
+  cr-button,
+  cr-checkbox {
+    margin: 5px 0;
+  }
 
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_checkbox/cr_checkbox.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_radio_group/cr_radio_group.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="network_ui_browser_proxy.html">
+  cr-radio-group {
+    --cr-radio-group-item-padding: 6px;
+  }
 
-<dom-module id="network-logs-ui">
-  <template>
-    <style include="cr-shared-style">
-      cr-button,
-      cr-checkbox {
-        margin: 5px 0;
-      }
+  .error {
+    color: red;
+  }
 
-      cr-radio-group {
-        --cr-radio-group-item-padding: 6px;
-      }
+  .indented {
+    margin-inline-start: 10px;
+  }
 
-      .error {
-        color: red;
-      }
+  #storeResult {
+    margin: 10px 0;
+    white-space: pre-wrap;
+  }
+</style>
+<div>
+  <h2>$i18n{networkLogsTab}</h2>
+  <p>$i18n{networkLogsDescription}</p>
+  <span>$i18nRaw{deviceLogLinkText}</span>
+  <h3>Options</h3>
+  <div class="indented">
+    <cr-checkbox checked="{{systemLogs_}}">
+      $i18n{networkLogsSystemLogs}
+    </cr-checkbox>
+    <div class="indented">
+      <cr-checkbox class="indented" checked="{{filterPII_}}"
+          disabled="[[!systemLogs_]]">
+        $i18n{networkLogsFilterPii}
+      </cr-checkbox>
+    </div>
+    <cr-checkbox checked="{{policies_}}">
+      $i18n{networkLogsPolicies}
+    </cr-checkbox>
+    <cr-checkbox checked="{{debugLogs_}}">
+      $i18n{networkLogsDebugLogs}
+    </cr-checkbox>
+    <div class="indented">
+      <cr-checkbox checked="{{chromeLogs_}}" class="indented"
+          disabled="[[!debugLogs_]]">
+        $i18n{networkLogsChromeLogs}
+      </cr-checkbox>
+    </div>
+  </div>
+  <cr-button on-click="onStore_"
+      disabled="[[!validOptions_(systemLogs_, policies_, debugLogs_)]]">
+    $i18n{networkLogsStoreButton}
+  </cr-button>
+  <div id="storeResult"></div>
 
-      .indented {
-        margin-inline-start: 10px;
-      }
-
-      #storeResult {
-        margin: 10px 0;
-        white-space: pre-wrap;
-      }
-    </style>
-    <div>
-      <h2>$i18n{networkLogsTab}</h2>
-      <p>$i18n{networkLogsDescription}</p>
-      <span>$i18nRaw{deviceLogLinkText}</span>
-      <h3>Options</h3>
-      <div class="indented">
-        <cr-checkbox checked="{{systemLogs_}}">
-          $i18n{networkLogsSystemLogs}
-        </cr-checkbox>
-        <div class="indented">
-          <cr-checkbox class="indented" checked="{{filterPII_}}"
-              disabled="[[!systemLogs_]]">
-            $i18n{networkLogsFilterPii}
-          </cr-checkbox>
-        </div>
-        <cr-checkbox checked="{{policies_}}">
-          $i18n{networkLogsPolicies}
-        </cr-checkbox>
-        <cr-checkbox checked="{{debugLogs_}}">
-          $i18n{networkLogsDebugLogs}
-        </cr-checkbox>
-        <div class="indented">
-          <cr-checkbox checked="{{chromeLogs_}}" class="indented"
-              disabled="[[!debugLogs_]]">
-            $i18n{networkLogsChromeLogs}
-          </cr-checkbox>
-        </div>
-      </div>
-      <cr-button on-click="onStore_"
-          disabled="[[!validOptions_(systemLogs_, policies_, debugLogs_)]]">
-        $i18n{networkLogsStoreButton}
-      </cr-button>
-      <div id="storeResult"></div>
-
-      <h2>$i18n{networkLogsDebuggingTitle}</h2>
-      <p>$i18n{networkLogsDebuggingDescription}</p>
-      <cr-radio-group selected="{{shillDebugging_}}">
-        <cr-radio-button name="unknown" disabled>
-          $i18n{networkLogsDebuggingUnknown}
-        </cr-radio-button>
-        <cr-radio-button name="none">
-          $i18n{networkLogsDebuggingNone}
-        </cr-radio-button>
-        <cr-radio-button name="wifi">
-          $i18n{OncTypeWiFi}
-        </cr-radio-button>
-        <cr-radio-button name="cellular">
-          $i18n{OncTypeCellular}
-        </cr-radio-button>
-        <cr-radio-button name="ethernet">
-          $i18n{OncTypeEthernet}
-        </cr-radio-button>
-      </cr-radio-group>
-  </template>
-  <script src="network_logs_ui.js"></script>
-</dom-module>
+  <h2>$i18n{networkLogsDebuggingTitle}</h2>
+  <p>$i18n{networkLogsDebuggingDescription}</p>
+  <cr-radio-group selected="{{shillDebugging_}}">
+    <cr-radio-button name="unknown" disabled>
+      $i18n{networkLogsDebuggingUnknown}
+    </cr-radio-button>
+    <cr-radio-button name="none">
+      $i18n{networkLogsDebuggingNone}
+    </cr-radio-button>
+    <cr-radio-button name="wifi">
+      $i18n{OncTypeWiFi}
+    </cr-radio-button>
+    <cr-radio-button name="cellular">
+      $i18n{OncTypeCellular}
+    </cr-radio-button>
+    <cr-radio-button name="ethernet">
+      $i18n{OncTypeEthernet}
+    </cr-radio-button>
+  </cr-radio-group>
+</div>
diff --git a/chrome/browser/resources/chromeos/network_ui/network_logs_ui.js b/chrome/browser/resources/chromeos/network_ui/network_logs_ui.js
index 464d5991..62577dac 100644
--- a/chrome/browser/resources/chromeos/network_ui/network_logs_ui.js
+++ b/chrome/browser/resources/chromeos/network_ui/network_logs_ui.js
@@ -2,6 +2,17 @@
 // 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_checkbox/cr_checkbox.m.js';
+import 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button.m.js';
+import 'chrome://resources/cr_elements/cr_radio_group/cr_radio_group.m.js';
+import 'chrome://resources/cr_elements/shared_style_css.m.js';
+
+import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {NetworkUIBrowserProxy, NetworkUIBrowserProxyImpl} from './network_ui_browser_proxy.js';
+
 /**
  * @fileoverview
  * Polymer element for UI controlling the storing of system logs.
@@ -10,6 +21,8 @@
 Polymer({
   is: 'network-logs-ui',
 
+  _template: html`{__html_template__}`,
+
   behaviors: [I18nBehavior],
 
   properties: {
@@ -70,8 +83,8 @@
 
   observers: ['onShillDebuggingChanged_(shillDebugging_)'],
 
-  /** @type {!network_ui.NetworkUIBrowserProxy} */
-  browserProxy_: network_ui.NetworkUIBrowserProxyImpl.getInstance(),
+  /** @type {!NetworkUIBrowserProxy} */
+  browserProxy_: NetworkUIBrowserProxyImpl.getInstance(),
 
   /** @override */
   attached() {},
diff --git a/chrome/browser/resources/chromeos/network_ui/network_state_ui.html b/chrome/browser/resources/chromeos/network_ui/network_state_ui.html
index 98a6f80..f89958c 100644
--- a/chrome/browser/resources/chromeos/network_ui/network_state_ui.html
+++ b/chrome/browser/resources/chromeos/network_ui/network_state_ui.html
@@ -1,135 +1,121 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_icon.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html">
-<link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html">
-<link rel="import" href="chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom.html">
-<link rel="import" href="network_ui_browser_proxy.html">
+<style include="cr-shared-style">
+  div {
+    margin: 10px 0;
+  }
 
-<dom-module id="network-state-ui">
-  <template>
-    <style include="cr-shared-style">
-      div {
-        margin: 10px 0;
-      }
+  .state-table {
+    border-collapse: collapse;
+    min-width: 800px;
+  }
 
-      .state-table {
-        border-collapse: collapse;
-        min-width: 800px;
-      }
+  .state-table tr td {
+    border: 1px solid rgb(220, 220, 220);
+    font-size: 13px;
+  }
 
-      .state-table tr td {
-        border: 1px solid rgb(220, 220, 220);
-        font-size: 13px;
-      }
+  .state-table-header {
+    font-weight: bold;
+  }
 
-      .state-table-header {
-        font-weight: bold;
-      }
+  .state-table-expand-button-cell {
+    text-align: center;
+  }
 
-      .state-table-expand-button-cell {
-        text-align: center;
-      }
+  .state-table-expand-button {
+    background-color: #fff;
+    border: none;
+    height: 20px;
+    margin: 0;
+    outline: none;
+    padding: 0;
+    width: 20px;
+  }
 
-      .state-table-expand-button {
-        background-color: #fff;
-        border: none;
-        height: 20px;
-        margin: 0;
-        outline: none;
-        padding: 0;
-        width: 20px;
-      }
+  .state-table-expanded-cell {
+    min-width: 400px;
+    white-space: pre-wrap;
+  }
 
-      .state-table-expanded-cell {
-        min-width: 400px;
-        white-space: pre-wrap;
-      }
+  .state-table-icon-cell {
+    height: 32px;
+    width: 32px;
+  }
+</style>
 
-      .state-table-icon-cell {
-        height: 32px;
-        width: 32px;
-      }
-    </style>
+<div>$i18n{autoRefreshText}</div>
 
-    <div>$i18n{autoRefreshText}</div>
+<div>
+  <cr-button class="action-button" id="refresh"
+      on-click="requestNetworks_">
+    $i18n{networkRefreshText}
+  </cr-button>
+</div>
 
-    <div>
-      <cr-button class="action-button" id="refresh"
-          on-click="requestNetworks_">
-        $i18n{networkRefreshText}
-      </cr-button>
-    </div>
+<div>
+  <h2>$i18n{networkListsLabel}</h2>
+  <div>$i18n{clickToExpandText}</div>
+  <div>
+    <span>$i18n{propertyFormatText}</span>
+    <select id="get-property-format" on-change="requestNetworks_">
+      <option value="normal">$i18n{normalFormatOption}</option>
+      <option value="managed">$i18n{managedFormatOption}</option>
+      <option value="state">$i18n{stateFormatOption}</option>
+      <option value="shill">$i18n{shillFormatOption}</option>
+    </select>
+  </div>
 
-    <div>
-      <h2>$i18n{networkListsLabel}</h2>
-      <div>$i18n{clickToExpandText}</div>
-      <div>
-        <span>$i18n{propertyFormatText}</span>
-        <select id="get-property-format" on-change="requestNetworks_">
-          <option value="normal">$i18n{normalFormatOption}</option>
-          <option value="managed">$i18n{managedFormatOption}</option>
-          <option value="state">$i18n{stateFormatOption}</option>
-          <option value="shill">$i18n{shillFormatOption}</option>
-        </select>
-      </div>
+  <h3>$i18n{devicesLabel}</h3>
+  <table id="device-state-table" class="state-table">
+    <tr class="state-table-header">
+      <td></td>
+      <td></td>
+      <td>Type</td>
+      <td>State</td>
+    </tr>
+  </table>
 
-      <h3>$i18n{devicesLabel}</h3>
-      <table id="device-state-table" class="state-table">
-        <tr class="state-table-header">
-          <td></td>
-          <td></td>
-          <td>Type</td>
-          <td>State</td>
-        </tr>
-      </table>
+  <h3>$i18n{visibleNetworksLabel}</h3>
+  <table id="network-state-table" class="state-table">
+    <tr class="state-table-header">
+      <td></td>
+      <td></td>
+      <td>GUID</td>
+      <td>Name</td>
+      <td>Type</td>
+      <td>State</td>
+      <td>Connect?</td>
+      <td>Error</td>
+      <td>Security</td>
+      <td>Tech</td>
+      <td>Activation</td>
+      <td>Roam</td>
+      <td>Frequency</td>
+      <td>Strength</td>
+    </tr>
+  </table>
 
-      <h3>$i18n{visibleNetworksLabel}</h3>
-      <table id="network-state-table" class="state-table">
-        <tr class="state-table-header">
-          <td></td>
-          <td></td>
-          <td>GUID</td>
-          <td>Name</td>
-          <td>Type</td>
-          <td>State</td>
-          <td>Connect?</td>
-          <td>Error</td>
-          <td>Security</td>
-          <td>Tech</td>
-          <td>Activation</td>
-          <td>Roam</td>
-          <td>Frequency</td>
-          <td>Strength</td>
-        </tr>
-      </table>
+  <h3>$i18n{ethernetEapNetworkLabel}</h3>
+  <table id="ethernet-eap-state-table" class="state-table">
+    <tr class="state-table-header">
+      <td></td>
+      <td></td>
+      <td>GUID</td>
+      <td>Name</td>
+      <td>Type</td>
+      <td>ONC Source</td>
+    </tr>
+  </table>
 
-      <h3>$i18n{ethernetEapNetworkLabel}</h3>
-      <table id="ethernet-eap-state-table" class="state-table">
-        <tr class="state-table-header">
-          <td></td>
-          <td></td>
-          <td>GUID</td>
-          <td>Name</td>
-          <td>Type</td>
-          <td>ONC Source</td>
-        </tr>
-      </table>
-
-      <h3>$i18n{favoriteNetworksLabel}</h3>
-      <table id="favorite-state-table" class="state-table">
-        <tr class="state-table-header">
-          <td></td>
-          <td></td>
-          <td>GUID</td>
-          <td>Name</td>
-          <td>Type</td>
-          <td>ONC Source</td>
-        </tr>
-      </table>
-    </div>
-  </template>
-  <script src="network_state_ui.js"></script>
-</dom-module>
+  <h3>$i18n{favoriteNetworksLabel}</h3>
+  <table id="favorite-state-table" class="state-table">
+    <tr class="state-table-header">
+      <td></td>
+      <td></td>
+      <td>GUID</td>
+      <td>Name</td>
+      <td>Type</td>
+      <td>ONC Source</td>
+    </tr>
+  </table>
+</div>
diff --git a/chrome/browser/resources/chromeos/network_ui/network_state_ui.js b/chrome/browser/resources/chromeos/network_ui/network_state_ui.js
index 6b9cf6e3..900d1f1 100644
--- a/chrome/browser/resources/chromeos/network_ui/network_state_ui.js
+++ b/chrome/browser/resources/chromeos/network_ui/network_state_ui.js
@@ -2,6 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'chrome://resources/cr_components/chromeos/network/network_icon.m.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
+import 'chrome://resources/cr_components/chromeos/network/network_icon.m.js';
+import 'chrome://resources/cr_elements/shared_style_css.m.js';
+import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
+import 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-lite.js';
+
+import {OncMojo} from 'chrome://resources/cr_components/chromeos/network/onc_mojo.m.js';
+import {assert} from 'chrome://resources/js/assert.m.js';
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {NetworkUIBrowserProxy, NetworkUIBrowserProxyImpl} from './network_ui_browser_proxy.js';
+
+
 /**
  * @typedef {!OncMojo.DeviceStateProperties|!OncMojo.NetworkStateProperties}
  */
@@ -10,6 +24,8 @@
 Polymer({
   is: 'network-state-ui',
 
+  _template: html`{__html_template__}`,
+
   properties: {},
 
   /**
@@ -39,8 +55,8 @@
    */
   networkConfig_: null,
 
-  /** @private {!network_ui.NetworkUIBrowserProxy} */
-  browserProxy_: network_ui.NetworkUIBrowserProxyImpl.getInstance(),
+  /** @private {!NetworkUIBrowserProxy} */
+  browserProxy_: NetworkUIBrowserProxyImpl.getInstance(),
 
   /** @override */
   created() {
diff --git a/chrome/browser/resources/chromeos/network_ui/network_ui.html b/chrome/browser/resources/chromeos/network_ui/network_ui.html
index aa1b1c09..a67d813 100644
--- a/chrome/browser/resources/chromeos/network_ui/network_ui.html
+++ b/chrome/browser/resources/chromeos/network_ui/network_ui.html
@@ -1,135 +1,114 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style>
+  .button-group > cr-button {
+    margin-inline-start: 10px;
+  }
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_select.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network_health/network_diagnostics.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network_health/network_health_summary.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_tabs/cr_tabs.html">
-<link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html">
-<link rel="import" href="chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html">
-<link rel="import" href="network_ui_browser_proxy.html">
-<link rel="import" href="network_state_ui.html">
-<link rel="import" href="network_logs_ui.html">
+  .tabpanel > div {
+    margin-bottom: 10px;
+  }
 
-<dom-module id="network-ui">
-  <template>
-    <style>
-      .button-group > cr-button {
-        margin-inline-start: 10px;
-      }
+  #global-policy {
+    white-space: pre-wrap;
+  }
 
-      .tabpanel > div {
-        margin-bottom: 10px;
-      }
+  #select-div {
+    display: flex;
+    height: 400px;
+    width: 500px;
+  }
 
-      #global-policy {
-        white-space: pre-wrap;
-      }
+  #onc-import-result {
+    margin: 10px 0
+  }
 
-      #select-div {
-        display: flex;
-        height: 400px;
-        width: 500px;
-      }
+  iron-pages {
+    flex: 1;
+    position: relative;
+  }
 
-      #onc-import-result {
-        margin: 10px 0
-      }
+  network-select {
+    flex: 1;
+  }
 
-      iron-pages {
-        flex: 1;
-        position: relative;
-      }
+  .error {
+    color: red;
+  }
+</style>
 
-      network-select {
-        flex: 1;
-      }
+<cr-tabs selected="{{selectedTab_}}" tab-names="[[tabNames_]]">
+</cr-tabs>
+<iron-pages selected="[[selectedTab_]]">
+  <div class="tabpanel" id="general">
+    <h2>$i18n{titleText}</h2>
+    <div>
+      <h2>$i18n{globalPolicyLabel}</h2>
+      <div id="global-policy"></div>
+    </div>
 
-      .error {
-        color: red;
-      }
-    </style>
+    <div>
+      <h2>$i18n{dhcpHostnameLabel}</h2>
+      <cr-input id="hostnameInput" value="{{hostname_}}"
+          on-change="onHostnameChanged_">
+      </cr-input>
+    </div>
 
-    <cr-tabs selected="{{selectedTab_}}" tab-names="[[tabNames_]]">
-    </cr-tabs>
-    <iron-pages selected="[[selectedTab_]]">
-      <div class="tabpanel" id="general">
-        <h2>$i18n{titleText}</h2>
-        <div>
-          <h2>$i18n{globalPolicyLabel}</h2>
-          <div id="global-policy"></div>
-        </div>
-
-        <div>
-          <h2>$i18n{dhcpHostnameLabel}</h2>
-          <cr-input id="hostnameInput" value="{{hostname_}}"
-              on-change="onHostnameChanged_">
-          </cr-input>
-        </div>
-
-        <div>
-          <h2>$i18n{cellularActivationLabel}</h2>
-          <cr-button class="action-button" id="cellular-activation-button"
-              on-click="openCellularActivationUi_">
-            $i18n{cellularActivationButtonText}
-          </cr-button>
-          <div id="cellular-error-text" class="error" hidden>
-            $i18n{noCellularErrorText}
-          </div>
-        </div>
-
-        <div>
-          <h2>$i18n{addNewWifiLabel}</h2>
-          <cr-button class="action-button" id="add-new-wifi-button"
-              on-click="showAddNewWifi_">
-            $i18n{addNewWifiButtonText}
-          </cr-button>
-        </div>
-
-        <div>
-          <h2>$i18n{importOncButtonText}</h2>
-          <input type="file" id="import-onc" on-change="onImportOncChange_">
-          <div id="onc-import-result"></div>
-        </div>
+    <div>
+      <h2>$i18n{cellularActivationLabel}</h2>
+      <cr-button class="action-button" id="cellular-activation-button"
+          on-click="openCellularActivationUi_">
+        $i18n{cellularActivationButtonText}
+      </cr-button>
+      <div id="cellular-error-text" class="error" hidden>
+        $i18n{noCellularErrorText}
       </div>
+    </div>
 
-      <div class="tabpanel" id="health">
-        <h2>$i18n{networkHealthLabel}</h2>
-        <network-health-summary></network-health-summary>
-        <h2>$i18n{networkDiagnosticsLabel}</h2>
-        <div class="button-group">
-          <cr-button on-click="onRunAllRoutinesClick_">
-            [[i18n('NetworkDiagnosticsRunAll')]]
-          </cr-button>
-          <cr-button on-click="onSendFeedbackReportClick_">
-            [[i18n('NetworkDiagnosticsSendFeedback')]]
-          </cr-button>
-        </div>
-        <network-diagnostics id="network-diagnostics"
-            on-open-feedback-dialog="onOpenFeedbackDialog_">
-        </network-diagnostics>
-      </div>
+    <div>
+      <h2>$i18n{addNewWifiLabel}</h2>
+      <cr-button class="action-button" id="add-new-wifi-button"
+          on-click="showAddNewWifi_">
+        $i18n{addNewWifiButtonText}
+      </cr-button>
+    </div>
 
-      <div class="tabpanel" id="logs">
-        <network-logs-ui></network-logs-ui>
-      </div>
+    <div>
+      <h2>$i18n{importOncButtonText}</h2>
+      <input type="file" id="import-onc" on-change="onImportOncChange_">
+      <div id="onc-import-result"></div>
+    </div>
+  </div>
 
-      <div class="tabpanel" id="state">
-        <network-state-ui></network-state-ui>
-      </div>
+  <div class="tabpanel" id="health">
+    <h2>$i18n{networkHealthLabel}</h2>
+    <network-health-summary></network-health-summary>
+    <h2>$i18n{networkDiagnosticsLabel}</h2>
+    <div class="button-group">
+      <cr-button on-click="onRunAllRoutinesClick_">
+        [[i18n('NetworkDiagnosticsRunAll')]]
+      </cr-button>
+      <cr-button on-click="onSendFeedbackReportClick_">
+        [[i18n('NetworkDiagnosticsSendFeedback')]]
+      </cr-button>
+    </div>
+    <network-diagnostics id="network-diagnostics"
+        on-open-feedback-dialog="onOpenFeedbackDialog_">
+    </network-diagnostics>
+  </div>
 
-      <div class="tabpanel" id="select">
-        <div id="select-div">
-          <network-select
-              on-network-item-selected="onNetworkItemSelected_"
-              on-custom-item-selected="onCustomItemSelected_">
-          </network-select>
-        </div>
-      </div>
-    </iron-pages>
-  </template>
-  <script src="network_ui.js"></script>
-</dom-module>
+  <div class="tabpanel" id="logs">
+    <network-logs-ui></network-logs-ui>
+  </div>
+
+  <div class="tabpanel" id="state">
+    <network-state-ui></network-state-ui>
+  </div>
+
+  <div class="tabpanel" id="select">
+    <div id="select-div">
+      <network-select
+          on-network-item-selected="onNetworkItemSelected_"
+          on-custom-item-selected="onCustomItemSelected_">
+      </network-select>
+    </div>
+  </div>
+</iron-pages>
diff --git a/chrome/browser/resources/chromeos/network_ui/network_ui.js b/chrome/browser/resources/chromeos/network_ui/network_ui.js
index 3087ed57..b3883cf 100644
--- a/chrome/browser/resources/chromeos/network_ui/network_ui.js
+++ b/chrome/browser/resources/chromeos/network_ui/network_ui.js
@@ -2,6 +2,26 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'chrome://resources/cr_components/chromeos/network/network_select.m.js';
+import 'chrome://resources/cr_components/chromeos/network_health/network_diagnostics.m.js';
+import 'chrome://resources/cr_components/chromeos/network_health/network_health_summary.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 'chrome://resources/cr_elements/cr_tabs/cr_tabs.m.js';
+import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
+import 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-lite.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
+import 'chrome://resources/polymer/v3_0/iron-pages/iron-pages.js';
+import './strings.m.js';
+import './network_state_ui.js';
+import './network_logs_ui.js';
+
+import {OncMojo} from 'chrome://resources/cr_components/chromeos/network/onc_mojo.m.js';
+import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {NetworkUIBrowserProxy, NetworkUIBrowserProxyImpl} from './network_ui_browser_proxy.js';
+
+
 /**
  * @fileoverview
  * Polymer element network debugging UI.
@@ -10,6 +30,8 @@
 Polymer({
   is: 'network-ui',
 
+  _template: html`{__html_template__}`,
+
   behaviors: [I18nBehavior],
 
   properties: {
@@ -49,8 +71,8 @@
   /** @type {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */
   networkConfig_: null,
 
-  /** @type {!network_ui.NetworkUIBrowserProxy} */
-  browserProxy_: network_ui.NetworkUIBrowserProxyImpl.getInstance(),
+  /** @type {!NetworkUIBrowserProxy} */
+  browserProxy_: NetworkUIBrowserProxyImpl.getInstance(),
 
   /** @override */
   attached() {
diff --git a/chrome/browser/resources/chromeos/network_ui/network_ui_browser_proxy.js b/chrome/browser/resources/chromeos/network_ui/network_ui_browser_proxy.js
index 44861d0..1ef0e41 100644
--- a/chrome/browser/resources/chromeos/network_ui/network_ui_browser_proxy.js
+++ b/chrome/browser/resources/chromeos/network_ui/network_ui_browser_proxy.js
@@ -2,150 +2,144 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-cr.define('network_ui', function() {
-  /** @interface */
-  /* #export */ class NetworkUIBrowserProxy {
-    /** @param {string} type */
-    addNetwork(type) {}
+import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js';
 
-    /**
-     * @param {string} type
-     * @return {Promise<!Array>}
-     */
-    getShillDeviceProperties(type) {}
+/** @interface */
+export class NetworkUIBrowserProxy {
+  /** @param {string} type */
+  addNetwork(type) {}
 
-    /**
-     * @return {Promise<!Array>}
-     */
-    getShillEthernetEAP() {}
+  /**
+   * @param {string} type
+   * @return {Promise<!Array>}
+   */
+  getShillDeviceProperties(type) {}
 
-    /**
-     * @param {string} guid
-     * @return {Promise<!Array>}
-     */
-    getShillNetworkProperties(guid) {}
+  /**
+   * @return {Promise<!Array>}
+   */
+  getShillEthernetEAP() {}
 
-    /**
-     * @param {string} content
-     * @return {Promise<!Array>}
-     */
-    importONC(content) {}
+  /**
+   * @param {string} guid
+   * @return {Promise<!Array>}
+   */
+  getShillNetworkProperties(guid) {}
 
-    /**
-     * @return {Promise<!Array>}
-     */
-    openCellularActivationUi() {}
+  /**
+   * @param {string} content
+   * @return {Promise<!Array>}
+   */
+  importONC(content) {}
 
-    /**
-     * @param {string} debugging
-     * @return {Promise<!Array>}
-     */
-    setShillDebugging(debugging) {}
+  /**
+   * @return {Promise<!Array>}
+   */
+  openCellularActivationUi() {}
 
-    showAddNewWifi() {}
+  /**
+   * @param {string} debugging
+   * @return {Promise<!Array>}
+   */
+  setShillDebugging(debugging) {}
 
-    /** @param {string} guid */
-    showNetworkConfig(guid) {}
+  showAddNewWifi() {}
 
-    /** @param {string} guid */
-    showNetworkDetails(guid) {}
+  /** @param {string} guid */
+  showNetworkConfig(guid) {}
 
-    /**
-     * @param {Object<string>} options
-     * @return {Promise<!Array>}
-     */
-    storeLogs(options) {}
+  /** @param {string} guid */
+  showNetworkDetails(guid) {}
 
-    /**
-     * @return {Promise<string>}
-     */
-    getHostname() {}
+  /**
+   * @param {Object<string>} options
+   * @return {Promise<!Array>}
+   */
+  storeLogs(options) {}
 
-    /**
-     * @param {string} hostname
-     */
-    setHostname(hostname) {}
+  /**
+   * @return {Promise<string>}
+   */
+  getHostname() {}
+
+  /**
+   * @param {string} hostname
+   */
+  setHostname(hostname) {}
+}
+
+/**
+ * @implements {NetworkUIBrowserProxy}
+ */
+export class NetworkUIBrowserProxyImpl {
+  /** @override */
+  addNetwork(type) {
+    chrome.send('addNetwork', [type]);
+  }
+
+  /** @override */
+  getShillDeviceProperties(type) {
+    return sendWithPromise('getShillDeviceProperties', type);
+  }
+
+  /** @override */
+  getShillEthernetEAP() {
+    return sendWithPromise('getShillEthernetEAP');
+  }
+
+  /** @override */
+  getShillNetworkProperties(guid) {
+    return sendWithPromise('getShillNetworkProperties', guid);
+  }
+
+  /** @override */
+  importONC(content) {
+    return sendWithPromise('importONC', content);
+  }
+
+  /** @override */
+  openCellularActivationUi() {
+    return sendWithPromise('openCellularActivationUi');
+  }
+
+  /** @override */
+  setShillDebugging(debugging) {
+    return sendWithPromise('setShillDebugging', debugging);
+  }
+
+  /** @override */
+  showAddNewWifi() {
+    chrome.send('showAddNewWifi');
+  }
+
+  /** @override */
+  showNetworkConfig(guid) {
+    chrome.send('showNetworkConfig', [guid]);
+  }
+
+  /** @override */
+  showNetworkDetails(guid) {
+    chrome.send('showNetworkDetails', [guid]);
+  }
+
+  /** @override */
+  storeLogs(options) {
+    return sendWithPromise('storeLogs', options);
   }
 
   /**
-   * @implements {network_ui.NetworkUIBrowserProxy}
+   * @return {Promise<string>}
    */
-  /* #export */ class NetworkUIBrowserProxyImpl {
-    /** @override */
-    addNetwork(type) {
-      chrome.send('addNetwork', [type]);
-    }
-
-    /** @override */
-    getShillDeviceProperties(type) {
-      return cr.sendWithPromise('getShillDeviceProperties', type);
-    }
-
-    /** @override */
-    getShillEthernetEAP() {
-      return cr.sendWithPromise('getShillEthernetEAP');
-    }
-
-    /** @override */
-    getShillNetworkProperties(guid) {
-      return cr.sendWithPromise('getShillNetworkProperties', guid);
-    }
-
-    /** @override */
-    importONC(content) {
-      return cr.sendWithPromise('importONC', content);
-    }
-
-    /** @override */
-    openCellularActivationUi() {
-      return cr.sendWithPromise('openCellularActivationUi');
-    }
-
-    /** @override */
-    setShillDebugging(debugging) {
-      return cr.sendWithPromise('setShillDebugging', debugging);
-    }
-
-    /** @override */
-    showAddNewWifi() {
-      chrome.send('showAddNewWifi');
-    }
-
-    /** @override */
-    showNetworkConfig(guid) {
-      chrome.send('showNetworkConfig', [guid]);
-    }
-
-    /** @override */
-    showNetworkDetails(guid) {
-      chrome.send('showNetworkDetails', [guid]);
-    }
-
-    /** @override */
-    storeLogs(options) {
-      return cr.sendWithPromise('storeLogs', options);
-    }
-
-    /**
-     * @return {Promise<string>}
-     */
-    getHostname() {
-      return cr.sendWithPromise('getHostname');
-    }
-
-    /**
-     * @param {string} hostname
-     */
-    setHostname(hostname) {
-      chrome.send('setHostname', [hostname]);
-    }
+  getHostname() {
+    return sendWithPromise('getHostname');
   }
 
-  cr.addSingletonGetter(NetworkUIBrowserProxyImpl);
+  /**
+   * @param {string} hostname
+   */
+  setHostname(hostname) {
+    chrome.send('setHostname', [hostname]);
+  }
+}
 
-  // #cr_define_end
-  return {
-    NetworkUIBrowserProxy: NetworkUIBrowserProxy,
-    NetworkUIBrowserProxyImpl: NetworkUIBrowserProxyImpl
-  };
-});
+addSingletonGetter(NetworkUIBrowserProxyImpl);
diff --git a/chrome/browser/resources/commander/option.html b/chrome/browser/resources/commander/option.html
index 2e5b837..ffdf8fd 100644
--- a/chrome/browser/resources/commander/option.html
+++ b/chrome/browser/resources/commander/option.html
@@ -22,7 +22,12 @@
     margin-inline-start: auto;
   }
 
-  span {
+  .title {
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+
+  .title-piece {
     white-space: pre;
   }
 
@@ -32,14 +37,18 @@
   }
 
   iron-icon {
+    flex-shrink: 0;
     margin-inline-end: .5em;
     --iron-icon-fill-color: --google-grey-800;
   }
 </style>
 <iron-icon icon="[[computeIcon_(model.entity)]]"></iron-icon>
+<span class="title">
 <template is="dom-repeat"
     items="[[computeMatchSpans_(model.title, model.matchedRanges)]]"
     as="span">
-  <span class$="[[getClassForMatch(span.isMatch)]]">[[span.text]]</span>
+  <span class$="title-piece
+      [[getClassForMatch(span.isMatch)]]">[[span.text]]</span>
 </template>
+</span>
 <span class="annotation">[[model.annotation]]</span>
diff --git a/chrome/browser/resources/pdf/viewport.js b/chrome/browser/resources/pdf/viewport.js
index 0125303..efd8e13 100644
--- a/chrome/browser/resources/pdf/viewport.js
+++ b/chrome/browser/resources/pdf/viewport.js
@@ -269,7 +269,9 @@
     const height = dimensions.height;
     const width = dimensions.width;
 
-    const matrix = new DOMMatrix();
+    // TODO(dpapad): Use the no-arg constructor when
+    // https://github.com/google/closure-compiler/issues/3768 is fixed.
+    const matrix = new DOMMatrix([1, 0, 0, 1, 0, 0]);
 
     const rotation = this.getClockwiseRotations() * 90;
     // Set origin for rotation.
@@ -288,10 +290,8 @@
     matrix.scaleSelf(1, -1);
 
     const pointsToPixels = 96 / 72;
-    const result = matrix.transformPoint({
-      x: point.x * pointsToPixels,
-      y: point.y * pointsToPixels,
-    });
+    const result = matrix.transformPoint(
+        new DOMPoint(point.x * pointsToPixels, point.y * pointsToPixels));
     return {
       x: result.x + PAGE_SHADOW.left,
       y: result.y + PAGE_SHADOW.top,
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html b/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html
index 8a3c13ca..c890eadf 100644
--- a/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html
+++ b/chrome/browser/resources/settings/appearance_page/appearance_fonts_page.html
@@ -51,15 +51,13 @@
             menu-options="[[fontOptions_]]">
         </settings-dropdown-menu>
       </div>
-      <div class="list-item cr-padded-text"
+      <div id="standardFontPreview" class="list-item cr-padded-text"
           style="
               font-size:[[prefs.webkit.webprefs.default_font_size.value]]px;
               font-family:
                   '[[prefs.webkit.webprefs.fonts.standard.Zyyy.value]]';">
-        <span>
-          [[prefs.webkit.webprefs.default_font_size.value]]:
-          $i18n{quickBrownFox}
-        </span>
+        [[prefs.webkit.webprefs.default_font_size.value]]:
+        $i18n{quickBrownFox}
       </div>
     </div>
     <div class="cr-row" aria-hidden="true">
@@ -72,15 +70,13 @@
             menu-options="[[fontOptions_]]">
         </settings-dropdown-menu>
       </div>
-      <div class="list-item cr-padded-text"
+      <div id="serifFontPreview" class="list-item cr-padded-text"
           style="
               font-size:[[prefs.webkit.webprefs.default_font_size.value]]px;
               font-family:
                   '[[prefs.webkit.webprefs.fonts.serif.Zyyy.value]]';">
-        <span>
-          [[prefs.webkit.webprefs.default_font_size.value]]:
-          $i18n{quickBrownFox}
-        </span>
+        [[prefs.webkit.webprefs.default_font_size.value]]:
+        $i18n{quickBrownFox}
       </div>
     </div>
     <div class="cr-row" aria-hidden="true">
@@ -93,15 +89,13 @@
             menu-options="[[fontOptions_]]">
         </settings-dropdown-menu>
       </div>
-      <div class="list-item cr-padded-text"
+      <div id="sansSerifFontPreview" class="list-item cr-padded-text"
           style="
               font-size:[[prefs.webkit.webprefs.default_font_size.value]]px;
               font-family:
                   '[[prefs.webkit.webprefs.fonts.sansserif.Zyyy.value]]';">
-        <span>
-          [[prefs.webkit.webprefs.default_font_size.value]]:
-          $i18n{quickBrownFox}
-        </span>
+        [[prefs.webkit.webprefs.default_font_size.value]]:
+        $i18n{quickBrownFox}
       </div>
     </div>
     <div class="cr-row" aria-hidden="true">
@@ -114,13 +108,13 @@
             menu-options="[[fontOptions_]]">
         </settings-dropdown-menu>
       </div>
-      <div class="list-item cr-padded-text"
+      <div id="fixedFontPreview" class="list-item cr-padded-text"
           style="
               font-size:
                   [[prefs.webkit.webprefs.default_fixed_font_size.value]]px;
               font-family:
                   '[[prefs.webkit.webprefs.fonts.fixed.Zyyy.value]]';">
-        [[prefs.webkit.webprefs.default_font_size.value]]:
+        [[prefs.webkit.webprefs.default_fixed_font_size.value]]:
         $i18n{quickBrownFox}
       </div>
     </div>
diff --git a/chrome/browser/resources/settings/chromeos/ensure_lazy_loaded.m.js b/chrome/browser/resources/settings/chromeos/ensure_lazy_loaded.m.js
index a471dc89..18619fd 100644
--- a/chrome/browser/resources/settings/chromeos/ensure_lazy_loaded.m.js
+++ b/chrome/browser/resources/settings/chromeos/ensure_lazy_loaded.m.js
@@ -17,7 +17,6 @@
       'os-settings-files-page',
       'settings-smb-shares-page',
       'os-printing-page',
-      'settings-crostini-page',
     ];
     if (!loadTimeData.getBoolean('isAccountManagementFlowsV2Enabled')) {
       lazyLoadPages.push('os-settings-privacy-page');
diff --git a/chrome/browser/resources/settings/chromeos/lazy_load.html b/chrome/browser/resources/settings/chromeos/lazy_load.html
index 585422e..7cdc415 100644
--- a/chrome/browser/resources/settings/chromeos/lazy_load.html
+++ b/chrome/browser/resources/settings/chromeos/lazy_load.html
@@ -1,7 +1,6 @@
 <html>
 <head></head>
 <body>
-  <link rel="import" href="crostini_page/crostini_page.html">
   <link rel="import" href="date_time_page/date_time_page.html">
   <link rel="import" href="date_time_page/timezone_selector.html">
   <link rel="import" href="on_startup_page/on_startup_page.html">
diff --git a/chrome/browser/resources/settings/chromeos/lazy_load.js b/chrome/browser/resources/settings/chromeos/lazy_load.js
index 257d759..4ee6c14 100644
--- a/chrome/browser/resources/settings/chromeos/lazy_load.js
+++ b/chrome/browser/resources/settings/chromeos/lazy_load.js
@@ -3,17 +3,6 @@
 // found in the LICENSE file.
 
 // Uncomment as these modules are migrated to Polymer 3.
-import './crostini_page/crostini_arc_adb.m.js';
-import './crostini_page/crostini_arc_adb_confirmation_dialog.m.js';
-import './crostini_page/crostini_disk_resize_confirmation_dialog.m.js';
-import './crostini_page/crostini_disk_resize_dialog.m.js';
-import './crostini_page/crostini_export_import.m.js';
-import './crostini_page/crostini_import_confirmation_dialog.m.js';
-import './crostini_page/crostini_mic_sharing_dialog.m.js';
-import './crostini_page/crostini_page.m.js';
-import './crostini_page/crostini_port_forwarding.m.js';
-import './crostini_page/crostini_port_forwarding_add_port_dialog.m.js';
-import './crostini_page/crostini_subpage.m.js';
 import './date_time_page/date_time_page.m.js';
 import './date_time_page/timezone_selector.m.js';
 import './os_a11y_page/os_a11y_page.m.js';
@@ -53,7 +42,6 @@
 export {SmbBrowserProxyImpl, SmbMountResult} from 'chrome://resources/cr_components/chromeos/smb_shares/smb_browser_proxy.m.js';
 export {LanguagesBrowserProxy, LanguagesBrowserProxyImpl} from '../languages_page/languages_browser_proxy.m.js';
 export {LifetimeBrowserProxyImpl} from '../lifetime_browser_proxy.m.js';
-export {CrostiniBrowserProxy, CrostiniBrowserProxyImpl} from './crostini_page/crostini_browser_proxy.m.js';
 export {TimeZoneAutoDetectMethod} from './date_time_page/date_time_types.m.js';
 export {TimeZoneBrowserProxyImpl} from './date_time_page/timezone_browser_proxy.m.js';
 export {LanguagesMetricsProxy, LanguagesMetricsProxyImpl, LanguagesPageInteraction} from './os_languages_page/languages_metrics_proxy.m.js';
diff --git a/chrome/browser/safe_browsing/safe_browsing_metrics_collector.cc b/chrome/browser/safe_browsing/safe_browsing_metrics_collector.cc
index f62bda4..be4c5f5b 100644
--- a/chrome/browser/safe_browsing/safe_browsing_metrics_collector.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_metrics_collector.cc
@@ -6,20 +6,68 @@
 
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/util/values/values_util.h"
 #include "components/prefs/pref_service.h"
+#include "components/prefs/scoped_user_pref_update.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 
 namespace {
 
+using EventType = safe_browsing::SafeBrowsingMetricsCollector::EventType;
+using UserState = safe_browsing::SafeBrowsingMetricsCollector::UserState;
+using SafeBrowsingState = safe_browsing::SafeBrowsingState;
+
 const int kMetricsLoggingIntervalDay = 1;
 
+const int kTimestampsMaxLength = 30;
+
+std::string EventTypeToPrefKey(const EventType& type) {
+  return base::NumberToString(static_cast<int>(type));
+}
+
+std::string SafeBrowsingStateToPrefKey(const SafeBrowsingState state) {
+  switch (state) {
+    case SafeBrowsingState::ENHANCED_PROTECTION:
+      return base::NumberToString(
+          static_cast<int>(UserState::ENHANCED_PROTECTION));
+    case SafeBrowsingState::STANDARD_PROTECTION:
+      return base::NumberToString(
+          static_cast<int>(UserState::STANDARD_PROTECTION));
+    case SafeBrowsingState::NO_SAFE_BROWSING:
+      NOTREACHED() << "Unexpected Safe Browsing state.";
+      return base::NumberToString(
+          static_cast<int>(UserState::STANDARD_PROTECTION));
+  }
+}
+
+base::Value TimeToPrefValue(const base::Time& time) {
+  return util::Int64ToValue(time.ToDeltaSinceWindowsEpoch().InSeconds());
+}
+
+base::Time PrefValueToTime(const base::Value& value) {
+  return base::Time::FromDeltaSinceWindowsEpoch(
+      base::TimeDelta::FromSeconds(util::ValueToInt64(value).value_or(0)));
+}
+
 }  // namespace
 
 namespace safe_browsing {
 
 SafeBrowsingMetricsCollector::SafeBrowsingMetricsCollector(
     PrefService* pref_service)
-    : pref_service_(pref_service) {}
+    : pref_service_(pref_service) {
+  pref_change_registrar_.Init(pref_service_);
+  pref_change_registrar_.Add(
+      prefs::kSafeBrowsingEnhanced,
+      base::BindRepeating(
+          &SafeBrowsingMetricsCollector::OnEnhancedProtectionPrefChanged,
+          base::Unretained(this)));
+}
+
+void SafeBrowsingMetricsCollector::Shutdown() {
+  pref_change_registrar_.RemoveAll();
+}
 
 void SafeBrowsingMetricsCollector::StartLogging() {
   base::TimeDelta log_interval =
@@ -57,4 +105,96 @@
       &SafeBrowsingMetricsCollector::LogMetricsAndScheduleNextLogging);
 }
 
+void SafeBrowsingMetricsCollector::AddSafeBrowsingEventToPref(
+    EventType event_type) {
+  DictionaryPrefUpdate update(pref_service_,
+                              prefs::kSafeBrowsingEventTimestamps);
+  base::DictionaryValue* mutable_state_dict = update.Get();
+
+  SafeBrowsingState sb_state = GetSafeBrowsingState(*pref_service_);
+  // Safe Browsing events should not be triggered when Safe Browsing is
+  // disabled.
+  DCHECK(sb_state != SafeBrowsingState::NO_SAFE_BROWSING);
+  base::Value* event_dict =
+      mutable_state_dict->FindDictKey(SafeBrowsingStateToPrefKey(sb_state));
+
+  if (!event_dict) {
+    event_dict =
+        mutable_state_dict->SetKey(SafeBrowsingStateToPrefKey(sb_state),
+                                   base::Value(base::Value::Type::DICTIONARY));
+  }
+
+  base::Value* timestamps =
+      event_dict->FindListKey(EventTypeToPrefKey(event_type));
+  if (!timestamps) {
+    timestamps = event_dict->SetKey(EventTypeToPrefKey(event_type),
+                                    base::Value(base::Value::Type::LIST));
+  }
+
+  // Remove the oldest timestamp if the length of the timestamps hits the limit.
+  while (timestamps->GetList().size() >= kTimestampsMaxLength) {
+    timestamps->EraseListIter(timestamps->GetList().begin());
+  }
+
+  timestamps->Append(TimeToPrefValue(base::Time::Now()));
+}
+
+void SafeBrowsingMetricsCollector::OnEnhancedProtectionPrefChanged() {
+  if (safe_browsing::GetSafeBrowsingState(*pref_service_) !=
+      SafeBrowsingState::ENHANCED_PROTECTION) {
+    LogEnhancedProtectionDisabledMetrics();
+  }
+}
+
+void SafeBrowsingMetricsCollector::LogEnhancedProtectionDisabledMetrics() {
+  const base::DictionaryValue* state_dict =
+      pref_service_->GetDictionary(prefs::kSafeBrowsingEventTimestamps);
+  const base::Value* event_dict = state_dict->FindDictKey(
+      SafeBrowsingStateToPrefKey(SafeBrowsingState::ENHANCED_PROTECTION));
+  if (!event_dict) {
+    return;
+  }
+
+  std::vector<Event> bypass_events;
+  for (int event_type_int = 0; event_type_int < EventType::kMaxValue + 1;
+       event_type_int += 1) {
+    EventType event_type = static_cast<EventType>(event_type_int);
+    if (!IsBypassEventType(event_type)) {
+      continue;
+    }
+    const base::Value* timestamps =
+        event_dict->FindListKey(EventTypeToPrefKey(event_type));
+
+    // Get the latest timestamp for this bypass event type.
+    if (timestamps && timestamps->GetList().size() > 0) {
+      base::Time time = PrefValueToTime(timestamps->GetList().back());
+      bypass_events.emplace_back(Event(event_type, time));
+    }
+  }
+
+  const auto latest_event = std::max_element(
+      bypass_events.begin(), bypass_events.end(),
+      [](const Event& a, const Event& b) { return a.timestamp < b.timestamp; });
+
+  if (latest_event != bypass_events.end()) {
+    base::UmaHistogramEnumeration(
+        "SafeBrowsing.EsbDisabled.LastBypassEventType", latest_event->type);
+  }
+}
+
+bool SafeBrowsingMetricsCollector::IsBypassEventType(const EventType& type) {
+  switch (type) {
+    case EventType::USER_STATE_DISABLED:
+    case EventType::USER_STATE_ENABLED:
+      return false;
+    case EventType::DATABASE_INTERSTITIAL_BYPASS:
+    case EventType::CSD_INTERSITITAL_BYPASS:
+    case EventType::REAL_TIME_INTERSTITIAL_BYPASS:
+      return true;
+  }
+}
+
+SafeBrowsingMetricsCollector::Event::Event(EventType type, base::Time timestamp)
+    : type(type), timestamp(timestamp) {}
+
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/safe_browsing_metrics_collector.h b/chrome/browser/safe_browsing/safe_browsing_metrics_collector.h
index 3bd92f0..f3678c5 100644
--- a/chrome/browser/safe_browsing/safe_browsing_metrics_collector.h
+++ b/chrome/browser/safe_browsing/safe_browsing_metrics_collector.h
@@ -9,6 +9,7 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "components/keyed_service/core/keyed_service.h"
+#include "components/prefs/pref_change_registrar.h"
 
 class PrefService;
 
@@ -16,8 +17,41 @@
 
 // This class is for logging Safe Browsing metrics regularly. Metrics are logged
 // everyday or at startup, if the last logging time was more than a day ago.
+// It is also responsible for adding Safe Browsing events in prefs and logging
+// metrics when enhanced protection is disabled.
 class SafeBrowsingMetricsCollector : public KeyedService {
  public:
+  // Enum representing different types of Safe Browsing events for measuring
+  // user friction. They are used as keys of the SafeBrowsingEventTimestamps
+  // pref. They are used for logging histograms, entries must not be removed or
+  // reordered. Please update the enums.xml file if new values are added.
+  enum EventType {
+    // The user state is disabled.
+    USER_STATE_DISABLED = 0,
+    // The user state is enabled.
+    USER_STATE_ENABLED = 1,
+    // The user bypasses the interstitial that is triggered by the Safe Browsing
+    // database.
+    DATABASE_INTERSTITIAL_BYPASS = 2,
+    // The user bypasses the interstitial that is triggered by client-side
+    // detection.
+    CSD_INTERSITITAL_BYPASS = 3,
+    // The user bypasses the interstitial that is triggered by real time URL
+    // check.
+    REAL_TIME_INTERSTITIAL_BYPASS = 4,
+
+    kMaxValue = REAL_TIME_INTERSTITIAL_BYPASS
+  };
+
+  // Enum representing the current user state. They are used as keys of the
+  // SafeBrowsingEventTimestamps pref, entries must not be removed or reordered.
+  enum UserState {
+    // Standard protection is enabled.
+    STANDARD_PROTECTION = 0,
+    // Enhanced protection is enabled.
+    ENHANCED_PROTECTION = 1
+  };
+
   explicit SafeBrowsingMetricsCollector(PrefService* pref_service_);
   ~SafeBrowsingMetricsCollector() override = default;
 
@@ -25,11 +59,29 @@
   // immediately. Otherwise, schedule the next logging with delay.
   void StartLogging();
 
+  // Add |event_type| and the current timestamp to pref.
+  void AddSafeBrowsingEventToPref(EventType event_type);
+
+  // KeyedService:
+  // Called before the actual deletion of the object.
+  void Shutdown() override;
+
  private:
+  struct Event {
+    Event(EventType type, base::Time timestamp);
+    EventType type;
+    base::Time timestamp;
+  };
+  static bool IsBypassEventType(const EventType& type);
+
   void LogMetricsAndScheduleNextLogging();
   void ScheduleNextLoggingAfterInterval(base::TimeDelta interval);
 
+  void OnEnhancedProtectionPrefChanged();
+  void LogEnhancedProtectionDisabledMetrics();
+
   PrefService* pref_service_;
+  PrefChangeRegistrar pref_change_registrar_;
   base::OneShotTimer metrics_collector_timer_;
 
   DISALLOW_COPY_AND_ASSIGN(SafeBrowsingMetricsCollector);
diff --git a/chrome/browser/safe_browsing/safe_browsing_metrics_collector_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_metrics_collector_unittest.cc
index a0302c0..4e3f8be7 100644
--- a/chrome/browser/safe_browsing/safe_browsing_metrics_collector_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_metrics_collector_unittest.cc
@@ -4,11 +4,14 @@
 
 #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector.h"
 #include <memory>
+#include <utility>
 
 #include "base/base64.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
+#include "base/util/values/values_util.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
@@ -17,6 +20,9 @@
 
 namespace safe_browsing {
 
+using EventType = SafeBrowsingMetricsCollector::EventType;
+using UserState = SafeBrowsingMetricsCollector::UserState;
+
 class SafeBrowsingMetricsCollectorTest : public ::testing::Test {
  public:
   SafeBrowsingMetricsCollectorTest() = default;
@@ -29,12 +35,43 @@
         std::make_unique<SafeBrowsingMetricsCollector>(&pref_service_);
   }
 
+  void TearDown() override { metrics_collector_->Shutdown(); }
+
  protected:
   void SetSafeBrowsingMetricsLastLogTime(base::Time time) {
     pref_service_.SetInt64(prefs::kSafeBrowsingMetricsLastLogTime,
                            time.ToDeltaSinceWindowsEpoch().InSeconds());
   }
 
+  const base::Value* GetTsFromUserStateAndEventType(UserState state,
+                                                    EventType event_type) {
+    const base::DictionaryValue* state_dict =
+        pref_service_.GetDictionary(prefs::kSafeBrowsingEventTimestamps);
+    const base::Value* event_dict =
+        state_dict->FindDictKey(base::NumberToString(static_cast<int>(state)));
+    DCHECK(event_dict);
+    DCHECK(event_dict->is_dict());
+    const base::Value* timestamps = event_dict->FindListKey(
+        base::NumberToString(static_cast<int>(event_type)));
+    DCHECK(timestamps);
+    DCHECK(timestamps->is_list());
+    return timestamps;
+  }
+
+  bool IsSortedInChronologicalOrder(const base::Value* ts) {
+    return std::is_sorted(ts->GetList().begin(), ts->GetList().end(),
+                          [](const base::Value& ts_a, const base::Value& ts_b) {
+                            return util::ValueToInt64(ts_a).value_or(0) <
+                                   util::ValueToInt64(ts_b).value_or(0);
+                          });
+  }
+
+  void FastForwardAndAddEvent(base::TimeDelta time_delta,
+                              EventType event_type) {
+    task_environment_->FastForwardBy(time_delta);
+    metrics_collector_->AddSafeBrowsingEventToPref(event_type);
+  }
+
   std::unique_ptr<SafeBrowsingMetricsCollector> metrics_collector_;
   std::unique_ptr<base::test::TaskEnvironment> task_environment_;
   TestingPrefServiceSimple pref_service_;
@@ -49,11 +86,13 @@
                                                   false);
     pref_service_.registry()->RegisterBooleanPref(
         prefs::kSafeBrowsingScoutReportingEnabled, false);
+    pref_service_.registry()->RegisterDictionaryPref(
+        prefs::kSafeBrowsingEventTimestamps);
   }
 };
 
 TEST_F(SafeBrowsingMetricsCollectorTest,
-       TestLastLoggingIntervalLongerThanScheduleInterval) {
+       StartLogging_LastLoggingIntervalLongerThanScheduleInterval) {
   base::HistogramTester histograms;
   SetSafeBrowsingMetricsLastLogTime(base::Time::Now() -
                                     base::TimeDelta::FromHours(25));
@@ -121,7 +160,7 @@
 }
 
 TEST_F(SafeBrowsingMetricsCollectorTest,
-       TestLastLoggingIntervalShorterThanScheduleInterval) {
+       StartLogging_LastLoggingIntervalShorterThanScheduleInterval) {
   base::HistogramTester histograms;
   SetSafeBrowsingMetricsLastLogTime(base::Time::Now() -
                                     base::TimeDelta::FromHours(1));
@@ -139,7 +178,8 @@
                                /* sample */ 1, /* expected_count */ 2);
 }
 
-TEST_F(SafeBrowsingMetricsCollectorTest, TestPrefChangeBetweenLogging) {
+TEST_F(SafeBrowsingMetricsCollectorTest,
+       StartLogging_PrefChangeBetweenLogging) {
   base::HistogramTester histograms;
   SetSafeBrowsingMetricsLastLogTime(base::Time::Now() -
                                     base::TimeDelta::FromHours(25));
@@ -156,4 +196,82 @@
   histograms.ExpectBucketCount("SafeBrowsing.Pref.Daily.SafeBrowsingState",
                                /* sample */ 0, /* expected_count */ 1);
 }
+
+TEST_F(SafeBrowsingMetricsCollectorTest,
+       AddSafeBrowsingEventToPref_OldestTsRemoved) {
+  SetSafeBrowsingState(&pref_service_, ENHANCED_PROTECTION);
+  metrics_collector_->AddSafeBrowsingEventToPref(
+      EventType::DATABASE_INTERSTITIAL_BYPASS);
+
+  task_environment_->FastForwardBy(base::TimeDelta::FromDays(1));
+  for (int i = 0; i < 29; i++) {
+    metrics_collector_->AddSafeBrowsingEventToPref(
+        EventType::DATABASE_INTERSTITIAL_BYPASS);
+  }
+
+  const base::Value* timestamps = GetTsFromUserStateAndEventType(
+      UserState::ENHANCED_PROTECTION, EventType::DATABASE_INTERSTITIAL_BYPASS);
+  EXPECT_EQ(30u, timestamps->GetList().size());
+  EXPECT_TRUE(IsSortedInChronologicalOrder(timestamps));
+
+  task_environment_->FastForwardBy(base::TimeDelta::FromDays(1));
+  metrics_collector_->AddSafeBrowsingEventToPref(
+      EventType::DATABASE_INTERSTITIAL_BYPASS);
+
+  EXPECT_EQ(30u, timestamps->GetList().size());
+  EXPECT_TRUE(IsSortedInChronologicalOrder(timestamps));
+  // The oldest timestamp should be removed.
+  EXPECT_EQ(timestamps->GetList()[0], timestamps->GetList()[1]);
+  // The newest timestamp should be added as the last element.
+  EXPECT_NE(timestamps->GetList()[28], timestamps->GetList()[29]);
+}
+
+TEST_F(SafeBrowsingMetricsCollectorTest,
+       LogEnhancedProtectionDisabledMetrics_GetLastBypassEventType) {
+  base::HistogramTester histograms;
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::ENHANCED_PROTECTION);
+
+  FastForwardAndAddEvent(base::TimeDelta::FromHours(1),
+                         EventType::DATABASE_INTERSTITIAL_BYPASS);
+  FastForwardAndAddEvent(base::TimeDelta::FromHours(1),
+                         EventType::CSD_INTERSITITAL_BYPASS);
+  FastForwardAndAddEvent(base::TimeDelta::FromHours(1),
+                         EventType::DATABASE_INTERSTITIAL_BYPASS);
+  FastForwardAndAddEvent(base::TimeDelta::FromHours(1),
+                         EventType::CSD_INTERSITITAL_BYPASS);
+
+  // Changing enhanced protection to standard protection should log the metric.
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::STANDARD_PROTECTION);
+  histograms.ExpectUniqueSample("SafeBrowsing.EsbDisabled.LastBypassEventType",
+                                /* sample */ EventType::CSD_INTERSITITAL_BYPASS,
+                                /* expected_count */ 1);
+
+  // Changing standard protection to enhanced protection shouldn't log the
+  // metric.
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::ENHANCED_PROTECTION);
+  histograms.ExpectUniqueSample("SafeBrowsing.EsbDisabled.LastBypassEventType",
+                                /* sample */ EventType::CSD_INTERSITITAL_BYPASS,
+                                /* expected_count */ 1);
+
+  // Changing enhanced protection to no protection should log the metric.
+  FastForwardAndAddEvent(base::TimeDelta::FromHours(1),
+                         EventType::REAL_TIME_INTERSTITIAL_BYPASS);
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::NO_SAFE_BROWSING);
+  histograms.ExpectTotalCount("SafeBrowsing.EsbDisabled.LastBypassEventType",
+                              /* expected_count */ 2);
+  histograms.ExpectBucketCount(
+      "SafeBrowsing.EsbDisabled.LastBypassEventType",
+      /* sample */ EventType::REAL_TIME_INTERSTITIAL_BYPASS,
+      /* expected_count */ 1);
+}
+
+TEST_F(SafeBrowsingMetricsCollectorTest,
+       LogEnhancedProtectionDisabledMetrics_NotLoggedIfNoEvent) {
+  base::HistogramTester histograms;
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::ENHANCED_PROTECTION);
+  SetSafeBrowsingState(&pref_service_, SafeBrowsingState::STANDARD_PROTECTION);
+  histograms.ExpectTotalCount("SafeBrowsing.EsbDisabled.LastBypassEventType",
+                              /* expected_count */ 0);
+}
+
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
index 0b6f04b..753a658 100644
--- a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
+++ b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
@@ -11,6 +11,7 @@
 #include "base/bind.h"
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "chrome/browser/download/simple_download_manager_coordinator_factory.h"
 #include "chrome/browser/history/history_service_factory.h"
@@ -38,6 +39,8 @@
 namespace {
 // File suffix for APKs.
 const base::FilePath::CharType kApkSuffix[] = FILE_PATH_LITERAL(".apk");
+// MIME-type for APKs.
+const char kApkMimeType[] = "application/vnd.android.package-archive";
 
 // The number of user gestures to trace back for the referrer chain.
 const int kAndroidTelemetryUserGestureLimit = 2;
@@ -111,6 +114,9 @@
   DCHECK(item->GetTargetFilePath().MatchesExtension(kApkSuffix));
 
   if (item->GetState() == download::DownloadItem::COMPLETE) {
+    base::UmaHistogramBoolean(
+        "SafeBrowsing.AndroidTelemetry.ApkDownload.IsMimeTypeApk",
+        (item->GetMimeType() == kApkMimeType));
     // Download completed. Send report.
     std::unique_ptr<ClientSafeBrowsingReportRequest> report = GetReport(item);
     MaybeSendApkDownloadReport(
@@ -133,7 +139,6 @@
     // how often people download non-APK files.
     return false;
   }
-  // TODO(crbug.com/1173145): Add a metric to check if the MIME type is APK.
 
   if (!IsSafeBrowsingEnabled(*GetPrefs())) {
     RecordApkDownloadTelemetryOutcome(
diff --git a/chrome/browser/sharesheet/sharesheet_service.cc b/chrome/browser/sharesheet/sharesheet_service.cc
index 1094d49..6b2ed32a 100644
--- a/chrome/browser/sharesheet/sharesheet_service.cc
+++ b/chrome/browser/sharesheet/sharesheet_service.cc
@@ -4,11 +4,9 @@
 
 #include "chrome/browser/sharesheet/sharesheet_service.h"
 
-#include <algorithm>
 #include <utility>
 
 #include "base/bind.h"
-#include "base/no_destructor.h"
 #include "base/optional.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -33,16 +31,6 @@
 
 namespace sharesheet {
 
-namespace {
-
-base::string16& GetSelectedApp() {
-  static base::NoDestructor<base::string16> selected_app;
-
-  return *selected_app;
-}
-
-}  // namespace
-
 SharesheetService::SharesheetService(Profile* profile)
     : profile_(profile),
       sharesheet_action_cache_(std::make_unique<SharesheetActionCache>()),
@@ -107,7 +95,14 @@
     delegate->OnActionLaunched();
     share_action->LaunchAction(delegate, share_action_view, std::move(intent));
   } else if (type == TargetType::kApp) {
-    LaunchApp(target_name, std::move(intent));
+    auto launch_source = apps::mojom::LaunchSource::kFromSharesheet;
+    app_service_proxy_->LaunchAppWithIntent(
+        base::UTF16ToUTF8(target_name),
+        apps::GetEventFlags(
+            apps::mojom::LaunchContainer::kLaunchContainerWindow,
+            WindowOpenDisposition::NEW_WINDOW,
+            /*prefer_container=*/true),
+        std::move(intent), launch_source, display::kDefaultDisplayId);
     delegate->CloseSharesheet();
   }
 }
@@ -155,12 +150,6 @@
   return sharesheet_action_cache_->GetVectorIconFromName(display_name);
 }
 
-// static
-void SharesheetService::SetSelectedAppForTesting(
-    const base::string16& target_name) {
-  GetSelectedApp() = target_name;
-}
-
 void SharesheetService::LoadAppIcons(
     std::vector<apps::IntentLaunchInfo> intent_launch_info,
     std::vector<TargetInfo> targets,
@@ -186,17 +175,6 @@
                      std::move(targets), index, std::move(callback)));
 }
 
-void SharesheetService::LaunchApp(const base::string16& target_name,
-                                  apps::mojom::IntentPtr intent) {
-  auto launch_source = apps::mojom::LaunchSource::kFromSharesheet;
-  app_service_proxy_->LaunchAppWithIntent(
-      base::UTF16ToUTF8(target_name),
-      apps::GetEventFlags(apps::mojom::LaunchContainer::kLaunchContainerWindow,
-                          WindowOpenDisposition::NEW_WINDOW,
-                          /*prefer_container=*/true),
-      std::move(intent), launch_source, display::kDefaultDisplayId);
-}
-
 void SharesheetService::OnIconLoaded(
     std::vector<apps::IntentLaunchInfo> intent_launch_info,
     std::vector<TargetInfo> targets,
@@ -222,24 +200,6 @@
                                          apps::mojom::IntentPtr intent,
                                          CloseCallback close_callback,
                                          std::vector<TargetInfo> targets) {
-  // If SetSelectedAppForTesting() has been called, immediately launch the app.
-  const base::string16 selected_app = GetSelectedApp();
-  if (!selected_app.empty()) {
-    SharesheetResult result = SharesheetResult::kCancel;
-    auto iter = std::find_if(targets.begin(), targets.end(),
-                             [selected_app](const auto& target) {
-                               return target.type == TargetType::kApp &&
-                                      target.launch_name == selected_app;
-                             });
-    if (iter != targets.end()) {
-      LaunchApp(selected_app, std::move(intent));
-      result = SharesheetResult::kSuccess;
-    }
-
-    std::move(close_callback).Run(result);
-    return;
-  }
-
   delegate->ShowBubble(std::move(targets), std::move(intent),
                        std::move(close_callback));
 }
diff --git a/chrome/browser/sharesheet/sharesheet_service.h b/chrome/browser/sharesheet/sharesheet_service.h
index 512277d..61af69e 100644
--- a/chrome/browser/sharesheet/sharesheet_service.h
+++ b/chrome/browser/sharesheet/sharesheet_service.h
@@ -79,8 +79,6 @@
   Profile* GetProfile();
   const gfx::VectorIcon* GetVectorIcon(const base::string16& display_name);
 
-  static void SetSelectedAppForTesting(const base::string16& target_name);
-
  private:
   using SharesheetServiceIconLoaderCallback =
       base::OnceCallback<void(std::vector<TargetInfo> targets)>;
@@ -90,9 +88,6 @@
                     size_t index,
                     SharesheetServiceIconLoaderCallback callback);
 
-  void LaunchApp(const base::string16& target_name,
-                 apps::mojom::IntentPtr intent);
-
   void OnIconLoaded(std::vector<apps::IntentLaunchInfo> intent_launch_info,
                     std::vector<TargetInfo> targets,
                     size_t index,
diff --git a/chrome/browser/signin/services/android/BUILD.gn b/chrome/browser/signin/services/android/BUILD.gn
index 1fb1fc41..983b5cba 100644
--- a/chrome/browser/signin/services/android/BUILD.gn
+++ b/chrome/browser/signin/services/android/BUILD.gn
@@ -7,7 +7,6 @@
 generate_jni("jni_headers") {
   sources = [
     "java/src/org/chromium/chrome/browser/signin/services/IdentityServicesProvider.java",
-    "java/src/org/chromium/chrome/browser/signin/services/ProfileDownloader.java",
     "java/src/org/chromium/chrome/browser/signin/services/SigninMetricsUtils.java",
     "java/src/org/chromium/chrome/browser/signin/services/UnifiedConsentServiceBridge.java",
     "java/src/org/chromium/chrome/browser/signin/services/WebSigninBridge.java",
@@ -65,8 +64,8 @@
     "//chrome/browser/profiles/android:java",
     "//chrome/test/android:chrome_java_test_support",
     "//components/signin/core/browser/android:java",
-    "//components/signin/core/browser/android:signin_java_test_support",
     "//components/signin/public/android:java",
+    "//components/signin/public/android:signin_java_test_support",
     "//content/public/test/android:content_java_test_support",
     "//third_party/android_deps:androidx_annotation_annotation_java",
     "//third_party/android_deps:androidx_test_runner_java",
diff --git a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCache.java b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCache.java
index b5b4472f..7f3d29c 100644
--- a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCache.java
+++ b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCache.java
@@ -151,7 +151,7 @@
 
         for (String accountEmail : accountEmails) {
             if (!mCachedProfileData.containsKey(accountEmail)) {
-                ProfileDownloader.get().startFetchingAccountInfoFor(accountEmail, mImageSize);
+                ProfileDownloader.get().startFetchingAccountInfoFor(accountEmail);
             }
         }
     }
diff --git a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDownloader.java b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDownloader.java
index e3d6277..4201db54 100644
--- a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDownloader.java
+++ b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDownloader.java
@@ -4,23 +4,18 @@
 
 package org.chromium.chrome.browser.signin.services;
 
-import android.graphics.Bitmap;
-
 import androidx.annotation.GuardedBy;
 import androidx.annotation.MainThread;
-import androidx.annotation.Px;
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.Log;
 import org.chromium.base.ObserverList;
 import org.chromium.base.ThreadUtils;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.NativeMethods;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.components.signin.AccountTrackerService;
 import org.chromium.components.signin.ProfileDataSource;
 import org.chromium.components.signin.base.AccountInfo;
-import org.chromium.components.signin.base.CoreAccountInfo;
+import org.chromium.components.signin.identitymanager.IdentityManager;
 
 import java.util.ArrayList;
 
@@ -92,11 +87,9 @@
         private static PendingProfileDownloads sPendingProfileDownloads;
 
         private final ArrayList<String> mAccountEmails;
-        private final ArrayList<Integer> mImageSizes;
 
         private PendingProfileDownloads() {
             mAccountEmails = new ArrayList<>();
-            mImageSizes = new ArrayList<>();
         }
 
         static PendingProfileDownloads get() {
@@ -110,78 +103,57 @@
             return sPendingProfileDownloads;
         }
 
-        void pendProfileDownload(String accountEmail, int imageSize) {
+        void pendProfileDownload(String accountEmail) {
             mAccountEmails.add(accountEmail);
-            mImageSizes.add(imageSize);
         }
 
         @Override
         public void onSystemAccountsSeedingComplete() {
-            int numberOfPendingRequests = mAccountEmails.size();
-            while (numberOfPendingRequests > 0) {
-                // Pending requests here must be pre-signin request since SigninManager will wait
-                // system accounts been seeded into AccountTrackerService before finishing sign in.
-                fetchAccountInfo(mAccountEmails.get(0), mImageSizes.get(0));
-                mAccountEmails.remove(0);
-                mImageSizes.remove(0);
-                numberOfPendingRequests--;
+            for (String accountEmail : mAccountEmails) {
+                fetchAccountInfo(accountEmail);
             }
+            mAccountEmails.clear();
         }
 
         @Override
         public void onSystemAccountsChanged() {
             mAccountEmails.clear();
-            mImageSizes.clear();
         }
     }
 
     /**
      * Starts fetching the account information for a given account.
      * @param accountEmail Account email to fetch the information for
-     * @param imageSize Request image side size (in pixels)
      */
-    public void startFetchingAccountInfoFor(String accountEmail, @Px int imageSize) {
+    public void startFetchingAccountInfoFor(String accountEmail) {
         ThreadUtils.assertOnUiThread();
         final Profile profile = Profile.getLastUsedRegularProfile();
         if (IdentityServicesProvider.get()
                         .getAccountTrackerService(profile)
                         .checkAndSeedSystemAccounts()) {
-            fetchAccountInfo(accountEmail, imageSize);
+            fetchAccountInfo(accountEmail);
         } else {
-            PendingProfileDownloads.get().pendProfileDownload(accountEmail, imageSize);
+            PendingProfileDownloads.get().pendProfileDownload(accountEmail);
         }
     }
 
-    @VisibleForTesting
-    @CalledByNative
-    static void onProfileDownloadSuccess(
-            String accountEmail, String fullName, String givenName, Bitmap avatar) {
-        ThreadUtils.assertOnUiThread();
-        ProfileDownloader.get().notifyObservers(
-                new ProfileDataSource.ProfileData(accountEmail, avatar, fullName, givenName));
-    }
-
     @MainThread
-    private static void fetchAccountInfo(String accountEmail, @Px int imageSize) {
-        final Profile profile = Profile.getLastUsedRegularProfile();
+    private static void fetchAccountInfo(String accountEmail) {
+        final IdentityManager identityManager = IdentityServicesProvider.get().getIdentityManager(
+                Profile.getLastUsedRegularProfile());
         final AccountInfo accountInfo =
-                IdentityServicesProvider.get()
-                        .getIdentityManager(profile)
-                        .findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
-                                accountEmail);
+                identityManager.findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
+                        accountEmail);
         if (accountInfo == null) {
             Log.i(TAG, "No AccountInfo available for email:" + accountEmail);
         } else if (accountInfo.getAccountImage() != null) {
-            onProfileDownloadSuccess(accountEmail, accountInfo.getFullName(),
-                    accountInfo.getGivenName(), accountInfo.getAccountImage());
+            ProfileDownloader.get().notifyObservers(
+                    new ProfileDataSource.ProfileData(accountEmail, accountInfo.getAccountImage(),
+                            accountInfo.getFullName(), accountInfo.getGivenName()));
         } else {
-            ProfileDownloaderJni.get().startFetchingAccountInfoFor(profile, accountInfo, imageSize);
+            // Downloads the extended account information(full name, account image, etc) and saves
+            // it on disk for the given Id.
+            identityManager.forceRefreshOfExtendedAccountInfo(accountInfo.getId());
         }
     }
-
-    @NativeMethods
-    interface Natives {
-        void startFetchingAccountInfoFor(
-                Profile profile, CoreAccountInfo coreAccountInfo, int imageSize);
-    }
 }
diff --git a/chrome/browser/signin/services/android/junit/src/org/chromium/chrome/browser/signin/services/ProfileDownloaderTest.java b/chrome/browser/signin/services/android/junit/src/org/chromium/chrome/browser/signin/services/ProfileDownloaderTest.java
index 439d9e5..e0a6a96 100644
--- a/chrome/browser/signin/services/android/junit/src/org/chromium/chrome/browser/signin/services/ProfileDownloaderTest.java
+++ b/chrome/browser/signin/services/android/junit/src/org/chromium/chrome/browser/signin/services/ProfileDownloaderTest.java
@@ -5,7 +5,6 @@
 package org.chromium.chrome.browser.signin.services;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -13,8 +12,6 @@
 
 import android.graphics.Bitmap;
 
-import androidx.annotation.Px;
-
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -28,7 +25,6 @@
 import org.mockito.junit.MockitoRule;
 
 import org.chromium.base.test.BaseRobolectricTestRunner;
-import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.services.ProfileDownloader.PendingProfileDownloads;
 import org.chromium.components.signin.AccountTrackerService;
@@ -44,18 +40,11 @@
 @RunWith(BaseRobolectricTestRunner.class)
 public class ProfileDownloaderTest {
     private static final String ACCOUNT_EMAIL = "test@gmail.com";
-    private static final @Px int IMAGE_SIZE = 64;
-
-    @Rule
-    public final JniMocker mocker = new JniMocker();
 
     @Rule
     public final MockitoRule mMockitoRule = MockitoJUnit.rule();
 
     @Mock
-    private ProfileDownloader.Natives mProfileDownloaderNativeMock;
-
-    @Mock
     private Profile mProfileMock;
 
     @Mock
@@ -75,7 +64,6 @@
 
     @Before
     public void setUp() {
-        mocker.mock(ProfileDownloaderJni.TEST_HOOKS, mProfileDownloaderNativeMock);
         Profile.setLastUsedProfileForTesting(mProfileMock);
         IdentityServicesProvider.setInstanceForTests(mIdentityServicesProviderMock);
         when(mIdentityServicesProviderMock.getAccountTrackerService(mProfileMock))
@@ -94,13 +82,12 @@
         when(mAccountTrackerServiceMock.checkAndSeedSystemAccounts()).thenReturn(false);
 
         ProfileDownloader.get().addObserver(mObserverMock);
-        ProfileDownloader.get().startFetchingAccountInfoFor(ACCOUNT_EMAIL, IMAGE_SIZE);
+        ProfileDownloader.get().startFetchingAccountInfoFor(ACCOUNT_EMAIL);
         final PendingProfileDownloads pendingProfileDownloads =
                 ProfileDownloader.PendingProfileDownloads.get();
 
         verify(mAccountTrackerServiceMock).addSystemAccountsSeededListener(pendingProfileDownloads);
-        verify(mProfileDownloaderNativeMock, never())
-                .startFetchingAccountInfoFor(any(), any(), anyInt());
+        verify(mIdentityManagerMock, never()).forceRefreshOfExtendedAccountInfo(any());
         verify(mObserverMock, never()).onProfileDataUpdated(any());
     }
 
@@ -109,15 +96,14 @@
         when(mAccountTrackerServiceMock.checkAndSeedSystemAccounts()).thenReturn(true);
 
         ProfileDownloader.get().addObserver(mObserverMock);
-        ProfileDownloader.get().startFetchingAccountInfoFor(ACCOUNT_EMAIL, IMAGE_SIZE);
+        ProfileDownloader.get().startFetchingAccountInfoFor(ACCOUNT_EMAIL);
         final PendingProfileDownloads pendingProfileDownloads =
                 ProfileDownloader.PendingProfileDownloads.get();
 
         verify(mAccountTrackerServiceMock).addSystemAccountsSeededListener(pendingProfileDownloads);
         verify(mIdentityManagerMock)
                 .findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(ACCOUNT_EMAIL);
-        verify(mProfileDownloaderNativeMock, never())
-                .startFetchingAccountInfoFor(any(), any(), anyInt());
+        verify(mIdentityManagerMock, never()).forceRefreshOfExtendedAccountInfo(any());
         verify(mObserverMock, never()).onProfileDataUpdated(any());
     }
 
@@ -131,14 +117,13 @@
                 .thenReturn(accountInfo);
 
         ProfileDownloader.get().addObserver(mObserverMock);
-        ProfileDownloader.get().startFetchingAccountInfoFor(ACCOUNT_EMAIL, IMAGE_SIZE);
+        ProfileDownloader.get().startFetchingAccountInfoFor(ACCOUNT_EMAIL);
         final PendingProfileDownloads pendingProfileDownloads =
                 ProfileDownloader.PendingProfileDownloads.get();
         verify(mAccountTrackerServiceMock).addSystemAccountsSeededListener(pendingProfileDownloads);
         verify(mIdentityManagerMock)
                 .findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(ACCOUNT_EMAIL);
-        verify(mProfileDownloaderNativeMock)
-                .startFetchingAccountInfoFor(mProfileMock, accountInfo, IMAGE_SIZE);
+        verify(mIdentityManagerMock).forceRefreshOfExtendedAccountInfo(accountInfo.getId());
         verify(mObserverMock, never()).onProfileDataUpdated(any());
     }
 
@@ -152,14 +137,13 @@
                 .thenReturn(accountInfo);
 
         ProfileDownloader.get().addObserver(mObserverMock);
-        ProfileDownloader.get().startFetchingAccountInfoFor(ACCOUNT_EMAIL, IMAGE_SIZE);
+        ProfileDownloader.get().startFetchingAccountInfoFor(ACCOUNT_EMAIL);
         final PendingProfileDownloads pendingProfileDownloads =
                 ProfileDownloader.PendingProfileDownloads.get();
         verify(mAccountTrackerServiceMock).addSystemAccountsSeededListener(pendingProfileDownloads);
         verify(mIdentityManagerMock)
                 .findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(ACCOUNT_EMAIL);
-        verify(mProfileDownloaderNativeMock, never())
-                .startFetchingAccountInfoFor(any(), any(), anyInt());
+        verify(mIdentityManagerMock, never()).forceRefreshOfExtendedAccountInfo(any());
         verify(mObserverMock).onProfileDataUpdated(mProfileDataCaptor.capture());
         final ProfileData profileData = mProfileDataCaptor.getValue();
         Assert.assertEquals(ACCOUNT_EMAIL, profileData.getAccountEmail());
@@ -167,21 +151,4 @@
         Assert.assertEquals(accountInfo.getGivenName(), profileData.getGivenName());
         Assert.assertEquals(accountInfo.getAccountImage(), profileData.getAvatar());
     }
-
-    @Test
-    public void testOnProfileDownloadSuccess() {
-        final String fullName = "Full name";
-        final String givenName = "Given name";
-        final Bitmap avatar = mock(Bitmap.class);
-
-        ProfileDownloader.get().addObserver(mObserverMock);
-        ProfileDownloader.onProfileDownloadSuccess(ACCOUNT_EMAIL, fullName, givenName, avatar);
-
-        verify(mObserverMock).onProfileDataUpdated(mProfileDataCaptor.capture());
-        final ProfileData profileData = mProfileDataCaptor.getValue();
-        Assert.assertEquals(ACCOUNT_EMAIL, profileData.getAccountEmail());
-        Assert.assertEquals(fullName, profileData.getFullName());
-        Assert.assertEquals(givenName, profileData.getGivenName());
-        Assert.assertEquals(avatar, profileData.getAvatar());
-    }
 }
diff --git a/chrome/browser/signin/ui/android/BUILD.gn b/chrome/browser/signin/ui/android/BUILD.gn
index ea91a54..d505a9fe 100644
--- a/chrome/browser/signin/ui/android/BUILD.gn
+++ b/chrome/browser/signin/ui/android/BUILD.gn
@@ -140,8 +140,8 @@
     "//chrome/test/android:chrome_java_test_support",
     "//components/signin/core/browser:signin_enums_java",
     "//components/signin/core/browser/android:java",
-    "//components/signin/core/browser/android:signin_java_test_support",
     "//components/signin/public/android:java",
+    "//components/signin/public/android:signin_java_test_support",
     "//content/public/android:content_java",
     "//third_party/android_deps:androidx_appcompat_appcompat_java",
     "//third_party/android_deps:androidx_fragment_fragment_java",
@@ -170,8 +170,8 @@
     "//chrome/test/android:chrome_java_test_support",
     "//components/signin/core/browser:signin_enums_java",
     "//components/signin/core/browser/android:java",
-    "//components/signin/core/browser/android:signin_java_test_support",
     "//components/signin/public/android:java",
+    "//components/signin/public/android:signin_java_test_support",
     "//content/public/test/android:content_java_test_support",
     "//third_party/android_deps:androidx_fragment_fragment_java",
     "//third_party/android_deps:androidx_test_runner_java",
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 5b9582b..30a169c5 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -433,8 +433,6 @@
     "//components/feature_engagement",
     "//components/feed:buildflags",
     "//components/feed:feature_list",
-    "//components/feed/content:feed_content",
-    "//components/feed/core:feed_core",
     "//components/feedback",
     "//components/find_in_page",
     "//components/flags_ui",
@@ -619,6 +617,7 @@
       "//chrome/browser/ui/webui/feed_internals:mojo_bindings",
       "//components/browser_ui/util/android",
       "//components/feed/core/common:feed_core_common",
+      "//components/feed/core/shared_prefs:feed_shared_prefs",
       "//components/feed/core/v2:feed_core_v2",
       "//components/infobars/content",
       "//components/query_tiles",
@@ -794,18 +793,12 @@
       "webui/webapks/webapks_ui.cc",
       "webui/webapks/webapks_ui.h",
     ]
-    if (enable_feed_v1 || enable_feed_v2) {
+    if (enable_feed_v2) {
       sources += [
         "webui/feed_internals/feed_internals_ui.cc",
         "webui/feed_internals/feed_internals_ui.h",
       ]
     }
-    if (enable_feed_v1) {
-      sources += [
-        "webui/feed_internals/feed_internals_page_handler.cc",
-        "webui/feed_internals/feed_internals_page_handler.h",
-      ]
-    }
     if (enable_feed_v2) {
       sources += [
         "webui/feed_internals/feedv2_internals_page_handler.cc",
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
index e8466c4..aeb349d 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -2710,16 +2710,6 @@
       <message name="IDS_NTP_LEARN_MORE_ABOUT_SUGGESTED_CONTENT" desc="Text in the footer of the New Tab Page. Part of the text is a link to a help center page where the user can learn more about suggested content.">
         <ph name="BEGIN_LINK">&lt;link&gt;</ph>Learn more<ph name="END_LINK">&lt;/link&gt;</ph> about suggested content
       </message>
-      <if expr="enable_feed_v1">
-        <message name="IDS_NTP_SUGGESTIONS_FETCH_FAILED" desc="Snackbar text shown when the user presses the More button to get more suggestions, but this fails (eg, no internet connectivity).">
-          Can’t get suggestions
-        </message>
-      </if>
-      <if expr="enable_feed_v1">
-        <message name="IDS_NTP_SUGGESTIONS_FETCH_NO_NEW_SUGGESTIONS" desc="Snackbar text shown when the user presses the More button to get more suggestions, the fetch succeeds but provides no new suggestions.">
-          No new suggestions
-        </message>
-      </if>
       <message name="IDS_NTP_MANAGE_MY_ACTIVITY" desc="Content description to manage my activity from the feed header overflow menu.">
         Manage activity
       </message>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb
index 270e8ced..444364a 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb
@@ -451,7 +451,7 @@
 <translation id="4269820728363426813">Copier l'adresse du lien</translation>
 <translation id="4298388696830689168">Sites associés</translation>
 <translation id="4303044213806199882">chrome_screenshot_<ph name="CURRENT_TIMESTAMP_MS" /></translation>
-<translation id="4307992518367153382">Options de base</translation>
+<translation id="4307992518367153382">Paramètres de base</translation>
 <translation id="4314815835985389558">Gérer la synchronisation</translation>
 <translation id="4320177379694898372">Aucune connexion Internet.</translation>
 <translation id="4321739720395210191">Impossible d'ouvrir l'appareil photo. Redémarrez votre appareil et réessayez.</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb
index c076e57..4d39ed86 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb
@@ -929,7 +929,7 @@
 <translation id="7481312909269577407">Багыттоо</translation>
 <translation id="7482656565088326534">Алдын ала көрүү өтмөгү</translation>
 <translation id="7484997419527351112">Сунуштар- өчүк</translation>
-<translation id="7493994139787901920"><ph name="VERSION" /> (Жаңыртылган <ph name="TIME_SINCE_UPDATE" />)</translation>
+<translation id="7493994139787901920"><ph name="VERSION" /> (Жаңырган <ph name="TIME_SINCE_UPDATE" />)</translation>
 <translation id="7494974237137038751">үнөмдөлгөн дайындар</translation>
 <translation id="7498271377022651285">Күтө туруңуз…</translation>
 <translation id="7507207699631365376">Бул кызмат көрсөтүүчүнүн <ph name="BEGIN_LINK" />купуялык саясатын<ph name="END_LINK" /> көрүңүз</translation>
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java
index 46d2345..ab9e0da 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java
@@ -74,7 +74,6 @@
     public boolean onMenuItemClick(MenuItem item) {
         assert !mIsManagedByPolicySupplier.get();
         assert item.getItemId() == ID_SETTINGS;
-        assert mOnMenuClickCallback != null;
 
         mOnMenuClickCallback.onResult(getContext());
         return true;
@@ -95,7 +94,7 @@
     }
 
     private void updateContextMenuListener() {
-        if (!mIsManagedByPolicySupplier.get() && mOnMenuClickCallback != null) {
+        if (!mIsManagedByPolicySupplier.get()) {
             setOnCreateContextMenuListener(this);
         } else {
             setOnCreateContextMenuListener(null);
diff --git a/chrome/browser/ui/apps/chrome_app_delegate.cc b/chrome/browser/ui/apps/chrome_app_delegate.cc
index cebf696..4501d93 100644
--- a/chrome/browser/ui/apps/chrome_app_delegate.cc
+++ b/chrome/browser/ui/apps/chrome_app_delegate.cc
@@ -232,8 +232,8 @@
   zoom::ZoomController::CreateForWebContents(web_contents);
 }
 
-void ChromeAppDelegate::RenderViewCreated(
-    content::RenderViewHost* render_view_host) {
+void ChromeAppDelegate::RenderFrameCreated(
+    content::RenderFrameHost* frame_host) {
   if (!chrome::IsRunningInForcedAppMode()) {
     // Due to a bug in the way apps reacted to default zoom changes, some apps
     // can incorrectly have host level zoom settings. These aren't wanted as
@@ -241,12 +241,16 @@
     // can be made to zoom again.
     // See http://crbug.com/446759 for more details.
     content::WebContents* web_contents =
-        content::WebContents::FromRenderViewHost(render_view_host);
+        content::WebContents::FromRenderFrameHost(frame_host);
     DCHECK(web_contents);
-    content::HostZoomMap* zoom_map =
-        content::HostZoomMap::GetForWebContents(web_contents);
-    DCHECK(zoom_map);
-    zoom_map->SetZoomLevelForHost(web_contents->GetURL().host(), 0);
+
+    // Only do this for the initial main frame.
+    if (frame_host == web_contents->GetMainFrame()) {
+      content::HostZoomMap* zoom_map =
+          content::HostZoomMap::GetForWebContents(web_contents);
+      DCHECK(zoom_map);
+      zoom_map->SetZoomLevelForHost(web_contents->GetURL().host(), 0);
+    }
   }
 }
 
diff --git a/chrome/browser/ui/apps/chrome_app_delegate.h b/chrome/browser/ui/apps/chrome_app_delegate.h
index b9f3d7d..fa96b6f 100644
--- a/chrome/browser/ui/apps/chrome_app_delegate.h
+++ b/chrome/browser/ui/apps/chrome_app_delegate.h
@@ -42,7 +42,7 @@
 
   // extensions::AppDelegate:
   void InitWebContents(content::WebContents* web_contents) override;
-  void RenderViewCreated(content::RenderViewHost* render_view_host) override;
+  void RenderFrameCreated(content::RenderFrameHost* frame_host) override;
   void ResizeWebContents(content::WebContents* web_contents,
                          const gfx::Size& size) override;
   content::WebContents* OpenURLFromTab(
diff --git a/chrome/browser/ui/ash/media_notification_provider_impl_unittest.cc b/chrome/browser/ui/ash/media_notification_provider_impl_unittest.cc
index 575df74..5390afd8a 100644
--- a/chrome/browser/ui/ash/media_notification_provider_impl_unittest.cc
+++ b/chrome/browser/ui/ash/media_notification_provider_impl_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/ash/media_notification_provider_impl.h"
 
 #include "ash/public/cpp/media_notification_provider_observer.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/unguessable_token.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
@@ -16,6 +17,7 @@
 #include "chrome/test/base/testing_profile_manager.h"
 #include "components/session_manager/core/session_manager.h"
 #include "content/public/test/browser_task_environment.h"
+#include "media/base/media_switches.h"
 #include "services/media_session/public/mojom/audio_focus.mojom.h"
 #include "services/media_session/public/mojom/media_session.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -52,6 +54,11 @@
 
   void SetUp() override {
     testing::Test::SetUp();
+
+    // Disable a feature unrelated to the unit test. The use of cast features
+    // requires setting up extra dependencies.
+    feature_list_.InitAndDisableFeature(media::kGlobalMediaControlsForCast);
+
     user_manager_->Initialize();
     CHECK(testing_profile_manager_.SetUp());
 
@@ -109,7 +116,7 @@
 
   MediaNotificationProviderImpl* provider() { return provider_.get(); }
 
-  content::BrowserTaskEnvironment browser_environment;
+  content::BrowserTaskEnvironment browser_environment_;
 
  private:
   session_manager::SessionManager session_manager_;
@@ -117,7 +124,8 @@
       new chromeos::FakeChromeUserManager()};
   TestingProfileManager testing_profile_manager_{
       TestingBrowserProcess::GetGlobal()};
-  views::LayoutProvider layout_provider;
+  views::LayoutProvider layout_provider_;
+  base::test::ScopedFeatureList feature_list_;
 
   std::unique_ptr<MockMediaNotificationProviderObserver> mock_observer_;
   std::unique_ptr<MediaNotificationProviderImpl> provider_;
diff --git a/chrome/browser/ui/ash/network/network_portal_notification_controller.cc b/chrome/browser/ui/ash/network/network_portal_notification_controller.cc
index faed11cb..603ca18 100644
--- a/chrome/browser/ui/ash/network/network_portal_notification_controller.cc
+++ b/chrome/browser/ui/ash/network/network_portal_notification_controller.cc
@@ -149,7 +149,7 @@
   }
 
   // Don't do anything if we're currently activating the device.
-  if (MobileActivator::GetInstance()->RunningActivation())
+  if (ash::MobileActivator::GetInstance()->RunningActivation())
     return;
 
   // Don't do anything if notification for |network| already was
diff --git a/chrome/browser/ui/global_media_controls/media_toolbar_button_controller_unittest.cc b/chrome/browser/ui/global_media_controls/media_toolbar_button_controller_unittest.cc
index 11187bb..2f00936 100644
--- a/chrome/browser/ui/global_media_controls/media_toolbar_button_controller_unittest.cc
+++ b/chrome/browser/ui/global_media_controls/media_toolbar_button_controller_unittest.cc
@@ -7,7 +7,9 @@
 #include <memory>
 
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/unguessable_token.h"
+#include "chrome/browser/media/router/media_router_feature.h"
 #include "chrome/browser/ui/global_media_controls/media_dialog_delegate.h"
 #include "chrome/browser/ui/global_media_controls/media_notification_service.h"
 #include "chrome/browser/ui/global_media_controls/media_session_notification_producer.h"
@@ -88,13 +90,15 @@
  public:
   MediaToolbarButtonControllerTest()
       : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME,
-                          base::test::TaskEnvironment::MainThreadType::UI),
-        service_(&profile_, false) {}
+                          base::test::TaskEnvironment::MainThreadType::UI) {}
   ~MediaToolbarButtonControllerTest() override = default;
 
   void SetUp() override {
-    controller_ =
-        std::make_unique<MediaToolbarButtonController>(&delegate_, &service_);
+    // Disable Media Router, which has many dependencies of its own.
+    feature_list_.InitAndDisableFeature(media_router::kMediaRouter);
+    service_ = std::make_unique<MediaNotificationService>(&profile_, false);
+    controller_ = std::make_unique<MediaToolbarButtonController>(
+        &delegate_, service_.get());
   }
 
   void TearDown() override { controller_.reset(); }
@@ -125,14 +129,14 @@
 
   void SimulateFocusGained(const base::UnguessableToken& id,
                            bool controllable) {
-    service_.media_session_notification_producer_->OnFocusGained(
+    service_->media_session_notification_producer_->OnFocusGained(
         CreateFocusRequest(id, controllable));
   }
 
   void SimulateFocusLost(const base::UnguessableToken& id) {
     AudioFocusRequestStatePtr focus(AudioFocusRequestState::New());
     focus->request_id = id;
-    service_.media_session_notification_producer_->OnFocusLost(
+    service_->media_session_notification_producer_->OnFocusLost(
         std::move(focus));
   }
 
@@ -144,9 +148,9 @@
     // grab the MediaNotificationItem from the MediaNotificationService and
     // set the metadata.
     auto item_itr =
-        service_.media_session_notification_producer_->sessions_.find(
+        service_->media_session_notification_producer_->sessions_.find(
             id.ToString());
-    ASSERT_NE(service_.media_session_notification_producer_->sessions_.end(),
+    ASSERT_NE(service_->media_session_notification_producer_->sessions_.end(),
               item_itr);
 
     media_session::MediaMetadata metadata;
@@ -156,7 +160,7 @@
   }
 
   void SimulateDialogOpened(MockMediaDialogDelegate* delegate) {
-    delegate->Open(&service_);
+    delegate->Open(service_.get());
   }
 
   MockMediaToolbarButtonControllerDelegate& delegate() { return delegate_; }
@@ -165,8 +169,9 @@
   content::BrowserTaskEnvironment task_environment_;
   MockMediaToolbarButtonControllerDelegate delegate_;
   TestingProfile profile_;
-  MediaNotificationService service_;
+  std::unique_ptr<MediaNotificationService> service_;
   std::unique_ptr<MediaToolbarButtonController> controller_;
+  base::test::ScopedFeatureList feature_list_;
 
   DISALLOW_COPY_AND_ASSIGN(MediaToolbarButtonControllerTest);
 };
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
index 0aef06e..c1eda0c 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -499,8 +499,6 @@
   UpdatePasswordFormUsernameAndPassword(username, password,
                                         passwords_data_.form_manager());
 
-  UMA_HISTOGRAM_BOOLEAN("PasswordManager.PasswordSavedWithManualFallback",
-                        BubbleIsManualFallbackForSaving());
   if (GetPasswordFormMetricsRecorder() && BubbleIsManualFallbackForSaving()) {
     GetPasswordFormMetricsRecorder()->RecordDetailedUserAction(
         password_manager::PasswordFormMetricsRecorder::DetailedUserAction::
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
index 0b71f805..f027ad4 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
@@ -487,8 +487,6 @@
   controller()->SavePassword(submitted_form().username_value,
                              submitted_form().password_value);
   ExpectIconAndControllerStateIs(password_manager::ui::MANAGE_STATE);
-  histogram_tester.ExpectUniqueSample(
-      "PasswordManager.PasswordSavedWithManualFallback", false, 1);
 }
 
 TEST_F(ManagePasswordsUIControllerTest, PasswordSavedUKMRecording) {
@@ -1016,8 +1014,6 @@
   controller()->SavePassword(submitted_form().username_value,
                              submitted_form().password_value);
   ExpectIconAndControllerStateIs(password_manager::ui::MANAGE_STATE);
-  histogram_tester.ExpectUniqueSample(
-      "PasswordManager.PasswordSavedWithManualFallback", false, 1);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnBubbleHidden();
 }
@@ -1110,8 +1106,6 @@
     auto* entry = entries[0];
     EXPECT_EQ(source_id, entry->source_id);
 
-    histogram_tester.ExpectUniqueSample(
-        "PasswordManager.PasswordSavedWithManualFallback", true, 1);
     test_ukm_recorder.ExpectEntryMetric(
         entry, UkmEntry::kUser_Action_TriggeredManualFallbackForSavingName, 1u);
   }
diff --git a/chrome/browser/ui/search/search_ipc_router.cc b/chrome/browser/ui/search/search_ipc_router.cc
index 7b7198c..fdc8fc6 100644
--- a/chrome/browser/ui/search/search_ipc_router.cc
+++ b/chrome/browser/ui/search/search_ipc_router.cc
@@ -86,6 +86,7 @@
   if (!IsInInstantProcess(frame) || !is_main_frame) {
     return;
   }
+  client_receiver_->reset();
   client_receiver_->Bind(std::move(receiver));
   embedded_search_client_.reset();
   embedded_search_client_.Bind(std::move(client));
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc b/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc
index 06cb6f8..87e4bd7b 100644
--- a/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc
+++ b/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc
@@ -30,6 +30,7 @@
 #include "ui/views/bubble/bubble_border.h"
 #include "ui/views/focus/focus_manager.h"
 #include "ui/views/layout/fill_layout.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 
 namespace autofill {
 
@@ -38,37 +39,37 @@
       views::EMPHASIS_MEDIUM);
 }
 
-SkColor AutofillPopupBaseView::GetBackgroundColor() {
+SkColor AutofillPopupBaseView::GetBackgroundColor() const {
   return GetNativeTheme()->GetSystemColor(
       ui::NativeTheme::kColorId_DropdownBackgroundColor);
 }
 
-SkColor AutofillPopupBaseView::GetForegroundColor() {
+SkColor AutofillPopupBaseView::GetForegroundColor() const {
   return GetNativeTheme()->GetSystemColor(
       ui::NativeTheme::kColorId_DropdownForegroundColor);
 }
 
-SkColor AutofillPopupBaseView::GetSelectedBackgroundColor() {
+SkColor AutofillPopupBaseView::GetSelectedBackgroundColor() const {
   return GetNativeTheme()->GetSystemColor(
       ui::NativeTheme::kColorId_DropdownSelectedBackgroundColor);
 }
 
-SkColor AutofillPopupBaseView::GetSelectedForegroundColor() {
+SkColor AutofillPopupBaseView::GetSelectedForegroundColor() const {
   return GetNativeTheme()->GetSystemColor(
       ui::NativeTheme::kColorId_DropdownSelectedForegroundColor);
 }
 
-SkColor AutofillPopupBaseView::GetFooterBackgroundColor() {
+SkColor AutofillPopupBaseView::GetFooterBackgroundColor() const {
   return GetNativeTheme()->GetSystemColor(
       ui::NativeTheme::kColorId_BubbleFooterBackground);
 }
 
-SkColor AutofillPopupBaseView::GetSeparatorColor() {
+SkColor AutofillPopupBaseView::GetSeparatorColor() const {
   return GetNativeTheme()->GetSystemColor(
       ui::NativeTheme::kColorId_MenuSeparatorColor);
 }
 
-SkColor AutofillPopupBaseView::GetWarningColor() {
+SkColor AutofillPopupBaseView::GetWarningColor() const {
   return GetNativeTheme()->GetSystemColor(
       ui::NativeTheme::kColorId_AlertSeverityHigh);
 }
@@ -316,4 +317,16 @@
   return delegate_->container_view();
 }
 
+BEGIN_METADATA(AutofillPopupBaseView, views::WidgetDelegateView)
+ADD_READONLY_PROPERTY_METADATA(SkColor, BackgroundColor)
+ADD_READONLY_PROPERTY_METADATA(SkColor, ForegroundColor)
+ADD_READONLY_PROPERTY_METADATA(SkColor, SelectedBackgroundColor)
+ADD_READONLY_PROPERTY_METADATA(SkColor, SelectedForegroundColor)
+ADD_READONLY_PROPERTY_METADATA(SkColor, FooterBackgroundColor)
+ADD_READONLY_PROPERTY_METADATA(SkColor, SeparatorColor)
+ADD_READONLY_PROPERTY_METADATA(SkColor, WarningColor)
+ADD_READONLY_PROPERTY_METADATA(gfx::Rect, WindowBounds)
+ADD_READONLY_PROPERTY_METADATA(gfx::Rect, ContentAreaBounds)
+END_METADATA
+
 }  // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_base_view.h b/chrome/browser/ui/views/autofill/autofill_popup_base_view.h
index 5876a6c4..8d96c3e 100644
--- a/chrome/browser/ui/views/autofill/autofill_popup_base_view.h
+++ b/chrome/browser/ui/views/autofill/autofill_popup_base_view.h
@@ -13,6 +13,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/ui/autofill/autofill_popup_view_delegate.h"
 #include "ui/views/focus/widget_focus_manager.h"
+#include "ui/views/metadata/metadata_header_macros.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
 #include "ui/views/widget/widget_observer.h"
@@ -29,11 +30,16 @@
                               public views::WidgetFocusChangeListener,
                               public views::WidgetObserver {
  public:
+  METADATA_HEADER(AutofillPopupBaseView);
+
   // Consider the input element is |kElementBorderPadding| pixels larger at the
   // top and at the bottom in order to reposition the dropdown, so that it
   // doesn't look too close to the element.
   static const int kElementBorderPadding = 1;
 
+  AutofillPopupBaseView(const AutofillPopupBaseView&) = delete;
+  AutofillPopupBaseView& operator=(const AutofillPopupBaseView&) = delete;
+
   static int GetCornerRadius();
 
   // views::View:
@@ -44,13 +50,13 @@
 
   // Get colors used throughout various popup UIs, based on the current native
   // theme.
-  SkColor GetBackgroundColor();
-  SkColor GetForegroundColor();
-  SkColor GetSelectedBackgroundColor();
-  SkColor GetSelectedForegroundColor();
-  SkColor GetFooterBackgroundColor();
-  SkColor GetSeparatorColor();
-  SkColor GetWarningColor();
+  SkColor GetBackgroundColor() const;
+  SkColor GetForegroundColor() const;
+  SkColor GetSelectedBackgroundColor() const;
+  SkColor GetSelectedForegroundColor() const;
+  SkColor GetFooterBackgroundColor() const;
+  SkColor GetSeparatorColor() const;
+  SkColor GetWarningColor() const;
 
  protected:
   explicit AutofillPopupBaseView(AutofillPopupViewDelegate* delegate,
@@ -120,8 +126,6 @@
   bool is_ax_menu_start_event_fired_ = false;
 
   base::WeakPtrFactory<AutofillPopupBaseView> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(AutofillPopupBaseView);
 };
 
 }  // namespace autofill
diff --git a/chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc b/chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc
index 1adde90..0f31651b 100644
--- a/chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc
+++ b/chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc
@@ -15,6 +15,7 @@
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/native_widget_types.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/views/widget/widget.h"
 
 class EyeDropperView::ViewPositionHandler {
@@ -257,3 +258,8 @@
   // Use the last selected color and notify listener.
   listener_->ColorSelected(selected_color_.value());
 }
+
+BEGIN_METADATA(EyeDropperView, views::WidgetDelegateView)
+ADD_READONLY_PROPERTY_METADATA(gfx::Size, Size)
+ADD_READONLY_PROPERTY_METADATA(float, Diameter)
+END_METADATA
diff --git a/chrome/browser/ui/views/eye_dropper/eye_dropper_view.h b/chrome/browser/ui/views/eye_dropper/eye_dropper_view.h
index 34873f9a..fdc340a2 100644
--- a/chrome/browser/ui/views/eye_dropper/eye_dropper_view.h
+++ b/chrome/browser/ui/views/eye_dropper/eye_dropper_view.h
@@ -15,6 +15,7 @@
 #include "content/public/browser/eye_dropper_listener.h"
 #include "content/public/browser/render_frame_host.h"
 #include "ui/gfx/geometry/point.h"
+#include "ui/views/metadata/metadata_header_macros.h"
 #include "ui/views/widget/widget_delegate.h"
 
 // EyeDropperView is used on Aura platforms and on the Mac before 10.15.
@@ -23,6 +24,7 @@
 class EyeDropperView : public content::EyeDropper,
                        public views::WidgetDelegateView {
  public:
+  METADATA_HEADER(EyeDropperView);
   EyeDropperView(content::RenderFrameHost* frame,
                  content::EyeDropperListener* listener);
   EyeDropperView(const EyeDropperView&) = delete;
diff --git a/chrome/browser/ui/views/frame/test_with_browser_view.h b/chrome/browser/ui/views/frame/test_with_browser_view.h
index 99d2554..23d64f3e 100644
--- a/chrome/browser/ui/views/frame/test_with_browser_view.h
+++ b/chrome/browser/ui/views/frame/test_with_browser_view.h
@@ -8,6 +8,8 @@
 #include <memory>
 
 #include "base/macros.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/media/router/media_router_feature.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 
 class BrowserView;
@@ -18,7 +20,11 @@
 class TestWithBrowserView : public BrowserWithTestWindowTest {
  public:
   template <typename... Args>
-  TestWithBrowserView(Args... args) : BrowserWithTestWindowTest(args...) {}
+  explicit TestWithBrowserView(Args... args)
+      : BrowserWithTestWindowTest(args...) {
+    // Media Router requires the IO thread, which doesn't exist in this setup.
+    feature_list_.InitAndDisableFeature(media_router::kMediaRouter);
+  }
 
   ~TestWithBrowserView() override;
 
@@ -33,6 +39,7 @@
 
  private:
   BrowserView* browser_view_;  // Not owned.
+  base::test::ScopedFeatureList feature_list_;
 
   DISALLOW_COPY_AND_ASSIGN(TestWithBrowserView);
 };
diff --git a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc
index 87e54d90..369c606 100644
--- a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc
+++ b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc
@@ -41,6 +41,7 @@
 #include "ui/views/controls/webview/webview.h"
 #include "ui/views/focus/focus_manager.h"
 #include "ui/views/layout/box_layout.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/views/widget/widget.h"
 
 #if defined(OS_MAC)
@@ -412,3 +413,6 @@
   if (fullscreen == (location_bar_view_->height() > 0))
     Layout();
 }
+
+BEGIN_METADATA(PresentationReceiverWindowView, views::WidgetDelegateView)
+END_METADATA
diff --git a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.h b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.h
index da66aa85..455b542 100644
--- a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.h
+++ b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.h
@@ -19,6 +19,7 @@
 #include "chrome/browser/ui/toolbar/chrome_location_bar_model_delegate.h"
 #include "chrome/browser/ui/views/exclusive_access_bubble_views_context.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
+#include "ui/views/metadata/metadata_header_macros.h"
 #include "ui/views/widget/widget_delegate.h"
 
 class ExclusiveAccessBubbleViews;
@@ -43,8 +44,13 @@
       public ExclusiveAccessBubbleViewsContext,
       public ui::AcceleratorProvider {
  public:
+  METADATA_HEADER(PresentationReceiverWindowView);
   PresentationReceiverWindowView(PresentationReceiverWindowFrame* frame,
                                  PresentationReceiverWindowDelegate* delegate);
+  PresentationReceiverWindowView(const PresentationReceiverWindowView&) =
+      delete;
+  PresentationReceiverWindowView& operator=(
+      const PresentationReceiverWindowView&) = delete;
   ~PresentationReceiverWindowView() final;
 
   void Init();
@@ -130,8 +136,6 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   std::unique_ptr<FullscreenWindowObserver> window_observer_;
 #endif
-
-  DISALLOW_COPY_AND_ASSIGN(PresentationReceiverWindowView);
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_MEDIA_ROUTER_PRESENTATION_RECEIVER_WINDOW_VIEW_H_
diff --git a/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.cc b/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.cc
index 6471539d..43ec85e8 100644
--- a/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.cc
+++ b/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.h"
 
+#include "base/metrics/histogram_functions.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_service_factory.h"
@@ -79,14 +80,18 @@
     : sync_service_(sync_service),
       theme_service_(theme_service),
       show_bubble_callback_(std::move(show_bubble_callback)),
-      suggested_profile_color_(suggested_profile_color) {
+      suggested_profile_color_(suggested_profile_color),
+      observation_start_time_(base::TimeTicks::Now()) {
   DCHECK(sync_service_);
   DCHECK(theme_service_);
   DCHECK(show_bubble_callback_);
 }
 
 ProfileCustomizationBubbleSyncController::
-    ~ProfileCustomizationBubbleSyncController() = default;
+    ~ProfileCustomizationBubbleSyncController() {
+  base::UmaHistogramTimes("Profile.SyncCustomizationBubbleDelay",
+                          base::TimeTicks::Now() - observation_start_time_);
+}
 
 void ProfileCustomizationBubbleSyncController::Init() {
   if (!CanSyncStart(sync_service_)) {
diff --git a/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.h b/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.h
index 2b97d833..fe8619f1 100644
--- a/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.h
+++ b/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.h
@@ -7,6 +7,7 @@
 
 #include "base/callback.h"
 #include "base/scoped_observation.h"
+#include "base/time/time.h"
 #include "chrome/browser/themes/theme_syncable_service.h"
 #include "components/sync/driver/sync_service.h"
 #include "components/sync/driver/sync_service_observer.h"
@@ -80,6 +81,7 @@
   ThemeService* const theme_service_;
   base::OnceCallback<void(bool)> show_bubble_callback_;
   SkColor const suggested_profile_color_;
+  base::TimeTicks observation_start_time_;
 
   base::ScopedObservation<syncer::SyncService, syncer::SyncServiceObserver>
       sync_observation_{this};
diff --git a/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller_unittest.cc b/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller_unittest.cc
index 4908272..7fcce49b 100644
--- a/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller_unittest.cc
+++ b/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.h"
 
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_callback.h"
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_syncable_service.h"
@@ -82,14 +83,13 @@
     fake_theme_service_.DoSetTheme(nullptr, false);
   }
 
-  syncer::TestSyncService* test_sync_service() { return &test_sync_service_; }
-
   void NotifyOnSyncStarted() {
     theme_syncable_service_.NotifyOnSyncStartedForTesting();
   }
 
  protected:
   syncer::TestSyncService test_sync_service_;
+  base::HistogramTester histogram_tester_;
 
  private:
   FakeThemeService fake_theme_service_;
@@ -104,6 +104,7 @@
 
   ApplyColorAndShowBubbleWhenNoValueSynced(show_bubble.Get());
   NotifyOnSyncStarted();
+  histogram_tester_.ExpectTotalCount("Profile.SyncCustomizationBubbleDelay", 1);
 }
 
 TEST_F(ProfileCustomizationBubbleSyncControllerTest,
@@ -114,6 +115,7 @@
   test_sync_service_.SetDisableReasons(
       syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY);
   ApplyColorAndShowBubbleWhenNoValueSynced(show_bubble.Get());
+  histogram_tester_.ExpectTotalCount("Profile.SyncCustomizationBubbleDelay", 1);
 }
 
 TEST_F(ProfileCustomizationBubbleSyncControllerTest,
@@ -124,6 +126,7 @@
   ApplyColorAndShowBubbleWhenNoValueSynced(show_bubble.Get());
   SetSyncedProfileColor();
   NotifyOnSyncStarted();
+  histogram_tester_.ExpectTotalCount("Profile.SyncCustomizationBubbleDelay", 1);
 }
 
 TEST_F(ProfileCustomizationBubbleSyncControllerTest,
@@ -134,6 +137,7 @@
   ApplyColorAndShowBubbleWhenNoValueSynced(show_bubble.Get());
   SetSyncedProfileTheme();
   NotifyOnSyncStarted();
+  histogram_tester_.ExpectTotalCount("Profile.SyncCustomizationBubbleDelay", 1);
 }
 
 TEST_F(ProfileCustomizationBubbleSyncControllerTest,
@@ -144,6 +148,7 @@
   test_sync_service_.SetPassphraseRequired(true);
   ApplyColorAndShowBubbleWhenNoValueSynced(show_bubble.Get());
   test_sync_service_.FireStateChanged();
+  histogram_tester_.ExpectTotalCount("Profile.SyncCustomizationBubbleDelay", 1);
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view.cc b/chrome/browser/ui/views/profiles/profile_picker_view.cc
index 647d481..c9d8cc0 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_picker_view.cc
@@ -70,6 +70,7 @@
 #include "ui/views/controls/webview/webview.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/layout/flex_layout.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/views/view.h"
 #include "ui/views/view_class_properties.h"
 #include "ui/views/widget/widget.h"
@@ -683,7 +684,7 @@
     case IDC_RELOAD_BYPASSING_CACHE:
     case IDC_RELOAD_CLEARING_CACHE: {
       // Sign-in may fail due to connectivity issues, allow reloading.
-      if (IsSigningIn()) {
+      if (GetSigningIn()) {
         new_profile_contents_->GetController().Reload(
             content::ReloadType::BYPASSING_CACHE, true);
       }
@@ -699,7 +700,7 @@
 
 void ProfilePickerView::OnThemeChanged() {
   views::WidgetDelegateView::OnThemeChanged();
-  if (!IsSigningIn())
+  if (!GetSigningIn())
     return;
   UpdateToolbarColor();
 }
@@ -742,7 +743,7 @@
 void ProfilePickerView::NavigationStateChanged(
     content::WebContents* source,
     content::InvalidateTypes changed_flags) {
-  if (IsSigningIn() && IsExternalURL(new_profile_contents_->GetVisibleURL()))
+  if (GetSigningIn() && IsExternalURL(new_profile_contents_->GetVisibleURL()))
     FinishSignedInCreationFlowForSAML();
 }
 
@@ -818,11 +819,11 @@
   // Move from sign-in back to the previous screen of profile creation.
   // Do not load any url because the desired screen is still loaded in
   // `system_profile_contents_`.
-  if (IsSigningIn())
+  if (GetSigningIn())
     ShowScreen(system_profile_contents_.get(), GURL(), /*show_toolbar=*/false);
 }
 
-bool ProfilePickerView::IsSigningIn() const {
+bool ProfilePickerView::GetSigningIn() const {
   return (state_ == kReady || state_ == kFinalizing) && toolbar_->GetVisible();
 }
 
@@ -1086,6 +1087,11 @@
   dialog_host_.DisplayErrorMessage();
 }
 
-base::FilePath ProfilePickerView::GetForceSigninProfilePath() {
+base::FilePath ProfilePickerView::GetForceSigninProfilePath() const {
   return dialog_host_.GetForceSigninProfilePath();
 }
+
+BEGIN_METADATA(ProfilePickerView, views::WidgetDelegateView)
+ADD_READONLY_PROPERTY_METADATA(bool, SigningIn)
+ADD_READONLY_PROPERTY_METADATA(base::FilePath, ForceSigninProfilePath)
+END_METADATA
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view.h b/chrome/browser/ui/views/profiles/profile_picker_view.h
index 34c6372..ae02a4f 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_view.h
+++ b/chrome/browser/ui/views/profiles/profile_picker_view.h
@@ -17,6 +17,7 @@
 #include "content/public/browser/web_contents_delegate.h"
 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
 #include "ui/views/controls/webview/webview.h"
+#include "ui/views/metadata/metadata_header_macros.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget_delegate.h"
 
@@ -40,8 +41,13 @@
                           public ChromeWebModalDialogManagerDelegate,
                           public web_modal::WebContentsModalDialogHost {
  public:
+  METADATA_HEADER(ProfilePickerView);
+
   using BrowserOpenedCallback = base::OnceCallback<void(Browser*)>;
 
+  ProfilePickerView(const ProfilePickerView&) = delete;
+  ProfilePickerView& operator=(const ProfilePickerView&) = delete;
+
   const ui::ThemeProvider* GetThemeProviderForProfileBeingCreated() const;
 
  private:
@@ -140,7 +146,7 @@
   void NavigateBack();
 
   // Checks whether the sign-in flow is in progress.
-  bool IsSigningIn() const;
+  bool GetSigningIn() const;
 
   // Helper functions to deal with the lack of extended account info.
   void SetExtendedAccountInfoTimeoutForTesting(base::TimeDelta timeout);
@@ -184,7 +190,7 @@
 
   // Getter of the path of profile which is selected in profile picker for force
   // signin.
-  base::FilePath GetForceSigninProfilePath();
+  base::FilePath GetForceSigninProfilePath() const;
 
   ScopedKeepAlive keep_alive_;
   State state_ = State::kNotStarted;
@@ -235,8 +241,6 @@
   UserManagerProfileDialogHost dialog_host_;
 
   base::WeakPtrFactory<ProfilePickerView> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(ProfilePickerView);
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_PICKER_VIEW_H_
diff --git a/chrome/browser/ui/views/screen_capture_notification_ui_views.cc b/chrome/browser/ui/views/screen_capture_notification_ui_views.cc
index 1fb4059..a2028db 100644
--- a/chrome/browser/ui/views/screen_capture_notification_ui_views.cc
+++ b/chrome/browser/ui/views/screen_capture_notification_ui_views.cc
@@ -22,6 +22,8 @@
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/link.h"
 #include "ui/views/layout/box_layout.h"
+#include "ui/views/metadata/metadata_header_macros.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
@@ -40,17 +42,27 @@
 const float kWindowAlphaValue = 0.96f;
 
 // A ClientView that overrides NonClientHitTest() so that the whole window area
-// acts as a window caption, except a rect specified using set_client_rect().
+// acts as a window caption, except a rect specified using SetClientRect().
 // ScreenCaptureNotificationUIViews uses this class to make the notification bar
 // draggable.
 class NotificationBarClientView : public views::ClientView {
  public:
+  METADATA_HEADER(NotificationBarClientView);
   NotificationBarClientView(views::Widget* widget, views::View* view)
       : views::ClientView(widget, view) {
   }
-  ~NotificationBarClientView() override {}
+  NotificationBarClientView(const NotificationBarClientView&) = delete;
+  NotificationBarClientView& operator=(const NotificationBarClientView&) =
+      delete;
+  ~NotificationBarClientView() override = default;
 
-  void set_client_rect(const gfx::Rect& rect) { rect_ = rect; }
+  void SetClientRect(const gfx::Rect& rect) {
+    if (rect_ == rect)
+      return;
+    rect_ = rect;
+    OnPropertyChanged(&rect_, views::kPropertyEffectsNone);
+  }
+  gfx::Rect GetClientRect() const { return rect_; }
 
   // views::ClientView:
   int NonClientHitTest(const gfx::Point& point) override {
@@ -65,16 +77,23 @@
 
  private:
   gfx::Rect rect_;
-
-  DISALLOW_COPY_AND_ASSIGN(NotificationBarClientView);
 };
 
+BEGIN_METADATA(NotificationBarClientView, views::ClientView)
+ADD_PROPERTY_METADATA(gfx::Rect, ClientRect)
+END_METADATA
+
 // ScreenCaptureNotificationUI implementation using Views.
 class ScreenCaptureNotificationUIViews : public ScreenCaptureNotificationUI,
                                          public views::WidgetDelegateView,
                                          public views::ViewObserver {
  public:
+  METADATA_HEADER(ScreenCaptureNotificationUIViews);
   explicit ScreenCaptureNotificationUIViews(const base::string16& text);
+  ScreenCaptureNotificationUIViews(const ScreenCaptureNotificationUIViews&) =
+      delete;
+  ScreenCaptureNotificationUIViews& operator=(
+      const ScreenCaptureNotificationUIViews&) = delete;
   ~ScreenCaptureNotificationUIViews() override;
 
   // ScreenCaptureNotificationUI:
@@ -105,8 +124,6 @@
   views::View* source_button_ = nullptr;
   views::View* stop_button_ = nullptr;
   views::View* hide_link_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(ScreenCaptureNotificationUIViews);
 };
 
 ScreenCaptureNotificationUIViews::ScreenCaptureNotificationUIViews(
@@ -253,7 +270,7 @@
   gfx::Rect client_rect = source_button_->bounds();
   client_rect.Union(stop_button_->bounds());
   client_rect.Union(hide_link_->bounds());
-  client_view_->set_client_rect(client_rect);
+  client_view_->SetClientRect(client_rect);
 }
 
 void ScreenCaptureNotificationUIViews::NotifySourceChange() {
@@ -266,6 +283,9 @@
     std::move(stop_callback_).Run();
 }
 
+BEGIN_METADATA(ScreenCaptureNotificationUIViews, views::WidgetDelegateView)
+END_METADATA
+
 }  // namespace
 
 std::unique_ptr<ScreenCaptureNotificationUI>
diff --git a/chrome/browser/ui/web_applications/web_app_file_handling_browsertest.cc b/chrome/browser/ui/web_applications/web_app_file_handling_browsertest.cc
index 40997f7..cddd182 100644
--- a/chrome/browser/ui/web_applications/web_app_file_handling_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_file_handling_browsertest.cc
@@ -53,6 +53,7 @@
   }
 
   void Bind(mojo::ScopedInterfaceEndpointHandle handle) {
+    receiver_.reset();
     receiver_.Bind(
         mojo::PendingAssociatedReceiver<blink::mojom::FileHandlingExpiry>(
             std::move(handle)));
diff --git a/chrome/browser/ui/web_applications/web_share_target_browsertest.cc b/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
index 97a42aa..f38f5bea 100644
--- a/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
@@ -9,7 +9,6 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
@@ -17,9 +16,6 @@
 #include "chrome/browser/apps/app_service/intent_util.h"
 #include "chrome/browser/apps/app_service/launch_utils.h"
 #include "chrome/browser/chromeos/file_manager/path_util.h"
-#include "chrome/browser/sharesheet/sharesheet_service.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/ui/web_applications/web_app_controller_browsertest.h"
 #include "chrome/browser/web_applications/components/app_registrar.h"
@@ -109,23 +105,6 @@
     EXPECT_EQ(expected_url, web_contents->GetVisibleURL());
     return web_contents;
   }
-
-  std::string ExecuteShare(const std::string& script) {
-    const GURL url = embedded_test_server()->GetURL("/webshare/index.html");
-    ui_test_utils::NavigateToURL(browser(), url);
-    content::WebContents* const contents =
-        browser()->tab_strip_model()->GetActiveWebContents();
-    return content::EvalJs(contents, script).ExtractString();
-  }
-
-  content::WebContents* ShareToTarget(const std::string& script) {
-    ui_test_utils::AllBrowserTabAddedWaiter waiter;
-    EXPECT_EQ("share succeeded", ExecuteShare(script));
-
-    content::WebContents* contents = waiter.Wait();
-    EXPECT_TRUE(content::WaitForLoadStop(contents));
-    return contents;
-  }
 };
 
 IN_PROC_BROWSER_TEST_F(WebShareTargetBrowserTest, ShareTextFiles) {
@@ -304,54 +283,4 @@
   EXPECT_EQ(shared_link, ReadTextContent(web_contents, "link"));
 }
 
-IN_PROC_BROWSER_TEST_F(WebShareTargetBrowserTest, ShareToPosterWebApp) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-  const GURL app_url =
-      embedded_test_server()->GetURL("/web_share_target/poster.html");
-  const AppId app_id = web_app::InstallWebAppFromManifest(browser(), app_url);
-  sharesheet::SharesheetService::SetSelectedAppForTesting(
-      base::UTF8ToUTF16(app_id));
-
-  // Poster web app does not accept image shares.
-  EXPECT_EQ("share failed: AbortError: Share canceled",
-            ExecuteShare("share_single_file()"));
-
-  content::WebContents* web_contents = ShareToTarget("share_title()");
-  EXPECT_EQ("Subject", ReadTextContent(web_contents, "headline"));
-
-  web_contents = ShareToTarget("share_url()");
-  EXPECT_EQ("https://example.com/", ReadTextContent(web_contents, "link"));
-}
-
-IN_PROC_BROWSER_TEST_F(WebShareTargetBrowserTest, ShareToChartsWebApp) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-  const GURL app_url =
-      embedded_test_server()->GetURL("/web_share_target/charts.html");
-  const AppId app_id = web_app::InstallWebAppFromManifest(browser(), app_url);
-  sharesheet::SharesheetService::SetSelectedAppForTesting(
-      base::UTF8ToUTF16(app_id));
-
-  content::WebContents* web_contents = ShareToTarget("share_single_file()");
-  EXPECT_EQ("************", ReadTextContent(web_contents, "notes"));
-
-  web_contents = ShareToTarget("share_url()");
-  EXPECT_EQ("https://example.com/", ReadTextContent(web_contents, "link"));
-}
-
-IN_PROC_BROWSER_TEST_F(WebShareTargetBrowserTest, ShareToPartialWild) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-  const GURL app_url =
-      embedded_test_server()->GetURL("/web_share_target/partial-wild.html");
-  const AppId app_id = web_app::InstallWebAppFromManifest(browser(), app_url);
-  sharesheet::SharesheetService::SetSelectedAppForTesting(
-      base::UTF8ToUTF16(app_id));
-
-  // Partial Wild does not accept text shares.
-  EXPECT_EQ("share failed: AbortError: Share canceled",
-            ExecuteShare("share_title()"));
-
-  content::WebContents* web_contents = ShareToTarget("share_single_file()");
-  EXPECT_EQ("************", ReadTextContent(web_contents, "graphs"));
-}
-
 }  // namespace web_app
diff --git a/chrome/browser/ui/webui/app_launcher_page_ui.cc b/chrome/browser/ui/webui/app_launcher_page_ui.cc
index 0cb92fe..c69dc1f4 100644
--- a/chrome/browser/ui/webui/app_launcher_page_ui.cc
+++ b/chrome/browser/ui/webui/app_launcher_page_ui.cc
@@ -117,7 +117,7 @@
       {"page_switcher_same_title", IDS_NEW_TAB_PAGE_SWITCHER_SAME_TITLE},
       {"runonoslogin", IDS_APP_CONTEXT_MENU_RUN_ON_OS_LOGIN},
   };
-  AddLocalizedStringsBulk(source, kLocalizedStrings);
+  source->AddLocalizedStrings(kLocalizedStrings);
 
   PrefService* prefs = GetProfile()->GetPrefs();
   source->AddString(
diff --git a/chrome/browser/ui/webui/certificate_manager_localized_strings_provider.cc b/chrome/browser/ui/webui/certificate_manager_localized_strings_provider.cc
index a35b5c0..e93105e 100644
--- a/chrome/browser/ui/webui/certificate_manager_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/certificate_manager_localized_strings_provider.cc
@@ -105,7 +105,7 @@
     // For A11y.
     {"menu", IDS_MENU},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 }  // namespace certificate_manager
diff --git a/chrome/browser/ui/webui/certificate_viewer_ui.cc b/chrome/browser/ui/webui/certificate_viewer_ui.cc
index c3bd756..5d25922 100644
--- a/chrome/browser/ui/webui/certificate_viewer_ui.cc
+++ b/chrome/browser/ui/webui/certificate_viewer_ui.cc
@@ -46,7 +46,7 @@
       {"certFields", IDS_CERT_DETAILS_CERTIFICATE_FIELDS_LABEL},
       {"certFieldVal", IDS_CERT_DETAILS_CERTIFICATE_FIELD_VALUE_LABEL},
   };
-  AddLocalizedStringsBulk(html_source, kStrings);
+  html_source->AddLocalizedStrings(kStrings);
 
   html_source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::TrustedTypes,
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index e411d99..937c5f8 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -841,11 +841,11 @@
     return &NewWebUI<OfflineInternalsUI>;
   if (url.host_piece() == chrome::kChromeUISnippetsInternalsHost &&
       !profile->IsOffTheRecord()) {
-#if BUILDFLAG(ENABLE_FEED_V1) || BUILDFLAG(ENABLE_FEED_V2)
+#if BUILDFLAG(ENABLE_FEED_V2)
     return &NewWebUI<FeedInternalsUI>;
 #else
     return nullptr;
-#endif  // BUILDFLAG(ENABLE_FEED_V1) || BUILDFLAG(ENABLE_FEED_V2)
+#endif  // BUILDFLAG(ENABLE_FEED_V2)
   }
   if (url.host_piece() == chrome::kChromeUIWebApksHost)
     return &NewWebUI<WebApksUI>;
diff --git a/chrome/browser/ui/webui/chromeos/bluetooth_dialog_localized_strings_provider.cc b/chrome/browser/ui/webui/chromeos/bluetooth_dialog_localized_strings_provider.cc
index c1e8120..df15db2 100644
--- a/chrome/browser/ui/webui/chromeos/bluetooth_dialog_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/chromeos/bluetooth_dialog_localized_strings_provider.cc
@@ -63,7 +63,7 @@
       {"bluetooth_connect_writeNotPermitted",
        IDS_SETTINGS_BLUETOOTH_CONNECT_WRITE_NOT_PERMITTED},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 }  // namespace bluetooth_dialog
diff --git a/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_localized_strings_provider.cc b/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_localized_strings_provider.cc
index 2bf7180..b443320 100644
--- a/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_localized_strings_provider.cc
@@ -103,7 +103,7 @@
 }  //  namespace
 
 void AddLocalizedStrings(content::WebUIDataSource* html_source) {
-  AddLocalizedStringsBulk(html_source, kLocalizedStringsWithoutPlaceholders);
+  html_source->AddLocalizedStrings(kLocalizedStringsWithoutPlaceholders);
 }
 
 void AddLocalizedValuesToBuilder(::login::LocalizedValuesBuilder* builder) {
diff --git a/chrome/browser/ui/webui/chromeos/cellular_setup/mobile_setup_dialog.cc b/chrome/browser/ui/webui/chromeos/cellular_setup/mobile_setup_dialog.cc
index 0cdede0..3f6fc91 100644
--- a/chrome/browser/ui/webui/chromeos/cellular_setup/mobile_setup_dialog.cc
+++ b/chrome/browser/ui/webui/chromeos/cellular_setup/mobile_setup_dialog.cc
@@ -84,7 +84,8 @@
   // crash. Note: IsTryingToQuit can be cancelled on other platforms by the
   // onbeforeunload handler, except on ChromeOS. So IsTryingToQuit is the
   // appropriate check to use here.
-  bool running_activation = MobileActivator::GetInstance()->RunningActivation();
+  bool running_activation =
+      ash::MobileActivator::GetInstance()->RunningActivation();
   NET_LOG(EVENT) << "Closing MobileSetupDialog. Activation running = "
                  << running_activation;
   if (!dialog_window() || !running_activation ||
diff --git a/chrome/browser/ui/webui/chromeos/cellular_setup/mobile_setup_ui.cc b/chrome/browser/ui/webui/chromeos/cellular_setup/mobile_setup_ui.cc
index 3f11e2f..c4480451 100644
--- a/chrome/browser/ui/webui/chromeos/cellular_setup/mobile_setup_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/cellular_setup/mobile_setup_ui.cc
@@ -73,43 +73,45 @@
 const char kNoCellularServiceError[] =
     "$1 is unable to connect at this time due to insufficient coverage.";
 
-bool ActivationErrorRequiresCarrier(MobileActivator::ActivationError error) {
-  return error == MobileActivator::ActivationError::kActivationFailed;
+bool ActivationErrorRequiresCarrier(
+    ash::MobileActivator::ActivationError error) {
+  return error == ash::MobileActivator::ActivationError::kActivationFailed;
 }
 
-base::string16 GetActivationErrorMessage(MobileActivator::ActivationError error,
-                                         const std::string& carrier) {
+base::string16 GetActivationErrorMessage(
+    ash::MobileActivator::ActivationError error,
+    const std::string& carrier) {
   // If the activation error message requires the carrier name, and none was
   // provider, fallback to kNoCellularServiceError.
   if (carrier.empty() && ActivationErrorRequiresCarrier(error)) {
     CHECK(!ActivationErrorRequiresCarrier(
-        MobileActivator::ActivationError::kNoCellularService));
+        ash::MobileActivator::ActivationError::kNoCellularService));
     return GetActivationErrorMessage(
-        MobileActivator::ActivationError::kNoCellularService, carrier);
+        ash::MobileActivator::ActivationError::kNoCellularService, carrier);
   }
 
   switch (error) {
-    case MobileActivator::ActivationError::kNone:
+    case ash::MobileActivator::ActivationError::kNone:
       return base::string16();
-    case MobileActivator::ActivationError::kActivationFailed: {
+    case ash::MobileActivator::ActivationError::kActivationFailed: {
       return base::ReplaceStringPlaceholders(
           base::UTF8ToUTF16(kDefaultActivationError),
           std::vector<base::string16>(
               {ui::GetChromeOSDeviceName(), base::UTF8ToUTF16(carrier)}),
           nullptr);
     }
-    case MobileActivator::ActivationError::kCellularDisabled:
+    case ash::MobileActivator::ActivationError::kCellularDisabled:
       return base::UTF8ToUTF16(kCellularDisabledError);
-    case MobileActivator::ActivationError::kNoCellularDevice:
+    case ash::MobileActivator::ActivationError::kNoCellularDevice:
       return base::UTF8ToUTF16(kNoCellularDeviceError);
-    case MobileActivator::ActivationError::kNoCellularService:
+    case ash::MobileActivator::ActivationError::kNoCellularService:
       return base::ReplaceStringPlaceholders(
           base::UTF8ToUTF16(kNoCellularServiceError),
           ui::GetChromeOSDeviceName(), nullptr);
   }
   NOTREACHED() << "Unexpected activation error";
   return GetActivationErrorMessage(
-      MobileActivator::ActivationError::kActivationFailed, carrier);
+      ash::MobileActivator::ActivationError::kActivationFailed, carrier);
 }
 
 void DataRequestFailed(const std::string& service_path,
@@ -196,7 +198,7 @@
 
 // The handler for Javascript messages related to the "register" view.
 class MobileSetupHandler : public content::WebUIMessageHandler,
-                           public MobileActivator::Observer,
+                           public ash::MobileActivator::Observer,
                            public NetworkStateHandlerObserver {
  public:
   MobileSetupHandler();
@@ -206,11 +208,11 @@
   void RegisterMessages() override;
   void OnJavascriptDisallowed() override;
 
-  // MobileActivator::Observer.
+  // ash::MobileActivator::Observer.
   void OnActivationStateChanged(
       const NetworkState* network,
-      MobileActivator::PlanActivationState new_state,
-      MobileActivator::ActivationError error) override;
+      ash::MobileActivator::PlanActivationState new_state,
+      ash::MobileActivator::ActivationError error) override;
 
  private:
   enum Type {
@@ -373,8 +375,8 @@
 
 void MobileSetupHandler::OnActivationStateChanged(
     const NetworkState* network,
-    MobileActivator::PlanActivationState state,
-    MobileActivator::ActivationError error) {
+    ash::MobileActivator::PlanActivationState state,
+    ash::MobileActivator::ActivationError error) {
   DCHECK_EQ(TYPE_ACTIVATION, type_);
   if (!web_ui())
     return;
@@ -408,8 +410,8 @@
   active_ = false;
 
   if (type_ == TYPE_ACTIVATION) {
-    MobileActivator::GetInstance()->RemoveObserver(this);
-    MobileActivator::GetInstance()->TerminateActivation();
+    ash::MobileActivator::GetInstance()->RemoveObserver(this);
+    ash::MobileActivator::GetInstance()->TerminateActivation();
   } else if (type_ == TYPE_PORTAL_LTE) {
     NetworkHandler::Get()->network_state_handler()->RemoveObserver(this,
                                                                    FROM_HERE);
@@ -449,8 +451,8 @@
   AllowJavascript();
 
   type_ = TYPE_ACTIVATION;
-  MobileActivator::GetInstance()->AddObserver(this);
-  MobileActivator::GetInstance()->InitiateActivation(path.substr(1));
+  ash::MobileActivator::GetInstance()->AddObserver(this);
+  ash::MobileActivator::GetInstance()->InitiateActivation(path.substr(1));
 }
 
 void MobileSetupHandler::HandleSetTransactionStatus(
@@ -467,7 +469,7 @@
   if (!args->GetString(0, &status))
     return;
 
-  MobileActivator::GetInstance()->OnSetTransactionStatus(
+  ash::MobileActivator::GetInstance()->OnSetTransactionStatus(
       base::LowerCaseEqualsASCII(status, kJsApiResultOK));
 }
 
@@ -484,7 +486,7 @@
   if (!args->GetString(0, &result))
     return;
 
-  MobileActivator::GetInstance()->OnPortalLoaded(
+  ash::MobileActivator::GetInstance()->OnPortalLoaded(
       base::LowerCaseEqualsASCII(result, kJsApiResultOK));
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.cc b/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.cc
index 4f923da..dd70cc4 100644
--- a/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.cc
@@ -90,7 +90,7 @@
        IDS_CROSTINI_INSTALLER_USERNAME_NOT_AVAILABLE_ERROR},
       {"customDiskSizeLabel", IDS_CROSTINI_INSTALLER_CUSTOM_DISK_SIZE_LABEL},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
 
   base::string16 device_name = ui::GetChromeOSDeviceName();
 
diff --git a/chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_ui.cc b/chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_ui.cc
index 2268bdbc..cea4b90 100644
--- a/chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_ui.cc
@@ -79,7 +79,7 @@
       {"backupCheckboxMessage", IDS_CROSTINI_UPGRADER_BACKUP_CHECKBOX_MESSAGE},
       {"backupChangeLocation", IDS_CROSTINI_UPGRADER_BACKUP_CHANGE_LOCATION},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
   source->AddString("learnMoreUrl",
                     std::string{chrome::kLinuxAppsLearnMoreURL} +
                         "&b=" + base::SysInfo::GetLsbReleaseBoard());
diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/password_change_ui.cc b/chrome/browser/ui/webui/chromeos/in_session_password_change/password_change_ui.cc
index c6852410..0041449 100644
--- a/chrome/browser/ui/webui/chromeos/in_session_password_change/password_change_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/password_change_ui.cc
@@ -133,7 +133,7 @@
       {"matchError", IDS_PASSWORD_CHANGE_PASSWORDS_DONT_MATCH},
       {"save", IDS_PASSWORD_CHANGE_CONFIRM_SAVE_BUTTON}};
 
-  AddLocalizedStringsBulk(source, kLocalizedStrings);
+  source->AddLocalizedStrings(kLocalizedStrings);
 
   AddSize(source, "", ConfirmPasswordChangeDialog::GetSize(false, false));
   AddSize(source, "Old", ConfirmPasswordChangeDialog::GetSize(true, false));
@@ -177,7 +177,7 @@
   static constexpr webui::LocalizedString kLocalizedStrings[] = {
       {"body", IDS_PASSWORD_EXPIRY_CALL_TO_ACTION_CRITICAL},
       {"button", IDS_OK}};
-  AddLocalizedStringsBulk(source, kLocalizedStrings);
+  source->AddLocalizedStrings(kLocalizedStrings);
 
   source->UseStringsJs();
   source->SetDefaultResource(IDR_URGENT_PASSWORD_EXPIRY_NOTIFICATION_HTML);
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
index 51ddcab..1921e246 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -269,24 +269,25 @@
 }
 
 base::Value MakeSecurityTokenPinDialogParameters(
-    security_token_pin::CodeType code_type,
     bool enable_user_input,
     security_token_pin::ErrorLabel error_label,
     int attempts_left) {
   base::Value params(base::Value::Type::DICTIONARY);
-  params.SetIntKey("codeType", static_cast<int>(code_type));
+
   params.SetBoolKey("enableUserInput", enable_user_input);
-  params.SetIntKey("attemptsLeft", attempts_left);
   params.SetBoolKey("hasError",
                     error_label != security_token_pin::ErrorLabel::kNone);
   params.SetStringKey(
       "formattedError",
       GenerateErrorMessage(error_label, attempts_left, enable_user_input));
-  params.SetStringKey(
-      "formattedAttemptsLeft",
-      base::i18n::MessageFormatter::FormatWithNumberedArgs(
-          l10n_util::GetStringUTF16(IDS_REQUEST_PIN_DIALOG_ATTEMPTS_LEFT),
-          attempts_left));
+  if (attempts_left == -1) {
+    params.SetStringKey("formattedAttemptsLeft", base::string16());
+  } else {
+    params.SetStringKey(
+        "formattedAttemptsLeft",
+        GenerateErrorMessage(security_token_pin::ErrorLabel::kNone,
+                             attempts_left, true));
+  }
   return params;
 }
 
@@ -594,20 +595,6 @@
                IDS_SAML_SECURITY_TOKEN_PIN_DIALOG_TITLE);
   builder->Add("securityTokenPinDialogSubtitle",
                IDS_SAML_SECURITY_TOKEN_PIN_DIALOG_SUBTITLE);
-  builder->Add("securityTokenPinDialogTryAgain",
-               IDS_SAML_SECURITY_TOKEN_PIN_DIALOG_TRY_AGAIN);
-  builder->Add("securityTokenPinDialogAttemptsLeft",
-               IDS_REQUEST_PIN_DIALOG_ATTEMPTS_LEFT);
-  builder->Add("securityTokenPinDialogErrorAttempts",
-               IDS_REQUEST_PIN_DIALOG_ERROR_ATTEMPTS);
-  builder->Add("securityTokenPinDialogUnknownError",
-               IDS_REQUEST_PIN_DIALOG_UNKNOWN_ERROR);
-  builder->Add("securityTokenPinDialogUnknownInvalidPin",
-               IDS_REQUEST_PIN_DIALOG_INVALID_PIN_ERROR);
-  builder->Add("securityTokenPinDialogUnknownInvalidPuk",
-               IDS_REQUEST_PIN_DIALOG_INVALID_PUK_ERROR);
-  builder->Add("securityTokenPinDialogUnknownMaxAttemptsExceeded",
-               IDS_REQUEST_PIN_DIALOG_MAX_ATTEMPTS_EXCEEDED_ERROR);
 }
 
 void GaiaScreenHandler::Initialize() {
@@ -1188,8 +1175,8 @@
       std::move(pin_dialog_closed_callback);
 
   CallJS("login.GaiaSigninScreen.showPinDialog",
-         MakeSecurityTokenPinDialogParameters(code_type, enable_user_input,
-                                              error_label, attempts_left));
+         MakeSecurityTokenPinDialogParameters(enable_user_input, error_label,
+                                              attempts_left));
 }
 
 void GaiaScreenHandler::CloseSecurityTokenPinDialog() {
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc
index df9d873..c4da88cf 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc
+++ b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc
@@ -4,12 +4,15 @@
 
 #include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h"
 
+#include "ash/constants/ash_features.h"
+#include "ash/public/cpp/shelf_config.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/public/cpp/window_backdrop.h"
 #include "ash/public/cpp/window_properties.h"
 #include "base/bind.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/system/sys_info.h"
+#include "chrome/browser/chromeos/login/ui/oobe_dialog_size_utils.h"
 #include "chrome/browser/chromeos/multidevice_setup/multidevice_setup_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -28,8 +31,11 @@
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
+#include "net/base/url_util.h"
 #include "ui/aura/window.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/native_widget_types.h"
 
 namespace chromeos {
@@ -41,6 +47,9 @@
 constexpr int kPreferredDialogHeightPx = 640;
 constexpr int kPreferredDialogWidthPx = 768;
 
+constexpr char kOobeDialogHeightParamKey[] = "dialog-height";
+constexpr char kOobeDialogWidthParamKey[] = "dialog-width";
+
 }  // namespace
 
 // static
@@ -85,23 +94,42 @@
 }
 
 MultiDeviceSetupDialog::MultiDeviceSetupDialog()
-    : SystemWebDialogDelegate(GURL(chrome::kChromeUIMultiDeviceSetupUrl),
-                              base::string16()) {}
+    : SystemWebDialogDelegate(CreateMultiDeviceSetupURL(), base::string16()) {}
 
 MultiDeviceSetupDialog::~MultiDeviceSetupDialog() {
   for (auto& callback : on_close_callbacks_)
     std::move(callback).Run();
 }
 
+GURL MultiDeviceSetupDialog::CreateMultiDeviceSetupURL() {
+  GURL gurl(chrome::kChromeUIMultiDeviceSetupUrl);
+  gfx::Size size;
+  GetDialogSize(&size);
+  gurl = net::AppendQueryParameter(gurl, kOobeDialogHeightParamKey,
+                                   base::NumberToString(size.height()));
+  gurl = net::AppendQueryParameter(gurl, kOobeDialogWidthParamKey,
+                                   base::NumberToString(size.width()));
+  return gurl;
+}
+
 void MultiDeviceSetupDialog::GetDialogSize(gfx::Size* size) const {
-  // Note: The size is calculated once based on the current screen orientation
-  // and is not ever updated. It might be possible to resize the dialog upon
-  // each screen rotation, but https://crbug.com/1030993 prevents this from
-  // working.
-  // TODO(https://crbug.com/1030993): Explore resizing the dialog dynamically.
-  static const gfx::Size dialog_size = ComputeDialogSizeForInternalScreen(
-      gfx::Size(kPreferredDialogWidthPx, kPreferredDialogHeightPx));
-  size->SetSize(dialog_size.width(), dialog_size.height());
+  if (features::IsNewOobeLayoutEnabled()) {
+    const gfx::Size display_size =
+        display::Screen::GetScreen()->GetPrimaryDisplay().size();
+    const bool is_horizontal = display_size.width() > display_size.height();
+    const gfx::Size dialog_size = CalculateOobeDialogSize(
+        display_size, ash::ShelfConfig::Get()->shelf_size(), is_horizontal);
+    size->SetSize(dialog_size.width(), dialog_size.height());
+  } else {
+    // Note: The size is calculated once based on the current screen orientation
+    // and is not ever updated. It might be possible to resize the dialog upon
+    // each screen rotation, but https://crbug.com/1030993 prevents this from
+    // working.
+    // TODO(https://crbug.com/1030993): Explore resizing the dialog dynamically.
+    static const gfx::Size dialog_size = ComputeDialogSizeForInternalScreen(
+        gfx::Size(kPreferredDialogWidthPx, kPreferredDialogHeightPx));
+    size->SetSize(dialog_size.width(), dialog_size.height());
+  }
 }
 
 void MultiDeviceSetupDialog::OnDialogClosed(const std::string& json_retval) {
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h
index eab6f4d..ea362586 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h
+++ b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h
@@ -46,6 +46,8 @@
   void OnDialogClosed(const std::string& json_retval) override;
 
  private:
+  GURL CreateMultiDeviceSetupURL();
+
   static MultiDeviceSetupDialog* current_instance_;
   static gfx::NativeWindow containing_window_;
 
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.cc b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.cc
index b233999..4c5223d 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.cc
@@ -126,7 +126,7 @@
 }  //  namespace
 
 void AddLocalizedStrings(content::WebUIDataSource* html_source) {
-  AddLocalizedStringsBulk(html_source, kLocalizedStringsWithoutPlaceholders);
+  html_source->AddLocalizedStrings(kLocalizedStringsWithoutPlaceholders);
 
   html_source->AddBoolean(
       "phoneHubEnabled",
@@ -136,6 +136,9 @@
       "wifiSyncEnabled",
       base::FeatureList::IsEnabled(chromeos::features::kWifiSyncAndroid));
 
+  html_source->AddBoolean("newLayoutEnabled",
+                          chromeos::features::IsNewOobeLayoutEnabled());
+
   for (const auto& entry : GetLocalizedStringsWithPlaceholders())
     html_source->AddString(entry.name, entry.localized_string);
 }
diff --git a/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc b/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc
index 7ebcf2a..a247bb8 100644
--- a/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.cc
@@ -108,7 +108,7 @@
 }  //  namespace
 
 void AddLocalizedStrings(content::WebUIDataSource* html_source) {
-  AddLocalizedStringsBulk(html_source, kElementLocalizedStrings);
+  html_source->AddLocalizedStrings(kElementLocalizedStrings);
 }
 
 void AddLocalizedValuesToBuilder(::login::LocalizedValuesBuilder* builder) {
@@ -232,7 +232,7 @@
       {"Oncipv4-Netmask", IDS_ONC_IPV4_NETMASK},
       {"Oncipv6-IPAddress", IDS_ONC_IPV6_ADDRESS},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 void AddDetailsLocalizedStrings(content::WebUIDataSource* html_source) {
@@ -344,7 +344,7 @@
       {"networkProxyWpadNone", IDS_SETTINGS_INTERNET_NETWORK_PROXY_WPAD_NONE},
       {"remove", IDS_REMOVE},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 void AddConfigLocalizedStrings(content::WebUIDataSource* html_source) {
@@ -366,7 +366,7 @@
       {"hidePassword", IDS_SETTINGS_PASSWORD_HIDE},
       {"showPassword", IDS_SETTINGS_PASSWORD_SHOW},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean(
       "showHiddenNetworkWarning",
@@ -395,7 +395,7 @@
       {"networkErrorNotHardwareBacked",
        IDS_SETTINGS_INTERNET_NETWORK_REQUIRE_HARDWARE_BACKED},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   // Include Shill errors.
   const char* const shill_errors[] = {
diff --git a/chrome/browser/ui/webui/chromeos/network_ui.cc b/chrome/browser/ui/webui/chromeos/network_ui.cc
index 5c736042..107aa5d 100644
--- a/chrome/browser/ui/webui/chromeos/network_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/network_ui.cc
@@ -23,9 +23,12 @@
 #include "chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h"
 #include "chrome/browser/ui/webui/chromeos/network_logs_message_handler.h"
 #include "chrome/browser/ui/webui/chromeos/onc_import_message_handler.h"
+#include "chrome/browser/ui/webui/webui_util.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/browser_resources.h"
 #include "chrome/grit/generated_resources.h"
+#include "chrome/grit/network_ui_resources.h"
+#include "chrome/grit/network_ui_resources_map.h"
 #include "chromeos/components/network_ui/network_diagnostics_resource_provider.h"
 #include "chromeos/components/network_ui/network_health_resource_provider.h"
 #include "chromeos/network/device_state.h"
@@ -540,17 +543,9 @@
   network_element::AddOncLocalizedStrings(html);
   html->UseStringsJs();
 
-  html->AddResourcePath("network_ui_browser_proxy.html",
-                        IDR_NETWORK_UI_BROWSER_PROXY_HTML);
-  html->AddResourcePath("network_ui_browser_proxy.js",
-                        IDR_NETWORK_UI_BROWSER_PROXY_JS);
-  html->AddResourcePath("network_ui.html", IDR_NETWORK_UI_HTML);
-  html->AddResourcePath("network_ui.js", IDR_NETWORK_UI_JS);
-  html->AddResourcePath("network_state_ui.html", IDR_NETWORK_STATE_UI_HTML);
-  html->AddResourcePath("network_state_ui.js", IDR_NETWORK_STATE_UI_JS);
-  html->AddResourcePath("network_logs_ui.html", IDR_NETWORK_LOGS_UI_HTML);
-  html->AddResourcePath("network_logs_ui.js", IDR_NETWORK_LOGS_UI_JS);
-  html->SetDefaultResource(IDR_NETWORK_UI_PAGE_HTML);
+  webui::SetupWebUIDataSource(
+      html, base::make_span(kNetworkUiResources, kNetworkUiResourcesSize),
+      IDR_NETWORK_UI_NETWORK_HTML);
 
   content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
                                 html);
diff --git a/chrome/browser/ui/webui/chromeos/power_ui.cc b/chrome/browser/ui/webui/chromeos/power_ui.cc
index a5aeea6..9a33cae 100644
--- a/chrome/browser/ui/webui/chromeos/power_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/power_ui.cc
@@ -257,7 +257,7 @@
       {"frequencyStateOccupancyPercentageHeader",
        IDS_ABOUT_POWER_CPU_FREQ_STATE_OCCUPANCY_PERCENTAGE},
   };
-  AddLocalizedStringsBulk(html, kStrings);
+  html->AddLocalizedStrings(kStrings);
 
   html->UseStringsJs();
 
diff --git a/chrome/browser/ui/webui/chromeos/set_time_ui.cc b/chrome/browser/ui/webui/chromeos/set_time_ui.cc
index 2c2e1fd..58950b6 100644
--- a/chrome/browser/ui/webui/chromeos/set_time_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/set_time_ui.cc
@@ -188,7 +188,7 @@
       {"timeLabel", IDS_SET_TIME_TIME_LABEL},
       {"doneButton", IDS_DONE},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
 
   base::DictionaryValue values;
   // List of list of strings: [[ID, name], [ID, name], ...]
diff --git a/chrome/browser/ui/webui/chromeos/slow_ui.cc b/chrome/browser/ui/webui/chromeos/slow_ui.cc
index d2c570f..53df03e1 100644
--- a/chrome/browser/ui/webui/chromeos/slow_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/slow_ui.cc
@@ -51,7 +51,7 @@
       {"slowDescription", IDS_SLOW_DESCRIPTION},
       {"slowWarning", IDS_SLOW_WARNING},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
 
   source->AddResourcePath("slow.js", IDR_SLOW_JS);
   source->AddResourcePath("slow.css", IDR_SLOW_CSS);
diff --git a/chrome/browser/ui/webui/chromeos/smb_shares/smb_shares_localized_strings_provider.cc b/chrome/browser/ui/webui/chromeos/smb_shares/smb_shares_localized_strings_provider.cc
index dc49d9b..272f46f 100644
--- a/chrome/browser/ui/webui/chromeos/smb_shares/smb_shares_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/chromeos/smb_shares/smb_shares_localized_strings_provider.cc
@@ -49,7 +49,7 @@
       {"smbShareDiscoveryMessage",
        IDS_SETTINGS_DOWNLOADS_ADD_SHARE_DISCOVERY_MESSAGE},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 }  // namespace smb_dialog
diff --git a/chrome/browser/ui/webui/components/components_ui.cc b/chrome/browser/ui/webui/components/components_ui.cc
index 1622d0b..cfe77aa 100644
--- a/chrome/browser/ui/webui/components/components_ui.cc
+++ b/chrome/browser/ui/webui/components/components_ui.cc
@@ -58,7 +58,7 @@
       {"statusLabel", IDS_COMPONENTS_STATUS_LABEL},
       {"checkingLabel", IDS_COMPONENTS_CHECKING_LABEL},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
 
   source->AddBoolean(
       "isGuest",
diff --git a/chrome/browser/ui/webui/device_log_ui.cc b/chrome/browser/ui/webui/device_log_ui.cc
index 1e83f02c..ef93850 100644
--- a/chrome/browser/ui/webui/device_log_ui.cc
+++ b/chrome/browser/ui/webui/device_log_ui.cc
@@ -93,7 +93,7 @@
       {"logTypeCameraText", IDS_DEVICE_LOG_TYPE_CAMERA},
       {"logEntryFormat", IDS_DEVICE_LOG_ENTRY},
   };
-  AddLocalizedStringsBulk(html, kStrings);
+  html->AddLocalizedStrings(kStrings);
 
   html->UseStringsJs();
   html->AddResourcePath("device_log_ui.css", IDR_DEVICE_LOG_UI_CSS);
diff --git a/chrome/browser/ui/webui/downloads/downloads_ui.cc b/chrome/browser/ui/webui/downloads/downloads_ui.cc
index f87fdcb1..50d6b9c9 100644
--- a/chrome/browser/ui/webui/downloads/downloads_ui.cc
+++ b/chrome/browser/ui/webui/downloads/downloads_ui.cc
@@ -117,7 +117,7 @@
       {"toastRemovedFromList", IDS_DOWNLOAD_TOAST_REMOVED_FROM_LIST},
       {"undo", IDS_DOWNLOAD_UNDO},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
 
   source->AddLocalizedString("dangerDownloadDesc",
                              IDS_BLOCK_REASON_DANGEROUS_DOWNLOAD);
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc
index 5a0a19b..043c4dd 100644
--- a/chrome/browser/ui/webui/extensions/extensions_ui.cc
+++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -269,7 +269,7 @@
      IDS_EXTENSIONS_KIOSK_DISABLE_BAILOUT_SHORTCUT_WARNING_TITLE},
 #endif
   };
-  AddLocalizedStringsBulk(source, kLocalizedStrings);
+  source->AddLocalizedStrings(kLocalizedStrings);
 
   source->AddString("errorLinesNotShownSingular",
                     l10n_util::GetPluralStringFUTF16(
diff --git a/chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.cc b/chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.cc
deleted file mode 100644
index a14a4f0..0000000
--- a/chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.cc
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.h"
-
-#include <string>
-#include <utility>
-
-#include "base/feature_list.h"
-#include "base/metrics/statistics_recorder.h"
-#include "base/time/time.h"
-#include "chrome/browser/android/feed/feed_debugging_bridge.h"
-#include "chrome/browser/android/feed/feed_lifecycle_bridge.h"
-#include "chrome/browser/ui/webui/feed_internals/feed_internals.mojom.h"
-#include "components/feed/content/feed_host_service.h"
-#include "components/feed/content/feed_offline_host.h"
-#include "components/feed/core/common/pref_names.h"
-#include "components/feed/core/common/user_classifier.h"
-#include "components/feed/core/feed_scheduler_host.h"
-#include "components/feed/core/shared_prefs/pref_names.h"
-#include "components/feed/feed_feature_list.h"
-#include "components/offline_pages/core/prefetch/prefetch_prefs.h"
-#include "components/offline_pages/core/prefetch/suggestions_provider.h"
-#include "components/prefs/pref_service.h"
-#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "mojo/public/cpp/bindings/receiver.h"
-#include "url/gurl.h"
-
-namespace {
-
-const char kFeedHistogramPrefix[] = "ContentSuggestions.Feed.";
-
-// Converts |t| to a delta from the JS epoch, or 0 if |t| is null.
-base::TimeDelta ToJsTimeDelta(base::Time t) {
-  return t.is_null() ? base::TimeDelta() : t - base::Time::UnixEpoch();
-}
-
-std::string TriggerTypeToString(feed::TriggerType* trigger) {
-  if (trigger == nullptr)
-    return "Not set";
-  switch (*trigger) {
-    case feed::TriggerType::kNtpShown:
-      return "NTP Shown";
-    case feed::TriggerType::kForegrounded:
-      return "Foregrounded";
-    case feed::TriggerType::kFixedTimer:
-      return "Fixed Timer";
-  }
-}
-
-}  // namespace
-
-FeedInternalsPageHandler::FeedInternalsPageHandler(
-    mojo::PendingReceiver<feed_internals::mojom::PageHandler> receiver,
-    feed::FeedHostService* feed_host_service,
-    PrefService* pref_service)
-    : receiver_(this, std::move(receiver)),
-      feed_scheduler_host_(feed_host_service->GetSchedulerHost()),
-      feed_offline_host_(feed_host_service->GetOfflineHost()),
-      pref_service_(pref_service) {}
-
-FeedInternalsPageHandler::~FeedInternalsPageHandler() = default;
-
-void FeedInternalsPageHandler::GetGeneralProperties(
-    GetGeneralPropertiesCallback callback) {
-  auto properties = feed_internals::mojom::Properties::New();
-
-  properties->is_feed_enabled = true;
-  properties->is_feed_visible =
-      pref_service_->GetBoolean(feed::prefs::kArticlesListVisible);
-  properties->is_feed_allowed = IsFeedAllowed();
-  properties->is_prefetching_enabled =
-      offline_pages::prefetch_prefs::IsEnabled(pref_service_);
-  properties->feed_fetch_url = feed::GetFeedFetchUrlForDebugging();
-
-  std::move(callback).Run(std::move(properties));
-}
-
-void FeedInternalsPageHandler::GetUserClassifierProperties(
-    GetUserClassifierPropertiesCallback callback) {
-  auto properties = feed_internals::mojom::UserClassifier::New();
-
-  feed::UserClassifier* user_classifier =
-      feed_scheduler_host_->GetUserClassifierForDebugging();
-
-  properties->user_class_description =
-      user_classifier->GetUserClassDescriptionForDebugging();
-  properties->avg_hours_between_views = user_classifier->GetEstimatedAvgTime(
-      feed::UserClassifier::Event::kSuggestionsViewed);
-  properties->avg_hours_between_uses = user_classifier->GetEstimatedAvgTime(
-      feed::UserClassifier::Event::kSuggestionsUsed);
-
-  std::move(callback).Run(std::move(properties));
-}
-
-void FeedInternalsPageHandler::GetLastFetchProperties(
-    GetLastFetchPropertiesCallback callback) {
-  auto properties = feed_internals::mojom::LastFetchProperties::New();
-
-  properties->last_fetch_status =
-      feed_scheduler_host_->GetLastFetchStatusForDebugging();
-  properties->last_fetch_trigger = TriggerTypeToString(
-      feed_scheduler_host_->GetLastFetchTriggerTypeForDebugging());
-  properties->last_fetch_time =
-      ToJsTimeDelta(pref_service_->GetTime(feed::prefs::kLastFetchAttemptTime));
-  properties->refresh_suppress_time = ToJsTimeDelta(
-      feed_scheduler_host_->GetSuppressRefreshesUntilForDebugging());
-  properties->last_bless_nonce =
-      pref_service_->GetString(feed::prefs::kHostOverrideBlessNonce);
-
-  std::move(callback).Run(std::move(properties));
-}
-
-void FeedInternalsPageHandler::ClearUserClassifierProperties() {
-  feed_scheduler_host_->GetUserClassifierForDebugging()
-      ->ClearClassificationForDebugging();
-}
-
-void FeedInternalsPageHandler::ClearCachedDataAndRefreshFeed() {
-  feed::FeedLifecycleBridge::ClearCachedData();
-}
-
-void FeedInternalsPageHandler::RefreshFeed() {
-  feed::TriggerRefreshForDebugging();
-}
-
-void FeedInternalsPageHandler::GetCurrentContent(
-    GetCurrentContentCallback callback) {
-  if (!IsFeedAllowed()) {
-    std::move(callback).Run(
-        std::vector<feed_internals::mojom::SuggestionPtr>());
-    return;
-  }
-
-  feed_offline_host_->GetCurrentArticleSuggestions(base::BindOnce(
-      &FeedInternalsPageHandler::OnGetCurrentArticleSuggestionsDone,
-      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-}
-
-void FeedInternalsPageHandler::OnGetCurrentArticleSuggestionsDone(
-    GetCurrentContentCallback callback,
-    std::vector<offline_pages::PrefetchSuggestion> results) {
-  std::vector<feed_internals::mojom::SuggestionPtr> suggestions;
-
-  for (offline_pages::PrefetchSuggestion result : results) {
-    auto suggestion = feed_internals::mojom::Suggestion::New();
-    suggestion->title = std::move(result.article_title);
-    suggestion->url = std::move(result.article_url);
-    suggestion->publisher_name = std::move(result.article_attribution);
-    suggestion->image_url = std::move(result.thumbnail_url);
-    suggestion->favicon_url = std::move(result.favicon_url);
-
-    suggestions.push_back(std::move(suggestion));
-  }
-
-  std::move(callback).Run(std::move(suggestions));
-}
-
-void FeedInternalsPageHandler::GetFeedProcessScopeDump(
-    GetFeedProcessScopeDumpCallback callback) {
-  std::move(callback).Run(feed::GetFeedProcessScopeDumpForDebugging());
-}
-
-bool FeedInternalsPageHandler::IsFeedAllowed() {
-  return pref_service_->GetBoolean(feed::prefs::kEnableSnippets);
-}
-
-void FeedInternalsPageHandler::GetFeedHistograms(
-    GetFeedHistogramsCallback callback) {
-  std::string log;
-  base::StatisticsRecorder::WriteGraph(kFeedHistogramPrefix, &log);
-  std::move(callback).Run(log);
-}
-
-void FeedInternalsPageHandler::OverrideFeedHost(const GURL& host) {
-  pref_service_->SetString(feed::prefs::kHostOverrideHost,
-                           host.is_valid() ? host.spec() : std::string());
-}
-
-void FeedInternalsPageHandler::OverrideActionUploadEndpoint(
-    const GURL& endpoint_url) {
-  // Not implemented for Feed v1.
-}
-
-void FeedInternalsPageHandler::OverrideFeedStreamData(
-    const std::vector<uint8_t>& data) {
-  // Not implemented for Feed v1.
-}
diff --git a/chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.h b/chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.h
deleted file mode 100644
index 9877243..0000000
--- a/chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_WEBUI_FEED_INTERNALS_FEED_INTERNALS_PAGE_HANDLER_H_
-#define CHROME_BROWSER_UI_WEBUI_FEED_INTERNALS_FEED_INTERNALS_PAGE_HANDLER_H_
-
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/ui/webui/feed_internals/feed_internals.mojom.h"
-#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "mojo/public/cpp/bindings/receiver.h"
-
-class PrefService;
-
-namespace feed {
-class FeedHostService;
-class FeedOfflineHost;
-class FeedSchedulerHost;
-}  // namespace feed
-
-namespace offline_pages {
-struct PrefetchSuggestion;
-}  // namespace offline_pages
-
-// Concrete implementation of feed_internals::mojom::PageHandler.
-class FeedInternalsPageHandler : public feed_internals::mojom::PageHandler {
- public:
-  FeedInternalsPageHandler(
-      mojo::PendingReceiver<feed_internals::mojom::PageHandler> receiver,
-      feed::FeedHostService* feed_host_service,
-      PrefService* pref_service);
-  ~FeedInternalsPageHandler() override;
-
-  // feed_internals::mojom::PageHandler
-  void GetGeneralProperties(GetGeneralPropertiesCallback) override;
-  void GetUserClassifierProperties(
-      GetUserClassifierPropertiesCallback) override;
-  void ClearUserClassifierProperties() override;
-  void GetLastFetchProperties(GetLastFetchPropertiesCallback) override;
-  void ClearCachedDataAndRefreshFeed() override;
-  void RefreshFeed() override;
-  void GetCurrentContent(GetCurrentContentCallback) override;
-  void GetFeedProcessScopeDump(GetFeedProcessScopeDumpCallback) override;
-  void GetFeedHistograms(GetFeedHistogramsCallback) override;
-  void OverrideFeedHost(const GURL& host) override;
-  void OverrideActionUploadEndpoint(const GURL& endpoint_url) override;
-  void OverrideFeedStreamData(const std::vector<uint8_t>& data) override;
-
- private:
-  mojo::Receiver<feed_internals::mojom::PageHandler> receiver_;
-
-  void OnGetCurrentArticleSuggestionsDone(
-      GetCurrentContentCallback callback,
-      std::vector<offline_pages::PrefetchSuggestion> suggestions);
-
-  bool IsFeedAllowed();
-
-  // Services that provide the data and functionality.
-  feed::FeedSchedulerHost* feed_scheduler_host_;
-  feed::FeedOfflineHost* feed_offline_host_;
-  PrefService* pref_service_;
-
-  base::WeakPtrFactory<FeedInternalsPageHandler> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FeedInternalsPageHandler);
-};
-
-#endif  // CHROME_BROWSER_UI_WEBUI_FEED_INTERNALS_FEED_INTERNALS_PAGE_HANDLER_H_
diff --git a/chrome/browser/ui/webui/feed_internals/feed_internals_ui.cc b/chrome/browser/ui/webui/feed_internals/feed_internals_ui.cc
index 1783824..a5c249e 100644
--- a/chrome/browser/ui/webui/feed_internals/feed_internals_ui.cc
+++ b/chrome/browser/ui/webui/feed_internals/feed_internals_ui.cc
@@ -8,7 +8,6 @@
 
 #include "base/bind.h"
 #include "base/feature_list.h"
-#include "chrome/browser/android/feed/feed_host_service_factory.h"
 #include "chrome/browser/android/feed/v2/feed_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/feed_internals/feed_internals.mojom.h"
@@ -19,10 +18,6 @@
 #include "content/public/browser/web_ui_data_source.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 
-#if BUILDFLAG(ENABLE_FEED_V1)
-#include "chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.h"
-#endif
-
 #if BUILDFLAG(ENABLE_FEED_V2)
 #include "chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.h"
 #endif
@@ -47,20 +42,10 @@
 
 void FeedInternalsUI::BindInterface(
     mojo::PendingReceiver<feed_internals::mojom::PageHandler> receiver) {
-#if BUILDFLAG(ENABLE_FEED_V1)
-  if (feed::IsV1Enabled()) {
-    page_handler_ = std::make_unique<FeedInternalsPageHandler>(
-        std::move(receiver),
-        feed::FeedHostServiceFactory::GetForBrowserContext(profile_),
-        profile_->GetPrefs());
-  }
-#endif
 #if BUILDFLAG(ENABLE_FEED_V2)
-  if (feed::IsV2Enabled()) {
-    v2_page_handler_ = std::make_unique<FeedV2InternalsPageHandler>(
-        std::move(receiver),
-        feed::FeedServiceFactory::GetForBrowserContext(profile_),
-        profile_->GetPrefs());
-  }
+  v2_page_handler_ = std::make_unique<FeedV2InternalsPageHandler>(
+      std::move(receiver),
+      feed::FeedServiceFactory::GetForBrowserContext(profile_),
+      profile_->GetPrefs());
 #endif
 }
diff --git a/chrome/browser/ui/webui/feed_internals/feed_internals_ui.h b/chrome/browser/ui/webui/feed_internals/feed_internals_ui.h
index 7af4ddb..fc850b4 100644
--- a/chrome/browser/ui/webui/feed_internals/feed_internals_ui.h
+++ b/chrome/browser/ui/webui/feed_internals/feed_internals_ui.h
@@ -9,7 +9,6 @@
 
 #include "base/macros.h"
 #include "chrome/browser/ui/webui/feed_internals/feed_internals.mojom-forward.h"
-#include "chrome/browser/ui/webui/feed_internals/feed_internals_page_handler.h"
 #include "components/feed/buildflags.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "ui/webui/mojo_web_ui_controller.h"
@@ -36,12 +35,7 @@
 
  private:
   Profile* profile_;
-#if BUILDFLAG(ENABLE_FEED_V1)
-  std::unique_ptr<FeedInternalsPageHandler> page_handler_;
-#endif
-#if BUILDFLAG(ENABLE_FEED_V2)
   std::unique_ptr<FeedV2InternalsPageHandler> v2_page_handler_;
-#endif
   WEB_UI_CONTROLLER_TYPE_DECL();
 
   DISALLOW_COPY_AND_ASSIGN(FeedInternalsUI);
diff --git a/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.cc b/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.cc
index 32e9a9d..aefd7771 100644
--- a/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.cc
+++ b/chrome/browser/ui/webui/feed_internals/feedv2_internals_page_handler.cc
@@ -11,7 +11,6 @@
 #include "base/time/time.h"
 #include "chrome/browser/ui/webui/feed_internals/feed_internals.mojom.h"
 #include "components/feed/core/common/pref_names.h"
-#include "components/feed/core/common/user_classifier.h"
 #include "components/feed/core/proto/v2/ui.pb.h"
 #include "components/feed/core/shared_prefs/pref_names.h"
 #include "components/feed/core/v2/public/feed_service.h"
diff --git a/chrome/browser/ui/webui/history/history_ui.cc b/chrome/browser/ui/webui/history/history_ui.cc
index 4986ef5..c373a03 100644
--- a/chrome/browser/ui/webui/history/history_ui.cc
+++ b/chrome/browser/ui/webui/history/history_ui.cc
@@ -93,7 +93,7 @@
       {"signInPromoDesc", IDS_HISTORY_SIGN_IN_PROMO_DESC},
       {"title", IDS_HISTORY_TITLE},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
 
   source->AddString(
       "sidebarFooter",
diff --git a/chrome/browser/ui/webui/identity_internals_ui.cc b/chrome/browser/ui/webui/identity_internals_ui.cc
index b39cc38..0d6ab3c 100644
--- a/chrome/browser/ui/webui/identity_internals_ui.cc
+++ b/chrome/browser/ui/webui/identity_internals_ui.cc
@@ -187,7 +187,6 @@
 std::string IdentityInternalsUIMessageHandler::GetStatus(
     const extensions::IdentityTokenCacheValue& token_cache_value) {
   switch (token_cache_value.status()) {
-    case extensions::IdentityTokenCacheValue::CACHE_STATUS_ADVICE:
     case extensions::IdentityTokenCacheValue::CACHE_STATUS_REMOTE_CONSENT:
     case extensions::IdentityTokenCacheValue::
         CACHE_STATUS_REMOTE_CONSENT_APPROVED:
diff --git a/chrome/browser/ui/webui/management/management_ui.cc b/chrome/browser/ui/webui/management/management_ui.cc
index 0bff529..946dfdf 100644
--- a/chrome/browser/ui/webui/management/management_ui.cc
+++ b/chrome/browser/ui/webui/management/management_ui.cc
@@ -122,7 +122,7 @@
      IDS_MANAGEMENT_PAGE_VISITED_VISIBLE_DATA},
   };
 
-  AddLocalizedStringsBulk(source, kLocalizedStrings);
+  source->AddLocalizedStrings(kLocalizedStrings);
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   source->AddString("managementDeviceLearnMoreUrl",
diff --git a/chrome/browser/ui/webui/media/webrtc_logs_ui.cc b/chrome/browser/ui/webui/media/webrtc_logs_ui.cc
index a69083d..241faf3 100644
--- a/chrome/browser/ui/webui/media/webrtc_logs_ui.cc
+++ b/chrome/browser/ui/webui/media/webrtc_logs_ui.cc
@@ -76,7 +76,7 @@
       {"noTextLogsMessage", IDS_WEBRTC_LOGS_NO_TEXT_LOGS_MESSAGE},
       {"noEventLogsMessage", IDS_WEBRTC_LOGS_NO_EVENT_LOGS_MESSAGE},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
 
   source->UseStringsJs();
   webui::AddResourcePathsBulk(
diff --git a/chrome/browser/ui/webui/memories/memories_ui.cc b/chrome/browser/ui/webui/memories/memories_ui.cc
index 1461f82e..2b355e73 100644
--- a/chrome/browser/ui/webui/memories/memories_ui.cc
+++ b/chrome/browser/ui/webui/memories/memories_ui.cc
@@ -26,7 +26,7 @@
   static constexpr webui::LocalizedString kStrings[] = {
       {"title", IDS_MEMORIES_PAGE_TITLE},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
 
   webui::SetupWebUIDataSource(
       source, base::make_span(kMemoriesResources, kMemoriesResourcesSize),
diff --git a/chrome/browser/ui/webui/nearby_share/shared_resources.cc b/chrome/browser/ui/webui/nearby_share/shared_resources.cc
index 847b878..8f5363b 100644
--- a/chrome/browser/ui/webui/nearby_share/shared_resources.cc
+++ b/chrome/browser/ui/webui/nearby_share/shared_resources.cc
@@ -118,7 +118,7 @@
        IDS_NEARBY_HIGH_VISIBILITY_TRANSFER_IN_PROGRESS_ERROR},
       {"nearbyShareErrorTransferInProgressDescription",
        IDS_NEARBY_HIGH_VISIBILITY_TRANSFER_IN_PROGRESS_DESCRIPTION}};
-  webui::AddLocalizedStringsBulk(data_source, kLocalizedStrings);
+  data_source->AddLocalizedStrings(kLocalizedStrings);
 
   data_source->AddString("nearbyShareLearnMoreLink",
                          base::ASCIIToUTF16(chrome::kNearbyShareLearnMoreURL));
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
index 9cf3eab7..3bfbbc3 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -226,7 +226,7 @@
       {"modulesCartCartMenuRemoveMerchantToastMessage",
        IDS_NTP_MODULES_CART_CART_MENU_REMOVE_MERCHANT_TOAST_MESSAGE},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
 
   source->AddString("modulesTasksInfo1",
                     l10n_util::GetStringFUTF16(
diff --git a/chrome/browser/ui/webui/policy/policy_ui.cc b/chrome/browser/ui/webui/policy/policy_ui.cc
index 16336b60..dc454eb 100644
--- a/chrome/browser/ui/webui/policy/policy_ui.cc
+++ b/chrome/browser/ui/webui/policy/policy_ui.cc
@@ -75,7 +75,7 @@
 #endif
     {"statusUser", IDS_POLICY_STATUS_USER},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
 
   source->AddResourcePath("policy.css", IDR_POLICY_CSS);
   source->AddResourcePath("policy_base.js", IDR_POLICY_BASE_JS);
diff --git a/chrome/browser/ui/webui/policy/policy_ui_handler.cc b/chrome/browser/ui/webui/policy/policy_ui_handler.cc
index df1a0d2..6de7feb 100644
--- a/chrome/browser/ui/webui/policy/policy_ui_handler.cc
+++ b/chrome/browser/ui/webui/policy/policy_ui_handler.cc
@@ -822,7 +822,7 @@
 
 void PolicyUIHandler::AddCommonLocalizedStringsToSource(
     content::WebUIDataSource* source) {
-  AddLocalizedStringsBulk(source, policy::kPolicySources);
+  source->AddLocalizedStrings(policy::kPolicySources);
 
   static constexpr webui::LocalizedString kStrings[] = {
       {"conflict", IDS_POLICY_LABEL_CONFLICT},
@@ -853,7 +853,7 @@
       {"value", IDS_POLICY_LABEL_VALUE},
       {"sourceDefault", IDS_POLICY_SOURCE_DEFAULT},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
 
   source->UseStringsJs();
 }
diff --git a/chrome/browser/ui/webui/policy_indicator_localized_strings_provider.cc b/chrome/browser/ui/webui/policy_indicator_localized_strings_provider.cc
index 811053aa..c76176e 100644
--- a/chrome/browser/ui/webui/policy_indicator_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/policy_indicator_localized_strings_provider.cc
@@ -40,7 +40,7 @@
      IDS_CONTROLLED_SETTING_CHILD_RESTRICTION},
 #endif
   };
-  AddLocalizedStringsBulk(html_source, localized_strings);
+  html_source->AddLocalizedStrings(localized_strings);
 }
 
 }  // namespace policy_indicator
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
index a04c218..3b6c1a8 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -380,7 +380,7 @@
     {"openingPDFInPreview", IDS_PRINT_PREVIEW_OPENING_PDF_IN_PREVIEW_APP},
 #endif
   };
-  AddLocalizedStringsBulk(source, kLocalizedStrings);
+  source->AddLocalizedStrings(kLocalizedStrings);
 
   source->AddString("gcpCertificateErrorLearnMoreURL",
                     chrome::kCloudPrintCertificateErrorLearnMoreURL);
diff --git a/chrome/browser/ui/webui/settings/chromeos/about_section.cc b/chrome/browser/ui/webui/settings/chromeos/about_section.cc
index 18a2e42..ec99cb4 100644
--- a/chrome/browser/ui/webui/settings/chromeos/about_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/about_section.cc
@@ -277,7 +277,7 @@
     {"aboutReleaseNotesOffline", IDS_SETTINGS_ABOUT_PAGE_RELEASE_NOTES},
     {"aboutShowReleaseNotes", IDS_SETTINGS_ABOUT_PAGE_SHOW_RELEASE_NOTES},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddString("aboutTPMFirmwareUpdateLearnMoreURL",
                          chrome::kTPMFirmwareUpdateLearnMoreURL);
diff --git a/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc b/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc
index cd770efc..062ec7d 100644
--- a/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc
@@ -641,7 +641,7 @@
       {"caretBrowsingSubtitle", IDS_SETTINGS_ENABLE_CARET_BROWSING_SUBTITLE},
       {"cancel", IDS_CANCEL},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddString("a11yLearnMoreUrl",
                          chrome::kChromeAccessibilityHelpURL);
diff --git a/chrome/browser/ui/webui/settings/chromeos/apps_section.cc b/chrome/browser/ui/webui/settings/chromeos/apps_section.cc
index 72dc443..823225d11 100644
--- a/chrome/browser/ui/webui/settings/chromeos/apps_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/apps_section.cc
@@ -132,7 +132,7 @@
       {"appManagementStoragePermissionLabel", IDS_APP_MANAGEMENT_STORAGE},
       {"appManagementUninstallLabel", IDS_APP_MANAGEMENT_UNINSTALL_APP},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 void AddGuestOsStrings(content::WebUIDataSource* html_source) {
@@ -162,7 +162,7 @@
       {"guestOsSharedUsbDevicesReassign",
        IDS_SETTINGS_GUEST_OS_SHARED_USB_DEVICES_REASSIGN},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 bool ShowPluginVm(const Profile* profile, const PrefService& pref_service) {
@@ -210,7 +210,7 @@
       {"appsPageTitle", IDS_SETTINGS_APPS_TITLE},
       {"appManagementTitle", IDS_SETTINGS_APPS_LINK_TEXT},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   // We have 2 variants of Android apps settings. Default case, when the Play
   // Store app exists we show expandable section that allows as to
@@ -326,7 +326,7 @@
        IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_REMOVE},
       {"androidAppsManageAppLinks", IDS_SETTINGS_ANDROID_APPS_MANAGE_APP_LINKS},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
   html_source->AddLocalizedString("androidAppsPageTitle",
                                   arc::IsPlayStoreAvailable()
                                       ? IDS_SETTINGS_ANDROID_APPS_TITLE
@@ -354,7 +354,7 @@
       {"pluginVmPermissionDialogRelaunchButton",
        IDS_SETTINGS_APPS_PLUGIN_VM_PERMISSION_DIALOG_RELAUNCH_BUTTON},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean("showPluginVm",
                           ShowPluginVm(profile(), *pref_service_));
diff --git a/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc b/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc
index 12cc2b0..5cb7ace2 100644
--- a/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc
@@ -190,7 +190,7 @@
       {"bluetoothDeviceType_unknown",
        IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_UNKNOWN},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
   chromeos::bluetooth_dialog::AddLocalizedStrings(html_source);
 }
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc b/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc
index a8abae9..def3354 100644
--- a/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc
@@ -349,7 +349,7 @@
        IDS_SETTINGS_CROSTINI_MIC_DIALOG_SHUTDOWN_BUTTON},
       {"crostiniRemove", IDS_SETTINGS_CROSTINI_REMOVE},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   // Should the crostini section in settings be displayed?
   html_source->AddBoolean(
diff --git a/chrome/browser/ui/webui/settings/chromeos/date_time_section.cc b/chrome/browser/ui/webui/settings/chromeos/date_time_section.cc
index e42ba85d..37705412 100644
--- a/chrome/browser/ui/webui/settings/chromeos/date_time_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/date_time_section.cc
@@ -115,7 +115,7 @@
       {"use24HourClock", IDS_SETTINGS_USE_24_HOUR_CLOCK},
       {"setDateTime", IDS_SETTINGS_SET_DATE_TIME},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddString(
       "timeZoneSettingsLearnMoreURL",
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_section.cc b/chrome/browser/ui/webui/settings/chromeos/device_section.cc
index 3500f58..0b80910 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_section.cc
@@ -521,7 +521,7 @@
        IDS_SETTINGS_KEYBOARD_SHOW_LANGUAGE_AND_INPUT},
       {"keyboardShowInputSettings", IDS_SETTINGS_KEYBOARD_SHOW_INPUT_SETTINGS},
   };
-  AddLocalizedStringsBulk(html_source, keyboard_strings);
+  html_source->AddLocalizedStrings(keyboard_strings);
 
   html_source->AddLocalizedString("keyboardKeySearch",
                                   ui::DeviceUsesKeyboardLayout2()
@@ -553,7 +553,7 @@
        IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_NONE_AVAILABLE},
       {"stylusNoteTakingAppWaitingForAndroid",
        IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_WAITING_FOR_ANDROID}};
-  AddLocalizedStringsBulk(html_source, kStylusStrings);
+  html_source->AddLocalizedStrings(kStylusStrings);
 
   html_source->AddBoolean("hasInternalStylus",
                           ash::stylus_utils::HasInternalStylus());
@@ -642,7 +642,7 @@
        IDS_SETTINGS_DISPLAY_TOUCH_CALIBRATION_TITLE},
       {"displayTouchCalibrationText",
        IDS_SETTINGS_DISPLAY_TOUCH_CALIBRATION_TEXT}};
-  AddLocalizedStringsBulk(html_source, kDisplayStrings);
+  html_source->AddLocalizedStrings(kDisplayStrings);
 
   html_source->AddLocalizedString(
       "displayArrangementText",
@@ -712,7 +712,7 @@
       {"storageExternalStorageListHeader",
        IDS_SETTINGS_STORAGE_EXTERNAL_STORAGE_LIST_HEADER},
       {"storageOverviewAriaLabel", IDS_SETTINGS_STORAGE_OVERVIEW_ARIA_LABEL}};
-  AddLocalizedStringsBulk(html_source, kStorageStrings);
+  html_source->AddLocalizedStrings(kStorageStrings);
 
   html_source->AddBoolean("androidEnabled", is_external_storage_page_available);
 
@@ -750,7 +750,7 @@
       {"powerLidSignOutLabel", IDS_SETTINGS_POWER_LID_CLOSED_SIGN_OUT_LABEL},
       {"powerLidShutDownLabel", IDS_SETTINGS_POWER_LID_CLOSED_SHUT_DOWN_LABEL},
   };
-  AddLocalizedStringsBulk(html_source, kPowerStrings);
+  html_source->AddLocalizedStrings(kPowerStrings);
 }
 
 // Mirrors enum of the same name in enums.xml.
@@ -838,7 +838,7 @@
       {"devicePageTitle", IDS_SETTINGS_DEVICE_TITLE},
       {"touchPadScrollLabel", IDS_OS_SETTINGS_TOUCHPAD_REVERSE_SCROLL_LABEL},
   };
-  AddLocalizedStringsBulk(html_source, kDeviceStrings);
+  html_source->AddLocalizedStrings(kDeviceStrings);
 
   html_source->AddBoolean("isDemoSession",
                           chromeos::DemoSession::IsDeviceInDemoMode());
@@ -1205,7 +1205,7 @@
        IDS_SETTINGS_TOUCHPAD_SCROLL_ACCELERATION_LABEL},
       {"touchpadScrollSpeed", IDS_SETTINGS_TOUCHPAD_SCROLL_SPEED_LABEL},
   };
-  AddLocalizedStringsBulk(html_source, kPointersStrings);
+  html_source->AddLocalizedStrings(kPointersStrings);
 
   html_source->AddString("naturalScrollLearnMoreLink",
                          GetHelpUrlWithBoard(chrome::kNaturalScrollHelpURL));
diff --git a/chrome/browser/ui/webui/settings/chromeos/files_section.cc b/chrome/browser/ui/webui/settings/chromeos/files_section.cc
index 470fe55..75f9d465 100644
--- a/chrome/browser/ui/webui/settings/chromeos/files_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/files_section.cc
@@ -85,7 +85,7 @@
       {"smbShareAddedInvalidSSOURLMessage",
        IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_SSO_URL_MESSAGE},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   chromeos::smb_dialog::AddLocalizedStrings(html_source);
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/internet_section.cc b/chrome/browser/ui/webui/settings/chromeos/internet_section.cc
index 8ff22186b..7f28141 100644
--- a/chrome/browser/ui/webui/settings/chromeos/internet_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/internet_section.cc
@@ -725,7 +725,7 @@
       {"eSimDialogConnectionWarning",
        IDS_SETTINGS_INTERNET_ESIM_DIALOG_CONNECTION_WARNING},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   network_element::AddLocalizedStrings(html_source);
   network_element::AddOncLocalizedStrings(html_source);
diff --git a/chrome/browser/ui/webui/settings/chromeos/kerberos_accounts_handler.cc b/chrome/browser/ui/webui/settings/chromeos/kerberos_accounts_handler.cc
index 98f03c7..06f1ec6 100644
--- a/chrome/browser/ui/webui/settings/chromeos/kerberos_accounts_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/kerberos_accounts_handler.cc
@@ -48,7 +48,7 @@
        IDS_SETTINGS_KERBEROS_ACCOUNTS_SUBMENU_LABEL},
       {"kerberosAccountsPageTitle", IDS_SETTINGS_KERBEROS_ACCOUNTS_PAGE_TITLE},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 // Adds flags related to Kerberos settings visibility and its corresponding
@@ -115,7 +115,7 @@
       {"addKerberosAccount", IDS_SETTINGS_ADD_KERBEROS_ACCOUNT},
       {"refreshKerberosAccount", IDS_SETTINGS_REFRESH_KERBEROS_ACCOUNT},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   PrefService* local_state = g_browser_process->local_state();
 
@@ -154,7 +154,7 @@
        IDS_SETTINGS_KERBEROS_ACCOUNTS_ACCOUNT_REFRESHED_TIP},
       {"kerberosAccountsSignedIn", IDS_SETTINGS_KERBEROS_ACCOUNTS_SIGNED_IN},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   PrefService* local_state = g_browser_process->local_state();
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/languages_section.cc b/chrome/browser/ui/webui/settings/chromeos/languages_section.cc
index c0fbb5a..b28881b43 100644
--- a/chrome/browser/ui/webui/settings/chromeos/languages_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/languages_section.cc
@@ -196,7 +196,7 @@
       {"emojiSuggestionDescription",
        IDS_SETTINGS_SUGGESTIONS_EMOJI_SUGGESTION_DESCRIPTION},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean("allowAssistivePersonalInfo",
                           IsAssistivePersonalInfoAllowed());
@@ -254,7 +254,7 @@
       {"inputMethodOptionsColemakKeyboard",
        IDS_SETTINGS_INPUT_METHOD_OPTIONS_KEYBOARD_COLEMAK},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 void AddLanguagesPageStringsV2(content::WebUIDataSource* html_source) {
@@ -285,7 +285,7 @@
       {"changeDeviceLanguageConfirmButtonLabel",
        IDS_OS_SETTINGS_LANGUAGES_CHANGE_DEVICE_LANGUAGE_CONFIRM_BUTTON_LABEL},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddString(
       "languagesPreferenceDescription",
@@ -342,7 +342,7 @@
       {"noDictionaryWordsLabel",
        IDS_OS_SETTINGS_LANGUAGES_NO_DICTIONARY_WORDS_LABEL},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 }  // namespace
@@ -414,7 +414,7 @@
       {"moveUp", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_MOVE_UP},
       {"noSearchResults", IDS_SEARCH_NO_RESULTS},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
   AddSmartInputsStrings(html_source, IsEmojiSuggestionAllowed());
   AddInputMethodOptionsStrings(html_source);
   AddLanguagesPageStringsV2(html_source);
diff --git a/chrome/browser/ui/webui/settings/chromeos/main_section.cc b/chrome/browser/ui/webui/settings/chromeos/main_section.cc
index 87505d5a..023895cf 100644
--- a/chrome/browser/ui/webui/settings/chromeos/main_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/main_section.cc
@@ -48,7 +48,7 @@
       {"searchResultSelected", IDS_OS_SEARCH_RESULT_ROW_A11Y_RESULT_SELECTED},
       {"clearSearch", IDS_CLEAR_SEARCH},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddString(
       "searchNoOsResultsHelp",
@@ -157,7 +157,7 @@
       {"large", IDS_SETTINGS_LARGE_FONT},
       {"veryLarge", IDS_SETTINGS_VERY_LARGE_FONT},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   // This handler is for chrome://os-settings.
   html_source->AddBoolean("isOSSettings", true);
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc b/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc
index 6ee0a428..3229cc85 100644
--- a/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc
@@ -236,7 +236,7 @@
       {"easyUnlockUnlockDeviceAndAllowSignin",
        IDS_SETTINGS_EASY_UNLOCK_UNLOCK_DEVICE_AND_ALLOW_SIGNIN},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 bool IsOptedIn(multidevice_setup::mojom::HostStatus host_status) {
@@ -350,7 +350,7 @@
       {"multideviceForgetDeviceDisconnect",
        IDS_SETTINGS_MULTIDEVICE_FORGET_THIS_DEVICE_DISCONNECT},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean(
       "multideviceAllowedByPolicy",
diff --git a/chrome/browser/ui/webui/settings/chromeos/on_startup_section.cc b/chrome/browser/ui/webui/settings/chromeos/on_startup_section.cc
index dd22503..21700554 100644
--- a/chrome/browser/ui/webui/settings/chromeos/on_startup_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/on_startup_section.cc
@@ -63,7 +63,7 @@
       {"onStartupDoNotRestore", IDS_OS_SETTINGS_ON_STARTUP_DO_NOT_RESTORE},
   };
 
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean("showStartup", ShouldShowStartup());
 }
diff --git a/chrome/browser/ui/webui/settings/chromeos/people_section.cc b/chrome/browser/ui/webui/settings/chromeos/people_section.cc
index ef48f9d..685ce5b 100644
--- a/chrome/browser/ui/webui/settings/chromeos/people_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/people_section.cc
@@ -382,7 +382,7 @@
       {"accountManagerUnmanagedLabel",
        IDS_SETTINGS_ACCOUNT_MANAGER_MANAGEMENT_STATUS_UNMANAGED_ACCOUNT},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddString("accountManagerLearnMoreUrl",
                          chrome::kAccountManagerLearnMoreURL);
@@ -400,7 +400,7 @@
         {"accountListHeaderChild",
          IDS_SETTINGS_ACCOUNT_MANAGER_LIST_HEADER_CHILD},
     };
-    AddLocalizedStringsBulk(html_source, kLocalizedStringsV2);
+    html_source->AddLocalizedStrings(kLocalizedStringsV2);
 
     html_source->AddString(
         "accountManagerDescription",
@@ -412,7 +412,7 @@
         {"addAccountLabel", IDS_SETTINGS_ACCOUNT_MANAGER_ADD_ACCOUNT_LABEL},
         {"accountListHeader", IDS_SETTINGS_ACCOUNT_MANAGER_LIST_HEADER},
     };
-    AddLocalizedStringsBulk(html_source, kLocalizedStringsV1);
+    html_source->AddLocalizedStrings(kLocalizedStringsV1);
   }
 }
 
@@ -467,7 +467,7 @@
       {"passwordPromptEnterPasswordLoginLock",
        IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_ENTER_PASSWORD_LOGIN_LOCK},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean("quickUnlockEnabled",
                           chromeos::quick_unlock::IsPinEnabled(pref_service));
@@ -492,7 +492,7 @@
       {"lockScreenFingerprintWarning",
        IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_LESS_SECURE},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 void AddFingerprintStrings(content::WebUIDataSource* html_source,
@@ -564,7 +564,7 @@
       {"configureFingerprintImmobile",
        IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_FINGER_IMMOBILE},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 void AddSetupPinDialogStrings(content::WebUIDataSource* html_source) {
@@ -584,7 +584,7 @@
       {"pinKeyboardDeleteAccessibleName",
        IDS_PIN_KEYBOARD_DELETE_ACCESSIBLE_NAME},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   // Format numbers to be used on the pin keyboard.
   for (int j = 0; j <= 9; j++) {
@@ -607,7 +607,7 @@
       {"osSyncTurnOn", IDS_OS_SETTINGS_SYNC_TURN_ON},
       {"osSyncFeatureLabel", IDS_OS_SETTINGS_SYNC_FEATURE_LABEL},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean("splitSettingsSyncEnabled",
                           chromeos::features::IsSplitSettingsSyncEnabled());
@@ -631,7 +631,7 @@
       {"addUsersEmail", IDS_SETTINGS_USERS_ADD_USERS_EMAIL},
       {"userExistsError", IDS_SETTINGS_USER_EXISTS_ERROR},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 void AddParentalControlStrings(content::WebUIDataSource* html_source,
@@ -650,7 +650,7 @@
       {"parentalControlsSetUpButtonRole",
        IDS_SETTINGS_PARENTAL_CONTROLS_SET_UP_BUTTON_ROLE},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean("showParentalControls",
                           are_parental_control_settings_allowed);
@@ -797,7 +797,7 @@
        IDS_SETTINGS_SYNC_SYNC_AND_NON_PERSONALIZED_SERVICES},
       {"syncDisconnectConfirm", IDS_SETTINGS_SYNC_DISCONNECT_CONFIRM},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   user_manager::User* user = ProfileHelper::Get()->GetUserByProfile(profile());
   DCHECK(user);
@@ -819,7 +819,7 @@
         {"osPeoplePageTitle", IDS_OS_SETTINGS_PEOPLE},
         {"accountManagerPageTitle", IDS_SETTINGS_ACCOUNT_MANAGER_PAGE_TITLE},
     };
-    AddLocalizedStringsBulk(html_source, kAccountManagerStrings);
+    html_source->AddLocalizedStrings(kAccountManagerStrings);
   }
 
   // Toggles the Chrome OS Account Manager submenu in the People section.
@@ -839,13 +839,13 @@
         {"syncDisconnectTitle",
          IDS_SETTINGS_TURN_OFF_SYNC_AND_SIGN_OUT_DIALOG_TITLE},
     };
-    AddLocalizedStringsBulk(html_source, kTurnOffStrings);
+    html_source->AddLocalizedStrings(kTurnOffStrings);
   } else {
     static constexpr webui::LocalizedString kSignOutStrings[] = {
         {"syncDisconnect", IDS_SETTINGS_PEOPLE_SIGN_OUT},
         {"syncDisconnectTitle", IDS_SETTINGS_SYNC_DISCONNECT_TITLE},
     };
-    AddLocalizedStringsBulk(html_source, kSignOutStrings);
+    html_source->AddLocalizedStrings(kSignOutStrings);
   }
 
   std::string sync_dashboard_url =
diff --git a/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc b/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc
index 2f5dbf7..1c0359a 100644
--- a/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc
@@ -257,7 +257,7 @@
       {"photoModeAccessibleText", IDS_SETTINGS_PHOTO_MODE_ACCESSIBLE_TEXT},
       {"videoModeAccessibleText", IDS_SETTINGS_VIDEO_MODE_ACCESSIBLE_TEXT},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean(
       "changePictureVideoModeEnabled",
diff --git a/chrome/browser/ui/webui/settings/chromeos/printing_section.cc b/chrome/browser/ui/webui/settings/chromeos/printing_section.cc
index e6c04ed..6e42c80 100644
--- a/chrome/browser/ui/webui/settings/chromeos/printing_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/printing_section.cc
@@ -258,7 +258,7 @@
       {"printServerConfigurationErrorMessage",
        IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_REACHABLE_BUT_CANNOT_ADD},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddString("printingCUPSPrintLearnMoreUrl",
                          GetHelpUrlWithBoard(chrome::kCupsPrintLearnMoreURL));
diff --git a/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc b/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
index 5791f2f..90bf75b6 100644
--- a/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
@@ -197,7 +197,7 @@
       {"enableSuggestedContentDesc",
        IDS_SETTINGS_ENABLE_SUGGESTED_CONTENT_DESC},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean(
       "privacySettingsRedesignEnabled",
diff --git a/chrome/browser/ui/webui/settings/chromeos/reset_section.cc b/chrome/browser/ui/webui/settings/chromeos/reset_section.cc
index c840a79..6800b720 100644
--- a/chrome/browser/ui/webui/settings/chromeos/reset_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/reset_section.cc
@@ -70,7 +70,7 @@
       {"powerwashButtonRoleDescription",
        IDS_SETTINGS_FACTORY_RESET_BUTTON_ROLE},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean("allowPowerwash", IsPowerwashAllowed());
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/search_section.cc b/chrome/browser/ui/webui/settings/chromeos/search_section.cc
index effd253..f591a28 100644
--- a/chrome/browser/ui/webui/settings/chromeos/search_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/search_section.cc
@@ -162,7 +162,7 @@
        IDS_SETTINGS_GOOGLE_ASSISTANT_LAUNCH_WITH_MIC_OPEN_DESCRIPTION},
       {"googleAssistantSettings", IDS_SETTINGS_GOOGLE_ASSISTANT_SETTINGS},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean("hotwordDspAvailable", IsHotwordDspAvailable());
   html_source->AddBoolean("voiceMatchDisabled", !IsVoiceMatchAllowed());
@@ -203,7 +203,7 @@
       {"searchGoogleAssistantOn", IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT_ON},
       {"searchGoogleAssistantOff", IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT_OFF},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   const bool is_assistant_allowed = IsAssistantAllowed();
   html_source->AddBoolean("isAssistantAllowed", is_assistant_allowed);
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index 50bb4acd..cf4406e 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -185,7 +185,7 @@
     {"large", IDS_SETTINGS_LARGE_FONT},
     {"veryLarge", IDS_SETTINGS_VERY_LARGE_FONT},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean(
       "isGuest",
@@ -226,7 +226,7 @@
      IDS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION},
 #endif
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
 #if defined(OS_WIN)
   html_source->AddBoolean("isWindows10OrNewer",
@@ -268,7 +268,7 @@
      IDS_SETTINGS_ABOUT_SEE_OS_SETTINGS_FOR_UPDATE_MESSAGE},
 #endif
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddString("managementPage",
                          ManagementUI::GetManagementPageSubtitle(profile));
@@ -363,7 +363,7 @@
     {"readerMode", IDS_SETTINGS_READER_MODE},
     {"readerModeDescription", IDS_SETTINGS_READER_MODE_DESCRIPTION},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddString("presetZoomFactors",
                          zoom::GetPresetZoomFactorsAsJSON());
@@ -435,7 +435,7 @@
           IDS_CLEAR_BROWSING_DATA_PASSWORDS_NOTICE,
           l10n_util::GetStringUTF16(IDS_PASSWORDS_WEB_LINK)));
 
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 #if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_CHROMEOS_LACROS)
@@ -449,7 +449,7 @@
       {"defaultBrowserError", IDS_SETTINGS_DEFAULT_BROWSER_ERROR},
       {"defaultBrowserSecondary", IDS_SETTINGS_DEFAULT_BROWSER_SECONDARY},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 #endif
 
@@ -462,7 +462,7 @@
       {"openFileTypesAutomatically",
        IDS_SETTINGS_OPEN_FILE_TYPES_AUTOMATICALLY},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 #if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
@@ -531,7 +531,7 @@
        IDS_SETTINGS_RESET_CLEANUP_EXPLANATION_CLEANUP_UNAVAILABLE},
   };
 
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
   const std::string cleanup_learn_more_url =
       google_util::AppendGoogleLocaleParam(
           GURL(chrome::kChromeCleanerLearnMoreURL),
@@ -577,7 +577,7 @@
       {"incompatibleApplicationsDone",
        IDS_SETTINGS_INCOMPATIBLE_APPLICATIONS_DONE},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   // The help URL is provided via Field Trial param. If none is provided, the
   // "Learn How" text is left empty so that no link is displayed.
@@ -621,7 +621,7 @@
      IDS_SETTINGS_RESET_CLEAN_UP_COMPUTER_TRIGGER},
 #endif
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean(
       "showResetProfileBanner",
@@ -658,7 +658,7 @@
       {"noProfileFound", IDS_SETTINGS_IMPORT_NO_PROFILE_FOUND},
       {"importSuccess", IDS_SETTINGS_IMPORT_SUCCESS},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 #endif
 
@@ -718,7 +718,7 @@
      IDS_SETTINGS_LANGUAGES_DICTIONARY_DOWNLOAD_FAILED_HELP},
 #endif
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // Only the Chrome OS help article explains how language order affects website
@@ -781,7 +781,7 @@
       {"onStartupInvalidUrl", IDS_SETTINGS_INVALID_URL},
       {"onStartupUrlTooLong", IDS_SETTINGS_URL_TOOL_LONG},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 bool IsFidoAuthenticationAvailable(autofill::PersonalDataManager* personal_data,
@@ -1113,7 +1113,7 @@
                           base::FeatureList::IsEnabled(
                               autofill::features::kAutofillSaveAndFillVPA));
 
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 void AddSignOutDialogStrings(content::WebUIDataSource* html_source,
@@ -1134,13 +1134,13 @@
         {"syncDisconnectTitle",
          IDS_SETTINGS_TURN_OFF_SYNC_AND_SIGN_OUT_DIALOG_TITLE},
     };
-    AddLocalizedStringsBulk(html_source, kTurnOffStrings);
+    html_source->AddLocalizedStrings(kTurnOffStrings);
   } else {
     static constexpr webui::LocalizedString kSignOutStrings[] = {
         {"syncDisconnect", IDS_SETTINGS_PEOPLE_SIGN_OUT},
         {"syncDisconnectTitle", IDS_SETTINGS_SYNC_DISCONNECT_TITLE},
     };
-    AddLocalizedStringsBulk(html_source, kSignOutStrings);
+    html_source->AddLocalizedStrings(kSignOutStrings);
   }
 
   std::string sync_dashboard_url =
@@ -1158,14 +1158,14 @@
         {"syncDisconnectExplanation",
          IDS_SETTINGS_SYNC_DISCONNECT_AND_SIGN_OUT_EXPLANATION},
     };
-    AddLocalizedStringsBulk(html_source, kSyncDisconnectStrings);
+    html_source->AddLocalizedStrings(kSyncDisconnectStrings);
   } else {
     static constexpr webui::LocalizedString kSyncDisconnectStrings[] = {
         {"syncDisconnectDeleteProfile",
          IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE},
         {"syncDisconnectConfirm", IDS_SETTINGS_SYNC_DISCONNECT_CONFIRM},
     };
-    AddLocalizedStringsBulk(html_source, kSyncDisconnectStrings);
+    html_source->AddLocalizedStrings(kSyncDisconnectStrings);
 
     html_source->AddString(
         "syncDisconnectExplanation",
@@ -1224,7 +1224,7 @@
     {"deleteProfileWarningWithoutCounts",
      IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITHOUT_COUNTS},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   // Add Google Account URL and include UTM parameter to signal the source of
   // the navigation.
@@ -1390,7 +1390,7 @@
       {"networkPredictionEnabledDescCookiesPage",
        IDS_SETTINGS_NETWORK_PREDICTION_ENABLED_DESC_COOKIES_PAGE},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddString("cookiesSettingsHelpCenterURL",
                          chrome::kCookiesSettingsHelpCenterURL);
@@ -1440,7 +1440,7 @@
   static constexpr webui::LocalizedString kLocalizedStrings[] = {
       {"privacySandboxTitle", IDS_SETTINGS_PRIVACY_SANDBOX_TITLE},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   // Strings that only need to be available when the flag is enabled.
   if (PrivacySandboxSettingsFactory::GetForProfile(profile)
@@ -1449,7 +1449,7 @@
         {"privacySandboxPageHeading",
          IDS_SETTINGS_PRIVACY_SANDBOX_PAGE_HEADING},
     };
-    AddLocalizedStringsBulk(html_source, kLocalizedStringsBehindFlag);
+    html_source->AddLocalizedStrings(kLocalizedStringsBehindFlag);
 
     html_source->AddString("privacySandboxURL", chrome::kPrivacySandboxURL);
   }
@@ -1499,7 +1499,7 @@
      IDS_SETTINGS_SAFETY_CHECK_CHROME_CLEANER_BUTTON_ARIA_LABEL},
 #endif  // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 void AddSearchInSettingsStrings(content::WebUIDataSource* html_source) {
@@ -1509,7 +1509,7 @@
       {"searchResults", IDS_SEARCH_RESULTS},
       {"clearSearch", IDS_CLEAR_SEARCH},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   base::string16 help_text = l10n_util::GetStringFUTF16(
       IDS_SETTINGS_SEARCH_NO_RESULTS_HELP,
@@ -1523,7 +1523,7 @@
       {"searchPageTitle", IDS_SETTINGS_SEARCH},
       {"searchExplanation", IDS_SETTINGS_SEARCH_EXPLANATION},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddString("searchExplanationLearnMoreURL",
                          base::ASCIIToUTF16(chrome::kOmniboxLearnMoreURL));
@@ -1554,7 +1554,7 @@
       {"searchEnginesManageExtension",
        IDS_SETTINGS_SEARCH_ENGINES_MANAGE_EXTENSION},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
@@ -2266,7 +2266,7 @@
     {"siteSettingsIdleDetectionBlock",
      IDS_SETTINGS_SITE_SETTINGS_IDLE_DETECTION_BLOCK},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   // These ones cannot be constexpr because we need to check base::FeatureList.
   static webui::LocalizedString kSensorsLocalizedStrings[] = {
@@ -2287,7 +2287,7 @@
            ? IDS_SETTINGS_SITE_SETTINGS_SENSORS_BLOCK
            : IDS_SETTINGS_SITE_SETTINGS_MOTION_SENSORS_BLOCK},
   };
-  AddLocalizedStringsBulk(html_source, kSensorsLocalizedStrings);
+  html_source->AddLocalizedStrings(kSensorsLocalizedStrings);
 
   html_source->AddBoolean(
       "enableSafeBrowsingSubresourceFilter",
@@ -2339,7 +2339,7 @@
      IDS_SETTINGS_SYSTEM_HARDWARE_ACCELERATION_LABEL},
     {"proxySettingsLabel", IDS_SETTINGS_SYSTEM_PROXY_SETTINGS_LABEL},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddString(
       "proxySettingsExtensionLabel",
@@ -2460,7 +2460,7 @@
       {"securityKeysSamePINAsCurrent",
        IDS_SETTINGS_SECURITY_KEYS_SAME_PIN_AS_CURRENT},
   };
-  AddLocalizedStringsBulk(html_source, kSecurityKeysStrings);
+  html_source->AddLocalizedStrings(kSecurityKeysStrings);
   bool win_native_api_available = false;
 #if defined(OS_WIN)
   win_native_api_available =
diff --git a/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc
index a843dd4..f40dd4e7 100644
--- a/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc
@@ -87,7 +87,7 @@
       {"captionsEnableLiveCaptionSubtitle",
        IDS_SETTINGS_CAPTIONS_ENABLE_LIVE_CAPTION_SUBTITLE},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean("enableLiveCaption",
                           base::FeatureList::IsEnabled(media::kLiveCaption));
@@ -114,7 +114,7 @@
     {"driveSuggestPref", IDS_DRIVE_SUGGEST_PREF},
     {"driveSuggestPrefDesc", IDS_DRIVE_SUGGEST_PREF_DESC},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 void AddSyncControlsStrings(content::WebUIDataSource* html_source) {
@@ -135,7 +135,7 @@
       {"customizeSyncLabel", IDS_SETTINGS_CUSTOMIZE_SYNC},
       {"syncData", IDS_SETTINGS_SYNC_DATA},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 void AddSyncAccountControlStrings(content::WebUIDataSource* html_source) {
@@ -153,7 +153,7 @@
       {"useAnotherAccount", IDS_SETTINGS_PEOPLE_SYNC_ANOTHER_ACCOUNT},
       {"syncAdvancedPageTitle", IDS_SETTINGS_NEW_SYNC_ADVANCED_PAGE_TITLE},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -165,7 +165,7 @@
       {"passwordPromptPasswordLabel",
        IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_PASSWORD_LABEL},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 #endif
 
@@ -206,7 +206,7 @@
       {"manageSyncedDataTitle",
        IDS_SETTINGS_NEW_MANAGE_SYNCED_DATA_TITLE_UNIFIED_CONSENT},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   std::string sync_dashboard_url =
       google_util::AppendGoogleLocaleParam(
@@ -297,7 +297,7 @@
       {"nearbyShareHighVisibilityOff",
        IDS_SETTINGS_NEARBY_SHARE_HIGH_VISIBILITY_OFF}};
 
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 
   html_source->AddBoolean(
       "nearbySharingFeatureFlag",
diff --git a/chrome/browser/ui/webui/signin/inline_login_ui.cc b/chrome/browser/ui/webui/signin/inline_login_ui.cc
index d566611..e96de2f0 100644
--- a/chrome/browser/ui/webui/signin/inline_login_ui.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_ui.cc
@@ -201,7 +201,7 @@
      IDS_ACCOUNT_MANAGER_ERROR_CANNOT_ADD_ACCOUNT_BODY},
 #endif
   };
-  AddLocalizedStringsBulk(source, kLocalizedStrings);
+  source->AddLocalizedStrings(kLocalizedStrings);
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   source->AddBoolean("isAccountManagementFlowsV2Enabled",
diff --git a/chrome/browser/ui/webui/signin/profile_customization_ui.cc b/chrome/browser/ui/webui/signin/profile_customization_ui.cc
index 98d1520..af16c54 100644
--- a/chrome/browser/ui/webui/signin/profile_customization_ui.cc
+++ b/chrome/browser/ui/webui/signin/profile_customization_ui.cc
@@ -53,7 +53,7 @@
       {"thirdPartyThemeDescription", IDS_NTP_CUSTOMIZE_3PT_THEME_DESC},
       {"uninstallThirdPartyThemeButton", IDS_NTP_CUSTOMIZE_3PT_THEME_UNINSTALL},
   };
-  webui::AddLocalizedStringsBulk(source, kLocalizedStrings);
+  source->AddLocalizedStrings(kLocalizedStrings);
 
   // loadTimeData.
   Profile* profile = Profile::FromWebUI(web_ui);
diff --git a/chrome/browser/ui/webui/signin/profile_picker_ui.cc b/chrome/browser/ui/webui/signin/profile_picker_ui.cc
index 30725f2b..39b4cdb 100644
--- a/chrome/browser/ui/webui/signin/profile_picker_ui.cc
+++ b/chrome/browser/ui/webui/signin/profile_picker_ui.cc
@@ -136,7 +136,7 @@
       {"thirdPartyThemeDescription", IDS_NTP_CUSTOMIZE_3PT_THEME_DESC},
       {"uninstallThirdPartyThemeButton", IDS_NTP_CUSTOMIZE_3PT_THEME_UNINSTALL},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
   ProfilePicker::AvailabilityOnStartup availability_on_startup =
       static_cast<ProfilePicker::AvailabilityOnStartup>(
           g_browser_process->local_state()->GetInteger(
diff --git a/chrome/browser/ui/webui/signin/signin_email_confirmation_ui.cc b/chrome/browser/ui/webui/signin/signin_email_confirmation_ui.cc
index 4d2d43c..1a1f4143 100644
--- a/chrome/browser/ui/webui/signin/signin_email_confirmation_ui.cc
+++ b/chrome/browser/ui/webui/signin/signin_email_confirmation_ui.cc
@@ -46,7 +46,7 @@
       {"signinEmailConfirmationCloseLabel",
        IDS_SIGNIN_EMAIL_CONFIRMATION_CLOSE_BUTTON_LABEL},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
 
   base::DictionaryValue strings;
   webui::SetLoadTimeDataDefaults(g_browser_process->GetApplicationLocale(),
diff --git a/chrome/browser/ui/webui/system_info_ui.cc b/chrome/browser/ui/webui/system_info_ui.cc
index 5515358..a9d39ab 100644
--- a/chrome/browser/ui/webui/system_info_ui.cc
+++ b/chrome/browser/ui/webui/system_info_ui.cc
@@ -61,7 +61,7 @@
       {"collapseBtn", IDS_ABOUT_SYS_COLLAPSE},
       {"parseError", IDS_ABOUT_SYS_PARSE_ERROR},
   };
-  AddLocalizedStringsBulk(html_source, kStrings);
+  html_source->AddLocalizedStrings(kStrings);
 
   html_source->AddResourcePath("about_sys.js", IDR_ABOUT_SYS_JS);
   html_source->AddResourcePath("about_sys.css", IDR_ABOUT_SYS_CSS);
diff --git a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc
index 9138b66..779859e1 100644
--- a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc
+++ b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc
@@ -72,14 +72,19 @@
   if (!optional_details)
     return;
 
-  const TabDetails& details = optional_details.value();
-  bool tab_closed = details.tab_strip_model->CloseWebContentsAt(
-      details.index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
-
   ++num_tabs_closed_;
 
-  if (tab_closed)
-    NotifyTabsChanged();
+  // CloseTab() can target the WebContents hosting Tab Search if the Tab Search
+  // WebUI is open in a chrome browser tab rather than its bubble. In this case
+  // CloseWebContentsAt() closes the WebContents hosting this
+  // TabSearchPageHandler object, causing it to be immediately destroyed. Ensure
+  // that no further actions are performed following the call to
+  // CloseWebContentsAt(). See (https://crbug.com/1175507).
+  auto* tab_strip_model = optional_details->tab_strip_model;
+  const int tab_index = optional_details->index;
+  tab_strip_model->CloseWebContentsAt(
+      tab_index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
+  // Do not add code past this point.
 }
 
 void TabSearchPageHandler::GetProfileTabs(GetProfileTabsCallback callback) {
diff --git a/chrome/browser/ui/webui/tab_search/tab_search_page_handler_unittest.cc b/chrome/browser/ui/webui/tab_search/tab_search_page_handler_unittest.cc
index 2fb919ca..a145495 100644
--- a/chrome/browser/ui/webui/tab_search/tab_search_page_handler_unittest.cc
+++ b/chrome/browser/ui/webui/tab_search/tab_search_page_handler_unittest.cc
@@ -339,7 +339,6 @@
 
   int tab_id = extensions::ExtensionTabUtil::GetTabId(
       browser2()->tab_strip_model()->GetWebContentsAt(0));
-  EXPECT_CALL(page_, TabsChanged(_)).Times(1);
   EXPECT_CALL(page_, TabUpdated(_)).Times(1);
   EXPECT_CALL(page_, TabsRemoved(_)).Times(3);
   handler()->CloseTab(tab_id);
diff --git a/chrome/browser/ui/webui/tab_search/tab_search_ui.cc b/chrome/browser/ui/webui/tab_search/tab_search_ui.cc
index e068c88..298bf429 100644
--- a/chrome/browser/ui/webui/tab_search/tab_search_ui.cc
+++ b/chrome/browser/ui/webui/tab_search/tab_search_ui.cc
@@ -44,7 +44,7 @@
       {"a11yFoundTabFor", IDS_TAB_SEARCH_A11Y_FOUND_TAB_FOR},
       {"a11yFoundTabsFor", IDS_TAB_SEARCH_A11Y_FOUND_TABS_FOR},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
 
   source->AddBoolean(
       "submitFeedbackEnabled",
diff --git a/chrome/browser/ui/webui/tab_search/tab_search_ui_browsertest.cc b/chrome/browser/ui/webui/tab_search/tab_search_ui_browsertest.cc
index 7794af40..f53c43c 100644
--- a/chrome/browser/ui/webui/tab_search/tab_search_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/tab_search/tab_search_ui_browsertest.cc
@@ -133,3 +133,40 @@
   ASSERT_EQ(open_tab_ids.end(),
             std::find(open_tab_ids.begin(), open_tab_ids.end(), tab_id));
 }
+
+// When hosting the Tab Search UI as a browser tab, ensure that closing the tab
+// hosting Tab Search does not result in any UAF errors. Test for regression
+// (https://crbug.com/1175507).
+IN_PROC_BROWSER_TEST_F(TabSearchUIBrowserTest,
+                       CloseTabSearchAsBrowserTabDoesNotCrash) {
+  AppendTab(chrome::kChromeUITabSearchURL);
+  auto* tab_strip_model = browser()->tab_strip_model();
+  ASSERT_EQ(5, tab_strip_model->GetTabCount());
+  content::WebContents* tab_contents = tab_strip_model->GetWebContentsAt(4);
+  const int tab_id = extensions::ExtensionTabUtil::GetTabId(
+      tab_strip_model->GetWebContentsAt(4));
+
+  // Finish loading after initializing.
+  ASSERT_TRUE(content::WaitForLoadStop(tab_contents));
+
+  TabSearchPageHandler* page_handler = tab_contents->GetWebUI()
+                                           ->GetController()
+                                           ->template GetAs<TabSearchUI>()
+                                           ->page_handler_for_testing();
+  ASSERT_NE(nullptr, page_handler);
+  page_handler->CloseTab(tab_id);
+  ASSERT_EQ(4, tab_strip_model->GetTabCount());
+
+  // Check to make sure the browser tab hosting Tab Search has been closed but
+  // the rest remain.
+  int tab_count = tab_strip_model->GetTabCount();
+  ASSERT_EQ(4, tab_count);
+
+  std::vector<int> open_tab_ids(tab_count);
+  for (int tab_index = 0; tab_index < tab_count; tab_index++) {
+    open_tab_ids.push_back(extensions::ExtensionTabUtil::GetTabId(
+        tab_strip_model->GetWebContentsAt(tab_index)));
+  }
+  ASSERT_EQ(open_tab_ids.end(),
+            std::find(open_tab_ids.begin(), open_tab_ids.end(), tab_id));
+}
diff --git a/chrome/browser/ui/webui/tab_strip/tab_strip_ui.cc b/chrome/browser/ui/webui/tab_strip/tab_strip_ui.cc
index 69e7669..79694df 100644
--- a/chrome/browser/ui/webui/tab_strip/tab_strip_ui.cc
+++ b/chrome/browser/ui/webui/tab_strip/tab_strip_ui.cc
@@ -82,7 +82,7 @@
       {"unnamedGroupLabel", IDS_GROUP_AX_LABEL_UNNAMED_GROUP_FORMAT},
       {"namedGroupLabel", IDS_GROUP_AX_LABEL_NAMED_GROUP_FORMAT},
   };
-  AddLocalizedStringsBulk(html_source, kStrings);
+  html_source->AddLocalizedStrings(kStrings);
   content::WebUIDataSource::Add(profile, html_source);
 
   content::URLDataSource::Add(
diff --git a/chrome/browser/ui/webui/version/version_ui.cc b/chrome/browser/ui/webui/version/version_ui.cc
index ab478da..5af902d 100644
--- a/chrome/browser/ui/webui/version/version_ui.cc
+++ b/chrome/browser/ui/webui/version/version_ui.cc
@@ -83,7 +83,7 @@
     {version_ui::kGmsName, IDS_VERSION_UI_GMS},
 #endif  // OS_ANDROID
   };
-  AddLocalizedStringsBulk(html_source, kStrings);
+  html_source->AddLocalizedStrings(kStrings);
 
   VersionUI::AddVersionDetailStrings(html_source);
 
diff --git a/chrome/browser/ui/webui/webui_util.cc b/chrome/browser/ui/webui/webui_util.cc
index 1716cd7..1fe5d9b 100644
--- a/chrome/browser/ui/webui/webui_util.cc
+++ b/chrome/browser/ui/webui/webui_util.cc
@@ -49,12 +49,6 @@
   source->AddResourcePath("", default_resource);
 }
 
-void AddLocalizedStringsBulk(content::WebUIDataSource* html_source,
-                             base::span<const LocalizedString> strings) {
-  for (const auto& str : strings)
-    html_source->AddLocalizedString(str.name, str.id);
-}
-
 void AddResourcePathsBulk(content::WebUIDataSource* source,
                           base::span<const ResourcePath> paths) {
   for (const auto& path : paths)
diff --git a/chrome/browser/ui/webui/webui_util.h b/chrome/browser/ui/webui/webui_util.h
index cac2bbf2..9a70f36 100644
--- a/chrome/browser/ui/webui/webui_util.h
+++ b/chrome/browser/ui/webui/webui_util.h
@@ -17,9 +17,6 @@
 }
 
 namespace webui {
-
-struct LocalizedString;
-
 struct ResourcePath {
   const char* path;
   int id;
@@ -33,11 +30,6 @@
                           base::span<const GritResourceMap> resources,
                           int default_resource);
 
-// Calls content::WebUIDataSource::AddLocalizedString() in a for-loop for
-// |strings|. Reduces code size vs. reimplementing the same for-loop.
-void AddLocalizedStringsBulk(content::WebUIDataSource* html_source,
-                             base::span<const LocalizedString> strings);
-
 // Calls content::WebUIDataSource::AddResourcePath() in a for-loop for |paths|.
 // Reduces code size vs. reimplementing the same for-loop.
 void AddResourcePathsBulk(content::WebUIDataSource* source,
diff --git a/chrome/browser/ui/webui/welcome/welcome_ui.cc b/chrome/browser/ui/webui/welcome/welcome_ui.cc
index 125e00ec..57f7be4 100644
--- a/chrome/browser/ui/webui/welcome/welcome_ui.cc
+++ b/chrome/browser/ui/webui/welcome/welcome_ui.cc
@@ -107,7 +107,7 @@
       {"landingNewUser", IDS_WELCOME_LANDING_NEW_USER},
       {"landingExistingUser", IDS_WELCOME_LANDING_EXISTING_USER},
   };
-  AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 }  // namespace
diff --git a/chrome/browser/web_applications/components/web_app_data_retriever.cc b/chrome/browser/web_applications/components/web_app_data_retriever.cc
index d9edb5f..8a649b4 100644
--- a/chrome/browser/web_applications/components/web_app_data_retriever.cc
+++ b/chrome/browser/web_applications/components/web_app_data_retriever.cc
@@ -181,14 +181,13 @@
 
   Observe(nullptr);
 
-  DCHECK(data.manifest);
-  DCHECK(data.manifest_url.is_valid() || data.manifest->IsEmpty());
+  DCHECK(data.manifest_url.is_valid() || data.manifest.IsEmpty());
 
   const bool is_installable = data.NoBlockingErrors();
   DCHECK(!is_installable || data.valid_manifest);
   base::Optional<blink::Manifest> opt_manifest;
-  if (!data.manifest->IsEmpty())
-    opt_manifest = *data.manifest;
+  if (!data.manifest.IsEmpty())
+    opt_manifest = data.manifest;
 
   std::move(check_installability_callback_)
       .Run(std::move(opt_manifest), data.manifest_url, data.valid_manifest,
diff --git a/chrome/browser/web_applications/manifest_update_task.cc b/chrome/browser/web_applications/manifest_update_task.cc
index 7eda812..fe03d32 100644
--- a/chrome/browser/web_applications/manifest_update_task.cc
+++ b/chrome/browser/web_applications/manifest_update_task.cc
@@ -132,9 +132,8 @@
     return;
   }
 
-  DCHECK(data.manifest);
   web_application_info_.emplace();
-  UpdateWebAppInfoFromManifest(*data.manifest, data.manifest_url,
+  UpdateWebAppInfoFromManifest(data.manifest, data.manifest_url,
                                &web_application_info_.value());
 
   // We cannot allow the app ID to change via the manifest changing. We rely on
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 806fab5..c7cae7f4 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-master-1612807167-7cd725d3ed3deb2d1bfde13ae77d0e784ef1b65a.profdata
+chrome-linux-master-1612893594-29777cd5c2d7491b296bc41b175b30126012ae9e.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 3f3f168..576ab4e 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-master-1612807167-490040e8e78d3f16c1222d85ed3d6a3a4c099ef1.profdata
+chrome-mac-master-1612893594-d6bef2dab7e9387599496a21d4c41d44cc8e464d.profdata
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni
index 6717d54..bb2af04 100644
--- a/chrome/chrome_paks.gni
+++ b/chrome/chrome_paks.gni
@@ -183,6 +183,7 @@
         "$root_gen_dir/chrome/multidevice_setup_resources.pak",
         "$root_gen_dir/chrome/nearby_internals_resources.pak",
         "$root_gen_dir/chrome/nearby_share_dialog_resources.pak",
+        "$root_gen_dir/chrome/network_ui_resources.pak",
         "$root_gen_dir/chrome/os_settings_resources.pak",
         "$root_gen_dir/chromeos/chromeos_camera_app_resources.pak",
         "$root_gen_dir/chromeos/chromeos_diagnostics_app_resources.pak",
@@ -207,6 +208,7 @@
         "//chrome/browser/resources/chromeos:multidevice_setup_resources",
         "//chrome/browser/resources/chromeos/emoji_picker:resources",
         "//chrome/browser/resources/chromeos/multidevice_internals:resources",
+        "//chrome/browser/resources/chromeos/network_ui:resources",
         "//chrome/browser/resources/nearby_internals:resources",
         "//chrome/browser/resources/nearby_share:resources",
         "//chrome/browser/resources/settings/chromeos:resources",
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 936b3b5..3b4ac91f 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -643,6 +643,12 @@
                                          base::FEATURE_ENABLED_BY_DEFAULT};
 #endif  // BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS)
 
+#if defined(OS_MAC)
+// Enables the usage of Apple's new Notification API on macOS 10.14+
+const base::Feature kNewMacNotificationAPI{"NewMacNotificationAPI",
+                                           base::FEATURE_DISABLED_BY_DEFAULT};
+#endif  // OS_MAC
+
 // When kNoReferrers is enabled, most HTTP requests will provide empty
 // referrers instead of their ordinary behavior.
 const base::Feature kNoReferrers{"NoReferrers",
@@ -656,6 +662,12 @@
     base::FEATURE_DISABLED_BY_DEFAULT};
 #endif  // OS_WIN
 
+#if defined(OS_MAC)
+// Shows alert notifications via a helper app in a utility process.
+const base::Feature kNotificationsViaHelperApp{
+    "NotificationsViaHelperApp", base::FEATURE_DISABLED_BY_DEFAULT};
+#endif  // OS_MAC
+
 #if defined(OS_POSIX)
 // Enables NTLMv2, which implicitly disables NTLMv1.
 const base::Feature kNtlmV2Enabled{"NtlmV2Enabled",
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 6ac721b8..f18a1d70 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -424,6 +424,11 @@
 extern const base::Feature kNativeNotifications;
 #endif
 
+#if defined(OS_MAC)
+COMPONENT_EXPORT(CHROME_FEATURES)
+extern const base::Feature kNewMacNotificationAPI;
+#endif
+
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kNoReferrers;
 
 #if defined(OS_WIN)
@@ -431,6 +436,11 @@
 extern const base::Feature kNotificationDurationLongForRequireInteraction;
 #endif
 
+#if defined(OS_MAC)
+COMPONENT_EXPORT(CHROME_FEATURES)
+extern const base::Feature kNotificationsViaHelperApp;
+#endif
+
 #if defined(OS_POSIX)
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kNtlmV2Enabled;
 #endif
diff --git a/chrome/common/features.gni b/chrome/common/features.gni
index 1b2d4f0..c0038df 100644
--- a/chrome/common/features.gni
+++ b/chrome/common/features.gni
@@ -88,6 +88,5 @@
   "enable_webui_tab_strip=$enable_webui_tab_strip",
   "safe_browsing_mode=$safe_browsing_mode",
   "optimize_webui=$optimize_webui",
-  "enable_feed_v1=$enable_feed_v1",
   "enable_feed_v2=$enable_feed_v2",
 ]
diff --git a/chrome/common/profiler/thread_profiler.cc b/chrome/common/profiler/thread_profiler.cc
index 0d9af30..49bb665 100644
--- a/chrome/common/profiler/thread_profiler.cc
+++ b/chrome/common/profiler/thread_profiler.cc
@@ -55,7 +55,7 @@
 ThreadProfiler* g_main_thread_instance = nullptr;
 
 // Run continuous profiling 2% of the time.
-constexpr const double kFractionOfExecutionTimeToSample = 0.02;
+constexpr double kFractionOfExecutionTimeToSample = 0.02;
 
 bool IsCurrentProcessBackgrounded() {
 #if defined(OS_MAC)
diff --git a/chrome/renderer/previews/resource_loading_hints_agent.cc b/chrome/renderer/previews/resource_loading_hints_agent.cc
index 9f0f767..57e005a 100644
--- a/chrome/renderer/previews/resource_loading_hints_agent.cc
+++ b/chrome/renderer/previews/resource_loading_hints_agent.cc
@@ -76,6 +76,7 @@
 void ResourceLoadingHintsAgent::SetReceiver(
     mojo::PendingAssociatedReceiver<
         previews::mojom::PreviewsResourceLoadingHintsReceiver> receiver) {
+  receiver_.reset();
   receiver_.Bind(std::move(receiver));
 }
 
diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc
index 0f8395b..cb6c34b7 100644
--- a/chrome/renderer/searchbox/searchbox_extension.cc
+++ b/chrome/renderer/searchbox/searchbox_extension.cc
@@ -941,10 +941,17 @@
                  &NewTabPageBindings::SetCustomBackgroundInfo)
       .SetMethod("selectLocalBackgroundImage",
                  &NewTabPageBindings::SelectLocalBackgroundImage)
+      // These methods have been renamed to match BlocklistSearchSuggestion*
+      // below, but are kept until JavaScript calls can be migrated.
+      // TODO: Remove the following two additions per guidance in b/179534247
       .SetMethod("blacklistSearchSuggestion",
                  &NewTabPageBindings::BlocklistSearchSuggestion)
       .SetMethod("blacklistSearchSuggestionWithHash",
                  &NewTabPageBindings::BlocklistSearchSuggestionWithHash)
+      .SetMethod("blocklistSearchSuggestion",
+                 &NewTabPageBindings::BlocklistSearchSuggestion)
+      .SetMethod("blocklistSearchSuggestionWithHash",
+                 &NewTabPageBindings::BlocklistSearchSuggestionWithHash)
       .SetMethod("searchSuggestionSelected",
                  &NewTabPageBindings::SearchSuggestionSelected)
       .SetMethod("optOutOfSearchSuggestions",
diff --git a/chrome/renderer/subresource_redirect/public_resource_decider_agent.cc b/chrome/renderer/subresource_redirect/public_resource_decider_agent.cc
index 42fabe5b..74338db 100644
--- a/chrome/renderer/subresource_redirect/public_resource_decider_agent.cc
+++ b/chrome/renderer/subresource_redirect/public_resource_decider_agent.cc
@@ -45,6 +45,7 @@
 void PublicResourceDeciderAgent::BindHintsReceiver(
     mojo::PendingAssociatedReceiver<mojom::SubresourceRedirectHintsReceiver>
         receiver) {
+  subresource_redirect_hints_receiver_.reset();
   subresource_redirect_hints_receiver_.Bind(std::move(receiver));
 }
 
diff --git a/chrome/services/mac_notifications/BUILD.gn b/chrome/services/mac_notifications/BUILD.gn
new file mode 100644
index 0000000..086ee88c
--- /dev/null
+++ b/chrome/services/mac_notifications/BUILD.gn
@@ -0,0 +1,41 @@
+# 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.
+
+source_set("mac_notifications") {
+  sources = [
+    "mac_notification_provider_impl.h",
+    "mac_notification_provider_impl.mm",
+    "mac_notification_service_un.h",
+    "mac_notification_service_un.mm",
+  ]
+
+  deps = [
+    "//base",
+    "//chrome/common:chrome_features",
+  ]
+
+  public_deps = [
+    "//chrome/services/mac_notifications/public/mojom",
+    "//mojo/public/mojom/base",
+  ]
+
+  frameworks = [ "Foundation.framework" ]
+  weak_frameworks = [
+    "UserNotifications.framework",  # macOS 10.14
+  ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+
+  sources = [ "mac_notification_service_un_unittest.mm" ]
+
+  deps = [
+    ":mac_notifications",
+    "//base/test:test_support",
+    "//testing/gmock",
+    "//testing/gtest",
+    "//third_party/ocmock",
+  ]
+}
diff --git a/chrome/services/mac_notifications/DEPS b/chrome/services/mac_notifications/DEPS
new file mode 100644
index 0000000..eb3e2405
--- /dev/null
+++ b/chrome/services/mac_notifications/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+third_party/ocmock",  # For unit tests.
+]
diff --git a/chrome/services/mac_notifications/OWNERS b/chrome/services/mac_notifications/OWNERS
new file mode 100644
index 0000000..b7659b514
--- /dev/null
+++ b/chrome/services/mac_notifications/OWNERS
@@ -0,0 +1 @@
+file://chrome/browser/notifications/OWNERS
diff --git a/chrome/services/mac_notifications/mac_notification_provider_impl.h b/chrome/services/mac_notifications/mac_notification_provider_impl.h
new file mode 100644
index 0000000..8a1673d
--- /dev/null
+++ b/chrome/services/mac_notifications/mac_notification_provider_impl.h
@@ -0,0 +1,39 @@
+// 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_SERVICES_MAC_NOTIFICATIONS_MAC_NOTIFICATION_PROVIDER_IMPL_H_
+#define CHROME_SERVICES_MAC_NOTIFICATIONS_MAC_NOTIFICATION_PROVIDER_IMPL_H_
+
+#include <memory>
+
+#include "chrome/services/mac_notifications/public/mojom/mac_notifications.mojom.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+class MacNotificationProviderImpl
+    : public notifications::mojom::MacNotificationProvider {
+ public:
+  explicit MacNotificationProviderImpl(
+      mojo::PendingReceiver<notifications::mojom::MacNotificationProvider>
+          binding);
+  MacNotificationProviderImpl(const MacNotificationProviderImpl&) = delete;
+  MacNotificationProviderImpl& operator=(const MacNotificationProviderImpl&) =
+      delete;
+  ~MacNotificationProviderImpl() override;
+
+  // notifications::mojom::MacNotificationProvider:
+  void BindNotificationService(
+      mojo::PendingReceiver<notifications::mojom::MacNotificationService>
+          service,
+      mojo::PendingRemote<notifications::mojom::MacNotificationActionHandler>
+          handler) override;
+
+ private:
+  mojo::Receiver<notifications::mojom::MacNotificationProvider> binding_;
+  std::unique_ptr<notifications::mojom::MacNotificationService> service_;
+};
+
+#endif  // CHROME_SERVICES_MAC_NOTIFICATIONS_MAC_NOTIFICATION_PROVIDER_IMPL_H_
diff --git a/chrome/services/mac_notifications/mac_notification_provider_impl.mm b/chrome/services/mac_notifications/mac_notification_provider_impl.mm
new file mode 100644
index 0000000..a4205a402
--- /dev/null
+++ b/chrome/services/mac_notifications/mac_notification_provider_impl.mm
@@ -0,0 +1,39 @@
+// 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/services/mac_notifications/mac_notification_provider_impl.h"
+
+#import <UserNotifications/UserNotifications.h>
+
+#include "base/feature_list.h"
+#include "base/logging.h"
+#include "chrome/common/chrome_features.h"
+#import "chrome/services/mac_notifications/mac_notification_service_un.h"
+
+MacNotificationProviderImpl::MacNotificationProviderImpl(
+    mojo::PendingReceiver<notifications::mojom::MacNotificationProvider>
+        binding)
+    : binding_(this, std::move(binding)) {}
+
+MacNotificationProviderImpl::~MacNotificationProviderImpl() = default;
+
+void MacNotificationProviderImpl::BindNotificationService(
+    mojo::PendingReceiver<notifications::mojom::MacNotificationService> service,
+    mojo::PendingRemote<notifications::mojom::MacNotificationActionHandler>
+        handler) {
+  DCHECK(!service_);
+
+  // Use the UNNotification API if available and enabled.
+  if (@available(macOS 10.14, *)) {
+    if (base::FeatureList::IsEnabled(features::kNewMacNotificationAPI)) {
+      service_ = std::make_unique<MacNotificationServiceUN>(
+          std::move(service), std::move(handler),
+          [UNUserNotificationCenter currentNotificationCenter]);
+      return;
+    }
+  }
+
+  // Fall back to the NSUserNotification API.
+  // TODO(crbug.com/1170731): Implement NSUserNotification api.
+}
diff --git a/chrome/services/mac_notifications/mac_notification_service_un.h b/chrome/services/mac_notifications/mac_notification_service_un.h
new file mode 100644
index 0000000..346cc067
--- /dev/null
+++ b/chrome/services/mac_notifications/mac_notification_service_un.h
@@ -0,0 +1,45 @@
+// 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_SERVICES_MAC_NOTIFICATIONS_MAC_NOTIFICATION_SERVICE_UN_H_
+#define CHROME_SERVICES_MAC_NOTIFICATIONS_MAC_NOTIFICATION_SERVICE_UN_H_
+
+#include "base/mac/scoped_nsobject.h"
+#include "chrome/services/mac_notifications/public/mojom/mac_notifications.mojom.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+
+@class AlertNotificationCenterDelegate;
+@class UNUserNotificationCenter;
+
+// Implementation of the MacNotificationService mojo interface using the
+// UNNotification system API.
+class API_AVAILABLE(macos(10.14)) MacNotificationServiceUN
+    : public notifications::mojom::MacNotificationService {
+ public:
+  MacNotificationServiceUN(
+      mojo::PendingReceiver<notifications::mojom::MacNotificationService>
+          service,
+      mojo::PendingRemote<notifications::mojom::MacNotificationActionHandler>
+          handler,
+      UNUserNotificationCenter* notification_center);
+  MacNotificationServiceUN(const MacNotificationServiceUN&) = delete;
+  MacNotificationServiceUN& operator=(const MacNotificationServiceUN&) = delete;
+  ~MacNotificationServiceUN() override;
+
+  // notifications::mojom::MacNotificationService:
+  void CloseAllNotifications() override;
+
+ private:
+  // Requests notification permissions from the system. This will ask the user
+  // to accept permissions if not granted or denied already.
+  void RequestPermission();
+
+  mojo::Receiver<notifications::mojom::MacNotificationService> binding_;
+  base::scoped_nsobject<AlertNotificationCenterDelegate> delegate_;
+  base::scoped_nsobject<UNUserNotificationCenter> notification_center_;
+};
+
+#endif  // CHROME_SERVICES_MAC_NOTIFICATIONS_MAC_NOTIFICATION_SERVICE_UN_H_
diff --git a/chrome/services/mac_notifications/mac_notification_service_un.mm b/chrome/services/mac_notifications/mac_notification_service_un.mm
new file mode 100644
index 0000000..1d336f5
--- /dev/null
+++ b/chrome/services/mac_notifications/mac_notification_service_un.mm
@@ -0,0 +1,95 @@
+// 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/services/mac_notifications/mac_notification_service_un.h"
+
+#import <Foundation/Foundation.h>
+#import <UserNotifications/UserNotifications.h>
+
+#include "base/callback.h"
+#include "base/notreached.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+API_AVAILABLE(macosx(10.14))
+@interface AlertNotificationCenterDelegate
+    : NSObject <UNUserNotificationCenterDelegate>
+- (instancetype)initWithActionHandler:
+    (mojo::PendingRemote<notifications::mojom::MacNotificationActionHandler>)
+        handler;
+@end
+
+MacNotificationServiceUN::MacNotificationServiceUN(
+    mojo::PendingReceiver<notifications::mojom::MacNotificationService> service,
+    mojo::PendingRemote<notifications::mojom::MacNotificationActionHandler>
+        handler,
+    UNUserNotificationCenter* notification_center)
+    : binding_(this, std::move(service)),
+      delegate_([[AlertNotificationCenterDelegate alloc]
+          initWithActionHandler:std::move(handler)]),
+      notification_center_([notification_center retain]) {
+  [notification_center_ setDelegate:delegate_.get()];
+  // TODO(crbug.com/1129366): Determine when to ask for permissions.
+  RequestPermission();
+}
+
+MacNotificationServiceUN::~MacNotificationServiceUN() {
+  [notification_center_ setDelegate:nil];
+}
+
+void MacNotificationServiceUN::CloseAllNotifications() {
+  [notification_center_ removeAllDeliveredNotifications];
+}
+
+void MacNotificationServiceUN::RequestPermission() {
+  UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
+                                       UNAuthorizationOptionSound |
+                                       UNAuthorizationOptionBadge;
+
+  auto resultHandler = ^(BOOL granted, NSError* _Nullable error) {
+    // TODO(knollr): Add UMA logging for permission status.
+    if (error != nil) {
+      DVLOG(1) << "Requesting permission did not succeed";
+    }
+  };
+
+  [notification_center_ requestAuthorizationWithOptions:authOptions
+                                      completionHandler:resultHandler];
+}
+
+@implementation AlertNotificationCenterDelegate {
+  mojo::Remote<notifications::mojom::MacNotificationActionHandler> _handler;
+}
+
+- (instancetype)initWithActionHandler:
+    (mojo::PendingRemote<notifications::mojom::MacNotificationActionHandler>)
+        handler {
+  if ((self = [super init])) {
+    _handler.Bind(std::move(handler));
+  }
+  return self;
+}
+
+- (void)userNotificationCenter:(UNUserNotificationCenter*)center
+       willPresentNotification:(UNNotification*)notification
+         withCompletionHandler:
+             (void (^)(UNNotificationPresentationOptions options))
+                 completionHandler {
+  // Receiving a notification when the app is in the foreground.
+  UNNotificationPresentationOptions presentationOptions =
+      UNNotificationPresentationOptionSound |
+      UNNotificationPresentationOptionAlert |
+      UNNotificationPresentationOptionBadge;
+  completionHandler(presentationOptions);
+}
+
+- (void)userNotificationCenter:(UNUserNotificationCenter*)center
+    didReceiveNotificationResponse:(UNNotificationResponse*)response
+             withCompletionHandler:(void (^)(void))completionHandler {
+  auto actionInfo = notifications::mojom::NotificationActionInfo::New();
+  // TODO(knollr): Fill |action_info| with details from |response|.
+  _handler->OnNotificationAction(std::move(actionInfo));
+  completionHandler();
+}
+
+@end
diff --git a/chrome/services/mac_notifications/mac_notification_service_un_unittest.mm b/chrome/services/mac_notifications/mac_notification_service_un_unittest.mm
new file mode 100644
index 0000000..31c3f7bf
--- /dev/null
+++ b/chrome/services/mac_notifications/mac_notification_service_un_unittest.mm
@@ -0,0 +1,124 @@
+// 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 <UserNotifications/UserNotifications.h>
+
+#include "base/run_loop.h"
+#include "base/test/task_environment.h"
+#import "chrome/services/mac_notifications/mac_notification_service_un.h"
+#include "chrome/services/mac_notifications/public/mojom/mac_notifications.mojom.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gtest_mac.h"
+#import "third_party/ocmock/OCMock/OCMock.h"
+
+namespace {
+
+class MockNotificationActionHandler
+    : public notifications::mojom::MacNotificationActionHandler {
+ public:
+  // notifications::mojom::MacNotificationActionHandler:
+  MOCK_METHOD(void,
+              OnNotificationAction,
+              (notifications::mojom::NotificationActionInfoPtr),
+              (override));
+};
+
+}  // namespace
+
+class MacNotificationServiceUNTest : public testing::Test {
+ public:
+  MacNotificationServiceUNTest() {
+    if (@available(macOS 10.14, *)) {
+      mock_notification_center_ =
+          [OCMockObject mockForClass:[UNUserNotificationCenter class]];
+      // Expect the MacNotificationServiceUN ctor to register a delegate with
+      // the UNNotificationCenter and ask for notification permissions.
+      ExpectAndUpdateUNUserNotificationCenterDelegate(/*expect_not_nil=*/true);
+      [[[mock_notification_center_ expect] ignoringNonObjectArgs]
+          requestAuthorizationWithOptions:0
+                        completionHandler:[OCMArg any]];
+      service_ = std::make_unique<MacNotificationServiceUN>(
+          service_remote_.BindNewPipeAndPassReceiver(),
+          handler_receiver_.BindNewPipeAndPassRemote(),
+          mock_notification_center_);
+      [mock_notification_center_ verify];
+    }
+  }
+
+  ~MacNotificationServiceUNTest() override {
+    if (@available(macOS 10.14, *)) {
+      // Expect the MacNotificationServiceUN dtor to clear the delegate from the
+      // UNNotificationCenter.
+      ExpectAndUpdateUNUserNotificationCenterDelegate(/*expect_not_nil=*/false);
+      service_.reset();
+      [mock_notification_center_ verify];
+    }
+  }
+
+ protected:
+  void ExpectAndUpdateUNUserNotificationCenterDelegate(bool expect_not_nil)
+      API_AVAILABLE(macos(10.14)) {
+    [[mock_notification_center_ expect]
+        setDelegate:[OCMArg checkWithBlock:^BOOL(
+                                id<UNUserNotificationCenterDelegate> delegate) {
+          EXPECT_EQ(expect_not_nil, delegate != nil);
+          notification_center_delegate_ = delegate;
+          return YES;
+        }]];
+  }
+
+  base::test::TaskEnvironment task_environment_;
+  MockNotificationActionHandler mock_handler_;
+  mojo::Receiver<notifications::mojom::MacNotificationActionHandler>
+      handler_receiver_{&mock_handler_};
+  mojo::Remote<notifications::mojom::MacNotificationService> service_remote_;
+  id mock_notification_center_ = nil;
+  API_AVAILABLE(macos(10.14))
+  id<UNUserNotificationCenterDelegate> notification_center_delegate_ = nullptr;
+  API_AVAILABLE(macos(10.14))
+  std::unique_ptr<MacNotificationServiceUN> service_;
+};
+
+TEST_F(MacNotificationServiceUNTest, CloseAllNotifications) {
+  if (@available(macOS 10.14, *)) {
+    base::RunLoop run_loop;
+    base::RepeatingClosure quit_closure = run_loop.QuitClosure();
+    [[[mock_notification_center_ expect] andDo:^(NSInvocation*) {
+      quit_closure.Run();
+    }] removeAllDeliveredNotifications];
+    service_remote_->CloseAllNotifications();
+    run_loop.Run();
+    [mock_notification_center_ verify];
+  }
+}
+
+TEST_F(MacNotificationServiceUNTest, OnNotificationAction) {
+  if (@available(macOS 10.14, *)) {
+    base::RunLoop run_loop;
+    EXPECT_CALL(mock_handler_, OnNotificationAction)
+        .WillOnce(
+            [&](notifications::mojom::NotificationActionInfoPtr action_info) {
+              // TODO(knollr): verify properties of |action_info| once we set
+              // them.
+              run_loop.Quit();
+            });
+
+    // Simulate a notification action and wait until we acknowledge it.
+    base::RunLoop inner_run_loop;
+    base::RepeatingClosure inner_quit_closure = inner_run_loop.QuitClosure();
+    UNNotificationResponse* response =
+        [OCMockObject mockForClass:[UNNotificationResponse class]];
+    [notification_center_delegate_
+                userNotificationCenter:mock_notification_center_
+        didReceiveNotificationResponse:response
+                 withCompletionHandler:^() {
+                   inner_quit_closure.Run();
+                 }];
+    inner_run_loop.Run();
+    run_loop.Run();
+  }
+}
diff --git a/chrome/services/mac_notifications/public/mojom/BUILD.gn b/chrome/services/mac_notifications/public/mojom/BUILD.gn
new file mode 100644
index 0000000..78ca99d
--- /dev/null
+++ b/chrome/services/mac_notifications/public/mojom/BUILD.gn
@@ -0,0 +1,11 @@
+# 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("//mojo/public/tools/bindings/mojom.gni")
+
+mojom("mojom") {
+  sources = [ "mac_notifications.mojom" ]
+
+  public_deps = [ "//mojo/public/mojom/base" ]
+}
diff --git a/chrome/services/mac_notifications/public/mojom/OWNERS b/chrome/services/mac_notifications/public/mojom/OWNERS
new file mode 100644
index 0000000..08850f4
--- /dev/null
+++ b/chrome/services/mac_notifications/public/mojom/OWNERS
@@ -0,0 +1,2 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chrome/services/mac_notifications/public/mojom/mac_notifications.mojom b/chrome/services/mac_notifications/public/mojom/mac_notifications.mojom
new file mode 100644
index 0000000..c43e5289
--- /dev/null
+++ b/chrome/services/mac_notifications/public/mojom/mac_notifications.mojom
@@ -0,0 +1,39 @@
+// 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.
+
+module notifications.mojom;
+
+// Represents a notification and the action taken on it by the user.
+struct NotificationActionInfo {
+  // TODO(knollr): Fill struct.
+};
+
+// Interface to control notifications shown by the helper app. Implemented by
+// the helper app and called from the browser process.
+interface MacNotificationService {
+  // TODO(knollr): Add remaining methods to show / query notifications.
+
+  // Closes all notifications shown by the helper app in the system notification
+  // center for all profiles.
+  CloseAllNotifications();
+};
+
+// Handles notification actions such as click or close. Implemented in the
+// browser process and called from the helper app.
+interface MacNotificationActionHandler {
+  // Called when there has been an action on a notification. An example is a
+  // user clicking on a notification or when a notification got closed.
+  OnNotificationAction(NotificationActionInfo info);
+};
+
+// Main entrypoint for the system notification service. Implemented in a helper
+// app so we can set a custom alert style different from the main app. This
+// allows us to show both banner and alert style notifications on macOS.
+interface MacNotificationProvider {
+  // Called from the browser process to connect to the helper app. Further calls
+  // are made on the |service| interface and actions will be handled by the
+  // passed |handler|.
+  BindNotificationService(pending_receiver<MacNotificationService> service,
+                          pending_remote<MacNotificationActionHandler> handler);
+};
diff --git a/chrome/services/sharing/nearby/nearby_connections.cc b/chrome/services/sharing/nearby/nearby_connections.cc
index 826be39..7e38b85 100644
--- a/chrome/services/sharing/nearby/nearby_connections.cc
+++ b/chrome/services/sharing/nearby/nearby_connections.cc
@@ -28,7 +28,8 @@
 // delete the pointer it is provided without deleting the shared instance.
 class ServiceControllerProxy : public ServiceController {
  public:
-  explicit ServiceControllerProxy(ServiceController* inner_service_controller)
+  explicit ServiceControllerProxy(
+      std::unique_ptr<ServiceController>& inner_service_controller)
       : inner_service_controller_(inner_service_controller) {}
   ~ServiceControllerProxy() override = default;
 
@@ -37,11 +38,15 @@
                           const std::string& service_id,
                           const ConnectionOptions& options,
                           const ConnectionRequestInfo& info) override {
+    if (!inner_service_controller_)
+      return {Status::kError};
     return inner_service_controller_->StartAdvertising(client, service_id,
                                                        options, info);
   }
 
   void StopAdvertising(ClientProxy* client) override {
+    if (!inner_service_controller_)
+      return;
     inner_service_controller_->StopAdvertising(client);
   }
 
@@ -49,17 +54,23 @@
                         const std::string& service_id,
                         const ConnectionOptions& options,
                         const DiscoveryListener& listener) override {
+    if (!inner_service_controller_)
+      return {Status::kError};
     return inner_service_controller_->StartDiscovery(client, service_id,
                                                      options, listener);
   }
 
   void StopDiscovery(ClientProxy* client) override {
+    if (!inner_service_controller_)
+      return;
     inner_service_controller_->StopDiscovery(client);
   }
 
   void InjectEndpoint(ClientProxy* client,
                       const std::string& service_id,
                       const OutOfBandConnectionMetadata& metadata) override {
+    if (!inner_service_controller_)
+      return;
     inner_service_controller_->InjectEndpoint(client, service_id, metadata);
   }
 
@@ -67,6 +78,8 @@
                            const std::string& endpoint_id,
                            const ConnectionRequestInfo& info,
                            const ConnectionOptions& options) override {
+    if (!inner_service_controller_)
+      return {Status::kError};
     return inner_service_controller_->RequestConnection(client, endpoint_id,
                                                         info, options);
   }
@@ -80,33 +93,48 @@
 
   Status RejectConnection(ClientProxy* client,
                           const std::string& endpoint_id) override {
+    if (!inner_service_controller_)
+      return {Status::kError};
     return inner_service_controller_->RejectConnection(client, endpoint_id);
   }
 
   void InitiateBandwidthUpgrade(ClientProxy* client,
                                 const std::string& endpoint_id) override {
+    if (!inner_service_controller_)
+      return;
     inner_service_controller_->InitiateBandwidthUpgrade(client, endpoint_id);
   }
 
   void SendPayload(ClientProxy* client,
                    const std::vector<std::string>& endpoint_ids,
                    Payload payload) override {
+    if (!inner_service_controller_)
+      return;
     inner_service_controller_->SendPayload(client, endpoint_ids,
                                            std::move(payload));
   }
 
   Status CancelPayload(ClientProxy* client, Payload::Id payload_id) override {
+    if (!inner_service_controller_)
+      return {Status::kError};
     return inner_service_controller_->CancelPayload(client,
                                                     std::move(payload_id));
   }
 
   void DisconnectFromEndpoint(ClientProxy* client,
                               const std::string& endpoint_id) override {
+    if (!inner_service_controller_)
+      return;
     inner_service_controller_->DisconnectFromEndpoint(client, endpoint_id);
   }
 
  private:
-  ServiceController* inner_service_controller_ = nullptr;
+  // This is intentionally a reference to the unique_ptr owned by
+  // NearbyConnections. During the shutdown flow, NearbyConnection will clean up
+  // it's service controller before this proxy is destroyed. The reference
+  // allows us to stop forwarding calls if NearbyConnections has already cleaned
+  // it up.
+  std::unique_ptr<ServiceController>& inner_service_controller_;
 };
 
 ConnectionRequestInfo CreateConnectionRequestInfo(
@@ -245,8 +273,32 @@
 }
 
 NearbyConnections::~NearbyConnections() {
+  // We need to clean up the shared OfflineServiceController before cleaning up
+  // Core objects. This ensures that any tasks queued up on threads get run
+  // before the ClientProxy owned by Core is deleted. The ServiceControllerProxy
+  // for each Core uses a reference to the unique_ptr so it will understand that
+  // it can no longer forward calls once it is reset here.
+  // See http://b/177336457 and https://crbug.com/1149773 for more details.
+
+  // We call StopAllEndpoints() for each Core which is the same as
+  // ClientDisconnecting() to simulate what happens when the
+  // ServiceControllerRouter shuts down.
+  CountDownLatch latch(service_id_to_core_map_.size());
+  for (auto& pair : service_id_to_core_map_) {
+    pair.second->StopAllEndpoints(
+        {.result_cb = [&latch](Status status) { latch.CountDown(); }});
+  }
+  VLOG(1) << "Nearby Connections: waiting for Core objects to finish stopping "
+          << "all endpoints.";
+  latch.Await(absl::Seconds(5));
+
+  VLOG(1) << "Nearby Connections: shutting down the shared service controller "
+          << "prior to taking down Core objects";
+  service_controller_.reset();
+
   // Note that deleting active Core objects invokes their shutdown flows. This
   // is required to ensure that Nearby cleans itself up.
+  VLOG(1) << "Nearby Connections: cleaning up Core objects";
   service_id_to_core_map_.clear();
   g_instance = nullptr;
 }
@@ -626,8 +678,10 @@
     core = std::make_unique<Core>([&]() {
       // Core expects to take ownership of the pointer provided, but since we
       // share a single ServiceController among all Core objects created, we
-      // provide a delegate which calls into our shared instance.
-      return new ServiceControllerProxy(service_controller_.get());
+      // provide a proxy which calls into our shared instance.
+      // The |service_controller_| is passed by reference to the unique_ptr so
+      // the proxy knows if |service_controller_| has been reset.
+      return new ServiceControllerProxy(service_controller_);
     });
   }
 
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 7b2e124..c1114bad 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1004,6 +1004,7 @@
       "../browser/browsing_data/counters/passwords_counter_browsertest.cc",
       "../browser/browsing_data/counters/sync_aware_counter_browsertest.cc",
       "../browser/browsing_data/navigation_entry_remover_browsertest.cc",
+      "../browser/capability_delegation_browsertest.cc",
       "../browser/chrome_back_forward_cache_browsertest.cc",
       "../browser/chrome_content_browser_client_browsertest.cc",
       "../browser/chrome_do_not_track_browsertest.cc",
@@ -3953,6 +3954,7 @@
       "../browser/global_keyboard_shortcuts_mac_unittest.mm",
       "../browser/mac/exception_processor_unittest.mm",
       "../browser/mac/keystone_glue_unittest.mm",
+      "../browser/notifications/notification_alert_service_bridge_unittest.mm",
       "../browser/notifications/notification_platform_bridge_mac_unittest.mm",
       "../browser/notifications/notification_platform_bridge_mac_unnotification_unittest.mm",
       "../browser/notifications/notification_platform_bridge_mac_utils_unittest.mm",
@@ -4269,6 +4271,7 @@
 
   if (is_mac) {
     data_deps += [ "//chrome:chrome_framework" ]
+    deps += [ "//chrome/services/mac_notifications:unit_tests" ]
   }
 
   if (is_win) {
@@ -4337,11 +4340,6 @@
     ]
   }
 
-  if (enable_feed_v1 && is_android) {
-    sources +=
-        [ "../browser/android/feed/history/feed_history_helper_unittest.cc" ]
-  }
-
   if (enable_soda) {
     deps += [ "//chrome/services/speech/soda:unit_tests" ]
   }
@@ -5230,7 +5228,6 @@
       "../browser/extensions/api/file_system/file_system_api_unittest.cc",
       "../browser/extensions/api/identity/extension_token_key_unittest.cc",
       "../browser/extensions/api/identity/gaia_remote_consent_flow_unittest.cc",
-      "../browser/extensions/api/identity/gaia_web_auth_flow_unittest.cc",
       "../browser/extensions/api/identity/identity_api_unittest.cc",
       "../browser/extensions/api/identity/identity_mint_queue_unittest.cc",
       "../browser/extensions/api/identity/identity_token_cache_unittest.cc",
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn
index 60320c7..5f0fff2 100644
--- a/chrome/test/android/BUILD.gn
+++ b/chrome/test/android/BUILD.gn
@@ -296,8 +296,8 @@
     "//components/policy/android:policy_java",
     "//components/policy/android:policy_java_test_support",
     "//components/signin/core/browser/android:java",
-    "//components/signin/core/browser/android:signin_java_test_support",
     "//components/signin/public/android:java",
+    "//components/signin/public/android:signin_java_test_support",
     "//components/sync/android:sync_java",
     "//components/translate/content/android:java",
     "//components/webapps/browser/android:java",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java
index 29e456c..fbff5e72 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java
@@ -23,9 +23,9 @@
 import org.chromium.components.signin.ProfileDataSource;
 import org.chromium.components.signin.base.CoreAccountId;
 import org.chromium.components.signin.base.CoreAccountInfo;
-import org.chromium.components.signin.core.browser.javatests.R;
 import org.chromium.components.signin.test.util.FakeAccountManagerFacade;
 import org.chromium.components.signin.test.util.FakeProfileDataSource;
+import org.chromium.components.signin.test.util.R;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 
 /**
diff --git a/chrome/test/data/capability_delegation/payment_request_delegation.html b/chrome/test/data/capability_delegation/payment_request_delegation.html
new file mode 100644
index 0000000..dfac609
--- /dev/null
+++ b/chrome/test/data/capability_delegation/payment_request_delegation.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>Payment request delegation top frame</title>
+</head>
+<script>
+  let resolve_promise = null;
+  window.addEventListener("message", e => resolve_promise(e.data));
+
+  async function sendRequestToSubframe(delegate) {
+      const promise = new Promise(resolve => { resolve_promise = resolve; });
+
+      let post_message_options = {};
+      post_message_options["targetOrigin"] = "*";
+      if (delegate) {
+          post_message_options["createToken"] = "paymentrequest";
+      }
+      frames[0].postMessage("try", post_message_options);
+      return promise;
+  }
+</script>
+<iframe src="about:blank" id="iframe" allowpaymentrequest></iframe>
+</html>
diff --git a/chrome/test/data/capability_delegation/payment_request_delegation_sub.html b/chrome/test/data/capability_delegation/payment_request_delegation_sub.html
new file mode 100644
index 0000000..c48ecb5
--- /dev/null
+++ b/chrome/test/data/capability_delegation/payment_request_delegation_sub.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>Payment request delegation child frame</title>
+</head>
+<script>
+  async function tryPaymentRequestAndReport() {
+      const request = new PaymentRequest([{
+          supportedMethods: "basic-card",
+          data: { supportedNetworks: ["visa"] }
+      }], {
+          total: {
+              label: "total",
+              amount: { currency: "CAD", value: "1.00" }
+          }
+      });
+
+      request.show().catch(exception => {
+          parent.postMessage(exception.name, {targetOrigin: "*"});
+      });
+
+      // When show() is not allowed, the Promise above throws a "NotAllowedError"
+      // right away.  Otherwise, the visible dialog is aborted after a short delay
+      // below, which causes the Promise above to throw an "AbortError".
+      window.setTimeout(() => request.abort().catch(()=>{}), 0);
+  }
+
+  window.addEventListener("message", tryPaymentRequestAndReport);
+</script>
+</html>
diff --git a/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js b/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js
index ca50809e..eb959ac 100644
--- a/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js
+++ b/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js
@@ -263,6 +263,34 @@
   embedder.setUpNewWindowRequest_(webview, 'guest.html', '', testName);
 }
 
+// Test that an embedder can attach a new window to a <webview> in a different
+// frame.
+async function testNewWindowAttachInSubFrame() {
+  let testName = 'testNewWindowAttachInSubFrame';
+  let webview = embedder.setUpGuest_('foobar');
+
+  let subframe = document.createElement('iframe');
+  subframe.src = '/subframe_with_webview.html';
+  await new Promise((resolve) => {
+    subframe.onload = resolve;
+    document.body.appendChild(subframe);
+  });
+
+  webview.addEventListener('newwindow', (e) => {
+    embedder.assertCorrectEvent_(e, '');
+
+    let newwebview = subframe.contentDocument.querySelector('webview');
+    newwebview.addEventListener('loadstop', embedder.test.succeed);
+    try {
+      e.window.attach(newwebview);
+    } catch (e) {
+      embedder.test.fail();
+    }
+  });
+
+  embedder.setUpNewWindowRequest_(webview, 'guest.html', '', testName);
+}
+
 function testNewWindowClose() {
   var testName = 'testNewWindowClose';
   var webview = embedder.setUpGuest_('foobar');
@@ -600,6 +628,7 @@
 embedder.test.testList = {
   'testNewWindowAttachAfterOpenerDestroyed':
       testNewWindowAttachAfterOpenerDestroyed,
+  'testNewWindowAttachInSubFrame': testNewWindowAttachInSubFrame,
   'testNewWindowClose': testNewWindowClose,
   'testNewWindowDeclarativeWebRequest': testNewWindowDeclarativeWebRequest,
   'testNewWindowDeferredAttachment': testNewWindowDeferredAttachment,
diff --git a/chrome/test/data/extensions/platform_apps/web_view/newwindow/subframe_with_webview.html b/chrome/test/data/extensions/platform_apps/web_view/newwindow/subframe_with_webview.html
new file mode 100644
index 0000000..f182bee
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/web_view/newwindow/subframe_with_webview.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<!--
+ * 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.
+-->
+<html>
+<body>
+  <webview></webview>
+</body>
+</html>
diff --git a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js
index 2edd455..9a30de8 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js
+++ b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js
@@ -110,7 +110,7 @@
    * @return {!CrButtonElement}
    */
   function getSessionLogButton() {
-    return /** @type {!CrButtonElement} */ (page.$$('.session-log-button'));
+    return /** @type {!CrButtonElement} */ (page.$$('#sessionLogButton'));
   }
 
   /**
@@ -152,7 +152,7 @@
           assertTrue(!!batteryStatus);
 
           // Verify the session log button is in the page.
-          const sessionLog = page.$$('.session-log-button');
+          const sessionLog = page.$$('#sessionLogButton');
           assertTrue(!!sessionLog);
         });
   });
diff --git a/chrome/test/data/webui/chromeos/diagnostics/routine_section_test.js b/chrome/test/data/webui/chromeos/diagnostics/routine_section_test.js
index e7fbb52..2ef1a74 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/routine_section_test.js
+++ b/chrome/test/data/webui/chromeos/diagnostics/routine_section_test.js
@@ -243,13 +243,7 @@
           return clickRunTestsButton();
         })
         .then(() => {
-          // Report is still hidden by default, but toggle button is visible.
-          assertFalse(isIronCollapseOpen());
-          assertTrue(isVisible(getToggleTestReportButton()));
-          return clickToggleTestReportButton();
-        })
-        .then(() => {
-          // Report is visible when button is clicked.
+          // Report and toggle button are visible.
           assertTrue(isIronCollapseOpen());
           assertTrue(isVisible(getToggleTestReportButton()));
           return clickToggleTestReportButton();
diff --git a/chrome/test/data/webui/chromeos/scanning/BUILD.gn b/chrome/test/data/webui/chromeos/scanning/BUILD.gn
index 4d4cb3ab..4a5f9f1 100644
--- a/chrome/test/data/webui/chromeos/scanning/BUILD.gn
+++ b/chrome/test/data/webui/chromeos/scanning/BUILD.gn
@@ -14,6 +14,7 @@
   deps = [
     ":color_mode_select_test",
     ":file_type_select_test",
+    ":loading_page_test",
     ":page_size_select_test",
     ":resolution_select_test",
     ":scan_done_section_test",
@@ -41,6 +42,11 @@
   externs_list = [ "$externs_path/mocha-2.5.js" ]
 }
 
+js_library("loading_page_test") {
+  deps = [ "//chromeos/components/scanning/resources:loading_page" ]
+  externs_list = [ "$externs_path/mocha-2.5.js" ]
+}
+
 js_library("page_size_select_test") {
   deps = [ "//chromeos/components/scanning/resources:page_size_select" ]
   externs_list = [ "$externs_path/mocha-2.5.js" ]
diff --git a/chrome/test/data/webui/chromeos/scanning/loading_page_test.js b/chrome/test/data/webui/chromeos/scanning/loading_page_test.js
new file mode 100644
index 0000000..ca13508
--- /dev/null
+++ b/chrome/test/data/webui/chromeos/scanning/loading_page_test.js
@@ -0,0 +1,41 @@
+// 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://scanning/loading_page.js';
+
+import {AppState} from 'chrome://scanning/scanning_app_types.js';
+
+import {assertFalse, assertTrue} from '../../chai_assert.js';
+import {isVisible} from '../../test_util.m.js';
+
+export function loadingPageTest() {
+  /** @type {?LoadingPageElement} */
+  let loadingPage = null;
+
+  setup(() => {
+    loadingPage = /** @type {!LoadingPageElement} */ (
+        document.createElement('loading-page'));
+    assertTrue(!!loadingPage);
+    loadingPage.appState = AppState.GETTING_SCANNERS;
+    document.body.appendChild(loadingPage);
+  });
+
+  teardown(() => {
+    loadingPage.remove();
+    loadingPage = null;
+  });
+
+  test('noScanners', () => {
+    assertTrue(
+        isVisible(/** @type {!HTMLElement} */ (loadingPage.$$('#loadingDiv'))));
+    assertFalse(isVisible(
+        /** @type {!HTMLElement} */ (loadingPage.$$('#noScannersDiv'))));
+
+    loadingPage.appState = AppState.NO_SCANNERS;
+    assertFalse(
+        isVisible(/** @type {!HTMLElement} */ (loadingPage.$$('#loadingDiv'))));
+    assertTrue(isVisible(
+        /** @type {!HTMLElement} */ (loadingPage.$$('#noScannersDiv'))));
+  });
+}
diff --git a/chrome/test/data/webui/chromeos/scanning/scan_done_section_test.js b/chrome/test/data/webui/chromeos/scanning/scan_done_section_test.js
index 8795e90a..dc27ece 100644
--- a/chrome/test/data/webui/chromeos/scanning/scan_done_section_test.js
+++ b/chrome/test/data/webui/chromeos/scanning/scan_done_section_test.js
@@ -114,4 +114,14 @@
       });
     });
   });
+
+  test('doneClick', () => {
+    let doneEventFired = false;
+    scanDoneSection.addEventListener('done-click', function() {
+      doneEventFired = true;
+    });
+
+    scanDoneSection.$$('#doneButton').click();
+    assertTrue(doneEventFired);
+  });
 }
diff --git a/chrome/test/data/webui/chromeos/scanning/scanner_select_test.js b/chrome/test/data/webui/chromeos/scanning/scanner_select_test.js
index 304084b1..9b4937cb 100644
--- a/chrome/test/data/webui/chromeos/scanning/scanner_select_test.js
+++ b/chrome/test/data/webui/chromeos/scanning/scanner_select_test.js
@@ -41,12 +41,6 @@
     const select = scannerSelect.$$('select');
     assertTrue(!!select);
 
-    // Verify that scanner connection help text is visible before adding
-    // scanners.
-    const helpLink = scannerSelect.$$('#scanHelp');
-    assertTrue(!!helpLink);
-    assertFalse(helpLink.hidden);
-
     const scannerArr = [
       createScanner(firstScannerId, firstScannerName),
       createScanner(secondScannerId, secondScannerName)
@@ -54,37 +48,13 @@
     scannerSelect.scanners = scannerArr;
     flush();
 
-    // Verify that adding scanners results in the dropdown becoming visible
-    // with the correct options and the help text being hidden.
     assertFalse(select.disabled);
-    assertTrue(helpLink.hidden);
-    // The expected options are the 2 scanners + the hidden 'No scanners'
-    // option.
-    assertEquals(3, select.length);
+    assertEquals(2, select.length);
     assertEquals(firstScannerName, select.options[0].textContent.trim());
     assertEquals(secondScannerName, select.options[1].textContent.trim());
-    assertTrue(select.options[2].hidden);
     assertEquals(tokenToString(firstScannerId), select.value);
   });
 
-  test('noScanners', () => {
-    const select = scannerSelect.$$('select');
-    assertTrue(!!select);
-    const helpLink = scannerSelect.$$('#scanHelp');
-    assertTrue(!!helpLink);
-
-    scannerSelect.loaded = true;
-    flush();
-
-    // Verify that scanner connection help text is visible.
-    assertFalse(helpLink.hidden);
-
-    // Verify the dropdown displays the default option when no scanners are
-    // available.
-    assertEquals(1, select.length);
-    assertEquals('No available scanners', select.options[0].textContent.trim());
-  });
-
   test('scannersSortedAlphabetically', () => {
     const scanners = [
       createScanner(secondScannerId, secondScannerName),
diff --git a/chrome/test/data/webui/chromeos/scanning/scanning_app_browsertest.js b/chrome/test/data/webui/chromeos/scanning/scanning_app_browsertest.js
index 865eb35..d5c5d00 100644
--- a/chrome/test/data/webui/chromeos/scanning/scanning_app_browsertest.js
+++ b/chrome/test/data/webui/chromeos/scanning/scanning_app_browsertest.js
@@ -51,9 +51,9 @@
 // You must register all suites in unified test here as well for consistency,
 // although technically is not necessary.
 const debug_suites_list = [
-  'ColorModeSelect', 'FileTypeSelect', 'PageSizeSelect', 'ResolutionSelect',
-  'ScanApp', 'ScanDoneSection', 'ScannerSelect', 'ScanPreview', 'ScanToSelect',
-  'SourceSelect'
+  'ColorModeSelect', 'FileTypeSelect', 'LoadingPage', 'PageSizeSelect',
+  'ResolutionSelect', 'ScanApp', 'ScanDoneSection', 'ScannerSelect',
+  'ScanPreview', 'ScanToSelect', 'SourceSelect'
 ];
 
 TEST_F('ScanningAppBrowserTest', 'All', function() {
diff --git a/chrome/test/data/webui/chromeos/scanning/scanning_app_test.js b/chrome/test/data/webui/chromeos/scanning/scanning_app_test.js
index 5a0840eb7..6451462 100644
--- a/chrome/test/data/webui/chromeos/scanning/scanning_app_test.js
+++ b/chrome/test/data/webui/chromeos/scanning/scanning_app_test.js
@@ -333,6 +333,8 @@
         document.createElement('scanning-app'));
     document.body.appendChild(scanningApp);
     assert(!!scanningApp);
+    assertTrue(isVisible(
+        /** @type {!HTMLElement} */ (scanningApp.$$('loading-page'))));
     return fakeScanService_.whenCalled('getScanners');
   }
 
@@ -393,6 +395,9 @@
 
     return initializeScanningApp(expectedScanners, capabilities)
         .then(() => {
+          assertFalse(isVisible(
+              /** @type {!HTMLElement} */ (scanningApp.$$('loading-page'))));
+
           scannerSelect = scanningApp.$$('#scannerSelect').$$('select');
           sourceSelect = scanningApp.$$('#sourceSelect').$$('select');
           fileTypeSelect = scanningApp.$$('#fileTypeSelect').$$('select');
@@ -750,4 +755,14 @@
           assertFalse(isSettingsOpen());
         });
   });
+
+  test('NoScanners', () => {
+    return initializeScanningApp(/*scanners=*/[], /*capabilities=*/ new Map())
+        .then(() => {
+          assertTrue(isVisible(
+              /** @type {!HTMLElement} */ (scanningApp.$$('loading-page'))));
+          assertFalse(isVisible(
+              /** @type {!HTMLElement} */ (scanningApp.$$('#panelContainer'))));
+        });
+  });
 }
diff --git a/chrome/test/data/webui/chromeos/scanning/scanning_app_unified_test.js b/chrome/test/data/webui/chromeos/scanning/scanning_app_unified_test.js
index 368e403..1c8f4319 100644
--- a/chrome/test/data/webui/chromeos/scanning/scanning_app_unified_test.js
+++ b/chrome/test/data/webui/chromeos/scanning/scanning_app_unified_test.js
@@ -12,6 +12,7 @@
 
 import {colorModeSelectTest} from './color_mode_select_test.js';
 import {fileTypeSelectTest} from './file_type_select_test.js';
+import {loadingPageTest} from './loading_page_test.js';
 import {pageSizeSelectTest} from './page_size_select_test.js';
 import {resolutionSelectTest} from './resolution_select_test.js';
 import {scanDoneSectionTest} from './scan_done_section_test.js';
@@ -30,6 +31,7 @@
 
 runSuite('ColorModeSelect', colorModeSelectTest);
 runSuite('FileTypeSelect', fileTypeSelectTest);
+runSuite('LoadingPage', loadingPageTest);
 runSuite('PageSizeSelect', pageSizeSelectTest);
 runSuite('ResolutionSelect', resolutionSelectTest);
 runSuite('ScanApp', scanningAppTest);
diff --git a/chrome/test/data/webui/commander/commander_app_test.js b/chrome/test/data/webui/commander/commander_app_test.js
index 60c2321..8e15456 100644
--- a/chrome/test/data/webui/commander/commander_app_test.js
+++ b/chrome/test/data/webui/commander/commander_app_test.js
@@ -91,8 +91,8 @@
     assertEquals(titles.length, optionElements.length);
 
     const actualTitles = Array.from(optionElements).map(el => {
-      return Array.from(el.shadowRoot.querySelectorAll('span'))
-          .map(span => span.innerText)
+      return Array.from(el.shadowRoot.querySelectorAll('.title-piece'))
+          .map(piece => piece.innerText)
           .join('');
     });
     assertDeepEquals(titles, actualTitles);
diff --git a/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_browsertest.js b/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_browsertest.js
index 3f7a5bd..4d577da9 100644
--- a/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_browsertest.js
+++ b/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_browsertest.js
@@ -56,13 +56,11 @@
   ['NetworkSiminfo', 'network/network_siminfo_test.js', []],
 ].forEach(test => registerTest('NetworkComponents', 'os-settings', ...test));
 
+// The only remaining host that uses the Polymer 2 version of <network-select>
+// is oobe/login.
 [
   ['NetworkSelect', 'network/network_select_test.js', []],
-].forEach(test => registerTest('NetworkComponents', 'network', ...test));
-
-[
-  ['RoutineGroup', 'network_health/routine_group_test.js', []],
-].forEach(test => registerTest('NetworkHealth', 'network', ...test));
+].forEach(test => registerTest('NetworkComponents', 'oobe/login', ...test));
 
 [
   // TODO(https://crbug.com/1173345): Reenable flaky test suite.
@@ -106,6 +104,9 @@
   this[className] = class extends Polymer2DeprecatedTest {
     /** @override */
     get browsePreload() {
+      if (webuiHost.includes('/')) {
+        return `chrome://${webuiHost}`;
+      }
       return `chrome://${webuiHost}/`;
     }
 
diff --git a/chrome/test/data/webui/cr_components/chromeos/network/network_select_test.js b/chrome/test/data/webui/cr_components/chromeos/network/network_select_test.js
index 3c909bf..a00d0d2 100644
--- a/chrome/test/data/webui/cr_components/chromeos/network/network_select_test.js
+++ b/chrome/test/data/webui/cr_components/chromeos/network/network_select_test.js
@@ -12,7 +12,12 @@
   /** @type {!NetworkSelect|undefined} */
   let networkSelect;
 
-  setup(function() {
+  setup(async function() {
+    // The OOBE host uses polyfill which requires the test to wait until HTML
+    // imports have finished loading before initiating any tests. The Polymer 3
+    // version of the test does not use the OOBE host so this line should not
+    // execute.
+    /* #ignore */ await cr.ui.Oobe.waitForOobeToLoad();
     networkSelect = document.createElement('network-select');
     document.body.appendChild(networkSelect);
     Polymer.dom.flush();
diff --git a/chrome/test/data/webui/settings/appearance_fonts_page_test.js b/chrome/test/data/webui/settings/appearance_fonts_page_test.js
index c6dda78..a85b5d6d 100644
--- a/chrome/test/data/webui/settings/appearance_fonts_page_test.js
+++ b/chrome/test/data/webui/settings/appearance_fonts_page_test.js
@@ -63,4 +63,33 @@
     fontsPage.set('prefs.webkit.webprefs.minimum_font_size.value', 0);
     assertTrue(fontsPage.$.minimumSizeSample.hidden);
   });
+
+  test('font preview size', async () => {
+    /**
+     * @param {!HTMLElement} element
+     * @param {number} expectedFontSize
+     */
+    function assertFontSize(element, expectedFontSize) {
+      // Check that the font size is applied correctly.
+      const {value, unit} = element.computedStyleMap().get('font-size');
+      assertEquals('px', unit);
+      assertEquals(expectedFontSize, value);
+      // Check that the font size value is displayed correctly.
+      assertTrue(element.textContent.trim().startsWith(expectedFontSize));
+    }
+
+    fontsPage.prefs = {
+      webkit: {
+        webprefs: {
+          default_font_size: {value: 20},
+          default_fixed_font_size: {value: 10},
+        }
+      }
+    };
+
+    assertFontSize(fontsPage.$.standardFontPreview, 20);
+    assertFontSize(fontsPage.$.serifFontPreview, 20);
+    assertFontSize(fontsPage.$.sansSerifFontPreview, 20);
+    assertFontSize(fontsPage.$.fixedFontPreview, 10);
+  });
 });
diff --git a/chrome/test/data/webui/settings/chromeos/people_page_account_manager_test.js b/chrome/test/data/webui/settings/chromeos/people_page_account_manager_test.js
index 9c97563..9908f6e 100644
--- a/chrome/test/data/webui/settings/chromeos/people_page_account_manager_test.js
+++ b/chrome/test/data/webui/settings/chromeos/people_page_account_manager_test.js
@@ -157,18 +157,17 @@
       settings.Router.getInstance().resetRouteForTesting();
     });
 
-    test('AccountListIsPopulatedAtStartup', function() {
-      return browserProxy.whenCalled('getAccounts').then(() => {
-        Polymer.dom.flush();
-        if (accountManager.isAccountManagementFlowsV2Enabled_) {
-          // 1 device account + 3 secondary accounts were added in
-          // |getAccounts()| mock above.
-          assertEquals(3, accountList.items.length);
-        } else {
-          // 4 accounts were added in |getAccounts()| mock above.
-          assertEquals(4, accountList.items.length);
-        }
-      });
+    test('AccountListIsPopulatedAtStartup', async function() {
+      await browserProxy.whenCalled('getAccounts');
+      Polymer.dom.flush();
+      if (accountManager.isAccountManagementFlowsV2Enabled_) {
+        // 1 device account + 3 secondary accounts were added in
+        // |getAccounts()| mock above.
+        assertEquals(3, accountList.items.length);
+      } else {
+        // 4 accounts were added in |getAccounts()| mock above.
+        assertEquals(4, accountList.items.length);
+      }
     });
 
     test('AddAccount', function() {
@@ -178,51 +177,45 @@
       assertEquals(1, browserProxy.getCallCount('addAccount'));
     });
 
-    test('ReauthenticateAccount', function() {
-      return browserProxy.whenCalled('getAccounts').then(() => {
-        Polymer.dom.flush();
-        accountManager.root.querySelectorAll('.reauth-button')[0].click();
-        assertEquals(1, browserProxy.getCallCount('reauthenticateAccount'));
-        return browserProxy.whenCalled('reauthenticateAccount')
-            .then((account_email) => {
-              assertEquals('user2@example.com', account_email);
-            });
-      });
+    test('ReauthenticateAccount', async function() {
+      await browserProxy.whenCalled('getAccounts');
+      Polymer.dom.flush();
+      accountManager.root.querySelectorAll('.reauth-button')[0].click();
+      assertEquals(1, browserProxy.getCallCount('reauthenticateAccount'));
+      const accountEmail =
+          await browserProxy.whenCalled('reauthenticateAccount');
+      assertEquals('user2@example.com', accountEmail);
     });
 
-    test('UnauthenticatedAccountLabel', function() {
-      return browserProxy.whenCalled('getAccounts').then(() => {
-        Polymer.dom.flush();
-        assertEquals(
-            loadTimeData.getString('accountManagerReauthenticationLabel'),
-            accountManager.root.querySelectorAll('.reauth-button')[0]
-                .textContent.trim());
-      });
+    test('UnauthenticatedAccountLabel', async function() {
+      await browserProxy.whenCalled('getAccounts');
+      Polymer.dom.flush();
+      assertEquals(
+          loadTimeData.getString('accountManagerReauthenticationLabel'),
+          accountManager.root.querySelectorAll('.reauth-button')[0]
+              .textContent.trim());
     });
 
-    test('UnmigratedAccountLabel', function() {
-      return browserProxy.whenCalled('getAccounts').then(() => {
-        Polymer.dom.flush();
-        assertEquals(
-            loadTimeData.getString('accountManagerMigrationLabel'),
-            accountManager.root.querySelectorAll('.reauth-button')[1]
-                .textContent.trim());
-      });
+    test('UnmigratedAccountLabel', async function() {
+      await browserProxy.whenCalled('getAccounts');
+      Polymer.dom.flush();
+      assertEquals(
+          loadTimeData.getString('accountManagerMigrationLabel'),
+          accountManager.root.querySelectorAll('.reauth-button')[1]
+              .textContent.trim());
     });
 
-    test('RemoveAccount', function() {
-      return browserProxy.whenCalled('getAccounts').then(() => {
-        Polymer.dom.flush();
-        // Click on 'More Actions' for the second account (First one (index 0)
-        // to have the hamburger menu).
-        accountManager.root.querySelectorAll('cr-icon-button')[0].click();
-        // Click on 'Remove account'
-        accountManager.$$('cr-action-menu').querySelector('button').click();
+    test('RemoveAccount', async function() {
+      await browserProxy.whenCalled('getAccounts');
+      Polymer.dom.flush();
+      // Click on 'More Actions' for the second account (First one (index 0)
+      // to have the hamburger menu).
+      accountManager.root.querySelectorAll('cr-icon-button')[0].click();
+      // Click on 'Remove account'
+      accountManager.$$('cr-action-menu').querySelector('button').click();
 
-        return browserProxy.whenCalled('removeAccount').then((account) => {
-          assertEquals('456', account.id);
-        });
-      });
+      const account = await browserProxy.whenCalled('removeAccount');
+      assertEquals('456', account.id);
     });
 
     test('Deep link to remove account button', async () => {
@@ -256,22 +249,21 @@
       assertGT(browserProxy.getCallCount('showWelcomeDialogIfRequired'), 0);
     });
 
-    test('ManagementStatusForManagedAccounts', function() {
-      return browserProxy.whenCalled('getAccounts').then(() => {
-        Polymer.dom.flush();
+    test('ManagementStatusForManagedAccounts', async function() {
+      await browserProxy.whenCalled('getAccounts');
+      Polymer.dom.flush();
 
-        if (accountManager.isAccountManagementFlowsV2Enabled_) {
-          const managedBadge = accountManager.root.querySelector(
-              '.device-account-icon .managed-badge');
-          // Managed badge should be shown for managed accounts.
-          assertFalse(managedBadge.hidden);
-        } else {
-          const managementLabel =
-              accountManager.root.querySelectorAll('.management-status')[0]
-                  .innerHTML.trim();
-          assertEquals('Managed by Family Link', managementLabel);
-        }
-      });
+      if (accountManager.isAccountManagementFlowsV2Enabled_) {
+        const managedBadge = accountManager.root.querySelector(
+            '.device-account-icon .managed-badge');
+        // Managed badge should be shown for managed accounts.
+        assertFalse(managedBadge.hidden);
+      } else {
+        const managementLabel =
+            accountManager.root.querySelectorAll('.management-status')[0]
+                .innerHTML.trim();
+        assertEquals('Managed by Family Link', managementLabel);
+      }
     });
   });
 
@@ -301,22 +293,21 @@
       accountManager.remove();
     });
 
-    test('ManagementStatusForUnmanagedAccounts', function() {
-      return browserProxy.whenCalled('getAccounts').then(() => {
-        Polymer.dom.flush();
+    test('ManagementStatusForUnmanagedAccounts', async function() {
+      await browserProxy.whenCalled('getAccounts');
+      Polymer.dom.flush();
 
-        if (accountManager.isAccountManagementFlowsV2Enabled_) {
-          const managedBadge = accountManager.root.querySelector(
-              '.device-account-icon .managed-badge');
-          // Managed badge should not be shown for unmanaged accounts.
-          assertEquals(null, managedBadge);
-        } else {
-          const managementLabel =
-              accountManager.root.querySelectorAll('.management-status')[0]
-                  .innerHTML.trim();
-          assertEquals('Primary account', managementLabel);
-        }
-      });
+      if (accountManager.isAccountManagementFlowsV2Enabled_) {
+        const managedBadge = accountManager.root.querySelector(
+            '.device-account-icon .managed-badge');
+        // Managed badge should not be shown for unmanaged accounts.
+        assertEquals(null, managedBadge);
+      } else {
+        const managementLabel =
+            accountManager.root.querySelectorAll('.management-status')[0]
+                .innerHTML.trim();
+        assertEquals('Primary account', managementLabel);
+      }
     });
   });
 
diff --git a/chrome/test/data/webui/settings/chromeos/people_page_change_picture_test.js b/chrome/test/data/webui/settings/chromeos/people_page_change_picture_test.js
index 3424939b..e76401c4 100644
--- a/chrome/test/data/webui/settings/chromeos/people_page_change_picture_test.js
+++ b/chrome/test/data/webui/settings/chromeos/people_page_change_picture_test.js
@@ -69,7 +69,7 @@
     /** @override */
     selectDefaultImage(imageUrl) {
       cr.webUIListenerCallback('selected-image-changed', imageUrl);
-      this.methodCalled('selectDefaultImage', [imageUrl]);
+      this.methodCalled('selectDefaultImage', imageUrl);
     }
 
     /** @override */
@@ -136,7 +136,7 @@
       });
     });
 
-    setup(function() {
+    setup(async function() {
       browserProxy = new TestChangePictureBrowserProxy();
       settings.ChangePictureBrowserProxyImpl.instance_ = browserProxy;
       PolymerTest.clearBody();
@@ -151,9 +151,8 @@
 
       changePicture.currentRouteChanged(settings.routes.CHANGE_PICTURE);
 
-      return browserProxy.whenCalled('initialize').then(function() {
-        Polymer.dom.flush();
-      });
+      await browserProxy.whenCalled('initialize');
+      Polymer.dom.flush();
     });
 
     teardown(function() {
@@ -211,86 +210,77 @@
       assertFalse(activeElementPath.includes(crPictureList));
     });
 
-    test('ChangePictureSelectCamera', function() {
+    test('ChangePictureSelectCamera', async function() {
       // Force the camera to be absent, even if it's actually present.
       cr.webUIListenerCallback('camera-presence-changed', false);
       Polymer.dom.flush();
 
-      return new Promise(function(resolve) {
-               changePicture.async(resolve);
-             })
-          .then(function() {
-            const camera = crPicturePane.$$('#camera');
-            expectFalse(crPicturePane.cameraPresent);
-            expectFalse(crPicturePane.cameraActive_);
-            expectFalse(!!camera && camera.hidden);
+      await new Promise(function(resolve) {
+        changePicture.async(resolve);
+      });
+      let camera = crPicturePane.$$('#camera');
+      expectFalse(crPicturePane.cameraPresent);
+      expectFalse(crPicturePane.cameraActive_);
+      expectFalse(!!camera && camera.hidden);
 
-            cr.webUIListenerCallback('camera-presence-changed', true);
-            Polymer.dom.flush();
-            return new Promise(function(resolve) {
-              changePicture.async(resolve);
-            });
-          })
-          .then(function() {
-            const camera = crPicturePane.$$('#camera');
-            expectTrue(crPicturePane.cameraPresent);
-            expectFalse(crPicturePane.cameraActive_);
-            expectFalse(!!camera && camera.hidden);
+      cr.webUIListenerCallback('camera-presence-changed', true);
+      Polymer.dom.flush();
+      await new Promise(function(resolve) {
+        changePicture.async(resolve);
+      });
+      camera = crPicturePane.$$('#camera');
+      expectTrue(crPicturePane.cameraPresent);
+      expectFalse(crPicturePane.cameraActive_);
+      expectFalse(!!camera && camera.hidden);
 
-            const cameraImage = crPictureList.$.cameraImage;
-            cameraImage.click();
-            Polymer.dom.flush();
-            return new Promise(function(resolve) {
-              changePicture.async(resolve);
-            });
-          })
-          .then(function() {
-            const camera = crPicturePane.$$('#camera');
-            expectTrue(crPicturePane.cameraActive_);
-            assertTrue(!!camera && !camera.hidden);
-            expectEquals(
-                CrPicture.SelectionTypes.CAMERA,
-                changePicture.selectedItem_.dataset.type);
-            const discard = crPicturePane.$$('#discard');
-            expectTrue(!discard || discard.hidden);
+      const cameraImage = crPictureList.$.cameraImage;
+      cameraImage.click();
+      Polymer.dom.flush();
+      await new Promise(function(resolve) {
+        changePicture.async(resolve);
+      });
+      camera = crPicturePane.$$('#camera');
+      expectTrue(crPicturePane.cameraActive_);
+      assertTrue(!!camera && !camera.hidden);
+      expectEquals(
+          CrPicture.SelectionTypes.CAMERA,
+          changePicture.selectedItem_.dataset.type);
+      const discard = crPicturePane.$$('#discard');
+      expectTrue(!discard || discard.hidden);
 
-            // Ensure that the camera is deactivated if user navigates away.
-            changePicture.currentRouteChanged(settings.routes.BASIC);
-            return new Promise(function(resolve) {
-              changePicture.async(resolve);
-            });
-          })
-          .then(function() {
-            expectFalse(crPicturePane.cameraActive_);
-          });
+      // Ensure that the camera is deactivated if user navigates away.
+      changePicture.currentRouteChanged(settings.routes.BASIC);
+      await new Promise(function(resolve) {
+        changePicture.async(resolve);
+      });
+      expectFalse(crPicturePane.cameraActive_);
     });
 
-    test('ChangePictureProfileImage', function() {
+    test('ChangePictureProfileImage', async function() {
       const profileImage = crPictureList.$.profileImage;
       assertTrue(!!profileImage);
 
       expectEquals(null, changePicture.selectedItem_);
       profileImage.click();
 
-      return browserProxy.whenCalled('selectProfileImage').then(function() {
-        Polymer.dom.flush();
+      await browserProxy.whenCalled('selectProfileImage');
+      Polymer.dom.flush();
 
-        expectEquals(
-            CrPicture.SelectionTypes.PROFILE,
-            changePicture.selectedItem_.dataset.type);
-        expectFalse(crPicturePane.cameraActive_);
-        const discard = crPicturePane.$$('#discard');
-        expectTrue(!discard || discard.hidden);
+      expectEquals(
+          CrPicture.SelectionTypes.PROFILE,
+          changePicture.selectedItem_.dataset.type);
+      expectFalse(crPicturePane.cameraActive_);
+      const discard = crPicturePane.$$('#discard');
+      expectTrue(!discard || discard.hidden);
 
-        // Ensure that the selection is restored after navigating away and
-        // then back to the subpage.
-        changePicture.currentRouteChanged(settings.routes.BASIC);
-        changePicture.currentRouteChanged(settings.routes.CHANGE_PICTURE);
-        expectEquals(null, changePicture.selectedItem_);
-      });
+      // Ensure that the selection is restored after navigating away and
+      // then back to the subpage.
+      changePicture.currentRouteChanged(settings.routes.BASIC);
+      changePicture.currentRouteChanged(settings.routes.CHANGE_PICTURE);
+      expectEquals(null, changePicture.selectedItem_);
     });
 
-    test('ChangePictureOldImage', function() {
+    test('ChangePictureOldImage', async function() {
       assertFalse(!!changePicture.selectedItem_);
 
       // By default there is no old image and the element is hidden.
@@ -304,29 +294,27 @@
       });
       Polymer.dom.flush();
 
-      return new Promise(function(resolve) {
-               changePicture.async(resolve);
-             })
-          .then(function() {
-            assertTrue(!!changePicture.selectedItem_);
-            // Expect the old image to be selected once an old image is sent via
-            // the native interface.
-            expectEquals(
-                CrPicture.SelectionTypes.OLD,
-                changePicture.selectedItem_.dataset.type);
-            expectFalse(oldImage.hidden);
-            expectFalse(crPicturePane.cameraActive_);
-            const discard = crPicturePane.$$('#discard');
-            assertTrue(!!discard);
-            expectFalse(discard.hidden);
-            // Ensure the old image shows the author credit.
-            const credit = changePicture.$$('#authorCredit');
-            assertTrue(!!credit);
-            expectFalse(credit.hidden);
-          });
+      await new Promise(function(resolve) {
+        changePicture.async(resolve);
+      });
+      assertTrue(!!changePicture.selectedItem_);
+      // Expect the old image to be selected once an old image is sent via
+      // the native interface.
+      expectEquals(
+          CrPicture.SelectionTypes.OLD,
+          changePicture.selectedItem_.dataset.type);
+      expectFalse(oldImage.hidden);
+      expectFalse(crPicturePane.cameraActive_);
+      const discard = crPicturePane.$$('#discard');
+      assertTrue(!!discard);
+      expectFalse(discard.hidden);
+      // Ensure the old image shows the author credit.
+      const credit = changePicture.$$('#authorCredit');
+      assertTrue(!!credit);
+      expectFalse(credit.hidden);
     });
 
-    test('ChangePictureFileImage', function() {
+    test('ChangePictureFileImage', async function() {
       assertFalse(!!changePicture.selectedItem_);
 
       // By default there is no old image and the element is hidden.
@@ -340,86 +328,79 @@
       });
       Polymer.dom.flush();
 
-      return new Promise(function(resolve) {
-               changePicture.async(resolve);
-             })
-          .then(function() {
-            assertTrue(!!changePicture.selectedItem_);
-            // Expect the old image to be selected once an old image is sent via
-            // the native interface.
-            expectEquals(
-                CrPicture.SelectionTypes.OLD,
-                changePicture.selectedItem_.dataset.type);
-            expectFalse(oldImage.hidden);
-            expectFalse(crPicturePane.cameraActive_);
-            const discard = crPicturePane.$$('#discard');
-            assertTrue(!!discard);
-            expectFalse(discard.hidden);
-            // Ensure the file image does not show the author credit.
-            const credit = changePicture.$$('#authorCredit');
-            assertTrue(!credit || credit.hidden);
-          });
-    });
-
-    test('ChangePictureSelectFirstDefaultImage', function() {
-      const firstDefaultImage = crPictureList.$$('img[data-type="default"]');
-      assertTrue(!!firstDefaultImage);
-
-      firstDefaultImage.click();
-
-      return browserProxy.whenCalled('selectDefaultImage')
-          .then(function(args) {
-            expectEquals('chrome://foo/2.png', args[0]);
-
-            Polymer.dom.flush();
-            expectEquals(
-                CrPicture.SelectionTypes.DEFAULT,
-                changePicture.selectedItem_.dataset.type);
-            expectEquals(firstDefaultImage, changePicture.selectedItem_);
-            expectFalse(crPicturePane.cameraActive_);
-            const discard = crPicturePane.$$('#discard');
-            expectTrue(!discard || discard.hidden);
-
-            // Now verify that arrow keys actually select the new image.
-            browserProxy.resetResolver('selectDefaultImage');
-            MockInteractions.pressAndReleaseKeyOn(
-                changePicture.selectedItem_, RIGHT_KEY_CODE);
-            return browserProxy.whenCalled('selectDefaultImage');
-          })
-          .then(function(args) {
-            expectEquals('chrome://foo/3.png', args[0]);
-          });
-    });
-
-    test('ChangePictureRestoreImageAfterDiscard', function() {
-      const firstDefaultImage = crPictureList.$$('img[data-type="default"]');
-      assertTrue(!!firstDefaultImage);
-
-      firstDefaultImage.click();
-
-      return browserProxy.whenCalled('selectDefaultImage').then(function() {
-        Polymer.dom.flush();
-        expectEquals(firstDefaultImage, changePicture.selectedItem_);
-
-        cr.webUIListenerCallback('old-image-changed', {
-          url: 'fake-old-image.jpg',
-          index: 1,
-        });
-
-        Polymer.dom.flush();
-        expectEquals(
-            CrPicture.SelectionTypes.OLD,
-            changePicture.selectedItem_.dataset.type);
-
-        const discardButton = crPicturePane.$$('#discard cr-icon-button');
-        assertTrue(!!discardButton);
-        discardButton.click();
-
-        Polymer.dom.flush();
-        const profileImage = crPictureList.$.profileImage;
-        assertTrue(!!profileImage);
-        expectEquals(profileImage, changePicture.selectedItem_);
+      await new Promise(function(resolve) {
+        changePicture.async(resolve);
       });
+      assertTrue(!!changePicture.selectedItem_);
+      // Expect the old image to be selected once an old image is sent via
+      // the native interface.
+      expectEquals(
+          CrPicture.SelectionTypes.OLD,
+          changePicture.selectedItem_.dataset.type);
+      expectFalse(oldImage.hidden);
+      expectFalse(crPicturePane.cameraActive_);
+      const discard = crPicturePane.$$('#discard');
+      assertTrue(!!discard);
+      expectFalse(discard.hidden);
+      // Ensure the file image does not show the author credit.
+      const credit = changePicture.$$('#authorCredit');
+      assertTrue(!credit || credit.hidden);
+    });
+
+    test('ChangePictureSelectFirstDefaultImage', async function() {
+      const firstDefaultImage = crPictureList.$$('img[data-type="default"]');
+      assertTrue(!!firstDefaultImage);
+
+      firstDefaultImage.click();
+
+      let imageUrl = await browserProxy.whenCalled('selectDefaultImage');
+      expectEquals('chrome://foo/2.png', imageUrl);
+
+      Polymer.dom.flush();
+      expectEquals(
+          CrPicture.SelectionTypes.DEFAULT,
+          changePicture.selectedItem_.dataset.type);
+      expectEquals(firstDefaultImage, changePicture.selectedItem_);
+      expectFalse(crPicturePane.cameraActive_);
+      const discard = crPicturePane.$$('#discard');
+      expectTrue(!discard || discard.hidden);
+
+      // Now verify that arrow keys actually select the new image.
+      browserProxy.resetResolver('selectDefaultImage');
+      MockInteractions.pressAndReleaseKeyOn(
+          changePicture.selectedItem_, RIGHT_KEY_CODE);
+      imageUrl = await browserProxy.whenCalled('selectDefaultImage');
+      expectEquals('chrome://foo/3.png', imageUrl);
+    });
+
+    test('ChangePictureRestoreImageAfterDiscard', async function() {
+      const firstDefaultImage = crPictureList.$$('img[data-type="default"]');
+      assertTrue(!!firstDefaultImage);
+
+      firstDefaultImage.click();
+
+      await browserProxy.whenCalled('selectDefaultImage');
+      Polymer.dom.flush();
+      expectEquals(firstDefaultImage, changePicture.selectedItem_);
+
+      cr.webUIListenerCallback('old-image-changed', {
+        url: 'fake-old-image.jpg',
+        index: 1,
+      });
+
+      Polymer.dom.flush();
+      expectEquals(
+          CrPicture.SelectionTypes.OLD,
+          changePicture.selectedItem_.dataset.type);
+
+      const discardButton = crPicturePane.$$('#discard cr-icon-button');
+      assertTrue(!!discardButton);
+      discardButton.click();
+
+      Polymer.dom.flush();
+      const profileImage = crPictureList.$.profileImage;
+      assertTrue(!!profileImage);
+      expectEquals(profileImage, changePicture.selectedItem_);
     });
   });
 
diff --git a/chrome/test/data/webui/settings/people_page_manage_profile_test.js b/chrome/test/data/webui/settings/people_page_manage_profile_test.js
index 0bce4ea..a63aa00 100644
--- a/chrome/test/data/webui/settings/people_page_manage_profile_test.js
+++ b/chrome/test/data/webui/settings/people_page_manage_profile_test.js
@@ -241,7 +241,7 @@
 
       // Simulate tapping the profile shortcut toggle.
       hasShortcutToggle.click();
-      return browserProxy.whenCalled('addProfileShortcut');
+      await browserProxy.whenCalled('addProfileShortcut');
     }
     setFlags({newProfilePicker: false, profileShortcutsEnabled: true});
     await profileShortcutToggle();
diff --git a/chrome/test/data/webui/settings/people_page_sync_controls_test.js b/chrome/test/data/webui/settings/people_page_sync_controls_test.js
index 52e422a..2ce8fa7 100644
--- a/chrome/test/data/webui/settings/people_page_sync_controls_test.js
+++ b/chrome/test/data/webui/settings/people_page_sync_controls_test.js
@@ -15,13 +15,13 @@
 
 // clang-format on
 
-suite('SyncControlsTest', function() {
+suite('SyncControlsTest', async function() {
   let syncControls = null;
   let browserProxy = null;
   let syncEverything = null;
   let customizeSync = null;
 
-  setup(function() {
+  setup(async function() {
     setupRouterWithSyncRoutes();
     browserProxy = new TestSyncBrowserProxy();
     SyncBrowserProxyImpl.instance_ = browserProxy;
@@ -34,13 +34,11 @@
     webUIListenerCallback('sync-prefs-changed', getSyncAllPrefs());
     flush();
 
-    return waitBeforeNextRender().then(() => {
-      syncEverything =
-          syncControls.$$('cr-radio-button[name="sync-everything"]');
-      customizeSync = syncControls.$$('cr-radio-button[name="customize-sync"]');
-      assertTrue(!!syncEverything);
-      assertTrue(!!customizeSync);
-    });
+    await waitBeforeNextRender();
+    syncEverything = syncControls.$$('cr-radio-button[name="sync-everything"]');
+    customizeSync = syncControls.$$('cr-radio-button[name="customize-sync"]');
+    assertTrue(!!syncEverything);
+    assertTrue(!!customizeSync);
   });
 
   teardown(function() {
@@ -67,7 +65,7 @@
     browserProxy.resetResolver('setSyncDatatypes');
   }
 
-  test('SettingIndividualDatatypes', function() {
+  test('SettingIndividualDatatypes', async function() {
     assertTrue(syncEverything.checked);
     assertFalse(customizeSync.checked);
     assertEquals(syncControls.$$('#syncAllDataTypesControl'), null);
@@ -87,8 +85,8 @@
     assertFalse(syncEverything.checked);
     assertTrue(customizeSync.checked);
 
-    return browserProxy.whenCalled('setSyncDatatypes')
-        .then(prefs => assertPrefs(prefs, datatypeControls));
+    const prefs = await browserProxy.whenCalled('setSyncDatatypes');
+    assertPrefs(prefs, datatypeControls);
   });
 
   test('SignedIn', function() {
diff --git a/chrome/test/data/webui/settings/people_page_sync_page_test.js b/chrome/test/data/webui/settings/people_page_sync_page_test.js
index 913638f..97365908 100644
--- a/chrome/test/data/webui/settings/people_page_sync_page_test.js
+++ b/chrome/test/data/webui/settings/people_page_sync_page_test.js
@@ -58,25 +58,24 @@
     loadTimeData.overrideValues({signinAllowed: true});
   });
 
-  setup(function() {
+  setup(async function() {
     setupRouterWithSyncRoutes();
     browserProxy = new TestSyncBrowserProxy();
     SyncBrowserProxyImpl.instance_ = browserProxy;
 
     setupSyncPage();
 
-    return waitBeforeNextRender().then(() => {
-      encryptionElement = syncPage.$$('settings-sync-encryption-options');
-      assertTrue(!!encryptionElement);
-      encryptionRadioGroup = encryptionElement.$$('#encryptionRadioGroup');
-      encryptWithGoogle =
-          encryptionElement.$$('cr-radio-button[name="encrypt-with-google"]');
-      encryptWithPassphrase = encryptionElement.$$(
-          'cr-radio-button[name="encrypt-with-passphrase"]');
-      assertTrue(!!encryptionRadioGroup);
-      assertTrue(!!encryptWithGoogle);
-      assertTrue(!!encryptWithPassphrase);
-    });
+    await waitBeforeNextRender();
+    encryptionElement = syncPage.$$('settings-sync-encryption-options');
+    assertTrue(!!encryptionElement);
+    encryptionRadioGroup = encryptionElement.$$('#encryptionRadioGroup');
+    encryptWithGoogle =
+        encryptionElement.$$('cr-radio-button[name="encrypt-with-google"]');
+    encryptWithPassphrase =
+        encryptionElement.$$('cr-radio-button[name="encrypt-with-passphrase"]');
+    assertTrue(!!encryptionRadioGroup);
+    assertTrue(!!encryptWithGoogle);
+    assertTrue(!!encryptWithPassphrase);
   });
 
   teardown(function() {
@@ -87,39 +86,30 @@
   // TESTS FOR ALL PLATFORMS
   // #######################
 
-  test('NotifiesHandlerOfNavigation', function() {
+  test('NotifiesHandlerOfNavigation', async function() {
+    await browserProxy.whenCalled('didNavigateToSyncPage');
+
+    // Navigate away.
     const router = Router.getInstance();
-    function testNavigateAway() {
-      router.navigateTo(router.getRoutes().PEOPLE);
-      return browserProxy.whenCalled('didNavigateAwayFromSyncPage');
-    }
+    router.navigateTo(router.getRoutes().PEOPLE);
+    await browserProxy.whenCalled('didNavigateAwayFromSyncPage');
 
-    function testNavigateBack() {
-      browserProxy.resetResolver('didNavigateToSyncPage');
-      router.navigateTo(router.getRoutes().SYNC);
-      return browserProxy.whenCalled('didNavigateToSyncPage');
-    }
+    // Navigate back to the page.
+    browserProxy.resetResolver('didNavigateToSyncPage');
+    router.navigateTo(router.getRoutes().SYNC);
+    await browserProxy.whenCalled('didNavigateToSyncPage');
 
-    function testDetach() {
-      browserProxy.resetResolver('didNavigateAwayFromSyncPage');
-      syncPage.remove();
-      return browserProxy.whenCalled('didNavigateAwayFromSyncPage');
-    }
+    // Remove page element.
+    browserProxy.resetResolver('didNavigateAwayFromSyncPage');
+    syncPage.remove();
+    await browserProxy.whenCalled('didNavigateAwayFromSyncPage');
 
-    function testRecreate() {
-      browserProxy.resetResolver('didNavigateToSyncPage');
-      syncPage = document.createElement('settings-sync-page');
-      router.navigateTo(router.getRoutes().SYNC);
-
-      document.body.appendChild(syncPage);
-      return browserProxy.whenCalled('didNavigateToSyncPage');
-    }
-
-    return browserProxy.whenCalled('didNavigateToSyncPage')
-        .then(testNavigateAway)
-        .then(testNavigateBack)
-        .then(testDetach)
-        .then(testRecreate);
+    // Recreate page element.
+    browserProxy.resetResolver('didNavigateToSyncPage');
+    syncPage = document.createElement('settings-sync-page');
+    router.navigateTo(router.getRoutes().SYNC);
+    document.body.appendChild(syncPage);
+    await browserProxy.whenCalled('didNavigateToSyncPage');
   });
 
   test('SyncSectionLayout_SignedIn', function() {
@@ -559,7 +549,7 @@
   // ##################################
 
   if (!isChromeOS) {
-    test('SyncSetupCancel', function() {
+    test('SyncSetupCancel', async function() {
       syncPage.syncStatus = {
         syncSystemEnabled: true,
         firstSetupInProgress: true,
@@ -575,13 +565,12 @@
 
       // Clicking the setup cancel button aborts sync.
       cancelButton.click();
-      return browserProxy.whenCalled('didNavigateAwayFromSyncPage')
-          .then(abort => {
-            assertTrue(abort);
-          });
+      const abort =
+          await browserProxy.whenCalled('didNavigateAwayFromSyncPage');
+      assertTrue(abort);
     });
 
-    test('SyncSetupConfirm', function() {
+    test('SyncSetupConfirm', async function() {
       syncPage.syncStatus = {
         syncSystemEnabled: true,
         firstSetupInProgress: true,
@@ -597,13 +586,12 @@
       assertTrue(!!confirmButton);
       confirmButton.click();
 
-      return browserProxy.whenCalled('didNavigateAwayFromSyncPage')
-          .then(abort => {
-            assertFalse(abort);
-          });
+      const abort =
+          await browserProxy.whenCalled('didNavigateAwayFromSyncPage');
+      assertFalse(abort);
     });
 
-    test('SyncSetupLeavePage', function() {
+    test('SyncSetupLeavePage', async function() {
       syncPage.syncStatus = {
         syncSystemEnabled: true,
         firstSetupInProgress: true,
@@ -615,44 +603,32 @@
       // dialog.
       const router = Router.getInstance();
       router.navigateTo(routes.BASIC);
-      return eventToPromise('cr-dialog-open', syncPage)
-          .then(() => {
-            assertEquals(router.getRoutes().SYNC, router.getCurrentRoute());
-            assertTrue(syncPage.$$('#setupCancelDialog').open);
+      await eventToPromise('cr-dialog-open', syncPage);
+      assertEquals(router.getRoutes().SYNC, router.getCurrentRoute());
+      assertTrue(syncPage.$$('#setupCancelDialog').open);
 
-            // Clicking the cancel button on the 'Cancel sync?' dialog closes
-            // the dialog and removes it from the DOM.
-            syncPage.$$('#setupCancelDialog')
-                .querySelector('.cancel-button')
-                .click();
+      // Clicking the cancel button on the 'Cancel sync?' dialog closes
+      // the dialog and removes it from the DOM.
+      syncPage.$$('#setupCancelDialog').querySelector('.cancel-button').click();
+      await eventToPromise('close', syncPage.$$('#setupCancelDialog'));
+      flush();
+      assertEquals(router.getRoutes().SYNC, router.getCurrentRoute());
+      assertFalse(!!syncPage.$$('#setupCancelDialog'));
 
-            return eventToPromise('close', syncPage.$$('#setupCancelDialog'));
-          })
-          .then(() => {
-            flush();
-            assertEquals(router.getRoutes().SYNC, router.getCurrentRoute());
-            assertFalse(!!syncPage.$$('#setupCancelDialog'));
+      // Navigating away while setup is in progress opens the
+      // dialog again.
+      router.navigateTo(routes.BASIC);
+      await eventToPromise('cr-dialog-open', syncPage);
+      assertTrue(syncPage.$$('#setupCancelDialog').open);
 
-            // Navigating away while setup is in progress opens the
-            // dialog again.
-            router.navigateTo(routes.BASIC);
-            return eventToPromise('cr-dialog-open', syncPage);
-          })
-          .then(() => {
-            assertTrue(syncPage.$$('#setupCancelDialog').open);
-
-            // Clicking the confirm button on the dialog aborts sync.
-            syncPage.$$('#setupCancelDialog')
-                .querySelector('.action-button')
-                .click();
-            return browserProxy.whenCalled('didNavigateAwayFromSyncPage');
-          })
-          .then(abort => {
-            assertTrue(abort);
-          });
+      // Clicking the confirm button on the dialog aborts sync.
+      syncPage.$$('#setupCancelDialog').querySelector('.action-button').click();
+      const abort =
+          await browserProxy.whenCalled('didNavigateAwayFromSyncPage');
+      assertTrue(abort);
     });
 
-    test('SyncSetupSearchSettings', function() {
+    test('SyncSetupSearchSettings', async function() {
       syncPage.syncStatus = {
         syncSystemEnabled: true,
         firstSetupInProgress: true,
@@ -665,10 +641,9 @@
       router.navigateTo(
           router.getRoutes().BASIC, new URLSearchParams('search=foo'));
 
-      return browserProxy.whenCalled('didNavigateAwayFromSyncPage')
-          .then(abort => {
-            assertTrue(abort);
-          });
+      const abort =
+          await browserProxy.whenCalled('didNavigateAwayFromSyncPage');
+      assertTrue(abort);
     });
 
     test('ShowAccountRow', function() {
diff --git a/chrome/test/data/webui/settings/people_page_test.js b/chrome/test/data/webui/settings/people_page_test.js
index 5b06b12..5c426cb 100644
--- a/chrome/test/data/webui/settings/people_page_test.js
+++ b/chrome/test/data/webui/settings/people_page_test.js
@@ -110,21 +110,20 @@
       peoplePage.remove();
     });
 
-    test('ShowCorrectRows', function() {
-      return syncBrowserProxy.whenCalled('getSyncStatus').then(function() {
-        flush();
+    test('ShowCorrectRows', async function() {
+      await syncBrowserProxy.whenCalled('getSyncStatus');
+      flush();
 
-        // The correct /manageProfile link row is shown.
-        assertFalse(!!peoplePage.$$('#edit-profile'));
-        assertTrue(!!peoplePage.$$('#profile-row'));
+      // The correct /manageProfile link row is shown.
+      assertFalse(!!peoplePage.$$('#edit-profile'));
+      assertTrue(!!peoplePage.$$('#profile-row'));
 
-        // Control element doesn't exist when policy forbids sync.
-        simulateSyncStatus({
-          signedIn: false,
-          syncSystemEnabled: true,
-        });
-        assertFalse(!!peoplePage.$$('settings-sync-account-control'));
+      // Control element doesn't exist when policy forbids sync.
+      simulateSyncStatus({
+        signedIn: false,
+        syncSystemEnabled: true,
       });
+      assertFalse(!!peoplePage.$$('settings-sync-account-control'));
     });
   });
 
@@ -153,289 +152,246 @@
       assertTrue(peoplePage.$.toast.open);
     });
 
-    test('ShowCorrectRows', function() {
-      return syncBrowserProxy.whenCalled('getSyncStatus').then(function() {
-        simulateSyncStatus({
-          syncSystemEnabled: true,
-        });
-        flush();
+    test('ShowCorrectRows', async function() {
+      await syncBrowserProxy.whenCalled('getSyncStatus');
+      simulateSyncStatus({
+        syncSystemEnabled: true,
+      });
+      flush();
 
-        // The correct /manageProfile link row is shown.
-        assertTrue(!!peoplePage.$$('#edit-profile'));
-        assertFalse(!!peoplePage.$$('#profile-row'));
+      // The correct /manageProfile link row is shown.
+      assertTrue(!!peoplePage.$$('#edit-profile'));
+      assertFalse(!!peoplePage.$$('#profile-row'));
 
-        simulateSyncStatus({
-          signedIn: false,
-          syncSystemEnabled: true,
-        });
+      simulateSyncStatus({
+        signedIn: false,
+        syncSystemEnabled: true,
+      });
 
-        // The control element should exist when policy allows.
-        const accountControl = peoplePage.$$('settings-sync-account-control');
-        assertTrue(
-            window.getComputedStyle(accountControl)['display'] !== 'none');
+      // The control element should exist when policy allows.
+      const accountControl = peoplePage.$$('settings-sync-account-control');
+      assertTrue(window.getComputedStyle(accountControl)['display'] !== 'none');
 
-        // Control element doesn't exist when policy forbids sync.
-        simulateSyncStatus({
-          syncSystemEnabled: false,
-        });
-        assertEquals(
-            'none', window.getComputedStyle(accountControl)['display']);
+      // Control element doesn't exist when policy forbids sync.
+      simulateSyncStatus({
+        syncSystemEnabled: false,
+      });
+      assertEquals('none', window.getComputedStyle(accountControl)['display']);
 
-        const manageGoogleAccount = peoplePage.$$('#manage-google-account');
+      const manageGoogleAccount = peoplePage.$$('#manage-google-account');
 
-        // Do not show Google Account when stored accounts or sync status
-        // could not be retrieved.
-        simulateStoredAccounts(undefined);
-        simulateSyncStatus(undefined);
-        assertEquals(
-            'none', window.getComputedStyle(manageGoogleAccount)['display']);
+      // Do not show Google Account when stored accounts or sync status
+      // could not be retrieved.
+      simulateStoredAccounts(undefined);
+      simulateSyncStatus(undefined);
+      assertEquals(
+          'none', window.getComputedStyle(manageGoogleAccount)['display']);
 
-        simulateStoredAccounts([]);
-        simulateSyncStatus(undefined);
-        assertEquals(
-            'none', window.getComputedStyle(manageGoogleAccount)['display']);
+      simulateStoredAccounts([]);
+      simulateSyncStatus(undefined);
+      assertEquals(
+          'none', window.getComputedStyle(manageGoogleAccount)['display']);
 
-        simulateStoredAccounts(undefined);
-        simulateSyncStatus({});
-        assertEquals(
-            'none', window.getComputedStyle(manageGoogleAccount)['display']);
+      simulateStoredAccounts(undefined);
+      simulateSyncStatus({});
+      assertEquals(
+          'none', window.getComputedStyle(manageGoogleAccount)['display']);
 
-        simulateStoredAccounts([]);
-        simulateSyncStatus({});
-        assertEquals(
-            'none', window.getComputedStyle(manageGoogleAccount)['display']);
+      simulateStoredAccounts([]);
+      simulateSyncStatus({});
+      assertEquals(
+          'none', window.getComputedStyle(manageGoogleAccount)['display']);
 
-        // A stored account with sync off but no error should result in the
-        // Google Account being shown.
-        simulateStoredAccounts([{email: 'foo@foo.com'}]);
-        simulateSyncStatus({
-          signedIn: false,
-          hasError: false,
-        });
-        assertTrue(
-            window.getComputedStyle(manageGoogleAccount)['display'] !== 'none');
+      // A stored account with sync off but no error should result in the
+      // Google Account being shown.
+      simulateStoredAccounts([{email: 'foo@foo.com'}]);
+      simulateSyncStatus({
+        signedIn: false,
+        hasError: false,
+      });
+      assertTrue(
+          window.getComputedStyle(manageGoogleAccount)['display'] !== 'none');
 
-        // A stored account with sync off and error should not result in the
-        // Google Account being shown.
-        simulateStoredAccounts([{email: 'foo@foo.com'}]);
-        simulateSyncStatus({
-          signedIn: false,
-          hasError: true,
-        });
-        assertEquals(
-            'none', window.getComputedStyle(manageGoogleAccount)['display']);
+      // A stored account with sync off and error should not result in the
+      // Google Account being shown.
+      simulateStoredAccounts([{email: 'foo@foo.com'}]);
+      simulateSyncStatus({
+        signedIn: false,
+        hasError: true,
+      });
+      assertEquals(
+          'none', window.getComputedStyle(manageGoogleAccount)['display']);
 
-        // A stored account with sync on but no error should result in the
-        // Google Account being shown.
-        simulateStoredAccounts([{email: 'foo@foo.com'}]);
-        simulateSyncStatus({
-          signedIn: true,
-          hasError: false,
-        });
-        assertTrue(
-            window.getComputedStyle(manageGoogleAccount)['display'] !== 'none');
+      // A stored account with sync on but no error should result in the
+      // Google Account being shown.
+      simulateStoredAccounts([{email: 'foo@foo.com'}]);
+      simulateSyncStatus({
+        signedIn: true,
+        hasError: false,
+      });
+      assertTrue(
+          window.getComputedStyle(manageGoogleAccount)['display'] !== 'none');
 
-        // A stored account with sync on but with error should not result in
-        // the Google Account being shown.
-        simulateStoredAccounts([{email: 'foo@foo.com'}]);
-        simulateSyncStatus({
-          signedIn: true,
-          hasError: true,
-        });
-        assertEquals(
-            'none', window.getComputedStyle(manageGoogleAccount)['display']);
+      // A stored account with sync on but with error should not result in
+      // the Google Account being shown.
+      simulateStoredAccounts([{email: 'foo@foo.com'}]);
+      simulateSyncStatus({
+        signedIn: true,
+        hasError: true,
+      });
+      assertEquals(
+          'none', window.getComputedStyle(manageGoogleAccount)['display']);
+    });
+
+    test('SignOutNavigationNormalProfile', async function() {
+      // Navigate to chrome://settings/signOut
+      Router.getInstance().navigateTo(routes.SIGN_OUT);
+
+      await new Promise(function(resolve) {
+        peoplePage.async(resolve);
+      });
+      const signoutDialog = peoplePage.$$('settings-signout-dialog');
+      assertTrue(signoutDialog.$$('#dialog').open);
+      assertFalse(signoutDialog.$$('#deleteProfile').hidden);
+
+      const deleteProfileCheckbox = signoutDialog.$$('#deleteProfile');
+      assertTrue(!!deleteProfileCheckbox);
+      assertLT(0, deleteProfileCheckbox.clientHeight);
+
+      const disconnectConfirm = signoutDialog.$$('#disconnectConfirm');
+      assertTrue(!!disconnectConfirm);
+      assertFalse(disconnectConfirm.hidden);
+
+      disconnectConfirm.click();
+
+      await new Promise(function(resolve) {
+        listenOnce(window, 'popstate', resolve);
+      });
+      const deleteProfile = await syncBrowserProxy.whenCalled('signOut');
+      assertFalse(deleteProfile);
+    });
+
+    test('SignOutDialogManagedProfile', async function() {
+      let accountControl = null;
+      await syncBrowserProxy.whenCalled('getSyncStatus');
+      simulateSyncStatus({
+        signedIn: true,
+        domain: 'example.com',
+        syncSystemEnabled: true,
+      });
+
+      assertFalse(!!peoplePage.$$('#dialog'));
+      accountControl = peoplePage.$$('settings-sync-account-control');
+      await waitBeforeNextRender(accountControl);
+      const turnOffButton = accountControl.$$('#turn-off');
+      turnOffButton.click();
+      flush();
+
+      await new Promise(function(resolve) {
+        peoplePage.async(resolve);
+      });
+      const signoutDialog = peoplePage.$$('settings-signout-dialog');
+      assertTrue(signoutDialog.$$('#dialog').open);
+      assertFalse(!!signoutDialog.$$('#deleteProfile'));
+
+      const disconnectManagedProfileConfirm =
+          signoutDialog.$$('#disconnectManagedProfileConfirm');
+      assertTrue(!!disconnectManagedProfileConfirm);
+      assertFalse(disconnectManagedProfileConfirm.hidden);
+
+      syncBrowserProxy.resetResolver('signOut');
+
+
+      disconnectManagedProfileConfirm.click();
+
+      await new Promise(function(resolve) {
+        listenOnce(window, 'popstate', resolve);
+      });
+      const deleteProfile = await syncBrowserProxy.whenCalled('signOut');
+      assertTrue(deleteProfile);
+    });
+
+    test('getProfileStatsCount', async function() {
+      // Navigate to chrome://settings/signOut
+      Router.getInstance().navigateTo(routes.SIGN_OUT);
+
+      await new Promise(function(resolve) {
+        peoplePage.async(resolve);
+      });
+      flush();
+      const signoutDialog = peoplePage.$$('settings-signout-dialog');
+      assertTrue(signoutDialog.$$('#dialog').open);
+
+      // Assert the warning message is as expected.
+      const warningMessage = signoutDialog.$$('.delete-profile-warning');
+
+      webUIListenerCallback('profile-stats-count-ready', 0);
+      assertEquals(
+          loadTimeData.getStringF(
+              'deleteProfileWarningWithoutCounts', 'fakeUsername'),
+          warningMessage.textContent.trim());
+
+      webUIListenerCallback('profile-stats-count-ready', 1);
+      assertEquals(
+          loadTimeData.getStringF(
+              'deleteProfileWarningWithCountsSingular', 'fakeUsername'),
+          warningMessage.textContent.trim());
+
+      webUIListenerCallback('profile-stats-count-ready', 2);
+      assertEquals(
+          loadTimeData.getStringF(
+              'deleteProfileWarningWithCountsPlural', 2, 'fakeUsername'),
+          warningMessage.textContent.trim());
+
+      // Close the disconnect dialog.
+      signoutDialog.$$('#disconnectConfirm').click();
+      await new Promise(function(resolve) {
+        listenOnce(window, 'popstate', resolve);
       });
     });
 
-    test('SignOutNavigationNormalProfile', function() {
+    test('NavigateDirectlyToSignOutURL', async function() {
       // Navigate to chrome://settings/signOut
       Router.getInstance().navigateTo(routes.SIGN_OUT);
 
-      return new Promise(function(resolve) {
-               peoplePage.async(resolve);
-             })
-          .then(function() {
-            const signoutDialog = peoplePage.$$('settings-signout-dialog');
-            assertTrue(signoutDialog.$$('#dialog').open);
-            assertFalse(signoutDialog.$$('#deleteProfile').hidden);
+      await new Promise(function(resolve) {
+        peoplePage.async(resolve);
+      });
+      assertTrue(peoplePage.$$('settings-signout-dialog').$$('#dialog').open);
+      await profileInfoBrowserProxy.whenCalled('getProfileStatsCount');
+      // 'getProfileStatsCount' can be the first message sent to the
+      // handler if the user navigates directly to
+      // chrome://settings/signOut. if so, it should not cause a crash.
+      new ProfileInfoBrowserProxyImpl().getProfileStatsCount();
 
-            const deleteProfileCheckbox = signoutDialog.$$('#deleteProfile');
-            assertTrue(!!deleteProfileCheckbox);
-            assertLT(0, deleteProfileCheckbox.clientHeight);
-
-            const disconnectConfirm = signoutDialog.$$('#disconnectConfirm');
-            assertTrue(!!disconnectConfirm);
-            assertFalse(disconnectConfirm.hidden);
-
-            const popstatePromise = new Promise(function(resolve) {
-              listenOnce(window, 'popstate', resolve);
-            });
-
-            disconnectConfirm.click();
-
-            return popstatePromise;
-          })
-          .then(function() {
-            return syncBrowserProxy.whenCalled('signOut');
-          })
-          .then(function(deleteProfile) {
-            assertFalse(deleteProfile);
-          });
+      // Close the disconnect dialog.
+      peoplePage.$$('settings-signout-dialog').$$('#disconnectConfirm').click();
+      await new Promise(function(resolve) {
+        listenOnce(window, 'popstate', resolve);
+      });
     });
 
-    test('SignOutDialogManagedProfile', function() {
-      let accountControl = null;
-      return syncBrowserProxy.whenCalled('getSyncStatus')
-          .then(function() {
-            simulateSyncStatus({
-              signedIn: true,
-              domain: 'example.com',
-              syncSystemEnabled: true,
-            });
+    test('Signout dialog suppressed when not signed in', async function() {
+      await syncBrowserProxy.whenCalled('getSyncStatus');
+      Router.getInstance().navigateTo(routes.SIGN_OUT);
+      await new Promise(function(resolve) {
+        peoplePage.async(resolve);
+      });
+      assertTrue(peoplePage.$$('settings-signout-dialog').$$('#dialog').open);
 
-            assertFalse(!!peoplePage.$$('#dialog'));
-            accountControl = peoplePage.$$('settings-sync-account-control');
-            return waitBeforeNextRender(accountControl);
-          })
-          .then(function() {
-            const turnOffButton = accountControl.$$('#turn-off');
-            turnOffButton.click();
-            flush();
+      simulateSyncStatus({
+        signedIn: false,
+      });
 
-            return new Promise(function(resolve) {
-              peoplePage.async(resolve);
-            });
-          })
-          .then(function() {
-            const signoutDialog = peoplePage.$$('settings-signout-dialog');
-            assertTrue(signoutDialog.$$('#dialog').open);
-            assertFalse(!!signoutDialog.$$('#deleteProfile'));
+      await new Promise(function(resolve) {
+        listenOnce(window, 'popstate', resolve);
+      });
 
-            const disconnectManagedProfileConfirm =
-                signoutDialog.$$('#disconnectManagedProfileConfirm');
-            assertTrue(!!disconnectManagedProfileConfirm);
-            assertFalse(disconnectManagedProfileConfirm.hidden);
-
-            syncBrowserProxy.resetResolver('signOut');
-
-            const popstatePromise = new Promise(function(resolve) {
-              listenOnce(window, 'popstate', resolve);
-            });
-
-            disconnectManagedProfileConfirm.click();
-
-            return popstatePromise;
-          })
-          .then(function() {
-            return syncBrowserProxy.whenCalled('signOut');
-          })
-          .then(function(deleteProfile) {
-            assertTrue(deleteProfile);
-          });
-    });
-
-    test('getProfileStatsCount', function() {
-      // Navigate to chrome://settings/signOut
       Router.getInstance().navigateTo(routes.SIGN_OUT);
 
-      return new Promise(function(resolve) {
-               peoplePage.async(resolve);
-             })
-          .then(function() {
-            flush();
-            const signoutDialog = peoplePage.$$('settings-signout-dialog');
-            assertTrue(signoutDialog.$$('#dialog').open);
-
-            // Assert the warning message is as expected.
-            const warningMessage = signoutDialog.$$('.delete-profile-warning');
-
-            webUIListenerCallback('profile-stats-count-ready', 0);
-            assertEquals(
-                loadTimeData.getStringF(
-                    'deleteProfileWarningWithoutCounts', 'fakeUsername'),
-                warningMessage.textContent.trim());
-
-            webUIListenerCallback('profile-stats-count-ready', 1);
-            assertEquals(
-                loadTimeData.getStringF(
-                    'deleteProfileWarningWithCountsSingular', 'fakeUsername'),
-                warningMessage.textContent.trim());
-
-            webUIListenerCallback('profile-stats-count-ready', 2);
-            assertEquals(
-                loadTimeData.getStringF(
-                    'deleteProfileWarningWithCountsPlural', 2, 'fakeUsername'),
-                warningMessage.textContent.trim());
-
-            // Close the disconnect dialog.
-            signoutDialog.$$('#disconnectConfirm').click();
-            return new Promise(function(resolve) {
-              listenOnce(window, 'popstate', resolve);
-            });
-          });
-    });
-
-    test('NavigateDirectlyToSignOutURL', function() {
-      // Navigate to chrome://settings/signOut
-      Router.getInstance().navigateTo(routes.SIGN_OUT);
-
-      return new Promise(function(resolve) {
-               peoplePage.async(resolve);
-             })
-          .then(function() {
-            assertTrue(
-                peoplePage.$$('settings-signout-dialog').$$('#dialog').open);
-            return profileInfoBrowserProxy.whenCalled('getProfileStatsCount');
-          })
-          .then(function() {
-            // 'getProfileStatsCount' can be the first message sent to the
-            // handler if the user navigates directly to
-            // chrome://settings/signOut. if so, it should not cause a crash.
-            new ProfileInfoBrowserProxyImpl().getProfileStatsCount();
-
-            // Close the disconnect dialog.
-            peoplePage.$$('settings-signout-dialog')
-                .$$('#disconnectConfirm')
-                .click();
-          })
-          .then(function() {
-            return new Promise(function(resolve) {
-              listenOnce(window, 'popstate', resolve);
-            });
-          });
-    });
-
-    test('Signout dialog suppressed when not signed in', function() {
-      return syncBrowserProxy.whenCalled('getSyncStatus')
-          .then(function() {
-            Router.getInstance().navigateTo(routes.SIGN_OUT);
-            return new Promise(function(resolve) {
-              peoplePage.async(resolve);
-            });
-          })
-          .then(function() {
-            assertTrue(
-                peoplePage.$$('settings-signout-dialog').$$('#dialog').open);
-
-            const popstatePromise = new Promise(function(resolve) {
-              listenOnce(window, 'popstate', resolve);
-            });
-
-            simulateSyncStatus({
-              signedIn: false,
-            });
-
-            return popstatePromise;
-          })
-          .then(function() {
-            const popstatePromise = new Promise(function(resolve) {
-              listenOnce(window, 'popstate', resolve);
-            });
-
-            Router.getInstance().navigateTo(routes.SIGN_OUT);
-
-            return popstatePromise;
-          });
+      await new Promise(function(resolve) {
+        listenOnce(window, 'popstate', resolve);
+      });
     });
   });
 }
diff --git a/chrome/test/data/webui/settings/sync_account_control_test.js b/chrome/test/data/webui/settings/sync_account_control_test.js
index 2f3242b..4ef685a 100644
--- a/chrome/test/data/webui/settings/sync_account_control_test.js
+++ b/chrome/test/data/webui/settings/sync_account_control_test.js
@@ -29,7 +29,7 @@
     testElement.syncStatus = {signedIn: signedIn};
   }
 
-  setup(function() {
+  setup(async function() {
     setupRouterWithSyncRoutes();
     browserProxy = new TestSyncBrowserProxy();
     SyncBrowserProxyImpl.instance_ = browserProxy;
@@ -45,52 +45,50 @@
     };
     document.body.appendChild(testElement);
 
-    return browserProxy.whenCalled('getStoredAccounts').then(() => {
-      flush();
-      simulateStoredAccounts([
-        {
-          fullName: 'fooName',
-          givenName: 'foo',
-          email: 'foo@foo.com',
-        },
-        {
-          fullName: 'barName',
-          givenName: 'bar',
-          email: 'bar@bar.com',
-        },
-      ]);
-    });
+    await browserProxy.whenCalled('getStoredAccounts');
+    flush();
+    simulateStoredAccounts([
+      {
+        fullName: 'fooName',
+        givenName: 'foo',
+        email: 'foo@foo.com',
+      },
+      {
+        fullName: 'barName',
+        givenName: 'bar',
+        email: 'bar@bar.com',
+      },
+    ]);
   });
 
   teardown(function() {
     testElement.remove();
   });
 
-  test('promo shows/hides in the right states', function() {
+  test('promo shows/hides in the right states', async function() {
     // Not signed in, no accounts, will show banner.
     simulateStoredAccounts([]);
     forcePromoResetWithCount(0, false);
     const banner = testElement.$$('#banner');
     assertTrue(isVisible(banner));
     // Flipping signedIn in forcePromoResetWithCount should increment count.
-    return browserProxy.whenCalled('incrementPromoImpressionCount').then(() => {
-      forcePromoResetWithCount(MAX_SIGNIN_PROMO_IMPRESSION + 1, false);
-      assertFalse(isVisible(banner));
+    await browserProxy.whenCalled('incrementPromoImpressionCount');
+    forcePromoResetWithCount(MAX_SIGNIN_PROMO_IMPRESSION + 1, false);
+    assertFalse(isVisible(banner));
 
-      // Not signed in, has accounts, will show banner.
-      simulateStoredAccounts([{email: 'foo@foo.com'}]);
-      forcePromoResetWithCount(0, false);
-      assertTrue(isVisible(banner));
-      forcePromoResetWithCount(MAX_SIGNIN_PROMO_IMPRESSION + 1, false);
-      assertFalse(isVisible(banner));
+    // Not signed in, has accounts, will show banner.
+    simulateStoredAccounts([{email: 'foo@foo.com'}]);
+    forcePromoResetWithCount(0, false);
+    assertTrue(isVisible(banner));
+    forcePromoResetWithCount(MAX_SIGNIN_PROMO_IMPRESSION + 1, false);
+    assertFalse(isVisible(banner));
 
-      // signed in, banners never show.
-      simulateStoredAccounts([{email: 'foo@foo.com'}]);
-      forcePromoResetWithCount(0, true);
-      assertFalse(isVisible(banner));
-      forcePromoResetWithCount(MAX_SIGNIN_PROMO_IMPRESSION + 1, true);
-      assertFalse(isVisible(banner));
-    });
+    // signed in, banners never show.
+    simulateStoredAccounts([{email: 'foo@foo.com'}]);
+    forcePromoResetWithCount(0, true);
+    assertFalse(isVisible(banner));
+    forcePromoResetWithCount(MAX_SIGNIN_PROMO_IMPRESSION + 1, true);
+    assertFalse(isVisible(banner));
   });
 
   test('promo header is visible', function() {
@@ -121,7 +119,7 @@
     }
   });
 
-  test('not signed in but has stored accounts', function() {
+  test('not signed in but has stored accounts', async function() {
     // Chrome OS users are always signed in.
     if (isChromeOS) {
       return;
@@ -175,47 +173,40 @@
     syncButton.click();
     flush();
 
-    return browserProxy.whenCalled('startSyncingWithEmail')
-        .then((args) => {
-          const email = args[0];
-          const isDefaultPromoAccount = args[1];
+    let [email, isDefaultPromoAccount] =
+        await browserProxy.whenCalled('startSyncingWithEmail');
+    assertEquals(email, 'foo@foo.com');
+    assertEquals(isDefaultPromoAccount, true);
 
-          assertEquals(email, 'foo@foo.com');
-          assertEquals(isDefaultPromoAccount, true);
+    assertTrue(isChildVisible(testElement, 'cr-icon-button'));
+    assertTrue(testElement.$$('#sync-icon-container').hidden);
 
-          assertTrue(isChildVisible(testElement, 'cr-icon-button'));
-          assertTrue(testElement.$$('#sync-icon-container').hidden);
+    testElement.$$('#dropdown-arrow').click();
+    flush();
+    assertTrue(testElement.$$('#menu').open);
 
-          testElement.$$('#dropdown-arrow').click();
-          flush();
-          assertTrue(testElement.$$('#menu').open);
+    // Switching selected account will update UI with the right name and
+    // email.
+    items[1].click();
+    flush();
+    assertFalse(userInfo.textContent.includes('fooName'));
+    assertFalse(userInfo.textContent.includes('foo@foo.com'));
+    assertTrue(userInfo.textContent.includes('barName'));
+    assertTrue(userInfo.textContent.includes('bar@bar.com'));
+    assertTrue(isVisible(syncButton));
 
-          // Switching selected account will update UI with the right name and
-          // email.
-          items[1].click();
-          flush();
-          assertFalse(userInfo.textContent.includes('fooName'));
-          assertFalse(userInfo.textContent.includes('foo@foo.com'));
-          assertTrue(userInfo.textContent.includes('barName'));
-          assertTrue(userInfo.textContent.includes('bar@bar.com'));
-          assertTrue(isVisible(syncButton));
+    browserProxy.resetResolver('startSyncingWithEmail');
+    syncButton.click();
+    flush();
 
-          browserProxy.resetResolver('startSyncingWithEmail');
-          syncButton.click();
-          flush();
+    [email, isDefaultPromoAccount] =
+        await browserProxy.whenCalled('startSyncingWithEmail');
+    assertEquals(email, 'bar@bar.com');
+    assertEquals(isDefaultPromoAccount, false);
 
-          return browserProxy.whenCalled('startSyncingWithEmail');
-        })
-        .then((args) => {
-          const email = args[0];
-          const isDefaultPromoAccount = args[1];
-          assertEquals(email, 'bar@bar.com');
-          assertEquals(isDefaultPromoAccount, false);
-
-          // Tapping the last menu item will initiate sign-in.
-          items[2].click();
-          return browserProxy.whenCalled('startSignIn');
-        });
+    // Tapping the last menu item will initiate sign-in.
+    items[2].click();
+    await browserProxy.whenCalled('startSignIn');
   });
 
   test('signed in, no error', function() {
diff --git a/chrome/test/data/webui/signin/sync_confirmation_test.js b/chrome/test/data/webui/signin/sync_confirmation_test.js
index 48d856e..9417ace 100644
--- a/chrome/test/data/webui/signin/sync_confirmation_test.js
+++ b/chrome/test/data/webui/signin/sync_confirmation_test.js
@@ -9,7 +9,7 @@
 
 suite('SigninSyncConfirmationTest', function() {
   let app;
-  setup(function() {
+  setup(async function() {
     const browserProxy = new TestSyncConfirmationBrowserProxy();
     SyncConfirmationBrowserProxyImpl.instance_ = browserProxy;
     PolymerTest.clearBody();
@@ -17,7 +17,7 @@
     document.body.append(app);
     // Check that the account image is requested when the app element is
     // attached to the document.
-    return browserProxy.whenCalled('requestAccountImage');
+    await browserProxy.whenCalled('requestAccountImage');
   });
 
   // Tests that no DCHECKS are thrown during initialization of the UI.
@@ -35,7 +35,7 @@
   let app;
   let browserProxy;
 
-  setup(function() {
+  setup(async function() {
     // This test suite makes comparisons with strings in their default locale,
     // which is en-US.
     assertEquals(
@@ -50,7 +50,7 @@
     document.body.append(app);
     // Wait for the app element to get attached to the document (which is when
     // the account image gets requested).
-    return browserProxy.whenCalled('requestAccountImage');
+    await browserProxy.whenCalled('requestAccountImage');
   });
 
   const STANDARD_CONSENT_DESCRIPTION_TEXT = [
@@ -63,28 +63,25 @@
 
   // Tests that the expected strings are recorded when clicking the Confirm
   // button.
-  test('recordConsentOnConfirm', function() {
+  test('recordConsentOnConfirm', async function() {
     app.$$('#confirmButton').click();
-    return browserProxy.whenCalled('confirm').then(function(
-        [description, confirmation]) {
-      assertEquals(
-          JSON.stringify(STANDARD_CONSENT_DESCRIPTION_TEXT),
-          JSON.stringify(description));
-      assertEquals('Yes, I\'m in', confirmation);
-    });
+    const [description, confirmation] =
+        await browserProxy.whenCalled('confirm');
+    assertEquals(
+        JSON.stringify(STANDARD_CONSENT_DESCRIPTION_TEXT),
+        JSON.stringify(description));
+    assertEquals('Yes, I\'m in', confirmation);
   });
 
   // Tests that the expected strings are recorded when clicking the Confirm
   // button.
-  test('recordConsentOnSettingsLink', function() {
+  test('recordConsentOnSettingsLink', async function() {
     app.$$('#settingsButton').click();
-    return browserProxy.whenCalled('goToSettings').then(function([
-      description, confirmation
-    ]) {
-      assertEquals(
-          JSON.stringify(STANDARD_CONSENT_DESCRIPTION_TEXT),
-          JSON.stringify(description));
-      assertEquals('Settings', confirmation);
-    });
+    const [description, confirmation] =
+        await browserProxy.whenCalled('goToSettings');
+    assertEquals(
+        JSON.stringify(STANDARD_CONSENT_DESCRIPTION_TEXT),
+        JSON.stringify(description));
+    assertEquals('Settings', confirmation);
   });
 });
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn
index fa932a2..4893f1d 100644
--- a/chrome/utility/BUILD.gn
+++ b/chrome/utility/BUILD.gn
@@ -73,6 +73,10 @@
     ]
   }
 
+  if (is_mac) {
+    deps += [ "//chrome/services/mac_notifications" ]
+  }
+
   if (!is_android) {
     sources += [
       "importer/bookmark_html_reader.cc",
diff --git a/chrome/utility/DEPS b/chrome/utility/DEPS
index 185fc1d..96b8303a 100644
--- a/chrome/utility/DEPS
+++ b/chrome/utility/DEPS
@@ -6,6 +6,7 @@
   "+chrome/services/ipp_parser/public/mojom",
   "+chrome/services/file_util/file_util_service.h",
   "+chrome/services/file_util/public/mojom",
+  "+chrome/services/mac_notifications",
   "+chrome/services/machine_learning/machine_learning_service.h",
   "+chrome/services/machine_learning/public/mojom",
   "+chrome/services/media_gallery_util",
diff --git a/chrome/utility/services.cc b/chrome/utility/services.cc
index 26f5aa0..9d4ecfeb 100644
--- a/chrome/utility/services.cc
+++ b/chrome/utility/services.cc
@@ -44,6 +44,10 @@
 #include "media/mojo/services/media_service_factory.h"       // nogncheck
 #endif  // defined(OS_WIN)
 
+#if defined(OS_MAC)
+#include "chrome/services/mac_notifications/mac_notification_provider_impl.h"
+#endif  // defined(OS_MAC)
+
 #if !defined(OS_ANDROID)
 #include "chrome/common/importer/profile_import.mojom.h"
 #include "chrome/services/speech/speech_recognition_service_impl.h"
@@ -165,6 +169,14 @@
 }
 #endif  // defined(OS_WIN)
 
+#if defined(OS_MAC)
+auto RunMacNotificationService(
+    mojo::PendingReceiver<notifications::mojom::MacNotificationProvider>
+        receiver) {
+  return std::make_unique<MacNotificationProviderImpl>(std::move(receiver));
+}
+#endif  // defined(OS_MAC)
+
 #if !defined(OS_ANDROID)
 auto RunProxyResolver(
     mojo::PendingReceiver<proxy_resolver::mojom::ProxyResolverFactory>
@@ -338,6 +350,10 @@
   services.Add(RunCupsIppParser);
 #endif
 
+#if defined(OS_MAC)
+  services.Add(RunMacNotificationService);
+#endif  // defined(OS_MAC)
+
 #if BUILDFLAG(FULL_SAFE_BROWSING) || BUILDFLAG(IS_CHROMEOS_ASH)
   services.Add(RunFileUtil);
 #endif
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn
index fcfd322..945d02b 100644
--- a/chromecast/browser/BUILD.gn
+++ b/chromecast/browser/BUILD.gn
@@ -445,6 +445,7 @@
       "//extensions/browser",
       "//extensions/browser:core_api_provider",
       "//extensions/browser/api/messaging",
+      "//extensions/browser/updater",
       "//extensions/common",
       "//extensions/common/api",
       "//google_apis:google_apis",
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 9d12995..ba98125d 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-13779.0.0
\ No newline at end of file
+13780.0.0
\ No newline at end of file
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd
index 08f883a0..d1bf205 100644
--- a/chromeos/chromeos_strings.grd
+++ b/chromeos/chromeos_strings.grd
@@ -476,15 +476,6 @@
       <message name="IDS_SCANNING_APP_SCANNER_DROPDOWN_LABEL" desc="The label for the dropdown that displays connected scanners.">
         Scanner
       </message>
-      <message name="IDS_SCANNING_APP_NO_SCANNERS_HELP_LINK_LABEL" desc="The help label link displayed below the scanner dropdown when no scanners are available.">
-        Learn more
-      </message>
-      <message name="IDS_SCANNING_APP_NO_SCANNERS_HELP_TEXT" desc="The help text displayed below the scanner dropdown when no scanners are available.">
-        Can't connect to scanners?
-      </message>
-      <message name="IDS_SCANNING_APP_NO_SCANNERS_TEXT" desc="The text displayed in the scanner dropdown when no scanners are available.">
-        No available scanners
-      </message>
       <message name="IDS_SCANNING_APP_SOURCE_DROPDOWN_LABEL" desc="The label for the dropdown that displays available scan sources (e.g. flatbed, document feeder, etc.).">
         Source
       </message>
@@ -618,6 +609,12 @@
       <message name="IDS_SCANNING_APP_SCANNERS_LOADING_TEXT" desc="The text displayed while the app is searching for available scanners">
         Looking for scanners
       </message>
+      <message name="IDS_SCANNING_APP_NO_SCANNERS_TEXT" desc="The text displayed when there are no available scanners found for scanning">
+        No scanner available
+      </message>
+      <message name="IDS_SCANNING_APP_NO_SCANNERS_SUBTEXT" desc="The subtext displayed when there are no available scanners found for scanning">
+        Make sure the scanner is turned on and connected
+      </message>
 
       <!-- Diagnostics App -->
       <message name="IDS_DIAGNOSTICS_TITLE" desc="The title of the diagnostics app.">
@@ -675,7 +672,7 @@
         Remaining charge
       </message>
       <message name="IDS_DIAGNOSTICS_SESSION_LOG_LABEL" desc="The label for the button that opens the session log for the diagnostics app.">
-        Save Session log
+        Save session log
       </message>
       <message name="IDS_DIAGNOSTICS_BATTERY_CHIP_TEXT" desc="The text for a battery's full charge capacity represented in milliamp hours.">
         <ph name="CHARGE_VALUE">$1<ex>6000</ex></ph>mAh Battery
diff --git a/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_SESSION_LOG_LABEL.png.sha1 b/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_SESSION_LOG_LABEL.png.sha1
index 54bb250..e4240ae 100644
--- a/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_SESSION_LOG_LABEL.png.sha1
+++ b/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_SESSION_LOG_LABEL.png.sha1
@@ -1 +1 @@
-bf27bd33cff71f9a5c2c8308c5525cf54aebe085
\ No newline at end of file
+77fb3a3cdfa8c5c55e832199649494b2c90a8fa2
\ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_NO_SCANNERS_HELP_LINK_LABEL.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_NO_SCANNERS_HELP_LINK_LABEL.png.sha1
deleted file mode 100644
index 007e92cf..0000000
--- a/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_NO_SCANNERS_HELP_LINK_LABEL.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-b41fec481f16698eabe7f1a1a997e68fd4d67b38
\ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_NO_SCANNERS_HELP_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_NO_SCANNERS_HELP_TEXT.png.sha1
deleted file mode 100644
index 007e92cf..0000000
--- a/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_NO_SCANNERS_HELP_TEXT.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-b41fec481f16698eabe7f1a1a997e68fd4d67b38
\ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_NO_SCANNERS_SUBTEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_NO_SCANNERS_SUBTEXT.png.sha1
new file mode 100644
index 0000000..b2b0e7b5
--- /dev/null
+++ b/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_NO_SCANNERS_SUBTEXT.png.sha1
@@ -0,0 +1 @@
+1be8957ab5755b57bf03a9fa504e51e75cbee9f6
\ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_NO_SCANNERS_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_NO_SCANNERS_TEXT.png.sha1
index 57d958a..2d7d0ac 100644
--- a/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_NO_SCANNERS_TEXT.png.sha1
+++ b/chromeos/chromeos_strings_grd/IDS_SCANNING_APP_NO_SCANNERS_TEXT.png.sha1
@@ -1 +1 @@
-4b217539fe272161364035c92edcd077026c1b0d
\ No newline at end of file
+699e14de0f66613efa43a0e36501353eee24cfc2
\ No newline at end of file
diff --git a/chromeos/components/camera_app_ui/resources/js/BUILD.gn b/chromeos/components/camera_app_ui/resources/js/BUILD.gn
index 4fbf8c7..a65b589c 100644
--- a/chromeos/components/camera_app_ui/resources/js/BUILD.gn
+++ b/chromeos/components/camera_app_ui/resources/js/BUILD.gn
@@ -9,7 +9,6 @@
   closure_flags =
       default_closure_args + [
         "language_in=ECMASCRIPT_2019",
-        "jscomp_error=lintChecks",
         "jscomp_error=strictCheckTypes",
         "conformance_configs=" +
             rebase_path("externs/conformance_config.textproto", root_build_dir),
diff --git a/chromeos/components/diagnostics_ui/resources/diagnostics_app.html b/chromeos/components/diagnostics_ui/resources/diagnostics_app.html
index 7fa2c70..5b7a135 100644
--- a/chromeos/components/diagnostics_ui/resources/diagnostics_app.html
+++ b/chromeos/components/diagnostics_ui/resources/diagnostics_app.html
@@ -20,6 +20,13 @@
     position: relative;
   }
 
+  #download-icon {
+    --iron-icon-height: 20px;
+    --iron-icon-width: 20px;
+    color: var(--google-blue-600);
+    right: 4px;
+  }
+
   #header {
     @apply --diagnostics-header-font;
     align-self: flex-start;
@@ -35,14 +42,6 @@
     justify-content: center;
     margin: 20px 0;
   }
-  .session-log-button {
-    background-color: rgba(var(--google-blue-600), .06);
-    border-radius: 20px;
-    width: 144px;
-    height: 40px;
-    font-size: 14px;
-    padding: 5px;
-  }
 
   #toast {
     bottom: 0;
@@ -74,8 +73,9 @@
     </div>
   </div>
   <div class="session-log-container">
-    <cr-button class="session-log-button" on-click="onSessionLogClick_">
-      [[i18n('sessionLog')]]
+    <cr-button on-click="onSessionLogClick_" id="sessionLogButton">
+      <iron-icon icon="diagnostics:download" id="download-icon"></iron-icon> 
+      <span>[[i18n('sessionLog')]]</span>
     </cr-button>
   </div>
   <cr-toast id="toast" duration="2500">
diff --git a/chromeos/components/diagnostics_ui/resources/diagnostics_app.js b/chromeos/components/diagnostics_ui/resources/diagnostics_app.js
index 827b63f..0ad0481 100644
--- a/chromeos/components/diagnostics_ui/resources/diagnostics_app.js
+++ b/chromeos/components/diagnostics_ui/resources/diagnostics_app.js
@@ -4,10 +4,13 @@
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_toast/cr_toast.m.js';
+import 'chrome://resources/cr_elements/icons.m.js';
+import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import './battery_status_card.js';
 import './cpu_card.js';
 import './diagnostics_fonts_css.js';
 import './diagnostics_shared_css.js';
+import './icons.js';
 import './memory_card.js';
 import './overview_card.js';
 import './strings.m.js';
diff --git a/chromeos/components/diagnostics_ui/resources/icons.html b/chromeos/components/diagnostics_ui/resources/icons.html
index cc03322..b989baa9 100644
--- a/chromeos/components/diagnostics_ui/resources/icons.html
+++ b/chromeos/components/diagnostics_ui/resources/icons.html
@@ -70,6 +70,10 @@
     <g id="memory">
       <path d="M2,18 L18,18 L18,14 L2,14 L2,18 Z M4,15 L6,15 L6,17 L4,17 L4,15 Z M2,2 L2,6 L18,6 L18,2 L2,2 Z M6,5 L4,5 L4,3 L6,3 L6,5 Z M2,12 L18,12 L18,8 L2,8 L2,12 Z M4,9 L6,9 L6,11 L4,11 L4,9 Z" fill-rule="nonzero" />
     </g>
+    <g id="download">
+      <path d="M11 9.2L13.5 6.5L15 8L10 13L5 8L6.5 6.5L9 9.2V3H11V9.2Z" />
+      <path d="M6 15V13H4V15.375C4 16.2688 4.73125 17 5.625 17H14.375C15.2688 17 16 16.2688 16 15.375V13H14V15H6Z" />
+    </g>
     </defs>
   </svg>
 </iron-iconset-svg>
\ No newline at end of file
diff --git a/chromeos/components/diagnostics_ui/resources/routine_section.js b/chromeos/components/diagnostics_ui/resources/routine_section.js
index d127675..c9e7a49e 100644
--- a/chromeos/components/diagnostics_ui/resources/routine_section.js
+++ b/chromeos/components/diagnostics_ui/resources/routine_section.js
@@ -138,6 +138,11 @@
 
       resultListElem.initializeTestRun(filteredRoutines);
 
+      // Expand result list by default.
+      if (!this.shouldHideReportList_()) {
+        this.$.collapse.show();
+      }
+
       this.executor_ =
           new RoutineListExecutor(assert(this.systemRoutineController_));
       this.executor_
@@ -205,7 +210,7 @@
 
   /** @protected */
   isResultButtonHidden_() {
-    return this.routines.length < 2 ||
+    return this.shouldHideReportList_() ||
         this.executionStatus_ === ExecutionProgress.kNotStarted;
   },
 
@@ -312,6 +317,14 @@
     return this.executionStatus_ !== ExecutionProgress.kRunning;
   },
 
+  /**
+   * @protected
+   * @return {boolean}
+   */
+  shouldHideReportList_() {
+    return this.routines.length < 2;
+  },
+
   /** @override */
   detached() {
     this.cleanUp_();
diff --git a/chromeos/components/media_app_ui/test/driver.js b/chromeos/components/media_app_ui/test/driver.js
index 9d38f47a..66e37e4 100644
--- a/chromeos/components/media_app_ui/test/driver.js
+++ b/chromeos/components/media_app_ui/test/driver.js
@@ -81,7 +81,7 @@
       return;
     }
     const dataSize = data.size === undefined ? data.length : data.size;
-    this.writes.push({position, size: dataSize});
+    this.writes.push({position, size: /** @type {number} */ (dataSize)});
     this.data = new Blob([
       this.data.slice(0, position),
       data,
@@ -262,6 +262,11 @@
     // Store the file removed for spying in tests.
     this.lastDeleted = this.files.splice(fileHandleIndex, 1)[0];
   }
+
+  /** @override */
+  resolve() {
+    return Promise.resolve(null);
+  }
 }
 
 /**
diff --git a/chromeos/components/scanning/resources/loading_page.html b/chromeos/components/scanning/resources/loading_page.html
index 33e79c0..7c0b0afe 100644
--- a/chromeos/components/scanning/resources/loading_page.html
+++ b/chromeos/components/scanning/resources/loading_page.html
@@ -9,11 +9,20 @@
     text-align: center;
   }
 
-  #loadingText {
+  h1 {
     color: var(--scanning-scanners-loading-text-color);
     font-family: var(--scanning-scanners-loading-font-family);
     font-size: var(--scanning-scanners-loading-font-size);
     font-weight: var(--scanning-medium-font-weight);
+    line-height: var(--scanning-scanners-loading-line-height);
+  }
+
+  #noScannersSubtext {
+    color: var(--scanning-no-scanners-subtext-color);
+    font-family: var(--scanning-no-scanners-subtext-font-family);
+    font-size: var(--scanning-no-scanners-subtext-font-size);
+    font-weight: var(--scanning-regular-font-weight);
+    line-height: var(--scanning-no-scanners-subtext-line-height);
   }
 
   paper-progress {
@@ -26,6 +35,12 @@
   }
 </style>
 <div id="loadingContainer">
-  <h1 id="loadingText">[[i18n('scannersLoadingText')]]</h1>
-  <paper-progress indeterminate></paper-progress>
+  <div id="loadingDiv" hidden="[[noScannersAvailable_]]">
+    <h1>[[i18n('scannersLoadingText')]]</h1>
+    <paper-progress indeterminate></paper-progress>
+  </div>
+  <div id="noScannersDiv" hidden="[[!noScannersAvailable_]]">
+    <h1>[[i18n('noScannersText')]]</h1>
+    <span id="noScannersSubtext">[[i18n('noScannersSubtext')]]</span>
+  </div>
 </div>
diff --git a/chromeos/components/scanning/resources/loading_page.js b/chromeos/components/scanning/resources/loading_page.js
index 0da2fee..b147a8bb 100644
--- a/chromeos/components/scanning/resources/loading_page.js
+++ b/chromeos/components/scanning/resources/loading_page.js
@@ -7,6 +7,8 @@
 import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
 import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+import {AppState} from './scanning_app_types.js';
+
 /**
  * @fileoverview
  * 'loading-page' is shown while searching for available scanners.
@@ -17,4 +19,23 @@
   _template: html`{__html_template__}`,
 
   behaviors: [I18nBehavior],
+
+  properties: {
+    /** @type {!AppState} */
+    appState: {
+      type: Number,
+      observer: 'onAppStateChange_',
+    },
+
+    /** @private {boolean} */
+    noScannersAvailable_: {
+      type: Boolean,
+      value: false,
+    },
+  },
+
+  /** @private */
+  onAppStateChange_() {
+    this.noScannersAvailable_ = this.appState === AppState.NO_SCANNERS;
+  },
 });
diff --git a/chromeos/components/scanning/resources/scanner_select.html b/chromeos/components/scanning/resources/scanner_select.html
index 55948df..65ec9867d 100644
--- a/chromeos/components/scanning/resources/scanner_select.html
+++ b/chromeos/components/scanning/resources/scanner_select.html
@@ -1,16 +1,4 @@
-<style include="scanning-fonts scanning-shared">
-  #scanHelp {
-    color: var(--scanning-no-scanners-help-text-color);
-    font-family: var(--scanning-no-scanners-help-text-font-family);
-    font-size: var(--scanning-no-scanners-help-text-font-size);
-    font-weight: var(--scanning-regular-font-weight);
-    line-height: var(--scanning-no-scanners-help-text-line-height);
-  }
-
-  #scanHelpLink {
-    color: var(--google-blue-600);
-    text-decoration: none;
-  }
+<style include="scanning-shared">
 </style>
 <scan-settings-section>
   <span id="scannerLabel" slot="label" aria-hidden="true">
@@ -25,17 +13,6 @@
           [[getScannerDisplayName_(scanner)]]
         </option>
       </template>
-      <option value="" hidden="[[scanners.length]]">
-        [[i18n('noScannersText')]]
-      </option>
     </select>
   </div>
-  <div id="scanHelp" slot="error"
-      hidden$="[[shouldHideScanHelpLink_(scanners)]]">
-    [[i18n('noScannersHelpText')]]
-    <a id="scanHelpLink" target="_blank"
-        href="http://support.google.com/chromebook?p=chrome_scanning">
-      [[i18n('noScannersHelpLinkLabel')]]
-    </a>
-  </div>
 </scan-settings-section>
diff --git a/chromeos/components/scanning/resources/scanner_select.js b/chromeos/components/scanning/resources/scanner_select.js
index 69c7fa5..6d535e0 100644
--- a/chromeos/components/scanning/resources/scanner_select.js
+++ b/chromeos/components/scanning/resources/scanner_select.js
@@ -83,12 +83,4 @@
       this.selectedScannerId = tokenToString(this.scanners[0].id);
     }
   },
-
-  /**
-   * Helper function to decide whether to hide the scanner connection help link.
-   * @protected
-   */
-  shouldHideScanHelpLink_() {
-    return this.scanners.length !== 0;
-  }
 });
diff --git a/chromeos/components/scanning/resources/scanning_app.html b/chromeos/components/scanning/resources/scanning_app.html
index c192fcfc..4e6f722 100644
--- a/chromeos/components/scanning/resources/scanning_app.html
+++ b/chromeos/components/scanning/resources/scanning_app.html
@@ -175,7 +175,8 @@
   }
 </style>
 <div id="scanningContainer">
-  <loading-page hidden="[[scannersLoaded_]]"></loading-page>
+  <loading-page hidden="[[scannersLoaded_]]" app-state="[[appState_]]">
+  </loading-page>
   <div id="panelContainer" hidden="[[!scannersLoaded_]]">
     <div id="leftPanel">
       <scan-preview id="scanPreview" app-state="[[appState_]]"
diff --git a/chromeos/components/scanning/resources/scanning_app.js b/chromeos/components/scanning/resources/scanning_app.js
index 307d2826..1c3c193 100644
--- a/chromeos/components/scanning/resources/scanning_app.js
+++ b/chromeos/components/scanning/resources/scanning_app.js
@@ -363,11 +363,16 @@
    * @private
    */
   onScannersReceived_(response) {
-    this.setAppState_(AppState.GOT_SCANNERS);
+    if (response.scanners.length === 0) {
+      this.setAppState_(AppState.NO_SCANNERS);
+      return;
+    }
+
     for (const scanner of response.scanners) {
       this.scannerIds_.set(tokenToString(scanner.id), scanner.id);
     }
 
+    this.setAppState_(AppState.GOT_SCANNERS);
     this.scanners_ = response.scanners;
   },
 
@@ -544,6 +549,9 @@
       case (AppState.CANCELING):
         assert(this.appState_ === AppState.SCANNING);
         break;
+      case (AppState.NO_SCANNERS):
+        assert(this.appState_ === AppState.GETTING_SCANNERS);
+        break;
     }
 
     this.appState_ = newState;
@@ -551,7 +559,8 @@
 
   /** @private */
   onAppStateChange_() {
-    this.scannersLoaded_ = this.appState_ !== AppState.GETTING_SCANNERS;
+    this.scannersLoaded_ = this.appState_ !== AppState.GETTING_SCANNERS &&
+        this.appState_ !== AppState.NO_SCANNERS;
     this.settingsDisabled_ = this.appState_ !== AppState.READY;
     this.showCancelButton_ = this.appState_ === AppState.SCANNING ||
         this.appState_ === AppState.CANCELING;
diff --git a/chromeos/components/scanning/resources/scanning_app_types.js b/chromeos/components/scanning/resources/scanning_app_types.js
index 985a6b71..03ba7af 100644
--- a/chromeos/components/scanning/resources/scanning_app_types.js
+++ b/chromeos/components/scanning/resources/scanning_app_types.js
@@ -14,6 +14,7 @@
   SCANNING: 4,
   DONE: 5,
   CANCELING: 6,
+  NO_SCANNERS: 7,
 };
 
 /**
diff --git a/chromeos/components/scanning/resources/scanning_fonts_css.html b/chromeos/components/scanning/resources/scanning_fonts_css.html
index 0ea00d3..9d5c5ab 100644
--- a/chromeos/components/scanning/resources/scanning_fonts_css.html
+++ b/chromeos/components/scanning/resources/scanning_fonts_css.html
@@ -5,7 +5,7 @@
       --scanning-done-section-option-font-family: Roboto;
       --scanning-helper-text-font-family: Roboto;
       --scanning-more-settings-font-family: Roboto;
-      --scanning-no-scanners-help-text-font-family: Roboto;
+      --scanning-no-scanners-subtext-font-family: Roboto;
       --scanning-progress-text-font-family: "Google Sans", Roboto, sans-serif;
       --scanning-scan-setting-font-family: Roboto;
       --scanning-scanners-loading-font-family: "Google Sans", Roboto, sans-serif;
@@ -14,7 +14,7 @@
       --scanning-done-section-option-font-size: 13px;
       --scanning-helper-text-font-size: 13px;
       --scanning-more-settings-font-size: 12px;
-      --scanning-no-scanners-help-text-font-size: 10px;
+      --scanning-no-scanners-subtext-font-size: 14px;
       --scanning-progress-text-font-size: 16px;
       --scanning-scan-setting-font-size: 13px;
       --scanning-scanners-loading-font-size: 22px;
@@ -23,9 +23,10 @@
       --scanning-done-section-option-line-height: 20px;
       --scanning-helper-text-line-height: 20px;
       --scanning-more-settings-line-height: 18px;
-      --scanning-no-scanners-help-text-line-height: 10px;
+      --scanning-no-scanners-subtext-line-height: 20px;
       --scanning-progress-text-line-height: 24px;
       --scanning-scan-setting-line-height: 20px;
+      --scanning-scanners-loading-line-height: 28px;
 
       --scanning-regular-font-weight: 400;
       --scanning-medium-font-weight: 500;
@@ -34,7 +35,7 @@
       --scanning-done-section-option-text-color: var(--google-grey-900);
       --scanning-helper-text-color: var(--google-grey-700);
       --scanning-more-settings-text-color: var(--google-grey-700);
-      --scanning-no-scanners-help-text-color: var(--google-grey-700);
+      --scanning-no-scanners-subtext-color: var(--google-grey-700);
       --scanning-progress-text-color: var(--google-grey-700);
       --scanning-scan-setting-text-color: var(--google-grey-900);
       --scanning-scanners-loading-text-color: var(--google-grey-900);
diff --git a/chromeos/components/scanning/scanning_ui.cc b/chromeos/components/scanning/scanning_ui.cc
index 53d4c556..c48829e 100644
--- a/chromeos/components/scanning/scanning_ui.cc
+++ b/chromeos/components/scanning/scanning_ui.cc
@@ -66,9 +66,8 @@
       {"letterOptionText", IDS_SCANNING_APP_LETTER_OPTION_TEXT},
       {"moreSettings", IDS_SCANNING_APP_MORE_SETTINGS},
       {"myFilesSelectOption", IDS_SCANNING_APP_MY_FILES_SELECT_OPTION},
-      {"noScannersHelpLinkLabel", IDS_SCANNING_APP_NO_SCANNERS_HELP_LINK_LABEL},
-      {"noScannersHelpText", IDS_SCANNING_APP_NO_SCANNERS_HELP_TEXT},
       {"noScannersText", IDS_SCANNING_APP_NO_SCANNERS_TEXT},
+      {"noScannersSubtext", IDS_SCANNING_APP_NO_SCANNERS_SUBTEXT},
       {"okButtonLabel", IDS_SCANNING_APP_OK_BUTTON_LABEL},
       {"oneSidedDocFeederOptionText",
        IDS_SCANNING_APP_ONE_SIDED_DOC_FEEDER_OPTION_TEXT},
diff --git a/chromeos/components/security_token_pin/constants.h b/chromeos/components/security_token_pin/constants.h
index eb7df21..3dd3dbf 100644
--- a/chromeos/components/security_token_pin/constants.h
+++ b/chromeos/components/security_token_pin/constants.h
@@ -12,16 +12,12 @@
 
 // Type of the information asked from the user during a security token PIN
 // request.
-// Must be kept in sync with
-// chrome/browser/resources/chromeos/login/components/oobe_types.js.
 enum class CodeType {
   kPin = 0,
   kPuk = 1,
 };
 
 // Error to be displayed in the security token PIN request.
-// Must be kept in sync with
-// chrome/browser/resources/chromeos/login/components/oobe_types.js.
 enum class ErrorLabel {
   kNone = 0,
   kUnknown = 1,
diff --git a/chromeos/components/security_token_pin/error_generator.cc b/chromeos/components/security_token_pin/error_generator.cc
index fa1a1c40..6eb0f22 100644
--- a/chromeos/components/security_token_pin/error_generator.cc
+++ b/chromeos/components/security_token_pin/error_generator.cc
@@ -14,7 +14,6 @@
 
 // Only inform the user about the number of attempts left if it's smaller or
 // equal to this constant. (This is a pure UX heuristic.)
-// Please keep this constant in sync with the one in security_token_pin.js.
 constexpr int kAttemptsLeftThreshold = 3;
 
 base::string16 GenerateErrorMessage(ErrorLabel error_label,
diff --git a/chromeos/components/security_token_pin/error_generator_unittest.cc b/chromeos/components/security_token_pin/error_generator_unittest.cc
index 419ef40..ccf19f6 100644
--- a/chromeos/components/security_token_pin/error_generator_unittest.cc
+++ b/chromeos/components/security_token_pin/error_generator_unittest.cc
@@ -70,6 +70,9 @@
 
 // Tests the message when the number of attempts left is given.
 TEST_F(SecurityTokenPinErrorGeneratorTest, Attempts) {
+  EXPECT_EQ(GenerateErrorMessage(ErrorLabel::kNone, /*attempts_left=*/1,
+                                 /*accept_input=*/true),
+            base::ASCIIToUTF16("1 attempt left"));
   EXPECT_EQ(GenerateErrorMessage(ErrorLabel::kNone, /*attempts_left=*/3,
                                  /*accept_input=*/true),
             base::ASCIIToUTF16("3 attempts left"));
@@ -85,6 +88,9 @@
 
 // Tests the message for the kInvalidPin error with the number of attempts left.
 TEST_F(SecurityTokenPinErrorGeneratorTest, InvalidPinWithAttempts) {
+  EXPECT_EQ(GenerateErrorMessage(ErrorLabel::kInvalidPin, /*attempts_left=*/1,
+                                 /*accept_input=*/true),
+            base::ASCIIToUTF16("Invalid PIN. 1 attempt left"));
   EXPECT_EQ(GenerateErrorMessage(ErrorLabel::kInvalidPin, /*attempts_left=*/3,
                                  /*accept_input=*/true),
             base::ASCIIToUTF16("Invalid PIN. 3 attempts left"));
diff --git a/chromeos/components/telemetry_extension_ui/resources/BUILD.gn b/chromeos/components/telemetry_extension_ui/resources/BUILD.gn
index 50763739..71dafca 100644
--- a/chromeos/components/telemetry_extension_ui/resources/BUILD.gn
+++ b/chromeos/components/telemetry_extension_ui/resources/BUILD.gn
@@ -12,7 +12,7 @@
 group("closure_compile") {
   deps = [
     ":trusted_closure_compile",
-    ":untrusted_closure_compile",
+    "dpsl:dpsl_closure_compile",
   ]
 }
 
@@ -21,27 +21,11 @@
   deps = [ ":trusted" ]
 }
 
-js_type_check("untrusted_closure_compile") {
-  closure_flags = system_app_closure_flags_strict
-  deps = [ ":untrusted" ]
-}
-
 js_library("trusted") {
   sources = [ "trusted.js" ]
   deps = [
-    ":message_types",
     "../mojom:mojom_js_library_for_compile",
+    "dpsl:types",
     "//chromeos/components/system_apps/public/js:message_pipe",
   ]
 }
-
-js_library("untrusted") {
-  sources = [ "untrusted.js" ]
-  deps = [
-    ":message_types",
-    "//chromeos/components/system_apps/public/js:message_pipe",
-  ]
-}
-
-js_library("message_types") {
-}
diff --git a/chromeos/components/telemetry_extension_ui/resources/dpsl.js b/chromeos/components/telemetry_extension_ui/resources/dpsl.js
deleted file mode 100644
index ad702e70..0000000
--- a/chromeos/components/telemetry_extension_ui/resources/dpsl.js
+++ /dev/null
@@ -1,12 +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.
-
-/**
- * @fileoverview Concatenation of the JS files we use in
- * chrome-untrusted://telemetry-extension/index.html.
- */
-
-// <include src="../../system_apps/public/js/message_pipe.js">
-// <include src="message_types.js">
-// <include src="untrusted.js">
diff --git a/chromeos/components/telemetry_extension_ui/resources/dpsl/BUILD.gn b/chromeos/components/telemetry_extension_ui/resources/dpsl/BUILD.gn
new file mode 100644
index 0000000..9a26dfd6
--- /dev/null
+++ b/chromeos/components/telemetry_extension_ui/resources/dpsl/BUILD.gn
@@ -0,0 +1,30 @@
+# 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("//chromeos/components/web_applications/system_apps.gni")
+import("//third_party/closure_compiler/compile_js.gni")
+
+assert(is_chromeos, "Telemetry Extension is Chrome OS only")
+assert(!is_official_build,
+       "Telemetry Extension is only built for unofficial builds")
+
+group("closure_compile") {
+  deps = [ ":dpsl_closure_compile" ]
+}
+
+js_type_check("dpsl_closure_compile") {
+  closure_flags = system_app_closure_flags_strict
+  deps = [ ":dpsl" ]
+}
+
+js_library("dpsl") {
+  sources = [ "api.js" ]
+  deps = [
+    ":types",
+    "//chromeos/components/system_apps/public/js:message_pipe",
+  ]
+}
+
+js_library("types") {
+}
diff --git a/chromeos/components/telemetry_extension_ui/resources/untrusted.js b/chromeos/components/telemetry_extension_ui/resources/dpsl/api.js
similarity index 100%
rename from chromeos/components/telemetry_extension_ui/resources/untrusted.js
rename to chromeos/components/telemetry_extension_ui/resources/dpsl/api.js
diff --git a/chromeos/components/telemetry_extension_ui/resources/dpsl/dpsl.js b/chromeos/components/telemetry_extension_ui/resources/dpsl/dpsl.js
new file mode 100644
index 0000000..e1e3ce20
--- /dev/null
+++ b/chromeos/components/telemetry_extension_ui/resources/dpsl/dpsl.js
@@ -0,0 +1,12 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Wrapper library around lower level system APIs. The library is
+ * used by Telemetry System Extensions.
+ */
+
+// <include src="../../../system_apps/public/js/message_pipe.js">
+// <include src="types.js">
+// <include src="api.js">
diff --git a/chromeos/components/telemetry_extension_ui/resources/message_types.js b/chromeos/components/telemetry_extension_ui/resources/dpsl/types.js
similarity index 100%
rename from chromeos/components/telemetry_extension_ui/resources/message_types.js
rename to chromeos/components/telemetry_extension_ui/resources/dpsl/types.js
diff --git a/chromeos/components/telemetry_extension_ui/resources/telemetry_extension_resources.grd b/chromeos/components/telemetry_extension_ui/resources/telemetry_extension_resources.grd
index 205c9b5..b859026 100644
--- a/chromeos/components/telemetry_extension_ui/resources/telemetry_extension_resources.grd
+++ b/chromeos/components/telemetry_extension_ui/resources/telemetry_extension_resources.grd
@@ -22,7 +22,7 @@
         <include name="IDR_TELEMETRY_EXTENSION_SYSTEM_EVENTS_SERVICE_MOJO_LITE_JS" file="${root_gen_dir}/chromeos/components/telemetry_extension_ui/mojom/system_events_service.mojom-lite.js" resource_path= "system_events_service.mojom-lite.js" use_base_dir="false" type="BINDATA" />
 
         <!-- Untrusted app host contents. -->
-        <include name="IDR_TELEMETRY_EXTENSION_DPSL_JS" file="dpsl.js" flattenhtml="true" type="BINDATA" />
+        <include name="IDR_TELEMETRY_EXTENSION_DPSL_JS" file="dpsl/dpsl.js" flattenhtml="true" type="BINDATA" />
       </if>
     </includes>
   </release>
diff --git a/chromeos/components/telemetry_extension_ui/resources/trusted_scripts.js b/chromeos/components/telemetry_extension_ui/resources/trusted_scripts.js
index 9125614..5723ad85 100644
--- a/chromeos/components/telemetry_extension_ui/resources/trusted_scripts.js
+++ b/chromeos/components/telemetry_extension_ui/resources/trusted_scripts.js
@@ -5,5 +5,5 @@
 /** @fileoverview Concatenation of the JS files we use in index.html. */
 
 // <include src="../../system_apps/public/js/message_pipe.js">
-// <include src="message_types.js">
+// <include src="dpsl/types.js">
 // <include src="trusted.js">
diff --git a/chromeos/components/telemetry_extension_ui/test/BUILD.gn b/chromeos/components/telemetry_extension_ui/test/BUILD.gn
index f607a9f..2cd1f32 100644
--- a/chromeos/components/telemetry_extension_ui/test/BUILD.gn
+++ b/chromeos/components/telemetry_extension_ui/test/BUILD.gn
@@ -84,7 +84,7 @@
     "untrusted_browsertest.js",
     "untrusted_test_handlers.js",
   ]
-  deps = [ "//chromeos/components/telemetry_extension_ui/resources:untrusted" ]
+  deps = [ "//chromeos/components/telemetry_extension_ui/resources/dpsl" ]
   externs_list = [
     "$externs_path/pending.js",
     "//chromeos/components/web_applications/js2gtest_support.externs.js",
diff --git a/chromeos/components/web_applications/externs/file_handling.externs.js b/chromeos/components/web_applications/externs/file_handling.externs.js
index 35b637e9..c31c86a 100644
--- a/chromeos/components/web_applications/externs/file_handling.externs.js
+++ b/chromeos/components/web_applications/externs/file_handling.externs.js
@@ -29,133 +29,10 @@
   async close() {}
 }
 
-/**
- * @typedef {{
- *   type: string,
- *   size: (number|undefined),
- *   position: (number|undefined),
- *   data: (BufferSource|Blob|string|undefined)
- * }}
- */
-let WriteParams;
-
-/** @interface */
-class FileSystemWritableFileStream {
-  /**
-   * @param {BufferSource|Blob|string|WriteParams} data
-   * @return {!Promise<undefined>}
-   */
-  async write(data) {}
-
-  /**
-   * @param {number} size
-   * @return {!Promise<undefined>}
-   */
-  async truncate(size) {}
-
-  /**
-   * @return {!Promise<undefined>}
-   */
-  async close() {}
-
-  /**
-   * @param {number} offset
-   * @return {!Promise<undefined>}
-   */
-  async seek(offset) {}
-}
-
-/** @typedef {{mode: string}} */
-let FileSystemHandlePermissionDescriptor;
-
-/** @interface */
-class FileSystemHandle {
-  constructor() {
-    /** @type {string} */
-    this.kind;
-
-    /** @type {string} */
-    this.name;
-  }
-
-  /**
-   * @param {FileSystemHandle} other
-   * @return {!Promise<boolean>}
-   */
-  isSameEntry(other) {}
-
-  /**
-   * @param {FileSystemHandlePermissionDescriptor} descriptor
-   * @return {!Promise<PermissionState>}
-   */
-  queryPermission(descriptor) {}
-
-  /**
-   * @param {FileSystemHandlePermissionDescriptor} descriptor
-   * @return {!Promise<PermissionState>}
-   */
-  requestPermission(descriptor) {}
-}
-
-/** @typedef {{keepExistingData: boolean}} */
-let FileSystemCreateWritableOptions;
-
-/** @interface */
-class FileSystemFileHandle extends FileSystemHandle {
-  /**
-   * @param {FileSystemCreateWritableOptions=} options
-   * @return {!Promise<!FileSystemWritableFileStream>}
-   */
-  createWritable(options) {}
-
-  /** @return {!Promise<!File>} */
-  getFile() {}
-}
-
-/** @typedef {{create: boolean}} */
-let FileSystemGetFileOptions;
-
-/** @typedef {{create: boolean}} */
-let FileSystemGetDirectoryOptions;
-
-/** @typedef {{recursive: boolean}} */
-let FileSystemRemoveOptions;
-
 /** @typedef {{type: string}} */
 let GetSystemDirectoryOptions;
 
 /** @interface */
-class FileSystemDirectoryHandle extends FileSystemHandle {
-  /**
-   * @param {string} name
-   * @param {FileSystemGetFileOptions=} options
-   * @return {!Promise<!FileSystemFileHandle>}
-   */
-  getFileHandle(name, options) {}
-
-  /**
-   * @param {string} name
-   * @param {FileSystemGetDirectoryOptions=} options
-   * @return {Promise<!FileSystemDirectoryHandle>}
-   */
-  getDirectoryHandle(name, options) {}
-
-  /** @return {!AsyncIterable<!Array<string|!FileSystemHandle>>} */
-  entries() {}
-  /** @return {!AsyncIterable<string>} */
-  keys() {}
-  /** @return {!AsyncIterable<!FileSystemHandle>} */
-  values() {}
-
-  /**
-   * @param {string} name
-   * @param {FileSystemRemoveOptions=} options
-   * @return {Promise<undefined>}
-   */
-  removeEntry(name, options) {}
-}
-
-/** @interface */
 class LaunchParams {
   constructor() {
     /** @type {Array<FileSystemHandle>} */
@@ -176,30 +53,6 @@
 }
 
 /**
- * https://wicg.github.io/native-file-system/#dictdef-filepickeraccepttype
- * @typedef {{
- *    description: string,
- *    accept: !Array<!Object<string, Array<string>>>,
- * }}
- */
-let FilePickerAcceptType;
-
-/**
- * https://wicg.github.io/native-file-system/#dictdef-filepickeroptions
- * https://wicg.github.io/native-file-system/#dictdef-directorypickeroptions
- * https://wicg.github.io/native-file-system/#dictdef-openfilepickeroptions
- * https://wicg.github.io/native-file-system/#dictdef-savefilepickeroptions
- * Note: `multiple` is only used for openfilepicker.
- * `types` is required if excludeAcceptAllOption is true.
- * @typedef {{
- *    multiple: (boolean|undefined),
- *    types: (!Array<!FilePickerAcceptType>|undefined),
- *    excludeAcceptAllOption: (boolean|undefined)
- * }}
- */
-let FilePickerOptions;
-
-/**
  * https://wicg.github.io/native-file-system/#native-filesystem
  * @param {(!FilePickerOptions|undefined)} options
  * @return {!Promise<(!Array<!FileSystemFileHandle>)>}
diff --git a/chromeos/dbus/dbus_thread_manager.h b/chromeos/dbus/dbus_thread_manager.h
index 5bd653f..b6239ea 100644
--- a/chromeos/dbus/dbus_thread_manager.h
+++ b/chromeos/dbus/dbus_thread_manager.h
@@ -205,4 +205,9 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after moved to ash.
+namespace ash {
+using ::chromeos::DBusThreadManager;
+}
+
 #endif  // CHROMEOS_DBUS_DBUS_THREAD_MANAGER_H_
diff --git a/chromeos/network/device_state.h b/chromeos/network/device_state.h
index a636361..19c95e54 100644
--- a/chromeos/network/device_state.h
+++ b/chromeos/network/device_state.h
@@ -139,4 +139,9 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash
+namespace ash {
+using ::chromeos::DeviceState;
+}
+
 #endif  // CHROMEOS_NETWORK_DEVICE_STATE_H_
diff --git a/chromeos/network/network_connect.h b/chromeos/network/network_connect.h
index 0efcf22f4e..70efdb8 100644
--- a/chromeos/network/network_connect.h
+++ b/chromeos/network/network_connect.h
@@ -115,4 +115,9 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash
+namespace ash {
+using ::chromeos::NetworkConnect;
+}
+
 #endif  // CHROMEOS_NETWORK_NETWORK_CONNECT_H_
diff --git a/chromeos/network/network_connection_handler.h b/chromeos/network/network_connection_handler.h
index 56dce4c..307512f 100644
--- a/chromeos/network/network_connection_handler.h
+++ b/chromeos/network/network_connection_handler.h
@@ -235,4 +235,9 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+using ::chromeos::ConnectCallbackMode;
+}
+
 #endif  // CHROMEOS_NETWORK_NETWORK_CONNECTION_HANDLER_H_
diff --git a/chromeos/network/network_event_log.h b/chromeos/network/network_event_log.h
index ac444e91..9e2e2d57 100644
--- a/chromeos/network/network_event_log.h
+++ b/chromeos/network/network_event_log.h
@@ -33,4 +33,9 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+using ::chromeos::NetworkPathId;
+}
+
 #endif  // CHROMEOS_NETWORK_NETWORK_EVENT_LOG_H_
diff --git a/chromeos/network/network_handler_callbacks.h b/chromeos/network/network_handler_callbacks.h
index d41db13..8a4926a 100644
--- a/chromeos/network/network_handler_callbacks.h
+++ b/chromeos/network/network_handler_callbacks.h
@@ -84,4 +84,9 @@
 }  // namespace network_handler
 }  // namespace chromeos
 
+namespace ash {
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace network_handler = ::chromeos::network_handler;
+}
+
 #endif  // CHROMEOS_NETWORK_NETWORK_HANDLER_CALLBACKS_H_
diff --git a/chromeos/network/network_state.h b/chromeos/network/network_state.h
index d4ea62c4..ab1eecf 100644
--- a/chromeos/network/network_state.h
+++ b/chromeos/network/network_state.h
@@ -23,6 +23,11 @@
 class Value;
 }
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+class MobileActivatorTest;
+}
+
 namespace chromeos {
 
 // Simple class to provide network state information about a network service.
@@ -275,7 +280,9 @@
   constexpr static const int kSignalStrengthChangeThreshold = 5;
 
  private:
-  friend class MobileActivatorTest;
+  // TODO(https://crbug.com/1164001): remove namespace declaration for ash
+  // when moved to ash.
+  friend class ::ash::MobileActivatorTest;
   friend class NetworkStateHandler;
 
   // Updates |name_| from the 'WiFi.HexSSID' entry in |properties|, which must
@@ -377,4 +384,9 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+using ::chromeos::NetworkState;
+}
+
 #endif  // CHROMEOS_NETWORK_NETWORK_STATE_H_
diff --git a/chromeos/network/network_state_handler.h b/chromeos/network/network_state_handler.h
index 4dd56ba4..5ad5445 100644
--- a/chromeos/network/network_state_handler.h
+++ b/chromeos/network/network_state_handler.h
@@ -723,4 +723,9 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+using ::chromeos::NetworkStateHandler;
+}
+
 #endif  // CHROMEOS_NETWORK_NETWORK_STATE_HANDLER_H_
diff --git a/chromeos/network/network_state_handler_observer.h b/chromeos/network/network_state_handler_observer.h
index 517b9719..af5cca6 100644
--- a/chromeos/network/network_state_handler_observer.h
+++ b/chromeos/network/network_state_handler_observer.h
@@ -85,4 +85,9 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+using ::chromeos::NetworkStateHandlerObserver;
+}
+
 #endif  // CHROMEOS_NETWORK_NETWORK_STATE_HANDLER_OBSERVER_H_
diff --git a/chromeos/services/assistant/BUILD.gn b/chromeos/services/assistant/BUILD.gn
index 74157cd3..e332e62 100644
--- a/chromeos/services/assistant/BUILD.gn
+++ b/chromeos/services/assistant/BUILD.gn
@@ -56,9 +56,7 @@
     "//components/signin/public/identity_manager",
     "//components/user_manager",
     "//media",
-    "//services/device/public/mojom",
     "//services/media_session/public/cpp",
-    "//services/network/public/cpp:cpp",
     "//ui/accessibility:ax_assistant",
   ]
 
@@ -99,10 +97,6 @@
       "platform/file_provider_impl.h",
       "platform/network_provider_impl.cc",
       "platform/network_provider_impl.h",
-      "platform/power_manager_provider_impl.cc",
-      "platform/power_manager_provider_impl.h",
-      "platform/system_provider_impl.cc",
-      "platform/system_provider_impl.h",
       "platform/volume_control_impl.cc",
       "platform/volume_control_impl.h",
       "platform_api_impl.cc",
@@ -134,9 +128,7 @@
       "//libassistant/shared/public",
       "//libassistant/shared/public:export",
       "//net",
-      "//services/media_session/public/mojom",
       "//services/network/public/cpp",
-      "//services/network/public/mojom",
       "//ui/base",
       "//url",
     ]
@@ -164,11 +156,10 @@
     "//components/prefs:test_support",
     "//components/signin/public/identity_manager",
     "//components/signin/public/identity_manager:test_support",
-    "//mojo/public/cpp/bindings:bindings",
+    "//mojo/public/cpp/bindings",
     "//services/device/public/mojom",
     "//services/media_session/public/mojom",
     "//services/network:test_support",
-    "//services/network/public/cpp:cpp",
     "//testing/gmock",
     "//testing/gtest",
   ]
@@ -193,8 +184,6 @@
       "assistant_manager_service_impl_unittest.cc",
       "platform/audio_output_provider_impl_unittest.cc",
       "platform/network_provider_impl_unittest.cc",
-      "platform/power_manager_provider_impl_unittest.cc",
-      "platform/system_provider_impl_unittest.cc",
       "test_support/fake_service_context.cc",
       "test_support/fake_service_context.h",
     ]
@@ -205,13 +194,11 @@
       "//chromeos/assistant/internal:tests",
       "//chromeos/assistant/internal/proto/google3",
       "//chromeos/assistant/test_support",
-      "//chromeos/dbus",
       "//chromeos/services/assistant/proxy",
       "//chromeos/services/assistant/public/cpp/migration",
       "//chromeos/services/assistant/public/cpp/migration:test_support",
       "//chromeos/services/network_config/public/mojom",
       "//services/audio/public/cpp:test_support",
-      "//services/device/public/cpp:test_support",
     ]
   }
 }
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc
index 72b21d89..cf6b6fe 100644
--- a/chromeos/services/assistant/assistant_manager_service_impl.cc
+++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -152,35 +152,6 @@
   return !redirect_logging;
 }
 
-libassistant::mojom::AndroidAppStatus ToMojomEnum(const AppStatus& app_status) {
-  switch (app_status) {
-    case AppStatus::kAvailable:
-      return libassistant::mojom::AndroidAppStatus::kAvailable;
-    case AppStatus::kUnavailable:
-      return libassistant::mojom::AndroidAppStatus::kUnavailable;
-    case AppStatus::kDisabled:
-      return libassistant::mojom::AndroidAppStatus::kDisabled;
-    case AppStatus::kUnknown:
-      return libassistant::mojom::AndroidAppStatus::kUnknown;
-    case AppStatus::kVersionMismatch:
-      return libassistant::mojom::AndroidAppStatus::kVersionMismatch;
-  }
-}
-
-libassistant::mojom::AndroidAppInfoPtr ToAndroidAppInfoPtr(
-    const AndroidAppInfo& app_info) {
-  auto result = libassistant::mojom::AndroidAppInfo::New();
-
-  result->package_name = app_info.package_name;
-  result->version = app_info.version;
-  result->localized_app_name = app_info.localized_app_name;
-  result->intent = app_info.intent;
-  result->status = ToMojomEnum(app_info.status);
-  result->action = app_info.action;
-
-  return result;
-}
-
 }  // namespace
 
 // Observer that will receive all speech recognition related events,
@@ -1005,13 +976,13 @@
 
 void AssistantManagerServiceImpl::OnAndroidAppListRefreshed(
     const std::vector<AndroidAppInfo>& apps_info) {
-  std::vector<libassistant::mojom::AndroidAppInfoPtr> filtered_apps_info;
+  std::vector<AndroidAppInfo> filtered_apps_info;
   for (const auto& app_info : apps_info) {
     // TODO(b/146355799): Remove the special handling for Android settings app.
     if (app_info.package_name == kAndroidSettingsAppPackage)
       continue;
 
-    filtered_apps_info.emplace_back(ToAndroidAppInfoPtr(app_info));
+    filtered_apps_info.push_back(app_info);
   }
   display_controller().SetAndroidAppList(std::move(filtered_apps_info));
 }
diff --git a/chromeos/services/assistant/media_host.cc b/chromeos/services/assistant/media_host.cc
index c883793..725dd03 100644
--- a/chromeos/services/assistant/media_host.cc
+++ b/chromeos/services/assistant/media_host.cc
@@ -23,36 +23,6 @@
 
 constexpr char kIntentActionView[] = "android.intent.action.VIEW";
 
-AppStatus ToAppStatus(libassistant::mojom::AndroidAppStatus status) {
-  using libassistant::mojom::AndroidAppStatus;
-  switch (status) {
-    case AndroidAppStatus::kUnknown:
-      return AppStatus::kUnknown;
-    case AndroidAppStatus::kAvailable:
-      return AppStatus::kAvailable;
-    case AndroidAppStatus::kUnavailable:
-      return AppStatus::kUnavailable;
-    case AndroidAppStatus::kVersionMismatch:
-      return AppStatus::kVersionMismatch;
-    case AndroidAppStatus::kDisabled:
-      return AppStatus::kDisabled;
-  }
-}
-
-AndroidAppInfo ToAndroidAppInfo(
-    const libassistant::mojom::AndroidAppInfoPtr& app_info) {
-  AndroidAppInfo result;
-
-  result.package_name = app_info->package_name;
-  result.version = app_info->version;
-  result.localized_app_name = app_info->localized_app_name;
-  result.action = app_info->action;
-  result.intent = app_info->intent;
-  result.status = ToAppStatus(app_info->status);
-
-  return result;
-}
-
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -187,15 +157,11 @@
     parent_->media_session_->NotifyMediaSessionMetadataChanged(*new_state);
   }
 
-  void PlayAndroidMedia(
-      libassistant::mojom::AndroidAppInfoPtr app_info_ptr) override {
+  void PlayAndroidMedia(const AndroidAppInfo& app_info) override {
     // This is the only action that can be executed when we play android media.
-    DCHECK_EQ(app_info_ptr->action, kIntentActionView);
+    DCHECK_EQ(app_info.action, kIntentActionView);
     // Status is meaningless when playing android media.
-    DCHECK_EQ(app_info_ptr->status,
-              libassistant::mojom::AndroidAppStatus::kUnknown);
-
-    AndroidAppInfo app_info = ToAndroidAppInfo(app_info_ptr);
+    DCHECK_EQ(app_info.status, AppStatus::kUnknown);
 
     for (auto& subscriber : interaction_subscribers())
       subscriber.OnOpenAppResponse(app_info);
diff --git a/chromeos/services/assistant/media_host_unittest.cc b/chromeos/services/assistant/media_host_unittest.cc
index 70f5cb3..17150c3 100644
--- a/chromeos/services/assistant/media_host_unittest.cc
+++ b/chromeos/services/assistant/media_host_unittest.cc
@@ -501,11 +501,13 @@
 
   EXPECT_CALL(mock, OnOpenAppResponse(MatchesAndroidAppInfo(output_app_info)));
 
-  auto input_app_info = libassistant::mojom::AndroidAppInfo::New(
-      "the package name",
-      /*version=*/111, "the localized name", "the intent",
-      /*status=*/libassistant::mojom::AndroidAppStatus::kUnknown,
-      /*action=*/kPlayAndroidMediaAction);
+  AndroidAppInfo input_app_info;
+  input_app_info.package_name = "the package name";
+  input_app_info.version = 111;
+  input_app_info.localized_app_name = "the localized name";
+  input_app_info.intent = "the intent";
+  input_app_info.status = chromeos::assistant::AppStatus::kUnknown;
+  input_app_info.action = kPlayAndroidMediaAction;
 
   libassistant_media_delegate().PlayAndroidMedia(std::move(input_app_info));
 
diff --git a/chromeos/services/assistant/platform/power_manager_provider_impl.cc b/chromeos/services/assistant/platform/power_manager_provider_impl.cc
deleted file mode 100644
index 3cea70c..0000000
--- a/chromeos/services/assistant/platform/power_manager_provider_impl.cc
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/services/assistant/platform/power_manager_provider_impl.h"
-
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/threading/platform_thread.h"
-#include "base/time/tick_clock.h"
-#include "base/time/time.h"
-#include "chromeos/services/libassistant/public/mojom/platform_delegate.mojom.h"
-#include "mojo/public/cpp/bindings/remote.h"
-#include "services/device/public/mojom/wake_lock_provider.mojom.h"
-
-namespace chromeos {
-namespace assistant {
-
-namespace {
-
-// Tag used to identify Assistant timers.
-constexpr char kTag[] = "Assistant";
-
-// Used with wake lock APIs.
-constexpr char kWakeLockReason[] = "Assistant";
-
-// Copied from Chrome's //base/time/time_now_posix.cc.
-// Returns count of |clk_id| in the form of a time delta. Returns an empty time
-// delta if |clk_id| isn't present on the system.
-base::TimeDelta ClockNow(clockid_t clk_id) {
-  struct timespec ts;
-  if (clock_gettime(clk_id, &ts) != 0) {
-    NOTREACHED() << "clock_gettime(" << clk_id << ") failed.";
-    return base::TimeDelta();
-  }
-  return base::TimeDelta::FromTimeSpec(ts);
-}
-
-}  // namespace
-
-PowerManagerProviderImpl::PowerManagerProviderImpl(
-    scoped_refptr<base::SequencedTaskRunner> main_thread_task_runner,
-    chromeos::libassistant::mojom::PlatformDelegate* delegate)
-    : main_thread_task_runner_(std::move(main_thread_task_runner)),
-      platform_delegate_(delegate),
-      weak_factory_(this) {}
-
-PowerManagerProviderImpl::~PowerManagerProviderImpl() = default;
-
-PowerManagerProviderImpl::AlarmId PowerManagerProviderImpl::AddWakeAlarm(
-    uint64_t relative_time_ms,
-    uint64_t max_delay_ms,
-    assistant_client::Callback0 callback) {
-  const AlarmId id = next_id_++;
-  DVLOG(1) << __func__ << "Add alarm ID " << id << " for "
-           << base::Time::Now() +
-                  base::TimeDelta::FromMilliseconds(relative_time_ms);
-
-  main_thread_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&PowerManagerProviderImpl::AddWakeAlarmOnMainThread,
-                     weak_factory_.GetWeakPtr(), id,
-                     GetCurrentBootTime() +
-                         base::TimeDelta::FromMilliseconds(relative_time_ms),
-                     std::move(callback)));
-  return id;
-}
-
-void PowerManagerProviderImpl::ExpireWakeAlarmNow(AlarmId id) {
-  DVLOG(1) << __func__;
-  main_thread_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&PowerManagerProviderImpl::OnTimerFiredOnMainThread,
-                     weak_factory_.GetWeakPtr(), id));
-}
-
-void PowerManagerProviderImpl::AcquireWakeLock() {
-  DVLOG(1) << __func__;
-  main_thread_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&PowerManagerProviderImpl::AcquireWakeLockOnMainThread,
-                     weak_factory_.GetWeakPtr()));
-}
-
-void PowerManagerProviderImpl::ReleaseWakeLock() {
-  DVLOG(1) << __func__;
-  main_thread_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&PowerManagerProviderImpl::ReleaseWakeLockOnMainThread,
-                     weak_factory_.GetWeakPtr()));
-}
-
-base::TimeTicks PowerManagerProviderImpl::GetCurrentBootTime() {
-  if (tick_clock_)
-    return tick_clock_->NowTicks();
-  return base::TimeTicks() + ClockNow(CLOCK_BOOTTIME);
-}
-
-void PowerManagerProviderImpl::AddWakeAlarmOnMainThread(
-    AlarmId id,
-    base::TimeTicks absolute_expiration_time,
-    assistant_client::Callback0 callback) {
-  DVLOG(1) << __func__;
-  DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
-
-  auto timer = std::make_unique<NativeTimer>(kTag + base::NumberToString(id));
-  // Once the timer is created successfully, start the timer and store
-  // associated data. The stored |callback| will be called in
-  // |OnTimerFiredOnMainThread|.
-  DVLOG(1) << "Starting timer with ID " << id << " for "
-           << absolute_expiration_time;
-  timer->Start(
-      absolute_expiration_time,
-      base::BindOnce(&PowerManagerProviderImpl::OnTimerFiredOnMainThread,
-                     weak_factory_.GetWeakPtr(), id),
-      base::BindOnce(&PowerManagerProviderImpl::OnStartTimerCallback,
-                     weak_factory_.GetWeakPtr(), id));
-  timers_[id] = std::make_pair(std::move(callback), std::move(timer));
-}
-
-void PowerManagerProviderImpl::AcquireWakeLockOnMainThread() {
-  DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
-  DCHECK_GE(wake_lock_count_, 0);
-
-  wake_lock_count_++;
-  if (wake_lock_count_ > 1) {
-    DVLOG(1) << "Wake lock acquire. Count: " << wake_lock_count_;
-    return;
-  }
-
-  // Initialize |wake_lock_| if this is the first time we're using it. Assistant
-  // can acquire a wake lock even when it has nothing to show on the display,
-  // this shouldn't wake the display up. Hence, the wake lock acquired is of
-  // type kPreventAppSuspension.
-  if (!wake_lock_) {
-    mojo::Remote<device::mojom::WakeLockProvider> provider;
-    platform_delegate_->BindWakeLockProvider(
-        provider.BindNewPipeAndPassReceiver());
-    provider->GetWakeLockWithoutContext(
-        device::mojom::WakeLockType::kPreventAppSuspension,
-        device::mojom::WakeLockReason::kOther, kWakeLockReason,
-        wake_lock_.BindNewPipeAndPassReceiver());
-  }
-
-  DVLOG(1) << "Wake lock new acquire";
-  // This would violate |GetWakeLockWithoutContext|'s API contract.
-  DCHECK(wake_lock_);
-  wake_lock_->RequestWakeLock();
-}
-
-void PowerManagerProviderImpl::ReleaseWakeLockOnMainThread() {
-  DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
-  DCHECK_GE(wake_lock_count_, 0);
-
-  if (wake_lock_count_ == 0) {
-    LOG(WARNING) << "Release without acquire. Count: " << wake_lock_count_;
-    return;
-  }
-
-  wake_lock_count_--;
-  if (wake_lock_count_ >= 1) {
-    DVLOG(1) << "Wake lock release. Count: " << wake_lock_count_;
-    return;
-  }
-
-  DCHECK(wake_lock_);
-  DVLOG(1) << "Wake lock force release";
-  wake_lock_->CancelWakeLock();
-}
-
-void PowerManagerProviderImpl::OnStartTimerCallback(AlarmId id, bool result) {
-  DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
-
-  if (!result) {
-    // TODO(crbug.com/919984): Notify Assistant of error so that it can do
-    // something meaningful in the UI.
-    LOG(ERROR) << "Failed to start timer on alarm ID " << id;
-    // Remove any metadata and resources associated with timers mapped to |id|.
-    DCHECK_GT(timers_.erase(id), 0UL);
-  }
-}
-
-void PowerManagerProviderImpl::OnTimerFiredOnMainThread(AlarmId id) {
-  DVLOG(1) << __func__ << " ID " << id;
-  DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
-
-  auto it = timers_.find(id);
-  if (it == timers_.end()) {
-    LOG(ERROR) << "Alarm with id " << id << " not found";
-    return;
-  }
-
-  // Stop tracking the timer once it has fired.
-  CallbackAndTimer& callback_and_timer = it->second;
-  callback_and_timer.first();
-  timers_.erase(id);
-}
-
-}  // namespace assistant
-}  // namespace chromeos
diff --git a/chromeos/services/assistant/platform/power_manager_provider_impl.h b/chromeos/services/assistant/platform/power_manager_provider_impl.h
deleted file mode 100644
index 759f091..0000000
--- a/chromeos/services/assistant/platform/power_manager_provider_impl.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROMEOS_SERVICES_ASSISTANT_PLATFORM_POWER_MANAGER_PROVIDER_IMPL_H_
-#define CHROMEOS_SERVICES_ASSISTANT_PLATFORM_POWER_MANAGER_PROVIDER_IMPL_H_
-
-#include <map>
-#include <memory>
-#include <utility>
-
-#include "base/component_export.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequence_checker.h"
-#include "chromeos/dbus/power/native_timer.h"
-#include "chromeos/services/libassistant/public/mojom/platform_delegate.mojom-forward.h"
-#include "libassistant/shared/public/platform_system.h"
-#include "mojo/public/cpp/bindings/remote.h"
-#include "services/device/public/mojom/wake_lock.mojom.h"
-
-namespace chromeos {
-namespace assistant {
-
-// Implementation of power management features for libassistant.
-//
-// This object lives on Assistant service's main thread i.e. on the same
-// sequence as |main_thread_task_runner_|. It is safe to assume that no lifetime
-// issues will occur if all its state is accessed from
-// |main_thread_task_runner_|. Any tasks posted on that will be invalidated if
-// this object dies.
-//
-// However, the public API of this class is called by libassistant and has no
-// guarantees on which thread it's called on. Therefore each method posts a task
-// on |main_thread_task_runner_| to mimic running the API on the same sequence
-// for thread safe access to all class members, as well as using Chrome APIs in
-// a thread safe manner.
-class COMPONENT_EXPORT(ASSISTANT_SERVICE) PowerManagerProviderImpl
-    : public assistant_client::PowerManagerProvider {
- public:
-  PowerManagerProviderImpl(
-      scoped_refptr<base::SequencedTaskRunner> main_thread_task_runner,
-      chromeos::libassistant::mojom::PlatformDelegate* delegate);
-  ~PowerManagerProviderImpl() override;
-
-  // assistant_client::PowerManagerProvider overrides. These are called from
-  // libassistant threads.
-  AlarmId AddWakeAlarm(uint64_t relative_time_ms,
-                       uint64_t max_delay_ms,
-                       assistant_client::Callback0 callback) override;
-  void ExpireWakeAlarmNow(AlarmId alarm_id) override;
-  void AcquireWakeLock() override;
-  void ReleaseWakeLock() override;
-
-  void set_tick_clock_for_testing(const base::TickClock* tick_clock) {
-    DCHECK(tick_clock);
-    tick_clock_ = tick_clock;
-  }
-
- private:
-  using CallbackAndTimer =
-      std::pair<assistant_client::Callback0, std::unique_ptr<NativeTimer>>;
-
-  // Returns time ticks from boot including time ticks during sleeping.
-  base::TimeTicks GetCurrentBootTime();
-
-  // Creates a native timer by calling |NativeTimer::Create|. Runs on
-  // |main_thread_task_runner_|.
-  void AddWakeAlarmOnMainThread(AlarmId id,
-                                base::TimeTicks absolute_expiration_time,
-                                assistant_client::Callback0 callback);
-
-  // Creates (if not created) and acquires |wake_lock_|.
-  // Runs on |main_thread_task_runner_|.
-  void AcquireWakeLockOnMainThread();
-
-  // Releases |wake_lock_|. Runs on |main_thread_task_runner_|.
-  void ReleaseWakeLockOnMainThread();
-
-  // Callback for a start operation on a |NativeTimer|.
-  void OnStartTimerCallback(AlarmId id, bool result);
-
-  // Callback for timer with id |id| added via |AddWakeAlarm|. It calls the
-  // corresponding client callback associated with the alarm. Removes the entry
-  // for |id| from |timers_|.
-  void OnTimerFiredOnMainThread(AlarmId id);
-
-  // Store of currently active alarm ids returned to clients and the
-  // corresponding pair of timer objects and client callbacks.
-  std::map<AlarmId, CallbackAndTimer> timers_;
-
-  // Monotonically increasing id used as key in |timers_| and assigned to timers
-  // in |AddWakeAlarm|. This is the only member that is accessed from
-  // libassistant threads only and not from |main_thread_task_runner_|.
-  AlarmId next_id_ = 1;
-
-  // Lazily initialized in response to the first call to |AcquireWakeLock|.
-  mojo::Remote<device::mojom::WakeLock> wake_lock_;
-
-  // Current number of clients that requested |wake_lock_|. On zero |wake_lock_|
-  // is released.
-  int wake_lock_count_ = 0;
-
-  // Used to post tasks from a libassistant thread on to the main thread in
-  // order to use Chrome APIs safely.
-  const scoped_refptr<base::SequencedTaskRunner> main_thread_task_runner_;
-
-  // Owned by |AssistantManagerServiceImpl|. Used to initialize |wake_lock_|.
-  chromeos::libassistant::mojom::PlatformDelegate* const platform_delegate_;
-
-  // Clock to use to calculate time ticks. Set and used only for testing.
-  const base::TickClock* tick_clock_ = nullptr;
-
-  base::WeakPtrFactory<PowerManagerProviderImpl> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(PowerManagerProviderImpl);
-};
-
-}  // namespace assistant
-}  // namespace chromeos
-
-#endif  // CHROMEOS_SERVICES_ASSISTANT_PLATFORM_POWER_MANAGER_PROVIDER_IMPL_H_
diff --git a/chromeos/services/assistant/platform/power_manager_provider_impl_unittest.cc b/chromeos/services/assistant/platform/power_manager_provider_impl_unittest.cc
deleted file mode 100644
index 244341d..0000000
--- a/chromeos/services/assistant/platform/power_manager_provider_impl_unittest.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/services/assistant/platform/power_manager_provider_impl.h"
-
-#include "base/run_loop.h"
-#include "base/test/task_environment.h"
-#include "chromeos/dbus/power/fake_power_manager_client.h"
-#include "chromeos/services/assistant/public/cpp/migration/fake_platform_delegate.h"
-#include "services/device/public/cpp/test/test_wake_lock_provider.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace chromeos {
-namespace assistant {
-
-namespace {
-
-// Constants to be used with the |AddWakeAlarm| API.
-const uint64_t kAlarmRelativeTimeMs = 1000;
-const uint64_t kAlarmMaxDelayMs = 0;
-
-class FakePlatformDelegateImpl : public FakePlatformDelegate {
- public:
-  explicit FakePlatformDelegateImpl(
-      device::TestWakeLockProvider* wake_lock_provider)
-      : wake_lock_provider_(wake_lock_provider) {}
-
-  // FakePlatformDelegate implementation:
-  void BindWakeLockProvider(
-      mojo::PendingReceiver<::device::mojom::WakeLockProvider> receiver)
-      override {
-    wake_lock_provider_->BindReceiver(std::move(receiver));
-  }
-
- private:
-  device::TestWakeLockProvider* const wake_lock_provider_;
-};
-
-}  // namespace
-
-class AssistantPowerManagerProviderImplTest : public testing::Test {
- public:
-  AssistantPowerManagerProviderImplTest()
-      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO,
-                          base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
-  ~AssistantPowerManagerProviderImplTest() override = default;
-
-  void SetUp() override {
-    chromeos::PowerManagerClient::InitializeFake();
-    FakePowerManagerClient::Get()->set_tick_clock(
-        task_environment_.GetMockTickClock());
-    power_manager_provider_impl_ = std::make_unique<PowerManagerProviderImpl>(
-        task_environment_.GetMainThreadTaskRunner(), &platform_delegate_);
-    power_manager_provider_impl_->set_tick_clock_for_testing(
-        task_environment_.GetMockTickClock());
-  }
-
-  void TearDown() override {
-    power_manager_provider_impl_.reset();
-    chromeos::PowerManagerClient::Shutdown();
-  }
-
- protected:
-  PowerManagerProviderImpl* GetPowerManagerProviderImpl() {
-    return power_manager_provider_impl_.get();
-  }
-
-  // Calls the acquire wake lock API and ensures that the request has reached
-  // the wake lock provider.
-  void AcquireWakeLock() {
-    power_manager_provider_impl_->AcquireWakeLock();
-    base::RunLoop run_loop;
-    run_loop.RunUntilIdle();
-  }
-
-  // Calls the release wake lock API and ensures that the request has reached
-  // the wake lock provider.
-  void ReleaseWakeLock() {
-    power_manager_provider_impl_->ReleaseWakeLock();
-    base::RunLoop run_loop;
-    run_loop.RunUntilIdle();
-  }
-
-  // Returns the number of active wake locks of type |type|.
-  int GetActiveWakeLocks(device::mojom::WakeLockType type) {
-    base::RunLoop run_loop;
-    int result_count = 0;
-    wake_lock_provider_.GetActiveWakeLocksForTests(
-        type,
-        base::BindOnce(
-            [](base::RunLoop* run_loop, int* result_count, int32_t count) {
-              *result_count = count;
-              run_loop->Quit();
-            },
-            &run_loop, &result_count));
-    run_loop.Run();
-    return result_count;
-  }
-
-  // Returns true iff adding a wake alarm via |AddWakeAlarm| returns a > 0
-  // result and the alarm expiration callback fires.
-  bool CheckAddWakeAlarmAndExpiration(uint64_t relative_time_ms,
-                                      uint64_t max_delay_ms) {
-    // Schedule wake alarm and check if valid id is returned and timer callback
-    // is fired.
-    bool result = false;
-    assistant_client::Callback0 wake_alarm_expiration_cb(
-        [&result]() { result = true; });
-    assistant_client::PowerManagerProvider::AlarmId id =
-        power_manager_provider_impl_->AddWakeAlarm(
-            relative_time_ms, max_delay_ms,
-            std::move(wake_alarm_expiration_cb));
-    task_environment_.FastForwardBy(
-        base::TimeDelta::FromMilliseconds(relative_time_ms));
-
-    if (id <= 0UL)
-      return false;
-    return result;
-  }
-
- private:
-  // Needs to be of type |MainThreadType::IO| to use |NativeTimer|.
-  base::test::TaskEnvironment task_environment_;
-
-  device::TestWakeLockProvider wake_lock_provider_;
-  FakePlatformDelegateImpl platform_delegate_{&wake_lock_provider_};
-
-  std::unique_ptr<PowerManagerProviderImpl> power_manager_provider_impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(AssistantPowerManagerProviderImplTest);
-};
-
-TEST_F(AssistantPowerManagerProviderImplTest, CheckAcquireAndReleaseWakeLock) {
-  // Acquire wake lock and check wake lock count.
-  AcquireWakeLock();
-  EXPECT_EQ(1, GetActiveWakeLocks(
-                   device::mojom::WakeLockType::kPreventAppSuspension));
-  // Acquire another wake lock, this shouldn't change the overall count.
-  AcquireWakeLock();
-  EXPECT_EQ(1, GetActiveWakeLocks(
-                   device::mojom::WakeLockType::kPreventAppSuspension));
-  // Release wake lock, this shouldn't change the overall count.
-  ReleaseWakeLock();
-  EXPECT_EQ(1, GetActiveWakeLocks(
-                   device::mojom::WakeLockType::kPreventAppSuspension));
-  // Release wake lock, this should finally release the wake lock.
-  ReleaseWakeLock();
-  EXPECT_EQ(0, GetActiveWakeLocks(
-                   device::mojom::WakeLockType::kPreventAppSuspension));
-  // An unbalanced release call shouldn't do anything.
-  ReleaseWakeLock();
-  EXPECT_EQ(0, GetActiveWakeLocks(
-                   device::mojom::WakeLockType::kPreventAppSuspension));
-}
-
-TEST_F(AssistantPowerManagerProviderImplTest, CheckWakeAlarms) {
-  // Check consecutive wake alarms addition and expiration.
-  EXPECT_TRUE(
-      CheckAddWakeAlarmAndExpiration(kAlarmRelativeTimeMs, kAlarmMaxDelayMs));
-  EXPECT_TRUE(
-      CheckAddWakeAlarmAndExpiration(kAlarmRelativeTimeMs, kAlarmMaxDelayMs));
-}
-
-}  // namespace assistant
-}  // namespace chromeos
diff --git a/chromeos/services/assistant/platform/system_provider_impl.cc b/chromeos/services/assistant/platform/system_provider_impl.cc
deleted file mode 100644
index b171bbd..0000000
--- a/chromeos/services/assistant/platform/system_provider_impl.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/services/assistant/platform/system_provider_impl.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/system/sys_info.h"
-#include "chromeos/services/assistant/platform/power_manager_provider_impl.h"
-
-namespace chromeos {
-namespace assistant {
-
-SystemProviderImpl::SystemProviderImpl(
-    std::unique_ptr<PowerManagerProviderImpl> power_manager_provider,
-    chromeos::libassistant::mojom::PlatformDelegate* platform_delegate)
-    : power_manager_provider_(std::move(power_manager_provider)) {
-  platform_delegate->BindBatteryMonitor(
-      battery_monitor_.BindNewPipeAndPassReceiver());
-  battery_monitor_->QueryNextStatus(base::BindOnce(
-      &SystemProviderImpl::OnBatteryStatus, base::Unretained(this)));
-}
-
-SystemProviderImpl::~SystemProviderImpl() = default;
-
-assistant_client::MicMuteState SystemProviderImpl::GetMicMuteState() {
-  // CRAS input is never muted.
-  return assistant_client::MicMuteState::MICROPHONE_ENABLED;
-}
-
-void SystemProviderImpl::RegisterMicMuteChangeCallback(
-    ConfigChangeCallback callback) {
-  // No need to register since it will never change.
-}
-
-assistant_client::PowerManagerProvider*
-SystemProviderImpl::GetPowerManagerProvider() {
-  return power_manager_provider_.get();
-}
-
-bool SystemProviderImpl::GetBatteryState(BatteryState* state) {
-  if (!current_battery_status_)
-    return false;
-
-  state->is_charging = current_battery_status_->charging;
-  state->charge_percentage =
-      static_cast<int>(current_battery_status_->level * 100);
-  return true;
-}
-
-void SystemProviderImpl::UpdateTimezoneAndLocale(const std::string& timezone,
-                                                 const std::string& locale) {}
-
-void SystemProviderImpl::OnBatteryStatus(
-    device::mojom::BatteryStatusPtr battery_status) {
-  current_battery_status_ = std::move(battery_status);
-
-  // Battery monitor is one shot, send another query to get battery status
-  // updates. This query will only return when a status changes.
-  battery_monitor_->QueryNextStatus(base::BindOnce(
-      &SystemProviderImpl::OnBatteryStatus, base::Unretained(this)));
-}
-
-void SystemProviderImpl::FlushForTesting() {
-  battery_monitor_.FlushForTesting();
-}
-
-}  // namespace assistant
-}  // namespace chromeos
diff --git a/chromeos/services/assistant/platform/system_provider_impl.h b/chromeos/services/assistant/platform/system_provider_impl.h
deleted file mode 100644
index e4b03634..0000000
--- a/chromeos/services/assistant/platform/system_provider_impl.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROMEOS_SERVICES_ASSISTANT_PLATFORM_SYSTEM_PROVIDER_IMPL_H_
-#define CHROMEOS_SERVICES_ASSISTANT_PLATFORM_SYSTEM_PROVIDER_IMPL_H_
-
-#include <memory>
-#include <string>
-
-#include "base/component_export.h"
-#include "base/macros.h"
-#include "chromeos/services/libassistant/public/mojom/platform_delegate.mojom.h"
-#include "libassistant/shared/public/platform_system.h"
-#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "mojo/public/cpp/bindings/remote.h"
-#include "services/device/public/mojom/battery_monitor.mojom.h"
-#include "services/device/public/mojom/battery_status.mojom.h"
-
-namespace chromeos {
-namespace assistant {
-
-class PowerManagerProviderImpl;
-
-class COMPONENT_EXPORT(ASSISTANT_SERVICE) SystemProviderImpl
-    : public assistant_client::SystemProvider {
- public:
-  // Acceptable to pass in |nullptr| for |power_manager_provider| when no
-  // platform power manager provider is available.
-  SystemProviderImpl(
-      std::unique_ptr<PowerManagerProviderImpl> power_manager_provider,
-      chromeos::libassistant::mojom::PlatformDelegate* platform_delegate);
-  ~SystemProviderImpl() override;
-
-  // assistant_client::SystemProvider implementation:
-  assistant_client::MicMuteState GetMicMuteState() override;
-  void RegisterMicMuteChangeCallback(ConfigChangeCallback callback) override;
-  assistant_client::PowerManagerProvider* GetPowerManagerProvider() override;
-  bool GetBatteryState(BatteryState* state) override;
-  void UpdateTimezoneAndLocale(const std::string& timezone,
-                               const std::string& locale) override;
-
- private:
-  friend class AssistantSystemProviderImplTest;
-  void OnBatteryStatus(device::mojom::BatteryStatusPtr battery_status);
-
-  void FlushForTesting();
-
-  std::unique_ptr<PowerManagerProviderImpl> power_manager_provider_;
-
-  mojo::Remote<device::mojom::BatteryMonitor> battery_monitor_;
-  device::mojom::BatteryStatusPtr current_battery_status_;
-
-  DISALLOW_COPY_AND_ASSIGN(SystemProviderImpl);
-};
-
-}  // namespace assistant
-}  // namespace chromeos
-
-#endif  // CHROMEOS_SERVICES_ASSISTANT_PLATFORM_SYSTEM_PROVIDER_IMPL_H_
diff --git a/chromeos/services/assistant/platform/system_provider_impl_unittest.cc b/chromeos/services/assistant/platform/system_provider_impl_unittest.cc
deleted file mode 100644
index 6610ebb..0000000
--- a/chromeos/services/assistant/platform/system_provider_impl_unittest.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/services/assistant/platform/system_provider_impl.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/test/task_environment.h"
-#include "chromeos/services/assistant/platform/power_manager_provider_impl.h"
-#include "chromeos/services/assistant/public/cpp/migration/fake_platform_delegate.h"
-#include "mojo/public/cpp/bindings/receiver.h"
-#include "services/device/public/mojom/battery_monitor.mojom.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace chromeos {
-namespace assistant {
-
-class FakeBatteryMonitor : device::mojom::BatteryMonitor {
- public:
-  FakeBatteryMonitor() = default;
-
-  void Bind(
-      mojo::PendingReceiver<::device::mojom::BatteryMonitor> pending_receiver) {
-    receiver_.Bind(std::move(pending_receiver));
-  }
-
-  void QueryNextStatus(QueryNextStatusCallback callback) override {
-    if (has_status) {
-      std::move(callback).Run(std::move(battery_status_));
-      has_status = false;
-    } else {
-      callback_ = std::move(callback);
-    }
-  }
-
-  void SetStatus(device::mojom::BatteryStatusPtr battery_status) {
-    battery_status_ = std::move(battery_status);
-    has_status = true;
-
-    if (callback_) {
-      std::move(callback_).Run(std::move(battery_status_));
-      has_status = false;
-    }
-  }
-
- private:
-  bool has_status = false;
-
-  device::mojom::BatteryStatusPtr battery_status_;
-  QueryNextStatusCallback callback_;
-
-  mojo::Receiver<device::mojom::BatteryMonitor> receiver_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBatteryMonitor);
-};
-
-class AssistantSystemProviderImplTest : public testing::Test {
- public:
-  AssistantSystemProviderImplTest()
-      : task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {
-    battery_monitor_.SetStatus(device::mojom::BatteryStatus::New(
-        false /* charging */, 0 /* charging_time */, 0 /* discharging_time */,
-        0 /* level */));
-
-    system_provider_impl_ = std::make_unique<SystemProviderImpl>(
-        std::make_unique<PowerManagerProviderImpl>(
-            task_environment_.GetMainThreadTaskRunner(), &platform_delegate_),
-        &platform_delegate_);
-    battery_monitor_.Bind(platform_delegate_.battery_monitor_receiver());
-    FlushForTesting();
-  }
-
-  SystemProviderImpl* system_provider() { return system_provider_impl_.get(); }
-
-  FakeBatteryMonitor* battery_monitor() { return &battery_monitor_; }
-
-  void FlushForTesting() { system_provider_impl_->FlushForTesting(); }
-
- private:
-  base::test::TaskEnvironment task_environment_;
-  FakeBatteryMonitor battery_monitor_;
-  FakePlatformDelegate platform_delegate_;
-  std::unique_ptr<SystemProviderImpl> system_provider_impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(AssistantSystemProviderImplTest);
-};
-
-TEST_F(AssistantSystemProviderImplTest, GetBatteryStateReturnsLastState) {
-  SystemProviderImpl::BatteryState state;
-  // Initial level is 0
-  system_provider()->GetBatteryState(&state);
-  FlushForTesting();
-
-  EXPECT_EQ(state.charge_percentage, 0);
-  battery_monitor()->SetStatus(device::mojom::BatteryStatus::New(
-      false /* charging */, 0 /* charging_time */, 0 /* discharging_time */,
-      1 /* level */));
-
-  FlushForTesting();
-  // New level after status change
-  system_provider()->GetBatteryState(&state);
-  EXPECT_EQ(state.charge_percentage, 100);
-}
-
-}  // namespace assistant
-}  // namespace chromeos
diff --git a/chromeos/services/assistant/platform_api_impl.cc b/chromeos/services/assistant/platform_api_impl.cc
index cb90c66..6e6fe2b3 100644
--- a/chromeos/services/assistant/platform_api_impl.cc
+++ b/chromeos/services/assistant/platform_api_impl.cc
@@ -10,7 +10,6 @@
 
 #include "chromeos/services/assistant/media_session/assistant_media_session.h"
 #include "chromeos/services/assistant/platform/audio_devices.h"
-#include "chromeos/services/assistant/platform/power_manager_provider_impl.h"
 #include "chromeos/services/assistant/public/cpp/features.h"
 #include "chromeos/services/assistant/public/cpp/migration/audio_input_host.h"
 #include "chromeos/services/assistant/utils.h"
@@ -23,7 +22,6 @@
 using assistant_client::FileProvider;
 using assistant_client::NetworkProvider;
 using assistant_client::PlatformApi;
-using assistant_client::SystemProvider;
 
 namespace chromeos {
 namespace assistant {
@@ -42,16 +40,7 @@
                              platform_delegate,
                              background_task_runner,
                              media::AudioDeviceDescription::kDefaultDeviceId),
-      network_provider_(platform_delegate) {
-  // Only enable native power features if they are supported by the UI.
-  std::unique_ptr<PowerManagerProviderImpl> provider;
-  if (features::IsPowerManagerEnabled()) {
-    provider = std::make_unique<PowerManagerProviderImpl>(
-        std::move(main_thread_task_runner), platform_delegate);
-  }
-  system_provider_ = std::make_unique<SystemProviderImpl>(std::move(provider),
-                                                          platform_delegate);
-}
+      network_provider_(platform_delegate) {}
 
 PlatformApiImpl::~PlatformApiImpl() = default;
 
@@ -67,9 +56,5 @@
   return network_provider_;
 }
 
-SystemProvider& PlatformApiImpl::GetSystemProvider() {
-  return *system_provider_;
-}
-
 }  // namespace assistant
 }  // namespace chromeos
diff --git a/chromeos/services/assistant/platform_api_impl.h b/chromeos/services/assistant/platform_api_impl.h
index 9425e2cb..bf54f52e 100644
--- a/chromeos/services/assistant/platform_api_impl.h
+++ b/chromeos/services/assistant/platform_api_impl.h
@@ -5,7 +5,6 @@
 #ifndef CHROMEOS_SERVICES_ASSISTANT_PLATFORM_API_IMPL_H_
 #define CHROMEOS_SERVICES_ASSISTANT_PLATFORM_API_IMPL_H_
 
-#include <memory>
 #include <string>
 #include <utility>
 #include <vector>
@@ -13,7 +12,6 @@
 #include "chromeos/services/assistant/platform/audio_output_provider_impl.h"
 #include "chromeos/services/assistant/platform/file_provider_impl.h"
 #include "chromeos/services/assistant/platform/network_provider_impl.h"
-#include "chromeos/services/assistant/platform/system_provider_impl.h"
 #include "chromeos/services/assistant/public/cpp/assistant_service.h"
 #include "chromeos/services/assistant/public/cpp/migration/cros_platform_api.h"
 #include "chromeos/services/libassistant/public/mojom/platform_delegate.mojom-forward.h"
@@ -41,13 +39,11 @@
   assistant_client::AudioOutputProvider& GetAudioOutputProvider() override;
   assistant_client::FileProvider& GetFileProvider() override;
   assistant_client::NetworkProvider& GetNetworkProvider() override;
-  assistant_client::SystemProvider& GetSystemProvider() override;
 
  private:
   AudioOutputProviderImpl audio_output_provider_;
   FileProviderImpl file_provider_;
   NetworkProviderImpl network_provider_;
-  std::unique_ptr<SystemProviderImpl> system_provider_;
 
   DISALLOW_COPY_AND_ASSIGN(PlatformApiImpl);
 };
diff --git a/chromeos/services/assistant/public/cpp/migration/cros_platform_api.h b/chromeos/services/assistant/public/cpp/migration/cros_platform_api.h
index 67f0912..7d49688 100644
--- a/chromeos/services/assistant/public/cpp/migration/cros_platform_api.h
+++ b/chromeos/services/assistant/public/cpp/migration/cros_platform_api.h
@@ -11,7 +11,6 @@
 class AudioOutputProvider;
 class FileProvider;
 class NetworkProvider;
-class SystemProvider;
 }  // namespace assistant_client
 
 namespace chromeos {
@@ -35,9 +34,6 @@
   // Returns the network provider to be used by libassistant.
   virtual assistant_client::NetworkProvider& GetNetworkProvider() = 0;
 
-  // Returns the system provider to be used by libassistant.
-  virtual assistant_client::SystemProvider& GetSystemProvider() = 0;
-
  private:
   DISALLOW_COPY_AND_ASSIGN(CrosPlatformApi);
 };
diff --git a/chromeos/services/assistant/public/cpp/migration/fake_platform_api.cc b/chromeos/services/assistant/public/cpp/migration/fake_platform_api.cc
index 4013afb1..01e05f3f9 100644
--- a/chromeos/services/assistant/public/cpp/migration/fake_platform_api.cc
+++ b/chromeos/services/assistant/public/cpp/migration/fake_platform_api.cc
@@ -87,10 +87,5 @@
   abort();
 }
 
-assistant_client::SystemProvider& FakePlatformApi::GetSystemProvider() {
-  NOTIMPLEMENTED();
-  abort();
-}
-
 }  // namespace assistant
 }  // namespace chromeos
diff --git a/chromeos/services/assistant/public/cpp/migration/fake_platform_api.h b/chromeos/services/assistant/public/cpp/migration/fake_platform_api.h
index 50395d7..b22f00c 100644
--- a/chromeos/services/assistant/public/cpp/migration/fake_platform_api.h
+++ b/chromeos/services/assistant/public/cpp/migration/fake_platform_api.h
@@ -26,7 +26,6 @@
   assistant_client::AudioOutputProvider& GetAudioOutputProvider() override;
   assistant_client::FileProvider& GetFileProvider() override;
   assistant_client::NetworkProvider& GetNetworkProvider() override;
-  assistant_client::SystemProvider& GetSystemProvider() override;
 
  private:
   std::unique_ptr<assistant_client::AudioOutputProvider> audio_output_provider_;
diff --git a/chromeos/services/libassistant/BUILD.gn b/chromeos/services/libassistant/BUILD.gn
index 7cc5b42..00e1ed2 100644
--- a/chromeos/services/libassistant/BUILD.gn
+++ b/chromeos/services/libassistant/BUILD.gn
@@ -60,8 +60,12 @@
     "media_controller.h",
     "platform_api.cc",
     "platform_api.h",
+    "power_manager_provider_impl.cc",
+    "power_manager_provider_impl.h",
     "service_controller.cc",
     "service_controller.h",
+    "system_provider_impl.cc",
+    "system_provider_impl.h",
     "util.cc",
     "util.h",
   ]
@@ -74,6 +78,7 @@
     "//chromeos/assistant/internal:libassistant",
     "//chromeos/assistant/internal:support",
     "//chromeos/dbus",
+    "//chromeos/dbus/power",
     "//chromeos/services/assistant/public/cpp",
     "//chromeos/services/assistant/public/cpp/migration",
     "//chromeos/services/libassistant/public/mojom",
@@ -85,6 +90,7 @@
     "//media",
     "//services/audio/public/cpp",
     "//services/network/public/cpp",
+    "//services/network/public/mojom",
   ]
 
   defines = [ "IS_LIBASSISTANT_SERVICE_IMPL" ]
@@ -126,8 +132,10 @@
   sources = [
     "audio_input_controller_unittest.cc",
     "media_controller_unittest.cc",
+    "power_manager_provider_impl_unittest.cc",
     "service_controller_unittest.cc",
     "speech_recognition_observer_unittest.cc",
+    "system_provider_impl_unittest.cc",
   ]
 
   deps = [
@@ -139,6 +147,7 @@
     "//chromeos/assistant/internal",
     "//chromeos/assistant/internal:support",
     "//chromeos/assistant/internal:test_support",
+    "//chromeos/dbus/power",
     "//chromeos/services/assistant/public/cpp",
     "//chromeos/services/assistant/public/cpp/migration",
     "//chromeos/services/assistant/public/cpp/migration:test_support",
@@ -146,6 +155,7 @@
     "//libassistant/shared/internal_api:assistant_manager_internal",
     "//libassistant/shared/internal_api/c:api_wrappers",
     "//services/audio/public/cpp:test_support",
+    "//services/device/public/cpp:test_support",
     "//services/network:test_support",
     "//services/network/public/cpp",
     "//testing/gmock",
diff --git a/chromeos/services/libassistant/display_controller.cc b/chromeos/services/libassistant/display_controller.cc
index 6d43a92..fb1ce4a 100644
--- a/chromeos/services/libassistant/display_controller.cc
+++ b/chromeos/services/libassistant/display_controller.cc
@@ -14,29 +14,6 @@
 namespace chromeos {
 namespace libassistant {
 
-namespace {
-
-assistant::AndroidAppInfo ToAndroidAppInfo(
-    const mojom::AndroidAppInfoPtr& app) {
-  assistant::AndroidAppInfo result;
-  result.package_name = app->package_name;
-  result.version = app->version;
-  result.localized_app_name = app->localized_app_name;
-  return result;
-}
-
-std::vector<assistant::AndroidAppInfo> ToAndroidAppInfoList(
-    const std::vector<mojom::AndroidAppInfoPtr>& apps) {
-  std::vector<assistant::AndroidAppInfo> result;
-
-  for (const auto& app : apps)
-    result.push_back(ToAndroidAppInfo(app));
-
-  return result;
-}
-
-}  // namespace
-
 class DisplayController::EventObserver : public DisplayConnectionObserver {
  public:
   explicit EventObserver(DisplayController* parent) : parent_(parent) {}
@@ -85,8 +62,8 @@
 }
 
 void DisplayController::SetAndroidAppList(
-    std::vector<mojom::AndroidAppInfoPtr> apps) {
-  display_connection_->OnAndroidAppListRefreshed(ToAndroidAppInfoList(apps));
+    const std::vector<::chromeos::assistant::AndroidAppInfo>& apps) {
+  display_connection_->OnAndroidAppListRefreshed(apps);
 }
 
 void DisplayController::OnAssistantManagerCreated(
diff --git a/chromeos/services/libassistant/display_controller.h b/chromeos/services/libassistant/display_controller.h
index a097662..e796183 100644
--- a/chromeos/services/libassistant/display_controller.h
+++ b/chromeos/services/libassistant/display_controller.h
@@ -38,7 +38,8 @@
   void SetArcPlayStoreEnabled(bool enabled) override;
   void SetDeviceAppsEnabled(bool enabled) override;
   void SetRelatedInfoEnabled(bool enabled) override;
-  void SetAndroidAppList(std::vector<mojom::AndroidAppInfoPtr> apps) override;
+  void SetAndroidAppList(
+      const std::vector<::chromeos::assistant::AndroidAppInfo>& apps) override;
 
   // AssistantManagerObserver implementation:
   void OnAssistantManagerCreated(
diff --git a/chromeos/services/libassistant/libassistant_service.cc b/chromeos/services/libassistant/libassistant_service.cc
index 408951d..00cfa21 100644
--- a/chromeos/services/libassistant/libassistant_service.cc
+++ b/chromeos/services/libassistant/libassistant_service.cc
@@ -55,8 +55,7 @@
         .SetAudioOutputProvider(&platform_api->GetAudioOutputProvider())
         .SetAuthProvider(fake_auth_provider_.get())
         .SetFileProvider(&platform_api->GetFileProvider())
-        .SetNetworkProvider(&platform_api->GetNetworkProvider())
-        .SetSystemProvider(&platform_api->GetSystemProvider());
+        .SetNetworkProvider(&platform_api->GetNetworkProvider());
   }
 }
 
@@ -88,6 +87,8 @@
   media_controller_->Bind(std::move(media_controller),
                           std::move(media_delegate));
   service_controller_->Bind(std::move(service_controller));
+
+  platform_api_->Initialize(platform_delegate_.get());
 }
 
 void LibassistantService::SetInitializeCallback(InitializeCallback callback) {
diff --git a/chromeos/services/libassistant/media_controller.cc b/chromeos/services/libassistant/media_controller.cc
index 3244d3e8..18067e3 100644
--- a/chromeos/services/libassistant/media_controller.cc
+++ b/chromeos/services/libassistant/media_controller.cc
@@ -115,7 +115,7 @@
   return std::string();
 }
 
-mojom::AndroidAppInfoPtr GetAppInfoFromMediaArgs(
+base::Optional<AndroidAppInfo> GetAppInfoFromMediaArgs(
     const std::string& play_media_args_proto) {
   PlayMediaArgs play_media_args;
   if (play_media_args.ParseFromString(play_media_args_proto)) {
@@ -123,17 +123,16 @@
       if (media_item.has_provider() &&
           media_item.provider().has_android_app_info()) {
         auto& app_info = media_item.provider().android_app_info();
-        auto android_app_info_ptr = mojom::AndroidAppInfo::New();
-        android_app_info_ptr->package_name = app_info.package_name();
-        android_app_info_ptr->version = app_info.app_version();
-        android_app_info_ptr->localized_app_name =
-            app_info.localized_app_name();
-        android_app_info_ptr->intent = app_info.android_intent();
-        return android_app_info_ptr;
+        AndroidAppInfo result;
+        result.package_name = app_info.package_name();
+        result.version = app_info.app_version();
+        result.localized_app_name = app_info.localized_app_name();
+        result.intent = app_info.android_intent();
+        return result;
       }
     }
   }
-  return nullptr;
+  return base::nullopt;
 }
 
 std::string GetWebUrlFromMediaArgs(const std::string& play_media_args_proto) {
@@ -215,10 +214,11 @@
   }
 
   void OnPlayMedia(const std::string& play_media_args_proto) {
-    mojom::AndroidAppInfoPtr app_info =
+    base::Optional<AndroidAppInfo> app_info =
         GetAppInfoFromMediaArgs(play_media_args_proto);
     if (app_info) {
-      OnOpenMediaAndroidIntent(play_media_args_proto, std::move(app_info));
+      OnOpenMediaAndroidIntent(play_media_args_proto,
+                               std::move(app_info.value()));
     } else {
       OnOpenUrl(play_media_args_proto);
     }
@@ -226,12 +226,12 @@
 
   // Handle android media playback intent.
   void OnOpenMediaAndroidIntent(const std::string& play_media_args_proto,
-                                mojom::AndroidAppInfoPtr app_info) {
-    app_info->action = kIntentActionView;
-    if (app_info->intent.empty()) {
+                                AndroidAppInfo app_info) {
+    app_info.action = kIntentActionView;
+    if (app_info.intent.empty()) {
       std::string url = GetAndroidIntentUrlFromMediaArgs(play_media_args_proto);
       if (!url.empty())
-        app_info->intent = url;
+        app_info.intent = url;
     }
     VLOG(1) << "Playing android media";
     delegate().PlayAndroidMedia(std::move(app_info));
diff --git a/chromeos/services/libassistant/media_controller_unittest.cc b/chromeos/services/libassistant/media_controller_unittest.cc
index 9b812bf2..44127eb4 100644
--- a/chromeos/services/libassistant/media_controller_unittest.cc
+++ b/chromeos/services/libassistant/media_controller_unittest.cc
@@ -20,7 +20,8 @@
 namespace {
 
 using LibassistantPlaybackState = assistant_client::MediaStatus::PlaybackState;
-using chromeos::assistant::shared::AndroidAppInfo;
+using ProtoAndroidAppInfo = chromeos::assistant::shared::AndroidAppInfo;
+using AndroidAppInfo = chromeos::assistant::AndroidAppInfo;
 using chromeos::assistant::shared::PlayMediaArgs;
 using mojom::PlaybackState;
 
@@ -65,9 +66,7 @@
 
   // mojom::MediaDelegate implementation:
   MOCK_METHOD(void, OnPlaybackStateChanged, (mojom::MediaStatePtr new_state));
-  MOCK_METHOD(void,
-              PlayAndroidMedia,
-              (::chromeos::libassistant::mojom::AndroidAppInfoPtr app_info));
+  MOCK_METHOD(void, PlayAndroidMedia, (const AndroidAppInfo& app_info));
   MOCK_METHOD(void, PlayWebMedia, (const std::string& url));
   MOCK_METHOD(void, NextTrack, ());
   MOCK_METHOD(void, PreviousTrack, ());
@@ -307,27 +306,27 @@
 TEST_F(AssistantMediaControllerTest, ShouldSupportPlayAndroidMedia) {
   PlayMediaArgs play_media_args;
   PlayMediaArgs::MediaItem* media_item = play_media_args.add_media_item();
-  AndroidAppInfo* android_app_info =
+  ProtoAndroidAppInfo* android_app_info =
       media_item->mutable_provider()->mutable_android_app_info();
   android_app_info->set_package_name("package");
   android_app_info->set_localized_app_name("app name");
   android_app_info->set_app_version(111);
   media_item->set_uri("http://the/uri");
 
-  mojom::AndroidAppInfoPtr actual;
+  base::Optional<AndroidAppInfo> actual;
   EXPECT_CALL(delegate(), PlayAndroidMedia)
-      .WillOnce([&](mojom::AndroidAppInfoPtr ptr) { actual = std::move(ptr); });
+      .WillOnce([&](const AndroidAppInfo& a) { actual = a; });
 
   CallFallbackMediaHandler("media.PLAY_MEDIA",
                            play_media_args.SerializeAsString());
   FlushMojomPipes();
 
-  ASSERT_FALSE(actual.is_null());
-  EXPECT_EQ(actual->package_name, "package");
-  EXPECT_EQ(actual->localized_app_name, "app name");
-  EXPECT_EQ(actual->version, 111);
-  EXPECT_EQ(actual->action, "android.intent.action.VIEW");
-  EXPECT_EQ(actual->intent, "http://the/uri");
+  ASSERT_TRUE(actual.has_value());
+  EXPECT_EQ(actual.value().package_name, "package");
+  EXPECT_EQ(actual.value().localized_app_name, "app name");
+  EXPECT_EQ(actual.value().version, 111);
+  EXPECT_EQ(actual.value().action, "android.intent.action.VIEW");
+  EXPECT_EQ(actual.value().intent, "http://the/uri");
 }
 
 TEST_F(AssistantMediaControllerTest, ShouldSupportPlayWebMedia) {
diff --git a/chromeos/services/libassistant/platform_api.cc b/chromeos/services/libassistant/platform_api.cc
index c16f6cfa..51625ca 100644
--- a/chromeos/services/libassistant/platform_api.cc
+++ b/chromeos/services/libassistant/platform_api.cc
@@ -4,10 +4,29 @@
 
 #include "chromeos/services/libassistant/platform_api.h"
 #include "base/check.h"
+#include "chromeos/services/assistant/public/cpp/features.h"
+#include "chromeos/services/libassistant/power_manager_provider_impl.h"
+#include "chromeos/services/libassistant/system_provider_impl.h"
 
 namespace chromeos {
 namespace libassistant {
 
+PlatformApi::PlatformApi() {
+  // Only enable native power features if they are supported by the UI.
+  std::unique_ptr<PowerManagerProviderImpl> provider;
+  if (assistant::features::IsPowerManagerEnabled()) {
+    provider = std::make_unique<PowerManagerProviderImpl>();
+  }
+  system_provider_ = std::make_unique<SystemProviderImpl>(std::move(provider));
+}
+
+PlatformApi::~PlatformApi() = default;
+
+void PlatformApi::Initialize(
+    chromeos::libassistant::mojom::PlatformDelegate* delegate) {
+  system_provider_->Initialize(delegate);
+}
+
 PlatformApi& PlatformApi::SetAudioInputProvider(
     assistant_client::AudioInputProvider* provider) {
   audio_input_provider_ = provider;
@@ -38,12 +57,6 @@
   return *this;
 }
 
-PlatformApi& PlatformApi::SetSystemProvider(
-    assistant_client::SystemProvider* provider) {
-  system_provider_ = provider;
-  return *this;
-}
-
 assistant_client::AudioInputProvider& PlatformApi::GetAudioInputProvider() {
   DCHECK(audio_input_provider_);
   return *audio_input_provider_;
diff --git a/chromeos/services/libassistant/platform_api.h b/chromeos/services/libassistant/platform_api.h
index 2107ff7d..86a035a 100644
--- a/chromeos/services/libassistant/platform_api.h
+++ b/chromeos/services/libassistant/platform_api.h
@@ -7,25 +7,32 @@
 
 #include "libassistant/shared/public/platform_api.h"
 
+#include <memory>
+
+#include "chromeos/services/libassistant/public/mojom/platform_delegate.mojom.h"
+
 namespace chromeos {
 namespace libassistant {
 
+class SystemProviderImpl;
+
 // Implementation of the Libassistant PlatformApi.
 // The components that haven't been migrated to this mojom service will still be
 // implemented chromeos/service/assistant/platform (and simply be exposed here).
 class PlatformApi : public assistant_client::PlatformApi {
  public:
-  PlatformApi() = default;
+  PlatformApi();
   PlatformApi(const PlatformApi&) = delete;
   PlatformApi& operator=(const PlatformApi&) = delete;
-  ~PlatformApi() override = default;
+  ~PlatformApi() override;
+
+  void Initialize(chromeos::libassistant::mojom::PlatformDelegate* delegate);
 
   PlatformApi& SetAudioInputProvider(assistant_client::AudioInputProvider*);
   PlatformApi& SetAudioOutputProvider(assistant_client::AudioOutputProvider*);
   PlatformApi& SetAuthProvider(assistant_client::AuthProvider*);
   PlatformApi& SetFileProvider(assistant_client::FileProvider*);
   PlatformApi& SetNetworkProvider(assistant_client::NetworkProvider*);
-  PlatformApi& SetSystemProvider(assistant_client::SystemProvider*);
 
   // assistant_client::PlatformApi implementation:
   assistant_client::AudioInputProvider& GetAudioInputProvider() override;
@@ -43,7 +50,8 @@
   assistant_client::AuthProvider* auth_provider_ = nullptr;
   assistant_client::FileProvider* file_provider_ = nullptr;
   assistant_client::NetworkProvider* network_provider_ = nullptr;
-  assistant_client::SystemProvider* system_provider_ = nullptr;
+
+  std::unique_ptr<SystemProviderImpl> system_provider_;
 };
 
 }  // namespace libassistant
diff --git a/chromeos/services/libassistant/power_manager_provider_impl.cc b/chromeos/services/libassistant/power_manager_provider_impl.cc
new file mode 100644
index 0000000..a0a42a9
--- /dev/null
+++ b/chromeos/services/libassistant/power_manager_provider_impl.cc
@@ -0,0 +1,202 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/services/libassistant/power_manager_provider_impl.h"
+
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/threading/platform_thread.h"
+#include "base/time/tick_clock.h"
+#include "base/time/time.h"
+#include "chromeos/services/libassistant/public/mojom/platform_delegate.mojom.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "services/device/public/mojom/wake_lock_provider.mojom.h"
+
+namespace chromeos {
+namespace libassistant {
+
+namespace {
+
+// Tag used to identify Assistant timers.
+constexpr char kTag[] = "Assistant";
+
+// Used with wake lock APIs.
+constexpr char kWakeLockReason[] = "Assistant";
+
+// Copied from Chrome's //base/time/time_now_posix.cc.
+// Returns count of |clk_id| in the form of a time delta. Returns an empty time
+// delta if |clk_id| isn't present on the system.
+base::TimeDelta ClockNow(clockid_t clk_id) {
+  struct timespec ts;
+  if (clock_gettime(clk_id, &ts) != 0) {
+    NOTREACHED() << "clock_gettime(" << clk_id << ") failed.";
+    return base::TimeDelta();
+  }
+  return base::TimeDelta::FromTimeSpec(ts);
+}
+
+}  // namespace
+
+PowerManagerProviderImpl::PowerManagerProviderImpl()
+    : main_thread_task_runner_(base::SequencedTaskRunnerHandle::Get()),
+      weak_factory_(this) {}
+
+void PowerManagerProviderImpl::Initialize(
+    chromeos::libassistant::mojom::PlatformDelegate* delegate) {
+  platform_delegate_ = delegate;
+}
+
+PowerManagerProviderImpl::~PowerManagerProviderImpl() = default;
+
+PowerManagerProviderImpl::AlarmId PowerManagerProviderImpl::AddWakeAlarm(
+    uint64_t relative_time_ms,
+    uint64_t max_delay_ms,
+    assistant_client::Callback0 callback) {
+  const AlarmId id = next_id_++;
+  DVLOG(1) << __func__ << "Add alarm ID " << id << " for "
+           << base::Time::Now() +
+                  base::TimeDelta::FromMilliseconds(relative_time_ms);
+
+  main_thread_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(&PowerManagerProviderImpl::AddWakeAlarmOnMainThread,
+                     weak_factory_.GetWeakPtr(), id,
+                     GetCurrentBootTime() +
+                         base::TimeDelta::FromMilliseconds(relative_time_ms),
+                     std::move(callback)));
+  return id;
+}
+
+void PowerManagerProviderImpl::ExpireWakeAlarmNow(AlarmId id) {
+  DVLOG(1) << __func__;
+  main_thread_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(&PowerManagerProviderImpl::OnTimerFiredOnMainThread,
+                     weak_factory_.GetWeakPtr(), id));
+}
+
+void PowerManagerProviderImpl::AcquireWakeLock() {
+  DVLOG(1) << __func__;
+  main_thread_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(&PowerManagerProviderImpl::AcquireWakeLockOnMainThread,
+                     weak_factory_.GetWeakPtr()));
+}
+
+void PowerManagerProviderImpl::ReleaseWakeLock() {
+  DVLOG(1) << __func__;
+  main_thread_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(&PowerManagerProviderImpl::ReleaseWakeLockOnMainThread,
+                     weak_factory_.GetWeakPtr()));
+}
+
+base::TimeTicks PowerManagerProviderImpl::GetCurrentBootTime() {
+  if (tick_clock_)
+    return tick_clock_->NowTicks();
+  return base::TimeTicks() + ClockNow(CLOCK_BOOTTIME);
+}
+
+void PowerManagerProviderImpl::AddWakeAlarmOnMainThread(
+    AlarmId id,
+    base::TimeTicks absolute_expiration_time,
+    assistant_client::Callback0 callback) {
+  DVLOG(1) << __func__;
+  DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+
+  auto timer = std::make_unique<NativeTimer>(kTag + base::NumberToString(id));
+  // Once the timer is created successfully, start the timer and store
+  // associated data. The stored |callback| will be called in
+  // |OnTimerFiredOnMainThread|.
+  DVLOG(1) << "Starting timer with ID " << id << " for "
+           << absolute_expiration_time;
+  timer->Start(
+      absolute_expiration_time,
+      base::BindOnce(&PowerManagerProviderImpl::OnTimerFiredOnMainThread,
+                     weak_factory_.GetWeakPtr(), id),
+      base::BindOnce(&PowerManagerProviderImpl::OnStartTimerCallback,
+                     weak_factory_.GetWeakPtr(), id));
+  timers_[id] = std::make_pair(std::move(callback), std::move(timer));
+}
+
+void PowerManagerProviderImpl::AcquireWakeLockOnMainThread() {
+  DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_GE(wake_lock_count_, 0);
+
+  wake_lock_count_++;
+  if (wake_lock_count_ > 1) {
+    DVLOG(1) << "Wake lock acquire. Count: " << wake_lock_count_;
+    return;
+  }
+
+  // Initialize |wake_lock_| if this is the first time we're using it. Assistant
+  // can acquire a wake lock even when it has nothing to show on the display,
+  // this shouldn't wake the display up. Hence, the wake lock acquired is of
+  // type kPreventAppSuspension.
+  if (!wake_lock_) {
+    mojo::Remote<device::mojom::WakeLockProvider> provider;
+    platform_delegate_->BindWakeLockProvider(
+        provider.BindNewPipeAndPassReceiver());
+    provider->GetWakeLockWithoutContext(
+        device::mojom::WakeLockType::kPreventAppSuspension,
+        device::mojom::WakeLockReason::kOther, kWakeLockReason,
+        wake_lock_.BindNewPipeAndPassReceiver());
+  }
+
+  DVLOG(1) << "Wake lock new acquire";
+  // This would violate |GetWakeLockWithoutContext|'s API contract.
+  DCHECK(wake_lock_);
+  wake_lock_->RequestWakeLock();
+}
+
+void PowerManagerProviderImpl::ReleaseWakeLockOnMainThread() {
+  DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_GE(wake_lock_count_, 0);
+
+  if (wake_lock_count_ == 0) {
+    LOG(WARNING) << "Release without acquire. Count: " << wake_lock_count_;
+    return;
+  }
+
+  wake_lock_count_--;
+  if (wake_lock_count_ >= 1) {
+    DVLOG(1) << "Wake lock release. Count: " << wake_lock_count_;
+    return;
+  }
+
+  DCHECK(wake_lock_);
+  DVLOG(1) << "Wake lock force release";
+  wake_lock_->CancelWakeLock();
+}
+
+void PowerManagerProviderImpl::OnStartTimerCallback(AlarmId id, bool result) {
+  DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+
+  if (!result) {
+    // TODO(crbug.com/919984): Notify Assistant of error so that it can do
+    // something meaningful in the UI.
+    LOG(ERROR) << "Failed to start timer on alarm ID " << id;
+    // Remove any metadata and resources associated with timers mapped to |id|.
+    DCHECK_GT(timers_.erase(id), 0UL);
+  }
+}
+
+void PowerManagerProviderImpl::OnTimerFiredOnMainThread(AlarmId id) {
+  DVLOG(1) << __func__ << " ID " << id;
+  DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+
+  auto it = timers_.find(id);
+  if (it == timers_.end()) {
+    LOG(ERROR) << "Alarm with id " << id << " not found";
+    return;
+  }
+
+  // Stop tracking the timer once it has fired.
+  CallbackAndTimer& callback_and_timer = it->second;
+  callback_and_timer.first();
+  timers_.erase(id);
+}
+
+}  // namespace libassistant
+}  // namespace chromeos
diff --git a/chromeos/services/libassistant/power_manager_provider_impl.h b/chromeos/services/libassistant/power_manager_provider_impl.h
new file mode 100644
index 0000000..0957abe
--- /dev/null
+++ b/chromeos/services/libassistant/power_manager_provider_impl.h
@@ -0,0 +1,122 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_SERVICES_LIBASSISTANT_POWER_MANAGER_PROVIDER_IMPL_H_
+#define CHROMEOS_SERVICES_LIBASSISTANT_POWER_MANAGER_PROVIDER_IMPL_H_
+
+#include <map>
+#include <memory>
+#include <utility>
+
+#include "base/component_export.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequence_checker.h"
+#include "chromeos/dbus/power/native_timer.h"
+#include "chromeos/services/libassistant/public/mojom/platform_delegate.mojom-forward.h"
+#include "libassistant/shared/public/platform_system.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "services/device/public/mojom/wake_lock.mojom.h"
+
+namespace chromeos {
+namespace libassistant {
+
+// Implementation of power management features for libassistant.
+//
+// This object lives on Assistant service's main thread i.e. on the same
+// sequence as |main_thread_task_runner_|. It is safe to assume that no lifetime
+// issues will occur if all its state is accessed from
+// |main_thread_task_runner_|. Any tasks posted on that will be invalidated if
+// this object dies.
+//
+// However, the public API of this class is called by libassistant and has no
+// guarantees on which thread it's called on. Therefore each method posts a task
+// on |main_thread_task_runner_| to mimic running the API on the same sequence
+// for thread safe access to all class members, as well as using Chrome APIs in
+// a thread safe manner.
+class COMPONENT_EXPORT(ASSISTANT_SERVICE) PowerManagerProviderImpl
+    : public assistant_client::PowerManagerProvider {
+ public:
+  PowerManagerProviderImpl();
+  ~PowerManagerProviderImpl() override;
+
+  void Initialize(chromeos::libassistant::mojom::PlatformDelegate* delegate);
+
+  // assistant_client::PowerManagerProvider overrides. These are called from
+  // libassistant threads.
+  AlarmId AddWakeAlarm(uint64_t relative_time_ms,
+                       uint64_t max_delay_ms,
+                       assistant_client::Callback0 callback) override;
+  void ExpireWakeAlarmNow(AlarmId alarm_id) override;
+  void AcquireWakeLock() override;
+  void ReleaseWakeLock() override;
+
+  void set_tick_clock_for_testing(const base::TickClock* tick_clock) {
+    DCHECK(tick_clock);
+    tick_clock_ = tick_clock;
+  }
+
+ private:
+  using CallbackAndTimer =
+      std::pair<assistant_client::Callback0, std::unique_ptr<NativeTimer>>;
+
+  // Returns time ticks from boot including time ticks during sleeping.
+  base::TimeTicks GetCurrentBootTime();
+
+  // Creates a native timer by calling |NativeTimer::Create|. Runs on
+  // |main_thread_task_runner_|.
+  void AddWakeAlarmOnMainThread(AlarmId id,
+                                base::TimeTicks absolute_expiration_time,
+                                assistant_client::Callback0 callback);
+
+  // Creates (if not created) and acquires |wake_lock_|.
+  // Runs on |main_thread_task_runner_|.
+  void AcquireWakeLockOnMainThread();
+
+  // Releases |wake_lock_|. Runs on |main_thread_task_runner_|.
+  void ReleaseWakeLockOnMainThread();
+
+  // Callback for a start operation on a |NativeTimer|.
+  void OnStartTimerCallback(AlarmId id, bool result);
+
+  // Callback for timer with id |id| added via |AddWakeAlarm|. It calls the
+  // corresponding client callback associated with the alarm. Removes the entry
+  // for |id| from |timers_|.
+  void OnTimerFiredOnMainThread(AlarmId id);
+
+  // Store of currently active alarm ids returned to clients and the
+  // corresponding pair of timer objects and client callbacks.
+  std::map<AlarmId, CallbackAndTimer> timers_;
+
+  // Monotonically increasing id used as key in |timers_| and assigned to timers
+  // in |AddWakeAlarm|. This is the only member that is accessed from
+  // libassistant threads only and not from |main_thread_task_runner_|.
+  AlarmId next_id_ = 1;
+
+  // Lazily initialized in response to the first call to |AcquireWakeLock|.
+  mojo::Remote<device::mojom::WakeLock> wake_lock_;
+
+  // Current number of clients that requested |wake_lock_|. On zero |wake_lock_|
+  // is released.
+  int wake_lock_count_ = 0;
+
+  // Used to post tasks from a libassistant thread on to the main thread in
+  // order to use Chrome APIs safely.
+  const scoped_refptr<base::SequencedTaskRunner> main_thread_task_runner_;
+
+  // Owned by |PlatformApi|. Used to initialize |wake_lock_|.
+  chromeos::libassistant::mojom::PlatformDelegate* platform_delegate_ = nullptr;
+
+  // Clock to use to calculate time ticks. Set and used only for testing.
+  const base::TickClock* tick_clock_ = nullptr;
+
+  base::WeakPtrFactory<PowerManagerProviderImpl> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(PowerManagerProviderImpl);
+};
+
+}  // namespace libassistant
+}  // namespace chromeos
+
+#endif  // CHROMEOS_SERVICES_LIBASSISTANT_POWER_MANAGER_PROVIDER_IMPL_H_
diff --git a/chromeos/services/libassistant/power_manager_provider_impl_unittest.cc b/chromeos/services/libassistant/power_manager_provider_impl_unittest.cc
new file mode 100644
index 0000000..4b56fdb
--- /dev/null
+++ b/chromeos/services/libassistant/power_manager_provider_impl_unittest.cc
@@ -0,0 +1,167 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/services/libassistant/power_manager_provider_impl.h"
+
+#include "base/run_loop.h"
+#include "base/test/task_environment.h"
+#include "chromeos/dbus/power/fake_power_manager_client.h"
+#include "chromeos/services/assistant/public/cpp/migration/fake_platform_delegate.h"
+#include "services/device/public/cpp/test/test_wake_lock_provider.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace libassistant {
+
+namespace {
+
+// Constants to be used with the |AddWakeAlarm| API.
+const uint64_t kAlarmRelativeTimeMs = 1000;
+const uint64_t kAlarmMaxDelayMs = 0;
+
+class FakePlatformDelegateImpl : public assistant::FakePlatformDelegate {
+ public:
+  explicit FakePlatformDelegateImpl(
+      device::TestWakeLockProvider* wake_lock_provider)
+      : wake_lock_provider_(wake_lock_provider) {}
+
+  // FakePlatformDelegate implementation:
+  void BindWakeLockProvider(
+      mojo::PendingReceiver<::device::mojom::WakeLockProvider> receiver)
+      override {
+    wake_lock_provider_->BindReceiver(std::move(receiver));
+  }
+
+ private:
+  device::TestWakeLockProvider* const wake_lock_provider_;
+};
+
+}  // namespace
+
+class AssistantPowerManagerProviderImplTest : public testing::Test {
+ public:
+  AssistantPowerManagerProviderImplTest()
+      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO,
+                          base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
+  ~AssistantPowerManagerProviderImplTest() override = default;
+
+  void SetUp() override {
+    chromeos::PowerManagerClient::InitializeFake();
+    FakePowerManagerClient::Get()->set_tick_clock(
+        task_environment_.GetMockTickClock());
+    power_manager_provider_impl_ = std::make_unique<PowerManagerProviderImpl>();
+    power_manager_provider_impl_->set_tick_clock_for_testing(
+        task_environment_.GetMockTickClock());
+
+    power_manager_provider_impl_->Initialize(&platform_delegate_);
+  }
+
+  void TearDown() override {
+    power_manager_provider_impl_.reset();
+    chromeos::PowerManagerClient::Shutdown();
+  }
+
+ protected:
+  PowerManagerProviderImpl* GetPowerManagerProviderImpl() {
+    return power_manager_provider_impl_.get();
+  }
+
+  // Calls the acquire wake lock API and ensures that the request has reached
+  // the wake lock provider.
+  void AcquireWakeLock() {
+    power_manager_provider_impl_->AcquireWakeLock();
+    base::RunLoop run_loop;
+    run_loop.RunUntilIdle();
+  }
+
+  // Calls the release wake lock API and ensures that the request has reached
+  // the wake lock provider.
+  void ReleaseWakeLock() {
+    power_manager_provider_impl_->ReleaseWakeLock();
+    base::RunLoop run_loop;
+    run_loop.RunUntilIdle();
+  }
+
+  // Returns the number of active wake locks of type |type|.
+  int GetActiveWakeLocks(device::mojom::WakeLockType type) {
+    base::RunLoop run_loop;
+    int result_count = 0;
+    wake_lock_provider_.GetActiveWakeLocksForTests(
+        type,
+        base::BindOnce(
+            [](base::RunLoop* run_loop, int* result_count, int32_t count) {
+              *result_count = count;
+              run_loop->Quit();
+            },
+            &run_loop, &result_count));
+    run_loop.Run();
+    return result_count;
+  }
+
+  // Returns true iff adding a wake alarm via |AddWakeAlarm| returns a > 0
+  // result and the alarm expiration callback fires.
+  bool CheckAddWakeAlarmAndExpiration(uint64_t relative_time_ms,
+                                      uint64_t max_delay_ms) {
+    // Schedule wake alarm and check if valid id is returned and timer callback
+    // is fired.
+    bool result = false;
+    assistant_client::Callback0 wake_alarm_expiration_cb(
+        [&result]() { result = true; });
+    assistant_client::PowerManagerProvider::AlarmId id =
+        power_manager_provider_impl_->AddWakeAlarm(
+            relative_time_ms, max_delay_ms,
+            std::move(wake_alarm_expiration_cb));
+    task_environment_.FastForwardBy(
+        base::TimeDelta::FromMilliseconds(relative_time_ms));
+
+    if (id <= 0UL)
+      return false;
+    return result;
+  }
+
+ private:
+  // Needs to be of type |MainThreadType::IO| to use |NativeTimer|.
+  base::test::TaskEnvironment task_environment_;
+
+  device::TestWakeLockProvider wake_lock_provider_;
+  FakePlatformDelegateImpl platform_delegate_{&wake_lock_provider_};
+
+  std::unique_ptr<PowerManagerProviderImpl> power_manager_provider_impl_;
+
+  DISALLOW_COPY_AND_ASSIGN(AssistantPowerManagerProviderImplTest);
+};
+
+TEST_F(AssistantPowerManagerProviderImplTest, CheckAcquireAndReleaseWakeLock) {
+  // Acquire wake lock and check wake lock count.
+  AcquireWakeLock();
+  EXPECT_EQ(1, GetActiveWakeLocks(
+                   device::mojom::WakeLockType::kPreventAppSuspension));
+  // Acquire another wake lock, this shouldn't change the overall count.
+  AcquireWakeLock();
+  EXPECT_EQ(1, GetActiveWakeLocks(
+                   device::mojom::WakeLockType::kPreventAppSuspension));
+  // Release wake lock, this shouldn't change the overall count.
+  ReleaseWakeLock();
+  EXPECT_EQ(1, GetActiveWakeLocks(
+                   device::mojom::WakeLockType::kPreventAppSuspension));
+  // Release wake lock, this should finally release the wake lock.
+  ReleaseWakeLock();
+  EXPECT_EQ(0, GetActiveWakeLocks(
+                   device::mojom::WakeLockType::kPreventAppSuspension));
+  // An unbalanced release call shouldn't do anything.
+  ReleaseWakeLock();
+  EXPECT_EQ(0, GetActiveWakeLocks(
+                   device::mojom::WakeLockType::kPreventAppSuspension));
+}
+
+TEST_F(AssistantPowerManagerProviderImplTest, CheckWakeAlarms) {
+  // Check consecutive wake alarms addition and expiration.
+  EXPECT_TRUE(
+      CheckAddWakeAlarmAndExpiration(kAlarmRelativeTimeMs, kAlarmMaxDelayMs));
+  EXPECT_TRUE(
+      CheckAddWakeAlarmAndExpiration(kAlarmRelativeTimeMs, kAlarmMaxDelayMs));
+}
+
+}  // namespace libassistant
+}  // namespace chromeos
diff --git a/chromeos/services/libassistant/public/mojom/BUILD.gn b/chromeos/services/libassistant/public/mojom/BUILD.gn
index 86915574..eaff391 100644
--- a/chromeos/services/libassistant/public/mojom/BUILD.gn
+++ b/chromeos/services/libassistant/public/mojom/BUILD.gn
@@ -27,4 +27,23 @@
     "//services/device/public/mojom",
     "//services/network/public/mojom",
   ]
+
+  cpp_typemaps = [
+    {
+      types = [
+        {
+          mojom = "chromeos.libassistant.mojom.AndroidAppInfo"
+          cpp = "::chromeos::assistant::AndroidAppInfo"
+        },
+        {
+          mojom = "chromeos.libassistant.mojom.AndroidAppStatus"
+          cpp = "::chromeos::assistant::AppStatus"
+        },
+      ]
+
+      traits_headers = [ "mojom_traits.h" ]
+      traits_sources = [ "mojom_traits.cc" ]
+      traits_public_deps = [ "//chromeos/services/assistant/public/shared" ]
+    },
+  ]
 }
diff --git a/chromeos/services/libassistant/public/mojom/mojom_traits.cc b/chromeos/services/libassistant/public/mojom/mojom_traits.cc
new file mode 100644
index 0000000..1e11da4
--- /dev/null
+++ b/chromeos/services/libassistant/public/mojom/mojom_traits.cc
@@ -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.
+
+#include "chromeos/services/libassistant/public/mojom/mojom_traits.h"
+
+namespace mojo {
+
+using AppStatus = chromeos::assistant::AppStatus;
+using AndroidAppStatus = chromeos::libassistant::mojom::AndroidAppStatus;
+using chromeos::assistant::AndroidAppInfo;
+using chromeos::libassistant::mojom::AndroidAppInfoDataView;
+
+AndroidAppStatus EnumTraits<AndroidAppStatus, AppStatus>::ToMojom(
+    AppStatus input) {
+  switch (input) {
+    case AppStatus::kUnknown:
+      return AndroidAppStatus::kUnknown;
+    case AppStatus::kAvailable:
+      return AndroidAppStatus::kAvailable;
+    case AppStatus::kUnavailable:
+      return AndroidAppStatus::kUnavailable;
+    case AppStatus::kVersionMismatch:
+      return AndroidAppStatus::kVersionMismatch;
+    case AppStatus::kDisabled:
+      return AndroidAppStatus::kDisabled;
+  }
+}
+
+bool EnumTraits<AndroidAppStatus, AppStatus>::FromMojom(AndroidAppStatus input,
+                                                        AppStatus* output) {
+  switch (input) {
+    case AndroidAppStatus::kUnknown:
+      *output = AppStatus::kUnknown;
+      break;
+    case AndroidAppStatus::kAvailable:
+      *output = AppStatus::kAvailable;
+      break;
+    case AndroidAppStatus::kUnavailable:
+      *output = AppStatus::kUnavailable;
+      break;
+    case AndroidAppStatus::kVersionMismatch:
+      *output = AppStatus::kVersionMismatch;
+      break;
+    case AndroidAppStatus::kDisabled:
+      *output = AppStatus::kDisabled;
+      break;
+  }
+  return true;
+}
+
+std::string StructTraits<AndroidAppInfoDataView, AndroidAppInfo>::package_name(
+    const AndroidAppInfo& input) {
+  return input.package_name;
+}
+
+int64_t StructTraits<AndroidAppInfoDataView, AndroidAppInfo>::version(
+    const AndroidAppInfo& input) {
+  return input.version;
+}
+
+std::string
+StructTraits<AndroidAppInfoDataView, AndroidAppInfo>::localized_app_name(
+    const AndroidAppInfo& input) {
+  return input.localized_app_name;
+}
+
+std::string StructTraits<AndroidAppInfoDataView, AndroidAppInfo>::intent(
+    const AndroidAppInfo& input) {
+  return input.intent;
+}
+
+chromeos::assistant::AppStatus
+StructTraits<AndroidAppInfoDataView, AndroidAppInfo>::status(
+    const AndroidAppInfo& input) {
+  return input.status;
+}
+
+std::string StructTraits<AndroidAppInfoDataView, AndroidAppInfo>::action(
+    const AndroidAppInfo& input) {
+  return input.action;
+}
+
+bool StructTraits<AndroidAppInfoDataView, AndroidAppInfo>::Read(
+    chromeos::libassistant::mojom::AndroidAppInfoDataView data,
+    AndroidAppInfo* output) {
+  if (!data.ReadPackageName(&output->package_name))
+    return false;
+  output->version = data.version();
+  if (!data.ReadLocalizedAppName(&output->localized_app_name))
+    return false;
+  if (!data.ReadIntent(&output->intent))
+    return false;
+  if (!data.ReadStatus(&output->status))
+    return false;
+  if (!data.ReadAction(&output->action))
+    return false;
+  return true;
+}
+
+}  // namespace mojo
diff --git a/chromeos/services/libassistant/public/mojom/mojom_traits.h b/chromeos/services/libassistant/public/mojom/mojom_traits.h
new file mode 100644
index 0000000..d544d726
--- /dev/null
+++ b/chromeos/services/libassistant/public/mojom/mojom_traits.h
@@ -0,0 +1,40 @@
+// 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_SERVICES_LIBASSISTANT_PUBLIC_MOJOM_MOJOM_TRAITS_H_
+#define CHROMEOS_SERVICES_LIBASSISTANT_PUBLIC_MOJOM_MOJOM_TRAITS_H_
+
+#include "chromeos/services/assistant/public/shared/utils.h"
+#include "chromeos/services/libassistant/public/mojom/android_app_info.mojom.h"
+
+namespace mojo {
+
+template <>
+struct StructTraits<chromeos::libassistant::mojom::AndroidAppInfoDataView,
+                    chromeos::assistant::AndroidAppInfo> {
+  using AndroidAppInfo = chromeos::assistant::AndroidAppInfo;
+
+  static std::string package_name(const AndroidAppInfo& input);
+  static int64_t version(const AndroidAppInfo& input);
+  static std::string localized_app_name(const AndroidAppInfo& input);
+  static std::string intent(const AndroidAppInfo& input);
+  static chromeos::assistant::AppStatus status(const AndroidAppInfo& input);
+  static std::string action(const AndroidAppInfo& input);
+
+  static bool Read(chromeos::libassistant::mojom::AndroidAppInfoDataView data,
+                   AndroidAppInfo* output);
+};
+template <>
+struct EnumTraits<chromeos::libassistant::mojom::AndroidAppStatus,
+                  chromeos::assistant::AppStatus> {
+  using AppStatus = ::chromeos::assistant::AppStatus;
+  using AndroidAppStatus = ::chromeos::libassistant::mojom::AndroidAppStatus;
+
+  static AndroidAppStatus ToMojom(AppStatus input);
+  static bool FromMojom(AndroidAppStatus input, AppStatus* output);
+};
+
+}  // namespace mojo
+
+#endif  // CHROMEOS_SERVICES_LIBASSISTANT_PUBLIC_MOJOM_MOJOM_TRAITS_H_
diff --git a/chromeos/services/libassistant/system_provider_impl.cc b/chromeos/services/libassistant/system_provider_impl.cc
new file mode 100644
index 0000000..62512a6
--- /dev/null
+++ b/chromeos/services/libassistant/system_provider_impl.cc
@@ -0,0 +1,78 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/services/libassistant/system_provider_impl.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/system/sys_info.h"
+#include "chromeos/services/libassistant/power_manager_provider_impl.h"
+
+namespace chromeos {
+namespace libassistant {
+
+SystemProviderImpl::SystemProviderImpl(
+    std::unique_ptr<PowerManagerProviderImpl> power_manager_provider)
+    : power_manager_provider_(std::move(power_manager_provider)) {}
+
+SystemProviderImpl::~SystemProviderImpl() = default;
+
+void SystemProviderImpl::Initialize(
+    chromeos::libassistant::mojom::PlatformDelegate* platform_delegate) {
+  if (power_manager_provider_)
+    power_manager_provider_->Initialize(platform_delegate);
+
+  platform_delegate->BindBatteryMonitor(
+      battery_monitor_.BindNewPipeAndPassReceiver());
+  battery_monitor_->QueryNextStatus(base::BindOnce(
+      &SystemProviderImpl::OnBatteryStatus, base::Unretained(this)));
+}
+
+assistant_client::MicMuteState SystemProviderImpl::GetMicMuteState() {
+  // CRAS input is never muted.
+  return assistant_client::MicMuteState::MICROPHONE_ENABLED;
+}
+
+void SystemProviderImpl::RegisterMicMuteChangeCallback(
+    ConfigChangeCallback callback) {
+  // No need to register since it will never change.
+}
+
+assistant_client::PowerManagerProvider*
+SystemProviderImpl::GetPowerManagerProvider() {
+  return power_manager_provider_.get();
+}
+
+bool SystemProviderImpl::GetBatteryState(BatteryState* state) {
+  if (!current_battery_status_)
+    return false;
+
+  state->is_charging = current_battery_status_->charging;
+  state->charge_percentage =
+      static_cast<int>(current_battery_status_->level * 100);
+  return true;
+}
+
+void SystemProviderImpl::UpdateTimezoneAndLocale(const std::string& timezone,
+                                                 const std::string& locale) {}
+
+void SystemProviderImpl::OnBatteryStatus(
+    device::mojom::BatteryStatusPtr battery_status) {
+  current_battery_status_ = std::move(battery_status);
+
+  // Battery monitor is one shot, send another query to get battery status
+  // updates. This query will only return when a status changes.
+  battery_monitor_->QueryNextStatus(base::BindOnce(
+      &SystemProviderImpl::OnBatteryStatus, base::Unretained(this)));
+}
+
+void SystemProviderImpl::FlushForTesting() {
+  battery_monitor_.FlushForTesting();  // IN-TEST
+}
+
+}  // namespace libassistant
+}  // namespace chromeos
diff --git a/chromeos/services/libassistant/system_provider_impl.h b/chromeos/services/libassistant/system_provider_impl.h
new file mode 100644
index 0000000..b5bb821
--- /dev/null
+++ b/chromeos/services/libassistant/system_provider_impl.h
@@ -0,0 +1,61 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_SERVICES_LIBASSISTANT_SYSTEM_PROVIDER_IMPL_H_
+#define CHROMEOS_SERVICES_LIBASSISTANT_SYSTEM_PROVIDER_IMPL_H_
+
+#include <memory>
+#include <string>
+
+#include "base/component_export.h"
+#include "base/macros.h"
+#include "chromeos/services/libassistant/public/mojom/platform_delegate.mojom.h"
+#include "libassistant/shared/public/platform_system.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "services/device/public/mojom/battery_monitor.mojom.h"
+#include "services/device/public/mojom/battery_status.mojom.h"
+
+namespace chromeos {
+namespace libassistant {
+
+class PowerManagerProviderImpl;
+
+class SystemProviderImpl : public assistant_client::SystemProvider {
+ public:
+  // Acceptable to pass in |nullptr| for |power_manager_provider| when no
+  // platform power manager provider is available.
+  explicit SystemProviderImpl(
+      std::unique_ptr<PowerManagerProviderImpl> power_manager_provider);
+  ~SystemProviderImpl() override;
+
+  void Initialize(
+      chromeos::libassistant::mojom::PlatformDelegate* platform_delegate);
+
+  // assistant_client::SystemProvider implementation:
+  assistant_client::MicMuteState GetMicMuteState() override;
+  void RegisterMicMuteChangeCallback(ConfigChangeCallback callback) override;
+  assistant_client::PowerManagerProvider* GetPowerManagerProvider() override;
+  bool GetBatteryState(BatteryState* state) override;
+  void UpdateTimezoneAndLocale(const std::string& timezone,
+                               const std::string& locale) override;
+
+ private:
+  friend class AssistantSystemProviderImplTest;
+  void OnBatteryStatus(device::mojom::BatteryStatusPtr battery_status);
+
+  void FlushForTesting();
+
+  std::unique_ptr<PowerManagerProviderImpl> power_manager_provider_;
+
+  mojo::Remote<device::mojom::BatteryMonitor> battery_monitor_;
+  device::mojom::BatteryStatusPtr current_battery_status_;
+
+  DISALLOW_COPY_AND_ASSIGN(SystemProviderImpl);
+};
+
+}  // namespace libassistant
+}  // namespace chromeos
+
+#endif  // CHROMEOS_SERVICES_LIBASSISTANT_SYSTEM_PROVIDER_IMPL_H_
diff --git a/chromeos/services/libassistant/system_provider_impl_unittest.cc b/chromeos/services/libassistant/system_provider_impl_unittest.cc
new file mode 100644
index 0000000..9a84d195
--- /dev/null
+++ b/chromeos/services/libassistant/system_provider_impl_unittest.cc
@@ -0,0 +1,107 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/services/libassistant/system_provider_impl.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/test/task_environment.h"
+#include "chromeos/services/assistant/public/cpp/migration/fake_platform_delegate.h"
+#include "chromeos/services/libassistant/power_manager_provider_impl.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "services/device/public/mojom/battery_monitor.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace libassistant {
+
+class FakeBatteryMonitor : device::mojom::BatteryMonitor {
+ public:
+  FakeBatteryMonitor() = default;
+
+  void Bind(
+      mojo::PendingReceiver<::device::mojom::BatteryMonitor> pending_receiver) {
+    receiver_.Bind(std::move(pending_receiver));
+  }
+
+  void QueryNextStatus(QueryNextStatusCallback callback) override {
+    if (has_status) {
+      std::move(callback).Run(std::move(battery_status_));
+      has_status = false;
+    } else {
+      callback_ = std::move(callback);
+    }
+  }
+
+  void SetStatus(device::mojom::BatteryStatusPtr battery_status) {
+    battery_status_ = std::move(battery_status);
+    has_status = true;
+
+    if (callback_) {
+      std::move(callback_).Run(std::move(battery_status_));
+      has_status = false;
+    }
+  }
+
+ private:
+  bool has_status = false;
+
+  device::mojom::BatteryStatusPtr battery_status_;
+  QueryNextStatusCallback callback_;
+
+  mojo::Receiver<device::mojom::BatteryMonitor> receiver_{this};
+
+  DISALLOW_COPY_AND_ASSIGN(FakeBatteryMonitor);
+};
+
+class AssistantSystemProviderImplTest : public testing::Test {
+ public:
+  AssistantSystemProviderImplTest()
+      : task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {
+    battery_monitor_.SetStatus(device::mojom::BatteryStatus::New(
+        false /* charging */, 0 /* charging_time */, 0 /* discharging_time */,
+        0 /* level */));
+
+    system_provider_impl_ = std::make_unique<SystemProviderImpl>(
+        std::make_unique<PowerManagerProviderImpl>());
+    system_provider_impl_->Initialize(&platform_delegate_);
+    battery_monitor_.Bind(platform_delegate_.battery_monitor_receiver());
+    FlushForTesting();
+  }
+
+  SystemProviderImpl* system_provider() { return system_provider_impl_.get(); }
+
+  FakeBatteryMonitor* battery_monitor() { return &battery_monitor_; }
+
+  void FlushForTesting() { system_provider_impl_->FlushForTesting(); }
+
+ private:
+  base::test::TaskEnvironment task_environment_;
+  FakeBatteryMonitor battery_monitor_;
+  assistant::FakePlatformDelegate platform_delegate_;
+  std::unique_ptr<SystemProviderImpl> system_provider_impl_;
+
+  DISALLOW_COPY_AND_ASSIGN(AssistantSystemProviderImplTest);
+};
+
+TEST_F(AssistantSystemProviderImplTest, GetBatteryStateReturnsLastState) {
+  SystemProviderImpl::BatteryState state;
+  // Initial level is 0
+  system_provider()->GetBatteryState(&state);
+  FlushForTesting();
+
+  EXPECT_EQ(state.charge_percentage, 0);
+  battery_monitor()->SetStatus(device::mojom::BatteryStatus::New(
+      false /* charging */, 0 /* charging_time */, 0 /* discharging_time */,
+      1 /* level */));
+
+  FlushForTesting();
+  // New level after status change
+  system_provider()->GetBatteryState(&state);
+  EXPECT_EQ(state.charge_percentage, 100);
+}
+
+}  // namespace libassistant
+}  // namespace chromeos
diff --git a/chromeos/services/libassistant/util.cc b/chromeos/services/libassistant/util.cc
index af0f8c96..c8b43d847 100644
--- a/chromeos/services/libassistant/util.cc
+++ b/chromeos/services/libassistant/util.cc
@@ -31,6 +31,8 @@
 
 namespace {
 
+using AppStatus = ::chromeos::assistant::AppStatus;
+
 void CreateUserAgent(std::string* user_agent) {
   DCHECK(user_agent->empty());
   base::StringAppendF(user_agent,
@@ -56,17 +58,17 @@
 }
 
 ProviderVerificationResult::VerificationStatus GetProviderVerificationStatus(
-    libassistant::mojom::AndroidAppStatus status) {
+    AppStatus status) {
   switch (status) {
-    case libassistant::mojom::AndroidAppStatus::kUnknown:
+    case AppStatus::kUnknown:
       return ProviderVerificationResult::UNKNOWN;
-    case libassistant::mojom::AndroidAppStatus::kAvailable:
+    case AppStatus::kAvailable:
       return ProviderVerificationResult::AVAILABLE;
-    case libassistant::mojom::AndroidAppStatus::kUnavailable:
+    case AppStatus::kUnavailable:
       return ProviderVerificationResult::UNAVAILABLE;
-    case libassistant::mojom::AndroidAppStatus::kVersionMismatch:
+    case AppStatus::kVersionMismatch:
       return ProviderVerificationResult::VERSION_MISMATCH;
-    case libassistant::mojom::AndroidAppStatus::kDisabled:
+    case AppStatus::kDisabled:
       return ProviderVerificationResult::DISABLED;
   }
 }
@@ -278,8 +280,7 @@
     app_info->set_localized_app_name(android_app_info->localized_app_name);
     app_info->set_android_intent(android_app_info->intent);
 
-    if (android_app_info->status ==
-        libassistant::mojom::AndroidAppStatus::kAvailable)
+    if (android_app_info->status == AppStatus::kAvailable)
       any_provider_available = true;
   }
 
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc
index 2f1e3b8..f3fa8597 100644
--- a/components/autofill_assistant/browser/controller.cc
+++ b/components/autofill_assistant/browser/controller.cc
@@ -1231,9 +1231,8 @@
   const base::Optional<std::string> password_change_username =
       trigger_context_->GetPasswordChangeUsername();
   if (password_change_username) {
-    DCHECK(
-        GetCurrentURL().is_valid());  // At least |deeplink_url_| must be set.
-    user_data_->selected_login_.emplace(GetCurrentURL().GetOrigin(),
+    DCHECK(GetDeeplinkURL().is_valid());  // |deeplink_url_| must be set.
+    user_data_->selected_login_.emplace(GetDeeplinkURL().GetOrigin(),
                                         *password_change_username);
   }
 
diff --git a/components/autofill_assistant/browser/controller_unittest.cc b/components/autofill_assistant/browser/controller_unittest.cc
index 9646957..57802f46 100644
--- a/components/autofill_assistant/browser/controller_unittest.cc
+++ b/components/autofill_assistant/browser/controller_unittest.cc
@@ -2706,7 +2706,11 @@
 
   EXPECT_TRUE(
       controller_->Start(initialUrl, TriggerContext::Create(parameters, "")));
+  // Initial navigation.
+  SimulateNavigateToUrl(GURL("http://b.example.com"));
   EXPECT_EQ(GetUserData()->selected_login_->username, username);
+  EXPECT_EQ(GetUserData()->selected_login_->origin, initialUrl.GetOrigin());
+  EXPECT_EQ(controller_->GetCurrentURL().host(), "b.example.com");
 }
 
 TEST_F(ControllerTest, EndPromptWithOnEndNavigation) {
diff --git a/components/breadcrumbs/core/breadcrumb_manager.cc b/components/breadcrumbs/core/breadcrumb_manager.cc
index f43f1d5..6a6f7ea 100644
--- a/components/breadcrumbs/core/breadcrumb_manager.cc
+++ b/components/breadcrumbs/core/breadcrumb_manager.cc
@@ -5,7 +5,6 @@
 #include "components/breadcrumbs/core/breadcrumb_manager.h"
 
 #include "base/strings/stringprintf.h"
-#include "base/time/time.h"
 #include "components/breadcrumbs/core/breadcrumb_manager_observer.h"
 #include "components/breadcrumbs/core/crash_reporter_breadcrumb_constants.h"
 
diff --git a/components/breadcrumbs/core/breadcrumb_manager.h b/components/breadcrumbs/core/breadcrumb_manager.h
index 810296b..22bec331 100644
--- a/components/breadcrumbs/core/breadcrumb_manager.h
+++ b/components/breadcrumbs/core/breadcrumb_manager.h
@@ -6,8 +6,8 @@
 #define COMPONENTS_BREADCRUMBS_CORE_BREADCRUMB_MANAGER_H_
 
 #include <list>
-#include <memory>
 #include <string>
+#include <utility>
 
 #include "base/observer_list.h"
 #include "base/time/time.h"
@@ -23,6 +23,11 @@
 // stale data.
 class BreadcrumbManager {
  public:
+  BreadcrumbManager();
+  BreadcrumbManager(const BreadcrumbManager&) = delete;
+  BreadcrumbManager& operator=(const BreadcrumbManager&) = delete;
+  ~BreadcrumbManager();
+
   // Returns the number of collected breadcrumb events which are still relevant.
   // Note: This method may drop old events so the value can change even when no
   // new events have been added, but time has passed.
@@ -45,13 +50,7 @@
   void AddObserver(BreadcrumbManagerObserver* observer);
   void RemoveObserver(BreadcrumbManagerObserver* observer);
 
-  BreadcrumbManager();
-  ~BreadcrumbManager();
-
  private:
-  BreadcrumbManager(const BreadcrumbManager&) = delete;
-  BreadcrumbManager& operator=(const BreadcrumbManager&) = delete;
-
   // Drops events which are considered stale. Note that stale events are not
   // guaranteed to be removed. Explicitly, stale events will be retained while
   // newer events are limited.
diff --git a/components/embedder_support/android/metrics/BUILD.gn b/components/embedder_support/android/metrics/BUILD.gn
index 387ffd0d..92002b5 100644
--- a/components/embedder_support/android/metrics/BUILD.gn
+++ b/components/embedder_support/android/metrics/BUILD.gn
@@ -42,8 +42,6 @@
   deps = [
     "//base:base_java",
     "//base:jni_java",
-    "//third_party/android_deps:protobuf_lite_runtime_java",
-    "//third_party/metrics_proto:metrics_proto_java",
   ]
   annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
 }
diff --git a/components/embedder_support/android/metrics/DEPS b/components/embedder_support/android/metrics/DEPS
index a2b32b9..c96cb27 100644
--- a/components/embedder_support/android/metrics/DEPS
+++ b/components/embedder_support/android/metrics/DEPS
@@ -7,5 +7,4 @@
   "+content/public/test",
   "+services/network/public/cpp",
   "+services/resource_coordinator/public/cpp/memory_instrumentation",
-  "+third_party/metrics_proto",
 ]
diff --git a/components/embedder_support/android/metrics/java/src/org/chromium/components/metrics/AndroidMetricsLogUploader.java b/components/embedder_support/android/metrics/java/src/org/chromium/components/metrics/AndroidMetricsLogUploader.java
index 351c8be..58f9a2e5 100644
--- a/components/embedder_support/android/metrics/java/src/org/chromium/components/metrics/AndroidMetricsLogUploader.java
+++ b/components/embedder_support/android/metrics/java/src/org/chromium/components/metrics/AndroidMetricsLogUploader.java
@@ -4,12 +4,9 @@
 
 package org.chromium.components.metrics;
 
-import com.google.protobuf.InvalidProtocolBufferException;
-
 import org.chromium.base.Consumer;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
-import org.chromium.components.metrics.ChromeUserMetricsExtensionProtos.ChromeUserMetricsExtension;
 
 /**
  * Passes UMA logs from native to a java uploader.
@@ -29,19 +26,9 @@
     }
 
     @CalledByNative
-    public static void uploadLog(byte[] data) throws InvalidProtocolBufferException {
+    public static void uploadLog(byte[] data) {
         final Consumer<byte[]> uploader = sUploader;
         if (uploader != null) {
-            // Speculative validity checks to see why WebView UMA (and probably other embedders of
-            // this component) are missing system_profiles for a small fraction of records.
-            // TODO(https://crbug.com/1081925): remove entirely when we figure out the issue.
-            if (data.length == 0) {
-                throw new RuntimeException("UMA log is completely empty");
-            }
-            ChromeUserMetricsExtension log = ChromeUserMetricsExtension.parseFrom(data);
-            if (!log.hasSystemProfile()) {
-                throw new RuntimeException("UMA log is missing a system_profile");
-            }
             uploader.accept(data);
         }
     }
diff --git a/components/feed/BUILD.gn b/components/feed/BUILD.gn
index 827a98b..9a08ab0 100644
--- a/components/feed/BUILD.gn
+++ b/components/feed/BUILD.gn
@@ -10,10 +10,7 @@
 # any of the feed targets.
 buildflag_header("buildflags") {
   header = "buildflags.h"
-  flags = [
-    "ENABLE_FEED_V1=$enable_feed_v1",
-    "ENABLE_FEED_V2=$enable_feed_v2",
-  ]
+  flags = [ "ENABLE_FEED_V2=$enable_feed_v2" ]
 }
 
 static_library("feature_list") {
@@ -30,13 +27,5 @@
 
 source_set("unit_tests") {
   testonly = true
-  deps = [
-    "core:core_unit_tests",
-    "core/v2:core_unit_tests",
-    "//components/feed/core/common:core_common_unit_tests",
-  ]
-
-  if (!is_ios) {
-    deps += [ "content:content_unit_tests" ]
-  }
+  deps = [ "core/v2:core_unit_tests" ]
 }
diff --git a/components/feed/content/BUILD.gn b/components/feed/content/BUILD.gn
deleted file mode 100644
index 2c66bca0..0000000
--- a/components/feed/content/BUILD.gn
+++ /dev/null
@@ -1,43 +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.
-
-if (is_android) {
-  import("//build/config/android/rules.gni")
-}
-
-source_set("feed_content") {
-  sources = [
-    "feed_host_service.cc",
-    "feed_host_service.h",
-    "feed_offline_host.cc",
-    "feed_offline_host.h",
-  ]
-
-  public_deps = [
-    "//base",
-    "//components/feed/core:feed_core",
-    "//components/keyed_service/core",
-  ]
-
-  deps = [
-    "//components/offline_pages/core",
-    "//components/offline_pages/core/prefetch",
-  ]
-}
-
-source_set("content_unit_tests") {
-  testonly = true
-  sources = [ "feed_offline_host_unittest.cc" ]
-
-  deps = [
-    ":feed_content",
-    "//base",
-    "//base/test:test_support",
-    "//components/offline_pages/core",
-    "//components/offline_pages/core:test_support",
-    "//components/offline_pages/core/prefetch:test_support",
-    "//testing/gmock",
-    "//testing/gtest",
-  ]
-}
diff --git a/components/feed/content/feed_host_service.cc b/components/feed/content/feed_host_service.cc
deleted file mode 100644
index 91ee794..0000000
--- a/components/feed/content/feed_host_service.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/content/feed_host_service.h"
-
-#include <utility>
-
-namespace feed {
-
-FeedHostService::FeedHostService(
-    std::unique_ptr<FeedLoggingMetrics> logging_metrics,
-    std::unique_ptr<FeedNetworkingHost> networking_host,
-    std::unique_ptr<FeedSchedulerHost> scheduler_host,
-    std::unique_ptr<FeedContentDatabase> content_database,
-    std::unique_ptr<FeedJournalDatabase> journal_database,
-    std::unique_ptr<FeedOfflineHost> offline_host)
-    : logging_metrics_(std::move(logging_metrics)),
-      networking_host_(std::move(networking_host)),
-      scheduler_host_(std::move(scheduler_host)),
-      content_database_(std::move(content_database)),
-      journal_database_(std::move(journal_database)),
-      offline_host_(std::move(offline_host)) {}
-
-FeedHostService::~FeedHostService() = default;
-
-FeedNetworkingHost* FeedHostService::GetNetworkingHost() {
-  return networking_host_.get();
-}
-
-FeedSchedulerHost* FeedHostService::GetSchedulerHost() {
-  return scheduler_host_.get();
-}
-
-FeedContentDatabase* FeedHostService::GetContentDatabase() {
-  return content_database_.get();
-}
-
-FeedJournalDatabase* FeedHostService::GetJournalDatabase() {
-  return journal_database_.get();
-}
-
-FeedOfflineHost* FeedHostService::GetOfflineHost() {
-  return offline_host_.get();
-}
-
-FeedLoggingMetrics* FeedHostService::GetLoggingMetrics() {
-  return logging_metrics_.get();
-}
-
-}  // namespace feed
diff --git a/components/feed/content/feed_host_service.h b/components/feed/content/feed_host_service.h
deleted file mode 100644
index 0550994..0000000
--- a/components/feed/content/feed_host_service.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CONTENT_FEED_HOST_SERVICE_H_
-#define COMPONENTS_FEED_CONTENT_FEED_HOST_SERVICE_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "components/feed/content/feed_offline_host.h"
-#include "components/feed/core/feed_content_database.h"
-#include "components/feed/core/feed_journal_database.h"
-#include "components/feed/core/feed_logging_metrics.h"
-#include "components/feed/core/feed_networking_host.h"
-#include "components/feed/core/feed_scheduler_host.h"
-#include "components/keyed_service/core/keyed_service.h"
-
-namespace feed {
-
-// KeyedService responsible for managing the lifetime of Feed Host API
-// implementations. It instantiates and owns these API implementations, and
-// provides access to non-owning pointers to them. While host implementations
-// may be created on demand, it is possible they will not be fully initialized
-// yet.
-class FeedHostService : public KeyedService {
- public:
-  FeedHostService(std::unique_ptr<FeedLoggingMetrics> logging_metrics,
-                  std::unique_ptr<FeedNetworkingHost> networking_host,
-                  std::unique_ptr<FeedSchedulerHost> scheduler_host,
-                  std::unique_ptr<FeedContentDatabase> content_database,
-                  std::unique_ptr<FeedJournalDatabase> journal_database,
-                  std::unique_ptr<FeedOfflineHost> offline_host);
-  ~FeedHostService() override;
-
-  FeedLoggingMetrics* GetLoggingMetrics();
-  FeedNetworkingHost* GetNetworkingHost();
-  FeedSchedulerHost* GetSchedulerHost();
-  FeedContentDatabase* GetContentDatabase();
-  FeedJournalDatabase* GetJournalDatabase();
-  FeedOfflineHost* GetOfflineHost();
-
- private:
-  std::unique_ptr<FeedLoggingMetrics> logging_metrics_;
-  std::unique_ptr<FeedNetworkingHost> networking_host_;
-  std::unique_ptr<FeedSchedulerHost> scheduler_host_;
-  std::unique_ptr<FeedContentDatabase> content_database_;
-  std::unique_ptr<FeedJournalDatabase> journal_database_;
-
-  // Depends on the |scheduler_host_|, so must come after in this file to be
-  // destroyed before the scheduler.
-  std::unique_ptr<FeedOfflineHost> offline_host_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedHostService);
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CONTENT_FEED_HOST_SERVICE_H_
diff --git a/components/feed/content/feed_offline_host.cc b/components/feed/content/feed_offline_host.cc
deleted file mode 100644
index 1ee411be..0000000
--- a/components/feed/content/feed_offline_host.cc
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/content/feed_offline_host.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/hash/hash.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/feed/core/feed_scheduler_host.h"
-#include "components/offline_pages/core/client_namespace_constants.h"
-#include "components/offline_pages/core/page_criteria.h"
-#include "components/offline_pages/core/prefetch/prefetch_service.h"
-#include "url/gurl.h"
-
-namespace feed {
-
-using offline_pages::OfflinePageItem;
-using offline_pages::OfflinePageModel;
-using offline_pages::PrefetchService;
-using offline_pages::PrefetchSuggestion;
-using offline_pages::SuggestionsProvider;
-
-namespace {
-
-// Aggregates multiple callbacks from OfflinePageModel, storing the offline url.
-// When all callbacks have been invoked, tracked by ref counting, then
-// |on_completeion_| is finally invoked, sending all results together.
-class CallbackAggregator : public base::RefCounted<CallbackAggregator> {
- public:
-  using ReportStatusCallback =
-      base::OnceCallback<void(std::vector<std::string>)>;
-  using CacheIdCallback =
-      base::RepeatingCallback<void(const std::string&, int64_t)>;
-
-  CallbackAggregator(OfflinePageModel* model,
-                     ReportStatusCallback on_completion,
-                     CacheIdCallback on_each_result)
-      : on_completion_(std::move(on_completion)),
-        on_each_result_(std::move(on_each_result)),
-        start_time_(base::Time::Now()) {}
-
-  // We curry |feed_url|, which is the URL the Feed requested with. This is used
-  // instead of the URLs present in the |pages| because offline pages has
-  // non-exact URL matching, and we must communicate with the Feed with exact
-  // matches.
-  void OnGetPages(std::string feed_url,
-                  const std::vector<OfflinePageItem>& pages) {
-    if (!pages.empty()) {
-      OfflinePageItem best =
-          *std::max_element(pages.begin(), pages.end(), [](auto lhs, auto rhs) {
-            // Prefer prefetched articles over any other. They are typically of
-            // higher quality.
-            bool leftIsPrefetch = lhs.client_id.name_space ==
-                                  offline_pages::kSuggestedArticlesNamespace;
-            bool rightIsPrefetch = rhs.client_id.name_space ==
-                                   offline_pages::kSuggestedArticlesNamespace;
-            if (leftIsPrefetch != rightIsPrefetch) {
-              // Only one is prefetch, if that is |rhs|, then they're in the
-              // correct order.
-              return rightIsPrefetch;
-            } else {
-              // Newer articles are also better, but not as important as being
-              // prefetched.
-              return lhs.creation_time < rhs.creation_time;
-            }
-          });
-      urls_.push_back(feed_url);
-      on_each_result_.Run(feed_url, best.offline_id);
-    }
-  }
-
- private:
-  friend class base::RefCounted<CallbackAggregator>;
-
-  ~CallbackAggregator() {
-    base::TimeDelta duration = base::Time::Now() - start_time_;
-    UMA_HISTOGRAM_TIMES("ContentSuggestions.Feed.Offline.GetStatusDuration",
-                        duration);
-    std::move(on_completion_).Run(std::move(urls_));
-  }
-
-  OfflinePageModel* offline_page_model_;
-
-  // To be called once all callbacks are run or destroyed.
-  ReportStatusCallback on_completion_;
-
-  // The urls of the offlined pages seen so far. Ultimately will be given to
-  // |on_completeion_|.
-  std::vector<std::string> urls_;
-
-  // Is not run if there are no results for a given url.
-  CacheIdCallback on_each_result_;
-
-  // The time the aggregator was created, before any requests were sent to the
-  // OfflinePageModel.
-  base::Time start_time_;
-};
-
-// Consumes |metadataVector|, moving as many of the fields as possible.
-std::vector<PrefetchSuggestion> ConvertMetadataToSuggestions(
-    std::vector<ContentMetadata> metadataVector) {
-  std::vector<PrefetchSuggestion> suggestionsVector;
-  for (ContentMetadata& metadata : metadataVector) {
-    // TODO(skym): Copy over published time when PrefetchSuggestion adds
-    // support.
-    PrefetchSuggestion suggestion;
-    suggestion.article_url = GURL(metadata.url);
-    suggestion.article_title = std::move(metadata.title);
-    suggestion.article_attribution = std::move(metadata.publisher);
-    suggestion.article_snippet = std::move(metadata.snippet);
-    suggestion.thumbnail_url = GURL(metadata.image_url);
-    suggestion.favicon_url = GURL(metadata.favicon_url);
-    suggestionsVector.push_back(std::move(suggestion));
-  }
-  return suggestionsVector;
-}
-
-void RunSuggestionCallbackWithConversion(
-    SuggestionsProvider::SuggestionCallback suggestions_callback,
-    std::vector<offline_pages::PrefetchSuggestion> metadataVector) {
-  std::move(suggestions_callback).Run(metadataVector);
-}
-
-}  //  namespace
-
-FeedOfflineHost::FeedOfflineHost(OfflinePageModel* offline_page_model,
-                                 PrefetchService* prefetch_service,
-                                 base::RepeatingClosure on_suggestion_consumed,
-                                 base::RepeatingClosure on_suggestions_shown)
-    : offline_page_model_(offline_page_model),
-      prefetch_service_(prefetch_service),
-      on_suggestion_consumed_(on_suggestion_consumed),
-      on_suggestions_shown_(on_suggestions_shown) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(offline_page_model_);
-  DCHECK(prefetch_service_);
-  DCHECK(!on_suggestion_consumed_.is_null());
-  DCHECK(!on_suggestions_shown_.is_null());
-}
-
-FeedOfflineHost::~FeedOfflineHost() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // Safe to call RemoveObserver() even if AddObserver() has not been called.
-  offline_page_model_->RemoveObserver(this);
-}
-
-void FeedOfflineHost::Initialize(
-    const base::RepeatingClosure& trigger_get_known_content,
-    const NotifyStatusChangeCallback& notify_status_change) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(trigger_get_known_content_.is_null());
-  DCHECK(!trigger_get_known_content.is_null());
-  DCHECK(notify_status_change_.is_null());
-  DCHECK(!notify_status_change.is_null());
-  trigger_get_known_content_ = trigger_get_known_content;
-  notify_status_change_ = notify_status_change;
-  offline_page_model_->AddObserver(this);
-  // The host guarantees that the two callbacks passed into this method will not
-  // be invoked until Initialize() has exited. To guarantee this, the host
-  // cannot call SetSuggestionProvider() in task, because that would give
-  // Prefetch the ability to run |trigger_get_known_content_| immediately.
-  // PostTask is used to delay when SetSuggestionProvider() is called.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(&FeedOfflineHost::SetSuggestionProvider,
-                                weak_factory_.GetWeakPtr()));
-}
-
-void FeedOfflineHost::SetSuggestionProvider() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  prefetch_service_->SetSuggestionProvider(this);
-}
-
-base::Optional<int64_t> FeedOfflineHost::GetOfflineId(const std::string& url) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  auto iter = url_hash_to_id_.find(base::FastHash(url));
-  return iter == url_hash_to_id_.end() ? base::Optional<int64_t>()
-                                       : base::Optional<int64_t>(iter->second);
-}
-
-void FeedOfflineHost::GetOfflineStatus(
-    std::vector<std::string> urls,
-    base::OnceCallback<void(std::vector<std::string>)> callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  UMA_HISTOGRAM_EXACT_LINEAR("ContentSuggestions.Feed.Offline.GetStatusCount",
-                             urls.size(), 50);
-
-  scoped_refptr<CallbackAggregator> aggregator =
-      base::MakeRefCounted<CallbackAggregator>(
-          offline_page_model_, std::move(callback),
-          base::BindRepeating(&FeedOfflineHost::CacheOfflinePageUrlAndId,
-                              weak_factory_.GetWeakPtr()));
-
-  for (std::string url : urls) {
-    offline_pages::PageCriteria criteria;
-    criteria.url = GURL(url);
-    criteria.exclude_tab_bound_pages = true;
-    offline_page_model_->GetPagesWithCriteria(
-        criteria, base::BindOnce(&CallbackAggregator::OnGetPages, aggregator,
-                                 std::move(url)));
-  }
-}
-
-void FeedOfflineHost::OnContentRemoved(std::vector<std::string> urls) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  for (const std::string& url : urls) {
-    prefetch_service_->RemoveSuggestion(GURL(url));
-  }
-}
-
-void FeedOfflineHost::OnNewContentReceived() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  prefetch_service_->NewSuggestionsAvailable();
-}
-
-void FeedOfflineHost::OnNoListeners() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  url_hash_to_id_.clear();
-}
-
-void FeedOfflineHost::OnGetKnownContentDone(
-    std::vector<ContentMetadata> suggestions) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // While |suggestions| are movable, there might be multiple callbacks in
-  // |pending_known_content_callbacks_|. To be safe, copy all the suggestions.
-  std::vector<offline_pages::PrefetchSuggestion> converted_suggestions =
-      ConvertMetadataToSuggestions(std::move(suggestions));
-  for (auto& callback : pending_known_content_callbacks_) {
-    RunSuggestionCallbackWithConversion(std::move(callback),
-                                        converted_suggestions);
-  }
-  pending_known_content_callbacks_.clear();
-}
-
-void FeedOfflineHost::GetCurrentArticleSuggestions(
-    SuggestionsProvider::SuggestionCallback suggestions_callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  // This function is used by the internals page, which doesn't wait for
-  // initialization to complete. Just give up in this exceptional case.
-  if (!trigger_get_known_content_) {
-    std::move(suggestions_callback).Run({});
-    return;
-  }
-
-  pending_known_content_callbacks_.emplace_back(
-      std::move(suggestions_callback));
-  // Trigger after push_back() in case triggering results in a synchronous
-  // response via OnGetKnownContentDone().
-  if (pending_known_content_callbacks_.size() <= 1) {
-    trigger_get_known_content_.Run();
-  }
-}
-
-void FeedOfflineHost::ReportArticleListViewed() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  on_suggestion_consumed_.Run();
-}
-
-void FeedOfflineHost::ReportArticleViewed(GURL article_url) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  on_suggestions_shown_.Run();
-}
-
-void FeedOfflineHost::OfflinePageModelLoaded(OfflinePageModel* model) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // Ignored.
-}
-
-void FeedOfflineHost::OfflinePageAdded(OfflinePageModel* model,
-                                       const OfflinePageItem& added_page) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(!notify_status_change_.is_null());
-  const std::string& url = added_page.GetOriginalUrl().spec();
-  CacheOfflinePageUrlAndId(url, added_page.offline_id);
-  notify_status_change_.Run(url, true);
-}
-
-void FeedOfflineHost::OfflinePageDeleted(const OfflinePageItem& deleted_page) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(!notify_status_change_.is_null());
-  const std::string& url = deleted_page.url.spec();
-  EvictOfflinePageUrl(url);
-  notify_status_change_.Run(url, false);
-}
-
-void FeedOfflineHost::CacheOfflinePageUrlAndId(const std::string& url,
-                                               int64_t id) {
-  url_hash_to_id_[base::FastHash(url)] = id;
-}
-
-void FeedOfflineHost::EvictOfflinePageUrl(const std::string& url) {
-  url_hash_to_id_.erase(base::FastHash(url));
-}
-
-}  // namespace feed
diff --git a/components/feed/content/feed_offline_host.h b/components/feed/content/feed_offline_host.h
deleted file mode 100644
index ddc6988..0000000
--- a/components/feed/content/feed_offline_host.h
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CONTENT_FEED_OFFLINE_HOST_H_
-#define COMPONENTS_FEED_CONTENT_FEED_OFFLINE_HOST_H_
-
-#include <string>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/containers/flat_map.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
-#include "base/sequenced_task_runner.h"
-#include "components/feed/core/content_metadata.h"
-#include "components/offline_pages/core/offline_page_model.h"
-#include "components/offline_pages/core/prefetch/suggestions_provider.h"
-
-class GURL;
-
-namespace offline_pages {
-class PrefetchService;
-}  // namespace offline_pages
-
-namespace feed {
-
-// Responsible for wiring up connections for Feed operations pertaining to
-// articles that can be loaded from Offline Pages component. Most significantly
-// this class connects Prefetch and the Feed, and tracks offlined articles the
-// Feed may have badged for this user. This knowledge is later used when Feed
-// articles are opened to populate load params.
-class FeedOfflineHost : public offline_pages::SuggestionsProvider,
-                        public offline_pages::OfflinePageModel::Observer {
- public:
-  using GetKnownContentCallback =
-      base::OnceCallback<void(std::vector<ContentMetadata>)>;
-  using NotifyStatusChangeCallback =
-      base::RepeatingCallback<void(const std::string&, bool)>;
-
-  FeedOfflineHost(offline_pages::OfflinePageModel* offline_page_model,
-                  offline_pages::PrefetchService* prefetch_service,
-                  base::RepeatingClosure on_suggestion_consumed,
-                  base::RepeatingClosure on_suggestions_shown);
-  ~FeedOfflineHost() override;
-
-  // Initialize with callbacks to call into bridge/Java side. Should only be
-  // called once, and done as soon as the bridge is ready. The FeedOfflineHost
-  // will not be fully ready to perform its function without these dependencies.
-  // Neither of these callbacks will be invoked until after this method exits.
-  void Initialize(const base::RepeatingClosure& trigger_get_known_content,
-                  const NotifyStatusChangeCallback& notify_status_change);
-
-  // Called during initialization make ourselves known to |prefetch_service_|.
-  // This method is used to wrap PrefetchService::SetSuggestionProvider() to let
-  // our weak pointer guarantee everyone is still alive.
-  void SetSuggestionProvider();
-
-  // Synchronously returns the offline id of the given page. The host will only
-  // have knowledge of the page if it had previously returned status about it
-  // through GetOfflineState() or as a notification. Otherwise the caller will
-  // receive a false negative. Additionally, since the host tracks pages by
-  // hashing, there's also a small chance that the host erroneously returns an
-  // id for a page that is not offlined.
-  base::Optional<int64_t> GetOfflineId(const std::string& url);
-
-  // Asynchronously fetches offline status for the given URLs. Any pages that
-  // are currently offlined will be remembered by the FeedOfflineHost.
-  void GetOfflineStatus(
-      std::vector<std::string> urls,
-      base::OnceCallback<void(std::vector<std::string>)> callback);
-
-  // Should be called from Feed any time the user manually removes articles or
-  // groupings of articles. Propagates the signal to Prefetch.
-  void OnContentRemoved(std::vector<std::string> urls);
-
-  // Should be called from Feed any time new articles are fetched.
-  void OnNewContentReceived();
-
-  // Should be called from Feed side any time there are no active surfaces
-  // displaying articles and listening to our notifications. This signal is used
-  // to clear local tracking of offlined items.
-  void OnNoListeners();
-
-  // Should be called when async GetKnownContent is completed. Broadcasts to all
-  // waiting consumers in |pending_known_content_callbacks_|.
-  void OnGetKnownContentDone(std::vector<ContentMetadata> suggestions);
-
-  // offline_pages::SuggestionsProvider:
-  void GetCurrentArticleSuggestions(
-      offline_pages::SuggestionsProvider::SuggestionCallback
-          suggestions_callback) override;
-  void ReportArticleListViewed() override;
-  void ReportArticleViewed(GURL article_url) override;
-
-  // offline_pages::OfflinePageModel::Observer:
-  void OfflinePageModelLoaded(offline_pages::OfflinePageModel* model) override;
-  void OfflinePageAdded(
-      offline_pages::OfflinePageModel* model,
-      const offline_pages::OfflinePageItem& added_page) override;
-  void OfflinePageDeleted(
-      const offline_pages::OfflinePageItem& deleted_page) override;
-
- private:
-  // Stores the given record in |url_hash_to_id_|. If there's a conflict, the
-  // new id will overwrite the old value.
-  void CacheOfflinePageUrlAndId(const std::string& url, int64_t id);
-
-  // Removes a previously cached |id| for the given |url| if there was one.
-  void EvictOfflinePageUrl(const std::string& url);
-
-  // The following objects all outlive us, so it is safe to hold raw pointers to
-  // them. This is guaranteed by the FeedHostServiceFactory.
-  offline_pages::OfflinePageModel* offline_page_model_;
-  offline_pages::PrefetchService* prefetch_service_;
-
-  base::RepeatingClosure on_suggestion_consumed_;
-  base::RepeatingClosure on_suggestions_shown_;
-
-  // Only offlined pages that have passed through the host are stored. If there
-  // are ever no listeners to the offline host logic and OnNoListeners() is
-  // called this map is cleared. The key is the hash of the url, and the value
-  // is the offline id for the given page.
-  base::flat_map<size_t, int64_t> url_hash_to_id_;
-
-  // Starts an the async request for ContentMetadata through KnownContentApi's
-  // GetKnownContent(). Will only be invoked when there isn't already an
-  // outstanding GetKnownContent().
-  base::RepeatingClosure trigger_get_known_content_;
-
-  // Holds all consumers of GetKnownContent(). It is assumed that there's an
-  // outstanding GetKnownContent() if and only if this vector is not empty.
-  std::vector<SuggestionsProvider::SuggestionCallback>
-      pending_known_content_callbacks_;
-
-  // Calls all OfflineStatusListeners with the updated status.
-  NotifyStatusChangeCallback notify_status_change_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  base::WeakPtrFactory<FeedOfflineHost> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FeedOfflineHost);
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CONTENT_FEED_OFFLINE_HOST_H_
diff --git a/components/feed/content/feed_offline_host_unittest.cc b/components/feed/content/feed_offline_host_unittest.cc
deleted file mode 100644
index 3589d95..0000000
--- a/components/feed/content/feed_offline_host_unittest.cc
+++ /dev/null
@@ -1,461 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/content/feed_offline_host.h"
-
-#include <algorithm>
-#include <map>
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/task/post_task.h"
-#include "base/test/task_environment.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/feed/core/content_metadata.h"
-#include "components/offline_pages/core/client_namespace_constants.h"
-#include "components/offline_pages/core/offline_page_item.h"
-#include "components/offline_pages/core/offline_page_types.h"
-#include "components/offline_pages/core/page_criteria.h"
-#include "components/offline_pages/core/prefetch/stub_prefetch_service.h"
-#include "components/offline_pages/core/stub_offline_page_model.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-namespace feed {
-
-namespace {
-
-using offline_pages::MultipleOfflinePageItemCallback;
-using offline_pages::OfflinePageItem;
-using offline_pages::OfflinePageModel;
-using offline_pages::PageCriteria;
-using offline_pages::PrefetchSuggestion;
-using offline_pages::StubOfflinePageModel;
-using offline_pages::StubPrefetchService;
-using offline_pages::SuggestionsProvider;
-
-constexpr char kUrl1[] = "https://www.one.com/";
-constexpr char kUrl2[] = "https://www.two.com/";
-constexpr char kUrl3[] = "https://www.three.com/";
-
-constexpr char kOne[] = "One";
-constexpr char kTwo[] = "Two";
-constexpr char kThree[] = "Three";
-
-MATCHER_P(EqualsSpec, expected, "") {
-  return arg.spec() == expected;
-}
-
-class TestOfflinePageModel : public StubOfflinePageModel {
- public:
-  void AddOfflinedPage(const std::string& url,
-                       const std::string& original_url,
-                       int64_t offline_id,
-                       base::Time creation_time,
-                       std::string name_space) {
-    OfflinePageItem item;
-    item.url = GURL(url);
-    item.original_url_if_different = GURL(original_url);
-    item.offline_id = offline_id;
-    item.creation_time = creation_time;
-    item.client_id = offline_pages::ClientId(name_space, "");
-    url_to_offline_page_item_.emplace(url, item);
-    if (!original_url.empty()) {
-      url_to_offline_page_item_.emplace(original_url, item);
-    }
-  }
-
-  void AddOfflinedPage(const std::string& url, int64_t offline_id) {
-    AddOfflinedPage(url, "", offline_id, base::Time(), "");
-  }
-
-  MOCK_METHOD1(AddObserver, void(Observer*));
-  MOCK_METHOD1(RemoveObserver, void(Observer*));
-
- private:
-  void GetPagesWithCriteria(const PageCriteria& criteria,
-                            MultipleOfflinePageItemCallback callback) override {
-    // Feed should ignore tab-bound pages.
-    EXPECT_TRUE(criteria.exclude_tab_bound_pages);
-
-    auto iter = url_to_offline_page_item_.equal_range(criteria.url.spec());
-    std::vector<OfflinePageItem> ret;
-    ret.resize(std::distance(iter.first, iter.second));
-    std::transform(iter.first, iter.second, ret.begin(),
-                   [](auto pair) { return pair.second; });
-
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(std::move(callback), std::move(ret)));
-  }
-
-  // Maps URLs to OfflinePageItem. Items with both |urls| and |original_url|
-  // will be inserted at both locations in the multimap.
-  std::multimap<std::string, OfflinePageItem> url_to_offline_page_item_;
-};
-
-class TestPrefetchService : public StubPrefetchService {
- public:
-  MOCK_METHOD1(SetSuggestionProvider, void(SuggestionsProvider*));
-  MOCK_METHOD0(NewSuggestionsAvailable, void());
-  MOCK_METHOD1(RemoveSuggestion, void(GURL));
-};
-
-void IgnoreStatus(std::vector<std::string> result) {}
-
-void CopyStatus(std::vector<std::string>* out,
-                std::vector<std::string> result) {
-  *out = std::move(result);
-}
-
-void CopySuggestions(std::vector<PrefetchSuggestion>* out,
-                     std::vector<PrefetchSuggestion> result) {
-  *out = std::move(result);
-}
-
-}  // namespace
-
-class FeedOfflineHostTest : public ::testing::Test {
- public:
-  TestOfflinePageModel* offline_page_model() { return &offline_page_model_; }
-  FeedOfflineHost* host() { return host_.get(); }
-  TestPrefetchService* prefetch_service() { return &prefetch_service_; }
-  int get_suggestion_consumed_count() { return suggestion_consumed_count_; }
-  int get_suggestions_shown_count() { return suggestions_shown_count_; }
-  int get_get_known_content_count() { return get_known_content_count_; }
-  const std::vector<std::pair<std::string, bool>>& get_status_notifications() {
-    return status_notifications_;
-  }
-
-  void RunUntilIdle() { task_environment_.RunUntilIdle(); }
-
-  void SetupHost() {
-    EXPECT_CALL(*offline_page_model(), AddObserver(testing::_))
-        .Times(1)
-        .RetiresOnSaturation();
-    EXPECT_CALL(*offline_page_model(), RemoveObserver(testing::_))
-        .Times(1)
-        .RetiresOnSaturation();
-    ResetHost();
-    InitHost();
-  }
-
-  void ResetHost() {
-    host_ = std::make_unique<FeedOfflineHost>(
-        offline_page_model(), prefetch_service(),
-        base::BindRepeating(&FeedOfflineHostTest::OnSuggestionConsumed,
-                            base::Unretained(this)),
-        base::BindRepeating(&FeedOfflineHostTest::OnSuggestionsShown,
-                            base::Unretained(this)));
-  }
-
-  void InitHost() {
-    host()->Initialize(
-        base::BindRepeating(&FeedOfflineHostTest::OnGetKnownContentRequested,
-                            base::Unretained(this)),
-        base::BindRepeating(&FeedOfflineHostTest::NotifyStatusChange,
-                            base::Unretained(this)));
-  }
-
- protected:
-  FeedOfflineHostTest() { SetupHost(); }
-
- private:
-  void OnSuggestionConsumed() { ++suggestion_consumed_count_; }
-  void OnSuggestionsShown() { ++suggestions_shown_count_; }
-  void OnGetKnownContentRequested() { ++get_known_content_count_; }
-
-  void NotifyStatusChange(const std::string& url, bool available_offline) {
-    status_notifications_.emplace_back(url, available_offline);
-  }
-
-  base::test::TaskEnvironment task_environment_;
-  TestOfflinePageModel offline_page_model_;
-  TestPrefetchService prefetch_service_;
-  std::unique_ptr<FeedOfflineHost> host_;
-  int suggestion_consumed_count_ = 0;
-  int suggestions_shown_count_ = 0;
-  int get_known_content_count_ = 0;
-  std::vector<std::pair<std::string, bool>> status_notifications_;
-};
-
-TEST_F(FeedOfflineHostTest, ReportArticleListViewed) {
-  EXPECT_EQ(0, get_suggestion_consumed_count());
-  host()->ReportArticleListViewed();
-  EXPECT_EQ(1, get_suggestion_consumed_count());
-  host()->ReportArticleListViewed();
-  EXPECT_EQ(2, get_suggestion_consumed_count());
-  EXPECT_EQ(0, get_suggestions_shown_count());
-}
-
-TEST_F(FeedOfflineHostTest, OnSuggestionsShown) {
-  EXPECT_EQ(0, get_suggestions_shown_count());
-  host()->ReportArticleViewed(GURL(kUrl1));
-  EXPECT_EQ(1, get_suggestions_shown_count());
-  host()->ReportArticleViewed(GURL(kUrl1));
-  EXPECT_EQ(2, get_suggestions_shown_count());
-  EXPECT_EQ(0, get_suggestion_consumed_count());
-}
-
-TEST_F(FeedOfflineHostTest, GetOfflineStatusEmpty) {
-  std::vector<std::string> actual;
-  host()->GetOfflineStatus({}, base::BindOnce(&CopyStatus, &actual));
-  RunUntilIdle();
-
-  EXPECT_EQ(0U, actual.size());
-}
-
-TEST_F(FeedOfflineHostTest, GetOfflineStatusMiss) {
-  offline_page_model()->AddOfflinedPage(kUrl1, 4);
-
-  std::vector<std::string> actual;
-  host()->GetOfflineStatus({kUrl2}, base::BindOnce(&CopyStatus, &actual));
-  RunUntilIdle();
-
-  EXPECT_EQ(0U, actual.size());
-  EXPECT_FALSE(host()->GetOfflineId(kUrl1).has_value());
-  EXPECT_FALSE(host()->GetOfflineId(kUrl2).has_value());
-}
-
-TEST_F(FeedOfflineHostTest, GetOfflineStatusHit) {
-  offline_page_model()->AddOfflinedPage(kUrl1, 4);
-  offline_page_model()->AddOfflinedPage(kUrl2, 5);
-  offline_page_model()->AddOfflinedPage(kUrl3, 6);
-
-  std::vector<std::string> actual;
-  host()->GetOfflineStatus({kUrl1, kUrl2},
-                           base::BindOnce(&CopyStatus, &actual));
-
-  EXPECT_EQ(0U, actual.size());
-  RunUntilIdle();
-
-  EXPECT_EQ(2U, actual.size());
-  EXPECT_TRUE(actual[0] == kUrl1 || actual[1] == kUrl1);
-  EXPECT_TRUE(actual[0] == kUrl2 || actual[1] == kUrl2);
-  EXPECT_EQ(host()->GetOfflineId(kUrl1).value(), 4);
-  EXPECT_EQ(host()->GetOfflineId(kUrl2).value(), 5);
-  EXPECT_FALSE(host()->GetOfflineId(kUrl3).has_value());
-}
-
-TEST_F(FeedOfflineHostTest, GetOfflineIdOriginalUrl) {
-  offline_page_model()->AddOfflinedPage(kUrl1, kUrl2, 4, base::Time(), "");
-
-  std::vector<std::string> actual;
-  host()->GetOfflineStatus({kUrl2}, base::BindOnce(&CopyStatus, &actual));
-  RunUntilIdle();
-
-  EXPECT_EQ(1U, actual.size());
-  EXPECT_EQ(kUrl2, actual[0]);
-  EXPECT_FALSE(host()->GetOfflineId(kUrl1).has_value());
-  EXPECT_EQ(host()->GetOfflineId(kUrl2).value(), 4);
-}
-
-TEST_F(FeedOfflineHostTest, GetOfflineIdRequestUrl) {
-  offline_page_model()->AddOfflinedPage(kUrl2, kUrl1, 4, base::Time(), "");
-
-  std::vector<std::string> actual;
-  host()->GetOfflineStatus({kUrl2}, base::BindOnce(&CopyStatus, &actual));
-  RunUntilIdle();
-
-  EXPECT_EQ(1U, actual.size());
-  EXPECT_EQ(kUrl2, actual[0]);
-  EXPECT_FALSE(host()->GetOfflineId(kUrl1).has_value());
-  EXPECT_EQ(host()->GetOfflineId(kUrl2).value(), 4);
-}
-
-TEST_F(FeedOfflineHostTest, GetOfflineIdNewer) {
-  offline_page_model()->AddOfflinedPage(kUrl1, "", 4, base::Time(), "");
-  offline_page_model()->AddOfflinedPage(
-      kUrl1, "", 5, base::Time() + base::TimeDelta::FromHours(1), "");
-
-  std::vector<std::string> actual;
-  host()->GetOfflineStatus({kUrl1}, base::BindOnce(&CopyStatus, &actual));
-  RunUntilIdle();
-
-  EXPECT_EQ(1U, actual.size());
-  EXPECT_EQ(kUrl1, actual[0]);
-  EXPECT_EQ(host()->GetOfflineId(kUrl1).value(), 5);
-}
-
-TEST_F(FeedOfflineHostTest, GetOfflineIdNamespace) {
-  // Even though id of 5 is newer, id of 4 will be chosen because it has the
-  // preferred namespace.
-  offline_page_model()->AddOfflinedPage(
-      kUrl1, "", 4, base::Time(), offline_pages::kSuggestedArticlesNamespace);
-  offline_page_model()->AddOfflinedPage(
-      kUrl1, "", 5, base::Time() + base::TimeDelta::FromHours(1), "");
-
-  std::vector<std::string> actual;
-  host()->GetOfflineStatus({kUrl1}, base::BindOnce(&CopyStatus, &actual));
-  RunUntilIdle();
-
-  EXPECT_EQ(1U, actual.size());
-  EXPECT_EQ(kUrl1, actual[0]);
-  EXPECT_EQ(host()->GetOfflineId(kUrl1).value(), 4);
-}
-
-TEST_F(FeedOfflineHostTest, GetCurrentArticleSuggestions) {
-  std::vector<PrefetchSuggestion> actual;
-  host()->GetCurrentArticleSuggestions(
-      base::BindOnce(&CopySuggestions, &actual));
-  EXPECT_EQ(1, get_get_known_content_count());
-  EXPECT_EQ(0U, actual.size());
-
-  ContentMetadata metadata;
-  metadata.url = kUrl1;
-  metadata.title = kOne;
-  metadata.time_published = base::Time();
-  metadata.image_url = kUrl2;
-  metadata.publisher = kTwo;
-  metadata.favicon_url = kUrl3;
-  metadata.snippet = kThree;
-  host()->OnGetKnownContentDone({std::move(metadata)});
-
-  EXPECT_EQ(1U, actual.size());
-  EXPECT_EQ(kUrl1, actual[0].article_url.spec());
-  EXPECT_EQ(kOne, actual[0].article_title);
-  EXPECT_EQ(kTwo, actual[0].article_attribution);
-  EXPECT_EQ(kThree, actual[0].article_snippet);
-  EXPECT_EQ(kUrl2, actual[0].thumbnail_url.spec());
-  EXPECT_EQ(kUrl3, actual[0].favicon_url.spec());
-}
-
-TEST_F(FeedOfflineHostTest, GetCurrentArticleSuggestionsMultiple) {
-  std::vector<PrefetchSuggestion> suggestions1;
-  host()->GetCurrentArticleSuggestions(
-      base::BindOnce(&CopySuggestions, &suggestions1));
-  EXPECT_EQ(1, get_get_known_content_count());
-  std::vector<PrefetchSuggestion> suggestions2;
-  host()->GetCurrentArticleSuggestions(
-      base::BindOnce(&CopySuggestions, &suggestions2));
-  // This second GetCurrentArticleSuggestions() should not re-trigger since the
-  // host should know there's an outstanding request.
-  EXPECT_EQ(1, get_get_known_content_count());
-
-  // Use both url and title, url goes through a GURL and isn't really moved all
-  // the way, but title should actually be moved into one of the results.
-  ContentMetadata metadata1;
-  metadata1.url = kUrl1;
-  metadata1.title = kOne;
-  ContentMetadata metadata2;
-  metadata2.url = kUrl2;
-  metadata2.title = kTwo;
-  host()->OnGetKnownContentDone({std::move(metadata1), std::move(metadata2)});
-
-  EXPECT_EQ(2U, suggestions1.size());
-  EXPECT_EQ(kUrl1, suggestions1[0].article_url.spec());
-  EXPECT_EQ(kOne, suggestions1[0].article_title);
-  EXPECT_EQ(kUrl2, suggestions1[1].article_url.spec());
-  EXPECT_EQ(kTwo, suggestions1[1].article_title);
-  EXPECT_EQ(2U, suggestions2.size());
-  EXPECT_EQ(kUrl1, suggestions2[0].article_url.spec());
-  EXPECT_EQ(kOne, suggestions2[0].article_title);
-  EXPECT_EQ(kUrl2, suggestions2[1].article_url.spec());
-  EXPECT_EQ(kTwo, suggestions2[1].article_title);
-
-  // Now perform another GetCurrentArticleSuggestions and make sure the
-  // originally bound callbacks are not invoked.
-  std::vector<PrefetchSuggestion> suggestions3;
-  host()->GetCurrentArticleSuggestions(
-      base::BindOnce(&CopySuggestions, &suggestions3));
-  EXPECT_EQ(2, get_get_known_content_count());
-
-  ContentMetadata metadata3;
-  metadata3.url = kUrl3;
-  metadata3.title = kThree;
-  host()->OnGetKnownContentDone({std::move(metadata3)});
-
-  EXPECT_EQ(2U, suggestions1.size());
-  EXPECT_EQ(2U, suggestions2.size());
-  EXPECT_EQ(1U, suggestions3.size());
-  EXPECT_EQ(kUrl3, suggestions3[0].article_url.spec());
-  EXPECT_EQ(kThree, suggestions3[0].article_title);
-}
-
-TEST_F(FeedOfflineHostTest, OfflinePageAdded) {
-  OfflinePageItem added_page;
-  added_page.url = GURL(kUrl1);
-  added_page.original_url_if_different = GURL(kUrl2);
-  added_page.offline_id = 4;
-
-  host()->OfflinePageAdded(nullptr, added_page);
-
-  EXPECT_EQ(1U, get_status_notifications().size());
-  EXPECT_EQ(kUrl2, get_status_notifications()[0].first);
-  EXPECT_TRUE(get_status_notifications()[0].second);
-  EXPECT_EQ(host()->GetOfflineId(kUrl2).value(), 4);
-}
-
-TEST_F(FeedOfflineHostTest, OfflinePageDeleted) {
-  offline_page_model()->AddOfflinedPage(kUrl1, 4);
-  host()->GetOfflineStatus({kUrl1}, base::BindOnce(&IgnoreStatus));
-  RunUntilIdle();
-  EXPECT_EQ(host()->GetOfflineId(kUrl1).value(), 4);
-  OfflinePageItem page_item;
-  page_item.url = GURL(kUrl1);
-
-  host()->OfflinePageDeleted(page_item);
-
-  EXPECT_EQ(1U, get_status_notifications().size());
-  EXPECT_EQ(kUrl1, get_status_notifications()[0].first);
-  EXPECT_FALSE(get_status_notifications()[0].second);
-  EXPECT_FALSE(host()->GetOfflineId(kUrl1).has_value());
-}
-
-TEST_F(FeedOfflineHostTest, OnNoListeners) {
-  offline_page_model()->AddOfflinedPage(kUrl1, 4);
-  host()->GetOfflineStatus({kUrl1}, base::BindOnce(&IgnoreStatus));
-  RunUntilIdle();
-  EXPECT_EQ(host()->GetOfflineId(kUrl1).value(), 4);
-
-  host()->OnNoListeners();
-
-  EXPECT_FALSE(host()->GetOfflineId(kUrl1).has_value());
-}
-
-TEST_F(FeedOfflineHostTest, NoAddObserverWithoutInitialize) {
-  // Normally SetupHost() will set all observer expectations. Here we explicitly
-  // do not expect AddObserver and then reset the host.
-  EXPECT_CALL(*offline_page_model(), RemoveObserver(testing::_))
-      .Times(1)
-      .RetiresOnSaturation();
-  ResetHost();
-}
-
-TEST_F(FeedOfflineHostTest, SetSuggestionProviderNotCalledSynchronously) {
-  EXPECT_CALL(*prefetch_service(), SetSuggestionProvider(testing::_)).Times(0);
-}
-
-TEST_F(FeedOfflineHostTest, SetSuggestionProviderCalledAsync) {
-  EXPECT_CALL(*prefetch_service(), SetSuggestionProvider(testing::_)).Times(1);
-  RunUntilIdle();
-}
-
-TEST_F(FeedOfflineHostTest, OnNewContentReceived) {
-  EXPECT_CALL(*prefetch_service(), NewSuggestionsAvailable()).Times(1);
-  host()->OnNewContentReceived();
-}
-
-TEST_F(FeedOfflineHostTest, RemoveZeroSuggestions) {
-  EXPECT_CALL(*prefetch_service(), RemoveSuggestion(testing::_)).Times(0);
-  host()->OnContentRemoved({});
-}
-
-TEST_F(FeedOfflineHostTest, RemoveOneSuggestion) {
-  EXPECT_CALL(*prefetch_service(), RemoveSuggestion(EqualsSpec(kUrl1)))
-      .Times(1);
-  host()->OnContentRemoved({kUrl1});
-}
-
-TEST_F(FeedOfflineHostTest, RemoveTwoSuggestions) {
-  EXPECT_CALL(*prefetch_service(), RemoveSuggestion(EqualsSpec(kUrl1)))
-      .Times(1);
-  EXPECT_CALL(*prefetch_service(), RemoveSuggestion(EqualsSpec(kUrl2)))
-      .Times(1);
-  host()->OnContentRemoved({kUrl1, kUrl2});
-}
-
-}  // namespace feed
diff --git a/components/feed/core/BUILD.gn b/components/feed/core/BUILD.gn
deleted file mode 100644
index 0cd324a..0000000
--- a/components/feed/core/BUILD.gn
+++ /dev/null
@@ -1,97 +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.
-
-if (is_android) {
-  import("//build/config/android/rules.gni")
-}
-
-source_set("feed_core") {
-  sources = [
-    "content_metadata.cc",
-    "content_metadata.h",
-    "feed_content_database.cc",
-    "feed_content_database.h",
-    "feed_content_mutation.cc",
-    "feed_content_mutation.h",
-    "feed_content_operation.cc",
-    "feed_content_operation.h",
-    "feed_journal_database.cc",
-    "feed_journal_database.h",
-    "feed_journal_mutation.cc",
-    "feed_journal_mutation.h",
-    "feed_journal_operation.cc",
-    "feed_journal_operation.h",
-    "feed_logging_metrics.cc",
-    "feed_logging_metrics.h",
-    "feed_networking_host.cc",
-    "feed_networking_host.h",
-    "feed_scheduler_host.cc",
-    "feed_scheduler_host.h",
-    "time_serialization.cc",
-    "time_serialization.h",
-  ]
-
-  public_deps = [
-    "//base",
-    "//components/feed:feature_list",
-    "//components/feed/core/proto",
-    "//components/feed/core/shared_prefs:feed_shared_prefs",
-    "//components/leveldb_proto",
-    "//net",
-    "//ui/base/mojom:mojom",
-  ]
-
-  deps = [
-    "//components/feed/core/common:feed_core_common",
-    "//components/prefs",
-    "//components/signin/public/identity_manager",
-    "//components/variations",
-    "//components/variations/net",
-    "//components/variations/service",
-    "//components/web_resource",
-    "//google_apis",
-    "//services/network/public/cpp",
-    "//services/network/public/mojom",
-    "//third_party/zlib/google:compression_utils",
-  ]
-}
-
-if (is_android) {
-  java_cpp_enum("feed_core_java_enums_srcjar") {
-    sources = [ "feed_scheduler_host.h" ]
-  }
-}
-
-source_set("core_unit_tests") {
-  testonly = true
-  sources = [
-    "feed_content_database_unittest.cc",
-    "feed_content_mutation_unittest.cc",
-    "feed_journal_database_unittest.cc",
-    "feed_journal_mutation_unittest.cc",
-    "feed_logging_metrics_unittest.cc",
-    "feed_networking_host_unittest.cc",
-    "feed_scheduler_host_unittest.cc",
-  ]
-
-  deps = [
-    ":feed_core",
-    "//base",
-    "//base/test:test_support",
-    "//build:chromeos_buildflags",
-    "//build:chromeos_buildflags",
-    "//components/feed/core/common:feed_core_common",
-    "//components/leveldb_proto:test_support",
-    "//components/prefs:test_support",
-    "//components/signin/public/identity_manager:test_support",
-    "//components/variations:test_support",
-    "//components/web_resource",
-    "//net:test_support",
-    "//services/network:test_support",
-    "//services/network/public/cpp",
-    "//services/network/public/mojom",
-    "//third_party/zlib/google:compression_utils",
-    "//ui/gfx:test_support",
-  ]
-}
diff --git a/components/feed/core/common/BUILD.gn b/components/feed/core/common/BUILD.gn
index 61b32e02..fc24128 100644
--- a/components/feed/core/common/BUILD.gn
+++ b/components/feed/core/common/BUILD.gn
@@ -8,44 +8,13 @@
 
 source_set("feed_core_common") {
   sources = [
-    "enums.h",
     "pref_names.cc",
     "pref_names.h",
-    "refresh_throttler.cc",
-    "refresh_throttler.h",
-    "user_classifier.cc",
-    "user_classifier.h",
   ]
   deps = [ "//components/prefs" ]
 
   public_deps = [
     "//base",
     "//components/feed:feature_list",
-    "//components/feed/core/proto",
-  ]
-}
-
-source_set("core_common_unit_tests") {
-  testonly = true
-  sources = [
-    "refresh_throttler_unittest.cc",
-    "user_classifier_unittest.cc",
-  ]
-
-  deps = [
-    ":feed_core_common",
-    "//base",
-    "//base/test:test_support",
-    "//components/leveldb_proto:test_support",
-    "//components/prefs:test_support",
-    "//components/signin/public/identity_manager:test_support",
-    "//components/variations:test_support",
-    "//components/web_resource",
-    "//net:test_support",
-    "//services/network:test_support",
-    "//services/network/public/cpp",
-    "//services/network/public/mojom",
-    "//third_party/zlib/google:compression_utils",
-    "//ui/gfx:test_support",
   ]
 }
diff --git a/components/feed/core/common/enums.h b/components/feed/core/common/enums.h
deleted file mode 100644
index 23fc0ea..0000000
--- a/components/feed/core/common/enums.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_COMMON_ENUMS_H_
-#define COMPONENTS_FEED_CORE_COMMON_ENUMS_H_
-
-// This file contains enumerations common to Feed v1 and v2.
-
-namespace feed {
-
-// The TriggerType enum specifies values for the events that can trigger
-// refreshing articles. When adding values, be certain to also update the
-// corresponding definition in enums.xml.
-enum class TriggerType {
-  kNtpShown = 0,
-  kForegrounded = 1,
-  kFixedTimer = 2,
-  kMaxValue = kFixedTimer
-};
-
-// Different groupings of usage. A user will belong to exactly one of these at
-// any given point in time. Can change at runtime.
-enum class UserClass {
-  kRareSuggestionsViewer,      // Almost never opens surfaces that show
-                               // suggestions, like the NTP.
-  kActiveSuggestionsViewer,    // Frequently shown suggestions, but does not
-                               // usually open them.
-  kActiveSuggestionsConsumer,  // Frequently opens news articles.
-};
-
-// Enum for the status of the refresh, reported through UMA.
-// If any new values are added, update FeedSchedulerRefreshStatus in
-// enums.xml.
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused.
-enum class ShouldRefreshResult {
-  kShouldRefresh = 0,
-  kDontRefreshOutstandingRequest = 1,
-  kDontRefreshTriggerDisabled = 2,
-  kDontRefreshNetworkOffline = 3,
-  kDontRefreshEulaNotAccepted = 4,
-  kDontRefreshArticlesHidden = 5,
-  kDontRefreshRefreshSuppressed = 6,
-  kDontRefreshNotStale = 7,
-  kDontRefreshRefreshThrottled = 8,
-  kMaxValue = kDontRefreshRefreshThrottled,
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CORE_COMMON_ENUMS_H_
diff --git a/components/feed/core/common/pref_names.cc b/components/feed/core/common/pref_names.cc
index 70cd159..6efbeab 100644
--- a/components/feed/core/common/pref_names.cc
+++ b/components/feed/core/common/pref_names.cc
@@ -6,37 +6,21 @@
 
 #include <string>
 
-#include "components/feed/core/common/user_classifier.h"
 #include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
 
 namespace feed {
 
 namespace prefs {
 
-const char kBackgroundRefreshPeriod[] = "feed.background_refresh_period";
-
 const char kLastFetchAttemptTime[] = "feed.last_fetch_attempt";
 
-const char kThrottlerRequestCount[] = "feed.refresh_throttler.count";
-const char kThrottlerRequestsDay[] = "feed.refresh_throttler.day";
-
-const char kUserClassifierAverageSuggestionsViwedPerHour[] =
-    "feed.user_classifier.average_suggestions_veiwed_per_hour";
-const char kUserClassifierAverageSuggestionsUsedPerHour[] =
-    "feed.user_classifier.average_suggestions_used_per_hour";
-
-const char kUserClassifierLastTimeToViewSuggestions[] =
-    "feed.user_classifier.last_time_to_view_suggestions";
-const char kUserClassifierLastTimeToUseSuggestions[] =
-    "feed.user_classifier.last_time_to_use_suggestions";
-
 const char kHostOverrideHost[] = "feed.host_override.host";
 const char kHostOverrideBlessNonce[] = "feed.host_override.bless_nonce";
 
 const char kHasReachedClickAndViewActionsUploadConditions[] =
     "feed.clicks_and_views_upload_conditions_reached";
 const char kLastFetchHadNoticeCard[] = "feed.last_fetch_had_notice_card";
-const char kLastRefreshWasSignedIn[] = "feed.last_refresh_was_signed_in";
 const char kNoticeCardViewsCount[] = "feed.notice_card_views_count";
 const char kNoticeCardClicksCount[] = "feed.notice_card_clicks_count";
 
@@ -52,14 +36,43 @@
 
 }  // namespace prefs
 
+// Deprecated prefs:
+namespace {
+const char kLastRefreshWasSignedIn[] = "feed.last_refresh_was_signed_in";
+const char kBackgroundRefreshPeriod[] = "feed.background_refresh_period";
+const char kThrottlerRequestCount[] = "feed.refresh_throttler.count";
+const char kThrottlerRequestsDay[] = "feed.refresh_throttler.day";
+const char kUserClassifierAverageSuggestionsViwedPerHour[] =
+    "feed.user_classifier.average_suggestions_veiwed_per_hour";
+const char kUserClassifierAverageSuggestionsUsedPerHour[] =
+    "feed.user_classifier.average_suggestions_used_per_hour";
+
+const char kUserClassifierLastTimeToViewSuggestions[] =
+    "feed.user_classifier.last_time_to_view_suggestions";
+const char kUserClassifierLastTimeToUseSuggestions[] =
+    "feed.user_classifier.last_time_to_use_suggestions";
+
+void RegisterObsoletePrefsFeb_2021(PrefRegistrySimple* registry) {
+  registry->RegisterBooleanPref(kLastRefreshWasSignedIn, false);
+  registry->RegisterTimeDeltaPref(kBackgroundRefreshPeriod, base::TimeDelta());
+  registry->RegisterIntegerPref(kThrottlerRequestCount, 0);
+  registry->RegisterIntegerPref(kThrottlerRequestsDay, 0);
+
+  registry->RegisterDoublePref(kUserClassifierAverageSuggestionsViwedPerHour,
+                               0.0);
+  registry->RegisterDoublePref(kUserClassifierAverageSuggestionsUsedPerHour,
+                               0.0);
+  registry->RegisterTimePref(kUserClassifierLastTimeToViewSuggestions,
+                             base::Time());
+  registry->RegisterTimePref(kUserClassifierLastTimeToUseSuggestions,
+                             base::Time());
+}
+}  // namespace
+
 void RegisterProfilePrefs(PrefRegistrySimple* registry) {
   registry->RegisterStringPref(feed::prefs::kHostOverrideHost, "");
   registry->RegisterStringPref(feed::prefs::kHostOverrideBlessNonce, "");
-  registry->RegisterIntegerPref(feed::prefs::kThrottlerRequestCount, 0);
-  registry->RegisterIntegerPref(feed::prefs::kThrottlerRequestsDay, 0);
   registry->RegisterTimePref(prefs::kLastFetchAttemptTime, base::Time());
-  registry->RegisterTimeDeltaPref(prefs::kBackgroundRefreshPeriod,
-                                  base::TimeDelta());
   registry->RegisterListPref(feed::prefs::kThrottlerRequestCountListPrefName);
   registry->RegisterTimePref(feed::prefs::kThrottlerLastRequestTime,
                              base::Time());
@@ -71,10 +84,23 @@
   registry->RegisterBooleanPref(
       feed::prefs::kHasReachedClickAndViewActionsUploadConditions, false);
   registry->RegisterBooleanPref(feed::prefs::kLastFetchHadNoticeCard, true);
-  registry->RegisterBooleanPref(feed::prefs::kLastRefreshWasSignedIn, false);
+
   registry->RegisterIntegerPref(feed::prefs::kNoticeCardViewsCount, 0);
   registry->RegisterIntegerPref(feed::prefs::kNoticeCardClicksCount, 0);
-  UserClassifier::RegisterProfilePrefs(registry);
+
+  RegisterObsoletePrefsFeb_2021(registry);
+}
+
+void MigrateObsoleteProfilePrefsFeb_2021(PrefService* prefs) {
+  prefs->ClearPref(kLastRefreshWasSignedIn);
+  prefs->ClearPref(kBackgroundRefreshPeriod);
+  prefs->ClearPref(kThrottlerRequestCount);
+  prefs->ClearPref(kThrottlerRequestsDay);
+
+  prefs->ClearPref(kUserClassifierAverageSuggestionsViwedPerHour);
+  prefs->ClearPref(kUserClassifierAverageSuggestionsUsedPerHour);
+  prefs->ClearPref(kUserClassifierLastTimeToViewSuggestions);
+  prefs->ClearPref(kUserClassifierLastTimeToUseSuggestions);
 }
 
 }  // namespace feed
diff --git a/components/feed/core/common/pref_names.h b/components/feed/core/common/pref_names.h
index 93116f5..a66cca68 100644
--- a/components/feed/core/common/pref_names.h
+++ b/components/feed/core/common/pref_names.h
@@ -6,37 +6,15 @@
 #define COMPONENTS_FEED_CORE_COMMON_PREF_NAMES_H_
 
 class PrefRegistrySimple;
+class PrefService;
 
 namespace feed {
 
 namespace prefs {
 
-// The pref name for the period of time between background refreshes.
-extern const char kBackgroundRefreshPeriod[];
-
 // The pref name for the last time when a background fetch was attempted.
 extern const char kLastFetchAttemptTime[];
 
-// The pref name for today's count of RefreshThrottler requests, so far.
-extern const char kThrottlerRequestCount[];
-// The pref name for the current day for the counter of RefreshThrottler's
-// requests.
-extern const char kThrottlerRequestsDay[];
-
-// The pref name for the discounted average number of browsing sessions per hour
-// that involve opening a new NTP.
-extern const char kUserClassifierAverageSuggestionsViwedPerHour[];
-// The pref name for the discounted average number of browsing sessions per hour
-// that involve using content suggestions (i.e. opening one or clicking on the
-// "More" button).
-extern const char kUserClassifierAverageSuggestionsUsedPerHour[];
-
-// The pref name for the last time a surface was shown that displayed
-// suggestions to the user.
-extern const char kUserClassifierLastTimeToViewSuggestions[];
-// The pref name for the last time content suggestions were used by the user.
-extern const char kUserClassifierLastTimeToUseSuggestions[];
-
 // The pref name for the feed host override.
 extern const char kHostOverrideHost[];
 // The pref name for the feed host override auth token.
@@ -56,10 +34,6 @@
 // detected.
 extern const char kLastFetchHadNoticeCard[];
 
-// The pref name for the bit that determines whether the last refresh request
-// was signed in. Currently only used in V1.
-extern const char kLastRefreshWasSignedIn[];
-
 // The pref name for the counter for the number of views on the notice card.
 extern const char kNoticeCardViewsCount[];
 
@@ -86,6 +60,7 @@
 }  // namespace prefs
 
 void RegisterProfilePrefs(PrefRegistrySimple* registry);
+void MigrateObsoleteProfilePrefsFeb_2021(PrefService* prefs);
 
 }  // namespace feed
 
diff --git a/components/feed/core/common/refresh_throttler.cc b/components/feed/core/common/refresh_throttler.cc
deleted file mode 100644
index b121d1a..0000000
--- a/components/feed/core/common/refresh_throttler.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/common/refresh_throttler.h"
-
-#include <limits>
-#include <set>
-#include <utility>
-#include <vector>
-
-#include "base/metrics/field_trial_params.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_base.h"
-#include "base/strings/stringprintf.h"
-#include "base/time/clock.h"
-#include "components/feed/core/common/pref_names.h"
-#include "components/feed/feed_feature_list.h"
-#include "components/prefs/pref_service.h"
-
-namespace feed {
-
-namespace {
-
-// Values correspond to ntp_snippets::RequestStatus and histograms.xml
-enum class RequestStatus {
-  kObsolete1 = 0,
-  kQuotaGranted = 1,
-  kQuotaExceeded = 2,
-  kObsolete2 = 3,
-  kStatusCount = 4
-};
-
-// When adding a new type here, extend also the "RequestThrottlerTypes"
-// <histogram_suffixes> in histograms.xml with the |name| string. First value in
-// the pair is the name, second is the default requests per day.
-std::pair<std::string, int> GetThrottlerParams(UserClass user_class) {
-  switch (user_class) {
-    case UserClass::kRareSuggestionsViewer:
-      return {"SuggestionFetcherRareNTPUser", 5};
-    case UserClass::kActiveSuggestionsViewer:
-      return {"SuggestionFetcherActiveNTPUser", 20};
-    case UserClass::kActiveSuggestionsConsumer:
-      return {"SuggestionFetcherActiveSuggestionsConsumer", 20};
-  }
-}
-
-}  // namespace
-
-RefreshThrottler::RefreshThrottler(UserClass user_class,
-                                   PrefService* pref_service,
-                                   const base::Clock* clock)
-    : pref_service_(pref_service), clock_(clock) {
-  DCHECK(pref_service);
-  DCHECK(clock);
-
-  std::pair<std::string, int> throttler_params = GetThrottlerParams(user_class);
-  name_ = throttler_params.first;
-  max_requests_per_day_ = base::GetFieldTrialParamByFeatureAsInt(
-      kInterestFeedContentSuggestions,
-      base::StringPrintf("quota_%s", name_.c_str()), throttler_params.second);
-
-  // Since the histogram names are dynamic, we cannot use the standard macros
-  // and we need to lookup the histograms, instead.
-  int status_count = static_cast<int>(RequestStatus::kStatusCount);
-  // Corresponds to UMA_HISTOGRAM_ENUMERATION(name, sample, |status_count|).
-  histogram_request_status_ = base::LinearHistogram::FactoryGet(
-      base::StringPrintf("NewTabPage.RequestThrottler.RequestStatus_%s",
-                         name_.c_str()),
-      1, status_count, status_count + 1,
-      base::HistogramBase::kUmaTargetedHistogramFlag);
-  // Corresponds to UMA_HISTOGRAM_COUNTS_100(name, sample).
-  histogram_per_day_ = base::Histogram::FactoryGet(
-      base::StringPrintf("NewTabPage.RequestThrottler.PerDay_%s",
-                         name_.c_str()),
-      1, 100, 50, base::HistogramBase::kUmaTargetedHistogramFlag);
-}
-
-bool RefreshThrottler::RequestQuota() {
-  ResetCounterIfDayChanged();
-
-  // Increment |new_count| in a overflow safe fashion.
-  int new_count = GetCount();
-  if (new_count < std::numeric_limits<int>::max()) {
-    new_count++;
-  }
-  SetCount(new_count);
-  bool available = (new_count <= GetQuota());
-
-  histogram_request_status_->Add(
-      static_cast<int>(available ? RequestStatus::kQuotaGranted
-                                 : RequestStatus::kQuotaExceeded));
-
-  return available;
-}
-
-void RefreshThrottler::ResetCounterIfDayChanged() {
-  // Grant new quota on local midnight to spread out when clients that start
-  // making un-throttled requests to server.
-  int now_day = clock_->Now().LocalMidnight().since_origin().InDays();
-
-  if (!HasDay()) {
-    // The counter is used for the first time in this profile.
-    SetDay(now_day);
-  } else if (now_day != GetDay()) {
-    // Day has changed - report the number of requests from the previous day.
-    histogram_per_day_->Add(GetCount());
-    // Reset the counters.
-    SetCount(0);
-    SetDay(now_day);
-  }
-}
-
-int RefreshThrottler::GetQuota() const {
-  return max_requests_per_day_;
-}
-
-int RefreshThrottler::GetCount() const {
-  return pref_service_->GetInteger(prefs::kThrottlerRequestCount);
-}
-
-void RefreshThrottler::SetCount(int count) {
-  pref_service_->SetInteger(prefs::kThrottlerRequestCount, count);
-}
-
-int RefreshThrottler::GetDay() const {
-  return pref_service_->GetInteger(prefs::kThrottlerRequestsDay);
-}
-
-void RefreshThrottler::SetDay(int day) {
-  pref_service_->SetInteger(prefs::kThrottlerRequestsDay, day);
-}
-
-bool RefreshThrottler::HasDay() const {
-  return pref_service_->HasPrefPath(prefs::kThrottlerRequestsDay);
-}
-
-}  // namespace feed
diff --git a/components/feed/core/common/refresh_throttler.h b/components/feed/core/common/refresh_throttler.h
deleted file mode 100644
index d854799..0000000
--- a/components/feed/core/common/refresh_throttler.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_COMMON_REFRESH_THROTTLER_H_
-#define COMPONENTS_FEED_CORE_COMMON_REFRESH_THROTTLER_H_
-
-#include <string>
-
-#include "base/macros.h"
-#include "components/feed/core/common/user_classifier.h"
-
-class PrefService;
-
-namespace base {
-class Clock;
-class HistogramBase;
-}  // namespace base
-
-namespace feed {
-
-// Counts requests to perform refreshes, compares them to a daily quota, and
-// reports them to UMA. In the application code, create one local instance for
-// each given throttler name, identified by the UserClass. Reports to the same
-// histograms that previous NTP implementation used:
-//  - "NewTabPage.RequestThrottler.RequestStatus_|name|" - status of each
-//  request;
-//  - "NewTabPage.RequestThrottler.PerDay_|name|" - the daily count of requests.
-class RefreshThrottler {
- public:
-  RefreshThrottler(UserClass user_class,
-                   PrefService* pref_service,
-                   const base::Clock* clock);
-
-  // Returns whether quota is available for another request, persists the usage
-  // of said quota, and reports this information to UMA.
-  bool RequestQuota();
-
- private:
-  // Also emits the PerDay histogram if the day changed.
-  void ResetCounterIfDayChanged();
-
-  int GetQuota() const;
-  int GetCount() const;
-  void SetCount(int count);
-  int GetDay() const;
-  void SetDay(int day);
-  bool HasDay() const;
-
-  // Provides durable storage.
-  PrefService* pref_service_;
-
-  // Used to access current time, injected for testing.
-  const base::Clock* clock_;
-
-  // The name used by this throttler, based off UserClass, which will be used as
-  // a suffix when constructing histogram or finch param names.
-  std::string name_;
-
-  // The total requests allowed before RequestQuota() starts returning false,
-  // reset every time |clock_| changes days. Read from a variation param during
-  // initialization.
-  int max_requests_per_day_;
-
-  // The histograms for reporting the requests of the given |type_|.
-  base::HistogramBase* histogram_request_status_;
-  base::HistogramBase* histogram_per_day_;
-
-  DISALLOW_COPY_AND_ASSIGN(RefreshThrottler);
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CORE_COMMON_REFRESH_THROTTLER_H_
diff --git a/components/feed/core/common/refresh_throttler_unittest.cc b/components/feed/core/common/refresh_throttler_unittest.cc
deleted file mode 100644
index 74ab0d4..0000000
--- a/components/feed/core/common/refresh_throttler_unittest.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/common/refresh_throttler.h"
-
-#include <limits>
-#include <memory>
-
-#include "base/test/scoped_feature_list.h"
-#include "base/test/simple_test_clock.h"
-#include "components/feed/core/common/pref_names.h"
-#include "components/feed/core/common/user_classifier.h"
-#include "components/feed/feed_feature_list.h"
-#include "components/prefs/testing_pref_service.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace feed {
-
-namespace {
-
-// Fixed "now" to make tests more deterministic.
-char kNowString[] = "2018-06-11 15:41";
-
-}  // namespace
-
-class RefreshThrottlerTest : public testing::Test {
- public:
-  RefreshThrottlerTest() {
-    feed::RegisterProfilePrefs(test_prefs_.registry());
-
-    base::Time now;
-    EXPECT_TRUE(base::Time::FromUTCString(kNowString, &now));
-    test_clock_.SetNow(now);
-
-    scoped_feature_list_.InitAndEnableFeatureWithParameters(
-        kInterestFeedContentSuggestions,
-        {{"quota_SuggestionFetcherActiveNTPUser", "2"}});
-
-    throttler_ = std::make_unique<RefreshThrottler>(
-        UserClass::kActiveSuggestionsViewer, &test_prefs_, &test_clock_);
-  }
-
- protected:
-  TestingPrefServiceSimple test_prefs_;
-  base::SimpleTestClock test_clock_;
-  std::unique_ptr<RefreshThrottler> throttler_;
-  base::test::ScopedFeatureList scoped_feature_list_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(RefreshThrottlerTest);
-};
-
-TEST_F(RefreshThrottlerTest, QuotaExceeded) {
-  EXPECT_TRUE(throttler_->RequestQuota());
-  EXPECT_TRUE(throttler_->RequestQuota());
-  EXPECT_FALSE(throttler_->RequestQuota());
-}
-
-TEST_F(RefreshThrottlerTest, QuotaIsPerDay) {
-  EXPECT_TRUE(throttler_->RequestQuota());
-  EXPECT_TRUE(throttler_->RequestQuota());
-  EXPECT_FALSE(throttler_->RequestQuota());
-
-  test_clock_.Advance(base::TimeDelta::FromDays(1));
-  EXPECT_TRUE(throttler_->RequestQuota());
-}
-
-TEST_F(RefreshThrottlerTest, RollOver) {
-  // Exhaust our quota so the for loop can verify everything as false.
-  EXPECT_TRUE(throttler_->RequestQuota());
-  EXPECT_TRUE(throttler_->RequestQuota());
-
-  test_clock_.SetNow(test_clock_.Now().LocalMidnight());
-  for (int i = 0; i < 24; i++) {
-    EXPECT_FALSE(throttler_->RequestQuota());
-    test_clock_.Advance(base::TimeDelta::FromHours(1));
-  }
-  EXPECT_TRUE(throttler_->RequestQuota());
-}
-
-TEST_F(RefreshThrottlerTest, Overflow) {
-  test_prefs_.SetInteger(prefs::kThrottlerRequestCount,
-                         std::numeric_limits<int>::max());
-  EXPECT_FALSE(throttler_->RequestQuota());
-  EXPECT_EQ(std::numeric_limits<int>::max(),
-            test_prefs_.GetInteger(prefs::kThrottlerRequestCount));
-}
-
-}  // namespace feed
diff --git a/components/feed/core/common/user_classifier.cc b/components/feed/core/common/user_classifier.cc
deleted file mode 100644
index 22628de..0000000
--- a/components/feed/core/common/user_classifier.cc
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/common/user_classifier.h"
-
-#include <algorithm>
-#include <cfloat>
-#include <cmath>
-#include <string>
-
-#include "base/metrics/histogram_macros.h"
-#include "base/numerics/ranges.h"
-#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/time/clock.h"
-#include "components/feed/core/common/pref_names.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/pref_service.h"
-
-namespace feed {
-
-namespace {
-
-// The discount rate for computing the discounted-average rates. Must be
-// strictly larger than 0 and strictly smaller than 1!
-constexpr double kDiscountRatePerDay = 0.25;
-static_assert(kDiscountRatePerDay > 0 && kDiscountRatePerDay < 1,
-              "invalid value");
-// Compute discount_rate_per_hour such that
-//   kDiscountRatePerDay = 1 - e^{-kDiscountRatePerHour * 24}.
-const double kDiscountRatePerHour =
-    std::log(1.0 / (1.0 - kDiscountRatePerDay)) / 24.0;
-
-// Never consider any larger interval than this (so that extreme situations such
-// as losing your phone or going for a long offline vacation do not skew the
-// average too much).
-const double kMaxHours = 7 * 24;
-
-// Ignore events within |kMinHours| hours since the last event (|kMinHours| is
-// the length of the browsing session where subsequent events of the same type
-// do not count again).
-const double kMinHours = 0.5;
-
-// Classification constants.
-const double kActiveConsumerClicksAtLeastOncePerHours = 96;
-const double kRareUserViewsAtMostOncePerHours = 96;
-
-// Histograms for logging the estimated average hours to next event. During
-// launch these must match legacy histogram names.
-const char kHistogramAverageHoursToOpenNTP[] =
-    "NewTabPage.UserClassifier.AverageHoursToOpenNTP";
-const char kHistogramAverageHoursToUseSuggestions[] =
-    "NewTabPage.UserClassifier.AverageHoursToUseSuggestions";
-
-// List of all Events used for iteration.
-const UserClassifier::Event kEvents[] = {
-    UserClassifier::Event::kSuggestionsViewed,
-    UserClassifier::Event::kSuggestionsUsed};
-static_assert(base::size(kEvents) ==
-                  static_cast<int>(UserClassifier::Event::kMaxValue) + 1,
-              "kEvents should have all enum values.");
-
-const char* GetRateKey(UserClassifier::Event event) {
-  switch (event) {
-    case UserClassifier::Event::kSuggestionsViewed:
-      return prefs::kUserClassifierAverageSuggestionsViwedPerHour;
-    case UserClassifier::Event::kSuggestionsUsed:
-      return prefs::kUserClassifierAverageSuggestionsUsedPerHour;
-  }
-}
-
-const char* GetLastTimeKey(UserClassifier::Event event) {
-  switch (event) {
-    case UserClassifier::Event::kSuggestionsViewed:
-      return prefs::kUserClassifierLastTimeToViewSuggestions;
-    case UserClassifier::Event::kSuggestionsUsed:
-      return prefs::kUserClassifierLastTimeToUseSuggestions;
-  }
-}
-
-double GetInitialHoursBetweenEvents(UserClassifier::Event event) {
-  switch (event) {
-    case UserClassifier::Event::kSuggestionsViewed:
-      return 24;
-    case UserClassifier::Event::kSuggestionsUsed:
-      return 120;
-  }
-}
-
-// Returns the new value of the rate using its |old_value|, assuming
-// |hours_since_last_time| hours have passed since it was last discounted.
-double DiscountRate(double old_value,
-                    double hours_since_last_time,
-                    double discount_rate_per_hour) {
-  // Compute the new discounted average according to the formula
-  //   avg_events := e^{-discount_rate_per_hour * hours_since} * avg_events
-  return std::exp(-discount_rate_per_hour * hours_since_last_time) * old_value;
-}
-
-// Compute the number of hours between two events for the given rate value
-// assuming the events were equally distributed.
-double GetEstimateHoursBetweenEvents(double rate,
-                                     double discount_rate_per_hour,
-                                     double min_hours,
-                                     double max_hours) {
-  // The computation below is well-defined only for |rate| > 1 (log of
-  // negative value or division by zero). When |rate| -> 1, the estimate
-  // below -> infinity, so max_hours is a natural result, here.
-  if (rate <= 1) {
-    return max_hours;
-  }
-
-  // This is the estimate with the assumption that last event happened right
-  // now and the system is in the steady-state. Solve estimate_hours in the
-  // steady-state equation:
-  //   rate = 1 + e^{-discount_rate * estimate_hours} * rate,
-  // i.e.
-  //   -discount_rate * estimate_hours = log((rate - 1) / rate),
-  //   discount_rate * estimate_hours = log(rate / (rate - 1)),
-  //   estimate_hours = log(rate / (rate - 1)) / discount_rate.
-  double estimate_hours = std::log(rate / (rate - 1)) / discount_rate_per_hour;
-  return base::ClampToRange(estimate_hours, min_hours, max_hours);
-}
-
-// The inverse of GetEstimateHoursBetweenEvents().
-double GetRateForEstimateHoursBetweenEvents(double estimate_hours,
-                                            double discount_rate_per_hour,
-                                            double min_hours,
-                                            double max_hours) {
-  // Keep the input value within [min_hours, max_hours].
-  estimate_hours = base::ClampToRange(estimate_hours, min_hours, max_hours);
-  // Return |rate| such that GetEstimateHoursBetweenEvents for |rate| returns
-  // |estimate_hours|. Thus, solve |rate| in
-  //   rate = 1 + e^{-discount_rate * estimate_hours} * rate,
-  // i.e.
-  //   rate * (1 - e^{-discount_rate * estimate_hours}) = 1,
-  //   rate = 1 / (1 - e^{-discount_rate * estimate_hours}).
-  return 1.0 / (1.0 - std::exp(-discount_rate_per_hour * estimate_hours));
-}
-
-}  // namespace
-
-UserClassifier::UserClassifier(PrefService* pref_service,
-                               const base::Clock* clock)
-    : pref_service_(pref_service), clock_(clock) {
-  // The pref_service_ can be null in tests.
-  if (!pref_service_) {
-    return;
-  }
-
-  // TODO(jkrcal): Store the current discount rate per hour into prefs. If it
-  // differs from the previous value, rescale the rate values so that the
-  // expectation does not change abruptly!
-
-  // Initialize the prefs storing the last time: the counter has just started!
-  for (const Event event : kEvents) {
-    if (!HasLastTime(event)) {
-      SetLastTimeToNow(event);
-    }
-  }
-}
-
-UserClassifier::~UserClassifier() = default;
-
-// static
-void UserClassifier::RegisterProfilePrefs(PrefRegistrySimple* registry) {
-  for (Event event : kEvents) {
-    double default_rate = GetRateForEstimateHoursBetweenEvents(
-        GetInitialHoursBetweenEvents(event), kDiscountRatePerHour, kMinHours,
-        kMaxHours);
-    registry->RegisterDoublePref(GetRateKey(event), default_rate);
-    registry->RegisterTimePref(GetLastTimeKey(event), base::Time());
-  }
-}
-
-void UserClassifier::OnEvent(Event event) {
-  double metric_value = UpdateRateOnEvent(event);
-  double avg = GetEstimateHoursBetweenEvents(metric_value, kDiscountRatePerHour,
-                                             kMinHours, kMaxHours);
-  // We use kMaxHours as the max value below as the maximum value for the
-  // histograms must be constant.
-  switch (event) {
-    case Event::kSuggestionsViewed:
-      UMA_HISTOGRAM_CUSTOM_COUNTS(kHistogramAverageHoursToOpenNTP, avg, 1,
-                                  kMaxHours, 50);
-      break;
-    case Event::kSuggestionsUsed:
-      UMA_HISTOGRAM_CUSTOM_COUNTS(kHistogramAverageHoursToUseSuggestions, avg,
-                                  1, kMaxHours, 50);
-      break;
-  }
-}
-
-double UserClassifier::GetEstimatedAvgTime(Event event) const {
-  double rate = GetUpToDateRate(event);
-  return GetEstimateHoursBetweenEvents(rate, kDiscountRatePerHour, kMinHours,
-                                       kMaxHours);
-}
-
-UserClass UserClassifier::GetUserClass() const {
-  // The pref_service_ can be null in tests.
-  if (!pref_service_) {
-    return UserClass::kActiveSuggestionsViewer;
-  }
-
-  if (GetEstimatedAvgTime(Event::kSuggestionsViewed) >=
-      kRareUserViewsAtMostOncePerHours) {
-    return UserClass::kRareSuggestionsViewer;
-  }
-
-  if (GetEstimatedAvgTime(Event::kSuggestionsUsed) <=
-      kActiveConsumerClicksAtLeastOncePerHours) {
-    return UserClass::kActiveSuggestionsConsumer;
-  }
-
-  return UserClass::kActiveSuggestionsViewer;
-}
-
-std::string UserClassifier::GetUserClassDescriptionForDebugging() const {
-  switch (GetUserClass()) {
-    case UserClass::kRareSuggestionsViewer:
-      return "Rare viewer of Feed articles";
-    case UserClass::kActiveSuggestionsViewer:
-      return "Active viewer of Feed articles";
-    case UserClass::kActiveSuggestionsConsumer:
-      return "Active consumer of Feed articles";
-  }
-  NOTREACHED();
-  return std::string();
-}
-
-void UserClassifier::ClearClassificationForDebugging() {
-  // The pref_service_ can be null in tests.
-  if (!pref_service_) {
-    return;
-  }
-
-  for (const Event& event : kEvents) {
-    ClearRate(event);
-    SetLastTimeToNow(event);
-  }
-}
-
-double UserClassifier::UpdateRateOnEvent(Event event) {
-  // The pref_service_ can be null in tests.
-  if (!pref_service_) {
-    return 0;
-  }
-
-  double hours_since_last_time =
-      std::min(kMaxHours, GetHoursSinceLastTime(event));
-  // Ignore events within the same "browsing session".
-  if (hours_since_last_time < kMinHours) {
-    return GetUpToDateRate(event);
-  }
-
-  SetLastTimeToNow(event);
-
-  double rate = GetRate(event);
-  // Add 1 to the discounted rate as the event has happened right now.
-  double new_rate =
-      1 + DiscountRate(rate, hours_since_last_time, kDiscountRatePerHour);
-  SetRate(event, new_rate);
-  return new_rate;
-}
-
-double UserClassifier::GetUpToDateRate(Event event) const {
-  // The pref_service_ can be null in tests.
-  if (!pref_service_) {
-    return 0;
-  }
-
-  const double hours_since_last_time =
-      std::min(kMaxHours, GetHoursSinceLastTime(event));
-
-  const double rate = GetRate(event);
-  return DiscountRate(rate, hours_since_last_time, kDiscountRatePerHour);
-}
-
-double UserClassifier::GetHoursSinceLastTime(Event event) const {
-  if (!HasLastTime(event)) {
-    return 0;
-  }
-
-  const base::TimeDelta since_last_time =
-      clock_->Now() - pref_service_->GetTime(GetLastTimeKey(event));
-  return since_last_time / base::TimeDelta::FromHours(1);
-}
-
-bool UserClassifier::HasLastTime(Event event) const {
-  return pref_service_->HasPrefPath(GetLastTimeKey(event));
-}
-
-void UserClassifier::SetLastTimeToNow(Event event) {
-  pref_service_->SetTime(GetLastTimeKey(event), clock_->Now());
-}
-
-double UserClassifier::GetRate(Event event) const {
-  return pref_service_->GetDouble(GetRateKey(event));
-}
-
-void UserClassifier::SetRate(Event event, double rate) {
-  pref_service_->SetDouble(GetRateKey(event), rate);
-}
-
-void UserClassifier::ClearRate(Event event) {
-  pref_service_->ClearPref(GetRateKey(event));
-}
-
-}  // namespace feed
diff --git a/components/feed/core/common/user_classifier.h b/components/feed/core/common/user_classifier.h
deleted file mode 100644
index 154df8b..0000000
--- a/components/feed/core/common/user_classifier.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_COMMON_USER_CLASSIFIER_H_
-#define COMPONENTS_FEED_CORE_COMMON_USER_CLASSIFIER_H_
-
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-#include "components/feed/core/common/enums.h"
-
-class PrefRegistrySimple;
-class PrefService;
-
-namespace base {
-class Clock;
-}  // namespace base
-
-namespace feed {
-
-// Collects data about user usage patterns of content suggestions, computes
-// long-term user rates locally using pref, and reports the metrics to UMA.
-// Based on these long-term user rates, it classifies the user in a UserClass.
-class UserClassifier {
- public:
-  // For estimating the average length of the intervals between two successive
-  // events, we keep a simple frequency model, a single value that we call
-  // "rate" below.
-  // We track exponentially-discounted rate of the given event per hour where
-  // the continuous utility function between two successive events (e.g. opening
-  // a NTP) at times t1 < t2 is 1 / (t2-t1), i.e. intuitively the rate of this
-  // event in this time interval.
-  // See https://en.wikipedia.org/wiki/Exponential_discounting for more details.
-  // We keep track of the following events.
-  // NOTE: if you add any element, add it also in the static arrays in .cc and
-  // create another histogram.
-  enum class Event {
-    kSuggestionsViewed = 0,  // When the user opens a surface that is showing
-                             // suggestions, such as the NTP. This indicates
-                             // potential use of content suggestions.
-    kSuggestionsUsed = 1,    // When the user clicks on some suggestions or on
-                             // the "More" button.
-    kMaxValue = kSuggestionsUsed
-  };
-
-  // The provided |pref_service| may be nullptr in unit-tests.
-  UserClassifier(PrefService* pref_service, const base::Clock* clock);
-  virtual ~UserClassifier();
-
-  // Registers profile prefs for all rates. Called from pref_names.cc.
-  static void RegisterProfilePrefs(PrefRegistrySimple* registry);
-
-  // Informs the UserClassifier about a new event for |event|. The
-  // classification is based on these calls.
-  void OnEvent(Event event);
-
-  // Get the estimate average length of the interval between two successive
-  // events of the given type.
-  double GetEstimatedAvgTime(Event event) const;
-
-  // Return the classification of the current user.
-  // Virtual for testing.
-  virtual UserClass GetUserClass() const;
-  std::string GetUserClassDescriptionForDebugging() const;
-
-  // Resets the classification (emulates a fresh upgrade / install).
-  void ClearClassificationForDebugging();
-
- private:
-  // The event has happened, recompute the rate accordingly. Then store and
-  // return the new rate.
-  double UpdateRateOnEvent(Event event);
-  // No event has happened but we need to get up-to-date rate, recompute and
-  // return the new rate. This function does not store the recomputed rate.
-  double GetUpToDateRate(Event event) const;
-
-  // Returns the number of hours since the last event of the same type. If there
-  // is no last event of that type, assume it happened just now and return 0.
-  double GetHoursSinceLastTime(Event event) const;
-  bool HasLastTime(Event event) const;
-  void SetLastTimeToNow(Event event);
-
-  double GetRate(Event event) const;
-  void SetRate(Event event, double rate);
-  void ClearRate(Event event);
-
-  PrefService* pref_service_;
-  const base::Clock* clock_;
-
-  DISALLOW_COPY_AND_ASSIGN(UserClassifier);
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CORE_COMMON_USER_CLASSIFIER_H_
diff --git a/components/feed/core/common/user_classifier_unittest.cc b/components/feed/core/common/user_classifier_unittest.cc
deleted file mode 100644
index 6d0eebb..0000000
--- a/components/feed/core/common/user_classifier_unittest.cc
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/common/user_classifier.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/simple_test_clock.h"
-#include "base/time/time.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/testing_pref_service.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::DoubleNear;
-using testing::Eq;
-using testing::Gt;
-using testing::Lt;
-using testing::SizeIs;
-
-namespace feed {
-
-namespace {
-
-char kNowString[] = "2017-03-01 10:45";
-
-class FeedUserClassifierTest : public testing::Test {
- public:
-  FeedUserClassifierTest() {
-    UserClassifier::RegisterProfilePrefs(test_prefs_.registry());
-  }
-
-  UserClassifier* CreateUserClassifier() {
-    base::Time now;
-    CHECK(base::Time::FromUTCString(kNowString, &now));
-    test_clock_.SetNow(now);
-
-    user_classifier_ =
-        std::make_unique<UserClassifier>(&test_prefs_, &test_clock_);
-    return user_classifier_.get();
-  }
-
-  base::SimpleTestClock* test_clock() { return &test_clock_; }
-
- private:
-  TestingPrefServiceSimple test_prefs_;
-  std::unique_ptr<UserClassifier> user_classifier_;
-  base::SimpleTestClock test_clock_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedUserClassifierTest);
-};
-
-TEST_F(FeedUserClassifierTest, ShouldBeActiveSuggestionsViewerInitially) {
-  UserClassifier* user_classifier = CreateUserClassifier();
-  EXPECT_THAT(user_classifier->GetUserClass(),
-              Eq(UserClass::kActiveSuggestionsViewer));
-}
-
-TEST_F(FeedUserClassifierTest,
-       ShouldBecomeActiveSuggestionsConsumerByClickingOften) {
-  UserClassifier* user_classifier = CreateUserClassifier();
-
-  // After one click still only an active user.
-  user_classifier->OnEvent(UserClassifier::Event::kSuggestionsUsed);
-  EXPECT_THAT(user_classifier->GetUserClass(),
-              Eq(UserClass::kActiveSuggestionsViewer));
-
-  // After a few more clicks, become an active consumer.
-  for (int i = 0; i < 5; i++) {
-    test_clock()->Advance(base::TimeDelta::FromHours(1));
-    user_classifier->OnEvent(UserClassifier::Event::kSuggestionsUsed);
-  }
-  EXPECT_THAT(user_classifier->GetUserClass(),
-              Eq(UserClass::kActiveSuggestionsConsumer));
-}
-
-TEST_F(FeedUserClassifierTest,
-       ShouldBecomeRareSuggestionsViewerUserByNoActivity) {
-  UserClassifier* user_classifier = CreateUserClassifier();
-
-  // After two days of waiting still an active user.
-  test_clock()->Advance(base::TimeDelta::FromDays(2));
-  EXPECT_THAT(user_classifier->GetUserClass(),
-              Eq(UserClass::kActiveSuggestionsViewer));
-
-  // Two more days to become a rare user.
-  test_clock()->Advance(base::TimeDelta::FromDays(2));
-  EXPECT_THAT(user_classifier->GetUserClass(),
-              Eq(UserClass::kRareSuggestionsViewer));
-}
-
-class FeedUserClassifierEventTest
-    : public FeedUserClassifierTest,
-      public ::testing::WithParamInterface<
-          std::pair<UserClassifier::Event, std::string>> {
- public:
-  FeedUserClassifierEventTest() {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FeedUserClassifierEventTest);
-};
-
-TEST_P(FeedUserClassifierEventTest, ShouldDecreaseEstimateAfterEvent) {
-  UserClassifier::Event event = GetParam().first;
-  UserClassifier* user_classifier = CreateUserClassifier();
-
-  // The initial event. does not decrease the estimate.
-  user_classifier->OnEvent(event);
-
-  for (int i = 0; i < 10; i++) {
-    test_clock()->Advance(base::TimeDelta::FromHours(1));
-    double old_rate = user_classifier->GetEstimatedAvgTime(event);
-    user_classifier->OnEvent(event);
-    EXPECT_THAT(user_classifier->GetEstimatedAvgTime(event), Lt(old_rate));
-  }
-}
-
-TEST_P(FeedUserClassifierEventTest, ShouldReportToUmaOnEvent) {
-  UserClassifier::Event event = GetParam().first;
-  const std::string& histogram_name = GetParam().second;
-  base::HistogramTester histogram_tester;
-  UserClassifier* user_classifier = CreateUserClassifier();
-
-  user_classifier->OnEvent(event);
-  EXPECT_THAT(histogram_tester.GetAllSamples(histogram_name), SizeIs(1));
-}
-
-TEST_P(FeedUserClassifierEventTest, ShouldConvergeTowardsPattern) {
-  UserClassifier::Event event = GetParam().first;
-  UserClassifier* user_classifier = CreateUserClassifier();
-
-  // Have the pattern of an event every five hours and start changing it towards
-  // an event every 10 hours.
-  for (int i = 0; i < 100; i++) {
-    test_clock()->Advance(base::TimeDelta::FromHours(5));
-    user_classifier->OnEvent(event);
-  }
-  EXPECT_THAT(user_classifier->GetEstimatedAvgTime(event),
-              DoubleNear(5.0, 0.1));
-  for (int i = 0; i < 3; i++) {
-    test_clock()->Advance(base::TimeDelta::FromHours(10));
-    user_classifier->OnEvent(event);
-  }
-  EXPECT_THAT(user_classifier->GetEstimatedAvgTime(event), Gt(5.5));
-  for (int i = 0; i < 100; i++) {
-    test_clock()->Advance(base::TimeDelta::FromHours(10));
-    user_classifier->OnEvent(event);
-  }
-  EXPECT_THAT(user_classifier->GetEstimatedAvgTime(event),
-              DoubleNear(10.0, 0.1));
-}
-
-TEST_P(FeedUserClassifierEventTest, ShouldIgnoreSubsequentEventsForHalfAnHour) {
-  UserClassifier::Event event = GetParam().first;
-  UserClassifier* user_classifier = CreateUserClassifier();
-
-  // The initial event.
-  user_classifier->OnEvent(event);
-  // Subsequent events get ignored for the next 30 minutes.
-  for (int i = 0; i < 5; i++) {
-    test_clock()->Advance(base::TimeDelta::FromMinutes(5));
-    double old_rate = user_classifier->GetEstimatedAvgTime(event);
-    user_classifier->OnEvent(event);
-    EXPECT_THAT(user_classifier->GetEstimatedAvgTime(event), Eq(old_rate));
-  }
-  // An event 30 minutes after the initial event is finally not ignored.
-  test_clock()->Advance(base::TimeDelta::FromMinutes(5));
-  double old_rate = user_classifier->GetEstimatedAvgTime(event);
-  user_classifier->OnEvent(event);
-  EXPECT_THAT(user_classifier->GetEstimatedAvgTime(event), Lt(old_rate));
-}
-
-TEST_P(FeedUserClassifierEventTest, ShouldCapDelayBetweenEvents) {
-  UserClassifier::Event event = GetParam().first;
-  UserClassifier* user_classifier = CreateUserClassifier();
-
-  // The initial event.
-  user_classifier->OnEvent(event);
-  // Wait for an insane amount of time
-  test_clock()->Advance(base::TimeDelta::FromDays(365));
-  user_classifier->OnEvent(event);
-  double rate_after_a_year = user_classifier->GetEstimatedAvgTime(event);
-
-  // Now repeat the same with s/one year/one week.
-  user_classifier->ClearClassificationForDebugging();
-  user_classifier->OnEvent(event);
-  test_clock()->Advance(base::TimeDelta::FromDays(7));
-  user_classifier->OnEvent(event);
-
-  // The results should be the same.
-  EXPECT_THAT(user_classifier->GetEstimatedAvgTime(event),
-              Eq(rate_after_a_year));
-}
-
-INSTANTIATE_TEST_SUITE_P(
-    All,  // An empty prefix for the parametrized tests names (no need to
-          // distinguish the only instance we make here).
-    FeedUserClassifierEventTest,
-    testing::Values(
-        std::make_pair(UserClassifier::Event::kSuggestionsViewed,
-                       "NewTabPage.UserClassifier.AverageHoursToOpenNTP"),
-        std::make_pair(
-            UserClassifier::Event::kSuggestionsUsed,
-            "NewTabPage.UserClassifier.AverageHoursToUseSuggestions")));
-}  // namespace
-
-}  // namespace feed
diff --git a/components/feed/core/content_metadata.cc b/components/feed/core/content_metadata.cc
deleted file mode 100644
index 8f78ace..0000000
--- a/components/feed/core/content_metadata.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/content_metadata.h"
-
-namespace feed {
-
-ContentMetadata::ContentMetadata() = default;
-
-ContentMetadata::ContentMetadata(const ContentMetadata&) = default;
-
-ContentMetadata::ContentMetadata(ContentMetadata&&) = default;
-
-ContentMetadata::~ContentMetadata() = default;
-
-}  // namespace feed
diff --git a/components/feed/core/content_metadata.h b/components/feed/core/content_metadata.h
deleted file mode 100644
index bf31306cd..0000000
--- a/components/feed/core/content_metadata.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_CONTENT_METADATA_H_
-#define COMPONENTS_FEED_CORE_CONTENT_METADATA_H_
-
-#include <string>
-
-#include "base/time/time.h"
-
-namespace feed {
-
-// Native counterpart of ContentMetadata.java.
-struct ContentMetadata {
-  ContentMetadata();
-  ContentMetadata(const ContentMetadata&);
-  ContentMetadata(ContentMetadata&&);
-  ~ContentMetadata();
-
-  // A link to the underlying article.
-  std::string url;
-
-  // The title of the article.
-  std::string title;
-
-  // The time the article was published, independent of when the device was
-  // downloaded this metadata.
-  base::Time time_published;
-
-  // A link to a thumbnail.
-  std::string image_url;
-
-  // The name of the publisher.
-  std::string publisher;
-
-  // A link to the favicon for the publisher's domain.
-  std::string favicon_url;
-
-  // A short description of the article, human readable.
-  std::string snippet;
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CORE_CONTENT_METADATA_H_
diff --git a/components/feed/core/feed_content_database.cc b/components/feed/core/feed_content_database.cc
deleted file mode 100644
index df1d058..0000000
--- a/components/feed/core/feed_content_database.cc
+++ /dev/null
@@ -1,369 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_content_database.h"
-
-#include <unordered_set>
-
-#include "base/bind.h"
-#include "base/files/file_path.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/string_util.h"
-#include "base/system/sys_info.h"
-#include "base/task/post_task.h"
-#include "base/task/thread_pool.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/feed/core/feed_content_mutation.h"
-#include "components/feed/core/feed_content_operation.h"
-#include "components/feed/core/proto/content_storage.pb.h"
-#include "components/leveldb_proto/public/proto_database_provider.h"
-
-namespace feed {
-
-namespace {
-
-const char kContentDatabaseFolder[] = "content";
-
-// Content writes vary a lot in size, loading full page will will have a couple
-// dozen writes totaling a couple dozen KB, but there's a lot of variability.
-// This should result in some batching while also keeping the memory impact very
-// small.
-const size_t kDatabaseWriteBufferSizeBytes = 8 * 1024;                 // 8KB
-const size_t kDatabaseWriteBufferSizeBytesForLowEndDevice = 4 * 1024;  // 4KB
-
-leveldb::ReadOptions CreateReadOptions() {
-  leveldb::ReadOptions opts;
-  opts.fill_cache = false;
-  return opts;
-}
-
-bool DatabaseKeyFilter(const std::unordered_set<std::string>& key_set,
-                       const std::string& key) {
-  return key_set.find(key) != key_set.end();
-}
-
-bool DatabasePrefixFilter(const std::string& key_prefix,
-                          const std::string& key) {
-  return base::StartsWith(key, key_prefix, base::CompareCase::SENSITIVE);
-}
-
-}  // namespace
-
-FeedContentDatabase::FeedContentDatabase(
-    leveldb_proto::ProtoDatabaseProvider* proto_database_provider,
-    const base::FilePath& database_folder)
-    : database_status_(InitStatus::kNotInitialized),
-      task_runner_(base::ThreadPool::CreateSequencedTaskRunner(
-          {base::MayBlock(), base::TaskPriority::USER_VISIBLE})),
-      storage_database_(proto_database_provider->GetDB<ContentStorageProto>(
-          leveldb_proto::ProtoDbType::FEED_CONTENT_DATABASE,
-          database_folder.AppendASCII(kContentDatabaseFolder),
-          task_runner_)) {
-  task_runner_->PostTask(FROM_HERE,
-                         base::BindOnce(&FeedContentDatabase::InitInternal,
-                                        weak_ptr_factory_.GetWeakPtr()));
-}
-
-// Used for testing.
-FeedContentDatabase::FeedContentDatabase(
-    std::unique_ptr<leveldb_proto::ProtoDatabase<ContentStorageProto>>
-        storage_database,
-    scoped_refptr<base::SequencedTaskRunner> task_runner)
-    : database_status_(InitStatus::kNotInitialized),
-      task_runner_(task_runner),
-      storage_database_(std::move(storage_database)) {
-  task_runner_->PostTask(FROM_HERE,
-                         base::BindOnce(&FeedContentDatabase::InitInternal,
-                                        weak_ptr_factory_.GetWeakPtr()));
-}
-
-FeedContentDatabase::~FeedContentDatabase() = default;
-
-bool FeedContentDatabase::IsInitialized() const {
-  return database_status_ == InitStatus::kOK;
-}
-
-void FeedContentDatabase::InitInternal() {
-  leveldb_env::Options options = leveldb_proto::CreateSimpleOptions();
-  options.write_buffer_size = base::SysInfo::IsLowEndDevice()
-                                  ? kDatabaseWriteBufferSizeBytesForLowEndDevice
-                                  : kDatabaseWriteBufferSizeBytes;
-
-  storage_database_->Init(
-      options, base::BindOnce(&FeedContentDatabase::OnDatabaseInitialized,
-                              weak_ptr_factory_.GetWeakPtr()));
-}
-
-void FeedContentDatabase::LoadContent(const std::vector<std::string>& keys,
-                                      ContentLoadCallback callback) {
-  std::unordered_set<std::string> key_set(keys.begin(), keys.end());
-
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          &FeedContentDatabase::LoadEntriesWithFilterInternal,
-          weak_ptr_factory_.GetWeakPtr(),
-          base::BindRepeating(&DatabaseKeyFilter, std::move(key_set)),
-          std::move(callback)));
-}
-
-void FeedContentDatabase::LoadContentByPrefix(const std::string& prefix,
-                                              ContentLoadCallback callback) {
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          &FeedContentDatabase::LoadEntriesWithFilterInternal,
-          weak_ptr_factory_.GetWeakPtr(),
-          base::BindRepeating(&DatabasePrefixFilter, std::move(prefix)),
-          std::move(callback)));
-}
-
-void FeedContentDatabase::LoadEntriesWithFilterInternal(
-    const leveldb_proto::KeyFilter& key_filter,
-    ContentLoadCallback callback) {
-  storage_database_->LoadEntriesWithFilter(
-      std::move(key_filter), CreateReadOptions(), /* target_prefix */ "",
-      base::BindOnce(&FeedContentDatabase::OnLoadEntriesForLoadContent,
-                     weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(),
-                     std::move(callback)));
-}
-
-void FeedContentDatabase::LoadAllContentKeys(ContentKeyCallback callback) {
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&FeedContentDatabase::LoadKeysInternal,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-}
-
-void FeedContentDatabase::LoadKeysInternal(ContentKeyCallback callback) {
-  storage_database_->LoadKeys(
-      base::BindOnce(&FeedContentDatabase::OnLoadKeysForLoadAllContentKeys,
-                     weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(),
-                     std::move(callback)));
-}
-
-void FeedContentDatabase::CommitContentMutation(
-    std::unique_ptr<ContentMutation> content_mutation,
-    ConfirmationCallback callback) {
-  DCHECK(content_mutation);
-
-  UMA_HISTOGRAM_COUNTS_100(
-      "ContentSuggestions.Feed.ContentStorage.CommitMutationCount",
-      content_mutation->Size());
-
-  if (content_mutation->Empty()) {
-    task_runner_->PostTask(FROM_HERE,
-                           base::BindOnce(std::move(callback), true));
-    return;
-  }
-
-  PerformNextOperation(std::move(content_mutation), std::move(callback));
-}
-
-void FeedContentDatabase::PerformNextOperation(
-    std::unique_ptr<ContentMutation> content_mutation,
-    ConfirmationCallback callback) {
-  DCHECK(!content_mutation->Empty());
-
-  ContentOperation operation = content_mutation->TakeFirstOperation();
-
-  switch (operation.type()) {
-    case ContentOperation::CONTENT_DELETE:
-      // TODO(gangwu): If deletes are continuous, we should combine them into
-      // one commit.
-      DeleteContent(std::move(operation), std::move(content_mutation),
-                    std::move(callback));
-      break;
-    case ContentOperation::CONTENT_DELETE_BY_PREFIX:
-      DeleteContentByPrefix(std::move(operation), std::move(content_mutation),
-                            std::move(callback));
-      break;
-    case ContentOperation::CONTENT_UPSERT:
-      // TODO(gangwu): If upserts are continuous, we should combine them into
-      // one commit.
-      UpsertContent(std::move(operation), std::move(content_mutation),
-                    std::move(callback));
-      break;
-    case ContentOperation::CONTENT_DELETE_ALL:
-      DeleteAllContent(std::move(operation), std::move(content_mutation),
-                       std::move(callback));
-      break;
-    default:
-      // Operation type is not supported, therefore failing immediately.
-      task_runner_->PostTask(FROM_HERE,
-                             base::BindOnce(std::move(callback), false));
-  }
-}
-
-void FeedContentDatabase::UpsertContent(
-    ContentOperation operation,
-    std::unique_ptr<ContentMutation> content_mutation,
-    ConfirmationCallback callback) {
-  DCHECK_EQ(operation.type(), ContentOperation::CONTENT_UPSERT);
-
-  auto contents_to_save = std::make_unique<StorageEntryVector>();
-  ContentStorageProto proto;
-  proto.set_key(operation.key());
-  proto.set_content_data(operation.value());
-  contents_to_save->emplace_back(proto.key(), std::move(proto));
-
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&FeedContentDatabase::UpdateEntriesInternal,
-                     weak_ptr_factory_.GetWeakPtr(),
-                     std::move(contents_to_save),
-                     std::make_unique<std::vector<std::string>>(),
-                     std::move(content_mutation), std::move(callback)));
-}
-
-void FeedContentDatabase::DeleteContent(
-    ContentOperation operation,
-    std::unique_ptr<ContentMutation> content_mutation,
-    ConfirmationCallback callback) {
-  DCHECK_EQ(operation.type(), ContentOperation::CONTENT_DELETE);
-
-  auto content_to_delete = std::make_unique<std::vector<std::string>>(
-      std::initializer_list<std::string>({operation.key()}));
-
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&FeedContentDatabase::UpdateEntriesInternal,
-                     weak_ptr_factory_.GetWeakPtr(),
-                     std::make_unique<StorageEntryVector>(),
-                     std::move(content_to_delete), std::move(content_mutation),
-                     std::move(callback)));
-}
-
-void FeedContentDatabase::UpdateEntriesInternal(
-    std::unique_ptr<StorageEntryVector> entries_to_save,
-    std::unique_ptr<std::vector<std::string>> keys_to_remove,
-    std::unique_ptr<ContentMutation> content_mutation,
-    ConfirmationCallback callback) {
-  storage_database_->UpdateEntries(
-      std::move(entries_to_save), std::move(keys_to_remove),
-      base::BindOnce(&FeedContentDatabase::OnOperationCommitted,
-                     weak_ptr_factory_.GetWeakPtr(),
-                     std::move(content_mutation), std::move(callback)));
-}
-
-void FeedContentDatabase::DeleteContentByPrefix(
-    ContentOperation operation,
-    std::unique_ptr<ContentMutation> content_mutation,
-    ConfirmationCallback callback) {
-  DCHECK_EQ(operation.type(), ContentOperation::CONTENT_DELETE_BY_PREFIX);
-
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          &FeedContentDatabase::UpdateEntriesWithRemoveFilterInternal,
-          weak_ptr_factory_.GetWeakPtr(),
-          base::BindRepeating(&DatabasePrefixFilter, operation.prefix()),
-          std::move(content_mutation), std::move(callback)));
-}
-
-void FeedContentDatabase::DeleteAllContent(
-    ContentOperation operation,
-    std::unique_ptr<ContentMutation> content_mutation,
-    ConfirmationCallback callback) {
-  DCHECK_EQ(operation.type(), ContentOperation::CONTENT_DELETE_ALL);
-
-  std::string key_prefix = "";
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          &FeedContentDatabase::UpdateEntriesWithRemoveFilterInternal,
-          weak_ptr_factory_.GetWeakPtr(),
-          base::BindRepeating(&DatabasePrefixFilter, std::move(key_prefix)),
-          std::move(content_mutation), std::move(callback)));
-}
-
-void FeedContentDatabase::UpdateEntriesWithRemoveFilterInternal(
-    const leveldb_proto::KeyFilter& key_filter,
-    std::unique_ptr<ContentMutation> content_mutation,
-    ConfirmationCallback callback) {
-  storage_database_->UpdateEntriesWithRemoveFilter(
-      std::make_unique<StorageEntryVector>(), std::move(key_filter),
-      base::BindOnce(&FeedContentDatabase::OnOperationCommitted,
-                     weak_ptr_factory_.GetWeakPtr(),
-                     std::move(content_mutation), std::move(callback)));
-}
-
-void FeedContentDatabase::OnDatabaseInitialized(InitStatus status) {
-  DCHECK_EQ(database_status_, InitStatus::kNotInitialized);
-  database_status_ = status;
-}
-
-void FeedContentDatabase::OnLoadEntriesForLoadContent(
-    base::TimeTicks start_time,
-    ContentLoadCallback callback,
-    bool success,
-    std::unique_ptr<std::vector<ContentStorageProto>> content) {
-  base::TimeDelta load_time = base::TimeTicks::Now() - start_time;
-  UMA_HISTOGRAM_TIMES("ContentSuggestions.Feed.ContentStorage.LoadTime",
-                      load_time);
-
-  std::vector<KeyAndData> results;
-  if (success) {
-    for (const auto& proto : *content) {
-      DCHECK(proto.has_key());
-      DCHECK(proto.has_content_data());
-
-      results.emplace_back(proto.key(), proto.content_data());
-    }
-  }
-
-  std::move(callback).Run(success, std::move(results));
-}
-
-void FeedContentDatabase::OnLoadKeysForLoadAllContentKeys(
-    base::TimeTicks start_time,
-    ContentKeyCallback callback,
-    bool success,
-    std::unique_ptr<std::vector<std::string>> keys) {
-  if (success) {
-    // Typical usage has a max around 300(100 cards, 3 pieces of content per
-    // card), could grow forever through heavy usage of dismiss. If typically
-    // usage changes, 1000 maybe too small.
-    UMA_HISTOGRAM_COUNTS_1000("ContentSuggestions.Feed.ContentStorage.Count",
-                              keys->size());
-  }
-
-  base::TimeDelta load_time = base::TimeTicks::Now() - start_time;
-  UMA_HISTOGRAM_TIMES("ContentSuggestions.Feed.ContentStorage.LoadKeysTime",
-                      load_time);
-
-  // We std::move the |*keys|'s entries to |callback|, after that, |keys| become
-  // a pointer holding an empty vector, then we can safely delete unique_ptr
-  // |keys| when it out of scope.
-  std::move(callback).Run(success, std::move(*keys));
-}
-
-void FeedContentDatabase::OnOperationCommitted(
-    std::unique_ptr<ContentMutation> content_mutation,
-    ConfirmationCallback callback,
-    bool success) {
-  // Commit is unsuccessful, skip processing the other operations since
-  // ContentStorage.java requires "In the event of a failure, processing is
-  // halted immediately".
-  if (!success) {
-    std::move(callback).Run(success);
-    return;
-  }
-
-  // All operations were committed successfully, call |callback|.
-  if (content_mutation->Empty()) {
-    base::TimeDelta commit_time =
-        base::TimeTicks::Now() - content_mutation->GetStartTime();
-    UMA_HISTOGRAM_TIMES(
-        "ContentSuggestions.Feed.ContentStorage.OperationCommitTime",
-        commit_time);
-
-    std::move(callback).Run(success);
-    return;
-  }
-
-  PerformNextOperation(std::move(content_mutation), std::move(callback));
-}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_content_database.h b/components/feed/core/feed_content_database.h
deleted file mode 100644
index 0d951f3..0000000
--- a/components/feed/core/feed_content_database.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_FEED_CONTENT_DATABASE_H_
-#define COMPONENTS_FEED_CORE_FEED_CONTENT_DATABASE_H_
-
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/memory/weak_ptr.h"
-#include "base/sequenced_task_runner.h"
-#include "components/leveldb_proto/public/proto_database.h"
-
-namespace leveldb_proto {
-class ProtoDatabaseProvider;
-}  // namespace leveldb_proto
-
-namespace feed {
-
-class ContentMutation;
-class ContentOperation;
-class ContentStorageProto;
-
-using InitStatus = leveldb_proto::Enums::InitStatus;
-
-// FeedContentDatabase is leveldb backend store for Feed's content storage data.
-// Feed's content data are key-value pairs. In order to support callers from
-// different threads, this class posts all database operations to an owned
-// sequenced task runner.
-class FeedContentDatabase {
- public:
-  using KeyAndData = std::pair<std::string, std::string>;
-
-  // Returns the storage data as a vector of key-value pairs when calling
-  // loading data.
-  using ContentLoadCallback =
-      base::OnceCallback<void(bool, std::vector<KeyAndData>)>;
-
-  // Returns the content keys as a vector when calling loading all content keys.
-  using ContentKeyCallback =
-      base::OnceCallback<void(bool, std::vector<std::string>)>;
-
-  // Returns whether the commit operation succeeded when calling for database
-  // operations, or return whether the entry exists when calling for checking
-  // the entry's existence.
-  using ConfirmationCallback = base::OnceCallback<void(bool)>;
-
-  using StorageEntryVector =
-      leveldb_proto::ProtoDatabase<ContentStorageProto>::KeyEntryVector;
-
-  // Initializes the database with |proto_database_provider| and
-  // |database_folder|.
-  FeedContentDatabase(
-      leveldb_proto::ProtoDatabaseProvider* proto_database_provider,
-      const base::FilePath& database_folder);
-
-  // Creates storage using the given |storage_database| for local storage.
-  // Useful for testing.
-  explicit FeedContentDatabase(
-      std::unique_ptr<leveldb_proto::ProtoDatabase<ContentStorageProto>>
-          storage_database,
-      scoped_refptr<base::SequencedTaskRunner> task_runner);
-
-  ~FeedContentDatabase();
-
-  // Returns true if initialization has finished successfully, else false.
-  // While this is false, initialization may already started, or initialization
-  // failed.
-  bool IsInitialized() const;
-
-  // Loads the content data for the |keys| and passes them to |callback|.
-  void LoadContent(const std::vector<std::string>& keys,
-                   ContentLoadCallback callback);
-
-  // Loads the content data whose key matches |prefix|, and passes them to
-  // |callback|.
-  void LoadContentByPrefix(const std::string& prefix,
-                           ContentLoadCallback callback);
-
-  // Loads all content keys in the storage, and passes them to |callback|.
-  void LoadAllContentKeys(ContentKeyCallback callback);
-
-  // Commits the operations in the |content_mutation|. |callback| will be called
-  // when all the operations are committed. Or if any operation failed, database
-  // will stop process any operations and passed error to |callback|.
-  void CommitContentMutation(std::unique_ptr<ContentMutation> content_mutation,
-                             ConfirmationCallback callback);
-
- private:
-  // These methods work with |CommitContentMutation|. They process
-  // |ContentOperation| in |ContentMutation| which is passed to
-  // |PerformNextOperation| by |CommitContentMutation|.
-  void PerformNextOperation(std::unique_ptr<ContentMutation> content_mutation,
-                            ConfirmationCallback callback);
-  void UpsertContent(ContentOperation operation,
-                     std::unique_ptr<ContentMutation> content_mutation,
-                     ConfirmationCallback callback);
-  void DeleteContent(ContentOperation operation,
-                     std::unique_ptr<ContentMutation> content_mutation,
-                     ConfirmationCallback callback);
-  void DeleteContentByPrefix(ContentOperation operation,
-                             std::unique_ptr<ContentMutation> content_mutation,
-                             ConfirmationCallback callback);
-  void DeleteAllContent(ContentOperation operation,
-                        std::unique_ptr<ContentMutation> content_mutation,
-                        ConfirmationCallback callback);
-
-  // The following *Internal methods must be executed from |task_runner_|.
-  void InitInternal();
-  void LoadEntriesWithFilterInternal(const leveldb_proto::KeyFilter& key_filter,
-                                     ContentLoadCallback callback);
-  void LoadKeysInternal(ContentKeyCallback callback);
-  void UpdateEntriesInternal(
-      std::unique_ptr<StorageEntryVector> entries_to_save,
-      std::unique_ptr<std::vector<std::string>> keys_to_remove,
-      std::unique_ptr<ContentMutation> content_mutation,
-      ConfirmationCallback callback);
-  void UpdateEntriesWithRemoveFilterInternal(
-      const leveldb_proto::KeyFilter& key_filter,
-      std::unique_ptr<ContentMutation> content_mutation,
-      ConfirmationCallback callback);
-
-  // Callback methods given to |storage_database_| for async responses.
-  void OnDatabaseInitialized(InitStatus status);
-  void OnLoadEntriesForLoadContent(
-      base::TimeTicks start_time,
-      ContentLoadCallback callback,
-      bool success,
-      std::unique_ptr<std::vector<ContentStorageProto>> content);
-  void OnLoadKeysForLoadAllContentKeys(
-      base::TimeTicks start_time,
-      ContentKeyCallback callback,
-      bool success,
-      std::unique_ptr<std::vector<std::string>> keys);
-  void OnOperationCommitted(std::unique_ptr<ContentMutation> content_mutation,
-                            ConfirmationCallback callback,
-                            bool success);
-
-  // Status of the database initialization.
-  InitStatus database_status_;
-
-  // Task runner on which to execute database calls.
-  scoped_refptr<base::SequencedTaskRunner> task_runner_;
-
-  // The database for storing content storage information.
-  std::unique_ptr<leveldb_proto::ProtoDatabase<ContentStorageProto>>
-      storage_database_;
-
-  base::WeakPtrFactory<FeedContentDatabase> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FeedContentDatabase);
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CORE_FEED_CONTENT_DATABASE_H_
diff --git a/components/feed/core/feed_content_database_unittest.cc b/components/feed/core/feed_content_database_unittest.cc
deleted file mode 100644
index ab9e343..0000000
--- a/components/feed/core/feed_content_database_unittest.cc
+++ /dev/null
@@ -1,490 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_content_database.h"
-
-#include <map>
-
-#include "base/bind.h"
-#include "base/task/thread_pool.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/task_environment.h"
-#include "components/feed/core/feed_content_mutation.h"
-#include "components/feed/core/proto/content_storage.pb.h"
-#include "components/leveldb_proto/testing/fake_db.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using base::HistogramTester;
-using leveldb_proto::test::FakeDB;
-using testing::_;
-
-namespace feed {
-
-namespace {
-
-const char kContentKeyPrefix[] = "ContentKey";
-const char kContentKey1[] = "ContentKey1";
-const char kContentKey2[] = "ContentKey2";
-const char kContentKey3[] = "ContentKey3";
-const char kContentData1[] = "Content Data1";
-const char kContentData2[] = "Content Data2";
-
-const char kUmaCommitMutationSizeHistogramName[] =
-    "ContentSuggestions.Feed.ContentStorage.CommitMutationCount";
-const char kUmaLoadKeysTimeHistogramName[] =
-    "ContentSuggestions.Feed.ContentStorage.LoadKeysTime";
-const char kUmaLoadTimeHistogramName[] =
-    "ContentSuggestions.Feed.ContentStorage.LoadTime";
-const char kUmaOperationCommitTimeHistogramName[] =
-    "ContentSuggestions.Feed.ContentStorage.OperationCommitTime";
-const char kUmaSizeHistogramName[] =
-    "ContentSuggestions.Feed.ContentStorage.Count";
-
-}  // namespace
-
-class FeedContentDatabaseTest : public testing::Test {
- public:
-  FeedContentDatabaseTest() : content_db_(nullptr) {}
-
-  void CreateDatabase(bool init_database) {
-    // The FakeDBs are owned by |feed_db_|, so clear our pointers before
-    // resetting |feed_db_| itself.
-    content_db_ = nullptr;
-    // Explicitly destroy any existing database before creating a new one.
-    feed_db_.reset();
-
-    auto storage_db =
-        std::make_unique<FakeDB<ContentStorageProto>>(&content_db_storage_);
-
-    task_runner_ = base::ThreadPool::CreateSequencedTaskRunner(
-        {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
-
-    content_db_ = storage_db.get();
-    feed_db_ = std::make_unique<FeedContentDatabase>(std::move(storage_db),
-                                                     task_runner_);
-    if (init_database) {
-      InitStatusCallback(content_db_, leveldb_proto::Enums::InitStatus::kOK);
-      ASSERT_TRUE(db()->IsInitialized());
-    }
-  }
-
-  void InjectContentStorageProto(const std::string& key,
-                                 const std::string& data) {
-    ContentStorageProto storage_proto;
-    storage_proto.set_key(key);
-    storage_proto.set_content_data(data);
-    content_db_storage_[key] = storage_proto;
-  }
-
-  // Since the FakeDB implementation doesn't run callbacks on the same task
-  // runner as the original request was made (like the real ProtoDatabase impl
-  // does), we explicitly post all callbacks onto the DB task runner here.
-  void InitStatusCallback(FakeDB<ContentStorageProto>* storage_db,
-                          leveldb_proto::Enums::InitStatus status) {
-    task_runner()->PostTask(FROM_HERE,
-                            base::BindOnce(
-                                [](FakeDB<ContentStorageProto>* storage_db,
-                                   leveldb_proto::Enums::InitStatus status) {
-                                  storage_db->InitStatusCallback(status);
-                                },
-                                storage_db, status));
-    RunUntilIdle();
-  }
-  void LoadCallback(FakeDB<ContentStorageProto>* storage_db, bool success) {
-    task_runner()->PostTask(
-        FROM_HERE,
-        base::BindOnce([](FakeDB<ContentStorageProto>* storage_db,
-                          bool success) { storage_db->LoadCallback(success); },
-                       storage_db, success));
-    RunUntilIdle();
-  }
-  void LoadKeysCallback(FakeDB<ContentStorageProto>* storage_db, bool success) {
-    task_runner()->PostTask(
-        FROM_HERE,
-        base::BindOnce(
-            [](FakeDB<ContentStorageProto>* storage_db, bool success) {
-              storage_db->LoadKeysCallback(success);
-            },
-            storage_db, success));
-    RunUntilIdle();
-  }
-  void UpdateCallback(FakeDB<ContentStorageProto>* storage_db, bool success) {
-    task_runner()->PostTask(
-        FROM_HERE,
-        base::BindOnce(
-            [](FakeDB<ContentStorageProto>* storage_db, bool success) {
-              storage_db->UpdateCallback(success);
-            },
-            storage_db, success));
-    RunUntilIdle();
-  }
-
-  void RunUntilIdle() { task_environment_.RunUntilIdle(); }
-
-  scoped_refptr<base::SequencedTaskRunner> task_runner() {
-    return task_runner_;
-  }
-
-  FakeDB<ContentStorageProto>* storage_db() { return content_db_; }
-
-  FeedContentDatabase* db() { return feed_db_.get(); }
-
-  HistogramTester& histogram() { return histogram_; }
-
-  MOCK_METHOD2(OnContentEntriesReceived,
-               void(bool, std::vector<std::pair<std::string, std::string>>));
-  MOCK_METHOD2(OnContentKeyReceived, void(bool, std::vector<std::string>));
-  MOCK_METHOD1(OnStorageCommitted, void(bool));
-
- private:
-  base::test::TaskEnvironment task_environment_;
-
-  std::map<std::string, ContentStorageProto> content_db_storage_;
-
-  scoped_refptr<base::SequencedTaskRunner> task_runner_;
-
-  // Owned by |feed_db_|.
-  FakeDB<ContentStorageProto>* content_db_;
-
-  std::unique_ptr<FeedContentDatabase> feed_db_;
-
-  HistogramTester histogram_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedContentDatabaseTest);
-};
-
-TEST_F(FeedContentDatabaseTest, Init) {
-  ASSERT_FALSE(db());
-
-  CreateDatabase(/*init_database=*/false);
-
-  InitStatusCallback(storage_db(), leveldb_proto::Enums::InitStatus::kOK);
-
-  EXPECT_TRUE(db()->IsInitialized());
-}
-
-TEST_F(FeedContentDatabaseTest, LoadContentAfterInitSuccess) {
-  CreateDatabase(/*init_database=*/true);
-
-  EXPECT_CALL(*this, OnContentEntriesReceived(_, _));
-  db()->LoadContent(
-      {kContentKey1},
-      base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived,
-                     base::Unretained(this)));
-  LoadCallback(storage_db(), true);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1);
-}
-
-TEST_F(FeedContentDatabaseTest, LoadContentsEntries) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Store |kContentKey1| and |kContentKey2|.
-  InjectContentStorageProto(kContentKey1, kContentData1);
-  InjectContentStorageProto(kContentKey2, kContentData2);
-
-  // Try to Load |kContentKey2| and |kContentKey3|, only |kContentKey2| should
-  // return.
-  EXPECT_CALL(*this, OnContentEntriesReceived(_, _))
-      .WillOnce([](bool success,
-                   std::vector<std::pair<std::string, std::string>> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 1U);
-        EXPECT_EQ(results[0].first, kContentKey2);
-        EXPECT_EQ(results[0].second, kContentData2);
-      });
-  db()->LoadContent(
-      {kContentKey2, kContentKey3},
-      base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived,
-                     base::Unretained(this)));
-  LoadCallback(storage_db(), true);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1);
-}
-
-TEST_F(FeedContentDatabaseTest, LoadContentsEntriesByPrefix) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Store |kContentKey1|, |kContentKey2|.
-  InjectContentStorageProto(kContentKey1, kContentData1);
-  InjectContentStorageProto(kContentKey2, kContentData2);
-
-  // Try to Load "ContentKey", both |kContentKey1| and |kContentKey2| should
-  // return.
-  EXPECT_CALL(*this, OnContentEntriesReceived(_, _))
-      .WillOnce([](bool success,
-                   std::vector<std::pair<std::string, std::string>> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 2U);
-        EXPECT_EQ(results[0].first, kContentKey1);
-        EXPECT_EQ(results[0].second, kContentData1);
-        EXPECT_EQ(results[1].first, kContentKey2);
-        EXPECT_EQ(results[1].second, kContentData2);
-      });
-  db()->LoadContentByPrefix(
-      kContentKeyPrefix,
-      base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived,
-                     base::Unretained(this)));
-  LoadCallback(storage_db(), true);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1);
-}
-
-TEST_F(FeedContentDatabaseTest, LoadAllContentKeys) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Store |kContentKey1|, |kContentKey2|.
-  InjectContentStorageProto(kContentKey1, kContentData1);
-  InjectContentStorageProto(kContentKey2, kContentData2);
-
-  EXPECT_CALL(*this, OnContentKeyReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 2U);
-        EXPECT_EQ(results[0], kContentKey1);
-        EXPECT_EQ(results[1], kContentKey2);
-      });
-  db()->LoadAllContentKeys(base::BindOnce(
-      &FeedContentDatabaseTest::OnContentKeyReceived, base::Unretained(this)));
-  LoadKeysCallback(storage_db(), true);
-
-  histogram().ExpectBucketCount(kUmaSizeHistogramName,
-                                /*size=*/2, 1);
-  histogram().ExpectTotalCount(kUmaLoadKeysTimeHistogramName, 1);
-}
-
-TEST_F(FeedContentDatabaseTest, SaveContent) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Store |kContentKey1|, |kContentKey2|.
-  std::unique_ptr<ContentMutation> content_mutation =
-      std::make_unique<ContentMutation>();
-  content_mutation->AppendUpsertOperation(kContentKey1, kContentData1);
-  content_mutation->AppendUpsertOperation(kContentKey2, kContentData2);
-  EXPECT_CALL(*this, OnStorageCommitted(true));
-  db()->CommitContentMutation(
-      std::move(content_mutation),
-      base::BindOnce(&FeedContentDatabaseTest::OnStorageCommitted,
-                     base::Unretained(this)));
-  UpdateCallback(storage_db(), true);
-  UpdateCallback(storage_db(), true);
-
-  // Make sure they're there.
-  EXPECT_CALL(*this, OnContentEntriesReceived(_, _))
-      .WillOnce([](bool success,
-                   std::vector<std::pair<std::string, std::string>> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 2U);
-        EXPECT_EQ(results[0].first, kContentKey1);
-        EXPECT_EQ(results[0].second, kContentData1);
-        EXPECT_EQ(results[1].first, kContentKey2);
-        EXPECT_EQ(results[1].second, kContentData2);
-      });
-  db()->LoadContent(
-      {kContentKey1, kContentKey2},
-      base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived,
-                     base::Unretained(this)));
-  LoadCallback(storage_db(), true);
-
-  histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName,
-                                /*operations=*/2, 1);
-  histogram().ExpectTotalCount(kUmaOperationCommitTimeHistogramName, 1);
-}
-
-TEST_F(FeedContentDatabaseTest, DeleteContent) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Store |kContentKey1| and |kContentKey2|.
-  InjectContentStorageProto(kContentKey1, kContentData1);
-  InjectContentStorageProto(kContentKey2, kContentData2);
-
-  // Delete |kContentKey2| and |kContentKey3|
-  std::unique_ptr<ContentMutation> content_mutation =
-      std::make_unique<ContentMutation>();
-  content_mutation->AppendDeleteOperation(kContentKey2);
-  content_mutation->AppendDeleteOperation(kContentKey3);
-  EXPECT_CALL(*this, OnStorageCommitted(true));
-  db()->CommitContentMutation(
-      std::move(content_mutation),
-      base::BindOnce(&FeedContentDatabaseTest::OnStorageCommitted,
-                     base::Unretained(this)));
-  UpdateCallback(storage_db(), true);
-  UpdateCallback(storage_db(), true);
-
-  // Make sure only |kContentKey2| got deleted.
-  EXPECT_CALL(*this, OnContentEntriesReceived(_, _))
-      .WillOnce([](bool success,
-                   std::vector<std::pair<std::string, std::string>> results) {
-        EXPECT_TRUE(success);
-        EXPECT_EQ(results.size(), 1U);
-        EXPECT_EQ(results[0].first, kContentKey1);
-        EXPECT_EQ(results[0].second, kContentData1);
-      });
-  db()->LoadContent(
-      {kContentKey1, kContentKey2},
-      base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived,
-                     base::Unretained(this)));
-  LoadCallback(storage_db(), true);
-
-  histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName,
-                                /*operations=*/2, 1);
-  histogram().ExpectTotalCount(kUmaOperationCommitTimeHistogramName, 1);
-}
-
-TEST_F(FeedContentDatabaseTest, DeleteContentByPrefix) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Store |kContentKey1| and |kContentKey2|.
-  InjectContentStorageProto(kContentKey1, kContentData1);
-  InjectContentStorageProto(kContentKey2, kContentData2);
-
-  // Delete |kContentKey1| and |kContentKey2|
-  std::unique_ptr<ContentMutation> content_mutation =
-      std::make_unique<ContentMutation>();
-  content_mutation->AppendDeleteByPrefixOperation(kContentKeyPrefix);
-  EXPECT_CALL(*this, OnStorageCommitted(true));
-  db()->CommitContentMutation(
-      std::move(content_mutation),
-      base::BindOnce(&FeedContentDatabaseTest::OnStorageCommitted,
-                     base::Unretained(this)));
-  UpdateCallback(storage_db(), true);
-
-  // Make sure |kContentKey1| and |kContentKey2| got deleted.
-  EXPECT_CALL(*this, OnContentEntriesReceived(_, _))
-      .WillOnce([](bool success,
-                   std::vector<std::pair<std::string, std::string>> results) {
-        EXPECT_TRUE(success);
-        EXPECT_EQ(results.size(), 0U);
-      });
-  db()->LoadContent(
-      {kContentKey1, kContentKey2},
-      base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived,
-                     base::Unretained(this)));
-  LoadCallback(storage_db(), true);
-
-  histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName,
-                                /*operations=*/1, 1);
-  histogram().ExpectTotalCount(kUmaOperationCommitTimeHistogramName, 1);
-}
-
-TEST_F(FeedContentDatabaseTest, DeleteAllContent) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Store |kContentKey1| and |kContentKey2|.
-  InjectContentStorageProto(kContentKey1, kContentData1);
-  InjectContentStorageProto(kContentKey2, kContentData2);
-
-  // Delete all content, meaning |kContentKey1| and |kContentKey2| are expected
-  // to be deleted.
-  std::unique_ptr<ContentMutation> content_mutation =
-      std::make_unique<ContentMutation>();
-  content_mutation->AppendDeleteAllOperation();
-  EXPECT_CALL(*this, OnStorageCommitted(true));
-  db()->CommitContentMutation(
-      std::move(content_mutation),
-      base::BindOnce(&FeedContentDatabaseTest::OnStorageCommitted,
-                     base::Unretained(this)));
-  UpdateCallback(storage_db(), true);
-
-  // Make sure |kContentKey1| and |kContentKey2| got deleted.
-  EXPECT_CALL(*this, OnContentEntriesReceived(_, _))
-      .WillOnce([](bool success,
-                   std::vector<std::pair<std::string, std::string>> results) {
-        EXPECT_TRUE(success);
-        EXPECT_EQ(results.size(), 0U);
-      });
-  db()->LoadContent(
-      {kContentKey1, kContentKey2},
-      base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived,
-                     base::Unretained(this)));
-  LoadCallback(storage_db(), true);
-
-  histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName,
-                                /*operations=*/1, 1);
-  histogram().ExpectTotalCount(kUmaOperationCommitTimeHistogramName, 1);
-}
-
-TEST_F(FeedContentDatabaseTest, SaveAndDeleteContent) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Store |kContentKey1|, |kContentKey2|.
-  std::unique_ptr<ContentMutation> content_mutation =
-      std::make_unique<ContentMutation>();
-  content_mutation->AppendUpsertOperation(kContentKey1, kContentData1);
-  content_mutation->AppendUpsertOperation(kContentKey2, kContentData2);
-  content_mutation->AppendDeleteOperation(kContentKey2);
-  content_mutation->AppendDeleteOperation(kContentKey3);
-  EXPECT_CALL(*this, OnStorageCommitted(true));
-  db()->CommitContentMutation(
-      std::move(content_mutation),
-      base::BindOnce(&FeedContentDatabaseTest::OnStorageCommitted,
-                     base::Unretained(this)));
-  UpdateCallback(storage_db(), true);
-  UpdateCallback(storage_db(), true);
-  UpdateCallback(storage_db(), true);
-  UpdateCallback(storage_db(), true);
-
-  // Make sure only |kContentKey2| got deleted.
-  EXPECT_CALL(*this, OnContentEntriesReceived(_, _))
-      .WillOnce([](bool success,
-                   std::vector<std::pair<std::string, std::string>> results) {
-        EXPECT_TRUE(success);
-        EXPECT_EQ(results.size(), 1U);
-        EXPECT_EQ(results[0].first, kContentKey1);
-        EXPECT_EQ(results[0].second, kContentData1);
-      });
-  db()->LoadContent(
-      {kContentKey1, kContentKey2},
-      base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived,
-                     base::Unretained(this)));
-  LoadCallback(storage_db(), true);
-
-  histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName,
-                                /*operations=*/4, 1);
-  histogram().ExpectTotalCount(kUmaOperationCommitTimeHistogramName, 1);
-}
-
-TEST_F(FeedContentDatabaseTest, LoadContentsFail) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Store |kContentKey1| and |kContentKey2|.
-  InjectContentStorageProto(kContentKey1, kContentData1);
-  InjectContentStorageProto(kContentKey2, kContentData2);
-
-  // Try to Load |kContentKey2| and |kContentKey3|,.
-  EXPECT_CALL(*this, OnContentEntriesReceived(_, _))
-      .WillOnce([](bool success,
-                   std::vector<std::pair<std::string, std::string>> results) {
-        EXPECT_FALSE(success);
-      });
-  db()->LoadContent(
-      {kContentKey2, kContentKey3},
-      base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived,
-                     base::Unretained(this)));
-  LoadCallback(storage_db(), false);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1);
-}
-
-TEST_F(FeedContentDatabaseTest, LoadAllContentKeysFail) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Store |kContentKey1|, |kContentKey2|.
-  InjectContentStorageProto(kContentKey1, kContentData1);
-  InjectContentStorageProto(kContentKey2, kContentData2);
-
-  EXPECT_CALL(*this, OnContentKeyReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_FALSE(success);
-      });
-  db()->LoadAllContentKeys(base::BindOnce(
-      &FeedContentDatabaseTest::OnContentKeyReceived, base::Unretained(this)));
-  LoadKeysCallback(storage_db(), false);
-
-  histogram().ExpectTotalCount(kUmaSizeHistogramName, 0);
-  histogram().ExpectTotalCount(kUmaLoadKeysTimeHistogramName, 1);
-}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_content_mutation.cc b/components/feed/core/feed_content_mutation.cc
deleted file mode 100644
index 57502baf..0000000
--- a/components/feed/core/feed_content_mutation.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_content_mutation.h"
-
-#include <utility>
-
-#include "components/feed/core/feed_content_operation.h"
-
-namespace feed {
-
-ContentMutation::ContentMutation() : start_time_(base::TimeTicks::Now()) {}
-
-ContentMutation::~ContentMutation() = default;
-
-void ContentMutation::AppendDeleteOperation(std::string key) {
-  operations_list_.emplace_back(
-      ContentOperation::CreateDeleteOperation(std::move(key)));
-}
-
-void ContentMutation::AppendDeleteAllOperation() {
-  operations_list_.emplace_back(ContentOperation::CreateDeleteAllOperation());
-}
-
-void ContentMutation::AppendDeleteByPrefixOperation(std::string prefix) {
-  operations_list_.emplace_back(
-      ContentOperation::CreateDeleteByPrefixOperation(std::move(prefix)));
-}
-
-void ContentMutation::AppendUpsertOperation(std::string key,
-                                            std::string value) {
-  operations_list_.emplace_back(ContentOperation::CreateUpsertOperation(
-      std::move(key), std::move(value)));
-}
-
-bool ContentMutation::Empty() {
-  return operations_list_.empty();
-}
-
-size_t ContentMutation::Size() const {
-  return operations_list_.size();
-}
-
-base::TimeTicks ContentMutation::GetStartTime() const {
-  return start_time_;
-}
-
-ContentOperation ContentMutation::TakeFirstOperation() {
-  ContentOperation operation = std::move(operations_list_.front());
-  operations_list_.pop_front();
-  return operation;
-}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_content_mutation.h b/components/feed/core/feed_content_mutation.h
deleted file mode 100644
index 61e9f98a..0000000
--- a/components/feed/core/feed_content_mutation.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_FEED_CONTENT_MUTATION_H_
-#define COMPONENTS_FEED_CORE_FEED_CONTENT_MUTATION_H_
-
-#include <list>
-#include <string>
-
-#include "base/macros.h"
-#include "base/time/time.h"
-
-namespace feed {
-
-class ContentOperation;
-
-// Native counterpart of ContentMutation.java.
-// To commit a set of ContentOperation into FeedContentDatabase, user need to
-// create a ContentMutation, next use Append* methods to append operations
-// into the mutation, and then pass the ContentMutation to
-// |FeedContentDatabase::CommitContentMutation| to commit operations.
-class ContentMutation {
- public:
-  ContentMutation();
-  ~ContentMutation();
-
-  void AppendDeleteOperation(std::string key);
-  void AppendDeleteAllOperation();
-  void AppendDeleteByPrefixOperation(std::string prefix);
-  void AppendUpsertOperation(std::string key, std::string value);
-
-  // Check if mutation has ContentOperation left.
-  bool Empty();
-
-  // Return the number of operations in the mutation.
-  size_t Size() const;
-
-  base::TimeTicks GetStartTime() const;
-
-  // This will remove the first ContentOperation in |operations_list_| and
-  // return it to caller.
-  ContentOperation TakeFirstOperation();
-
- private:
-  std::list<ContentOperation> operations_list_;
-
-  const base::TimeTicks start_time_;
-
-  DISALLOW_COPY_AND_ASSIGN(ContentMutation);
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CORE_FEED_CONTENT_MUTATION_H_
diff --git a/components/feed/core/feed_content_mutation_unittest.cc b/components/feed/core/feed_content_mutation_unittest.cc
deleted file mode 100644
index 3a56c2f..0000000
--- a/components/feed/core/feed_content_mutation_unittest.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_content_mutation.h"
-
-#include "components/feed/core/feed_content_operation.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace feed {
-
-namespace {
-
-const char kContentkey[] = "ContentKey";
-const char kContentValue[] = "Value";
-const char kContentPrefix[] = "Content";
-
-}  // namespace
-
-class FeedContentMutationTest : public testing::Test {
- public:
-  FeedContentMutationTest() = default;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FeedContentMutationTest);
-};
-
-TEST_F(FeedContentMutationTest, AppendDeleteOperation) {
-  ContentMutation mutation;
-  EXPECT_TRUE(mutation.Empty());
-
-  mutation.AppendDeleteOperation(kContentkey);
-  EXPECT_FALSE(mutation.Empty());
-
-  ContentOperation operation = mutation.TakeFirstOperation();
-  EXPECT_TRUE(mutation.Empty());
-  EXPECT_EQ(operation.type(), ContentOperation::CONTENT_DELETE);
-  EXPECT_EQ(operation.key(), kContentkey);
-}
-
-TEST_F(FeedContentMutationTest, AppendDeleteAllOperation) {
-  ContentMutation mutation;
-  EXPECT_TRUE(mutation.Empty());
-
-  mutation.AppendDeleteAllOperation();
-  EXPECT_FALSE(mutation.Empty());
-
-  ContentOperation operation = mutation.TakeFirstOperation();
-  EXPECT_TRUE(mutation.Empty());
-  EXPECT_EQ(operation.type(), ContentOperation::CONTENT_DELETE_ALL);
-}
-
-TEST_F(FeedContentMutationTest, AppendDeleteByPrefixOperation) {
-  ContentMutation mutation;
-  EXPECT_TRUE(mutation.Empty());
-
-  mutation.AppendDeleteByPrefixOperation(kContentPrefix);
-  EXPECT_FALSE(mutation.Empty());
-
-  ContentOperation operation = mutation.TakeFirstOperation();
-  EXPECT_TRUE(mutation.Empty());
-  EXPECT_EQ(operation.type(), ContentOperation::CONTENT_DELETE_BY_PREFIX);
-  EXPECT_EQ(operation.prefix(), kContentPrefix);
-}
-
-TEST_F(FeedContentMutationTest, AppendUpsertOperation) {
-  ContentMutation mutation;
-  EXPECT_TRUE(mutation.Empty());
-
-  mutation.AppendUpsertOperation(kContentkey, kContentValue);
-  EXPECT_FALSE(mutation.Empty());
-
-  ContentOperation operation = mutation.TakeFirstOperation();
-  EXPECT_TRUE(mutation.Empty());
-  EXPECT_EQ(operation.type(), ContentOperation::CONTENT_UPSERT);
-  EXPECT_EQ(operation.key(), kContentkey);
-  EXPECT_EQ(operation.value(), kContentValue);
-}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_content_operation.cc b/components/feed/core/feed_content_operation.cc
deleted file mode 100644
index 073de92..0000000
--- a/components/feed/core/feed_content_operation.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_content_operation.h"
-
-#include <utility>
-
-#include "base/check_op.h"
-
-namespace feed {
-
-// static
-ContentOperation ContentOperation::CreateDeleteOperation(std::string key) {
-  return ContentOperation(CONTENT_DELETE, std::move(key), std::string(),
-                          std::string());
-}
-
-// static
-ContentOperation ContentOperation::CreateDeleteAllOperation() {
-  return ContentOperation(CONTENT_DELETE_ALL, std::string(), std::string(),
-                          std::string());
-}
-
-// static
-ContentOperation ContentOperation::CreateDeleteByPrefixOperation(
-    std::string prefix) {
-  return ContentOperation(CONTENT_DELETE_BY_PREFIX, std::string(),
-                          std::string(), std::move(prefix));
-}
-
-// static
-ContentOperation ContentOperation::CreateUpsertOperation(std::string key,
-                                                         std::string value) {
-  return ContentOperation(CONTENT_UPSERT, std::move(key), std::move(value),
-                          std::string());
-}
-
-ContentOperation::ContentOperation(ContentOperation&& operation) = default;
-
-ContentOperation::Type ContentOperation::type() {
-  return type_;
-}
-
-const std::string& ContentOperation::key() {
-  DCHECK(type_ == CONTENT_UPSERT || type_ == CONTENT_DELETE);
-  return key_;
-}
-
-const std::string& ContentOperation::value() {
-  DCHECK_EQ(type_, CONTENT_UPSERT);
-  return value_;
-}
-
-const std::string& ContentOperation::prefix() {
-  DCHECK_EQ(type_, CONTENT_DELETE_BY_PREFIX);
-  return prefix_;
-}
-
-ContentOperation::ContentOperation(Type type,
-                                   std::string key,
-                                   std::string value,
-                                   std::string prefix)
-    : type_(type),
-      key_(std::move(key)),
-      value_(std::move(value)),
-      prefix_(std::move(prefix)) {}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_content_operation.h b/components/feed/core/feed_content_operation.h
deleted file mode 100644
index 103e902d..0000000
--- a/components/feed/core/feed_content_operation.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_FEED_CONTENT_OPERATION_H_
-#define COMPONENTS_FEED_CORE_FEED_CONTENT_OPERATION_H_
-
-#include <string>
-
-#include "base/macros.h"
-
-namespace feed {
-
-// Native counterpart of ContentOperation.java.
-class ContentOperation {
- public:
-  enum Type {
-    CONTENT_DELETE,
-    CONTENT_DELETE_ALL,
-    CONTENT_DELETE_BY_PREFIX,
-    CONTENT_UPSERT,
-  };
-
-  static ContentOperation CreateDeleteOperation(std::string key);
-  static ContentOperation CreateDeleteAllOperation();
-  static ContentOperation CreateDeleteByPrefixOperation(std::string prefix);
-  static ContentOperation CreateUpsertOperation(std::string key,
-                                                std::string value);
-
-  ContentOperation(ContentOperation&& operation);
-
-  Type type();
-  const std::string& key();
-  const std::string& value();
-  const std::string& prefix();
-
- private:
-  ContentOperation(Type type,
-                   std::string key,
-                   std::string value,
-                   std::string prefix);
-
-  const Type type_;
-  const std::string key_;
-  const std::string value_;
-  const std::string prefix_;
-
-  DISALLOW_COPY_AND_ASSIGN(ContentOperation);
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CORE_FEED_CONTENT_OPERATION_H_
diff --git a/components/feed/core/feed_journal_database.cc b/components/feed/core/feed_journal_database.cc
deleted file mode 100644
index 63a4540a..0000000
--- a/components/feed/core/feed_journal_database.cc
+++ /dev/null
@@ -1,349 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_journal_database.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/system/sys_info.h"
-#include "base/task/post_task.h"
-#include "base/task/thread_pool.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/feed/core/feed_journal_mutation.h"
-#include "components/feed/core/feed_journal_operation.h"
-#include "components/feed/core/proto/journal_storage.pb.h"
-#include "components/leveldb_proto/public/proto_database_provider.h"
-
-namespace feed {
-
-namespace {
-
-const char kJournalDatabaseFolder[] = "journal";
-
-// Journal updates happen infrequently and are typically ~8KB. However there's
-// also one tiny write during startup before more writes that 1KB should handle.
-const size_t kDatabaseWriteBufferSizeBytes = 1 * 1024;  // 1KB
-
-void ReportLoadTimeHistogram(bool success, base::TimeTicks start_time) {
-  base::TimeDelta load_time = base::TimeTicks::Now() - start_time;
-  UMA_HISTOGRAM_TIMES("ContentSuggestions.Feed.JournalStorage.LoadTime",
-                      load_time);
-}
-
-}  // namespace
-
-FeedJournalDatabase::FeedJournalDatabase(
-    leveldb_proto::ProtoDatabaseProvider* proto_database_provider,
-    const base::FilePath& database_folder)
-    : database_status_(InitStatus::kNotInitialized),
-      task_runner_(base::ThreadPool::CreateSequencedTaskRunner(
-          {base::MayBlock(), base::TaskPriority::USER_VISIBLE})),
-      storage_database_(proto_database_provider->GetDB<JournalStorageProto>(
-          leveldb_proto::ProtoDbType::FEED_JOURNAL_DATABASE,
-          database_folder.AppendASCII(kJournalDatabaseFolder),
-          task_runner_)) {
-  task_runner_->PostTask(FROM_HERE,
-                         base::BindOnce(&FeedJournalDatabase::InitInternal,
-                                        weak_ptr_factory_.GetWeakPtr()));
-}
-
-// Used for testing.
-FeedJournalDatabase::FeedJournalDatabase(
-    std::unique_ptr<leveldb_proto::ProtoDatabase<JournalStorageProto>>
-        storage_database,
-    scoped_refptr<base::SequencedTaskRunner> task_runner)
-    : database_status_(InitStatus::kNotInitialized),
-      task_runner_(task_runner),
-      storage_database_(std::move(storage_database)) {
-  task_runner_->PostTask(FROM_HERE,
-                         base::BindOnce(&FeedJournalDatabase::InitInternal,
-                                        weak_ptr_factory_.GetWeakPtr()));
-}
-
-FeedJournalDatabase::~FeedJournalDatabase() = default;
-
-bool FeedJournalDatabase::IsInitialized() const {
-  return database_status_ == InitStatus::kOK;
-}
-
-void FeedJournalDatabase::InitInternal() {
-  leveldb_env::Options options = leveldb_proto::CreateSimpleOptions();
-  options.write_buffer_size = kDatabaseWriteBufferSizeBytes;
-
-  storage_database_->Init(
-      options, base::BindOnce(&FeedJournalDatabase::OnDatabaseInitialized,
-                              weak_ptr_factory_.GetWeakPtr()));
-}
-
-void FeedJournalDatabase::LoadJournal(const std::string& key,
-                                      JournalLoadCallback callback) {
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          &FeedJournalDatabase::GetEntryInternal,
-          weak_ptr_factory_.GetWeakPtr(), std::move(key),
-          base::BindOnce(&FeedJournalDatabase::OnGetEntryForLoadJournal,
-                         weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(),
-                         std::move(callback))));
-}
-
-void FeedJournalDatabase::DoesJournalExist(const std::string& key,
-                                           CheckExistingCallback callback) {
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          &FeedJournalDatabase::GetEntryInternal,
-          weak_ptr_factory_.GetWeakPtr(), std::move(key),
-          base::BindOnce(&FeedJournalDatabase::OnGetEntryForDoesJournalExist,
-                         weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(),
-                         std::move(callback))));
-}
-
-void FeedJournalDatabase::CommitJournalMutation(
-    std::unique_ptr<JournalMutation> journal_mutation,
-    ConfirmationCallback callback) {
-  DCHECK(journal_mutation);
-
-  UMA_HISTOGRAM_COUNTS_100(
-      "ContentSuggestions.Feed.JournalStorage.CommitMutationCount",
-      journal_mutation->Size());
-
-  if (journal_mutation->Empty()) {
-    task_runner_->PostTask(FROM_HERE,
-                           base::BindOnce(std::move(callback), true));
-    return;
-  }
-
-  // Skip loading journal if the first operation is JOURNAL_DELETE.
-  if (journal_mutation->FirstOperationType() ==
-      JournalOperation::JOURNAL_DELETE) {
-    task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&FeedJournalDatabase::PerformOperations,
-                       weak_ptr_factory_.GetWeakPtr(), nullptr,
-                       std::move(journal_mutation), std::move(callback)));
-    return;
-  }
-
-  std::string journal_name = journal_mutation->journal_name();
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          &FeedJournalDatabase::GetEntryInternal,
-          weak_ptr_factory_.GetWeakPtr(), std::move(journal_name),
-          base::BindOnce(
-              &FeedJournalDatabase::OnGetEntryForCommitJournalMutation,
-              weak_ptr_factory_.GetWeakPtr(), std::move(journal_mutation),
-              std::move(callback))));
-}
-
-void FeedJournalDatabase::GetEntryInternal(
-    const std::string& key,
-    leveldb_proto::Callbacks::Internal<JournalStorageProto>::GetCallback
-        callback) {
-  storage_database_->GetEntry(key, std::move(callback));
-}
-
-void FeedJournalDatabase::LoadAllJournalKeys(JournalLoadCallback callback) {
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&FeedJournalDatabase::LoadKeysInternal,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-}
-
-void FeedJournalDatabase::LoadKeysInternal(JournalLoadCallback callback) {
-  storage_database_->LoadKeys(
-      base::BindOnce(&FeedJournalDatabase::OnLoadKeysForLoadAllJournalKeys,
-                     weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(),
-                     std::move(callback)));
-}
-
-void FeedJournalDatabase::DeleteAllJournals(ConfirmationCallback callback) {
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&FeedJournalDatabase::DeleteAllEntriesInternal,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-}
-
-void FeedJournalDatabase::DeleteAllEntriesInternal(
-    ConfirmationCallback callback) {
-  // For deleting all, filter method always return true.
-  storage_database_->UpdateEntriesWithRemoveFilter(
-      std::make_unique<StorageEntryVector>(),
-      base::BindRepeating([](const std::string& x) { return true; }),
-      base::BindOnce(&FeedJournalDatabase::OnOperationCommitted,
-                     weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(),
-                     std::move(callback)));
-}
-
-void FeedJournalDatabase::PerformOperations(
-    std::unique_ptr<JournalStorageProto> journal,
-    std::unique_ptr<JournalMutation> journal_mutation,
-    ConfirmationCallback callback) {
-  DCHECK(!journal_mutation->Empty());
-
-  if (journal) {
-    DCHECK_EQ(journal->key(), journal_mutation->journal_name());
-  } else {
-    journal = std::make_unique<JournalStorageProto>();
-    journal->set_key(journal_mutation->journal_name());
-  }
-
-  JournalMap copy_to_journal;
-  while (!journal_mutation->Empty()) {
-    JournalOperation operation = journal_mutation->TakeFirstOperation();
-    switch (operation.type()) {
-      case JournalOperation::JOURNAL_APPEND:
-        journal->add_journal_data(operation.value());
-        break;
-      case JournalOperation::JOURNAL_COPY:
-        copy_to_journal[operation.to_journal_name()] =
-            CopyJournal(operation.to_journal_name(), *journal);
-        break;
-      case JournalOperation::JOURNAL_DELETE:
-        journal->clear_journal_data();
-        break;
-    }
-  }
-
-  CommitOperations(journal_mutation->GetStartTime(), std::move(journal),
-                   std::move(copy_to_journal), std::move(callback));
-}
-
-void FeedJournalDatabase::CommitOperations(
-    base::TimeTicks start_time,
-    std::unique_ptr<JournalStorageProto> journal,
-    JournalMap copy_to_journal,
-    ConfirmationCallback callback) {
-  auto journals_to_save = std::make_unique<StorageEntryVector>();
-  auto journals_to_delete = std::make_unique<std::vector<std::string>>();
-
-  if (journal->journal_data_size() == 0) {
-    // This can only happens when the journal is deleted.
-    journals_to_delete->push_back(journal->key());
-  } else {
-    std::string journal_name = journal->key();
-    journals_to_save->emplace_back(journal_name, std::move(*journal));
-  }
-
-  for (auto it = copy_to_journal.begin(); it != copy_to_journal.end(); ++it) {
-    journals_to_save->emplace_back(it->first, std::move(it->second));
-  }
-
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&FeedJournalDatabase::UpdateEntriesInternal,
-                     weak_ptr_factory_.GetWeakPtr(),
-                     std::move(journals_to_save), std::move(journals_to_delete),
-                     std::move(start_time), std::move(callback)));
-}
-
-void FeedJournalDatabase::UpdateEntriesInternal(
-    std::unique_ptr<StorageEntryVector> entries_to_save,
-    std::unique_ptr<std::vector<std::string>> keys_to_remove,
-    base::TimeTicks start_time,
-    ConfirmationCallback callback) {
-  storage_database_->UpdateEntries(
-      std::move(entries_to_save), std::move(keys_to_remove),
-      base::BindOnce(&FeedJournalDatabase::OnOperationCommitted,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(start_time),
-                     std::move(callback)));
-}
-
-void FeedJournalDatabase::OnDatabaseInitialized(InitStatus status) {
-  DCHECK_EQ(database_status_, InitStatus::kNotInitialized);
-  database_status_ = status;
-}
-
-void FeedJournalDatabase::OnGetEntryForLoadJournal(
-    base::TimeTicks start_time,
-    JournalLoadCallback callback,
-    bool success,
-    std::unique_ptr<JournalStorageProto> journal) {
-  std::vector<std::string> results;
-  if (journal) {
-    for (int i = 0; i < journal->journal_data_size(); ++i) {
-      results.emplace_back(journal->journal_data(i));
-    }
-  }
-
-  ReportLoadTimeHistogram(success, start_time);
-
-  std::move(callback).Run(success, std::move(results));
-}
-
-void FeedJournalDatabase::OnGetEntryForDoesJournalExist(
-    base::TimeTicks start_time,
-    CheckExistingCallback callback,
-    bool success,
-    std::unique_ptr<JournalStorageProto> journal) {
-  ReportLoadTimeHistogram(success, start_time);
-
-  std::move(callback).Run(success, journal ? true : false);
-}
-
-void FeedJournalDatabase::OnLoadKeysForLoadAllJournalKeys(
-    base::TimeTicks start_time,
-    JournalLoadCallback callback,
-    bool success,
-    std::unique_ptr<std::vector<std::string>> keys) {
-  std::vector<std::string> results;
-  if (keys) {
-    results = std::move(*keys);
-  }
-
-  if (success) {
-    // Journal count is about how many Feed surfaces opens/shows to a user.
-    UMA_HISTOGRAM_EXACT_LINEAR("ContentSuggestions.Feed.JournalStorage.Count",
-                               results.size(), 50);
-  }
-
-  base::TimeDelta load_time = base::TimeTicks::Now() - start_time;
-  UMA_HISTOGRAM_TIMES("ContentSuggestions.Feed.JournalStorage.LoadKeysTime",
-                      load_time);
-
-  std::move(callback).Run(success, std::move(results));
-}
-
-void FeedJournalDatabase::OnGetEntryForCommitJournalMutation(
-    std::unique_ptr<JournalMutation> journal_mutation,
-    ConfirmationCallback callback,
-    bool success,
-    std::unique_ptr<JournalStorageProto> journal) {
-  if (!success) {
-    DVLOG(1) << "FeedJournalDatabase load journal failed.";
-    std::move(callback).Run(success);
-    return;
-  }
-
-  PerformOperations(std::move(journal), std::move(journal_mutation),
-                    std::move(callback));
-}
-
-void FeedJournalDatabase::OnOperationCommitted(base::TimeTicks start_time,
-                                               ConfirmationCallback callback,
-                                               bool success) {
-  base::TimeDelta commit_time = base::TimeTicks::Now() - start_time;
-  UMA_HISTOGRAM_TIMES(
-      "ContentSuggestions.Feed.JournalStorage.OperationCommitTime",
-      commit_time);
-
-  std::move(callback).Run(success);
-}
-
-JournalStorageProto FeedJournalDatabase::CopyJournal(
-    const std::string& new_journal_name,
-    const JournalStorageProto& source_journal) {
-  JournalStorageProto new_journal;
-  new_journal.set_key(new_journal_name);
-  for (int i = 0; i < source_journal.journal_data_size(); ++i) {
-    new_journal.add_journal_data(source_journal.journal_data(i));
-  }
-
-  return new_journal;
-}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_journal_database.h b/components/feed/core/feed_journal_database.h
deleted file mode 100644
index eda0e74..0000000
--- a/components/feed/core/feed_journal_database.h
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_FEED_JOURNAL_DATABASE_H_
-#define COMPONENTS_FEED_CORE_FEED_JOURNAL_DATABASE_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/containers/flat_map.h"
-#include "base/files/file_path.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequenced_task_runner.h"
-#include "components/leveldb_proto/public/proto_database.h"
-
-namespace leveldb_proto {
-class ProtoDatabaseProvider;
-}  // namespace leveldb_proto
-
-namespace feed {
-
-class JournalMutation;
-class JournalOperation;
-class JournalStorageProto;
-
-using InitStatus = leveldb_proto::Enums::InitStatus;
-
-// FeedJournalDatabase is leveldb backend store for Feed's journal storage data.
-// Feed's journal data are key-value pairs.  In order to support callers from
-// different threads, this class posts all database operations to an owned
-// sequenced task runner.
-class FeedJournalDatabase {
- public:
-  // Returns the journal data as a vector of strings when calling loading data
-  // or keys.
-  using JournalLoadCallback =
-      base::OnceCallback<void(bool, std::vector<std::string>)>;
-
-  // Return whether the entry exists when calling for checking
-  // the entry's existence.
-  using CheckExistingCallback = base::OnceCallback<void(bool, bool)>;
-
-  // Returns whether the commit operation succeeded when calling for database
-  // operations.
-  using ConfirmationCallback = base::OnceCallback<void(bool)>;
-
-  using JournalMap = base::flat_map<std::string, JournalStorageProto>;
-
-  using StorageEntryVector =
-      leveldb_proto::ProtoDatabase<JournalStorageProto>::KeyEntryVector;
-
-  // Initializes the database with |proto_database_provider| and
-  // |database_folder|.
-  FeedJournalDatabase(
-      leveldb_proto::ProtoDatabaseProvider* proto_database_provider,
-      const base::FilePath& database_folder);
-
-  // Creates storage using the given |storage_database| for local storage.
-  // Useful for testing.
-  explicit FeedJournalDatabase(
-      std::unique_ptr<leveldb_proto::ProtoDatabase<JournalStorageProto>>
-          storage_database,
-      scoped_refptr<base::SequencedTaskRunner> task_runner);
-
-  ~FeedJournalDatabase();
-
-  // Returns true if initialization has finished successfully, else false.
-  // While this is false, initialization may already started, or initialization
-  // failed.
-  bool IsInitialized() const;
-
-  // Loads the journal data for the |key| and passes it to |callback|.
-  void LoadJournal(const std::string& key, JournalLoadCallback callback);
-
-  // Checks if the journal for the |key| exists, and return the result to
-  // |callback|.
-  void DoesJournalExist(const std::string& key, CheckExistingCallback callback);
-
-  // Commits the operations in the |journal_mutation|. |callback| will be called
-  // when all the operations are committed. Or if any operation failed, database
-  // will stop process any operations and passed error to |callback|.
-  void CommitJournalMutation(std::unique_ptr<JournalMutation> journal_mutation,
-                             ConfirmationCallback callback);
-
-  // Loads all journal keys in the storage, and passes them to |callback|.
-  void LoadAllJournalKeys(JournalLoadCallback callback);
-
-  // Delete all journals, |callback| will be called when all journals are
-  // deleted or if there is an error.
-  void DeleteAllJournals(ConfirmationCallback callback);
-
- private:
-  // This method performs JournalOperation in the |journal_mutation|.
-  // If the first operation in |journal_mutation| is JOURNAL_DELETE, journal
-  // can be empty, otherwise we need to load |journal| from database and
-  // then pass to this method.
-  void PerformOperations(std::unique_ptr<JournalStorageProto> journal,
-                         std::unique_ptr<JournalMutation> journal_mutation,
-                         ConfirmationCallback callback);
-  void CommitOperations(base::TimeTicks start_time,
-                        std::unique_ptr<JournalStorageProto> journal,
-                        JournalMap copy_to_journal,
-                        ConfirmationCallback callback);
-
-  // The following *Internal methods must be executed from |task_runner_|.
-  void InitInternal();
-  void GetEntryInternal(
-      const std::string& key,
-      leveldb_proto::Callbacks::Internal<JournalStorageProto>::GetCallback
-          callback);
-  void LoadKeysInternal(JournalLoadCallback callback);
-  void DeleteAllEntriesInternal(ConfirmationCallback callback);
-  void UpdateEntriesInternal(
-      std::unique_ptr<StorageEntryVector> entries_to_save,
-      std::unique_ptr<std::vector<std::string>> keys_to_remove,
-      base::TimeTicks start_time,
-      ConfirmationCallback callback);
-
-  // Callback methods given to |storage_database_| for async responses.
-  void OnDatabaseInitialized(InitStatus status);
-  void OnGetEntryForLoadJournal(base::TimeTicks start_time,
-                                JournalLoadCallback callback,
-                                bool success,
-                                std::unique_ptr<JournalStorageProto> journal);
-  void OnGetEntryForDoesJournalExist(
-      base::TimeTicks start_time,
-      CheckExistingCallback callback,
-      bool success,
-      std::unique_ptr<JournalStorageProto> journal);
-  void OnGetEntryForCommitJournalMutation(
-      std::unique_ptr<JournalMutation> journal_mutation,
-      ConfirmationCallback callback,
-      bool success,
-      std::unique_ptr<JournalStorageProto> journal);
-  void OnLoadKeysForLoadAllJournalKeys(
-      base::TimeTicks start_time,
-      JournalLoadCallback callback,
-      bool success,
-      std::unique_ptr<std::vector<std::string>> keys);
-  void OnOperationCommitted(base::TimeTicks start_time,
-                            ConfirmationCallback callback,
-                            bool success);
-
-  JournalStorageProto CopyJournal(const std::string& new_journal_name,
-                                  const JournalStorageProto& source_journal);
-
-  // Status of the database initialization.
-  InitStatus database_status_;
-
-  // Task runner on which to execute database calls.
-  scoped_refptr<base::SequencedTaskRunner> task_runner_;
-
-  // The database for storing journal storage information.
-  std::unique_ptr<leveldb_proto::ProtoDatabase<JournalStorageProto>>
-      storage_database_;
-
-  base::WeakPtrFactory<FeedJournalDatabase> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FeedJournalDatabase);
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CORE_FEED_JOURNAL_DATABASE_H_
diff --git a/components/feed/core/feed_journal_database_unittest.cc b/components/feed/core/feed_journal_database_unittest.cc
deleted file mode 100644
index cd0b2deb..0000000
--- a/components/feed/core/feed_journal_database_unittest.cc
+++ /dev/null
@@ -1,625 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_journal_database.h"
-
-#include <map>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/task/thread_pool.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/task_environment.h"
-#include "components/feed/core/feed_journal_mutation.h"
-#include "components/feed/core/proto/journal_storage.pb.h"
-#include "components/leveldb_proto/testing/fake_db.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using base::HistogramTester;
-using leveldb_proto::test::FakeDB;
-using testing::Mock;
-using testing::NotNull;
-using testing::_;
-
-namespace feed {
-
-namespace {
-
-const char kJournalKey1[] = "JournalKey1";
-const char kJournalKey2[] = "JournalKey2";
-const char kJournalKey3[] = "JournalKey3";
-const char kJournalData1[] = "Journal Data1";
-const char kJournalData2[] = "Journal Data2";
-const char kJournalData3[] = "Journal Data3";
-const char kJournalData4[] = "Journal Data4";
-const char kJournalData5[] = "Journal Data5";
-const char kJournalData6[] = "Journal Data6";
-
-const char kUmaCommitMutationSizeHistogramName[] =
-    "ContentSuggestions.Feed.JournalStorage.CommitMutationCount";
-const char kUmaLoadKeysTimeHistogramName[] =
-    "ContentSuggestions.Feed.JournalStorage.LoadKeysTime";
-const char kUmaLoadTimeHistogramName[] =
-    "ContentSuggestions.Feed.JournalStorage.LoadTime";
-const char kUmaOperationCommitTimeHistogramName[] =
-    "ContentSuggestions.Feed.JournalStorage.OperationCommitTime";
-const char kUmaSizeHistogramName[] =
-    "ContentSuggestions.Feed.JournalStorage.Count";
-
-}  // namespace
-
-class FeedJournalDatabaseTest : public testing::Test {
- public:
-  FeedJournalDatabaseTest() : journal_db_(nullptr) {}
-
-  void CreateDatabase(bool init_database) {
-    // The FakeDBs are owned by |feed_db_|, so clear our pointers before
-    // resetting |feed_db_| itself.
-    journal_db_ = nullptr;
-    // Explicitly destroy any existing database before creating a new one.
-    feed_db_.reset();
-
-    auto storage_db =
-        std::make_unique<FakeDB<JournalStorageProto>>(&journal_db_storage_);
-
-    task_runner_ = base::ThreadPool::CreateSequencedTaskRunner(
-        {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
-
-    journal_db_ = storage_db.get();
-    feed_db_ = std::make_unique<FeedJournalDatabase>(std::move(storage_db),
-                                                     task_runner_);
-    if (init_database) {
-      InitStatusCallback(journal_db_, leveldb_proto::Enums::InitStatus::kOK);
-      ASSERT_TRUE(db()->IsInitialized());
-    }
-  }
-
-  void InjectJournalStorageProto(const std::string& key,
-                                 const std::vector<std::string>& entries) {
-    JournalStorageProto storage_proto;
-    storage_proto.set_key(key);
-    for (const std::string& entry : entries) {
-      storage_proto.add_journal_data(entry);
-    }
-    journal_db_storage_[key] = storage_proto;
-  }
-
-  // Since the FakeDB implementation doesn't run callbacks on the same task
-  // runner as the original request was made (like the real ProtoDatabase impl
-  // does), we explicitly post all callbacks onto the DB task runner here.
-  void InitStatusCallback(FakeDB<JournalStorageProto>* storage_db,
-                          leveldb_proto::Enums::InitStatus status) {
-    task_runner()->PostTask(FROM_HERE,
-                            base::BindOnce(
-                                [](FakeDB<JournalStorageProto>* storage_db,
-                                   leveldb_proto::Enums::InitStatus status) {
-                                  storage_db->InitStatusCallback(status);
-                                },
-                                storage_db, status));
-    RunUntilIdle();
-  }
-  void GetCallback(FakeDB<JournalStorageProto>* storage_db, bool success) {
-    task_runner()->PostTask(
-        FROM_HERE,
-        base::BindOnce([](FakeDB<JournalStorageProto>* storage_db,
-                          bool success) { storage_db->GetCallback(success); },
-                       storage_db, success));
-    RunUntilIdle();
-  }
-  void LoadKeysCallback(FakeDB<JournalStorageProto>* storage_db, bool success) {
-    task_runner()->PostTask(
-        FROM_HERE,
-        base::BindOnce(
-            [](FakeDB<JournalStorageProto>* storage_db, bool success) {
-              storage_db->LoadKeysCallback(success);
-            },
-            storage_db, success));
-    RunUntilIdle();
-  }
-  void UpdateCallback(FakeDB<JournalStorageProto>* storage_db, bool success) {
-    task_runner()->PostTask(
-        FROM_HERE,
-        base::BindOnce(
-            [](FakeDB<JournalStorageProto>* storage_db, bool success) {
-              storage_db->UpdateCallback(success);
-            },
-            storage_db, success));
-    RunUntilIdle();
-  }
-
-  void RunUntilIdle() { task_environment_.RunUntilIdle(); }
-
-  scoped_refptr<base::SequencedTaskRunner> task_runner() {
-    return task_runner_;
-  }
-
-  FakeDB<JournalStorageProto>* storage_db() { return journal_db_; }
-
-  FeedJournalDatabase* db() { return feed_db_.get(); }
-
-  HistogramTester& histogram() { return histogram_; }
-
-  MOCK_METHOD2(OnJournalEntryReceived, void(bool, std::vector<std::string>));
-  MOCK_METHOD1(OnStorageCommitted, void(bool));
-  MOCK_METHOD2(OnCheckJournalExistReceived, void(bool, bool));
-
- private:
-  base::test::TaskEnvironment task_environment_;
-
-  std::map<std::string, JournalStorageProto> journal_db_storage_;
-
-  scoped_refptr<base::SequencedTaskRunner> task_runner_;
-
-  // Owned by |feed_db_|.
-  FakeDB<JournalStorageProto>* journal_db_;
-
-  std::unique_ptr<FeedJournalDatabase> feed_db_;
-
-  HistogramTester histogram_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedJournalDatabaseTest);
-};
-
-TEST_F(FeedJournalDatabaseTest, Init) {
-  ASSERT_FALSE(db());
-
-  CreateDatabase(/*init_database=*/false);
-
-  EXPECT_FALSE(db()->IsInitialized());
-  InitStatusCallback(storage_db(), leveldb_proto::Enums::InitStatus::kOK);
-  EXPECT_TRUE(db()->IsInitialized());
-}
-
-TEST_F(FeedJournalDatabaseTest, LoadJournalEntry) {
-  CreateDatabase(/*init_database=*/true);
-  EXPECT_TRUE(db()->IsInitialized());
-
-  // Store |kJournalKey1| and |kJournalKey2|.
-  InjectJournalStorageProto(kJournalKey1,
-                            {kJournalData1, kJournalData2, kJournalData3});
-  InjectJournalStorageProto(kJournalKey2, {kJournalData4});
-
-  // Try to Load |kJournalKey1|.
-  EXPECT_CALL(*this, OnJournalEntryReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 3U);
-        EXPECT_EQ(results[0], kJournalData1);
-        EXPECT_EQ(results[1], kJournalData2);
-        EXPECT_EQ(results[2], kJournalData3);
-      });
-  db()->LoadJournal(
-      kJournalKey1,
-      base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), true);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1);
-}
-
-TEST_F(FeedJournalDatabaseTest, LoadNonExistingJournalEntry) {
-  CreateDatabase(/*init_database=*/true);
-  EXPECT_TRUE(db()->IsInitialized());
-
-  // Try to Load |kJournalKey1|.
-  EXPECT_CALL(*this, OnJournalEntryReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 0U);
-      });
-  db()->LoadJournal(
-      kJournalKey1,
-      base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), true);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1);
-}
-
-TEST_F(FeedJournalDatabaseTest, AppendJournal) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Save |kJournalKey1|.
-  auto journal_mutation = std::make_unique<JournalMutation>(kJournalKey1);
-  journal_mutation->AddAppendOperation(kJournalData1);
-  journal_mutation->AddAppendOperation(kJournalData2);
-  EXPECT_CALL(*this, OnStorageCommitted(true));
-  db()->CommitJournalMutation(
-      std::move(journal_mutation),
-      base::BindOnce(&FeedJournalDatabaseTest::OnStorageCommitted,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), true);
-  UpdateCallback(storage_db(), true);
-
-  // Make sure they're there.
-  EXPECT_CALL(*this, OnJournalEntryReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 2U);
-        EXPECT_EQ(results[0], kJournalData1);
-        EXPECT_EQ(results[1], kJournalData2);
-      });
-  db()->LoadJournal(
-      kJournalKey1,
-      base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), true);
-
-  histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName,
-                                /*operations=*/2, 1);
-  histogram().ExpectTotalCount(kUmaOperationCommitTimeHistogramName, 1);
-
-  Mock::VerifyAndClearExpectations(this);
-
-  // Append more for |kJournalKey1|.
-  journal_mutation = std::make_unique<JournalMutation>(kJournalKey1);
-  journal_mutation->AddAppendOperation(kJournalData3);
-  journal_mutation->AddAppendOperation(kJournalData4);
-  journal_mutation->AddAppendOperation(kJournalData5);
-  EXPECT_CALL(*this, OnStorageCommitted(true));
-  db()->CommitJournalMutation(
-      std::move(journal_mutation),
-      base::BindOnce(&FeedJournalDatabaseTest::OnStorageCommitted,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), true);
-  UpdateCallback(storage_db(), true);
-
-  // Check new instances are there.
-  EXPECT_CALL(*this, OnJournalEntryReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 5U);
-        EXPECT_EQ(results[0], kJournalData1);
-        EXPECT_EQ(results[1], kJournalData2);
-        EXPECT_EQ(results[2], kJournalData3);
-        EXPECT_EQ(results[3], kJournalData4);
-        EXPECT_EQ(results[4], kJournalData5);
-      });
-  db()->LoadJournal(
-      kJournalKey1,
-      base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), true);
-
-  histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName,
-                                /*operations=*/3, 1);
-  histogram().ExpectTotalCount(kUmaOperationCommitTimeHistogramName, 2);
-}
-
-TEST_F(FeedJournalDatabaseTest, CopyJournal) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Save |kJournalKey1|.
-  InjectJournalStorageProto(kJournalKey1, {kJournalData1, kJournalData2});
-
-  // Copy |kJournalKey1| to |kJournalKey2|.
-  auto journal_mutation = std::make_unique<JournalMutation>(kJournalKey1);
-  journal_mutation->AddCopyOperation(kJournalKey2);
-  journal_mutation->AddAppendOperation(kJournalData3);
-  journal_mutation->AddAppendOperation(kJournalData4);
-  journal_mutation->AddCopyOperation(kJournalKey3);
-  EXPECT_CALL(*this, OnStorageCommitted(true));
-  db()->CommitJournalMutation(
-      std::move(journal_mutation),
-      base::BindOnce(&FeedJournalDatabaseTest::OnStorageCommitted,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), true);
-  UpdateCallback(storage_db(), true);
-
-  histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName,
-                                /*operations=*/4, 1);
-  histogram().ExpectTotalCount(kUmaOperationCommitTimeHistogramName, 1);
-
-  // Check new journal is there.
-  EXPECT_CALL(*this, OnJournalEntryReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 2U);
-        EXPECT_EQ(results[0], kJournalData1);
-        EXPECT_EQ(results[1], kJournalData2);
-      });
-  db()->LoadJournal(
-      kJournalKey2,
-      base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), true);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1);
-
-  Mock::VerifyAndClearExpectations(this);
-
-  // Check new journal is there.
-  EXPECT_CALL(*this, OnJournalEntryReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 4U);
-        EXPECT_EQ(results[0], kJournalData1);
-        EXPECT_EQ(results[1], kJournalData2);
-        EXPECT_EQ(results[2], kJournalData3);
-        EXPECT_EQ(results[3], kJournalData4);
-      });
-  db()->LoadJournal(
-      kJournalKey3,
-      base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), true);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 2);
-
-  Mock::VerifyAndClearExpectations(this);
-
-  // Check first journal is still there.
-  EXPECT_CALL(*this, OnJournalEntryReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 4U);
-        EXPECT_EQ(results[0], kJournalData1);
-        EXPECT_EQ(results[1], kJournalData2);
-        EXPECT_EQ(results[2], kJournalData3);
-        EXPECT_EQ(results[3], kJournalData4);
-      });
-  db()->LoadJournal(
-      kJournalKey1,
-      base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), true);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 3);
-}
-
-TEST_F(FeedJournalDatabaseTest, DeleteJournal) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Store |kJournalKey1|, |kJournalKey2|.
-  InjectJournalStorageProto(kJournalKey1,
-                            {kJournalData1, kJournalData2, kJournalData3});
-  InjectJournalStorageProto(kJournalKey2, {kJournalData4, kJournalData5});
-
-  // Delete |kJournalKey2|.
-  auto journal_mutation = std::make_unique<JournalMutation>(kJournalKey2);
-  journal_mutation->AddDeleteOperation();
-  EXPECT_CALL(*this, OnStorageCommitted(true));
-  db()->CommitJournalMutation(
-      std::move(journal_mutation),
-      base::BindOnce(&FeedJournalDatabaseTest::OnStorageCommitted,
-                     base::Unretained(this)));
-  RunUntilIdle();
-  UpdateCallback(storage_db(), true);
-
-  histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName,
-                                /*operations=*/1, 1);
-  histogram().ExpectTotalCount(kUmaOperationCommitTimeHistogramName, 1);
-
-  // Make sure |kJournalKey2| got deleted.
-  EXPECT_CALL(*this, OnJournalEntryReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 0U);
-      });
-  db()->LoadJournal(
-      kJournalKey2,
-      base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), true);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1);
-
-  Mock::VerifyAndClearExpectations(this);
-
-  // Make sure |kJournalKey1| is still there.
-  EXPECT_CALL(*this, OnJournalEntryReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 3U);
-        EXPECT_EQ(results[0], kJournalData1);
-        EXPECT_EQ(results[1], kJournalData2);
-        EXPECT_EQ(results[2], kJournalData3);
-      });
-  db()->LoadJournal(
-      kJournalKey1,
-      base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), true);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 2);
-}
-
-TEST_F(FeedJournalDatabaseTest, ChecExistingJournal) {
-  CreateDatabase(/*init_database=*/true);
-  EXPECT_TRUE(db()->IsInitialized());
-
-  // Store |kJournalKey1| and |kJournalKey2|.
-  InjectJournalStorageProto(kJournalKey1,
-                            {kJournalData1, kJournalData2, kJournalData3});
-  InjectJournalStorageProto(kJournalKey2, {kJournalData4});
-
-  // Check |kJournalKey1|.
-  EXPECT_CALL(*this, OnCheckJournalExistReceived(true, true));
-
-  db()->DoesJournalExist(
-      kJournalKey1,
-      base::BindOnce(&FeedJournalDatabaseTest::OnCheckJournalExistReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), true);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1);
-}
-
-TEST_F(FeedJournalDatabaseTest, CheckNonExistingJournal) {
-  CreateDatabase(/*init_database=*/true);
-  EXPECT_TRUE(db()->IsInitialized());
-
-  // Check |kJournalKey1|.
-  EXPECT_CALL(*this, OnCheckJournalExistReceived(true, false));
-  db()->DoesJournalExist(
-      kJournalKey1,
-      base::BindOnce(&FeedJournalDatabaseTest::OnCheckJournalExistReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), true);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1);
-}
-
-TEST_F(FeedJournalDatabaseTest, LoadAllJournalKeys) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Store |kJournalKey1|, |kJournalKey2| and |kJournalKey3|.
-  InjectJournalStorageProto(kJournalKey1,
-                            {kJournalData1, kJournalData2, kJournalData3});
-  InjectJournalStorageProto(kJournalKey2, {kJournalData4, kJournalData5});
-  InjectJournalStorageProto(kJournalKey3, {kJournalData6});
-
-  EXPECT_CALL(*this, OnJournalEntryReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 3U);
-        EXPECT_EQ(results[0], kJournalKey1);
-        EXPECT_EQ(results[1], kJournalKey2);
-        EXPECT_EQ(results[2], kJournalKey3);
-      });
-  db()->LoadAllJournalKeys(
-      base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived,
-                     base::Unretained(this)));
-  LoadKeysCallback(storage_db(), true);
-
-  histogram().ExpectBucketCount(kUmaSizeHistogramName,
-                                /*size=*/3, 1);
-  histogram().ExpectTotalCount(kUmaLoadKeysTimeHistogramName, 1);
-}
-
-TEST_F(FeedJournalDatabaseTest, DeleteAllJournals) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Store |kJournalKey1|, |kJournalKey2|, |kJournalKey3|.
-  InjectJournalStorageProto(kJournalKey1,
-                            {kJournalData1, kJournalData2, kJournalData3});
-  InjectJournalStorageProto(kJournalKey2, {kJournalData4, kJournalData5});
-  InjectJournalStorageProto(kJournalKey3, {kJournalData6});
-
-  // Delete all journals, meaning |kJournalKey1|, |kJournalKey2| and
-  // |kJournalKey3| are expected to be deleted.
-  EXPECT_CALL(*this, OnStorageCommitted(true));
-  db()->DeleteAllJournals(base::BindOnce(
-      &FeedJournalDatabaseTest::OnStorageCommitted, base::Unretained(this)));
-  UpdateCallback(storage_db(), true);
-
-  histogram().ExpectTotalCount(kUmaOperationCommitTimeHistogramName, 1);
-
-  // Make sure all journals got deleted.
-  EXPECT_CALL(*this, OnJournalEntryReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_TRUE(success);
-        ASSERT_EQ(results.size(), 0U);
-      });
-  db()->LoadAllJournalKeys(
-      base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived,
-                     base::Unretained(this)));
-  LoadKeysCallback(storage_db(), true);
-
-  histogram().ExpectBucketCount(kUmaSizeHistogramName,
-                                /*size=*/0, 1);
-  histogram().ExpectTotalCount(kUmaLoadKeysTimeHistogramName, 1);
-}
-
-TEST_F(FeedJournalDatabaseTest, LoadJournalEntryFail) {
-  CreateDatabase(/*init_database=*/true);
-  EXPECT_TRUE(db()->IsInitialized());
-
-  // Store |kJournalKey1| and |kJournalKey2|.
-  InjectJournalStorageProto(kJournalKey1,
-                            {kJournalData1, kJournalData2, kJournalData3});
-  InjectJournalStorageProto(kJournalKey2, {kJournalData4});
-
-  // Try to Load |kJournalKey1|.
-  EXPECT_CALL(*this, OnJournalEntryReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_FALSE(success);
-      });
-  db()->LoadJournal(
-      kJournalKey1,
-      base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), false);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1);
-}
-
-TEST_F(FeedJournalDatabaseTest, LoadNonExistingJournalEntryFail) {
-  CreateDatabase(/*init_database=*/true);
-  EXPECT_TRUE(db()->IsInitialized());
-
-  // Try to Load |kJournalKey1|.
-  EXPECT_CALL(*this, OnJournalEntryReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_FALSE(success);
-      });
-  db()->LoadJournal(
-      kJournalKey1,
-      base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), false);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1);
-}
-
-TEST_F(FeedJournalDatabaseTest, LoadAllJournalKeysFail) {
-  CreateDatabase(/*init_database=*/true);
-
-  // Store |kJournalKey1|, |kJournalKey2| and |kJournalKey3|.
-  InjectJournalStorageProto(kJournalKey1,
-                            {kJournalData1, kJournalData2, kJournalData3});
-  InjectJournalStorageProto(kJournalKey2, {kJournalData4, kJournalData5});
-  InjectJournalStorageProto(kJournalKey3, {kJournalData6});
-
-  EXPECT_CALL(*this, OnJournalEntryReceived(_, _))
-      .WillOnce([](bool success, std::vector<std::string> results) {
-        EXPECT_FALSE(success);
-      });
-  db()->LoadAllJournalKeys(
-      base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived,
-                     base::Unretained(this)));
-  LoadKeysCallback(storage_db(), false);
-
-  histogram().ExpectTotalCount(kUmaSizeHistogramName, 0);
-  histogram().ExpectTotalCount(kUmaLoadKeysTimeHistogramName, 1);
-}
-
-TEST_F(FeedJournalDatabaseTest, ChecExistingJournalFail) {
-  CreateDatabase(/*init_database=*/true);
-  EXPECT_TRUE(db()->IsInitialized());
-
-  // Store |kJournalKey1| and |kJournalKey2|.
-  InjectJournalStorageProto(kJournalKey1,
-                            {kJournalData1, kJournalData2, kJournalData3});
-  InjectJournalStorageProto(kJournalKey2, {kJournalData4});
-
-  // Check |kJournalKey1|.
-  EXPECT_CALL(*this, OnCheckJournalExistReceived(false, true));
-
-  db()->DoesJournalExist(
-      kJournalKey1,
-      base::BindOnce(&FeedJournalDatabaseTest::OnCheckJournalExistReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), false);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1);
-}
-
-TEST_F(FeedJournalDatabaseTest, CheckNonExistingJournalFail) {
-  CreateDatabase(/*init_database=*/true);
-  EXPECT_TRUE(db()->IsInitialized());
-
-  // Check |kJournalKey1|.
-  EXPECT_CALL(*this, OnCheckJournalExistReceived(false, false));
-  db()->DoesJournalExist(
-      kJournalKey1,
-      base::BindOnce(&FeedJournalDatabaseTest::OnCheckJournalExistReceived,
-                     base::Unretained(this)));
-  GetCallback(storage_db(), false);
-
-  histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1);
-}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_journal_mutation.cc b/components/feed/core/feed_journal_mutation.cc
deleted file mode 100644
index 1ff1321..0000000
--- a/components/feed/core/feed_journal_mutation.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_journal_mutation.h"
-
-#include <utility>
-
-#include "base/check.h"
-
-namespace feed {
-
-JournalMutation::JournalMutation(std::string journal_name)
-    : journal_name_(std::move(journal_name)),
-      start_time_(base::TimeTicks::Now()) {}
-
-JournalMutation::~JournalMutation() = default;
-
-void JournalMutation::AddAppendOperation(std::string value) {
-  operations_list_.emplace_back(
-      JournalOperation::CreateAppendOperation(std::move(value)));
-}
-
-void JournalMutation::AddCopyOperation(std::string to_journal_name) {
-  operations_list_.emplace_back(
-      JournalOperation::CreateCopyOperation(std::move(to_journal_name)));
-}
-
-void JournalMutation::AddDeleteOperation() {
-  operations_list_.emplace_back(JournalOperation::CreateDeleteOperation());
-}
-
-const std::string& JournalMutation::journal_name() {
-  return journal_name_;
-}
-
-bool JournalMutation::Empty() {
-  return operations_list_.empty();
-}
-
-size_t JournalMutation::Size() const {
-  return operations_list_.size();
-}
-
-base::TimeTicks JournalMutation::GetStartTime() const {
-  return start_time_;
-}
-
-JournalOperation JournalMutation::TakeFirstOperation() {
-  JournalOperation operation = std::move(operations_list_.front());
-  operations_list_.pop_front();
-  return operation;
-}
-
-JournalOperation::Type JournalMutation::FirstOperationType() {
-  DCHECK(!operations_list_.empty());
-  return operations_list_.front().type();
-}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_journal_mutation.h b/components/feed/core/feed_journal_mutation.h
deleted file mode 100644
index bdbf598..0000000
--- a/components/feed/core/feed_journal_mutation.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_FEED_JOURNAL_MUTATION_H_
-#define COMPONENTS_FEED_CORE_FEED_JOURNAL_MUTATION_H_
-
-#include <list>
-#include <string>
-
-#include "base/macros.h"
-#include "base/time/time.h"
-#include "components/feed/core/feed_journal_operation.h"
-
-namespace feed {
-
-// Native counterpart of JournalMutation.java.
-// To commit a set of JournalOperation into FeedJournalDatabase, first,
-// JournalMutation need to be created, then use Add* methods to add operations
-// into the mutation, and pass the JournalMutation to
-// FeedJournalDatabase::CommitJournalMutation to commit operations.
-class JournalMutation {
- public:
-  explicit JournalMutation(std::string journal_name);
-  ~JournalMutation();
-
-  void AddAppendOperation(std::string value);
-  void AddCopyOperation(std::string to_journal_name);
-  void AddDeleteOperation();
-
-  const std::string& journal_name();
-
-  // Check if mutation has JournalOperation left.
-  bool Empty();
-
-  // Return the number of operations in the mutation.
-  size_t Size() const;
-
-  base::TimeTicks GetStartTime() const;
-
-  // This will remove the first JournalOperation in |operations_list_| and
-  // return it to caller.
-  JournalOperation TakeFirstOperation();
-
-  JournalOperation::Type FirstOperationType();
-
- private:
-  const std::string journal_name_;
-
-  std::list<JournalOperation> operations_list_;
-
-  const base::TimeTicks start_time_;
-
-  DISALLOW_COPY_AND_ASSIGN(JournalMutation);
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CORE_FEED_JOURNAL_MUTATION_H_
diff --git a/components/feed/core/feed_journal_mutation_unittest.cc b/components/feed/core/feed_journal_mutation_unittest.cc
deleted file mode 100644
index 63ba4d5..0000000
--- a/components/feed/core/feed_journal_mutation_unittest.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_journal_mutation.h"
-
-#include "components/feed/core/feed_journal_operation.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace feed {
-
-namespace {
-
-const char kJournalName1[] = "Journal1";
-const char kJournalName2[] = "Journal2";
-const uint8_t kJournalValue[] = {
-    8,   1,   18,  40,  70,  69,  65,   84,  85,  82,  69, 58, 58,
-    115, 116, 111, 114, 105, 101, 115,  46,  102, 58,  58, 45, 56,
-    57,  48,  56,  51,  51,  54,  49,   56,  52,  53,  48, 48, 54,
-    55,  56,  48,  51,  57,  24,  -119, -10, -71, -35, 5};
-
-}  // namespace
-
-class FeedJournalMutationTest : public testing::Test {
- public:
-  FeedJournalMutationTest() = default;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FeedJournalMutationTest);
-};
-
-TEST_F(FeedJournalMutationTest, AddAppendOperation) {
-  JournalMutation mutation(kJournalName1);
-  EXPECT_EQ(mutation.journal_name(), kJournalName1);
-  EXPECT_TRUE(mutation.Empty());
-
-  std::vector<uint8_t> bytes_vector(
-      kJournalValue,
-      kJournalValue + sizeof(kJournalValue) / sizeof(kJournalValue[0]));
-
-  mutation.AddAppendOperation(
-      std::string(bytes_vector.begin(), bytes_vector.end()));
-  EXPECT_FALSE(mutation.Empty());
-
-  JournalOperation operation = mutation.TakeFirstOperation();
-  EXPECT_TRUE(mutation.Empty());
-  EXPECT_EQ(operation.type(), JournalOperation::JOURNAL_APPEND);
-  EXPECT_EQ(operation.value(),
-            std::string(bytes_vector.begin(), bytes_vector.end()));
-}
-
-TEST_F(FeedJournalMutationTest, AddCopyOperation) {
-  JournalMutation mutation(kJournalName1);
-  EXPECT_EQ(mutation.journal_name(), kJournalName1);
-  EXPECT_TRUE(mutation.Empty());
-
-  mutation.AddCopyOperation(kJournalName2);
-  EXPECT_FALSE(mutation.Empty());
-
-  JournalOperation operation = mutation.TakeFirstOperation();
-  EXPECT_TRUE(mutation.Empty());
-  EXPECT_EQ(operation.type(), JournalOperation::JOURNAL_COPY);
-  EXPECT_EQ(operation.to_journal_name(), kJournalName2);
-}
-
-TEST_F(FeedJournalMutationTest, AddDeleteOperation) {
-  JournalMutation mutation(kJournalName1);
-  EXPECT_EQ(mutation.journal_name(), kJournalName1);
-  EXPECT_TRUE(mutation.Empty());
-
-  mutation.AddDeleteOperation();
-  EXPECT_FALSE(mutation.Empty());
-
-  JournalOperation operation = mutation.TakeFirstOperation();
-  EXPECT_TRUE(mutation.Empty());
-  EXPECT_EQ(operation.type(), JournalOperation::JOURNAL_DELETE);
-}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_journal_operation.cc b/components/feed/core/feed_journal_operation.cc
deleted file mode 100644
index 803114cb..0000000
--- a/components/feed/core/feed_journal_operation.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_journal_operation.h"
-
-#include <utility>
-
-#include "base/check_op.h"
-
-namespace feed {
-
-// static
-JournalOperation JournalOperation::CreateAppendOperation(std::string value) {
-  return JournalOperation(JOURNAL_APPEND, std::move(value), std::string());
-}
-
-// static
-JournalOperation JournalOperation::CreateCopyOperation(
-    std::string to_journal_name) {
-  return JournalOperation(JOURNAL_COPY, std::string(),
-                          std::move(to_journal_name));
-}
-
-// static
-JournalOperation JournalOperation::CreateDeleteOperation() {
-  return JournalOperation(JOURNAL_DELETE, std::string(), std::string());
-}
-
-JournalOperation::JournalOperation(JournalOperation&& operation) = default;
-
-JournalOperation::Type JournalOperation::type() {
-  return type_;
-}
-
-const std::string& JournalOperation::value() {
-  DCHECK_EQ(type_, JOURNAL_APPEND);
-  return value_;
-}
-
-const std::string& JournalOperation::to_journal_name() {
-  DCHECK_EQ(type_, JOURNAL_COPY);
-  return to_journal_name_;
-}
-
-JournalOperation::JournalOperation(Type type,
-                                   std::string value,
-                                   std::string to_journal_name)
-    : type_(type),
-      value_(std::move(value)),
-      to_journal_name_(std::move(to_journal_name)) {}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_journal_operation.h b/components/feed/core/feed_journal_operation.h
deleted file mode 100644
index 7e447950..0000000
--- a/components/feed/core/feed_journal_operation.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_FEED_JOURNAL_OPERATION_H_
-#define COMPONENTS_FEED_CORE_FEED_JOURNAL_OPERATION_H_
-
-#include <string>
-
-#include "base/macros.h"
-
-namespace feed {
-
-// Native counterpart of JournalOperation.java.
-class JournalOperation {
- public:
-  enum Type {
-    JOURNAL_APPEND,
-    JOURNAL_COPY,
-    JOURNAL_DELETE,
-  };
-
-  static JournalOperation CreateAppendOperation(std::string value);
-  static JournalOperation CreateCopyOperation(std::string to_journal_name);
-  static JournalOperation CreateDeleteOperation();
-
-  JournalOperation(JournalOperation&& operation);
-
-  Type type();
-  const std::string& value();
-  const std::string& to_journal_name();
-
- private:
-  JournalOperation(Type type, std::string value, std::string to_journal_name);
-
-  const Type type_;
-
-  // Used for JOURNAL_APPEND, |value_| will be append to the end of journal.
-  const std::string value_;
-
-  // Used for JOURNAL_COPY, copy current journal to |to_journal_name_|.
-  const std::string to_journal_name_;
-
-  DISALLOW_COPY_AND_ASSIGN(JournalOperation);
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CORE_FEED_JOURNAL_OPERATION_H_
diff --git a/components/feed/core/feed_logging_metrics.cc b/components/feed/core/feed_logging_metrics.cc
deleted file mode 100644
index 55fec7919..0000000
--- a/components/feed/core/feed_logging_metrics.cc
+++ /dev/null
@@ -1,769 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_logging_metrics.h"
-
-#include <cmath>
-#include <string>
-#include <type_traits>
-
-#include "base/bind.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/metrics/user_metrics.h"
-#include "base/strings/stringprintf.h"
-#include "base/time/clock.h"
-#include "base/time/time.h"
-#include "components/feed/core/feed_scheduler_host.h"
-#include "ui/base/mojom/window_open_disposition.mojom.h"
-
-namespace feed {
-
-namespace {
-
-//  Instead of using base::UMA_HISTOGRAM_TIMES which has 50 buckets, we use 20
-//  buckets here.
-#define TASK_CUSTOM_UMA_HISTOGRAM_TIMES(histogram_name, time)         \
-  UMA_HISTOGRAM_CUSTOM_TIMES(histogram_name,                          \
-                             base::TimeDelta::FromMilliseconds(time), \
-                             base::TimeDelta::FromMilliseconds(1),    \
-                             base::TimeDelta::FromSeconds(10), 20);
-
-#define REPORT_TASK_HISTOGRAM_TIMES(histogram_base, delay_time, task_time) \
-  TASK_CUSTOM_UMA_HISTOGRAM_TIMES(                                         \
-      base::StringPrintf("%s.%s", histogram_base.c_str(), "DelayTime"),    \
-      delay_time);                                                         \
-  TASK_CUSTOM_UMA_HISTOGRAM_TIMES(                                         \
-      base::StringPrintf("%s.%s", histogram_base.c_str(), "TaskTime"),     \
-      task_time);
-
-#define AGE_CUSTOM_UMA_HISTOGRAM_TIMES(histogram_name, time)  \
-  UMA_HISTOGRAM_CUSTOM_TIMES(histogram_name, time,            \
-                             base::TimeDelta::FromSeconds(1), \
-                             base::TimeDelta::FromDays(7), 100);
-
-// The constant integers(bucket sizes) and strings(UMA names) in this file need
-// matching with Zine's in the file
-// components/ntp_snippets/content_suggestions_metrics.cc. The purpose to have
-// identical bucket sizes and names with Zine is for comparing Feed with Zine
-// easily. After Zine is deprecated, we can change the values if we needed.
-
-// Constants used as max sample sizes for histograms.
-const int kMaxContentCount = 50;
-const int kMaxFailureCount = 10;
-const int kMaxSuggestionsTotal = 50;
-const int kMaxTokenCount = 10;
-
-// Keep in sync with MAX_SUGGESTIONS_PER_SECTION in NewTabPageUma.java.
-const int kMaxSuggestionsForArticle = 20;
-
-const char kHistogramArticlesUsageTimeLocal[] =
-    "NewTabPage.ContentSuggestions.UsageTimeLocal";
-
-// Values correspond to
-// third_party/feed_library/src/
-//   src/main/java/com/google/android/libraries/feed/host/
-// logging/SpinnerType.java, enums.xml and histograms.xml.
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused.
-enum class SpinnerType {
-  KInitialLoad = 1,
-  KZeroStateRefresh = 2,
-  KMoreButton = 3,
-  KSyntheticToken = 4,
-  KInfiniteFeed = 5,
-  kMaxValue = KInfiniteFeed
-};
-
-// Values correspond to
-// third_party/feed_library/src/
-//   src/main/java/com/google/android/libraries/feed/host/
-// logging/Task.java.
-enum class TaskType {
-  KUnknown = 0,
-  KCleanUpSessionJournals = 1,
-  KClearAll = 2,
-  KClearAllWithRefresh = 3,
-  KClearPersistentStoreTask = 4,
-  KCommitTask = 5,
-  KCreateAndUpload = 6,
-  KDetachSession = 7,
-  KDismissLocal = 8,
-  KDumpEphemeralActions = 9,
-  KExecuteUploadActionRequest = 10,
-  KGarbageCollectContent = 11,
-  KGetExistingSession = 12,
-  KGetNewSession = 13,
-  KGetStreamFeaturesFromHead = 14,
-  KHandleResponseBytes = 15,
-  KHandleSyntheticToken = 16,
-  KHandleToken = 17,
-  KHandleUploadableActionResponseBytes = 18,
-  KInvalidateHead = 19,
-  KInvalidateSession = 20,
-  KLocalActionGC = 21,
-  KNoCardErrorClear = 22,
-  KPersistMutation = 23,
-  KPopulateNewSession = 24,
-  KRequestFailure = 25,
-  KRequestManagerTriggerRefresh = 26,
-  KSendRequest = 27,
-  KSessionManagerTriggerRefresh = 28,
-  KSessionMutation = 29,
-  KTaskQueueInitialize = 30,
-  KUpdateContentTracker = 31,
-  KUploadAllActionsForURL = 32,
-  kMaxValue = KUploadAllActionsForURL
-};
-
-// Values correspond to
-// third_party/feed_library/src/
-//   main/proto/search/now/ui/action/feed_action.proto.
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused.
-enum class ElementType {
-  KUnknownElementType = 0,
-  KCardLargeImage = 1,
-  KCardSmallImage = 2,
-  KInterestHeader = 3,
-  KTooltip = 4,
-  kMaxValue = KTooltip
-};
-
-// Each suffix here should correspond to an entry under histogram suffix
-// FeedSpinnerType in histograms.xml.
-std::string GetSpinnerTypeSuffix(SpinnerType spinner_type) {
-  switch (spinner_type) {
-    case SpinnerType::KInitialLoad:
-      return "InitialLoad";
-    case SpinnerType::KZeroStateRefresh:
-      return "ZeroStateRefresh";
-    case SpinnerType::KMoreButton:
-      return "MoreButton";
-    case SpinnerType::KSyntheticToken:
-      return "SyntheticToken";
-    case SpinnerType::KInfiniteFeed:
-      return "InfiniteFeed";
-  }
-
-  // TODO(https://crbug.com/935602): Handle new values when adding new values on
-  // java side.
-  NOTREACHED();
-  return std::string();
-}
-
-// Each suffix here should correspond to an entry under histogram suffix
-// FeedElementType in histograms.xml.
-std::string GetElementTypeSuffix(ElementType element_type) {
-  switch (element_type) {
-    case ElementType::KUnknownElementType:
-      return "UnknownElementType";
-    case ElementType::KCardLargeImage:
-      return "CardLargeImage";
-    case ElementType::KCardSmallImage:
-      return "CardSmallImage";
-    case ElementType::KInterestHeader:
-      return "InterestHeader";
-    case ElementType::KTooltip:
-      return "Tooltip";
-  }
-
-  NOTREACHED();
-  return std::string();
-}
-
-// Each suffix here should correspond to an entry under histogram suffix
-// FeedTaskType in histograms.xml.
-void ReportTaskTime(TaskType task_type, int delay_time_ms, int task_time_ms) {
-  switch (task_type) {
-    case TaskType::KUnknown:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s", "Unknown"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KCleanUpSessionJournals:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "CleanUpSessionJournals"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KClearAll:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s", "ClearAll"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KClearAllWithRefresh:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "ClearAllWithRefresh"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KClearPersistentStoreTask:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "ClearPersistentStoreTask"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KCommitTask:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s", "CommitTask"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KCreateAndUpload:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "CreateAndUpload"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KDetachSession:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "DetachSession"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KDismissLocal:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s", "DismissLocal"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KDumpEphemeralActions:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "DumpEphemeralActions"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KExecuteUploadActionRequest:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "ExecuteUploadActionRequest"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KGarbageCollectContent:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "GarbageCollectContent"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KGetExistingSession:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "GetExistingSession"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KGetNewSession:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "GetNewSession"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KGetStreamFeaturesFromHead:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "GetStreamFeaturesFromHead"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KHandleResponseBytes:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "HandleResponseBytes"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KHandleSyntheticToken:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "HandleSyntheticToken"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KHandleToken:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s", "HandleToken"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KHandleUploadableActionResponseBytes:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "HandleUploadableActionResponseBytes"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KInvalidateHead:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "InvalidateHead"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KInvalidateSession:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "InvalidateSession"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KLocalActionGC:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "LocalActionGC"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KNoCardErrorClear:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "NoCardErrorClear"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KPersistMutation:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "PersistMutation"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KPopulateNewSession:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "PopulateNewSession"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KRequestFailure:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "RequestFailure"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KRequestManagerTriggerRefresh:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "RequestManagerTriggerRefresh"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KSendRequest:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s", "SendRequest"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KSessionManagerTriggerRefresh:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "SessionManagerTriggerRefresh"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KSessionMutation:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "SessionMutation"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KTaskQueueInitialize:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "TaskQueueInitialize"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KUpdateContentTracker:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "UpdateContentTracker"),
-          delay_time_ms, task_time_ms);
-      break;
-    case TaskType::KUploadAllActionsForURL:
-      REPORT_TASK_HISTOGRAM_TIMES(
-          base::StringPrintf("ContentSuggestions.Feed.Task.%s",
-                             "UploadAllActionsForURL"),
-          delay_time_ms, task_time_ms);
-      break;
-  }
-}
-
-// Records ContentSuggestions usage. Therefore the day is sliced into 20min
-// buckets. Depending on the current local time the count of the corresponding
-// bucket is increased.
-void RecordContentSuggestionsUsage(base::Time now) {
-  const int kBucketSizeMins = 20;
-  const int kNumBuckets = 24 * 60 / kBucketSizeMins;
-
-  base::Time::Exploded now_exploded;
-  now.LocalExplode(&now_exploded);
-  int bucket = (now_exploded.hour * 60 + now_exploded.minute) / kBucketSizeMins;
-
-  const char* kWeekdayNames[] = {"Sunday",   "Monday", "Tuesday", "Wednesday",
-                                 "Thursday", "Friday", "Saturday"};
-  std::string histogram_name(
-      base::StringPrintf("%s.%s", kHistogramArticlesUsageTimeLocal,
-                         kWeekdayNames[now_exploded.day_of_week]));
-  // Since the |histogram_name| is dynamic, we can't use the regular macro.
-  base::UmaHistogramExactLinear(histogram_name, bucket, kNumBuckets);
-  UMA_HISTOGRAM_EXACT_LINEAR(kHistogramArticlesUsageTimeLocal, bucket,
-                             kNumBuckets);
-
-  base::RecordAction(
-      base::UserMetricsAction("NewTabPage_ContentSuggestions_ArticlesUsage"));
-}
-
-int ToUMAScore(float score) {
-  // Scores are typically reported in a range of (0,1]. As UMA does not support
-  // floats, we put them on a discrete scale of [1,10]. We keep the extra bucket
-  // 11 for unexpected over-flows as we want to distinguish them from scores
-  // close to 1. For instance, the discrete value 1 represents score values
-  // within (0.0, 0.1].
-  return ceil(score * 10);
-}
-
-void RecordSuggestionPageVisited(bool return_to_ntp) {
-  if (return_to_ntp) {
-    base::RecordAction(
-        base::UserMetricsAction("MobileNTP.Snippets.VisitEndBackInNTP"));
-  }
-  base::RecordAction(base::UserMetricsAction("MobileNTP.Snippets.VisitEnd"));
-}
-
-void RecordUndoableActionUMA(const std::string& histogram_base,
-                             int position,
-                             bool committed) {
-  std::string histogram_name =
-      histogram_base + (committed ? ".Commit" : ".Undo");
-
-  // Since the |histogram_name| is dynamic, we can't use the regular macro.
-  base::UmaHistogramExactLinear(histogram_name, position, kMaxSuggestionsTotal);
-
-  // Report to |histogram_base| as well, then |histogram_base| will be the sum
-  // of "Commit" and "Undo".
-  base::UmaHistogramExactLinear(histogram_base, position, kMaxSuggestionsTotal);
-}
-
-void CheckURLVisitedDone(int position, bool committed, bool visited) {
-  if (visited) {
-    RecordUndoableActionUMA("NewTabPage.ContentSuggestions.DismissedVisited",
-                            position, committed);
-  } else {
-    RecordUndoableActionUMA("NewTabPage.ContentSuggestions.DismissedUnvisited",
-                            position, committed);
-  }
-}
-
-void RecordSpinnerTimeUMA(const char* base_name,
-                          const base::TimeDelta& time,
-                          int spinner_type) {
-  SpinnerType type = static_cast<SpinnerType>(spinner_type);
-  std::string suffix = GetSpinnerTypeSuffix(type);
-  std::string histogram_name(
-      base::StringPrintf("%s.%s", base_name, suffix.c_str()));
-  base::UmaHistogramTimes(histogram_name, time);
-  base::UmaHistogramTimes(base_name, time);
-}
-
-void RecordElementPositionUMA(const char* base_name,
-                              int position,
-                              int element_type) {
-  ElementType type = static_cast<ElementType>(element_type);
-  std::string suffix = GetElementTypeSuffix(type);
-  std::string histogram_name(
-      base::StringPrintf("%s.%s", base_name, suffix.c_str()));
-  base::UmaHistogramExactLinear(histogram_name, position, kMaxSuggestionsTotal);
-  base::UmaHistogramExactLinear(base_name, position, kMaxSuggestionsTotal);
-}
-
-void RecordElementTimeUMA(const char* base_name,
-                          const base::TimeDelta& time,
-                          int element_type) {
-  ElementType type = static_cast<ElementType>(element_type);
-  std::string suffix = GetElementTypeSuffix(type);
-  std::string histogram_name(
-      base::StringPrintf("%s.%s", base_name, suffix.c_str()));
-  base::UmaHistogramCustomTimes(histogram_name, time,
-                                base::TimeDelta::FromSeconds(1),
-                                base::TimeDelta::FromDays(7), 100);
-  base::UmaHistogramCustomTimes(base_name, time,
-                                base::TimeDelta::FromSeconds(1),
-                                base::TimeDelta::FromDays(7), 100);
-}
-
-}  // namespace
-
-FeedLoggingMetrics::FeedLoggingMetrics(
-    HistoryURLCheckCallback history_url_check_callback,
-    base::Clock* clock,
-    FeedSchedulerHost* scheduler_host)
-    : history_url_check_callback_(std::move(history_url_check_callback)),
-      clock_(clock),
-      scheduler_host_(scheduler_host) {
-  DCHECK(scheduler_host_);
-}
-
-FeedLoggingMetrics::~FeedLoggingMetrics() = default;
-
-void FeedLoggingMetrics::OnPageShown(const int suggestions_count) {
-  UMA_HISTOGRAM_EXACT_LINEAR(
-      "NewTabPage.ContentSuggestions.CountOnNtpOpenedIfVisible",
-      suggestions_count, kMaxSuggestionsTotal);
-}
-
-void FeedLoggingMetrics::OnPagePopulated(base::TimeDelta timeToPopulate) {
-  UMA_HISTOGRAM_MEDIUM_TIMES("ContentSuggestions.Feed.PagePopulatingTime",
-                             timeToPopulate);
-}
-
-void FeedLoggingMetrics::OnSuggestionShown(int position,
-                                           base::Time publish_date,
-                                           float score,
-                                           base::Time fetch_date,
-                                           bool is_available_offline) {
-  UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.Shown", position,
-                             kMaxSuggestionsTotal);
-
-  base::TimeDelta age = clock_->Now() - publish_date;
-  AGE_CUSTOM_UMA_HISTOGRAM_TIMES(
-      "NewTabPage.ContentSuggestions.ShownAge.Articles", age);
-
-  UMA_HISTOGRAM_EXACT_LINEAR(
-      "NewTabPage.ContentSuggestions.ShownScoreNormalized.Articles",
-      ToUMAScore(score), 11);
-
-  // Records the time since the fetch time of the displayed snippet.
-  base::TimeDelta fetch_age = clock_->Now() - fetch_date;
-  AGE_CUSTOM_UMA_HISTOGRAM_TIMES(
-      "NewTabPage.ContentSuggestions.TimeSinceSuggestionFetched", fetch_age);
-
-  // When the first of the articles suggestions is shown, then we count this as
-  // a single usage of content suggestions.
-  if (position == 0) {
-    RecordContentSuggestionsUsage(clock_->Now());
-  }
-
-  UMA_HISTOGRAM_BOOLEAN("ContentSuggestions.Feed.AvailableOffline.Shown",
-                        is_available_offline);
-}
-
-void FeedLoggingMetrics::OnSuggestionOpened(int position,
-                                            base::Time publish_date,
-                                            float score,
-                                            bool is_available_offline) {
-  UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.Opened", position,
-                             kMaxSuggestionsTotal);
-
-  base::TimeDelta age = clock_->Now() - publish_date;
-  AGE_CUSTOM_UMA_HISTOGRAM_TIMES(
-      "NewTabPage.ContentSuggestions.OpenedAge.Articles", age);
-
-  UMA_HISTOGRAM_EXACT_LINEAR(
-      "NewTabPage.ContentSuggestions.OpenedScoreNormalized.Articles",
-      ToUMAScore(score), 11);
-
-  RecordContentSuggestionsUsage(clock_->Now());
-
-  base::RecordAction(base::UserMetricsAction("Suggestions.Content.Opened"));
-  UMA_HISTOGRAM_BOOLEAN("ContentSuggestions.Feed.AvailableOffline.Opened",
-                        is_available_offline);
-}
-
-void FeedLoggingMetrics::OnSuggestionWindowOpened(
-    WindowOpenDisposition disposition) {
-  // We use WindowOpenDisposition::MAX_VALUE + 1 for |value_max| since MAX_VALUE
-  // itself is a valid (and used) enum value.
-  UMA_HISTOGRAM_EXACT_LINEAR(
-      "NewTabPage.ContentSuggestions.OpenDisposition.Articles",
-      static_cast<int>(disposition),
-      static_cast<int>(WindowOpenDisposition::MAX_VALUE) + 1);
-
-  if (disposition == WindowOpenDisposition::CURRENT_TAB) {
-    base::RecordAction(base::UserMetricsAction("Suggestions.Card.Tapped"));
-  }
-}
-
-void FeedLoggingMetrics::OnSuggestionMenuOpened(int position,
-                                                base::Time publish_date,
-                                                float score) {
-  UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.MenuOpened",
-                             position, kMaxSuggestionsTotal);
-
-  base::TimeDelta age = clock_->Now() - publish_date;
-  AGE_CUSTOM_UMA_HISTOGRAM_TIMES(
-      "NewTabPage.ContentSuggestions.MenuOpenedAge.Articles", age);
-
-  UMA_HISTOGRAM_EXACT_LINEAR(
-      "NewTabPage.ContentSuggestions.MenuOpenedScoreNormalized.Articles",
-      ToUMAScore(score), 11);
-}
-
-void FeedLoggingMetrics::OnSuggestionDismissed(int position,
-                                               const GURL& url,
-                                               bool committed) {
-  history_url_check_callback_.Run(
-      url, base::BindOnce(&CheckURLVisitedDone, position, committed));
-
-  base::RecordAction(base::UserMetricsAction("Suggestions.Content.Dismissed"));
-}
-
-void FeedLoggingMetrics::OnSuggestionSwiped() {
-  base::RecordAction(base::UserMetricsAction("Suggestions.Card.SwipedAway"));
-}
-
-void FeedLoggingMetrics::OnSuggestionArticleVisited(base::TimeDelta visit_time,
-                                                    bool return_to_ntp) {
-  base::UmaHistogramLongTimes(
-      "NewTabPage.ContentSuggestions.VisitDuration.Articles", visit_time);
-  RecordSuggestionPageVisited(return_to_ntp);
-}
-
-void FeedLoggingMetrics::OnMoreButtonShown(int position) {
-  // The "more" card can appear in addition to the actual suggestions, so add
-  // one extra bucket to this histogram.
-  UMA_HISTOGRAM_EXACT_LINEAR(
-      "NewTabPage.ContentSuggestions.MoreButtonShown.Articles", position,
-      kMaxSuggestionsForArticle + 1);
-}
-
-void FeedLoggingMetrics::OnMoreButtonClicked(int position) {
-  // Inform the user classifier that a suggestion was consumed
-  // (https://crbug.com/992517).
-  scheduler_host_->OnSuggestionConsumed();
-
-  // The "more" card can appear in addition to the actual suggestions, so add
-  // one extra bucket to this histogram.
-  UMA_HISTOGRAM_EXACT_LINEAR(
-      "NewTabPage.ContentSuggestions.MoreButtonClicked.Articles", position,
-      kMaxSuggestionsForArticle + 1);
-}
-
-void FeedLoggingMetrics::OnNotInterestedInSource(int position, bool committed) {
-  RecordUndoableActionUMA(
-      "ContentSuggestions.Feed.InterestHeader.NotInterestedInSource", position,
-      committed);
-}
-
-void FeedLoggingMetrics::OnNotInterestedInTopic(int position, bool committed) {
-  RecordUndoableActionUMA(
-      "ContentSuggestions.Feed.InterestHeader.NotInterestedInTopic", position,
-      committed);
-}
-
-void FeedLoggingMetrics::OnSpinnerStarted(int spinner_type) {
-  // TODO(https://crbug.com/935602): Handle new values when adding new values on
-  // java side.
-  SpinnerType type = static_cast<SpinnerType>(spinner_type);
-  UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.FetchPendingSpinner.Shown",
-                            type);
-}
-
-void FeedLoggingMetrics::OnSpinnerFinished(base::TimeDelta shown_time,
-                                           int spinner_type) {
-  RecordSpinnerTimeUMA(
-      "ContentSuggestions.Feed.FetchPendingSpinner.VisibleDuration", shown_time,
-      spinner_type);
-}
-
-void FeedLoggingMetrics::OnSpinnerDestroyedWithoutCompleting(
-    base::TimeDelta shown_time,
-    int spinner_type) {
-  RecordSpinnerTimeUMA(
-      "ContentSuggestions.Feed.FetchPendingSpinner."
-      "VisibleDurationWithoutCompleting",
-      shown_time, spinner_type);
-}
-
-void FeedLoggingMetrics::OnPietFrameRenderingEvent(
-    std::vector<int> piet_error_codes) {
-  for (auto error_code : piet_error_codes) {
-    base::UmaHistogramSparse(
-        "ContentSuggestions.Feed.Piet.FrameRenderingErrorCode", error_code);
-  }
-}
-
-void FeedLoggingMetrics::OnVisualElementClicked(int element_type,
-                                                int position,
-                                                base::Time fetch_date) {
-  RecordElementPositionUMA("ContentSuggestions.Feed.VisualElement.Clicked",
-                           position, element_type);
-
-  RecordElementTimeUMA(
-      "ContentSuggestions.Feed.VisualElement.Clicked."
-      "TimeSinceElementFetched",
-      clock_->Now() - fetch_date, element_type);
-}
-
-void FeedLoggingMetrics::OnVisualElementViewed(int element_type,
-                                               int position,
-                                               base::Time fetch_date) {
-  RecordElementPositionUMA("ContentSuggestions.Feed.VisualElement.Viewed",
-                           position, element_type);
-
-  RecordElementTimeUMA(
-      "ContentSuggestions.Feed.VisualElement.Viewed.TimeSinceElementFetched",
-      clock_->Now() - fetch_date, element_type);
-}
-
-void FeedLoggingMetrics::OnInternalError(int internal_error) {
-  // TODO(https://crbug.com/935602): The max value here is fragile, figure out
-  // some way to test the @IntDef size. For now the count needs to be kept in
-  // sync with InternalFeedError.java and enums.xml.
-  UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.InternalError",
-                            internal_error, 18);
-}
-
-void FeedLoggingMetrics::OnTokenCompleted(bool was_synthetic,
-                                          int content_count,
-                                          int token_count) {
-  if (was_synthetic) {
-    UMA_HISTOGRAM_EXACT_LINEAR(
-        "ContentSuggestions.Feed.TokenCompleted.ContentCount2.Synthetic",
-        content_count, kMaxContentCount);
-    UMA_HISTOGRAM_EXACT_LINEAR(
-        "ContentSuggestions.Feed.TokenCompleted.TokenCount.Synthetic",
-        token_count, kMaxTokenCount);
-  } else {
-    UMA_HISTOGRAM_EXACT_LINEAR(
-        "ContentSuggestions.Feed.TokenCompleted.ContentCount2.NotSynthetic",
-        content_count, kMaxContentCount);
-    UMA_HISTOGRAM_EXACT_LINEAR(
-        "ContentSuggestions.Feed.TokenCompleted.TokenCount.NotSynthetic",
-        token_count, kMaxTokenCount);
-  }
-}
-
-void FeedLoggingMetrics::OnTokenFailedToComplete(bool was_synthetic,
-                                                 int failure_count) {
-  if (was_synthetic) {
-    UMA_HISTOGRAM_EXACT_LINEAR(
-        "ContentSuggestions.Feed.TokenFailedToCompleted.Synthetic",
-        failure_count, kMaxFailureCount);
-  } else {
-    UMA_HISTOGRAM_EXACT_LINEAR(
-        "ContentSuggestions.Feed.TokenFailedToCompleted.NotSynthetic",
-        failure_count, kMaxFailureCount);
-  }
-}
-
-void FeedLoggingMetrics::OnServerRequest(int request_reason) {
-  // TODO(https://crbug.com/935602): The max value here is fragile, figure out
-  // some way to test the @IntDef size.
-  UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.ServerRequest.Reason",
-                            request_reason, 8);
-}
-
-void FeedLoggingMetrics::OnZeroStateShown(int zero_state_show_reason) {
-  // TODO(https://crbug.com/935602): The max value here is fragile, figure out
-  // some way to test the @IntDef size.
-  UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.ZeroStateShown.Reason",
-                            zero_state_show_reason, 3);
-}
-
-void FeedLoggingMetrics::OnZeroStateRefreshCompleted(int new_content_count,
-                                                     int new_token_count) {
-  UMA_HISTOGRAM_EXACT_LINEAR(
-      "ContentSuggestions.Feed.ZeroStateRefreshCompleted.ContentCount",
-      new_content_count, kMaxContentCount);
-  UMA_HISTOGRAM_EXACT_LINEAR(
-      "ContentSuggestions.Feed.ZeroStateRefreshCompleted.TokenCount",
-      new_token_count, kMaxTokenCount);
-}
-
-void FeedLoggingMetrics::OnTaskFinished(int task_type,
-                                        int delay_time_ms,
-                                        int task_time_ms) {
-  TaskType type = static_cast<TaskType>(task_type);
-  ReportTaskTime(type, delay_time_ms, task_time_ms);
-}
-
-void FeedLoggingMetrics::ReportScrolledAfterOpen() {
-  base::RecordAction(base::UserMetricsAction("Suggestions.ScrolledAfterOpen"));
-}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_logging_metrics.h b/components/feed/core/feed_logging_metrics.h
deleted file mode 100644
index 441580c..0000000
--- a/components/feed/core/feed_logging_metrics.h
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_FEED_LOGGING_METRICS_H_
-#define COMPONENTS_FEED_CORE_FEED_LOGGING_METRICS_H_
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "components/feed/core/feed_scheduler_host.h"
-#include "url/gurl.h"
-
-namespace base {
-class Clock;
-class Time;
-class TimeDelta;
-}  // namespace base
-
-enum class WindowOpenDisposition;
-
-namespace feed {
-
-// FeedLoggingMetrics is a central place to report all the UMA metrics for Feed.
-class FeedLoggingMetrics {
- public:
-  // Return whether the URL is visited when calling checking URL visited.
-  using CheckURLVisitCallback = base::OnceCallback<void(bool)>;
-
-  // Calling this callback when need to check whether url is visited, and will
-  // tell CheckURLVisitCallback the result.
-  using HistoryURLCheckCallback =
-      base::RepeatingCallback<void(const GURL&, CheckURLVisitCallback)>;
-
-  explicit FeedLoggingMetrics(HistoryURLCheckCallback callback,
-                              base::Clock* clock,
-                              FeedSchedulerHost* scheduler_host);
-  ~FeedLoggingMetrics();
-
-  // |suggestions_count| contains how many cards show to users. It does not
-  // depend on whether the user actually saw the cards.
-  void OnPageShown(const int suggestions_count);
-
-  // The amount of time for the Feed to populate articles. This does not include
-  // time to render but time to populate data in the UI.
-  void OnPagePopulated(base::TimeDelta timeToPopulate);
-
-  // Should only be called once per NTP for each suggestion.
-  void OnSuggestionShown(int position,
-                         base::Time publish_date,
-                         float score,
-                         base::Time fetch_date,
-                         bool is_available_offline);
-
-  void OnSuggestionOpened(int position,
-                          base::Time publish_date,
-                          float score,
-                          bool is_available_offline);
-
-  void OnSuggestionWindowOpened(WindowOpenDisposition disposition);
-
-  void OnSuggestionMenuOpened(int position,
-                              base::Time publish_date,
-                              float score);
-
-  void OnSuggestionDismissed(int position, const GURL& url, bool committed);
-
-  void OnSuggestionSwiped();
-
-  void OnSuggestionArticleVisited(base::TimeDelta visit_time,
-                                  bool return_to_ntp);
-
-  // Should only be called once per NTP for each "more" button.
-  void OnMoreButtonShown(int position);
-
-  void OnMoreButtonClicked(int position);
-
-  void OnNotInterestedInSource(int position, bool committed);
-
-  void OnNotInterestedInTopic(int position, bool committed);
-
-  void OnSpinnerStarted(int spinner_type);
-
-  void OnSpinnerFinished(base::TimeDelta shown_time, int spinner_type);
-
-  void OnSpinnerDestroyedWithoutCompleting(base::TimeDelta shown_time,
-                                           int spinner_type);
-
-  void OnPietFrameRenderingEvent(std::vector<int> piet_error_codes);
-
-  void OnVisualElementClicked(int element_type,
-                              int position,
-                              base::Time fetch_date);
-
-  void OnVisualElementViewed(int element_type,
-                             int position,
-                             base::Time fetch_date);
-
-  void OnInternalError(int internal_error);
-
-  void OnTokenCompleted(bool was_synthetic, int content_count, int token_count);
-
-  void OnTokenFailedToComplete(bool was_synthetic, int failure_count);
-
-  void OnServerRequest(int request_reason);
-
-  void OnZeroStateShown(int zero_state_show_reason);
-
-  void OnZeroStateRefreshCompleted(int new_content_count, int new_token_count);
-
-  void OnTaskFinished(int task_type, int delay_time_ms, int task_time_ms);
-
-  void ReportScrolledAfterOpen();
-
- private:
-  const HistoryURLCheckCallback history_url_check_callback_;
-
-  // Used to access current time, injected for testing.
-  base::Clock* clock_;
-
-  FeedSchedulerHost* scheduler_host_;
-
-  base::WeakPtrFactory<FeedLoggingMetrics> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FeedLoggingMetrics);
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CORE_FEED_LOGGING_METRICS_H_
diff --git a/components/feed/core/feed_logging_metrics_unittest.cc b/components/feed/core/feed_logging_metrics_unittest.cc
deleted file mode 100644
index 3463ccc..0000000
--- a/components/feed/core/feed_logging_metrics_unittest.cc
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_logging_metrics.h"
-
-#include "base/bind.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/simple_test_clock.h"
-#include "base/time/time.h"
-#include "components/feed/core/common/pref_names.h"
-#include "components/feed/core/common/user_classifier.h"
-#include "components/prefs/testing_pref_service.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/base/mojom/window_open_disposition.mojom.h"
-
-using testing::ElementsAre;
-using testing::IsEmpty;
-using testing::SizeIs;
-
-namespace feed {
-namespace {
-
-// Fixed "now" to make tests more deterministic.
-char kNowString[] = "2018-06-11 15:41";
-
-// This needs to keep in sync with ActionType in
-// third_party/feed_library/src/src/main/
-// java/com/google/android/libraries/feed/host/logging/ActionType.java.
-enum FeedActionType {
-  UNKNOWN = -1,
-  OPEN_URL = 1,
-  OPEN_URL_INCOGNITO = 2,
-  OPEN_URL_NEW_WINDOW = 3,
-  OPEN_URL_NEW_TAB = 4,
-  DOWNLOAD = 5,
-};
-
-// TODO(https://crbug.com/1042727): Fix test GURL scoping and remove this getter
-// function.
-GURL VisitedUrl() {
-  return GURL("http://visited_url.com/");
-}
-
-void CheckURLVisit(const GURL& url,
-                   FeedLoggingMetrics::CheckURLVisitCallback callback) {
-  if (url == VisitedUrl()) {
-    std::move(callback).Run(true);
-  } else {
-    std::move(callback).Run(false);
-  }
-}
-
-}  // namespace
-
-class FeedLoggingMetricsTest : public testing::Test {
- public:
-  FeedLoggingMetricsTest() {
-    base::Time now;
-    EXPECT_TRUE(base::Time::FromUTCString(kNowString, &now));
-    test_clock_.SetNow(now);
-
-    feed::RegisterProfilePrefs(prefs_.registry());
-    scheduler_host_ =
-        std::make_unique<FeedSchedulerHost>(&prefs_, &prefs_, &test_clock_);
-
-    feed_logging_metrics_ = std::make_unique<FeedLoggingMetrics>(
-        base::BindRepeating(&CheckURLVisit), &test_clock_,
-        scheduler_host_.get());
-  }
-
-  FeedLoggingMetrics* feed_logging_metrics() {
-    return feed_logging_metrics_.get();
-  }
-  base::SimpleTestClock* test_clock() { return &test_clock_; }
-
- private:
-  base::SimpleTestClock test_clock_;
-
-  TestingPrefServiceSimple prefs_;
-
-  std::unique_ptr<FeedSchedulerHost> scheduler_host_;
-
-  std::unique_ptr<FeedLoggingMetrics> feed_logging_metrics_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedLoggingMetricsTest);
-};
-
-TEST_F(FeedLoggingMetricsTest, ShouldLogOnSuggestionsShown) {
-  base::HistogramTester histogram_tester;
-  feed_logging_metrics()->OnSuggestionShown(
-      /*position=*/1, test_clock()->Now(),
-      /*score=*/0.01f, test_clock()->Now() - base::TimeDelta::FromHours(2),
-      /*is_available_offline=*/false);
-  // Test corner cases for score.
-  feed_logging_metrics()->OnSuggestionShown(
-      /*position=*/2, test_clock()->Now(),
-      /*score=*/0.0f, test_clock()->Now() - base::TimeDelta::FromHours(2),
-      /*is_available_offline=*/true);
-  feed_logging_metrics()->OnSuggestionShown(
-      /*position=*/3, test_clock()->Now(),
-      /*score=*/1.0f, test_clock()->Now() - base::TimeDelta::FromHours(2),
-      /*is_available_offline=*/true);
-  feed_logging_metrics()->OnSuggestionShown(
-      /*position=*/4, test_clock()->Now(),
-      /*score=*/8.0f, test_clock()->Now() - base::TimeDelta::FromHours(2),
-      /*is_available_offline=*/true);
-
-  EXPECT_THAT(
-      histogram_tester.GetAllSamples("NewTabPage.ContentSuggestions.Shown"),
-      ElementsAre(base::Bucket(/*min=*/1, /*count=*/1),
-                  base::Bucket(/*min=*/2, /*count=*/1),
-                  base::Bucket(/*min=*/3, /*count=*/1),
-                  base::Bucket(/*min=*/4, /*count=*/1)));
-  EXPECT_THAT(
-      histogram_tester.GetAllSamples(
-          "NewTabPage.ContentSuggestions.ShownScoreNormalized.Articles"),
-      ElementsAre(base::Bucket(/*min=*/0, /*count=*/1),
-                  base::Bucket(/*min=*/1, /*count=*/1),
-                  base::Bucket(/*min=*/10, /*count=*/1),
-                  base::Bucket(/*min=*/11, /*count=*/1)));
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "ContentSuggestions.Feed.AvailableOffline.Shown"),
-              ElementsAre(base::Bucket(/*min=*/0, /*count=*/1),
-                          base::Bucket(/*min=*/1, /*count=*/3)));
-}
-
-TEST_F(FeedLoggingMetricsTest, ShouldLogOnPageShown) {
-  base::HistogramTester histogram_tester;
-  feed_logging_metrics()->OnPageShown(/*content_count=*/10);
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "NewTabPage.ContentSuggestions.CountOnNtpOpenedIfVisible"),
-              ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
-}
-
-TEST_F(FeedLoggingMetricsTest, ShouldLogOnSuggestionOpened) {
-  base::HistogramTester histogram_tester;
-  feed_logging_metrics()->OnSuggestionOpened(
-      /*position=*/11, test_clock()->Now(),
-      /*score=*/1.0f, /*is_available_offline=*/false);
-  feed_logging_metrics()->OnSuggestionOpened(
-      /*position=*/13, test_clock()->Now(),
-      /*score=*/1.0f, /*is_available_offline=*/false);
-  feed_logging_metrics()->OnSuggestionOpened(
-      /*position=*/15, test_clock()->Now(),
-      /*score=*/1.0f, /*is_available_offline=*/false);
-  feed_logging_metrics()->OnSuggestionOpened(
-      /*position=*/23, test_clock()->Now(),
-      /*score=*/1.0f, /*is_available_offline=*/true);
-
-  EXPECT_THAT(
-      histogram_tester.GetAllSamples("NewTabPage.ContentSuggestions.Opened"),
-      ElementsAre(base::Bucket(/*min=*/11, /*count=*/1),
-                  base::Bucket(/*min=*/13, /*count=*/1),
-                  base::Bucket(/*min=*/15, /*count=*/1),
-                  base::Bucket(/*min=*/23, /*count=*/1)));
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "ContentSuggestions.Feed.AvailableOffline.Opened"),
-              ElementsAre(base::Bucket(/*min=*/0, /*count=*/3),
-                          base::Bucket(/*min=*/1, /*count=*/1)));
-}
-
-TEST_F(FeedLoggingMetricsTest, ShouldLogOnSuggestionWindowOpened) {
-  base::HistogramTester histogram_tester;
-  feed_logging_metrics()->OnSuggestionWindowOpened(
-      WindowOpenDisposition::CURRENT_TAB);
-  feed_logging_metrics()->OnSuggestionWindowOpened(
-      WindowOpenDisposition::CURRENT_TAB);
-  feed_logging_metrics()->OnSuggestionWindowOpened(
-      WindowOpenDisposition::CURRENT_TAB);
-  feed_logging_metrics()->OnSuggestionWindowOpened(
-      WindowOpenDisposition::CURRENT_TAB);
-
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "NewTabPage.ContentSuggestions.OpenDisposition.Articles"),
-              ElementsAre(base::Bucket(
-                  /*WindowOpenDisposition::CURRENT_TAB=*/static_cast<int>(
-                      WindowOpenDisposition::CURRENT_TAB),
-                  /*count=*/4)));
-}
-
-TEST_F(FeedLoggingMetricsTest, ShouldLogOnSuggestionDismissedCommitIfVisited) {
-  base::HistogramTester histogram_tester;
-  feed_logging_metrics()->OnSuggestionDismissed(/*position=*/10, VisitedUrl(),
-                                                true);
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "NewTabPage.ContentSuggestions.DismissedVisited.Commit"),
-              ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
-}
-
-TEST_F(FeedLoggingMetricsTest,
-       ShouldLogOnSuggestionDismissedCommitIfNotVisited) {
-  base::HistogramTester histogram_tester;
-  feed_logging_metrics()->OnSuggestionDismissed(
-      /*position=*/10, GURL("http://non_visited.com"), true);
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "NewTabPage.ContentSuggestions.DismissedUnvisited.Commit"),
-              ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
-}
-
-TEST_F(FeedLoggingMetricsTest,
-       ShouldLogOnSuggestionDismissedUndoIfUndoDismissAndVisited) {
-  base::HistogramTester histogram_tester;
-  feed_logging_metrics()->OnSuggestionDismissed(/*position=*/10, VisitedUrl(),
-                                                false);
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "NewTabPage.ContentSuggestions.DismissedVisited.Undo"),
-              ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
-}
-
-TEST_F(FeedLoggingMetricsTest,
-       ShouldLogOnSuggestionDismissedUndoIfUndoDismissAndNotVisited) {
-  base::HistogramTester histogram_tester;
-  feed_logging_metrics()->OnSuggestionDismissed(
-      /*position=*/10, GURL("http://non_visited.com"), false);
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "NewTabPage.ContentSuggestions.DismissedUnvisited.Undo"),
-              ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
-}
-
-TEST_F(FeedLoggingMetricsTest, ShouldReportOnPietFrameRenderingEvent) {
-  base::HistogramTester histogram_tester;
-  std::vector<int> error_codes({0, 1, 6, 7});
-  feed_logging_metrics()->OnPietFrameRenderingEvent(error_codes);
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "ContentSuggestions.Feed.Piet.FrameRenderingErrorCode"),
-              ElementsAre(base::Bucket(/*min=*/0, /*count=*/1),
-                          base::Bucket(/*min=*/1, /*count=*/1),
-                          base::Bucket(/*min=*/6, /*count=*/1),
-                          base::Bucket(/*min=*/7, /*count=*/1)));
-}
-
-TEST_F(FeedLoggingMetricsTest, ShouldLogOnTaskFinished) {
-  base::HistogramTester histogram_tester;
-  feed_logging_metrics()->OnTaskFinished(/*KExecuteUploadActionRequest=*/10, 8,
-                                         8);
-  EXPECT_THAT(
-      histogram_tester.GetAllSamples(
-          "ContentSuggestions.Feed.Task.ExecuteUploadActionRequest.DelayTime"),
-      ElementsAre(base::Bucket(/*min=*/8, /*count=*/1)));
-  EXPECT_THAT(
-      histogram_tester.GetAllSamples(
-          "ContentSuggestions.Feed.Task.ExecuteUploadActionRequest.TaskTime"),
-      ElementsAre(base::Bucket(/*min=*/8, /*count=*/1)));
-}
-
-TEST_F(FeedLoggingMetricsTest, ShouldLogOnMoreButtonClicked) {
-  base::HistogramTester histogram_tester;
-
-  feed_logging_metrics()->OnMoreButtonClicked(1);
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "NewTabPage.ContentSuggestions.MoreButtonClicked.Articles"),
-              ElementsAre(base::Bucket(/*min=*/1, /*count=*/1)));
-
-  // User classifier should have been informed of a suggestion being consumed.
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "NewTabPage.UserClassifier.AverageHoursToUseSuggestions"),
-              SizeIs(1));
-}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_networking_host.cc b/components/feed/core/feed_networking_host.cc
deleted file mode 100644
index b6104f5..0000000
--- a/components/feed/core/feed_networking_host.cc
+++ /dev/null
@@ -1,401 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_networking_host.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/metrics/field_trial_params.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/stringprintf.h"
-#include "base/time/tick_clock.h"
-#include "base/time/time.h"
-#include "base/values.h"
-#include "components/feed/core/common/pref_names.h"
-#include "components/feed/feed_feature_list.h"
-#include "components/prefs/pref_service.h"
-#include "components/signin/public/identity_manager/access_token_info.h"
-#include "components/signin/public/identity_manager/identity_manager.h"
-#include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h"
-#include "components/signin/public/identity_manager/scope_set.h"
-#include "components/variations/net/variations_http_headers.h"
-#include "google_apis/gaia/google_service_auth_error.h"
-#include "net/base/load_flags.h"
-#include "net/base/url_util.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_status_code.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "services/network/public/cpp/resource_request.h"
-#include "services/network/public/cpp/resource_request_body.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/zlib/google/compression_utils.h"
-
-using IdentityManager = signin::IdentityManager;
-
-namespace {
-
-constexpr char kApiKeyQueryParam[] = "key";
-constexpr char kAuthenticationScope[] =
-    "https://www.googleapis.com/auth/googlenow";
-constexpr char kAuthorizationRequestHeaderFormat[] = "Bearer %s";
-
-constexpr char kContentEncoding[] = "Content-Encoding";
-constexpr char kContentType[] = "application/octet-stream";
-constexpr char kGzip[] = "gzip";
-
-}  // namespace
-
-namespace feed {
-
-// NetworkFetch is a helper class internal to the networking host. Each
-// instance represents a single "logical" fetch that ends by calling the
-// associated callback. Network fetches will actually attempt two fetches if
-// there is a signed in user; the first to retrieve an access token, and the
-// second to the specified url.
-class NetworkFetch {
- public:
-  NetworkFetch(const GURL& url,
-               const std::string& request_type,
-               std::vector<uint8_t> request_body,
-               IdentityManager* identity_manager,
-               network::SharedURLLoaderFactory* loader_factory,
-               const std::string& api_key,
-               const base::TickClock* tick_clock,
-               PrefService* pref_service);
-
-  void Start(FeedNetworkingHost::ResponseCallback done_callback);
-
- private:
-  void StartAccessTokenFetch();
-  void AccessTokenFetchFinished(base::TimeTicks token_start_ticks,
-                                GoogleServiceAuthError error,
-                                signin::AccessTokenInfo access_token_info);
-  void StartLoader();
-  std::unique_ptr<network::SimpleURLLoader> MakeLoader();
-  void SetRequestHeaders(bool has_request_body,
-                         network::ResourceRequest* request) const;
-  void PopulateRequestBody(network::SimpleURLLoader* loader);
-  void OnSimpleLoaderComplete(std::unique_ptr<std::string> response);
-
-  GURL url_;
-  const std::string request_type_;
-  std::string access_token_;
-  const std::vector<uint8_t> request_body_;
-  IdentityManager* const identity_manager_;
-  std::unique_ptr<signin::PrimaryAccountAccessTokenFetcher> token_fetcher_;
-  std::unique_ptr<network::SimpleURLLoader> simple_loader_;
-  FeedNetworkingHost::ResponseCallback done_callback_;
-  network::SharedURLLoaderFactory* loader_factory_;
-  const std::string api_key_;
-  const base::TickClock* tick_clock_;
-
-  // Set when the NetworkFetch is constructed, before token and article fetch.
-  const base::TimeTicks entire_send_start_ticks_;
-
-  // Should be set right before the article fetch, and after the token fetch if
-  // there is one.
-  base::TimeTicks loader_only_start_ticks_;
-  PrefService* pref_service_;
-  bool host_overridden_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(NetworkFetch);
-};
-
-NetworkFetch::NetworkFetch(const GURL& url,
-                           const std::string& request_type,
-                           std::vector<uint8_t> request_body,
-                           IdentityManager* identity_manager,
-                           network::SharedURLLoaderFactory* loader_factory,
-                           const std::string& api_key,
-                           const base::TickClock* tick_clock,
-                           PrefService* pref_service)
-    : url_(url),
-      request_type_(request_type),
-      request_body_(std::move(request_body)),
-      identity_manager_(identity_manager),
-      loader_factory_(loader_factory),
-      api_key_(api_key),
-      tick_clock_(tick_clock),
-      entire_send_start_ticks_(tick_clock_->NowTicks()),
-      pref_service_(pref_service) {
-  // Apply the host override (from snippets-internals).
-  std::string host_override =
-      pref_service_->GetString(feed::prefs::kHostOverrideHost);
-  if (!host_override.empty()) {
-    GURL override_host_url(host_override);
-    if (override_host_url.is_valid()) {
-      GURL::Replacements replacements;
-      replacements.SetSchemeStr(override_host_url.scheme_piece());
-      replacements.SetHostStr(override_host_url.host_piece());
-      replacements.SetPortStr(override_host_url.port_piece());
-      url_ = url_.ReplaceComponents(replacements);
-      host_overridden_ = true;
-    }
-  }
-}
-
-void NetworkFetch::Start(FeedNetworkingHost::ResponseCallback done_callback) {
-  done_callback_ = std::move(done_callback);
-
-  if (!identity_manager_->HasPrimaryAccount()) {
-    StartLoader();
-    return;
-  }
-
-  StartAccessTokenFetch();
-}
-
-void NetworkFetch::StartAccessTokenFetch() {
-  signin::ScopeSet scopes{kAuthenticationScope};
-  // It's safe to pass base::Unretained(this) since deleting the token fetcher
-  // will prevent the callback from being completed.
-  token_fetcher_ = std::make_unique<signin::PrimaryAccountAccessTokenFetcher>(
-      "feed", identity_manager_, scopes,
-      base::BindOnce(&NetworkFetch::AccessTokenFetchFinished,
-                     base::Unretained(this), tick_clock_->NowTicks()),
-      signin::PrimaryAccountAccessTokenFetcher::Mode::kWaitUntilAvailable);
-}
-
-void NetworkFetch::AccessTokenFetchFinished(
-    base::TimeTicks token_start_ticks,
-    GoogleServiceAuthError error,
-    signin::AccessTokenInfo access_token_info) {
-  UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.Network.TokenFetchStatus",
-                            error.state(), GoogleServiceAuthError::NUM_STATES);
-
-  base::TimeDelta token_duration = tick_clock_->NowTicks() - token_start_ticks;
-  UMA_HISTOGRAM_MEDIUM_TIMES("ContentSuggestions.Feed.Network.TokenDuration",
-                             token_duration);
-
-  access_token_ = access_token_info.token;
-  StartLoader();
-}
-
-void NetworkFetch::StartLoader() {
-  loader_only_start_ticks_ = tick_clock_->NowTicks();
-  simple_loader_ = MakeLoader();
-  simple_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
-      loader_factory_, base::BindOnce(&NetworkFetch::OnSimpleLoaderComplete,
-                                      base::Unretained(this)));
-}
-
-std::unique_ptr<network::SimpleURLLoader> NetworkFetch::MakeLoader() {
-  // TODO(pnoland): Add data use measurement once it's supported for simple
-  // url loader.
-  net::NetworkTrafficAnnotationTag traffic_annotation =
-      net::DefineNetworkTrafficAnnotation("interest_feed_send", R"(
-        semantics {
-          sender: "Feed Library"
-          description: "Chrome can show content suggestions (e.g. articles) "
-          "in the form of a feed. For signed-in users, these may be "
-          "personalized based on the user's synced browsing history."
-          trigger: "Triggered periodically in the background, or upon "
-          "explicit user request."
-          data: "The locale of the device and data describing the suggested "
-            "content that the user interacted with. For signed in users "
-            "the request is authenticated. "
-          destination: GOOGLE_OWNED_SERVICE
-        }
-        policy {
-          cookies_allowed: YES
-          cookies_store: "user"
-          setting: "This can be disabled from the New Tab Page by collapsing "
-          "the articles section."
-          chrome_policy {
-            NTPContentSuggestionsEnabled {
-              policy_options {mode: MANDATORY}
-              NTPContentSuggestionsEnabled: false
-            }
-          }
-        })");
-  GURL url(url_);
-  if (access_token_.empty() && !api_key_.empty())
-    url = net::AppendQueryParameter(url_, kApiKeyQueryParam, api_key_);
-
-  auto resource_request = std::make_unique<network::ResourceRequest>();
-  resource_request->url = url;
-
-  resource_request->load_flags = net::LOAD_BYPASS_CACHE;
-  resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;
-  resource_request->method = request_type_;
-
-  // Include credentials ONLY if the user has overridden the feed host through
-  // the internals page. This allows for some authentication workflows we need
-  // for testing.
-  if (host_overridden_) {
-    resource_request->credentials_mode =
-        network::mojom::CredentialsMode::kInclude;
-    resource_request->site_for_cookies = net::SiteForCookies::FromUrl(url);
-  }
-
-  SetRequestHeaders(!request_body_.empty(), resource_request.get());
-
-  auto simple_loader = network::SimpleURLLoader::Create(
-      std::move(resource_request), traffic_annotation);
-  simple_loader->SetAllowHttpErrorResults(true);
-  simple_loader->SetTimeoutDuration(
-      base::TimeDelta::FromSeconds(kTimeoutDurationSeconds.Get()));
-  PopulateRequestBody(simple_loader.get());
-  return simple_loader;
-}
-
-void NetworkFetch::SetRequestHeaders(bool has_request_body,
-                                     network::ResourceRequest* request) const {
-  if (has_request_body) {
-    request->headers.SetHeader(net::HttpRequestHeaders::kContentType,
-                               kContentType);
-    request->headers.SetHeader(kContentEncoding, kGzip);
-  }
-
-  variations::SignedIn signed_in_status = variations::SignedIn::kNo;
-  if (!access_token_.empty()) {
-    std::string auth_header = base::StringPrintf(
-        kAuthorizationRequestHeaderFormat, access_token_.c_str());
-    request->headers.SetHeader(net::HttpRequestHeaders::kAuthorization,
-                               auth_header);
-    signed_in_status = variations::SignedIn::kYes;
-  }
-
-  // Add X-Client-Data header with experiment IDs from field trials.
-  variations::AppendVariationsHeader(url_, variations::InIncognito::kNo,
-                                     signed_in_status, request);
-}
-
-void NetworkFetch::PopulateRequestBody(network::SimpleURLLoader* loader) {
-  std::string compressed_request_body;
-  if (!request_body_.empty()) {
-    std::string uncompressed_request_body(
-        reinterpret_cast<const char*>(request_body_.data()),
-        request_body_.size());
-
-    compression::GzipCompress(uncompressed_request_body,
-                              &compressed_request_body);
-
-    loader->AttachStringForUpload(compressed_request_body, kContentType);
-  }
-
-  UMA_HISTOGRAM_COUNTS_1M(
-      "ContentSuggestions.Feed.Network.RequestSizeKB.Compressed",
-      static_cast<int>(compressed_request_body.size() / 1024));
-}
-
-void NetworkFetch::OnSimpleLoaderComplete(
-    std::unique_ptr<std::string> response) {
-  int32_t status_code = simple_loader_->NetError();
-  // If overriding the feed host, try to grab the Bless nonce. This is
-  // strictly informational, and only displayed in snippets-internals.
-  if (host_overridden_ && simple_loader_->ResponseInfo()) {
-    size_t iter = 0;
-    std::string value;
-    while (simple_loader_->ResponseInfo()->headers->EnumerateHeader(
-        &iter, "www-authenticate", &value)) {
-      size_t pos = value.find("nonce=\"");
-      if (pos != std::string::npos) {
-        std::string nonce = value.substr(pos + 7, 16);
-        if (nonce.size() == 16) {
-          pref_service_->SetString(feed::prefs::kHostOverrideBlessNonce, nonce);
-          break;
-        }
-      }
-    }
-  }
-  std::vector<uint8_t> response_body;
-
-  if (response) {
-    status_code = simple_loader_->ResponseInfo()->headers->response_code();
-
-    if (status_code == net::HTTP_UNAUTHORIZED) {
-      signin::ScopeSet scopes{kAuthenticationScope};
-      CoreAccountId account_id = identity_manager_->GetPrimaryAccountId();
-      if (!account_id.empty()) {
-        identity_manager_->RemoveAccessTokenFromCache(account_id, scopes,
-                                                      access_token_);
-      }
-    }
-
-    const uint8_t* begin = reinterpret_cast<const uint8_t*>(response->data());
-    const uint8_t* end = begin + response->size();
-    response_body.assign(begin, end);
-  }
-
-  base::TimeDelta entire_send_duration =
-      tick_clock_->NowTicks() - entire_send_start_ticks_;
-  UMA_HISTOGRAM_MEDIUM_TIMES("ContentSuggestions.Feed.Network.Duration",
-                             entire_send_duration);
-
-  base::TimeDelta loader_only_duration =
-      tick_clock_->NowTicks() - loader_only_start_ticks_;
-  // This histogram purposefully matches name and bucket size used in
-  // RemoteSuggestionsFetcherImpl.
-  UMA_HISTOGRAM_TIMES("NewTabPage.Snippets.FetchTime", loader_only_duration);
-
-  base::UmaHistogramSparse("ContentSuggestions.Feed.Network.RequestStatusCode",
-                           status_code);
-
-  // The below is true even if there is a protocol error, so this will
-  // record response size as long as the request completed.
-  if (status_code >= 200) {
-    UMA_HISTOGRAM_COUNTS_1M("ContentSuggestions.Feed.Network.ResponseSizeKB",
-                            static_cast<int>(response_body.size() / 1024));
-  }
-
-  std::move(done_callback_)
-      .Run(status_code, std::move(response_body), !access_token_.empty());
-}
-
-FeedNetworkingHost::FeedNetworkingHost(
-    signin::IdentityManager* identity_manager,
-    const std::string& api_key,
-    scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
-    const base::TickClock* tick_clock,
-    PrefService* pref_service)
-    : identity_manager_(identity_manager),
-      api_key_(api_key),
-      loader_factory_(std::move(loader_factory)),
-      tick_clock_(tick_clock),
-      pref_service_(pref_service) {}
-
-FeedNetworkingHost::~FeedNetworkingHost() = default;
-
-void FeedNetworkingHost::CancelRequests() {
-  pending_requests_.clear();
-}
-
-void FeedNetworkingHost::Send(
-    const GURL& url,
-    const std::string& request_type,
-    std::vector<uint8_t> request_body,
-    ResponseCallback callback) {
-  auto fetch = std::make_unique<NetworkFetch>(
-      url, request_type, std::move(request_body), identity_manager_,
-      loader_factory_.get(), api_key_, tick_clock_, pref_service_);
-  NetworkFetch* fetch_unowned = fetch.get();
-  pending_requests_.emplace(std::move(fetch));
-
-  // It's safe to pass base::Unretained(this) since deleting the network fetch
-  // will prevent the callback from being completed.
-  fetch_unowned->Start(base::BindOnce(&FeedNetworkingHost::NetworkFetchFinished,
-                                      base::Unretained(this), fetch_unowned,
-                                      std::move(callback)));
-}
-
-void FeedNetworkingHost::NetworkFetchFinished(
-    NetworkFetch* fetch,
-    ResponseCallback callback,
-    int32_t http_code,
-    std::vector<uint8_t> response_body,
-    bool is_signed_in) {
-  auto fetch_iterator = pending_requests_.find(fetch);
-  CHECK(fetch_iterator != pending_requests_.end());
-  pending_requests_.erase(fetch_iterator);
-
-  std::move(callback).Run(http_code, std::move(response_body), is_signed_in);
-}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_networking_host.h b/components/feed/core/feed_networking_host.h
deleted file mode 100644
index dcfec63..0000000
--- a/components/feed/core/feed_networking_host.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_FEED_NETWORKING_HOST_H_
-#define COMPONENTS_FEED_CORE_FEED_NETWORKING_HOST_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/containers/flat_set.h"
-#include "base/containers/unique_ptr_adapters.h"
-#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "url/gurl.h"
-
-class PrefService;
-
-namespace base {
-class TickClock;
-}
-
-namespace signin {
-class IdentityManager;
-}
-
-namespace network {
-class SharedURLLoaderFactory;
-}
-
-namespace feed {
-
-class NetworkFetch;
-
-// Implementation of the Feed Networking Host API. The networking host handles
-// the process of sending http requests to remote endpoints, including the
-// fetching of access tokens for the primary user.
-class FeedNetworkingHost {
- public:
-  // status_code is a union of net::Error (if the request failed) and the http
-  // status code(if the request succeeded in reaching the server).
-  using ResponseCallback =
-      base::OnceCallback<void(int32_t status_code,
-                              std::vector<uint8_t> response_bytes,
-                              bool is_signed_in)>;
-
-  FeedNetworkingHost(
-      signin::IdentityManager* identity_manager,
-      const std::string& api_key,
-      scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
-      const base::TickClock* tick_clock,
-      PrefService* pref_service);
-
-  ~FeedNetworkingHost();
-
-  // Cancels all pending requests immediately. This could be used, for example,
-  // if there are pending requests for a user who just signed out.
-  void CancelRequests();
-
-  // Start a request to |url| of type |request_type| with body |request_body|.
-  // |callback| will be called when the response is received or if there is
-  // an error, including non-protocol errors. The contents of |request_body|
-  // will be gzipped.
-  void Send(
-      const GURL& url,
-      const std::string& request_type,
-      std::vector<uint8_t> request_body,
-      ResponseCallback callback);
-
- private:
-  void NetworkFetchFinished(NetworkFetch* fetch,
-                            ResponseCallback callback,
-                            int32_t http_code,
-                            std::vector<uint8_t> response_body,
-                            bool isSignedIn);
-
-  base::flat_set<std::unique_ptr<NetworkFetch>, base::UniquePtrComparator>
-      pending_requests_;
-  signin::IdentityManager* identity_manager_;
-  const std::string api_key_;
-  scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
-  const base::TickClock* tick_clock_;
-  PrefService* pref_service_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedNetworkingHost);
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CORE_FEED_NETWORKING_HOST_H_
diff --git a/components/feed/core/feed_networking_host_unittest.cc b/components/feed/core/feed_networking_host_unittest.cc
deleted file mode 100644
index c571b9b9..0000000
--- a/components/feed/core/feed_networking_host_unittest.cc
+++ /dev/null
@@ -1,460 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_networking_host.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/test/bind.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "base/test/task_environment.h"
-#include "build/chromeos_buildflags.h"
-#include "components/feed/core/common/pref_names.h"
-#include "components/feed/feed_feature_list.h"
-#include "components/prefs/testing_pref_service.h"
-#include "components/signin/public/identity_manager/identity_test_environment.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_status_code.h"
-#include "net/http/http_util.h"
-#include "net/traffic_annotation/network_traffic_annotation_test_helper.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/test/test_url_loader_factory.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/zlib/google/compression_utils.h"
-
-namespace feed {
-
-using base::TimeDelta;
-using network::PendingSharedURLLoaderFactory;
-using network::SharedURLLoaderFactory;
-using network::TestURLLoaderFactory;
-using testing::ElementsAre;
-
-namespace {
-
-const char kHistogramNetworkRequestStatusCode[] =
-    "ContentSuggestions.Feed.Network.RequestStatusCode";
-
-class MockResponseDoneCallback {
- public:
-  MockResponseDoneCallback() : has_run(false), code(0) {}
-
-  void Done(int32_t http_code,
-            std::vector<uint8_t> response,
-            bool is_signed_in) {
-    EXPECT_FALSE(has_run);
-    has_run = true;
-    code = http_code;
-    response_bytes = std::move(response);
-    is_signed_in_result = is_signed_in;
-  }
-
-  bool has_run;
-  int32_t code;
-  std::vector<uint8_t> response_bytes;
-  bool is_signed_in_result;
-};
-
-}  // namespace
-
-class FeedNetworkingHostTest : public testing::Test {
- protected:
-  FeedNetworkingHostTest() {
-    identity_test_env_.MakePrimaryAccountAvailable("example@gmail.com");
-    identity_test_env_.SetAutomaticIssueOfAccessTokens(true);
-  }
-
-  ~FeedNetworkingHostTest() override {}
-
-  void SetUp() override {
-    feed::RegisterProfilePrefs(profile_prefs_.registry());
-
-    shared_url_loader_factory_ =
-        base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
-            &test_factory_);
-    net_service_ = std::make_unique<FeedNetworkingHost>(
-        identity_test_env_.identity_manager(), "dummy_api_key",
-        shared_url_loader_factory_, task_environment_.GetMockTickClock(),
-        &profile_prefs_);
-  }
-
-  FeedNetworkingHost* service() { return net_service_.get(); }
-
-  signin::IdentityTestEnvironment* identity_env() {
-    return &identity_test_env_;
-  }
-
-  void Respond(const GURL& url,
-               const std::string& response_string,
-               net::HttpStatusCode code = net::HTTP_OK,
-               network::URLLoaderCompletionStatus status =
-                   network::URLLoaderCompletionStatus()) {
-    auto head = network::mojom::URLResponseHead::New();
-    if (code >= 0) {
-      head->headers = base::MakeRefCounted<net::HttpResponseHeaders>(
-          "HTTP/1.1 " + base::NumberToString(code));
-      status.decoded_body_length = response_string.length();
-    }
-
-    test_factory_.AddResponse(url, std::move(head), response_string, status);
-
-    task_environment_.FastForwardUntilNoTasksRemain();
-  }
-
-  void SendRequestAndRespond(const std::string& url_string,
-                             const std::string& request_type,
-                             const std::string& request_string,
-                             const std::string& response_string,
-                             net::HttpStatusCode code,
-                             network::URLLoaderCompletionStatus status,
-                             MockResponseDoneCallback* done_callback) {
-    GURL req_url(url_string);
-    std::vector<uint8_t> request_body(request_string.begin(),
-                                      request_string.end());
-    service()->Send(req_url, request_type, request_body,
-                    base::BindOnce(&MockResponseDoneCallback::Done,
-                                   base::Unretained(done_callback)));
-
-    Respond(req_url, response_string, code, status);
-  }
-
-  void SendRequestAndValidateResponse(
-      const std::string& url_string,
-      const std::string& request_string,
-      const std::string& response_string,
-      net::HttpStatusCode code,
-      network::URLLoaderCompletionStatus status =
-          network::URLLoaderCompletionStatus()) {
-    MockResponseDoneCallback done_callback;
-    SendRequestAndRespond(url_string, "POST", request_string, response_string,
-                          code, status, &done_callback);
-
-    EXPECT_TRUE(done_callback.has_run);
-    EXPECT_EQ(done_callback.code, code);
-    EXPECT_EQ(std::string(done_callback.response_bytes.begin(),
-                          done_callback.response_bytes.end()),
-              response_string);
-  }
-
-  network::TestURLLoaderFactory* test_factory() { return &test_factory_; }
-
-  base::test::TaskEnvironment task_environment_{
-      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
-
-  TestingPrefServiceSimple& profile_prefs() { return profile_prefs_; }
-
- private:
-  signin::IdentityTestEnvironment identity_test_env_;
-  std::unique_ptr<FeedNetworkingHost> net_service_;
-  network::TestURLLoaderFactory test_factory_;
-  scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_;
-  base::SimpleTestTickClock test_tick_clock_;
-  TestingPrefServiceSimple profile_prefs_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedNetworkingHostTest);
-};
-
-TEST_F(FeedNetworkingHostTest, ShouldSendSuccessfullyEmpty) {
-  SendRequestAndValidateResponse("http://foobar.com/feed", "", "",
-                                 net::HTTP_OK);
-}
-
-TEST_F(FeedNetworkingHostTest, ShouldSendSuccessfullySimple) {
-  SendRequestAndValidateResponse("http://foobar.com/feed", "?bar=baz&foo=1",
-                                 "{key:'val'}", net::HTTP_OK);
-}
-
-TEST_F(FeedNetworkingHostTest, ShouldSendSuccessfullyMultipleInflight) {
-  MockResponseDoneCallback done_callback1;
-  MockResponseDoneCallback done_callback2;
-  MockResponseDoneCallback done_callback3;
-  base::HistogramTester histogram_tester;
-
-  SendRequestAndRespond("http://foobar.com/feed", "POST", "", "", net::HTTP_OK,
-                        network::URLLoaderCompletionStatus(), &done_callback1);
-  SendRequestAndRespond("http://foobar.com/foobar", "POST", "", "",
-                        net::HTTP_OK, network::URLLoaderCompletionStatus(),
-                        &done_callback2);
-  SendRequestAndRespond("http://foobar.com/other", "POST", "", "", net::HTTP_OK,
-                        network::URLLoaderCompletionStatus(), &done_callback3);
-  task_environment_.FastForwardUntilNoTasksRemain();
-
-  EXPECT_TRUE(done_callback1.has_run);
-  EXPECT_TRUE(done_callback2.has_run);
-  EXPECT_TRUE(done_callback3.has_run);
-
-  EXPECT_THAT(
-      histogram_tester.GetAllSamples(kHistogramNetworkRequestStatusCode),
-      ElementsAre(base::Bucket(/*min=*/200, /*count=*/3)));
-}
-
-TEST_F(FeedNetworkingHostTest, ShouldSendSuccessfullyDifferentRequestMethods) {
-  std::vector<std::string> request_methods({"POST", "GET", "PUT", "PATCH"});
-  for (const auto& method : request_methods) {
-    MockResponseDoneCallback done_callback;
-
-    SendRequestAndRespond("http://foobar.com/feed", method, "", "",
-                          net::HTTP_OK, network::URLLoaderCompletionStatus(),
-                          &done_callback);
-
-    task_environment_.FastForwardUntilNoTasksRemain();
-    EXPECT_TRUE(done_callback.has_run);
-    EXPECT_EQ(done_callback.code, 200);
-  }
-}
-
-TEST_F(FeedNetworkingHostTest, ShouldReportProtocolErrorCodes) {
-  std::vector<net::HttpStatusCode> error_codes(
-      {net::HTTP_BAD_REQUEST, net::HTTP_UNAUTHORIZED, net::HTTP_FORBIDDEN,
-       net::HTTP_NOT_FOUND, net::HTTP_INTERNAL_SERVER_ERROR,
-       net::HTTP_BAD_GATEWAY, net::HTTP_SERVICE_UNAVAILABLE});
-
-  for (const auto& code : error_codes) {
-    base::HistogramTester histogram_tester;
-    SendRequestAndValidateResponse("http://foobar.com/feed", "?bar=baz&foo=1",
-                                   "error_response_data", code);
-    EXPECT_THAT(
-        histogram_tester.GetAllSamples(kHistogramNetworkRequestStatusCode),
-        ElementsAre(base::Bucket(/*min=*/code, /*count=*/1)));
-  }
-}
-
-TEST_F(FeedNetworkingHostTest, ShouldReportNonProtocolErrorCodes) {
-  std::vector<int32_t> error_codes(
-      {net::ERR_CERT_COMMON_NAME_INVALID, net::ERR_CERT_DATE_INVALID,
-       net::ERR_CERT_WEAK_KEY, net::ERR_NAME_RESOLUTION_FAILED});
-  for (const auto& code : error_codes) {
-    base::HistogramTester histogram_tester;
-    MockResponseDoneCallback done_callback;
-
-    SendRequestAndRespond(
-        "http://foobar.com/feed", "POST", "", "", net::HTTP_OK,
-        network::URLLoaderCompletionStatus(code), &done_callback);
-
-    EXPECT_TRUE(done_callback.has_run);
-    EXPECT_EQ(done_callback.code, code);
-    EXPECT_THAT(
-        histogram_tester.GetAllSamples(kHistogramNetworkRequestStatusCode),
-        ElementsAre(base::Bucket(/*min=*/code, /*count=*/1)));
-  }
-}
-
-TEST_F(FeedNetworkingHostTest, ShouldSetHeadersCorrectly) {
-  MockResponseDoneCallback done_callback;
-  net::HttpRequestHeaders headers;
-  base::RunLoop interceptor_run_loop;
-
-  test_factory()->SetInterceptor(
-      base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
-        headers = request.headers;
-        interceptor_run_loop.Quit();
-      }));
-
-  SendRequestAndRespond("http://foobar.com/feed", "POST", "body", "",
-                        net::HTTP_OK, network::URLLoaderCompletionStatus(),
-                        &done_callback);
-
-  std::string content_encoding;
-  std::string authorization;
-  EXPECT_TRUE(headers.GetHeader("content-encoding", &content_encoding));
-  EXPECT_TRUE(headers.GetHeader("Authorization", &authorization));
-
-  EXPECT_EQ(content_encoding, "gzip");
-  EXPECT_EQ(authorization, "Bearer access_token");
-}
-
-TEST_F(FeedNetworkingHostTest, ProvideIsSignedInBitInResult) {
-  MockResponseDoneCallback done_callback;
-  SendRequestAndRespond("http://foobar.com/feed", "POST", "body", "",
-                        net::HTTP_OK, network::URLLoaderCompletionStatus(),
-                        &done_callback);
-
-  EXPECT_TRUE(done_callback.is_signed_in_result);
-}
-
-TEST_F(FeedNetworkingHostTest, ShouldNotSendContentEncodingForEmptyBody) {
-  MockResponseDoneCallback done_callback;
-  net::HttpRequestHeaders headers;
-  base::RunLoop interceptor_run_loop;
-
-  test_factory()->SetInterceptor(
-      base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
-        headers = request.headers;
-        interceptor_run_loop.Quit();
-      }));
-
-  SendRequestAndRespond("http://foobar.com/feed", "GET", "", "", net::HTTP_OK,
-                        network::URLLoaderCompletionStatus(), &done_callback);
-
-  EXPECT_FALSE(headers.HasHeader("content-encoding"));
-}
-
-TEST_F(FeedNetworkingHostTest, ShouldReportSizeHistograms) {
-  std::string uncompressed_request_string(2048, 'a');
-  std::string response_string(1024, 'b');
-  base::HistogramTester histogram_tester;
-
-  SendRequestAndValidateResponse("http://foobar.com/feed",
-                                 uncompressed_request_string, response_string,
-                                 net::HTTP_OK);
-
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "ContentSuggestions.Feed.Network.ResponseSizeKB"),
-              ElementsAre(base::Bucket(/*min=*/1, /*count=*/1)));
-
-  // A single character repeated 2048 times compresses to well under 1kb.
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "ContentSuggestions.Feed.Network.RequestSizeKB.Compressed"),
-              ElementsAre(base::Bucket(/*min=*/0, /*count=*/1)));
-}
-
-TEST_F(FeedNetworkingHostTest, CancellationIsSafe) {
-  MockResponseDoneCallback done_callback;
-  MockResponseDoneCallback done_callback2;
-  std::vector<uint8_t> request_body;
-
-  service()->Send(GURL("http://foobar.com/feed"), "POST", request_body,
-                  base::BindOnce(&MockResponseDoneCallback::Done,
-                                 base::Unretained(&done_callback)));
-
-  identity_env()->SetAutomaticIssueOfAccessTokens(false);
-  service()->Send(GURL("http://foobar.com/feed2"), "POST", request_body,
-                  base::BindOnce(&MockResponseDoneCallback::Done,
-                                 base::Unretained(&done_callback2)));
-  task_environment_.FastForwardUntilNoTasksRemain();
-  service()->CancelRequests();
-}
-
-TEST_F(FeedNetworkingHostTest, ShouldIncludeAPIKeyForAuthError) {
-  identity_env()->SetAutomaticIssueOfAccessTokens(false);
-  MockResponseDoneCallback done_callback;
-  base::HistogramTester histogram_tester;
-
-  service()->Send(GURL("http://foobar.com/feed"), "POST",
-                  std::vector<uint8_t>(),
-                  base::BindOnce(&MockResponseDoneCallback::Done,
-                                 base::Unretained(&done_callback)));
-  identity_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithError(
-      GoogleServiceAuthError(
-          GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS));
-
-  Respond(GURL("http://foobar.com/feed?key=dummy_api_key"), "");
-  EXPECT_TRUE(done_callback.has_run);
-
-  EXPECT_THAT(
-      histogram_tester.GetAllSamples(
-          "ContentSuggestions.Feed.Network.TokenFetchStatus"),
-      ElementsAre(base::Bucket(
-          /*min=*/GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS,
-          /*count=*/1)));
-}
-
-// Disabled for chromeos, which doesn't allow for there not to be a signed in
-// user.
-#if !BUILDFLAG(IS_CHROMEOS_ASH)
-TEST_F(FeedNetworkingHostTest, ShouldIncludeAPIKeyForNoSignedInUser) {
-  identity_env()->ClearPrimaryAccount();
-  MockResponseDoneCallback done_callback;
-
-  service()->Send(GURL("http://foobar.com/feed"), "POST",
-                  std::vector<uint8_t>(),
-                  base::BindOnce(&MockResponseDoneCallback::Done,
-                                 base::Unretained(&done_callback)));
-
-  Respond(GURL("http://foobar.com/feed?key=dummy_api_key"), "");
-  EXPECT_TRUE(done_callback.has_run);
-}
-#endif
-
-TEST_F(FeedNetworkingHostTest, TestDurationHistogram) {
-  base::HistogramTester histogram_tester;
-  MockResponseDoneCallback done_callback;
-  GURL url = GURL("http://foobar.com/feed");
-  std::vector<uint8_t> request_body;
-  TimeDelta duration = TimeDelta::FromMilliseconds(12345);
-
-  service()->Send(url, "POST", request_body,
-                  base::BindOnce(&MockResponseDoneCallback::Done,
-                                 base::Unretained(&done_callback)));
-  task_environment_.FastForwardBy(duration);
-  Respond(url, "", net::HTTP_OK, network::URLLoaderCompletionStatus());
-
-  EXPECT_TRUE(done_callback.has_run);
-  histogram_tester.ExpectTimeBucketCount(
-      "ContentSuggestions.Feed.Network.Duration", duration, 1);
-}
-
-TEST_F(FeedNetworkingHostTest, TestDefaultTimeout) {
-  base::HistogramTester histogram_tester;
-  MockResponseDoneCallback done_callback;
-  GURL url = GURL("http://foobar.com/feed");
-  std::vector<uint8_t> request_body;
-
-  service()->Send(url, "POST", request_body,
-                  base::BindOnce(&MockResponseDoneCallback::Done,
-                                 base::Unretained(&done_callback)));
-  task_environment_.FastForwardBy(TimeDelta::FromSeconds(29));
-  EXPECT_FALSE(done_callback.has_run);
-
-  task_environment_.FastForwardBy(TimeDelta::FromSeconds(29));
-  EXPECT_TRUE(done_callback.has_run);
-  histogram_tester.ExpectTimeBucketCount(
-      "ContentSuggestions.Feed.Network.Duration", TimeDelta::FromSeconds(30),
-      1);
-}
-
-TEST_F(FeedNetworkingHostTest, TestParamTimeout) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions, {{kTimeoutDurationSeconds.name, "2"}});
-  MockResponseDoneCallback done_callback;
-  GURL url = GURL("http://foobar.com/feed");
-  std::vector<uint8_t> request_body;
-
-  service()->Send(url, "POST", request_body,
-                  base::BindOnce(&MockResponseDoneCallback::Done,
-                                 base::Unretained(&done_callback)));
-  task_environment_.FastForwardBy(TimeDelta::FromSeconds(1));
-  EXPECT_FALSE(done_callback.has_run);
-
-  task_environment_.FastForwardBy(TimeDelta::FromSeconds(1));
-  EXPECT_TRUE(done_callback.has_run);
-}
-
-// Verify that the kHostOverrideHost pref overrides the feed host
-// and updates the Bless nonce if one sent in the response.
-TEST_F(FeedNetworkingHostTest, TestHostOverrideWithAuthHeader) {
-  MockResponseDoneCallback done_callback;
-  profile_prefs().SetString(feed::prefs::kHostOverrideHost,
-                            "http://www.newhost.com/");
-
-  service()->Send(GURL("http://foobar.com/feed"), "GET", {},
-                  base::BindOnce(&MockResponseDoneCallback::Done,
-                                 base::Unretained(&done_callback)));
-
-  auto head = network::mojom::URLResponseHead::New();
-  head->headers = base::MakeRefCounted<net::HttpResponseHeaders>(
-      net::HttpUtil::AssembleRawHeaders(
-          "HTTP/1.1 401 Unauthorized\nwww-authenticate: Foo "
-          "nonce=\"1234123412341234\"\n\n"));
-  // The response is from www.newhost.com, which verifies that the host is
-  // overridden in the request as expected.
-  test_factory()->AddResponse(GURL("http://www.newhost.com/feed"),
-                              std::move(head), std::string(),
-                              network::URLLoaderCompletionStatus());
-  task_environment_.FastForwardUntilNoTasksRemain();
-
-  EXPECT_TRUE(done_callback.has_run);
-  EXPECT_EQ("1234123412341234",
-            profile_prefs().GetString(feed::prefs::kHostOverrideBlessNonce));
-}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_scheduler_host.cc b/components/feed/core/feed_scheduler_host.cc
deleted file mode 100644
index 7a2b7348..0000000
--- a/components/feed/core/feed_scheduler_host.cc
+++ /dev/null
@@ -1,636 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_scheduler_host.h"
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/containers/contains.h"
-#include "base/metrics/field_trial_params.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/string_split.h"
-#include "base/strings/stringprintf.h"
-#include "base/time/clock.h"
-#include "base/time/time.h"
-#include "components/feed/core/common/pref_names.h"
-#include "components/feed/core/shared_prefs/pref_names.h"
-#include "components/feed/core/time_serialization.h"
-#include "components/feed/feed_feature_list.h"
-#include "components/prefs/pref_service.h"
-#include "components/web_resource/web_resource_pref_names.h"
-#include "net/base/network_change_notifier.h"
-
-namespace feed {
-
-namespace {
-
-// Enum for the relation between boolean fields the Feed and host both track.
-// Reported through UMA and must match the corresponding definition in
-// enums.xml
-enum class FeedHostMismatch {
-  kNeitherAreSet = 0,
-  kFeedIsSetOnly = 1,
-  kHostIsSetOnly = 2,
-  kBothAreSet = 3,
-  kMaxValue = kBothAreSet,
-};
-
-FeedHostMismatch GetMismatch(bool feed_is_set, bool host_is_set) {
-  if (feed_is_set && host_is_set) {
-    return FeedHostMismatch::kBothAreSet;
-  } else if (feed_is_set) {
-    return FeedHostMismatch::kFeedIsSetOnly;
-  } else if (host_is_set) {
-    return FeedHostMismatch::kHostIsSetOnly;
-  }
-  return FeedHostMismatch::kNeitherAreSet;
-}
-
-struct ParamPair {
-  std::string name;
-  double default_value;
-};
-
-// The Cartesian product of TriggerType and UserClass each need a different
-// param name in case we decide to change it via a config change. This nested
-// switch lookup ensures that all combinations are defined, along with a
-// default value.
-ParamPair LookupParam(UserClass user_class, TriggerType trigger) {
-  switch (user_class) {
-    case UserClass::kRareSuggestionsViewer:
-      switch (trigger) {
-        case TriggerType::kNtpShown:
-          return {"ntp_shown_hours_rare_ntp_user", 4.0};
-        case TriggerType::kForegrounded:
-          return {"foregrounded_hours_rare_ntp_user", 24.0};
-        case TriggerType::kFixedTimer:
-          return {"fixed_timer_hours_rare_ntp_user", 96.0};
-      }
-    case UserClass::kActiveSuggestionsViewer:
-      switch (trigger) {
-        case TriggerType::kNtpShown:
-          return {"ntp_shown_hours_active_ntp_user", 4.0};
-        case TriggerType::kForegrounded:
-          return {"foregrounded_hours_active_ntp_user", 24.0};
-        case TriggerType::kFixedTimer:
-          return {"fixed_timer_hours_active_ntp_user", 48.0};
-      }
-    case UserClass::kActiveSuggestionsConsumer:
-      switch (trigger) {
-        case TriggerType::kNtpShown:
-          return {"ntp_shown_hours_active_suggestions_consumer", 1.0};
-        case TriggerType::kForegrounded:
-          return {"foregrounded_hours_active_suggestions_consumer", 12.0};
-        case TriggerType::kFixedTimer:
-          return {"fixed_timer_hours_active_suggestions_consumer", 24.0};
-      }
-  }
-}
-
-// Coverts from base::StringPiece to TriggerType and adds it to the set if the
-// trigger is recognized. Otherwise it is ignored.
-void TryAddTriggerType(base::StringPiece trigger_as_string_piece,
-                       std::set<TriggerType>* trigger_set) {
-  static_assert(static_cast<unsigned int>(TriggerType::kMaxValue) == 2,
-                "New TriggerTypes must be handled below.");
-  if (trigger_as_string_piece == "ntp_shown") {
-    trigger_set->insert(TriggerType::kNtpShown);
-  } else if (trigger_as_string_piece == "foregrounded") {
-    trigger_set->insert(TriggerType::kForegrounded);
-  } else if (trigger_as_string_piece == "fixed_timer") {
-    trigger_set->insert(TriggerType::kFixedTimer);
-  }
-}
-
-// Generates a set of disabled triggers.
-std::set<TriggerType> GetDisabledTriggerTypes() {
-  std::set<TriggerType> disabled_triggers;
-
-  // Do not in-line FeatureParam::Get(), |param_value| must stay alive while
-  // StringPieces reference segments.
-  std::string param_value = kDisableTriggerTypes.Get();
-
-  for (auto token :
-       base::SplitStringPiece(param_value, ",", base::TRIM_WHITESPACE,
-                              base::SPLIT_WANT_NONEMPTY)) {
-    TryAddTriggerType(token, &disabled_triggers);
-  }
-  return disabled_triggers;
-}
-
-// Run the given closure if it is valid.
-void TryRun(base::OnceClosure closure) {
-  if (closure) {
-    std::move(closure).Run();
-  }
-}
-
-// Converts UserClass to a string that corresponds to the
-// entries in histogram suffix "UserClasses".
-std::string UserClassToHistogramSuffix(UserClass user_class) {
-  switch (user_class) {
-    case UserClass::kRareSuggestionsViewer:
-      return "RareNTPUser";
-    case UserClass::kActiveSuggestionsViewer:
-      return "ActiveNTPUser";
-    case UserClass::kActiveSuggestionsConsumer:
-      return "ActiveSuggestionsConsumer";
-  }
-}
-
-// This has a small performance penalty because it is looking up the histogram
-// dynamically, which avoids a significantly amount of boilerplate code for the
-// various |qualified_trigger| and user class strings. This is reasonable
-// because this method is only called as a result of a direct user interaction,
-// like opening the NTP or foregrounding the browser.
-void ReportAgeWithSuffix(const std::string& qualified_trigger,
-                         UserClass user_class,
-                         base::TimeDelta sample) {
-  std::string name = base::StringPrintf(
-      "NewTabPage.ContentSuggestions.%s.%s", qualified_trigger.c_str(),
-      UserClassToHistogramSuffix(user_class).c_str());
-  base::UmaHistogramCustomTimes(name, sample, base::TimeDelta::FromSeconds(1),
-                                base::TimeDelta::FromDays(7),
-                                /*bucket_count=*/50);
-}
-
-void ReportReasonForNotRefreshingByBehavior(NativeRequestBehavior behavior,
-                                            ShouldRefreshResult status) {
-  DCHECK_NE(status, ShouldRefreshResult::kShouldRefresh);
-  switch (behavior) {
-    case kNoRequestWithWait:
-      UMA_HISTOGRAM_ENUMERATION(
-          "ContentSuggestions.Feed.Scheduler.ShouldRefreshResult."
-          "NoRequestWithWait",
-          status);
-      break;
-    case kNoRequestWithContent:
-      UMA_HISTOGRAM_ENUMERATION(
-          "ContentSuggestions.Feed.Scheduler.ShouldRefreshResult."
-          "NoRequestWithContent",
-          status);
-      break;
-    case kNoRequestWithTimeout:
-      UMA_HISTOGRAM_ENUMERATION(
-          "ContentSuggestions.Feed.Scheduler.ShouldRefreshResult."
-          "NoRequestWithTimeout",
-          status);
-      break;
-    case kUnknown:
-    case kRequestWithWait:
-    case kRequestWithContent:
-    case kRequestWithTimeout:
-      NOTREACHED();
-      break;
-  }
-}
-
-void ReportReasonForNotRefreshingByTrigger(TriggerType trigger_type,
-                                           ShouldRefreshResult status) {
-  DCHECK_NE(status, ShouldRefreshResult::kShouldRefresh);
-  switch (trigger_type) {
-    case TriggerType::kNtpShown:
-      UMA_HISTOGRAM_ENUMERATION(
-          "ContentSuggestions.Feed.Scheduler.ShouldRefreshResult."
-          "RequestByNtpShown",
-          status);
-      break;
-    case TriggerType::kForegrounded:
-      UMA_HISTOGRAM_ENUMERATION(
-          "ContentSuggestions.Feed.Scheduler.ShouldRefreshResult."
-          "RequestByForegrounded",
-          status);
-      break;
-    case TriggerType::kFixedTimer:
-      UMA_HISTOGRAM_ENUMERATION(
-          "ContentSuggestions.Feed.Scheduler.ShouldRefreshResult."
-          "RequestByFixedTimer",
-          status);
-      break;
-  }
-}
-
-const int kHttpStatusOk = 200;
-
-}  // namespace
-
-FeedSchedulerHost::FeedSchedulerHost(PrefService* profile_prefs,
-                                     PrefService* local_state,
-                                     base::Clock* clock)
-    : profile_prefs_(profile_prefs),
-      clock_(clock),
-      user_classifier_(profile_prefs, clock),
-      disabled_triggers_(GetDisabledTriggerTypes()),
-      eula_accepted_notifier_(
-          web_resource::EulaAcceptedNotifier::Create(local_state)) {
-  if (eula_accepted_notifier_) {
-    eula_accepted_notifier_->Init(this);
-  }
-
-  throttlers_.emplace(
-      UserClass::kRareSuggestionsViewer,
-      std::make_unique<RefreshThrottler>(UserClass::kRareSuggestionsViewer,
-                                         profile_prefs_, clock_));
-  throttlers_.emplace(
-      UserClass::kActiveSuggestionsViewer,
-      std::make_unique<RefreshThrottler>(UserClass::kActiveSuggestionsViewer,
-                                         profile_prefs_, clock_));
-  throttlers_.emplace(
-      UserClass::kActiveSuggestionsConsumer,
-      std::make_unique<RefreshThrottler>(UserClass::kActiveSuggestionsConsumer,
-                                         profile_prefs_, clock_));
-}
-
-FeedSchedulerHost::~FeedSchedulerHost() = default;
-
-void FeedSchedulerHost::Initialize(
-    base::RepeatingClosure refresh_callback,
-    ScheduleBackgroundTaskCallback schedule_background_task_callback,
-    base::RepeatingClosure cancel_background_task_callback) {
-  // There should only ever be one scheduler host and bridge created. Neither
-  // are ever destroyed before shutdown, and this method should only be called
-  // once as the bridge is constructed.
-  DCHECK(!refresh_callback_);
-  DCHECK(!schedule_background_task_callback_);
-  DCHECK(!cancel_background_task_callback_);
-
-  refresh_callback_ = std::move(refresh_callback);
-  schedule_background_task_callback_ =
-      std::move(schedule_background_task_callback);
-  cancel_background_task_callback_ = std::move(cancel_background_task_callback);
-
-  if (!profile_prefs_->GetBoolean(prefs::kArticlesListVisible)) {
-    CancelFixedTimerWakeUp();
-    return;
-  }
-
-  base::TimeDelta old_period =
-      profile_prefs_->GetTimeDelta(prefs::kBackgroundRefreshPeriod);
-  base::TimeDelta new_period = GetTriggerThreshold(TriggerType::kFixedTimer);
-  if (old_period != new_period) {
-    ScheduleFixedTimerWakeUp(new_period);
-  }
-}
-
-NativeRequestBehavior FeedSchedulerHost::ShouldSessionRequestData(
-    bool has_content,
-    base::Time content_creation_date_time,
-    bool has_outstanding_request) {
-  // Both the Feed and the scheduler track if there are outstanding requests.
-  // It's possible that this data gets out of sync. We treat the Feed as
-  // authoritative and we change our values to match.
-  UMA_HISTOGRAM_ENUMERATION(
-      "ContentSuggestions.Feed.Scheduler.OutstandingRequest",
-      GetMismatch(has_outstanding_request,
-                  !outstanding_request_until_.is_null()));
-  if (has_outstanding_request == outstanding_request_until_.is_null()) {
-    if (has_outstanding_request) {
-      outstanding_request_until_ =
-          clock_->Now() +
-          base::TimeDelta::FromSeconds(kTimeoutDurationSeconds.Get());
-    } else {
-      outstanding_request_until_ = base::Time();
-    }
-  }
-
-  // It seems to be possible for the scheduler's tracking of having content to
-  // get out of sync with the Feed. Root cause is currently unknown, but similar
-  // to outstanding request handling, we can repair with the information we
-  // have.
-  bool scheduler_thinks_has_content =
-      !profile_prefs_->FindPreference(prefs::kLastFetchAttemptTime)
-           ->IsDefaultValue();
-  UMA_HISTOGRAM_ENUMERATION(
-      "ContentSuggestions.Feed.Scheduler.HasContent",
-      GetMismatch(has_content, scheduler_thinks_has_content));
-  if (has_content != scheduler_thinks_has_content) {
-    if (has_content) {
-      profile_prefs_->SetTime(prefs::kLastFetchAttemptTime,
-                              content_creation_date_time);
-    } else {
-      profile_prefs_->ClearPref(prefs::kLastFetchAttemptTime);
-    }
-  } else if (has_content) {  // && scheduler_thinks_has_content
-    // Split into two histograms so the difference is always positive.
-    base::Time last_attempt =
-        profile_prefs_->GetTime(prefs::kLastFetchAttemptTime);
-    if (content_creation_date_time > last_attempt) {
-      base::TimeDelta difference = (content_creation_date_time - last_attempt);
-      UMA_HISTOGRAM_CUSTOM_TIMES(
-          "ContentSuggestions.Feed.Scheduler.ContentAgeDifference.FeedIsOlder",
-          difference, base::TimeDelta::FromMilliseconds(1),
-          base::TimeDelta::FromDays(7), 100);
-    } else {
-      base::TimeDelta difference = (last_attempt - content_creation_date_time);
-      UMA_HISTOGRAM_CUSTOM_TIMES(
-          "ContentSuggestions.Feed.Scheduler.ContentAgeDifference.HostIsOlder",
-          difference, base::TimeDelta::FromMilliseconds(1),
-          base::TimeDelta::FromDays(7), 100);
-    }
-  }
-
-  NativeRequestBehavior behavior;
-  ShouldRefreshResult refresh_status = ShouldRefresh(TriggerType::kNtpShown);
-  if (ShouldRefreshResult::kShouldRefresh == refresh_status) {
-    if (!has_content) {
-      behavior = kRequestWithWait;
-    } else if (IsContentStale(content_creation_date_time)) {
-      behavior = kRequestWithTimeout;
-    } else {
-      behavior = kRequestWithContent;
-    }
-  } else {
-    // Note that kNoRequestWithWait is used to show a blank article section
-    // even when no request is being made. The user will be given the ability to
-    // force a refresh but this scheduler is not driving it.
-    if (!has_content) {
-      behavior = kNoRequestWithWait;
-    } else if (IsContentStale(content_creation_date_time) &&
-               has_outstanding_request) {
-      // This needs to check |has_outstanding_request|, it does not make sense
-      // to use a timeout when no request is being made. Just show the stale
-      // content, since nothing better is on the way.
-      behavior = kNoRequestWithTimeout;
-    } else {
-      behavior = kNoRequestWithContent;
-    }
-    ReportReasonForNotRefreshingByBehavior(behavior, refresh_status);
-  }
-
-  OnSuggestionsShown();
-  DVLOG(2) << "Specifying NativeRequestBehavior of "
-           << static_cast<int>(behavior);
-  UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.Scheduler.RequestBehavior",
-                            behavior);
-  return behavior;
-}
-
-void FeedSchedulerHost::OnReceiveNewContent(
-    base::Time content_creation_date_time) {
-  profile_prefs_->SetTime(prefs::kLastFetchAttemptTime,
-                          content_creation_date_time);
-  last_fetch_status_ = kHttpStatusOk;
-  TryRun(std::move(fixed_timer_completion_));
-  ScheduleFixedTimerWakeUp(GetTriggerThreshold(TriggerType::kFixedTimer));
-  outstanding_request_until_ = base::Time();
-  time_until_first_shown_trigger_reported_ = false;
-  time_until_first_foregrounded_trigger_reported_ = false;
-  DVLOG(2) << "Received OnReceiveNewContent with time "
-           << content_creation_date_time;
-}
-
-void FeedSchedulerHost::OnRequestError(int network_response_code) {
-  if (!kOnlySetLastRefreshAttemptOnSuccess.Get())
-    profile_prefs_->SetTime(prefs::kLastFetchAttemptTime, clock_->Now());
-
-  last_fetch_status_ = network_response_code;
-  TryRun(std::move(fixed_timer_completion_));
-  outstanding_request_until_ = base::Time();
-  time_until_first_shown_trigger_reported_ = false;
-  time_until_first_foregrounded_trigger_reported_ = false;
-  DVLOG(2) << "Received OnRequestError with code " << network_response_code;
-}
-
-void FeedSchedulerHost::OnForegrounded() {
-  DCHECK(refresh_callback_);
-  ShouldRefreshResult refresh_status =
-      ShouldRefresh(TriggerType::kForegrounded);
-  if (ShouldRefreshResult::kShouldRefresh == refresh_status) {
-    refresh_callback_.Run();
-  } else {
-    ReportReasonForNotRefreshingByTrigger(TriggerType::kForegrounded,
-                                          refresh_status);
-  }
-}
-
-void FeedSchedulerHost::OnFixedTimer(base::OnceClosure on_completion) {
-  DCHECK(refresh_callback_);
-  DCHECK(cancel_background_task_callback_);
-
-  // While the check and cancel isn't strictly necessary, a long lived session
-  // could be issuing refreshes due to the background trigger while articles are
-  // not visible. So check and cancel.
-  if (!profile_prefs_->GetBoolean(prefs::kArticlesListVisible)) {
-    CancelFixedTimerWakeUp();
-  }
-
-  ShouldRefreshResult refresh_status = ShouldRefresh(TriggerType::kFixedTimer);
-  if (ShouldRefreshResult::kShouldRefresh == refresh_status) {
-    // There shouldn't typically be anything in |fixed_timer_completion_| right
-    // now, but if there was, run it before we replace it.
-    TryRun(std::move(fixed_timer_completion_));
-
-    fixed_timer_completion_ = std::move(on_completion);
-    refresh_callback_.Run();
-  } else {
-    ReportReasonForNotRefreshingByTrigger(TriggerType::kFixedTimer,
-                                          refresh_status);
-    // The task driving this doesn't need to stay around, since no work is being
-    // done on its behalf.
-    TryRun(std::move(on_completion));
-  }
-}
-
-void FeedSchedulerHost::OnSuggestionConsumed() {
-  user_classifier_.OnEvent(UserClassifier::Event::kSuggestionsUsed);
-}
-
-void FeedSchedulerHost::OnSuggestionsShown() {
-  user_classifier_.OnEvent(UserClassifier::Event::kSuggestionsViewed);
-}
-
-bool FeedSchedulerHost::OnArticlesCleared(bool suppress_refreshes) {
-  base::TimeDelta attempt_age =
-      clock_->Now() - profile_prefs_->GetTime(prefs::kLastFetchAttemptTime);
-  UMA_HISTOGRAM_CUSTOM_TIMES(
-      "ContentSuggestions.Feed.Scheduler.TimeSinceLastFetchOnClear",
-      attempt_age, base::TimeDelta::FromSeconds(1),
-      base::TimeDelta::FromDays(7),
-      /*bucket_count=*/50);
-
-  // Since there are no stored articles, a refresh will be needed soon.
-  profile_prefs_->ClearPref(prefs::kLastFetchAttemptTime);
-
-  // The Feed will try to drop any outstanding refresh request, so we should
-  // stop tracking one as well.
-  outstanding_request_until_ = base::Time();
-
-  if (suppress_refreshes) {
-    // Due to privacy, we should not fetch for a while (unless the user
-    // explicitly asks for new suggestions) to give sync the time to propagate
-    // the changes in history to the server.
-    suppress_refreshes_until_ =
-        clock_->Now() +
-        base::TimeDelta::FromMinutes(kSuppressRefreshDurationMinutes.Get());
-  }
-
-  ShouldRefreshResult refresh_status = ShouldRefresh(TriggerType::kNtpShown);
-  if (ShouldRefreshResult::kShouldRefresh == refresh_status) {
-    // Instead of using |refresh_callback_|, instead return our desire to
-    // refresh back up to our caller. This allows more information to be given
-    // all at once to the Feed which allows it to act more intelligently.
-    return true;
-  } else {
-    ReportReasonForNotRefreshingByTrigger(TriggerType::kNtpShown,
-                                          refresh_status);
-  }
-
-  return false;
-}
-
-UserClassifier* FeedSchedulerHost::GetUserClassifierForDebugging() {
-  return &user_classifier_;
-}
-
-base::Time FeedSchedulerHost::GetSuppressRefreshesUntilForDebugging() const {
-  return suppress_refreshes_until_;
-}
-
-int FeedSchedulerHost::GetLastFetchStatusForDebugging() const {
-  return last_fetch_status_;
-}
-
-TriggerType* FeedSchedulerHost::GetLastFetchTriggerTypeForDebugging() const {
-  return last_fetch_trigger_type_.get();
-}
-
-void FeedSchedulerHost::OnEulaAccepted() {
-  OnForegrounded();
-}
-
-ShouldRefreshResult FeedSchedulerHost::ShouldRefresh(TriggerType trigger) {
-  if (clock_->Now() < outstanding_request_until_) {
-    DVLOG(2) << "Outstanding request stopped refresh from trigger "
-             << static_cast<int>(trigger);
-    return ShouldRefreshResult::kDontRefreshOutstandingRequest;
-  }
-
-  if (base::Contains(disabled_triggers_, trigger)) {
-    DVLOG(2) << "Disabled trigger stopped refresh from trigger "
-             << static_cast<int>(trigger);
-    return ShouldRefreshResult::kDontRefreshTriggerDisabled;
-  }
-
-  if (net::NetworkChangeNotifier::IsOffline()) {
-    DVLOG(2) << "Network is offline stopped refresh from trigger "
-             << static_cast<int>(trigger);
-    return ShouldRefreshResult::kDontRefreshNetworkOffline;
-  }
-
-  if (eula_accepted_notifier_ && !eula_accepted_notifier_->IsEulaAccepted()) {
-    DVLOG(2) << "EULA not being accepted stopped refresh from trigger "
-             << static_cast<int>(trigger);
-    return ShouldRefreshResult::kDontRefreshEulaNotAccepted;
-  }
-
-  if (!profile_prefs_->GetBoolean(prefs::kArticlesListVisible)) {
-    DVLOG(2) << "Articles being hidden stopped refresh from trigger "
-             << static_cast<int>(trigger);
-    return ShouldRefreshResult::kDontRefreshArticlesHidden;
-  }
-
-  base::TimeDelta attempt_age =
-      clock_->Now() - profile_prefs_->GetTime(prefs::kLastFetchAttemptTime);
-  UserClass user_class = user_classifier_.GetUserClass();
-  if (trigger == TriggerType::kNtpShown &&
-      !time_until_first_shown_trigger_reported_) {
-    time_until_first_shown_trigger_reported_ = true;
-    ReportAgeWithSuffix("TimeUntilFirstShownTrigger", user_class, attempt_age);
-  }
-
-  if (trigger == TriggerType::kForegrounded &&
-      !time_until_first_foregrounded_trigger_reported_) {
-    time_until_first_foregrounded_trigger_reported_ = true;
-    ReportAgeWithSuffix("TimeUntilFirstStartupTrigger", user_class,
-                        attempt_age);
-  }
-
-  if (clock_->Now() < suppress_refreshes_until_) {
-    DVLOG(2) << "Refresh suppression until " << suppress_refreshes_until_
-             << " stopped refresh from trigger " << static_cast<int>(trigger);
-    return ShouldRefreshResult::kDontRefreshRefreshSuppressed;
-  }
-
-  // https://crbug.com/988165: When kThrottleBackgroundFetches == false, skip
-  // checks for quota and staleness for background fetching.
-  if (kThrottleBackgroundFetches.Get() || trigger != TriggerType::kFixedTimer) {
-    if (attempt_age < GetTriggerThreshold(trigger)) {
-      DVLOG(2) << "Last attempt age of " << attempt_age
-               << " stopped refresh from trigger " << static_cast<int>(trigger);
-      return ShouldRefreshResult::kDontRefreshNotStale;
-    }
-
-    auto throttlerIter = throttlers_.find(user_class);
-    if (throttlerIter == throttlers_.end() ||
-        !throttlerIter->second->RequestQuota()) {
-      DVLOG(2) << "Throttler stopped refresh from trigger "
-               << static_cast<int>(trigger);
-      return ShouldRefreshResult::kDontRefreshRefreshThrottled;
-    }
-  }
-
-  switch (trigger) {
-    case TriggerType::kNtpShown:
-      ReportAgeWithSuffix("TimeUntilSoftFetch", user_class, attempt_age);
-      break;
-    case TriggerType::kForegrounded:
-      ReportAgeWithSuffix("TimeUntilStartupFetch", user_class, attempt_age);
-      break;
-    case TriggerType::kFixedTimer:
-      ReportAgeWithSuffix("TimeUntilPersistentFetch", user_class, attempt_age);
-      break;
-  }
-
-  DVLOG(2) << "Requesting refresh from trigger " << static_cast<int>(trigger);
-  UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.Scheduler.RefreshTrigger",
-                            trigger);
-  outstanding_request_until_ =
-      clock_->Now() +
-      base::TimeDelta::FromSeconds(kTimeoutDurationSeconds.Get());
-
-  last_fetch_trigger_type_ = std::make_unique<TriggerType>(trigger);
-
-  return ShouldRefreshResult::kShouldRefresh;
-}
-
-bool FeedSchedulerHost::IsContentStale(base::Time content_creation_date_time) {
-  return (clock_->Now() - content_creation_date_time) >
-         GetTriggerThreshold(TriggerType::kForegrounded);
-}
-
-base::TimeDelta FeedSchedulerHost::GetTriggerThreshold(TriggerType trigger) {
-  UserClass user_class = user_classifier_.GetUserClass();
-  ParamPair param = LookupParam(user_class, trigger);
-  double value_hours = base::GetFieldTrialParamByFeatureAsDouble(
-      kInterestFeedContentSuggestions, param.name, param.default_value);
-
-  // Use FromSecondsD in case one of the values contained a decimal.
-  return base::TimeDelta::FromSecondsD(value_hours * 3600.0);
-}
-
-void FeedSchedulerHost::ScheduleFixedTimerWakeUp(base::TimeDelta period) {
-  profile_prefs_->SetTimeDelta(prefs::kBackgroundRefreshPeriod, period);
-
-  // CancelFixedTimerWakeUp() uses Preference::IsDefaultValue() to check if the
-  // cancellation logic needs to be run. We should therefor never schedule and
-  // set the preference to the default value. This DCHECK after SetTimeDelta
-  // verifies that this isn't happening.
-  DCHECK(!profile_prefs_->FindPreference(prefs::kBackgroundRefreshPeriod)
-              ->IsDefaultValue());
-
-  schedule_background_task_callback_.Run(period);
-}
-
-void FeedSchedulerHost::CancelFixedTimerWakeUp() {
-  if (!profile_prefs_->FindPreference(prefs::kBackgroundRefreshPeriod)
-           ->IsDefaultValue()) {
-    profile_prefs_->ClearPref(prefs::kBackgroundRefreshPeriod);
-    cancel_background_task_callback_.Run();
-  }
-}
-
-}  // namespace feed
diff --git a/components/feed/core/feed_scheduler_host.h b/components/feed/core/feed_scheduler_host.h
deleted file mode 100644
index e1e1375..0000000
--- a/components/feed/core/feed_scheduler_host.h
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_FEED_SCHEDULER_HOST_H_
-#define COMPONENTS_FEED_CORE_FEED_SCHEDULER_HOST_H_
-
-#include <memory>
-#include <set>
-
-#include "base/callback.h"
-#include "base/containers/flat_map.h"
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "components/feed/core/common/enums.h"
-#include "components/feed/core/common/refresh_throttler.h"
-#include "components/feed/core/common/user_classifier.h"
-#include "components/web_resource/eula_accepted_notifier.h"
-
-class PrefService;
-
-namespace base {
-class Clock;
-class Time;
-class TimeDelta;
-}  // namespace base
-
-namespace feed {
-
-// The enum values and names are kept in sync with SchedulerApi.RequestBehavior
-// through Java unit tests, new values however must be manually added. If any
-// new values are added, also update FeedSchedulerBridgeTest.java as well as
-// the corresponding definition in enums.xml.
-// A Java counterpart will be generated for this enum.
-// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.feed
-enum NativeRequestBehavior {
-  kUnknown = 0,
-  kRequestWithWait = 1,
-  kRequestWithContent = 2,
-  kRequestWithTimeout = 3,
-  kNoRequestWithWait = 4,
-  kNoRequestWithContent = 5,
-  kNoRequestWithTimeout = 6,
-  kMaxValue = kNoRequestWithTimeout
-};
-
-// Implementation of the Feed Scheduler Host API. The scheduler host decides
-// what content is allowed to be shown, based on its age, and when to fetch new
-// content.
-class FeedSchedulerHost : web_resource::EulaAcceptedNotifier::Observer {
- public:
-
-  FeedSchedulerHost(PrefService* profile_prefs,
-                    PrefService* local_state,
-                    base::Clock* clock);
-  ~FeedSchedulerHost() override;
-
-  using ScheduleBackgroundTaskCallback =
-      base::RepeatingCallback<void(base::TimeDelta)>;
-
-  // Provide dependent pieces of functionality the scheduler relies on. Should
-  // be called exactly once before other public methods are called. This is
-  // separate from the constructor because the FeedHostService owns and creates
-  // this class, while these providers need to be bridged through the JNI into a
-  // specific place that the FeedHostService does not know of.
-  void Initialize(
-      base::RepeatingClosure refresh_callback,
-      ScheduleBackgroundTaskCallback schedule_background_task_callback,
-      base::RepeatingClosure cancel_background_task_callback);
-
-  // Called when the NTP is opened to decide how to handle displaying and
-  // refreshing content.
-  NativeRequestBehavior ShouldSessionRequestData(
-      bool has_content,
-      base::Time content_creation_date_time,
-      bool has_outstanding_request);
-
-  // Called when a successful refresh completes.
-  void OnReceiveNewContent(base::Time content_creation_date_time);
-
-  // Called when an unsuccessful refresh completes.
-  void OnRequestError(int network_response_code);
-
-  // Called when browser is opened, launched, or foregrounded.
-  void OnForegrounded();
-
-  // Called when the scheduled fixed timer wakes up, |on_completion| will be
-  // invoked when the refresh completes, regardless of success. If no refresh
-  // is started for this trigger, |on_completion| is run immediately.
-  void OnFixedTimer(base::OnceClosure on_completion);
-
-  // Should be called when a suggestion is consumed. This is a signal the
-  // scheduler users to track the kind of user, and optimize refresh frequency.
-  void OnSuggestionConsumed();
-
-  // Should be called when suggestions are shown. This is a signal the scheduler
-  // users to track the kind of user, and optimize refresh frequency.
-  void OnSuggestionsShown();
-
-  // Should be called when something happens to clear stored articles. The
-  // scheduler updates its internal state and treats this event as a kNtpShown
-  // trigger. Similar to ShouldSessionRequestData(), the scheduler will not
-  // start a refresh itself during this method. Instead, the caller should check
-  // the return value, and if true, the caller should start a refresh.
-  bool OnArticlesCleared(bool suppress_refreshes);
-
-  // Surface user_classifier_ for internals debugging page.
-  UserClassifier* GetUserClassifierForDebugging();
-
-  // Surface suppress_refreshes_until_ for internals debugging page.
-  base::Time GetSuppressRefreshesUntilForDebugging() const;
-
-  // Surface last_fetch_status_ for internals debugging page.
-  int GetLastFetchStatusForDebugging() const;
-
-  // Surface the TriggerType for the last ShouldRefresh check that resulted in
-  // kShouldRefresh. Callers of ShouldRefresh are presumed to follow with the
-  // actual refresh.
-  TriggerType* GetLastFetchTriggerTypeForDebugging() const;
-
- private:
-  FRIEND_TEST_ALL_PREFIXES(FeedSchedulerHostTest, GetTriggerThreshold);
-
-  // web_resource::EulaAcceptedNotifier::Observer:
-  void OnEulaAccepted() override;
-
-  // Determines whether a refresh should be performed for the given |trigger|.
-  // If this method is called and returns kShouldRefresh we presume the refresh
-  // will happen, therefore we report metrics respectively and update
-  // |tracking_oustanding_request_|.
-  ShouldRefreshResult ShouldRefresh(TriggerType trigger);
-
-  // Decides if content whose age is the difference between now and
-  // |content_creation_date_time| is old enough to be considered stale.
-  bool IsContentStale(base::Time content_creation_date_time);
-
-  // Returns the time threshold for content or previous refresh attempt to be
-  // considered old enough for a given trigger to warrant a refresh.
-  base::TimeDelta GetTriggerThreshold(TriggerType trigger);
-
-  // Schedules a task to wake up and try to refresh. Overrides previously
-  // scheduled tasks.
-  void ScheduleFixedTimerWakeUp(base::TimeDelta period);
-
-  // Clears the task to wake up and try to refresh.
-  void CancelFixedTimerWakeUp();
-
-  // Non-owning reference to pref service providing durable storage.
-  PrefService* profile_prefs_;
-
-  // Non-owning reference to clock to get current time.
-  base::Clock* clock_;
-
-  // Persists NTP and article usage over time and provides a classification.
-  UserClassifier user_classifier_;
-
-  // Callback to request that an async refresh be started.
-  base::RepeatingClosure refresh_callback_;
-
-  // Provides ability to schedule persistent background fixed timer wake ups
-  // that will call into OnFixedTimer().
-  ScheduleBackgroundTaskCallback schedule_background_task_callback_;
-
-  // Provides ability to cancel the persistent background fixed timer wake ups.
-  base::RepeatingClosure cancel_background_task_callback_;
-
-  // When a background wake up has caused a fixed timer refresh, this callback
-  // will be valid and holds a way to inform the task driving this wake up that
-  // the refresh has completed. Is called on refresh success or failure.
-  base::OnceClosure fixed_timer_completion_;
-
-  // Set of triggers that should be ignored. By default this is empty.
-  std::set<TriggerType> disabled_triggers_;
-
-  // In some circumstances, such as when history is cleared, the scheduler will
-  // stop requesting refreshes for a given period. During this time, only direct
-  // user interaction with the NTP (and outside of the scheduler's control)
-  // should cause a refresh to occur.
-  base::Time suppress_refreshes_until_;
-
-  // The goal of this field is to not make multiple refresh request at the same
-  // time. When the scheduler starts or indicates the caller should start a
-  // request, this field is set. When that request finishes, this field is
-  // cleared. It is unclear if this field is always and correctly cleared out,
-  // so after the point in time held by this field, the scheduler is allowed to
-  // trigger another request.
-  base::Time outstanding_request_until_;
-
-  // May hold a nullptr if the platform does not show the user a EULA. Will only
-  // notify if IsEulaAccepted() is called and it returns false.
-  std::unique_ptr<web_resource::EulaAcceptedNotifier> eula_accepted_notifier_;
-
-  // Variables to allow metrics to be reported the first time a given trigger
-  // occurs after a refresh.
-  bool time_until_first_shown_trigger_reported_ = false;
-  bool time_until_first_foregrounded_trigger_reported_ = false;
-
-  // In the case the user transitions between user classes, hold onto a
-  // throttler for any situation.
-  base::flat_map<UserClass, std::unique_ptr<RefreshThrottler>> throttlers_;
-
-  // Status of the last fetch for debugging.
-  int last_fetch_status_ = 0;
-
-  // Reason for last fetch for debugging.
-  std::unique_ptr<TriggerType> last_fetch_trigger_type_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedSchedulerHost);
-};
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CORE_FEED_SCHEDULER_HOST_H_
diff --git a/components/feed/core/feed_scheduler_host_unittest.cc b/components/feed/core/feed_scheduler_host_unittest.cc
deleted file mode 100644
index 52ff4a80..0000000
--- a/components/feed/core/feed_scheduler_host_unittest.cc
+++ /dev/null
@@ -1,1093 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_scheduler_host.h"
-
-#include <algorithm>
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/memory/weak_ptr.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
-#include "base/test/simple_test_clock.h"
-#include "base/test/task_environment.h"
-#include "components/feed/core/common/pref_names.h"
-#include "components/feed/core/common/refresh_throttler.h"
-#include "components/feed/core/common/user_classifier.h"
-#include "components/feed/core/shared_prefs/pref_names.h"
-#include "components/feed/core/time_serialization.h"
-#include "components/feed/feed_feature_list.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/testing_pref_service.h"
-#include "components/web_resource/web_resource_pref_names.h"
-#include "net/base/mock_network_change_notifier.h"
-#include "net/base/network_change_notifier.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using base::Time;
-using base::TimeDelta;
-
-namespace feed {
-
-namespace {
-
-// Fixed "now" to make tests more deterministic.
-char kNowString[] = "2018-06-11 15:41";
-
-}  // namespace
-
-class ForceDeviceOffline {
- public:
-  ForceDeviceOffline() {
-    notifier_->SetConnectionType(net::NetworkChangeNotifier::CONNECTION_NONE);
-  }
-
- private:
-  std::unique_ptr<net::test::MockNetworkChangeNotifier> notifier_ =
-      net::test::MockNetworkChangeNotifier::Create();
-};
-
-class FeedSchedulerHostTest : public ::testing::Test {
- public:
-  void FixedTimerCompletion() { fixed_timer_completion_count_++; }
-
- protected:
-  FeedSchedulerHostTest() {
-    feed::RegisterProfilePrefs(profile_prefs_.registry());
-    local_state()->registry()->RegisterBooleanPref(::prefs::kEulaAccepted,
-                                                   true);
-    profile_prefs()->registry()->RegisterBooleanPref(
-        feed::prefs::kArticlesListVisible, true);
-
-    Time now;
-    EXPECT_TRUE(Time::FromUTCString(kNowString, &now));
-    test_clock_.SetNow(now);
-
-    NewScheduler();
-  }
-
-  void InitializeScheduler(FeedSchedulerHost* scheduler) {
-    scheduler->Initialize(
-        base::BindRepeating(&FeedSchedulerHostTest::TriggerRefresh,
-                            base::Unretained(this)),
-        base::BindRepeating(&FeedSchedulerHostTest::ScheduleWakeUp,
-                            base::Unretained(this)),
-        base::BindRepeating(&FeedSchedulerHostTest::CancelWakeUp,
-                            base::Unretained(this)));
-  }
-
-  // Recreates a new copy of the scheduler. This is useful if a test case needs
-  // to change some global state like prefs or params before the scheduler's
-  // constructor runs.
-  void NewScheduler() {
-    scheduler_ = std::make_unique<FeedSchedulerHost>(
-        &profile_prefs_, &local_state_, &test_clock_);
-    InitializeScheduler(scheduler());
-  }
-
-  // Note: Time will be advanced.
-  void ClassifyAsRareNtpUser() {
-    // By moving time forward from initial seed events, the user will be moved
-    // into kRareNtpUser classification.
-    test_clock()->Advance(TimeDelta::FromDays(7));
-
-    ASSERT_EQ(UserClass::kRareSuggestionsViewer,
-              scheduler()->GetUserClassifierForDebugging()->GetUserClass());
-  }
-
-  // Note: Time will be advanced.
-  void ClassifyAsActiveSuggestionsConsumer() {
-    // Click on some articles to move the user into kActiveSuggestionsConsumer
-    // classification. Separate by at least 30 minutes for different sessions.
-    scheduler()->OnSuggestionConsumed();
-    test_clock()->Advance(TimeDelta::FromMinutes(31));
-    scheduler()->OnSuggestionConsumed();
-
-    // Depending on which events occurred over which period of time in the test
-    // before this function was called, it may not necessarily be sufficient to
-    // push the user into the active consumer class.
-    ASSERT_EQ(UserClass::kActiveSuggestionsConsumer,
-              scheduler()->GetUserClassifierForDebugging()->GetUserClass());
-  }
-
-  // Many test cases want to ask the scheduler multiple times in a row to see
-  // which of the different triggers or under which conditions the scheduler
-  // will request a refresh. However the scheduler updates internal state when
-  // it decides a refresh must be made, most importantly, it sets
-  // |tracking_oustanding_request_| to true. Any subsequent trigger would then
-  // not start a refresh. To get around this, this method clears out
-  // |tracking_oustanding_request_|.
-  void ResetRefreshState(Time last_attempt) {
-    // OnRequestError() has the side effect of setting kLastFetchAttemptTime to
-    // the scheduler's clock's now. This typically is not helpful to most test
-    // cases, so override it.
-    scheduler()->OnRequestError(0);
-    profile_prefs()->SetTime(prefs::kLastFetchAttemptTime, last_attempt);
-  }
-
-  bool PlatformSupportsEula() {
-    return web_resource::EulaAcceptedNotifier::Create(local_state()) != nullptr;
-  }
-
-  // This helper method sets prefs::kLastFetchAttemptTime to the same value
-  // that's about to be passed into ShouldSessionRequestData(). This is what the
-  // scheduler will typically experience when refreshes are successful. Also
-  // clears out |tracking_oustanding_request_| through OnRequestError().
-  NativeRequestBehavior ShouldSessionRequestData(
-      bool has_content,
-      Time content_creation_date_time,
-      bool has_outstanding_request) {
-    ResetRefreshState(content_creation_date_time);
-    return scheduler()->ShouldSessionRequestData(
-        has_content, content_creation_date_time, has_outstanding_request);
-  }
-
-  TestingPrefServiceSimple* profile_prefs() { return &profile_prefs_; }
-  TestingPrefServiceSimple* local_state() { return &local_state_; }
-  base::SimpleTestClock* test_clock() { return &test_clock_; }
-  FeedSchedulerHost* scheduler() { return scheduler_.get(); }
-  int refresh_call_count() { return refresh_call_count_; }
-  const std::vector<TimeDelta>& schedule_wake_up_times() {
-    return schedule_wake_up_times_;
-  }
-  int cancel_wake_up_call_count() { return cancel_wake_up_call_count_; }
-  int fixed_timer_completion_count() { return fixed_timer_completion_count_; }
-
- private:
-  void TriggerRefresh() { refresh_call_count_++; }
-
-  void ScheduleWakeUp(TimeDelta threshold_ms) {
-    schedule_wake_up_times_.push_back(threshold_ms);
-  }
-
-  void CancelWakeUp() { cancel_wake_up_call_count_++; }
-
-  // Required to instantiate a net::test::MockNetworkChangeNotifier, because it
-  // uses ObserverListThreadSafe.
-  base::test::TaskEnvironment task_environment_;
-
-  TestingPrefServiceSimple profile_prefs_;
-  TestingPrefServiceSimple local_state_;
-  base::SimpleTestClock test_clock_;
-  std::unique_ptr<FeedSchedulerHost> scheduler_;
-  int refresh_call_count_ = 0;
-  std::vector<TimeDelta> schedule_wake_up_times_;
-  int cancel_wake_up_call_count_ = 0;
-  int fixed_timer_completion_count_ = 0;
-  base::WeakPtrFactory<FeedSchedulerHostTest> weak_factory_{this};
-};
-
-TEST_F(FeedSchedulerHostTest, GetTriggerThreshold) {
-  // Make sure that there is no missing configuration in the Cartesian product
-  // of states between TriggerType and UserClass.
-  std::vector<TriggerType> triggers = {TriggerType::kNtpShown,
-                                       TriggerType::kForegrounded,
-                                       TriggerType::kFixedTimer};
-
-  // Classification starts out as an active NTP user.
-  for (TriggerType trigger : triggers) {
-    EXPECT_FALSE(scheduler()->GetTriggerThreshold(trigger).is_zero());
-  }
-
-  ClassifyAsActiveSuggestionsConsumer();
-  for (TriggerType trigger : triggers) {
-    EXPECT_FALSE(scheduler()->GetTriggerThreshold(trigger).is_zero());
-  }
-
-  ClassifyAsRareNtpUser();
-  for (TriggerType trigger : triggers) {
-    EXPECT_FALSE(scheduler()->GetTriggerThreshold(trigger).is_zero());
-  }
-}
-
-TEST_F(FeedSchedulerHostTest, ShouldSessionRequestDataSimple) {
-  // For an kActiveNtpUser, refreshes on NTP_OPEN should be triggered after 4
-  // hours, and staleness should be at 24 hours. Each case tests a range of
-  // values.
-  Time no_refresh_large = test_clock()->Now() - TimeDelta::FromHours(3);
-  Time refresh_only_small = test_clock()->Now() - TimeDelta::FromHours(5);
-  Time refresh_only_large = test_clock()->Now() - TimeDelta::FromHours(23);
-  Time stale_small = test_clock()->Now() - TimeDelta::FromHours(25);
-
-  EXPECT_EQ(kRequestWithWait,
-            ShouldSessionRequestData(
-                /*has_content*/ false, /*content_creation_date_time*/ Time(),
-                /*has_outstanding_request*/ false));
-
-  EXPECT_EQ(kRequestWithContent,
-            ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ refresh_only_small,
-                /*has_outstanding_request*/ false));
-  EXPECT_EQ(kRequestWithContent,
-            ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ refresh_only_large,
-                /*has_outstanding_request*/ false));
-
-  EXPECT_EQ(kRequestWithTimeout, ShouldSessionRequestData(
-                                     /*has_content*/ true,
-                                     /*content_creation_date_time*/ stale_small,
-                                     /*has_outstanding_request*/ false));
-  EXPECT_EQ(kRequestWithTimeout,
-            ShouldSessionRequestData(
-                /*has_content*/ true, /*content_creation_date_time*/ Time(),
-                /*has_outstanding_request*/ false));
-
-  // |content_creation_date_time| should be ignored when |has_content| is false.
-  EXPECT_EQ(kNoRequestWithWait,
-            ShouldSessionRequestData(
-                /*has_content*/ false,
-                /*content_creation_date_time*/ test_clock()->Now(),
-                /*has_outstanding_request*/ true));
-  EXPECT_EQ(kNoRequestWithWait,
-            ShouldSessionRequestData(
-                /*has_content*/ false, /*content_creation_date_time*/ Time(),
-                /*has_outstanding_request*/ true));
-
-  EXPECT_EQ(kNoRequestWithContent,
-            ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ test_clock()->Now(),
-                /*has_outstanding_request*/ false));
-  EXPECT_EQ(kNoRequestWithContent,
-            ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ no_refresh_large,
-                /*has_outstanding_request*/ false));
-  EXPECT_EQ(kNoRequestWithContent,
-            ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ test_clock()->Now(),
-                /*has_outstanding_request*/ true));
-  EXPECT_EQ(kNoRequestWithContent,
-            ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ refresh_only_large,
-                /*has_outstanding_request*/ true));
-
-  EXPECT_EQ(
-      kNoRequestWithTimeout,
-      ShouldSessionRequestData(
-          /*has_content*/ true, /*content_creation_date_time*/ stale_small,
-          /*has_outstanding_request*/ true));
-  EXPECT_EQ(kNoRequestWithTimeout,
-            ShouldSessionRequestData(
-                /*has_content*/ true, /*content_creation_date_time*/ Time(),
-                /*has_outstanding_request*/ true));
-}
-
-TEST_F(FeedSchedulerHostTest, ShouldSessionRequestDataDivergentTimes) {
-  // If a request fails, then the |content_creation_date_time| and the value of
-  // prefs::kLastFetchAttemptTime may diverge. This is okay, and will typically
-  // mean that refreshes are not taken. Staleness should continue to track
-  // |content_creation_date_time|, but because staleness uses a bigger threshold
-  // than NTP_OPEN, this will not affect much.
-
-  // Like above case, the user is an kActiveNtpUser, staleness at 24 hours and
-  // refresh at 4.
-  Time refresh = test_clock()->Now() - TimeDelta::FromHours(5);
-  Time no_refresh = test_clock()->Now() - TimeDelta::FromHours(3);
-  Time stale = test_clock()->Now() - TimeDelta::FromHours(25);
-  Time not_stale = test_clock()->Now() - TimeDelta::FromHours(23);
-
-  ResetRefreshState(no_refresh);
-  EXPECT_EQ(kNoRequestWithContent, scheduler()->ShouldSessionRequestData(
-                                       /*has_content*/ true,
-                                       /*content_creation_date_time*/ stale,
-                                       /*has_outstanding_request*/ false));
-
-  ResetRefreshState(refresh);
-  EXPECT_EQ(kRequestWithContent, scheduler()->ShouldSessionRequestData(
-                                     /*has_content*/ true,
-                                     /*content_creation_date_time*/ not_stale,
-                                     /*has_outstanding_request*/ false));
-
-  ResetRefreshState(refresh);
-  EXPECT_EQ(kRequestWithTimeout, scheduler()->ShouldSessionRequestData(
-                                     /*has_content*/ true,
-                                     /*content_creation_date_time*/ stale,
-                                     /*has_outstanding_request*/ false));
-
-  // This shouldn't be possible, since last attempt is farther back than
-  // |content_creation_date_time| which updates on success, but verify scheduler
-  // handles it reasonably.
-  ResetRefreshState(Time());
-  EXPECT_EQ(kRequestWithContent,
-            scheduler()->ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ test_clock()->Now(),
-                /*has_outstanding_request*/ false));
-
-  // By changing the foregrounded threshold, staleness calculation changes.
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{"foregrounded_hours_active_ntp_user", "7.5"}});
-
-  ResetRefreshState(Time());
-  EXPECT_EQ(kRequestWithContent,
-            scheduler()->ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ test_clock()->Now() -
-                    TimeDelta::FromHours(7),
-                /*has_outstanding_request*/ false));
-
-  ResetRefreshState(Time());
-  EXPECT_EQ(kRequestWithTimeout,
-            scheduler()->ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ test_clock()->Now() -
-                    TimeDelta::FromHours(8),
-                /*has_outstanding_request*/ false));
-}
-
-TEST_F(FeedSchedulerHostTest, NtpShownActiveNtpUser) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{"ntp_shown_hours_active_ntp_user", "2.5"}});
-
-  EXPECT_EQ(kNoRequestWithContent,
-            ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ test_clock()->Now() -
-                    TimeDelta::FromHours(2),
-                /*has_outstanding_request*/ false));
-
-  EXPECT_EQ(kRequestWithContent,
-            ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ test_clock()->Now() -
-                    TimeDelta::FromHours(3),
-                /*has_outstanding_request*/ false));
-}
-
-TEST_F(FeedSchedulerHostTest, NtpShownRareNtpUser) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{"ntp_shown_hours_rare_ntp_user", "1.5"}});
-
-  ClassifyAsRareNtpUser();
-
-  EXPECT_EQ(kNoRequestWithContent,
-            ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ test_clock()->Now() -
-                    TimeDelta::FromHours(1),
-                /*has_outstanding_request*/ false));
-
-  // ShouldSessionRequestData() has the side effect of adding NTP_SHOWN event to
-  // the classifier, so push the timer out to keep classification.
-  ClassifyAsRareNtpUser();
-
-  EXPECT_EQ(kRequestWithContent,
-            ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ test_clock()->Now() -
-                    TimeDelta::FromHours(2),
-                /*has_outstanding_request*/ false));
-}
-
-TEST_F(FeedSchedulerHostTest, NtpShownActiveSuggestionsConsumer) {
-  ClassifyAsActiveSuggestionsConsumer();
-
-  EXPECT_EQ(kNoRequestWithContent,
-            ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ test_clock()->Now() -
-                    TimeDelta::FromMinutes(59),
-                /*has_outstanding_request*/ false));
-
-  EXPECT_EQ(kRequestWithContent,
-            ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ test_clock()->Now() -
-                    TimeDelta::FromMinutes(61),
-                /*has_outstanding_request*/ false));
-
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{"ntp_shown_hours_active_suggestions_consumer", "7.5"}});
-
-  EXPECT_EQ(kNoRequestWithContent,
-            ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ test_clock()->Now() -
-                    TimeDelta::FromHours(7),
-                /*has_outstanding_request*/ false));
-
-  EXPECT_EQ(kRequestWithContent,
-            ShouldSessionRequestData(
-                /*has_content*/ true,
-                /*content_creation_date_time*/ test_clock()->Now() -
-                    TimeDelta::FromHours(8),
-                /*has_outstanding_request*/ false));
-}
-
-TEST_F(FeedSchedulerHostTest, OnReceiveNewContentVerifyPref) {
-  EXPECT_EQ(Time(), profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
-  scheduler()->OnReceiveNewContent(Time());
-  EXPECT_EQ(Time(), profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
-  // Scheduler should prefer to use specified time over clock time.
-  EXPECT_NE(test_clock()->Now(),
-            profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
-}
-
-TEST_F(FeedSchedulerHostTest, OnRequestErrorVerifyPref) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{"only_set_last_refresh_attempt_on_success", "false"}});
-
-  EXPECT_EQ(Time(), profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
-  scheduler()->OnRequestError(0);
-  EXPECT_EQ(test_clock()->Now(),
-            profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
-}
-
-TEST_F(FeedSchedulerHostTest, OnRequestErrorVerifyRefreshTimeNotUpdated) {
-  EXPECT_EQ(Time(), profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
-  scheduler()->OnRequestError(0);
-  EXPECT_EQ(Time(), profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
-}
-
-TEST_F(FeedSchedulerHostTest, OnForegroundedActiveNtpUser) {
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  // Default is 24 hours.
-  test_clock()->Advance(TimeDelta::FromHours(23));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromHours(2));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(2, refresh_call_count());
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{"foregrounded_hours_active_ntp_user", "7.5"}});
-
-  test_clock()->Advance(TimeDelta::FromHours(7));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(2, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromHours(1));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(3, refresh_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, OnForegroundedRareNtpUser) {
-  ClassifyAsRareNtpUser();
-
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  // Default is 24 hours.
-  test_clock()->Advance(TimeDelta::FromHours(23));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromHours(2));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(2, refresh_call_count());
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{"foregrounded_hours_rare_ntp_user", "7.5"}});
-
-  test_clock()->Advance(TimeDelta::FromHours(7));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(2, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromHours(1));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(3, refresh_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, OnForegroundedActiveSuggestionsConsumer) {
-  ClassifyAsActiveSuggestionsConsumer();
-
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  // Default is 12 hours.
-  test_clock()->Advance(TimeDelta::FromHours(11));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromHours(2));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(2, refresh_call_count());
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{"foregrounded_hours_active_suggestions_consumer", "7.5"}});
-
-  test_clock()->Advance(TimeDelta::FromHours(7));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(2, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromHours(1));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(3, refresh_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, OnFixedTimerNullCallback) {
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(1, refresh_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, OnFixedTimerCompletionRunOnSuccess) {
-  scheduler()->OnFixedTimer(base::BindOnce(
-      &FeedSchedulerHostTest::FixedTimerCompletion, base::Unretained(this)));
-  EXPECT_EQ(1, refresh_call_count());
-
-  scheduler()->OnReceiveNewContent(Time());
-  EXPECT_EQ(1, fixed_timer_completion_count());
-}
-
-TEST_F(FeedSchedulerHostTest, OnFixedTimerCompletionRunOnFailure) {
-  scheduler()->OnFixedTimer(base::BindOnce(
-      &FeedSchedulerHostTest::FixedTimerCompletion, base::Unretained(this)));
-  EXPECT_EQ(1, refresh_call_count());
-
-  scheduler()->OnRequestError(0);
-  EXPECT_EQ(1, fixed_timer_completion_count());
-}
-
-TEST_F(FeedSchedulerHostTest, OnFixedTimerActiveNtpUser) {
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(1, refresh_call_count());
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  // Default is 48 hours.
-  test_clock()->Advance(TimeDelta::FromHours(47));
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(1, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromHours(2));
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(2, refresh_call_count());
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{"fixed_timer_hours_active_ntp_user", "7.5"}});
-
-  test_clock()->Advance(TimeDelta::FromHours(7));
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(2, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromHours(1));
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(3, refresh_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, OnFixedTimerActiveRareNtpUser) {
-  ClassifyAsRareNtpUser();
-
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(1, refresh_call_count());
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  // Default is 96 hours.
-  test_clock()->Advance(TimeDelta::FromHours(95));
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(1, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromHours(2));
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(2, refresh_call_count());
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{"fixed_timer_hours_rare_ntp_user", "7.5"}});
-  test_clock()->Advance(TimeDelta::FromHours(7));
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(2, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromHours(1));
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(3, refresh_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, OnFixedTimerWhileHidden) {
-  profile_prefs()->SetBoolean(prefs::kArticlesListVisible, false);
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(0, refresh_call_count());
-  EXPECT_EQ(1, cancel_wake_up_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, OnFixedTimerActiveSuggestionsConsumer) {
-  ClassifyAsActiveSuggestionsConsumer();
-
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(1, refresh_call_count());
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  // Default is 24 hours.
-  test_clock()->Advance(TimeDelta::FromHours(23));
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(1, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromHours(2));
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(2, refresh_call_count());
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{"fixed_timer_hours_active_suggestions_consumer", "7.5"}});
-
-  test_clock()->Advance(TimeDelta::FromHours(7));
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(2, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromHours(1));
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(3, refresh_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, OnFixedTimerThrottlingDisabled) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{kThrottleBackgroundFetches.name, "false"}});
-
-  // Every call to OnFixedTimer() should cause a fetch.
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(1, refresh_call_count());
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(2, refresh_call_count());
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-}
-
-TEST_F(FeedSchedulerHostTest, ScheduleFixedTimerWakeUpOnSuccess) {
-  // First wake up scheduled during Initialize().
-  EXPECT_EQ(1U, schedule_wake_up_times().size());
-  scheduler()->OnReceiveNewContent(Time());
-  EXPECT_EQ(2U, schedule_wake_up_times().size());
-
-  // Make another scheduler to initialize, make sure it doesn't schedule a
-  // wake up.
-  NewScheduler();
-  EXPECT_EQ(2U, schedule_wake_up_times().size());
-}
-
-TEST_F(FeedSchedulerHostTest, InitializedIntoHidden) {
-  // First wake up scheduled during Initialize().
-  EXPECT_EQ(1U, schedule_wake_up_times().size());
-
-  profile_prefs()->SetBoolean(prefs::kArticlesListVisible, false);
-  profile_prefs()->ClearPref(prefs::kBackgroundRefreshPeriod);
-  NewScheduler();
-  EXPECT_EQ(1U, schedule_wake_up_times().size());
-  EXPECT_EQ(0, cancel_wake_up_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, InitializedIntoHiddenWithPrevious) {
-  // First wake up scheduled during Initialize().
-  EXPECT_EQ(1U, schedule_wake_up_times().size());
-
-  profile_prefs()->SetBoolean(prefs::kArticlesListVisible, false);
-  profile_prefs()->SetTimeDelta(prefs::kBackgroundRefreshPeriod,
-                                base::TimeDelta::FromDays(12345));
-  NewScheduler();
-  EXPECT_EQ(1U, schedule_wake_up_times().size());
-  EXPECT_EQ(1, cancel_wake_up_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, InitializedIntoVisible) {
-  // First wake up scheduled during Initialize().
-  EXPECT_EQ(1U, schedule_wake_up_times().size());
-
-  profile_prefs()->SetBoolean(prefs::kArticlesListVisible, true);
-  profile_prefs()->ClearPref(prefs::kBackgroundRefreshPeriod);
-  NewScheduler();
-  EXPECT_EQ(2U, schedule_wake_up_times().size());
-  EXPECT_EQ(0, cancel_wake_up_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, InitializedIntoVisibleWithPrevious) {
-  // First wake up scheduled during Initialize().
-  EXPECT_EQ(1U, schedule_wake_up_times().size());
-
-  profile_prefs()->SetBoolean(prefs::kArticlesListVisible, true);
-  profile_prefs()->SetTimeDelta(prefs::kBackgroundRefreshPeriod,
-                                base::TimeDelta::FromDays(12345));
-  NewScheduler();
-  EXPECT_EQ(2U, schedule_wake_up_times().size());
-  EXPECT_EQ(0, cancel_wake_up_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, ShouldRefreshOffline) {
-  {
-    ForceDeviceOffline forceDeviceOffline;
-    scheduler()->OnForegrounded();
-    EXPECT_EQ(0, refresh_call_count());
-  }
-
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, EulaNotAccepted) {
-  if (PlatformSupportsEula()) {
-    local_state()->SetBoolean(::prefs::kEulaAccepted, false);
-    scheduler()->OnForegrounded();
-    EXPECT_EQ(0, refresh_call_count());
-
-    // The transition should kick off a refresh.
-    local_state()->SetBoolean(::prefs::kEulaAccepted, true);
-    EXPECT_EQ(1, refresh_call_count());
-
-    // And now it doesn't block normal triggers either.
-    ResetRefreshState(Time());
-    scheduler()->OnForegrounded();
-    EXPECT_EQ(2, refresh_call_count());
-  }
-}
-
-TEST_F(FeedSchedulerHostTest, DisableOneTrigger) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{kDisableTriggerTypes.name, "foregrounded"}});
-  NewScheduler();
-
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(0, refresh_call_count());
-
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(1, refresh_call_count());
-
-  EXPECT_EQ(kRequestWithWait,
-            ShouldSessionRequestData(
-                /*has_content*/ false, /*content_creation_date_time*/ Time(),
-                /*has_outstanding_request*/ false));
-}
-
-TEST_F(FeedSchedulerHostTest, DisableAllTriggers) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{kDisableTriggerTypes.name, "ntp_shown,foregrounded,fixed_timer"}});
-  NewScheduler();
-
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(0, refresh_call_count());
-
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(0, refresh_call_count());
-
-  EXPECT_EQ(kNoRequestWithWait,
-            ShouldSessionRequestData(
-                /*has_content*/ false, /*content_creation_date_time*/ Time(),
-                /*has_outstanding_request*/ false));
-}
-
-TEST_F(FeedSchedulerHostTest, DisableBogusTriggers) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{kDisableTriggerTypes.name, "foo,123,#$*,,"}});
-  NewScheduler();
-
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-
-  ResetRefreshState(Time());
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(2, refresh_call_count());
-
-  EXPECT_EQ(kRequestWithWait,
-            ShouldSessionRequestData(
-                /*has_content*/ false, /*content_creation_date_time*/ Time(),
-                /*has_outstanding_request*/ false));
-}
-
-TEST_F(FeedSchedulerHostTest, OnArticlesCleared) {
-  // OnForegrounded() does nothing because content is fresher than threshold.
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(0, refresh_call_count());
-
-  EXPECT_FALSE(scheduler()->OnArticlesCleared(/*suppress_refreshes*/ true));
-
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(0, refresh_call_count());
-
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(0, refresh_call_count());
-
-  EXPECT_EQ(kNoRequestWithWait,
-            ShouldSessionRequestData(
-                /*has_content*/ false, /*content_creation_date_time*/ Time(),
-                /*has_outstanding_request*/ false));
-
-  test_clock()->Advance(TimeDelta::FromMinutes(29));
-
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(0, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromMinutes(1));
-
-  // Normally this would still be within foreground threshold, but the
-  // OnHistoryCleared() cleared the last attempt time.
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, SuppressRefreshDuration) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{kSuppressRefreshDurationMinutes.name, "100"}});
-  EXPECT_FALSE(scheduler()->OnArticlesCleared(/*suppress_refreshes*/ true));
-
-  test_clock()->Advance(TimeDelta::FromMinutes(99));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(0, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromMinutes(1));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, OnArticlesClearedNoSuppress) {
-  EXPECT_TRUE(scheduler()->OnArticlesCleared(/*suppress_refreshes*/ false));
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  EXPECT_TRUE(scheduler()->OnArticlesCleared(/*suppress_refreshes*/ false));
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-
-  EXPECT_FALSE(scheduler()->OnArticlesCleared(/*suppress_refreshes*/ true));
-  EXPECT_FALSE(scheduler()->OnArticlesCleared(/*suppress_refreshes*/ false));
-
-  // OnArticlesCleared() should never trigger the refresh itself.
-  EXPECT_EQ(0, refresh_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, OnArticlesClearedIgnoresOutstanding) {
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-
-  // Now that there's an outstanding request, new triggers are not acted upon.
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-
-  // Clearing articles should disregard the outstanding request logic.
-  EXPECT_TRUE(scheduler()->OnArticlesCleared(/*suppress_refreshes*/ false));
-  // OnArticlesCleared() should have returned true instead of triggering a
-  // refresh directly.
-  EXPECT_EQ(1, refresh_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, OustandingRequest) {
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-
-  scheduler()->OnForegrounded();
-  scheduler()->OnFixedTimer(base::OnceClosure());
-  EXPECT_EQ(1, refresh_call_count());
-  EXPECT_EQ(kNoRequestWithWait,
-            scheduler()->ShouldSessionRequestData(
-                /*has_content*/ false, /*content_creation_date_time*/ Time(),
-                /*has_outstanding_request*/ true));
-
-  profile_prefs()->SetTime(prefs::kLastFetchAttemptTime, base::Time());
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-
-  test_clock()->Advance(
-      TimeDelta::FromSeconds(kTimeoutDurationSeconds.Get() - 1));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromSeconds(2));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(2, refresh_call_count());
-
-  // OnReceiveNewContent() should also clear tracked outstanding request, but
-  // similar to above, last attempted time is also set.
-  scheduler()->OnReceiveNewContent(test_clock()->Now());
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(2, refresh_call_count());
-
-  test_clock()->Advance(TimeDelta::FromDays(7));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(3, refresh_call_count());
-
-  // Although this shouldn't typically happen, OnReceiveNewContent() takes a
-  // time that could be wildly divergent from the scheduler's clock's now.
-  scheduler()->OnReceiveNewContent(test_clock()->Now() -
-                                   TimeDelta::FromDays(7));
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(4, refresh_call_count());
-}
-
-TEST_F(FeedSchedulerHostTest, IncorporatesExternalOustandingRequest) {
-  EXPECT_EQ(kNoRequestWithWait,
-            scheduler()->ShouldSessionRequestData(
-                /*has_content*/ false, /*content_creation_date_time*/ Time(),
-                /*has_outstanding_request*/ true));
-
-  // Normally this would trigger a refresh. In this case the scheduler will
-  // notice the ShouldSessionRequestData() call carries information that there
-  // is an outstanding request, which the scheduler should remember and then
-  // prevent the OnForegrounded() from requesting a refresh.
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(0, refresh_call_count());
-
-  EXPECT_EQ(kRequestWithWait,
-            scheduler()->ShouldSessionRequestData(
-                /*has_content*/ false, /*content_creation_date_time*/ Time(),
-                /*has_outstanding_request*/ false));
-}
-
-TEST_F(FeedSchedulerHostTest, IncorporatesExternalHasContent) {
-  Time now = test_clock()->Now();
-  EXPECT_EQ(Time(), profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
-
-  EXPECT_EQ(kNoRequestWithContent,
-            scheduler()->ShouldSessionRequestData(
-                /*has_content*/ true, now, /*has_outstanding_request*/ false));
-  EXPECT_EQ(now, profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
-
-  // Use has_outstanding_request of true to keep the scheduler from actually
-  // triggering the refresh. We want to track the change to its internal state.
-  EXPECT_EQ(kNoRequestWithWait, scheduler()->ShouldSessionRequestData(
-                                    /*has_content*/ false, base::Time(),
-                                    /*has_outstanding_request*/ true));
-  EXPECT_EQ(Time(), profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
-}
-
-TEST_F(FeedSchedulerHostTest, TimeUntilFirstMetrics) {
-  base::HistogramTester histogram_tester;
-  std::string ntpOpenedHistogram =
-      "NewTabPage.ContentSuggestions.TimeUntilFirstShownTrigger.ActiveNTPUser";
-  std::string forgroundedHistogram =
-      "NewTabPage.ContentSuggestions.TimeUntilFirstStartupTrigger"
-      ".ActiveNTPUser";
-  Time now = test_clock()->Now();
-  profile_prefs()->SetTime(prefs::kLastFetchAttemptTime, now);
-  EXPECT_EQ(0U, histogram_tester.GetAllSamples(ntpOpenedHistogram).size());
-  EXPECT_EQ(0U, histogram_tester.GetAllSamples(forgroundedHistogram).size());
-
-  scheduler()->ShouldSessionRequestData(
-      /*has_content*/ true, now, /*has_outstanding_request*/ false);
-  EXPECT_EQ(1, histogram_tester.GetBucketCount(ntpOpenedHistogram, 0));
-  EXPECT_EQ(0U, histogram_tester.GetAllSamples(forgroundedHistogram).size());
-
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, histogram_tester.GetBucketCount(ntpOpenedHistogram, 0));
-  EXPECT_EQ(1, histogram_tester.GetBucketCount(forgroundedHistogram, 0));
-
-  scheduler()->ShouldSessionRequestData(
-      /*has_content*/ true, now, /*has_outstanding_request*/ false);
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(1, histogram_tester.GetBucketCount(ntpOpenedHistogram, 0));
-  EXPECT_EQ(1, histogram_tester.GetBucketCount(forgroundedHistogram, 0));
-
-  // OnRequestError() should reset the flags, allowing these metrics to be
-  // reported again.
-  scheduler()->OnRequestError(0);
-
-  scheduler()->ShouldSessionRequestData(
-      /*has_content*/ true, now, /*has_outstanding_request*/ false);
-  scheduler()->OnForegrounded();
-  EXPECT_EQ(2, histogram_tester.GetBucketCount(ntpOpenedHistogram, 0));
-  EXPECT_EQ(2, histogram_tester.GetBucketCount(forgroundedHistogram, 0));
-}
-
-TEST_F(FeedSchedulerHostTest, RefreshThrottler) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      kInterestFeedContentSuggestions,
-      {{"quota_SuggestionFetcherActiveNTPUser", "3"}});
-  NewScheduler();
-
-  for (int i = 0; i < 5; i++) {
-    scheduler()->OnForegrounded();
-    ResetRefreshState(Time());
-    EXPECT_EQ(std::min(i + 1, 3), refresh_call_count());
-  }
-}
-
-TEST_F(FeedSchedulerHostTest, GetUserClassifierForDebuggingRareUser) {
-  ClassifyAsRareNtpUser();
-
-  EXPECT_EQ(UserClass::kRareSuggestionsViewer,
-            scheduler()->GetUserClassifierForDebugging()->GetUserClass());
-}
-
-TEST_F(FeedSchedulerHostTest, GetUserClassifierForDebuggingActiveConsumer) {
-  ClassifyAsActiveSuggestionsConsumer();
-
-  EXPECT_EQ(UserClass::kActiveSuggestionsConsumer,
-            scheduler()->GetUserClassifierForDebugging()->GetUserClass());
-}
-
-TEST_F(FeedSchedulerHostTest, GetSuppressRefreshesUntilForDebugging) {
-  EXPECT_TRUE(scheduler()->GetSuppressRefreshesUntilForDebugging().is_null());
-
-  scheduler()->OnArticlesCleared(/*suppress_refreshes*/ true);
-
-  EXPECT_EQ(test_clock()->Now() + TimeDelta::FromMinutes(30),
-            scheduler()->GetSuppressRefreshesUntilForDebugging());
-}
-
-TEST_F(FeedSchedulerHostTest, GetLastFetchStatusForDebugging) {
-  EXPECT_EQ(0, scheduler()->GetLastFetchStatusForDebugging());
-
-  scheduler()->OnReceiveNewContent(Time());
-
-  EXPECT_EQ(200, scheduler()->GetLastFetchStatusForDebugging());
-
-  scheduler()->OnRequestError(-100);
-
-  EXPECT_EQ(-100, scheduler()->GetLastFetchStatusForDebugging());
-}
-
-TEST_F(FeedSchedulerHostTest, GetLastFetchTriggerTypeForDebugging) {
-  scheduler()->OnForegrounded();
-
-  EXPECT_EQ(TriggerType::kForegrounded,
-            *scheduler()->GetLastFetchTriggerTypeForDebugging());
-
-  scheduler()->OnArticlesCleared(/*suppress_refreshes*/ false);
-
-  EXPECT_EQ(TriggerType::kNtpShown,
-            *scheduler()->GetLastFetchTriggerTypeForDebugging());
-
-  ClassifyAsActiveSuggestionsConsumer();  // Fixed timer at 48 hours.
-  test_clock()->Advance(TimeDelta::FromHours(49));
-  scheduler()->OnFixedTimer(base::OnceClosure());
-
-  EXPECT_EQ(TriggerType::kFixedTimer,
-            *scheduler()->GetLastFetchTriggerTypeForDebugging());
-}
-
-}  // namespace feed
diff --git a/components/feed/core/proto/BUILD.gn b/components/feed/core/proto/BUILD.gn
index 3221e2c..c433364 100644
--- a/components/feed/core/proto/BUILD.gn
+++ b/components/feed/core/proto/BUILD.gn
@@ -8,14 +8,6 @@
   import("//build/config/android/rules.gni")
 }
 
-proto_library("proto") {
-  proto_in_dir = "../../../../"
-  sources = [
-    "content_storage.proto",
-    "journal_storage.proto",
-  ]
-}
-
 proto_library("proto_v2") {
   proto_in_dir = "../../../../"
   sources = [
@@ -60,66 +52,6 @@
 }
 
 if (is_android) {
-  proto_java_library("proto_java") {
-    proto_path = "../../../../"
-    sources = [
-      "libraries/api/internal/stream_data.proto",
-      "libraries/basicstream/internal/stream_saved_instance_state.proto",
-      "libraries/sharedstream/scroll_state.proto",
-      "libraries/sharedstream/ui_refresh_reason.proto",
-      "libraries/testing/ui_context_for_test.proto",
-      "ui/action/feed_action_payload.proto",
-      "ui/action/piet_extensions.proto",
-      "ui/action/ui_feed_action.proto",
-      "ui/piet/accessibility.proto",
-      "ui/piet/actions.proto",
-      "ui/piet/binding_refs.proto",
-      "ui/piet/elements.proto",
-      "ui/piet/errors.proto",
-      "ui/piet/form_fields.proto",
-      "ui/piet/gradients.proto",
-      "ui/piet/images.proto",
-      "ui/piet/log_data.proto",
-      "ui/piet/media_queries.proto",
-      "ui/piet/piet.proto",
-      "ui/piet/piet_android_support.proto",
-      "ui/piet/rounded_corners.proto",
-      "ui/piet/shadows.proto",
-      "ui/piet/styles.proto",
-      "ui/piet/text.proto",
-      "ui/stream/stream_offline_extension.proto",
-      "ui/stream/stream_structure.proto",
-      "ui/stream/stream_swipe_extension.proto",
-      "wire/action_payload.proto",
-      "wire/action_payload_for_test.proto",
-      "wire/action_request.proto",
-      "wire/action_type.proto",
-      "wire/capability.proto",
-      "wire/chrome_fulfillment_info.proto",
-      "wire/client_info.proto",
-      "wire/consistency_token.proto",
-      "wire/content_id.proto",
-      "wire/data_operation.proto",
-      "wire/display_info.proto",
-      "wire/feature.proto",
-      "wire/feed_action.proto",
-      "wire/feed_action_query_data.proto",
-      "wire/feed_action_request.proto",
-      "wire/feed_action_response.proto",
-      "wire/feed_query.proto",
-      "wire/feed_request.proto",
-      "wire/feed_response.proto",
-      "wire/mockserver/mock_server.proto",
-      "wire/payload_metadata.proto",
-      "wire/piet_shared_state_item.proto",
-      "wire/request.proto",
-      "wire/response.proto",
-      "wire/semantic_properties.proto",
-      "wire/token.proto",
-      "wire/version.proto",
-    ]
-  }
-
   proto_java_library("proto_java_v2") {
     proto_path = "../../../../"
     sources = [ "v2/ui.proto" ]
diff --git a/components/feed/core/proto/content_storage.proto b/components/feed/core/proto/content_storage.proto
deleted file mode 100644
index 750a15c..0000000
--- a/components/feed/core/proto/content_storage.proto
+++ /dev/null
@@ -1,18 +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.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package feed;
-
-// Used for storing content data in content storage.
-message ContentStorageProto {
-  // Original key for data.
-  optional string key = 1;
-
-  // Content data.
-  optional bytes content_data = 2;
-}
diff --git a/components/feed/core/proto/journal_storage.proto b/components/feed/core/proto/journal_storage.proto
deleted file mode 100644
index 9c5331a..0000000
--- a/components/feed/core/proto/journal_storage.proto
+++ /dev/null
@@ -1,18 +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.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package feed;
-
-// Used for storing journal data in journal storage.
-message JournalStorageProto {
-  // Original key for data.
-  optional string key = 1;
-
-  // Journal data.
-  repeated bytes journal_data = 2;
-}
diff --git a/components/feed/core/proto/libraries/api/internal/stream_data.proto b/components/feed/core/proto/libraries/api/internal/stream_data.proto
deleted file mode 100644
index f5e0b26..0000000
--- a/components/feed/core/proto/libraries/api/internal/stream_data.proto
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.libraries.api.internal;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/ui/stream/stream_structure.proto";
-import "components/feed/core/proto/wire/action_payload.proto";
-import "components/feed/core/proto/wire/consistency_token.proto";
-import "components/feed/core/proto/wire/piet_shared_state_item.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.libraries.api.internal";
-option java_outer_classname = "StreamDataProto";
-
-// A StreamFeature represents a node within the tree forming the Stream.  The
-// stream contains structure and content at multiple levels.  This
-// structure is represented as a tree of features.  These features include
-// Clusters, Hero Cards, Carousels, Piet Content, etc.  Nodes internal to the
-// tree may have both content and children.
-message StreamFeature {
-  // The content id of this feature.
-  optional string content_id = 1;
-
-  // The parent feature if defined.  Most features will have a parent, the root
-  // feature is the exception.
-  optional string parent_id = 2;
-
-  // Define the payloads for the various types of nodes present in the tree.
-  oneof feature_payload {
-    // Stream structure which defines how a stream will work and look.
-    components.feed.core.proto.ui.stream.Stream stream = 4;
-
-    // Card stream structure which defines how a card will work and look.
-    components.feed.core.proto.ui.stream.Card card = 5;
-
-    // Content stream structure.  Describes information which will be rendered
-    // on screen.
-    components.feed.core.proto.ui.stream.Content content = 6;
-
-    // Cluster stream structure which defines a logical grouping of Content and
-    // Cards.
-    components.feed.core.proto.ui.stream.Cluster cluster = 7;
-
-    // Legacy content
-    StreamLegacyPayload legacy_content = 8;
-  }
-}
-
-message StreamToken {
-  // The content id of this feature.
-  optional string content_id = 1;
-
-  // The parent feature if defined.  Most features will have a parent, the root
-  // feature is the exception.
-  optional string parent_id = 2;
-
-  // The Token
-  optional bytes next_page_token = 3;
-}
-
-// Represents the UI state held in a mutation initiated by the UI.
-message UiContext {
-  extensions 1 to max;
-}
-
-// This represents a shared state item.
-message StreamSharedState {
-  optional string content_id = 1;
-  oneof share_state {
-    // A Piet shared state item.
-    feedwire1.PietSharedStateItem piet_shared_state_item = 2;
-  }
-}
-
-// This is the structure of the stream.  It is defined through the parent/child
-// relationship and an operation.  This message will be journaled.  Reading
-// the journal from start to end will fully define the structure of the stream.
-message StreamStructure {
-  // The defined set of DataOperations.
-  enum Operation {
-    UNKNOWN = 0;
-
-    // All content in this Stream has been removed. See data_operation.proto.
-    CLEAR_ALL = 1;
-
-    // The item represented by content_id has been appended as a child to
-    // parent_content_id. See data_operation.proto.
-    UPDATE_OR_APPEND = 2;
-
-    // The item represented by content_id has been removed. See
-    // data_operation.proto.
-    REMOVE = 3;
-
-    // Indicates that the item represented by content_id is required by this
-    // Stream and should not be deleted.
-    REQUIRED_CONTENT = 4;
-  }
-  optional Operation operation = 1;
-
-  // ContentId of the content that is appended, removed, or required.
-  optional string content_id = 2;
-
-  // ContentId of the parent of content_id that is being appended.
-  optional string parent_content_id = 3;
-
-  extensions 10000 to max;
-}
-
-// The internal version of a DataOperation.
-message StreamDataOperation {
-  // Defines the structure of the stream
-  optional StreamStructure stream_structure = 1;
-
-  // The payload (content) of the DataOperation.
-  optional StreamPayload stream_payload = 2;
-}
-
-// This defines the content payload associated with a StreamDataOperation.
-// Payload is what is stored in the Content portion of the persisted storage
-// layer.  Each of the items defined here are persisted using the
-// StreamContentId (String) as the key to the payload.  By default, the
-// StreamContentId is formed by concatenation of the ContentId Table, followed
-// by ContentDomain, then Id.  In addition, for content requiring prefix based
-// queries, the Store will prefix the StreamContentId.
-message StreamPayload {
-  oneof payload {
-    // This contains a feature within the tree.  These are stored based upon
-    // the server defined StreamContentId (created by the ProtocolAdapter).
-    StreamFeature stream_feature = 3;
-
-    // This contains a shared state, such as the Piet shared state.  The
-    // Feed store prepends a prefix (see
-    // FeedStoreConstants.SHARED_STATE_PREFIX) so these can be retrieved
-    // through a prefix query.
-    StreamSharedState stream_shared_state = 4;
-
-    // Continuation Token for a parent.  These are stored in the same way other
-    // the stream_feature are stored.  They are treated the same as other
-    // feature content when persisted.
-    StreamToken stream_token = 5;
-
-    // This is stored as a single content record.  It contains information about
-    // each known session including $HEAD.  This is a list of the individual
-    // sessions which are currently active.  This has a StreamContentId defined
-    // by the SessionManager (see FeedSessionManager.STREAM_SESSION_CONTENT_ID).
-    StreamSessions stream_sessions = 6;
-
-    // The semantic data associated with a Feature.  These are stored as content
-    // with a prefix added by the Store (see
-    // FeedStoreConstants.SEMANTIC_PROPERTIES_PREFIX) allowing prefix queries.
-    bytes semantic_data = 7;
-
-    // The consistency token used to ensure that we are recording actions to
-    // the same server store.
-    feedwire1.ConsistencyToken consistency_token = 9;
-  }
-  reserved 8;
-}
-
-// Allow the payload to contain Legacy Stream content.
-// TODO: Should this be removed, this was designed for legacy content
-// which is currently not supported anywhere.
-message StreamLegacyPayload {
-  // String identifying the type of the legacy content.  This values is
-  // opaque to the infrastructure.
-  optional string type = 1;
-
-  // The data making up the Legacy payload. This value is opaque to the
-  // infrastructure.
-  optional bytes data = 2;
-}
-
-// List of all the sessions.
-message StreamSessions {
-  // Represents the current sessions
-  repeated StreamSession stream_session = 1;
-}
-
-// Persistence for a Session. This allows the UI to create a ModelProvider
-// from an existing session.
-message StreamSession {
-  // Unique identifier for the session.
-  optional string session_id = 1;
-
-  // The milliseconds of either the time this session was created or the last
-  // time content was added to the HEAD session.
-  optional int64 legacy_time_millis = 2;
-
-  // Metadata for the session. If this field is absent then fallback to
-  // #legacy_time_millis.
-  optional SessionMetadata session_metadata = 3;
-}
-
-// Metadata that describes a session.
-message SessionMetadata {
-  // The time in milliseconds that the most recent content was added to this
-  // session.
-  optional int64 last_added_time_millis = 1;
-
-  // The time in milliseconds that this session was created.
-  optional int64 creation_time_millis = 2;
-
-  // The schema used to create this session.
-  optional int32 schema_version = 3;
-}
-
-message StreamLocalAction {
-  // See LocalActionMutation.ActionType
-  optional int32 action = 1;
-
-  optional string feature_content_id = 2;
-
-  // When the action was recorded
-  optional int64 timestamp_seconds = 3;
-}
-
-message StreamUploadableAction {
-  optional string feature_content_id = 2;
-
-  // The number of time this action was attempted to be recorded
-  optional int32 upload_attempts = 3;
-
-  // When the action was recorded
-  optional int64 timestamp_seconds = 4;
-
-  optional feedwire1.ActionPayload payload = 6;
-
-  // The duration for the action in milliseconds. In case of view actions this
-  // is the duration for which the content is considered "viewed".
-  optional int64 duration_ms = 7;
-
-  reserved 1, 5;  // deprecated fields
-}
-
-// An extension to the BasicLoggingMetadata which is used to hide the notion of
-// the client needing this data in other places.
-message ClientBasicLoggingMetadata {
-  extend components.feed.core.proto.ui.stream.BasicLoggingMetadata {
-    optional ClientBasicLoggingMetadata client_basic_logging_metadata =
-        206218502;
-  }
-
-  // Time server filled out content.
-  optional int64 availability_time_seconds = 1;
-}
diff --git a/components/feed/core/proto/libraries/basicstream/internal/stream_saved_instance_state.proto b/components/feed/core/proto/libraries/basicstream/internal/stream_saved_instance_state.proto
deleted file mode 100644
index c3b37a0e..0000000
--- a/components/feed/core/proto/libraries/basicstream/internal/stream_saved_instance_state.proto
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.libraries.basicstream.internal;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/libraries/sharedstream/scroll_state.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.libraries.basicstream.internal";
-option java_outer_classname = "StreamSavedInstanceStateProto";
-option cc_enable_arenas = true;
-
-// Object representing the state of the Stream.
-message StreamSavedInstanceState {
-  optional string session_id = 1;
-  optional components.feed.core.proto.libraries.sharedstream.ScrollState
-      scroll_state = 2;
-}
diff --git a/components/feed/core/proto/libraries/sharedstream/scroll_state.proto b/components/feed/core/proto/libraries/sharedstream/scroll_state.proto
deleted file mode 100644
index 4230e87..0000000
--- a/components/feed/core/proto/libraries/sharedstream/scroll_state.proto
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.libraries.sharedstream;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.libraries.sharedstream";
-option java_outer_classname = "ScrollStateProto";
-option cc_enable_arenas = true;
-
-// Object representing scroll state in the Stream.
-message ScrollState {
-  optional int32 position = 1;
-  optional int32 offset = 2;
-}
diff --git a/components/feed/core/proto/libraries/sharedstream/ui_refresh_reason.proto b/components/feed/core/proto/libraries/sharedstream/ui_refresh_reason.proto
deleted file mode 100644
index 3787579a..0000000
--- a/components/feed/core/proto/libraries/sharedstream/ui_refresh_reason.proto
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.libraries.sharedstream;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/libraries/api/internal/stream_data.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.libraries.sharedstream";
-option java_outer_classname = "UiRefreshReasonProto";
-
-// UI only reason that a refresh occurred.
-message UiRefreshReason {
-  extend components.feed.core.proto.libraries.api.internal.UiContext {
-    optional UiRefreshReason ui_refresh_reason_extension = 237804819;
-  }
-
-  enum Reason {
-    UNKNOWN = 0;
-    ZERO_STATE = 1;
-  }
-
-  optional Reason reason = 1;
-}
diff --git a/components/feed/core/proto/libraries/testing/ui_context_for_test.proto b/components/feed/core/proto/libraries/testing/ui_context_for_test.proto
deleted file mode 100644
index 5b549ed2..0000000
--- a/components/feed/core/proto/libraries/testing/ui_context_for_test.proto
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.libraries.testing;
-
-import "components/feed/core/proto/libraries/api/internal/stream_data.proto";
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.libraries.testing";
-option java_outer_classname = "UiContextForTestProto";
-
-// Extension on UI context for testing.
-message UiContextForTest {
-  extend components.feed.core.proto.libraries.api.internal.UiContext {
-    optional UiContextForTest ui_context_for_test = 237897197;
-  }
-
-  // Allows distinguishing between different UiContext's
-  optional int32 value = 1;
-}
diff --git a/components/feed/core/proto/ui/action/feed_action_payload.proto b/components/feed/core/proto/ui/action/feed_action_payload.proto
deleted file mode 100644
index 610801f..0000000
--- a/components/feed/core/proto/ui/action/feed_action_payload.proto
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.action;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.action";
-option java_outer_classname = "FeedActionPayloadProto";
-
-// Specification of an action to be taken within the feed. This is a place
-// holder for host specific actions.
-message FeedActionPayload {
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
diff --git a/components/feed/core/proto/ui/action/piet_extensions.proto b/components/feed/core/proto/ui/action/piet_extensions.proto
deleted file mode 100644
index b52a6641..0000000
--- a/components/feed/core/proto/ui/action/piet_extensions.proto
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-import "components/feed/core/proto/ui/piet/actions.proto";
-import "components/feed/core/proto/ui/action/feed_action_payload.proto";
-
-package components.feed.core.proto.ui.action;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.action";
-option java_outer_classname = "PietExtensionsProto";
-
-// This is an extension message which adds the FeedActionPayload as an extension
-// to the Piet Action.
-message PietFeedActionPayload {
-  extend components.feed.core.proto.ui.piet.Action {
-    optional PietFeedActionPayload piet_feed_action_payload_extension =
-        182220593;
-  }
-
-  optional FeedActionPayload feed_action_payload = 1;
-}
diff --git a/components/feed/core/proto/ui/action/ui_feed_action.proto b/components/feed/core/proto/ui/action/ui_feed_action.proto
deleted file mode 100644
index ad714f0..0000000
--- a/components/feed/core/proto/ui/action/ui_feed_action.proto
+++ /dev/null
@@ -1,239 +0,0 @@
-/// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.action;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/ui/action/feed_action_payload.proto";
-import "components/feed/core/proto/wire/action_payload.proto";
-import "components/feed/core/proto/wire/content_id.proto";
-import "components/feed/core/proto/wire/data_operation.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.ui.action";
-option java_outer_classname = "FeedActionProto";
-
-// Specification of an action to be taken within the feed.
-message FeedAction {
-  extend FeedActionPayload {
-    optional FeedAction feed_action_extension = 192348469;
-  }
-
-  // The metadata, which is used by the client to update the client UI in
-  // real-time.
-  optional FeedActionMetadata metadata = 1;
-
-  reserved 2;  // deprecated fields
-}
-
-// Metadata needed by the host to handle the action.
-// Next Id: 11
-message FeedActionMetadata {
-  // The type of action, used by the host to perform any custom logic needed for
-  // a specific type of action.
-  // Next Id: 21
-  enum Type {
-    UNKNOWN = 0;
-    OPEN_URL = 1;
-    OPEN_URL_INCOGNITO = 2;
-    OPEN_URL_NEW_WINDOW = 3;
-    OPEN_CONTEXT_MENU = 4;
-    // Dismiss retained on the client and sent with requests. This information
-    // should not be persisted to server-side storage as this experience is
-    // intended for signed-out users or ones with WAA disabled.
-    DISMISS_LOCAL = 5;
-    // Dismiss logged on the server for signed-in users with WAA enabled.
-    DISMISS = 11;
-    // Note that the data required to download content is not on the action, but
-    // rather the content. This is intentionally done to avoid sending multiple
-    // copies of the same data, which could potentially be multiple long
-    // strings.
-    DOWNLOAD = 6;
-    OPEN_URL_NEW_TAB = 7;
-    LEARN_MORE = 8;
-    VIEW_ELEMENT = 12;
-    HIDE_ELEMENT = 13;
-    SHOW_TOOLTIP = 14;
-    NOT_INTERESTED_IN = 15;
-    SEE_SUGGESTED_SITES = 16;
-    SEND_FEEDBACK = 17;
-    MANAGE_INTERESTS = 18;
-    REPORT_VIEW = 19;
-    BLOCK_CONTENT = 20;
-    reserved 9, 10;  // Deprecated
-  }
-  optional Type type = 1;
-
-  oneof data {
-    // The data needed by the client to open the url for any OPEN_URL action
-    // including OPEN_URL_INCOGNITO and OPEN_URL_NEW_WINDOW.
-    OpenUrlData open_url_data = 2;
-
-    // The data needed by the Stream to open a context menu.
-    OpenContextMenuData open_context_menu_data = 3;
-
-    // The data needed by the Stream to perform a dismiss.
-    DismissData dismiss_data = 4;
-
-    // The data needed by the Stream to handle the not interested action.
-    NotInterestedInData not_interested_in_data = 6;
-
-    // The data needed by the Stream to render a tooltip.
-    TooltipData tooltip_data = 8;
-
-    // The data needed by the Stream to report a view action.
-    ViewReportData view_report_data = 10;
-
-    // The data needed by the stream to block content.
-    BlockContentData block_content_data = 11;
-  }
-  // The type of element this action is bounded on.
-  // Next Id: 5
-  enum ElementType {
-    UNKNOWN_ELEMENT_TYPE = 0;
-    CARD_LARGE_IMAGE = 1;
-    CARD_SMALL_IMAGE = 2;
-    INTEREST_HEADER = 3;
-    TOOLTIP = 4;
-  }
-  // Used by the host to perform Basic logging for views and clicks.
-  // This should be an ElementType.getNumber() but since proto lite doesn't
-  // handle when it gets added to, we need it to be an int instead of an enum
-  optional int32 element_type_value = 9;
-
-  reserved 5, 7;
-}
-
-// Data needed by the host to handle an OPEN_URL action.
-message OpenUrlData {
-  // The Url to open.
-  optional string url = 1;
-  // If populated, the client will attempt to recod all pending actions before
-  // opening the url. Once this finishes, the client will attach to the url its
-  //  latest frequency token as the value of this query param.
-  optional string consistency_token_query_param_name = 2;
-
-  // The content ID that was interacted with to cause a URL open.
-  optional feedwire1.ContentId content_id = 3;
-  // Roundtripped server data on a per-action level.
-  optional feedwire1.ActionPayload payload = 4;
-}
-
-// Data needed by Stream to open a context menu.
-message OpenContextMenuData {
-  repeated LabelledFeedActionData context_menu_data = 1;
-}
-
-// Data needed by Stream to perform a dismiss.
-message DismissData {
-  // The ContentId needed by the server to suppress reshowing the dismissed
-  // content. This will usually be the ContentId of the card which holds the
-  // content, not the ContentId of the content itself.
-  optional feedwire1.ContentId content_id = 1;
-
-  // The DataOperations which are needed to actually perform the dismiss on the
-  // client. This is typically a singleton list of a remove operation on the
-  // Cluster that the content belongs to.
-  repeated feedwire1.DataOperation data_operations = 2;
-
-  // Data used by the client to show a confirmation message with option to undo.
-  // This confirmation and undo option will only appear if the UndoAction is
-  // present and the client can handle this capability.
-  optional UndoAction undo_action = 3;
-  // Roundtripped server data on a per-action level.
-  optional feedwire1.ActionPayload payload = 4;
-}
-
-// Data needed by the client to handle the not interested action.
-message NotInterestedInData {
-  // Data used by the client to show a confirmation message with option to undo.
-  // This confirmation and undo option will only appear if the UndoAction is
-  // present and the client can handle this capability.
-  optional UndoAction undo_action = 1;
-  // The data needed by Stream to preform the dismiss.
-  repeated feedwire1.DataOperation data_operations = 2;
-  // Roundtripped server data on a per-action level.
-  optional feedwire1.ActionPayload payload = 3;
-  enum RecordedInterestType {
-    UNKNOWN_INTEREST_TYPE = 0;
-    TOPIC = 1;
-    SOURCE = 2;
-  }
-  // The type of NotInterested Action that was performed.
-  // This should be an RecordedInterestType.getNumber() but since proto lite
-  // doesn't handle when it gets added to, we need it to be an int instead of
-  // an enum
-  optional int32 interest_type_value = 5;
-
-  reserved 4;
-}
-
-message BlockContentData {
-  // The data needed by Stream to (locally) dismiss the content.
-  repeated feedwire1.DataOperation data_operations = 1;
-  // Roundtripped server data on a per-action level.
-  // Identifies to the server the content that must be blocked.
-  optional feedwire1.ActionPayload payload = 2;
-}
-
-// Data used by the client to show a confirmation message with an action to
-// reverse it.
-message UndoAction {
-  // The string shown to the user that confirms the action was just taken.
-  optional string confirmation_label = 1;
-  // The string that labels that option to reverse the action. Defaults to
-  // "Undo" if not sent.
-  optional string undo_label = 2;
-}
-
-// The data needed by the Stream to render a tooltip.
-message TooltipData {
-  optional string label = 1;
-  optional string accessibility_label = 2;
-  enum FeatureName {
-    // No tooltip will render if the FeatureName is UNKNOWN.
-    UNKNOWN = 0;
-    CARD_MENU = 1;
-  }
-  optional FeatureName feature_name = 3;
-  // The infromation for where to offset the arrow from the referenced view.
-  optional Insets insets = 4;
-}
-
-// The information for where to offset the tooltip arrow from the referenced
-// view. The host will decide if the tooltip is above or below the view and this
-// inset data changes the y coordinate of the tooltip arrow. For example, if top
-// inset is 5 and the tooltip is shown above the view, then the tooltip will
-// have its point of the arrow horizontally centered 5 dp below the top of the
-// referenced view. If bottom inset is 5 and the tooltip is shown below the
-// view, then the tooltip will have its point of the arrow horizontally centered
-// 5 dp above the bottom of the referenced view. If no inset is set then the
-// tooltip will show either directly above/below the referenced view.
-message Insets {
-  optional int32 top = 1;
-  optional int32 bottom = 2;
-}
-
-// Data used by the client to report a view action on content.
-message ViewReportData {
-  enum Visibility {
-    UNKNOWN = 0;
-    SHOW = 1;
-    HIDE = 2;
-  }
-  // Whether we're showing or hiding the content.
-  optional Visibility visibility = 1;
-  // The content ID of the view that needs to be reported.
-  optional feedwire1.ContentId content_id = 2;
-  // Roundtripped server data on a per-action level.
-  optional feedwire1.ActionPayload payload = 3;
-}
-
-// FeedActionMetadata with a label to show in a context menu.
-message LabelledFeedActionData {
-  optional string label = 1;
-  optional FeedActionPayload feed_action_payload = 2;
-}
diff --git a/components/feed/core/proto/ui/piet/accessibility.proto b/components/feed/core/proto/ui/piet/accessibility.proto
deleted file mode 100644
index b73760b..0000000
--- a/components/feed/core/proto/ui/piet/accessibility.proto
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-import "components/feed/core/proto/ui/piet/binding_refs.proto";
-import "components/feed/core/proto/ui/piet/text.proto";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "AccessibilityProto";
-option cc_enable_arenas = true;
-
-// Defines accessibility related attributes for Piet elements.
-message Accessibility {
-  oneof description_data {
-    // A string that may be spoken by the system. (TalkBack on Android,
-    // VoiceOver on iOS, browser on Web)
-    ParameterizedText description = 1;
-
-    // In case this is coming from a template.
-    ParameterizedTextBindingRef description_binding = 3;
-  }
-
-  // Roles that this UI element plays in the UI. These annotations will be used
-  // by the accessibility framework for applying role-specific treatments.
-  repeated AccessibilityRole roles = 2;
-
-  oneof accessibility_id_data {
-    // A string that uniquely identifies this UI element. This is used by
-    // automated UI testing frameworks. The identifier's scope is determined by
-    // the test framework, which typically allows searching by identifier across
-    // an element type or within a container.
-
-    // NOTE: parameters are not supported for accessibility_id. Only the 'text'
-    // field should be used to specify the identifier.
-    ParameterizedText accessibility_id = 4;
-
-    // ID coming from a template.
-    ParameterizedTextBindingRef accessibility_id_binding = 5;
-  }
-
-  oneof context_data {
-    // A string that may be spoken by the system that describes the result of an
-    // action. For example, "Opens the article." This provides additional
-    // context over the description.
-
-    // NOTE: Only supported by iOS and maps to accessibilityHint on an
-    // accessible element.
-    ParameterizedText context = 6;
-
-    // In case this is coming from a template.
-    ParameterizedTextBindingRef context_binding = 7;
-  }
-}
-
-// Semantic roles played by a UI element related to accessibility.
-enum AccessibilityRole {
-  // No special role. The default value, maps to 0.
-  ACCESSIBILITY_ROLE_UNSPECIFIED = 0;
-
-  // Indicates that the UI element is a list containing other elements.
-  LIST = 1;
-
-  // Indicates that the UI element is a header for a section.
-  HEADER = 2;
-}
diff --git a/components/feed/core/proto/ui/piet/actions.proto b/components/feed/core/proto/ui/piet/actions.proto
deleted file mode 100644
index c10cb1a..0000000
--- a/components/feed/core/proto/ui/piet/actions.proto
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "ActionsProto";
-option cc_enable_arenas = true;
-
-// Multiple actions can be associated with every UI element. To keep the set of
-// Actions consistent among multiple UI elements, they’re all defined in a
-// dedicated message.
-message Actions {
-  // Action to be executed when the user taps (clicks) on a UI element.
-  optional Action on_click_action = 1;
-
-  // Action to be executed when the user long-clicks (taps & holds) a UI
-  // element.
-  optional Action on_long_click_action = 2;
-
-  // These actions will fire once a view with visibility below the threshold
-  // goes above the threshold
-  //
-  // Ex. A view action at 0.5 will trigger when a view that was less than half
-  // visible becomes half visible, and not trigger again until the view has
-  // become less than half visible (reset) and then becomes more than half
-  // visible.
-  repeated VisibilityAction on_view_actions = 3;
-
-  // These actions will fire once a view with visibility above the threshold
-  // goes below the threshold.
-  //
-  // Ex. A hide action at 0.5 will trigger when a view that was half visible
-  // becomes less than half visible, and not trigger again until the view has
-  // become more than half visible (reset) and then becomes less than half
-  // visible.
-  repeated VisibilityAction on_hide_actions = 4;
-
-  // Action to be executed when the user force touches on a UI element. May not
-  // be supported on all platforms.
-  //
-  // Ex. Preview the matching detail UI for a UI element with this action.
-  optional Action on_force_touch_action = 5;
-}
-
-// Defines an Action which can be raised when the user clicks a UI element. The
-// action can be defined for the full slice or something inside a slice such as
-// a suggestion chip. All Actions should be defined as extensions, don’t define
-// fields in this proto directly.
-message Action {
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// Actions that trigger based on the proportion of the parent Element that is
-// visible.
-message VisibilityAction {
-  // Proportion of the view that should be visible for this action to trigger
-  // [0.0 to 1.0]
-  // Defaults to 1.0 to make this an "on full view" action.
-  optional float proportion_visible = 1 [default = 1.0];
-
-  // Action to trigger at the given visibility threshold
-  optional Action action = 2;
-}
diff --git a/components/feed/core/proto/ui/piet/binding_refs.proto b/components/feed/core/proto/ui/piet/binding_refs.proto
deleted file mode 100644
index 5d47314..0000000
--- a/components/feed/core/proto/ui/piet/binding_refs.proto
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "BindingRefsProto";
-option cc_enable_arenas = true;
-
-// A BindingRef (binding reference) identifies a BindingValue of a specific type
-// in a Binding. This is used when defining Templates, to bind to content.
-//
-// It is acceptable for multiple BindingRefs with the same binding_id to exist
-// within the same binding context, e.g. if the same text were to be used more
-// than once in the same Frame.
-//
-// It is NOT acceptable for multiple BindingValues in the same binding context
-// to have the same binding_id; ERR_DUPLICATE_BINDING_VALUE will be raised.
-//
-// Some types of BindingRefs may be optional. If an optional binding is not
-// provided, the element containing that binding will be omitted from the
-// resulting view hierarchy. If a required binding is not provided,
-// ERR_MISSING_BINDING_VALUE is raised.
-
-message CustomBindingRef {
-  // The unique ID for this binding. See comments at the top of the file.
-  optional string binding_id = 1;
-
-  // Indicates whether this binding reference is optional.
-  optional bool is_optional = 2;
-}
-
-message ModuleBindingRef {
-  // The unique ID for this binding. See comments at the top of the file.
-  optional string binding_id = 1;
-
-  // Indicates whether this binding reference is optional.
-  optional bool is_optional = 2;
-}
-
-message ParameterizedTextBindingRef {
-  // The unique ID for this binding. See comments at the top of the file.
-  optional string binding_id = 1;
-
-  // Indicates whether this binding reference is optional.
-  optional bool is_optional = 2;
-}
-
-message ChunkedTextBindingRef {
-  // The unique ID for this binding. See comments at the top of the file.
-  optional string binding_id = 1;
-
-  // Indicates whether this binding reference is optional.
-  optional bool is_optional = 2;
-}
-
-message ImageBindingRef {
-  // The unique ID for this binding. See comments at the top of the file.
-  optional string binding_id = 1;
-
-  // Indicates whether this binding reference is optional.
-  optional bool is_optional = 2;
-}
-
-// GridCellWidthBindings are always optional. If not provided, the default is
-// [width.weight = 1].
-message GridCellWidthBindingRef {
-  // The unique ID for this binding. See comments at the top of the file.
-  optional string binding_id = 1;
-}
-
-message ElementBindingRef {
-  // The unique ID for this binding. See comments at the top of the file.
-  optional string binding_id = 1;
-
-  // Indicates whether this binding reference is optional.
-  optional bool is_optional = 2;
-}
-
-message TemplateBindingRef {
-  // The unique ID for this binding. See comments at the top of the file.
-  optional string binding_id = 1;
-
-  // Indicates whether this binding reference is optional.
-  optional bool is_optional = 2;
-}
-
-// Actions binding references are always optional.
-message ActionsBindingRef {
-  // The unique ID for this binding. See comments at the top of the file.
-  optional string binding_id = 1;
-}
-
-// Style binding references are always optional.
-message StyleBindingRef {
-  // The unique ID for this binding. See comments at the top of the file.
-  optional string binding_id = 1;
-}
-
-// Visibility bindings are always optional.
-message VisibilityBindingRef {
-  // The unique ID for this binding. See comments at the top of the file.
-  optional string binding_id = 1;
-}
-
-// LogData binding references are always optional.
-message LogDataBindingRef {
-  // The unique ID for this binding. See comments at the top of the file.
-  optional string binding_id = 1;
-}
diff --git a/components/feed/core/proto/ui/piet/elements.proto b/components/feed/core/proto/ui/piet/elements.proto
deleted file mode 100644
index 1688823..0000000
--- a/components/feed/core/proto/ui/piet/elements.proto
+++ /dev/null
@@ -1,720 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/ui/piet/accessibility.proto";
-import "components/feed/core/proto/ui/piet/actions.proto";
-import "components/feed/core/proto/ui/piet/binding_refs.proto";
-import "components/feed/core/proto/ui/piet/images.proto";
-import "components/feed/core/proto/ui/piet/log_data.proto";
-import "components/feed/core/proto/ui/piet/styles.proto";
-import "components/feed/core/proto/ui/piet/text.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "ElementsProto";
-option cc_enable_arenas = true;
-
-// Content is a placeholder which contains a layout Element, or something which
-// resolves to a layout Element.
-message Content {
-  // The payload of this content.
-  oneof content_type {
-    // Element, specified inline.
-    Element element = 1;
-
-    // A binding to look up an element.
-    // May have a performance penalty on some platforms.
-    ElementBindingRef bound_element = 2;
-
-    // An instance of a Template, represented by a TemplateInvocation.
-    //
-    // If the referenced template has several binding contexts, an Element
-    // instance will be created for each one.
-    //
-    // This may happen in one of two cases:
-    //
-    // The Content appears inside an ElementList, or repeated Element
-    // --------------------------------------------------------------
-    //
-    // For example:
-    // In case there's an ElementList with the following Contents:
-    //
-    //  +----------------------------+
-    //  |         Template_1         |
-    //  +----------------------------+
-    //  |   Template_2 with binding  |
-    //  |     values [ a , b , c ]   |
-    //  +----------------------------+
-    //  |         Template_3         |
-    //  +----------------------------+
-    //
-    // After the bindings are resolved, it will become:
-    //  +----------------------------+
-    //  |         Template_1         |
-    //  +----------------------------+
-    //  | Template_2 {with data "a"} |
-    //  +----------------------------+
-    //  | Template_2 {with data "b"} |
-    //  +----------------------------+
-    //  | Template_2 {with data "c"} |
-    //  +----------------------------+
-    //  |         Template_3         |
-    //  +----------------------------+
-    //
-    // The Content appears in a GridCell
-    // ---------------------------------
-    // A GridCell is created for each invocation of the template. The created
-    // GridCells will be added to the GridRow containing this GridCell. The
-    // width of the created GridCells is duplicated from the GridCell containing
-    // this Content.
-    //
-    // For example:
-    // In case there's a GridRow with the following GridCells:
-    //  +----------+------------------------+----------+
-    //  |   Cell   | Cell with Content with |   Cell   |
-    //  |          |  Template 2 with data  |          |
-    //  |     1    |    bindings {a,b,c }   |    3     |
-    //  +----------+------------------------+----------+
-    //
-    // After the bindings are resolved, it will become:
-    //  +----------+------------+------------+------------+---------+
-    //  |   Cell   | Template 2 | Template 2 | Template 2 |   Cell  |
-    //  |     1    | {data "a"} | {data "b"} | {data "c"} |     3   |
-    //  +----------+------------+------------+------------+---------+
-    //
-    //
-    // IMPORTANT:
-    // This feature may not be supported on all platforms; see [INTERNAL LINK].
-    TemplateInvocation template_invocation = 3;
-
-    // See comment on template field; this looks up the template based on the
-    // ID in the bindings.
-    TemplateBindingRef template_binding = 4;
-  }
-}
-
-// Indicates element's visibility, and the option to bind visibility state that
-// overrides the default value.
-// This message should be used to bind external values for controlling display
-// of parts of the UI.
-message VisibilityState {
-  // Binding of values.
-  optional VisibilityBindingRef overriding_bound_visibility = 1;
-
-  // The default visibility.
-  optional Visibility default_visibility = 2 [default = VISIBLE];
-}
-
-// Element is the "superclass" of all container and content types, holding all
-// shared parameters (styles, actions, etc).
-//
-// Element size expands to fill its container, unless the content is taller than
-// the container, and the container height is not specified explicitly. In that
-// case, the Element and the container both get the height of the content.
-// Next Id: 27
-message Element {
-  // The specific content represented by this Element.
-  oneof elements {
-    /*** CONTENT ELEMENTS ***/
-
-    // An image container
-    ImageElement image_element = 3;
-
-    // A simple text line
-    TextElement text_element = 2;
-
-    /*** END CONTENT ELEMENTS ***/
-
-    /*** CONTAINER ELEMENTS ***/
-
-    // A horizontal layout of multiple items.
-    GridRow grid_row = 5;
-
-    // A vertical layout of multiple items.
-    ElementList element_list = 6;
-
-    // Multiple items stacked on top of each other (overlay).
-    ElementStack element_stack = 24;
-
-    /*** END CONTAINER ELEMENTS ***/
-
-    /*** NON-NATIVE ELEMENTS ***/
-
-    // A custom view that Piet knows nothing about. Servers can use this message
-    // to populate a custom proto extension, which Piet passes along to the Host
-    // for rendering. The Host is expected to be able to interpret and render
-    // this view and return to Piet, which then simply places it within the
-    // current view hierarchy at the proper position.
-    // If a renderer cannot be found for a particular CustomElement in a client
-    // implementation, Piet raises a ERR_CUSTOM_ELEMENT_RENDERER_MISSING & warns
-    // the user at runtime. A black/grey box is displayed in place of the
-    // CustomElement, but the rest of the Frame is still rendered. It is
-    // possible for CustomElements to invoke Piet for rendering sub-views, but
-    // only top-level Piet Frame protos can be embedded this way. (In other
-    // words, do not try to embed Piet Elements directly inside a
-    // CustomElement).
-    CustomElement custom_element = 1;
-
-    // A view that is implemented by a secondary (non-Core) Piet Module. Not all
-    // Piet Elements are useful to all clients/servers, so only the basic ones
-    // are included in Piet Core. Common shareable elements can be implemented
-    // in secondary Piet Modules, which are optional modules that can be
-    // included in or excluded from Piet-based apps on an as-needed basis.
-    // ModuleElements work similar to CustomElements, with the only difference
-    // being that CustomElements are rendered by non-Piet code, while
-    // ModuleElements are rendered by secondary Piet Modules.
-    ModuleElement module_element = 21;
-
-    /*** END NON-NATIVE ELEMENTS ***/
-  }
-
-  // Every UI element can have accessibility-related fields.
-  optional Accessibility accessibility = 11;
-
-  // Defines Actions that may be associated with the content of the Element.
-  // The server is responsible for ensuring that the size of this content is
-  // large enough to present a clear click target for the user.
-  oneof actions_data {
-    // Inlined actions.
-    Actions actions = 14;
-
-    // Actions coming from a template.
-    ActionsBindingRef actions_binding = 15;
-  }
-
-  // A list of Contents to be overlaid on top of this Element.
-  // This field is repeated to allow multiple overlay layers with different
-  // gravity settings. The index of the item inside the repeated field
-  // determines the order in which views will be laid out. Later items will
-  // appear above the earlier ones.
-  // Deprecated: To make an overlay on an Element, wrap the Element in an
-  // ElementStack.
-  repeated Content overlays = 22 [deprecated = true];
-
-  // Horizontal gravity of this element's content within the parent container
-  // Deprecated: use gravity_horizontal on Style instead
-  optional GravityHorizontal gravity_horizontal = 12 [deprecated = true];
-
-  // Vertical gravity of this element's content within the parent container
-  // Deprecated: use gravity_vertical on Style instead
-  optional GravityVertical gravity_vertical = 18 [deprecated = true];
-
-  // Defines the overflow behavior for contents that are wider than this
-  // Element.
-  // Contents can be wider than the container Element in two scenarios:
-  //  1. An element has defined width in its style, and the width is larger
-  //     than the size of the Element.
-  //  2. The element is a GridRow, where the width sum of cells with defined dp
-  //     width is larger than the containing Element.
-  //
-  // In all other cases, contents cannot be wider than the container
-  // Element.
-  //
-  // IMPORTANT: This might not be supported in all implementations of Piet, due
-  //   to implementation/product decisions (for example, horizontal scrolling in
-  //   a swipable card might be disabled).
-  optional OverflowBehavior horizontal_overflow = 16
-      [default = OVERFLOW_HIDDEN];
-
-  // Styles to apply to this Element. If any style_ids cannot be found,
-  // ERR_MISSING_STYLES is raised.
-  optional StyleIdsStack style_references = 17;
-
-  // Visibility state that can be controlled with binding.
-  optional VisibilityState visibility_state = 23;
-  oneof log_data_value {
-    LogData log_data = 25;
-    LogDataBindingRef log_data_ref = 26;
-  }
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-
-  // Deprecated field IDs.
-  reserved 4, 7, 8, 13, 19, 20, 9, 10;
-}
-
-/*
- *** CONTENT ELEMENTS ***
- */
-// An Image which is displayed as a horizontal slice within a parent container.
-message ImageElement {
-  // Content for this ImageElement.
-  oneof content {
-    // The image to be displayed.
-    Image image = 3;
-
-    // The binding to the BindingValue for an Image. It is an error if the
-    // BindingValue doesn't define an Image.
-    ImageBindingRef image_binding = 2;
-  }
-
-  // Styles applied to this ImageElement. If any style_ids cannot be found,
-  // ERR_MISSING_STYLES is raised.
-  // Deprecated: use the StyleIdsStack on Element instead.
-  optional StyleIdsStack style_references = 1 [deprecated = true];
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// A simple text line (Android TextView, iOS UILabel, or HTML <div>).
-message TextElement {
-  // Content for this TextElement.
-  oneof content {
-    // ChunkedText to be displayed. Styles referenced inside the text chunks
-    // should override the style references in this TextElement.
-    ChunkedText chunked_text = 5;
-
-    // The binding to the BindingValue for a ChunkedText. It is an error if the
-    // BindingValue doesn't define a ChunkedText. Styles referenced inside the
-    // ChunkedText should override the style references in this TextElement.
-    ChunkedTextBindingRef chunked_text_binding = 4;
-
-    // The text to display.
-    ParameterizedText parameterized_text = 3;
-
-    // The binding to the BindingValue for a ParameterizedText. It is an error
-    // if the BindingValue doesn't define a ParameterizedText.
-    ParameterizedTextBindingRef parameterized_text_binding = 2;
-  }
-
-  // Styles applied to this TextElement. If any style_ids cannot be found,
-  // ERR_MISSING_STYLES is raised.
-  // Deprecated: use the StyleIdsStack on Element instead.
-  optional StyleIdsStack style_references = 1 [deprecated = true];
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-/*
- *** END CONTENT ELEMENTS ***
- */
-
-/*
- *** CONTAINER ELEMENTS ***
- */
-// A horizontally-oriented left-to-right list of Contents with specified widths.
-// Without explicit dimensions or constraints by the parent, this container is
-// as tall as its tallest child, and as wide as the sum of its cells.
-message GridRow {
-  // A list of cells defining the content of the grid.
-  repeated GridCell cells = 2;
-
-  // Styles applied to this GridRow.
-  // Deprecated: use the StyleIdsStack on Element instead.
-  optional StyleIdsStack style_references = 1 [deprecated = true];
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// The Grid Cell represents the contents within a GridRow.
-// The content within each cell is always the same width as the cell (minus
-// margins) - width on the content's style is ignored. If the cell has extra
-// vertical space (the GridRow is taller than the content), the content can
-// float vertically with gravity.
-// If the child's style does not specify a height, it defaults to matching the
-// height of the GridRow.
-// Next Id: 8
-message GridCell {
-  // The content of the GridCell.
-  optional Content content = 7;
-
-  // The width of this cell, either fixed width or relative width.
-  // If width is not specified, behaves as if weight = 1 by default.
-  oneof cell_width {
-    // Specified inline.
-    GridCellWidth width = 4;
-
-    // Width specified in bindings.
-    GridCellWidthBindingRef width_binding = 5;
-  }
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-
-  // Deprecated field IDs.
-  reserved 1, 2, 3, 6;
-}
-
-// The width of a GridCell.
-message GridCellWidth {
-  // An enum that indicates the width of the GridCell, in reference to its
-  // content. The width of the GridCell will be the width of the contained
-  // element.
-  enum ContentWidth {
-    // Do not use. If used, this will raise
-    // ERR_CONTENT_WIDTH_GRID_CELL_WITH_INVALID_CONTENT at runtime.
-    INVALID_CONTENT_WIDTH = 0;
-
-    // This cell will expand just enough to fit its content.
-    CONTENT_WIDTH = 1;
-  }
-
-  // The width specification. One of these fields must be populated, otherwise
-  // ERR_GRID_CELL_WIDTH_WITHOUT_CONTENTS warning will be raised.
-  oneof width_spec {
-    // The width of the cell expressed as DP.
-    int32 dp = 1;
-
-    // The width of the cell expressed as a weight. This weight is relative to
-    // the remaining width, after DP and Content were allocated.
-    // For more information, see [INTERNAL LINK].
-    int32 weight = 2;
-
-    // The width of the content, limited to Content of TextElement or
-    // ImageElement. In case a different content is given to the cell,
-    // ERR_CONTENT_WIDTH_GRID_CELL_WITH_INVALID_CONTENT is raised.
-    ContentWidth content_width = 3;
-  }
-
-  // Whether this cell will shrink if the GridRow is too small for its contents.
-  // This cell will always be less than or equal to the defined width.
-  // If there are multiple collapsible cells in a row, they will shrink in order
-  // from last to first (ex. the last cell will be width 0 before the cell
-  // before it begins to shrink).
-  // This is ignored if weight is set.
-  optional bool is_collapsible = 4;
-}
-
-// A vertically-oriented top-to-bottom list of Contents.
-// Without explicit dimensions or constraints by the parent, this container is
-// as wide as its largest child, and as tall as the sum of its children.
-// Cell height is always the size of the child Element, and vertical gravity is
-// ignored. Cell width defaults to the width of the ElementList.
-message ElementList {
-  // The list items to be laid out vertically.
-  repeated Content contents = 6;
-
-  // Styles applied to this ElementList.
-  // Deprecated: use the StyleIdsStack on Element instead.
-  optional StyleIdsStack style_references = 3 [deprecated = true];
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-
-  // Deprecated field IDs.
-  reserved 1, 2, 4, 5;
-}
-
-// A stacked (overlaid) bottom-to-top list of Contents.
-// Children can be smaller than the ElementStack and float around within it
-// subject to their horizontal and vertical gravity.
-// Without explicit dimensions or constraints by the parent, this container is
-// as large as its largest child.
-// By default, children are the size of their content.
-message ElementStack {
-  // The items to be stacked from bottom to top.
-  repeated Content contents = 1;
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-/*
- *** END CONTAINER ELEMENTS ***
- */
-
-/*
-*** NON-NATIVE ELEMENTS
-*/
-// A custom view that Piet knows nothing about. Servers can use this message to
-// populate a custom proto extension, which Piet passes along to the Host for
-// rendering. The Host is expected to be able to interpret and render this view
-// and return to Piet, which then simply places it within the current view
-// hierarchy at the proper position. If no renderer for this CustomElement can
-// be found at runtime, ERR_CUSTOM_ELEMENT_RENDERER_MISSING is raised.
-message CustomElement {
-  // Content for this CustomElement.
-  oneof content {
-    // The data to be displayed.
-    CustomElementData custom_element_data = 3;
-
-    // The binding to the BindingValue for a CustomElement.
-    CustomBindingRef custom_binding = 2;
-  }
-
-  // Styles applied to this CustomElement. If any style_ids cannot be found,
-  // ERR_MISSING_STYLES is raised.
-  // Deprecated: use the StyleIdsStack on Element instead.
-  optional StyleIdsStack style_references = 1 [deprecated = true];
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// Data to be displayed in a CustomElement. Clients using Piet should add
-// extensions to this proto to pass their custom data to CustomElements.
-message CustomElementData {
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// A view that is implemented by a secondary (non-Core) Piet Module. Not all
-// Piet Elements are useful to all clients/servers, so only the basic ones are
-// included in Piet Core. Common shareable elements can be implemented in
-// secondary Piet Modules, which are optional modules that can be included in or
-// excluded from Piet-based apps on an as-needed basis.
-// ModuleElements work similar to CustomElements, with the only difference being
-// that CustomElements are rendered by non-Piet code, while ModuleElements are
-// rendered by secondary Piet Modules.
-message ModuleElement {
-  // Content for this ModuleElement.
-  oneof content {
-    // The data to be displayed.
-    ModuleElementData module_element_data = 3;
-
-    // The binding to the BindingValue for a ModuleElement.
-    ModuleBindingRef module_binding = 2;
-  }
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// Data to be displayed in a ModuleElement. Piet Modules should add extensions
-// to this proto to pass their custom data to ModuleElements.
-message ModuleElementData {
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-/*
- *** END NON-NATIVE ELEMENTS ***
- */
-
-/*
- *** TEMPLATES AND BINDINGS ***
- */
-
-// A template can be used to instantiate a single instance, or a list of
-// instances at once: each of these is termed a TemplateInvocation. One instance
-// is created for each `binding_context` provided.
-//
-// The types of objects instantiated by the template are determined by the
-// element that holds the invocation. For example, an invocation from an
-// ElementList will create one or more cells in that list. Invocation from a
-// GridCell will create one or more GridCells.
-message TemplateInvocation {
-  // The Template to be used.
-  optional string template_id = 1;
-
-  // To isolate Templates, we define the BindingContext used by the template
-  // within the invocation. When a TemplateInvocation is processed, we will
-  // create a template instance for each BindingContext defined (if none is
-  // defined, none will be created).
-  repeated BindingContext binding_contexts = 2;
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// A single binding context, such as a whole Frame, or a single row in a grid.
-// Binding IDs must be unique; if two or more BindingValues with the same
-// `binding_id` are found within the same binding context,
-// ERR_DUPLICATE_BINDING_VALUE is raised.
-message BindingContext {
-  // The set of all bindings for a Template.
-  repeated BindingValue binding_values = 1;
-}
-
-// A BindingValue is a name/value pair which provides a value to be substituted
-// wherever the specified `binding_id` is defined in the Template.
-// Next Id: 18
-message BindingValue {
-  // The name of the binding within the Template where this BindingValue should
-  // be substituted. Must be unique within a binding context.
-  optional string binding_id = 1;
-
-  // The possible values for the BindingValue.
-  oneof values {
-    // Actions that may be bound at runtime.
-    Actions actions = 10;
-
-    // Binding value for visibility, which changes the VisibilityState of an
-    // Element. This value can override the default visibility value set on an
-    // Element.
-    Visibility visibility = 13 [default = VISIBLE];
-
-    // Use an already existing bound value in a transcluded template.
-    // This should be used to pass parameters between templates.
-    //
-    // For example:
-    // Let's assume we have a template that shows a text with styling:
-    //
-    // template {
-    //   id: "StyledText"
-    //   ...
-    //   element {
-    //     text_element {
-    //       parameterized_text_binding { binding_id: "StyledTextContent" }
-    //     }
-    //   }
-    //   ...
-    // }
-    //
-    // And we want to create a template that shows the styled text overlayed
-    // over an image:
-    //
-    // template {
-    //   id: "ImageWithText"
-    //   ...
-    //   element {
-    //     image_element {
-    //       image_binding {
-    //         binding_id: "TopLevelImage"
-    //       }
-    //     }
-    //     overlays {
-    //       template_invocation {
-    //         id: 'StyledText'
-    //         binding_contexts {
-    //           binding_values {
-    //             binding_id: "StyledTextContent"
-    //             binding_id_from_transcluding_template: "TopLevelText"
-    //           }
-    //         }
-    //       }
-    //     }
-    //   }
-    //   ...
-    // }
-    //
-    // The invocation of the template will then be:
-    //
-    // frame {
-    //   template_invocation {
-    //     id: "ImageWithText"
-    //     binding_contexts {
-    //       binding_values {
-    //         binding_id: "TopLevelText"
-    //         ...
-    //       }
-    //       binding_values {
-    //         binding_id: "TopLevelImage"
-    //         ...
-    //       }
-    //     }
-    //   }
-    // }
-    string binding_id_from_transcluding_template = 16;
-
-    // Style that is bound to an element, and overrides the styles defined by
-    // the element. The Style attributes that can be bound are only a subset
-    // of all possible Styles.
-    BoundStyle bound_style = 11;
-
-    // Width of a cell.
-    GridCellWidth cell_width = 9;
-
-    // ChunkedText to be used in a TextElement.
-    ChunkedText chunked_text = 4;
-
-    // Data to be displayed in a CustomElement. Clients using Piet should add
-    // extensions to this proto to pass their custom data.
-    CustomElementData custom_element_data = 2;
-
-    // An Element, to allow binding of generic chunks of layout.
-    // May have a performance penalty on some platforms.
-    Element element = 15;
-
-    // Image to be used in an ImageElement.
-    Image image = 5;
-
-    // ParameterizedText to be used in a TextElement.
-    ParameterizedText parameterized_text = 3;
-
-    // Binding value for a TemplateInvocation.
-    TemplateInvocation template_invocation = 8;
-
-    // A Base64-encoded serialized ClickTrackingCGI proto that identifies the
-    // logged Visual Element corresponding to a bound Piet Template.
-    string ved = 7;
-
-    LogData log_data = 17;
-  }
-
-  // Data to provide a host in order for host to fulfill a binding for Piet.
-  // When Piet binds a value it will first look to see if there is a
-  // HostBindingData set. If there is one, then Piet asks the host for a new
-  // BindingValue to use. The host will be given this BindingValue from which it
-  // can use HostBindingData to determine how to create a new BindingValue. This
-  // allows the host to selectively alter the server specified BindingValue. If
-  // the BindingValue returned by the host has HostBindingData set it will be
-  // ignored. If there is no binding provided in the oneof then an error will be
-  // raised.  See [INTERNAL LINK] for a list of possible errors that could be
-  // raised.
-  //
-  // Piet will use the binding reference and ask the host for a specific
-  // binding based on that reference type. As an example, Piet will request the
-  // host for an Image when ImageBindingRef is specified.
-  //
-  // An example usage of a host binding would be to check if something has
-  // been stored on the device and signaling with icons whether content is
-  // there or not.  The server can specify where this element will appear and
-  // the host can determine what to show or even if the element should be
-  // shown.
-  optional HostBindingData host_binding_data = 14;
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-
-  // Deprecated field IDs.
-  reserved 6;
-}
-
-// Data which is accompanied with BindingValue in order for a host to determine
-// the information it needs to provide the correct BindingValue to fulfill a
-// binding reference.  Client using Piet should add extensions to this proto to
-// pass their host specific data needed to fulfill the binding reference.
-message HostBindingData {
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-/*
- *** END TEMPLATES AND BINDINGS ***
- */
-
-/*
- *** ENUMS ***
- */
-// Controls the visibility of a UI element.
-enum Visibility {
-  VISIBILITY_UNSPECIFIED = 0;
-
-  // By default, every element is visible. If set to VISIBLE, at least one of
-  // the elements in the `values` oneof MUST be present, otherwise an error is
-  // raised.
-  VISIBLE = 1;
-
-  // The UI element corresponding to this binding is included in
-  // layout computation, but its visible UI is hidden.
-  INVISIBLE = 2;
-
-  // The UI element corresponding to this binding is completely
-  // removed from the view hierarchy. It is not used to compute layout. This
-  // is the equivalent of Android’s visibility:GONE.
-  GONE = 3;
-}
-
-// Defines the behavior for elements that don't fit in the view
-enum OverflowBehavior {
-  // Unspecified value, will default to OVERFLOW_HIDDEN.
-  OVERFLOW_UNSPECIFIED = 0;
-
-  // All elements outside the boundaries of the view are hidden.
-  OVERFLOW_HIDDEN = 1;
-
-  // A scroll behavior is added to show elements that are outside of the view.
-  OVERFLOW_SCROLL = 2;
-}
-/*
- *** END ENUMS ***
- */
diff --git a/components/feed/core/proto/ui/piet/errors.proto b/components/feed/core/proto/ui/piet/errors.proto
deleted file mode 100644
index 54e2818..0000000
--- a/components/feed/core/proto/ui/piet/errors.proto
+++ /dev/null
@@ -1,422 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-// import "google/protobuf/descriptor.proto";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "ErrorsProto";
-option cc_enable_arenas = true;
-
-// Each error in Piet is described by a unique error code. Error levels indicate
-// how the issue should be handled by server implementations and client
-// implementations.
-//
-// Error handling in Piet is roughly modeled after Postel’s Law:
-// “Be conservative in what you send, be liberal in what you accept”.
-// https://en.wikipedia.org/wiki/Robustness_principle
-//
-// Servers will inform feature authors of problems in built protos as early and
-// as loudly as possible, to ensure that we are conservative in sending protos
-// to the client.
-//
-// Clients attempt their best in rendering protos, even if there are potential
-// errors as long as there is a reasonable way to recover with work-arounds and
-// defaults.
-//
-// Thus, two error levels are specified for each error code, allowing us to
-// treat the same issue with different treatments on the server and client.
-
-/* extend google.protobuf.EnumValueOptions {
-  // Determines how to treat a particular error code during server processing.
-  optional ErrorLevel server_error = 180986144
-      [default = UNKNOWN];  // Tag from CL number.
-
-  // Determines how to treat a particular error code during client processing.
-  optional ErrorLevel client_error = 180952597
-      [default = UNKNOWN];  // Tag from CL number.
-} */
-
-// clang-format off
-// +----------+--------------------------+--------------------------+------------------------+
-// | Level    | Server                   | Client Prod Build        | Client Dev Build       |
-// +----------+--------------------------+--------------------------+------------------------+
-// | UNKNOWN  | Should never be raised   | Should never be raised   | Should never be raised |
-// +----------+--------------------------+--------------------------+------------------------+
-// | FATAL    | Log to Console           | Log to Console           | Crash                  |
-// |          | Fail when building proto | Log to Clearcut          |                        |
-// |          | Fail tests               | Drop all affected Frames |                        |
-// +----------+--------------------------+--------------------------+------------------------+
-// | ERROR    | Log to Console           | Log to Console           | Crash                  |
-// |          | Refuse to build proto    | Log to Clearcut          |                        |
-// |          | Fail tests               | Drop current Frame       |                        |
-// |          |                          | Proceed with next Frame  |                        |
-// +----------+--------------------------+--------------------------+------------------------+
-// | WARNING  | Log to Console           | Log to Console           | Log to Console         |
-// |          | OK to build proto        | Log to Clearcut          | Annotate Frame         |
-// |          | Warn during tests        |                          |                        |
-// +----------+--------------------------+--------------------------+------------------------+
-// | NOTICE   | Log to Console           | Nothing                  | Log to Console         |
-// |          | OK to build proto        |                          |                        |
-// +----------+--------------------------+--------------------------+------------------------+
-// | QUIET    | Nothing                  | Nothing                  | Nothing                |
-// +----------+--------------------------+--------------------------+------------------------+
-// clang-format on
-//
-// A note on client build types:
-// * Dev: Only those builds used by developers who can see the source and have
-//   the power/ability to fix things should be considered Dev builds.
-//   E.g. AGSA built from source, or Chromium.
-// * Prod: Most builds should be classified as prod, for the purposes of the
-//   table above.
-//   E.g. AGSA Stable, AGSA Alpha, AGSA Beta, Chrome Stable, Chrome Beta, Chrome
-//   Dev, Chrome Canary.
-enum ErrorLevel {
-  // UNKNOWN is used when it is not possible to detect a particular kind of
-  // error, but is needed as a proto option. E.g. detecting a poor frame rate is
-  // not possible server-side, so `server_error = UNKNOWN` is appropriate for
-  // `ERR_POOR_FRAME_RATE`.
-  UNKNOWN = 0;
-
-  // Piet has encountered an invalid PietSharedState, which affects all Frames
-  // in the current response. Piet has determined that it cannot proceed with
-  // rendering any Frame at all.
-  FATAL = 1;
-
-  // Piet has encountered an invalid Frame, so it cannot proceed with rendering
-  // that particular Frame. It is possible to render all the other Frames in the
-  // current response.
-  ERROR = 2;
-
-  // Piet can use reasonably sane strategies to recover, but feature authors
-  // need to be aware that something unexpected happened.
-  WARNING = 3;
-
-  // Debug purposes only; notices are not visible in production builds.
-  NOTICE = 4;
-
-  // No reporting is performed; this class of errors can be silently ignored
-  // with no negative consequences. This level exists because certain types of
-  // errors can be treated as loud on the server but quiet on the client.
-  QUIET = 5;
-}
-
-enum ErrorCode {
-  // Not to be used for real errors; this only exists because proto enums must
-  // have a default value.
-  ERR_UNSPECIFIED = 0 /* [
-    // Die if ever used.
-    (server_error) = FATAL,
-    // Die if ever used.
-    (client_error) = FATAL
-  ] */;
-
-  // ---------------------------------------------------------------------------
-  // Missing or Duplicate IDs.
-  // Fields start at ID 1.
-  // ---------------------------------------------------------------------------
-
-  // When the client tries to reference a SharedState that is not found, the
-  // Frame cannot be rendered, and likely no frames can be rendered.
-  // This error code must be reported by the Piet host app, as the Piet
-  // implementation assumes that all shared states have been provided already.
-  ERR_MISSING_SHARED_STATE = 12 /* [
-    // Something is seriously wrong if a SharedState is missing
-    (server_error) = FATAL,
-    // Clients cannot render any Frame when SharedState is missing (no Template)
-    (client_error) = FATAL
-  ] */;
-
-  // When a Template cannot be located, it only affects Frames that reference
-  // it, so we can proceed to render other unaffected Frames, making this an
-  // ERROR, not FATAL.
-  ERR_MISSING_TEMPLATE = 5 /* [
-    // Server should flag to feature authors when a Template is missing.
-    (server_error) = ERROR,
-    // Clients cannot render a Frame with missing Templates, so drop the Frame.
-    (client_error) = ERROR
-  ] */;
-
-  // When two or more Templates with the same conflicting ID are found in
-  // PietSharedState, rendering of all Frames becomes unpredictable, making this
-  // FATAL.
-  ERR_DUPLICATE_TEMPLATE = 6 /* [
-    // Server should fail to build the proto containing duplicate Templates.
-    (server_error) = FATAL,
-    // Client should drop the affected Frame, but continue to render others.
-    (client_error) = ERROR
-  ] */;
-
-  // When a stylesheet cannot be located, it only affects Frames that reference
-  // it, so we can proceed to render other unaffected Frames, making this an
-  // ERROR, not FATAL.
-  ERR_MISSING_STYLESHEET = 1 /* [
-    // Server should flag to feature authors when a Stylesheet is missing.
-    (server_error) = ERROR,
-    // Clients cannot render a Frame with missing Stylesheets, so drop the
-    // Frame.
-    (client_error) = ERROR
-  ] */;
-
-  // When two or more Stylesheets with the same conflicting ID are found in
-  // PietSharedState, rendering of all Frames becomes unpredictable, making this
-  // FATAL.
-  ERR_DUPLICATE_STYLESHEET = 2 /* [
-    // Server should fail to build the proto containing duplicate Stylesheets.
-    (server_error) = FATAL,
-    // Client should drop the affected Frame, but continue to render others.
-    (client_error) = ERROR
-  ] */;
-
-  ERR_MISSING_STYLE = 3 /* [
-    // Server should flag to feature authors when a Style is missing.
-    (server_error) = ERROR,
-    // Clients should use the default style instead.
-    (client_error) = NOTICE
-  ] */;
-
-  // If two or more Styles with the same conflicting ID are found in the same
-  // BindingContext, rendering of the affected Frame is unpredictable.
-  ERR_DUPLICATE_STYLE = 4 /* [
-    // Server should flag to feature authors when duplicate styles are present.
-    (server_error) = ERROR,
-    // Clients prefer to avoid dropping Frames, so pick a matching style and
-    // continue to render. The choosing of which matching style is used is
-    // undefined.
-    (client_error) = WARNING
-  ] */;
-
-  // If a BindingValue is missing for a BindingRef that is required (i.e. not
-  // marked is_optional), this error is raised.
-  ERR_MISSING_BINDING_VALUE = 8 /* [
-    // Server should flag to feature authors when an expected BindingValue is
-    // missing.
-    (server_error) = ERROR,
-    // Clients cannot render a Frame until all bindings are resolved, so drop
-    // this Frame.
-    (client_error) = ERROR
-  ] */;
-
-  // If two or more BindingValues with the same conflicting ID are found in the
-  // same binding context, rendering of the affected Frame is unpredictable.
-  ERR_DUPLICATE_BINDING_VALUE = 9 /* [
-    // Server should flag to feature authors when duplicate BindingValues are
-    // present.
-    (server_error) = ERROR,
-    // Clients prefer to avoid dropping Frames, so pick the first matching
-    // BindingValue and continue to render.
-    (client_error) = ERROR
-  ] */;
-
-  // BindingValues must be of the same type as the BindingRefs they are expected
-  // to replace at runtime.
-  ERR_BINDING_VALUE_TYPE_MISMATCH = 10 /* [
-    // Server should flag to feature authors when a BindingValue is of the wrong
-    // type.
-    (server_error) = ERROR,
-    // Clients cannot render a Frame with the wrong types of bindings, so drop
-    // this Frame.
-    (client_error) = ERROR
-  ] */;
-
-  // Bindings are not supported in Frames or within Bound Elements.
-  ERR_UNSUPPORTED_CONTEXT_FOR_BINDING = 11 /* [
-    // Bindings will not work in this context
-    (server_error) = ERROR,
-    // Clients might support bindings in this context.
-    (client_error) = WARNING
-  ] */;
-
-  // ---------------------------------------------------------------------------
-  // Missing required proto fields, or invalid values.
-  // Fields start at ID 101.
-  // ---------------------------------------------------------------------------
-
-  // If and only if *all* fonts specified in the style are unavailable on the
-  // client at runtime, this error will be raised. If at least one font (from
-  // among the ordered list of fonts) is available, then this error MUST NOT be
-  // raised.
-  ERR_MISSING_FONTS = 101 /* [
-    // Server won’t know about available fonts.
-    (server_error) = UNKNOWN,
-    // Client SHOULD use the default font.
-    (client_error) = NOTICE
-  ] */;
-
-  // If and only if *all* ImageSources specified for a single ImageElement lack
-  // a valid URL this error should be raised. If at least one URL is present,
-  // this error MUST NOT be raised. Note that this error is only related to
-  // whether a URL is present or absent. Adverse network conditions should have
-  // no impact on this, and MUST NOT raise this error.
-  ERR_MISSING_IMAGE_URL = 102 /* [
-    // Server should flag to feature authors when image URLs are absent.
-    (server_error) = ERROR,
-    // Clients prefer to avoid dropping Frames, so they continue to render the
-    // rest of the Frame, substituting the missing image with a gray box.
-    (client_error) = WARNING
-  ] */;
-
-  // If and only if *all* ImageSources specified for a single ImageElement
-  // cannot be located at runtime (due of a temporary network issue, or if the
-  // asset cannot be located in the app binary), this error should be raised.
-  // If at least one URL can be correctly resolved, this error MUST NOT be
-  // raised.
-  ERR_IMAGE_UNAVAILABLE = 103 /* [
-    // Servers will not be able to detect runtime issues with network conditions
-    // or app resources.
-    (server_error) = UNKNOWN,
-    // Clients may face adverse network conditions, preventing an image from
-    // being downloaded, or may receive a URL for an asset that does not exist.
-    (client_error) = WARNING
-  ] */;
-
-  // If Piet encounters a CustomElement, and the Host is unable to locate a
-  // custom renderer for that CustomElement, this error will be raised.
-  ERR_MISSING_CUSTOM_ELEMENT_RENDERER = 104 /* [
-    // Server cannot know about the availability of renderers at runtime.
-    (server_error) = UNKNOWN,
-    // Piet will display an empty gray area where the CustomElement should have
-    // been rendered, but the rest of the Frame should be rendered.
-    (client_error) = WARNING
-  ] */;
-
-  // Gradient directions should be in the range [0, 360).
-  ERR_INVALID_GRADIENT_DIRECTION = 105 /* [
-    // There is no good reason for the server to provide values outside this
-    // range.
-    (server_error) = WARNING,
-    // Clients should quietly clamp values to within the acceptable range.
-    (client_error) = QUIET
-  ] */;
-
-  // If an Action Handler delegate (which is part of a Piet Host) encounters an
-  // `Action` proto that it cannot handle (e.g. because none of the extensions
-  // it can process are present), this error will be raised.
-  ERR_MISSING_ACTION_HANDLER = 106 /* [
-    // Server cannot know about the availability of action handlers at runtime.
-    (server_error) = UNKNOWN,
-    // Interacting with such a Piet view will cause a warning to be displayed to
-    // the user.
-    (client_error) = WARNING
-  ] */;
-
-  // If a GridCell with Content width has a content that is not TextElement or
-  // ImageElement, this error will be raised.
-  ERR_CONTENT_WIDTH_GRID_CELL_WITH_INVALID_CONTENT = 107 /* [
-    // Server should flag to feature authors when such data is given.
-    (server_error) = ERROR,
-    // Clients cannot render a Frame with this kind of error.
-    (client_error) = ERROR
-  ] */;
-
-  // It does not make sense to have a GridCell where GridCellWidth is specified
-  // but nothing inside the GridCellWidth is populated. Looks like missing data.
-  ERR_GRID_CELL_WIDTH_WITHOUT_CONTENTS = 108 /* [
-    // Server should flag to feature authors when such data is given.
-    (server_error) = ERROR,
-    // Clients will use the default value but warn about missing data.
-    (client_error) = WARNING
-  ] */;
-
-  // If a MediaQueryCondition is specified with any parameter unchanged from its
-  // default value, this error is raised.
-  ERR_INVALID_MEDIA_QUERY_CONDITION = 109 /* [
-    // Server should flag to feature authors when such data is given.
-    (server_error) = ERROR,
-    // Clients will ignore the MediaQueryCondition and continue rendering.
-    (client_error) = NOTICE
-  ] */;
-
-  // If an Element is passed to an adapter but is missing the required type of
-  // content (ex. an Element without a TextElement in TextElementAdapter).
-  ERR_MISSING_ELEMENT_CONTENTS = 110 /* [
-    // Server should flag to feature authors when such data is given.
-    (server_error) = ERROR,
-    // Clients cannot render a Frame with this kind of error.
-    (client_error) = ERROR
-  ] */;
-
-  // A proto is missing some of the content it is expected to have.
-  // Ex. getting an unrecognized value for an enum or oneof case.
-  ERR_MISSING_OR_UNHANDLED_CONTENT = 111 /* [
-    // Server should flag to feature authors when such data is given.
-    (server_error) = ERROR,
-    // Clients cannot render a Frame with this kind of error.
-    (client_error) = ERROR
-  ] */;
-
-  // ---------------------------------------------------------------------------
-  // Performance Related.
-  // Fields start at ID 201.
-  // ---------------------------------------------------------------------------
-
-  // It is possible and likely that different client implementations of Piet
-  // will not support all features equally at all points of time. Incomplete
-  // implementations MAY raise this error to indicate their lack of support for
-  // certain Piet features. It is not guaranteed that every implementation will
-  // raise this error for every feature.
-  ERR_UNSUPPORTED_FEATURE = 201 /* [
-    // TODO: Expose a way for servers to know feature support across
-    // clients, which feature authors can use to decide whether to use a certain
-    // feature.
-    (server_error) = UNKNOWN,
-    // Clients should render the rest of the Frame except for the missing
-    // feature, with or without workarounds, e.g. if gradients are not
-    // supported, clients may choose to substitute a solid color instead.
-    (client_error) = WARNING
-  ] */;
-
-  // Certain platforms, e.g. Android, have limitations on how large a proto can
-  // be, because it needs to be serialized/deserialized into structures with
-  // limited memory. On certain low-RAM devices, this error may be raised to
-  // inform the server of a potential performance implication.
-  ERR_PROTO_TOO_LARGE = 202 /* [
-    // Servers should not dictate how large a proto can be.
-    (server_error) = UNKNOWN,
-    // Clients that cannot handle large protos should raise this error.
-    (client_error) = ERROR
-  ] */;
-
-  // If a Piet renderer is unable to render content at 60 fps, it attempts to
-  // inform the server. Feature authors can monitor the number of dropped frames
-  // and consider if they want to make improvements, e.g. simplifying the visual
-  // design to reduce nesting levels.
-  ERR_POOR_FRAME_RATE = 203 /* [
-    // Servers will not know about client frame rates.
-    (server_error) = UNKNOWN,
-    // Warnings should be logged to the server.
-    (client_error) = WARNING
-  ] */;
-
-  // ChunkedText should be used only when there's more than one chunk in it,
-  // othewise, either ParameterizedText, or Image should be used.
-  ERR_CHUNKED_TEXT_WITH_SINGLE_CHUNK = 204 /* [
-    // Server should bring up a warning in case this is used, this has only
-    // performance penalty.
-    (server_error) = WARNING,
-    // Clients should render if possible.
-    (client_error) = QUIET
-  ] */;
-
-  // ---------------------------------------------------------------------------
-  // Accessibility Related.
-  // Fields start at ID 301.
-  // ---------------------------------------------------------------------------
-
-  // Piet will attempt to provide accessibility-related guidance whenever
-  // possible. These should all be server_error:NOTICE (server should flag to
-  // feature authors) & client_error:QUIET (clients have no way to recover).
-  //
-  // E.g. Click targets below a certain size (typically 44×44 dp) will be
-  // flagged for review.
-  // ERR_CLICK_TARGET_TOO_SMALL
-  //
-  // Color contrast between elements close to each other impacts accessibility.
-  // ERR_COLOR_CONTRAST_TOO_LOW
-}
diff --git a/components/feed/core/proto/ui/piet/form_fields.proto b/components/feed/core/proto/ui/piet/form_fields.proto
deleted file mode 100644
index 516eb86b..0000000
--- a/components/feed/core/proto/ui/piet/form_fields.proto
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-import "components/feed/core/proto/ui/piet/elements.proto";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "FormFieldsProto";
-option cc_enable_arenas = true;
-
-// Form Fields can be used to solicit user input and act upon it. Multiple
-// visual types of form fields can be used in a Piet layout, all of which are
-// represented using the `FormField` proto message.
-message FormField {
-  // FormFields are implemented in secondary Piet Modules, and thus extend
-  // ModuleElement.
-  extend ModuleElement { optional FormField form_field = 193737014; }
-
-  // A unique ID for the Form in which this field appears.
-  optional string form_id = 1;
-
-  // A unique ID for this form field. Uniqueness is only required within the
-  // same Form. Multiple Forms can have fields with the same ID.
-  optional string field_id = 2;
-
-  // All fields are optional by default. If a particular field must be filled
-  // in, it should be marked as `is_required`. A required field which has no
-  // value provided is considered to have failed validation.
-  optional bool is_required = 3 [default = false];
-
-  // The kind of visual presentation to be used for this field.
-  oneof form_field_type {
-    // A text field that accepts typed text responses.
-    TextArea text_area = 4;
-
-    // A list or dropdown that allows selecting one or more options from a list.
-    Selectable selectable = 5;
-
-    // A check box or radio button widget.
-    Checkable checkable = 6;
-
-    // A numeric range slider that can also handle discrete values.
-    Slider slider = 7;
-  }
-}
-
-// Fillable text field where user can type text or use free-form auto-complete
-// suggestions provided by the client platform. A text field can have different
-// visual presentations, and `InputType` decides the kinds of inputs that are
-// possible. Clients may use the hints provided by `InputType` to provide
-// auto-complete for special types (e.g. email, URLs, regular expressions).
-message TextArea {
-  // Whether this is a special kind of text input; see `InputType`.
-  optional InputType input_type = 1;
-
-  // The number of vertical lines to be made visible in the viewport. Content
-  // within this field may contain newlines, so
-  //   the number of lines in the accepted input text can be more or less than
-  //   this number.
-  optional int32 lines_visible = 2 [default = 1];
-
-  // Auto-complete suggestion to be shown in the UI.
-  optional string value = 3;
-
-  // Text to be shown when the text area’s contents are empty. The hint is
-  // usually rendered in a duller font and is immediately hidden as soon as the
-  // user types some text.
-  optional string hint = 4;
-
-  // If a `regex_pattern` is specified, then the field is considered valid if at
-  // least one `regex_pattern` from the set matches user input. Regular
-  // expression based validation is only performed when `InputType` is DEFAULT.
-  // (i.e., this field is ignored even if provided for types such as PASSWORD,
-  // EMAIL, URL, TEL, NUMERIC, DATE, TIME, or COLOR.)
-  repeated string regex_pattern = 5;
-}
-
-// A dropdown or list-selection widget that shows multiple items, and the user
-// can pick one or many from that list.
-message Selectable {
-  // Whether multiple items from a SELECTABLE field can be selected at once.
-  optional bool is_multi_select = 1;
-
-  // The number of vertical lines to be visible in the viewport. Non-positive
-  // values are overridden and set to 1. Note that this does not affect how many
-  // items can be selected by the user; see `is_multi_select`.
-  optional int32 lines_visible = 2 [default = 1];
-
-  // Options to be included in the selectable dropdown or list.
-  repeated string options = 3;
-}
-
-// A single form field type that represents both, check boxes and radio buttons.
-// To group together multiple radio buttons such that only one is selectable at
-// a given time, set the same `group_id` on all of them. To use a single
-// independent checkbox, ensure that `group_id` is not set.
-message Checkable {
-  // Multiple checkable fields that have the same `group_id` are treated as
-  // mutually exclusive (i.e. like radio buttons) such that checking any one
-  // will automatically un-check every other checkable field with the same
-  // `group_id`.
-  //
-  // If no `group_id` is specified, then a checkable field behaves like an
-  // independent checkbox. This field may affect the visual presentation of the
-  // field (i.e. circular radio button versus square checkbox, depending on
-  // platform conventions).
-  optional string group_id = 1;
-}
-
-// Numeric input types, or non-numeric input types that accept a discrete set
-// of values can be represented using sliders. For a read-only progress-bar-like
-// appearance, use a slider with `is_enabled` set to false.
-message Slider {
-  // The minimum value, inclusive.
-  optional int32 minimum = 1;
-
-  // The maximum value, inclusive.
-  optional int32 maximum = 2;
-
-  // The step between successive values.
-  optional int32 step = 3;
-}
-
-// For text areas, feature authors can specify in more detail the kinds of input
-// they expect to receive. `InputType` can be used for three purposes:
-//
-// - For Picker UI affordances: clients can show special UIs for special types
-//   such as a date picker, time picker, or color picker.
-//
-// - For Auto-Complete: clients can use `InputType` hints to pre-populate
-//   suggestions that may not be available server-side, e.g. email addresses,
-//   URLs from history, or frequently-dialed phone numbers.
-//
-// - For Validation: clients can perform client-side validation of most input
-//   types based on the expected text formats (e.g. email, date, time, or via
-//   regular expressions).
-enum InputType {
-  // No special treatment.
-  DEFAULT = 0;
-
-  // Any text typed by the user is masked according to platform conventions.
-  PASSWORD = 1;
-
-  // Only those characters that are valid in email addresses can be typed into
-  // the TEXT field. Client may provide auto-complete suggestions to
-  // pre-populate email addresses from client-side data. Typed input must
-  // validate as an email address.
-  EMAIL = 2;
-
-  // Only those characters that are valid in URLs can be typed into the TEXT
-  // field. Client may provide auto-complete suggestions to pre-populate browser
-  // navigation URLs from client-side data. Typed input must validate as a URL.
-  URL = 3;
-
-  // Only those characters that are valid in (international) telephone numbers
-  // can be typed into the TEXT field. Client may provide auto-complete
-  // suggestions to pre-populate browser navigation URLs from client-side data.
-  // Typed input must validate as a phone number.
-  TEL = 4;
-
-  // Only numeric characters can be typed into the TEXT field. If a range is
-  // provided, then typed input must be within the acceptable range. NUMERIC can
-  // be used with either TEXT or SLIDER visual types.
-  NUMERIC = 5;
-
-  // Clients may provide a Date Picker widget TEXT fields of type DATE.
-  DATE = 6;
-
-  // Clients may provide a Time Picker widget TEXT fields of type TIME.
-  TIME = 7;
-
-  // Clients may provide a Color Picker widget TEXT fields of type COLOR. The
-  // returned value is a color in ARGB hex form with a preceding literal '#'
-  // (#AARRGGBB).
-  COLOR = 8;
-}
diff --git a/components/feed/core/proto/ui/piet/gradients.proto b/components/feed/core/proto/ui/piet/gradients.proto
deleted file mode 100644
index 6e9a76b..0000000
--- a/components/feed/core/proto/ui/piet/gradients.proto
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "GradientsProto";
-option cc_enable_arenas = true;
-
-// Represents a Fill to be used for a Piet element.
-message Fill {
-  // A fill can be either a solid color or a gradient.
-  oneof fill_type {
-    // A solid color fill. Colors are ARGB.
-    fixed32 color = 1;
-
-    // A linear gradient, expressed as multiple color stops.
-    LinearGradient linear_gradient = 2;
-  }
-}
-
-// A linear gradient interpolates the given color stops linearly.
-message LinearGradient {
-  // Multiple stops for this gradient. A valid gradient must have at least
-  // two stops, one at position 0 and another at position 100.
-  repeated ColorStop stops = 1;
-
-  // Direction towards which this gradient should be rendered, in degrees from
-  // the top.
-  //   0: ↑ From Bottom to Top.
-  //  90: → From Left to Right.
-  // 180: ↓ From Top to Bottom.
-  // 270: ← From Right to Left.
-  // Values must be in the range [0..360). Negative values are not valid.
-  optional uint32 direction_deg = 2;
-
-  // If this boolean is true, the 'x' component of the gradient's angle will be
-  // reversed when Piet is rendering a layout for a right-to-left language.
-  optional bool reverse_for_rtl = 3;
-}
-
-// A GradientStop is one color in a gradient. A simple gradient is composed of
-// at least two stops: starting with `position_percent` 0 & ending with
-// `position_percent` 100. The linear gradient is interpolated between these two
-// endpoints. More complex gradients can be achieved by inserting more color
-// stops into the list.
-message ColorStop {
-  // ARGB color of the color stop.
-  optional fixed32 color = 1;
-
-  // Position of this color stop, expressed as a percent. It is an error for
-  // position_percent to be outside [0..100].
-  optional fixed32 position_percent = 2;
-}
diff --git a/components/feed/core/proto/ui/piet/images.proto b/components/feed/core/proto/ui/piet/images.proto
deleted file mode 100644
index 1a851cf..0000000
--- a/components/feed/core/proto/ui/piet/images.proto
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/ui/piet/media_queries.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "ImagesProto";
-option cc_enable_arenas = true;
-
-// An image asset.
-message Image {
-  // Image sources are `repeated` so that a feature author can specify multiple
-  // image sources in the order that they should be attempted to be fetched.
-  // Clients can go through the list until they find one they wish to fetch,
-  // based either on the type of URL (e.g. `https://` versus `asset://`) or
-  // based on the size of the raw image (e.g. 1x DPI or 2x DPI). Feature
-  // authors are responsible for ensuring that at least one image source is
-  // valid and accessible (https://gstatic.com URLs are recommended as the
-  // ultimate fallback).
-  // See [INTERNAL LINK] for more details on Image handling.
-  repeated ImageSource sources = 1;
-
-  // The type of scaling to apply.
-  enum ScaleType {
-    // When scale type is unspecified, we err on the side of preserving all
-    // areas of the image, so this is equivalent to CENTER_INSIDE.
-    SCALE_TYPE_UNSPECIFIED = 0;
-
-    // Scale the image uniformly such that width or height will be equal to the
-    // size of its view. The image will not be cropped.
-    CENTER_INSIDE = 1;
-
-    // Scale the image uniformly to fill its view. Some portion of the image
-    // will be cropped.
-    CENTER_CROP = 2;
-  }
-
-  // Reserved tags from deprecated fields
-  reserved 2, 3;
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// A single physical image, as contained in a single image file or embedded
-// resource. To accommodate devices with varying Device Pixel Ratios, each image
-// in a different DPI bucket can be represented as a separate `ImageSource`.
-// E.g. the same image can be offered as multiple resources as:
-//     ImageSource{
-//       url="ic_icon_24@1x.png",
-//       width=24,
-//       height=24
-//     }
-// and:
-//     ImageSource{
-//       url="ic_icon_24@2x.png",
-//       width=48,
-//       height=48
-//     }
-// This enables clients to choose which image to fetch based on the expected
-// width and height, without actually having to fetch it first.
-// These dimensions also allow clients to pre-size the view for the image before
-// it loads so that the view's size doesn't change once the image is loaded.
-message ImageSource {
-  // URLs can be "https://" or "asset://".
-  // HTTPS URLs can be fetched by a regular network communication library.
-  // Asset URLs can be fetched by implementation-specific asset helpers.
-  // Asset URLs must be specified in an implementation-agnostic manner.
-  // If missing, ERR_IMAGE_URL_EMPTY is raised.
-  optional string url = 1;
-
-  // This ImageSource is only eligible to be used if *all* the conditions
-  // enumerated below are met. If even one condition is unsatisfied, this
-  // ImageSource is skipped, and Piet will pick another image. It is recommended
-  // to include at least one ImageSource that is loaded unconditionally.
-  repeated MediaQueryCondition conditions = 2;
-
-  // The intrinsic width of this image, expressed in raw pixels. This may be
-  // different from the width of the container in which this image should be
-  // displayed. This can be used for pre-allocating space for the image before
-  // it loads. It is expected that the server will usually provide this field.
-  optional int32 width_px = 4;
-
-  // The intrinsic height of this image, expressed in raw pixels. This may be
-  // different from the height of the container in which this image should be
-  // displayed. This can be used for pre-allocating space for the image before
-  // it loads. It is expected that the server will usually provide this field.
-  optional int32 height_px = 5;
-}
diff --git a/components/feed/core/proto/ui/piet/log_data.proto b/components/feed/core/proto/ui/piet/log_data.proto
deleted file mode 100644
index d06ba125..0000000
--- a/components/feed/core/proto/ui/piet/log_data.proto
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "LogDataProto";
-option cc_enable_arenas = true;
-
-// LogData used to contain piet-agnostic information used for logging.
-message LogData {
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
diff --git a/components/feed/core/proto/ui/piet/media_queries.proto b/components/feed/core/proto/ui/piet/media_queries.proto
deleted file mode 100644
index 05ae25a..0000000
--- a/components/feed/core/proto/ui/piet/media_queries.proto
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "MediaQueriesProto";
-option cc_enable_arenas = true;
-
-// A single media query condition offers a way for a Piet renderer to decide
-// whether or not to apply a particular Stylesheet, Template, ImageSource, or
-// other entities based on the environment config at runtime. For example,
-// adding a width-based conditional enables providing different layouts/styles
-// based on the user’s device, and this can be re-evaluated entirely client-side
-// e.g. if the user rotates their device so that the width changes.
-// The name MediaQueryCondition derives from a similar concept for Web/CSS and
-// most principles in the Piet Media Query spec are influenced by their Web
-// equivalents.
-// https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries
-message MediaQueryCondition {
-  oneof condition {
-    // See the documentation for FrameWidthCondition.
-    FrameWidthCondition frame_width = 1;
-
-    // See the documentation for OrientationCondition.
-    OrientationCondition orientation = 2;
-
-    // See the documentation for DarkLightCondition.
-    DarkLightCondition dark_light = 3;
-  }
-}
-
-// Width of each Frame in the current Piet rendering context. For multi-column
-// layouts (in which Piet is instantiated independently in more than one
-// column), this refers to the width of the individual column, not the overall
-// width of the containing app.
-message FrameWidthCondition {
-  // Width of the viewport, expressed in DP.
-  optional int32 width = 1;
-
-  // Defines how the condition match should be evaluated.
-  optional ComparisonCondition condition = 2;
-}
-
-// Whether the device is oriented in portrait mode or landscape mode. This
-// applies mostly to mobile devices, but it is possible also for a Web device to
-// be oriented in portrait mode.
-message OrientationCondition {
-  enum Orientation {
-    // Must not be set to UNSPECIFIED, otherwise
-    // ERR_INVALID_MEDIA_QUERY_CONDITION will be raised.
-    UNSPECIFIED = 0;
-
-    // Height of the device is greater than or equal to the width of the device.
-    // Default.
-    PORTRAIT = 1;
-
-    // Width of the device is greater than the height of the device.
-    LANDSCAPE = 2;
-  }
-  optional Orientation orientation = 1;
-}
-
-// Whether the UI should use a dark theme (white/light text on a black/dark
-// background) or a light theme (black/dark text on a white/light background).
-message DarkLightCondition {
-  enum DarkLightMode {
-    // Must not be set to UNSPECIFIED, otherwise
-    // ERR_INVALID_MEDIA_QUERY_CONDITION will be raised.
-    UNSPECIFIED = 0;
-
-    // Black/dark text on white/light background.
-    LIGHT = 1;
-
-    // Light/white text on black/dark background.
-    DARK = 2;
-  }
-  optional DarkLightMode mode = 1;
-}
-
-// How a condition should be evaluated. Self-explanatory. Must not be set to
-// UNSPECIFIED, otherwise ERR_INVALID_MEDIA_QUERY_CONDITION will be raised.
-enum ComparisonCondition {
-  UNSPECIFIED = 0;
-
-  EQUALS = 1;
-
-  NOT_EQUALS = 2;
-
-  LESS_THAN = 3;
-
-  GREATER_THAN = 4;
-}
diff --git a/components/feed/core/proto/ui/piet/piet.proto b/components/feed/core/proto/ui/piet/piet.proto
deleted file mode 100644
index 71608102..0000000
--- a/components/feed/core/proto/ui/piet/piet.proto
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/ui/piet/actions.proto";
-import "components/feed/core/proto/ui/piet/elements.proto";
-import "components/feed/core/proto/ui/piet/log_data.proto";
-import "components/feed/core/proto/ui/piet/media_queries.proto";
-import "components/feed/core/proto/ui/piet/styles.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "PietProto";
-option cc_enable_arenas = true;
-
-// Piet • [INTERNAL LINK] • [INTERNAL LINK]
-//
-// Piet is a declarative UI rendering spec with a set of cross-platform
-// libraries that can render the same exact proto on Android, iOS and Web to
-// generate similar visual layouts.
-
-// DOCS
-//
-// Before using Piet, make sure to read the following docs:
-// - Core Design: [INTERNAL LINK]
-// - Client Support: [INTERNAL LINK]
-// - Error Handling: [INTERNAL LINK]
-//
-// IDs
-//
-// Every field that ends in `_id` must be unique within its containing message.
-// Examples:
-// - Style.style_id must be unique within a Stylesheet.
-// - Stylesheet.stylesheet_id must be unique within PietSharedState.
-// - Template.template_id must be unique within PietSharedState.
-// - BindingRef.binding_id must be unique within its containing Template.
-// etc.
-//
-// TAG
-//
-// Fields named `tag` are open-ended and never used for any processing. Servers,
-// Clients, and Hosts may use these fields as they see fit, mostly for debugging
-// purposes.
-//
-// COLORS
-//
-// - Although colors are expressed as 32-bit ARGB (Alpha, Red, Green, Blue)
-//   channels, not all platforms may support alpha.
-// - Colors have no meaningful default and must be specified explicitly wherever
-//   needed.
-// - If a platform requires an alternate representation for convenience, (e.g.
-//   CSS-style #000000 format), such representations should be segregated in
-//   platform-specific support protos, e.g. `piet_web_support.proto`.
-//
-// DIMENSIONS
-//
-// - All measurements are in dp (display pixels) unless otherwise specified.
-// - Negative values are officially unsupported, though they may happen to work
-//   in certain circumstances. Unless explicitly documented otherwise, do not
-//   assume that they will continue to work the same way across multiple client
-//   implementations or versions.
-//
-// -----------------------------------------------------------------------------
-
-// A Frame is the top-level UI construct in Piet. Every layout is contained
-// within a Frame. Each frame defines the contents displayed to the user as a
-// single view, which may contain a complex set of child views.
-// NextId: 13
-message Frame {
-  // A string tag for the frame, currently used for debugging purposes. Need not
-  // be unique.
-  optional string tag = 1;
-
-  // UI Elements in a Frame use a Stylesheet to resolve the Styles that define
-  // their appearance. This Stylesheet can either be provided directly inlined
-  // in every Frame, or via a lookup in the global shared state in
-  // PietSharedState.
-  //
-  // NOTE: Styles from this Stylesheet are not available to Templates; they can
-  // only be used by Elements defined directly in this Frame itself, such as
-  // non-template Content, or ElementLists bound to Templates. This limitation
-  // is a performance optimization that makes view recycling efficient. This
-  // applies to both the inlined Stylesheet and stylesheet_id's referencing a
-  // PietSharedState Stylesheet.
-  //
-  // DEPRECATED: Use stylesheets field instead. If that field is set, these
-  // deprecated fields will be ignored.
-  oneof frame_style_scope {
-    // If this is defined, the Stylesheet for the Frame is found by a lookup
-    // in PietSharedState.Stylesheets. If the stylesheet_id cannot be found,
-    // ERR_MISSING_STYLESHEET is raised.
-    // DEPRECATED: use stylesheets field instead.
-    string stylesheet_id = 2 [deprecated = true];
-
-    // A local Stylesheet that provides styles used by Elements in this Frame.
-    // DEPRECATED: use stylesheets field instead.
-    Stylesheet stylesheet = 3 [deprecated = true];
-  }
-
-  // Defines the Stylesheets used by this Frame.
-  //
-  // NOTE: Styles from this Stylesheet are not available to Templates; they can
-  // only be used by Elements defined directly in this Frame itself, such as
-  // non-template Content. This limitation is a performance optimization that
-  // makes view recycling efficient. This applies to both the inlined
-  // Stylesheets and stylesheet_id's referencing a PietSharedState Stylesheet.
-  optional Stylesheets stylesheets = 11;
-
-  // Styles applied to this Frame. If any style_ids cannot be found,
-  // ERR_MISSING_STYLES is raised.
-  optional StyleIdsStack style_references = 4;
-
-  // Templates that are available for use within the scope of this Frame.
-  repeated Template templates = 5;
-
-  // Content that makes up this Frame.
-  //
-  // There are a few differences in the use of Content here vs. elsewhere:
-  //  - These Contents are arranged in a vertical list layout.
-  //  - Bindings are not supported in these Contents, since there is no
-  //    BindingContext available at the Frame level.
-  //  - These Contents support sharding: each of these Contents can be recycled
-  //    as it leaves the screen, to reduce memory usage when scrolling a very
-  //    long Frame.
-  repeated Content contents = 10;
-
-  // Actions associated with the full Frame.
-  optional Actions actions = 7;
-
-  // Data used for logging info sent to the host.
-  optional LogData log_data = 12;
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-
-  // Deprecated field IDs.
-  reserved 6, 9, 8;
-}
-
-// UI Elements in a Frame or Template use a Stylesheet to resolve the Styles
-// that define their appearance. The Stylesheet is constructed by combining
-// Styles from any Stylesheets referenced here; Stylesheets can by directly
-// inlined, or referenced from the global shared state in PietSharedState.
-// Piet will report ERR_DUPLICATE_STYLE if multiple Styles across any of the
-// Stylesheets have the same style id (after MediaQueryCondition filtering).
-message Stylesheets {
-  // Stylesheets to be fetched from the global PietSharedState.
-  // If a stylesheet_id cannot be found, ERR_MISSING_STYLESHEET is raised.
-  repeated string stylesheet_ids = 1;
-
-  // Inline Stylesheets. These can be filtered by MediaQueryCondition.
-  repeated Stylesheet stylesheets = 2;
-}
-
-// A set of Styles; each Style must have a style_id that is unique within this
-// Stylesheet. If the same style_id is found twice, ERR_DUPLICATE_STYLES is
-// raised. Stylesheet is scoped to Frames or Templates. When a UI element uses a
-// Style, it is looked up in the Stylesheet within scope. If the style cannot be
-// found, ERR_MISSING_STYLES is raised.
-message Stylesheet {
-  // A string uniquely identifying this Stylesheet within the PietSharedState in
-  // which it is used. If two Stylesheets with the same stylesheet_id are found
-  // in a PietSharedState, ERR_DUPLICATE_STYLESHEET is raised. This
-  // `stylesheet_id` is used to select this Stylesheet using
-  // Frame.stylesheet_id.
-  optional string stylesheet_id = 1;
-
-  // Styles available in this Stylesheet.
-  repeated Style styles = 2;
-
-  // This Stylesheet is only eligible to be used if *all* the conditions
-  // enumerated below are met. If even one condition is unsatisfied,
-  // this Stylesheet is treated as if it was never sent, which may cause
-  // ERR_STYLESHEET_NOT_FOUND.
-  repeated MediaQueryCondition conditions = 3;
-}
-
-// A Template defines a reusable ElementList. The content is data-bound from
-// Bindings in the TemplateInvocation. Templates allow consistent creation of
-// elements using bound data. For example, table rows with different values, or
-// GridCells with different data values.
-message Template {
-  // A unique identifier for this template. If two Templates with the same
-  // template_id are found in a PietSharedState, ERR_DUPLICATE_TEMPLATE is
-  // raised.
-  optional string template_id = 1;
-
-  // The Stylesheet used within this Template's scope.
-  // - Styles from the Frame CANNOT be referenced from within a Template.
-  // - Styles from the PietSharedState CAN be referenced, only if the
-  //   stylesheet_id is defined by the Template.
-  //
-  // DEPRECATED: Use stylesheets field instead. If that field is set, these
-  // deprecated fields will be ignored.
-  oneof template_stylesheet {
-    // If defined, the Stylesheet for this Template is looked up in
-    // PietSharedState.Stylesheets. If the stylesheet_id cannot be found,
-    // ERR_MISSING_STYLESHEET is raised.
-    // DEPRECATED: use stylesheets field instead.
-    string stylesheet_id = 2 [deprecated = true];
-
-    // A local Stylesheet. Styles in this Stylesheet will only be available to
-    // elements defined in this Template.
-    // DEPRECATED: use stylesheets field instead.
-    Stylesheet stylesheet = 3 [deprecated = true];
-  }
-
-  // The Stylesheets used within this Template's scope.
-  // - Styles from the Frame CANNOT be referenced from within a Template.
-  // - Styles from the PietSharedState CAN be referenced, only if the
-  //   stylesheet_id is defined by the Template.
-  optional Stylesheets stylesheets = 11;
-
-  // Styles applied to all child views of this Template.
-  optional StyleIdsStack child_default_style_ids = 4 [deprecated = true];
-
-  // Content defined by this Template.
-  optional Element element = 6;
-
-  // This Template is only eligible to be used if *all* the conditions
-  // enumerated below are met. If even one condition is unsatisfied, this
-  // Template is treated as if it was never sent, which may cause
-  // ERR_TEMPLATE_NOT_FOUND.
-  repeated MediaQueryCondition conditions = 8;
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-
-  // Deprecated field IDs.
-  reserved 5;
-}
-
-// State shared among multiple Frame instances. This is a top-level object,
-// defined outside individual Frame instances.
-message PietSharedState {
-  // Stylesheet definitions that can be reused across Frames.
-  // Stylesheet.stylesheet_id must be unique within the List, otherwise
-  // ERR_DUPLICATE_STYLESHEET is raised.
-  repeated Stylesheet stylesheets = 1;
-
-  // Template definitions that can be reused across Frames. Each Template may
-  // define their own Stylesheet, or can access a Stylesheet defined in this
-  // PietSharedState. If two or more Templates with the same template_id are
-  // found, then ERR_DUPLICATE_TEMPLATE is raised.
-  repeated Template templates = 2;
-}
diff --git a/components/feed/core/proto/ui/piet/piet_android_support.proto b/components/feed/core/proto/ui/piet/piet_android_support.proto
deleted file mode 100644
index 19c684c..0000000
--- a/components/feed/core/proto/ui/piet/piet_android_support.proto
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "PietAndroidSupport";
-option cc_enable_arenas = true;
-
-// Define extensions and other supporting messages used by the Android
-// implementation of the Piet protocol.
-
-// This allows the Host to control the granularity of slices by returning
-// only slices specified instead of generating all the slices within the
-// full Card message.
-// TODO: Is this still relevant?
-message ShardingControl {
-  // The first slice to render, if this is undefined we will render the
-  // full card.
-  optional int32 start_slice = 1;
-
-  // The last slice to render.
-  optional int32 end_slice = 2;
-
-  // If we are rendering a list, this is the first index in the list.
-  optional int32 list_start = 3;
-
-  // if we are rendering a list, this is the last index in the list.
-  optional int32 list_end = 4;
-}
diff --git a/components/feed/core/proto/ui/piet/rounded_corners.proto b/components/feed/core/proto/ui/piet/rounded_corners.proto
deleted file mode 100644
index ebb6f96f..0000000
--- a/components/feed/core/proto/ui/piet/rounded_corners.proto
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "RoundedCornersProto";
-option cc_enable_arenas = true;
-
-// Rounded corners for Views, expressed as a bit mask. If a container view has
-// rounded corners applied to it, then the contents of that view SHOULD also be
-// cropped to fit within the rounded rectangle bounding box established by the
-// container. Specifically, content within such a view SHOULD be cropped too,
-// without having to explicitly specify rounded corners on the child content.
-// Check [INTERNAL LINK] for any client-specific limitations that apply to the
-// current version of the implementation.
-message RoundedCorners {
-  // Represents the set of values for a bitmask to specify which corners should
-  // be rounded. Start indicates the left side for LTR settings, right side for
-  // RTL.
-  enum Corners {
-    // If unspecified, then all corners will be rounded.
-    CORNERS_UNSPECIFIED = 0;
-
-    // Indicates that the top starting corner should be rounded (top left for
-    // LTR, top right for RTL).
-    TOP_START = 0x1;
-
-    // Indicates that the top end corner should be rounded.
-    TOP_END = 0x2;
-
-    // Indicates that the bottom end corner should be rounded.
-    BOTTOM_END = 0x4;
-
-    // Indicates that the bottom starting corner should be rounded.
-    BOTTOM_START = 0x8;
-  }
-
-  // A bitmask representing which corners should be rounded. Bit values are
-  // defined by the `Corners` enum. If no corners are specified, then all
-  // corners will be rounded.
-  //
-  // NOTICE: having a rounded corner with a border only on one side is strongly
-  // discouraged as it leads to undefined and inconsistent behavior across
-  // platforms.
-  optional int32 bitmask = 1;
-
-  // The radius of the rounding applied to the specified corners, specified in
-  // DP. This value must be non-zero, otherwise it’s a no-op.
-  //
-  // This field is deprecated. Please use radius_options instead.
-  // radius and radius_dp have the same functionality. Both fields can be
-  // specified if there are concerns about users with old client versions that
-  // don't support the new field yet. If the client does recognize the new
-  // radius_options and the deprecated radius is specified as well, only
-  // radius_options will be used.
-  optional int32 radius = 2 [deprecated = true];
-
-  // The rounding radius applied to the corners specified in the bitmask. Value
-  // must be non-zero, otherwise it's a no-op. If the deprecated radius field is
-  // specified in addition to radius_options, only radius_options will be used.
-  //
-  // If the width or height of the element is less than the radius value, or the
-  // radii of adjacent corners add up to more than the element's width or
-  // height, the behavior is undefined. Piet will not crash, but the corners may
-  // look different on different platforms.
-  //
-  // One advantage of using a percentage is that, if accessibility settings
-  // change the text size and make an element grow or shrink, the radius will
-  // adjust as the size of the element changes.
-  oneof radius_options {
-    // The radius specified in dp.
-    uint32 radius_dp = 4;
-
-    // An integer value between 1 and 100. The corner radius is calculated as a
-    // percentage of the height of the element being rounded. It does not
-    // require the height to be explicitly specified on the element.
-    //
-    // For example:
-    // height = 100dp, width = 50dp, radius_percentage_of_height = 20%
-    // Actual radius (calculated by the client) = 20dp.
-    //
-    // Note that the value calculated from the height (i.e. 20dp) will be
-    // applied to both halves of any corners specified in the bitmask.
-    uint32 radius_percentage_of_height = 5;
-
-    // An integer value between 1 and 100. The corner radius is calculated as a
-    // percentage of the width of the element being rounded. It does not
-    // require the width to be explicitly specified on the element.
-    //
-    // For example:
-    // height = 100dp, width = 50dp, radius_percentage_of_width = 20%
-    // Actual radius (calculated by the client) = 10dp.
-    //
-    // Note that the value calculated from the width (i.e. 10dp) will be
-    // applied to both halves of any corners specified in the bitmask.
-    uint32 radius_percentage_of_width = 6;
-  }
-
-  // Flag to ask the host for a default radius. If the host does not return a
-  // radius, fall back to "radius_options". If this field is true and the host
-  // has provided a default radius, radius_options will be ignored.
-  optional bool use_host_radius_override = 3;
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
diff --git a/components/feed/core/proto/ui/piet/shadows.proto b/components/feed/core/proto/ui/piet/shadows.proto
deleted file mode 100644
index 2f2a96c4ca..0000000
--- a/components/feed/core/proto/ui/piet/shadows.proto
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "ShadowsProto";
-option cc_enable_arenas = true;
-
-// Defines a shadow for a given element. This message has sub-messages that
-// correspond to different methods that define shadows. Each client might
-// support a subset of the methodologies, will ignore the ones it does not
-// support, and may have a priority order for which type is used when multiple
-// shadow messages are defined (probably defaulting to the most descriptive
-// shadow type supported by the platform).
-// See [INTERNAL LINK]
-message Shadow {
-  // BoxShadow definition. Supported by the web and iOS clients.
-  optional BoxShadow box_shadow = 1;
-
-  // Simple elevation-based shadow. Supported by Android.
-  optional ElevationShadow elevation_shadow = 2;
-}
-
-// Defines a box shadow, as described in the CSS spec:
-// https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow.
-message BoxShadow {
-  // Defines the horizontal offset of the shadow.
-  //  * A positive value puts the shadow on the right side of the box (does not
-  //    flip in RTL presentation).
-  //  * A negative value puts the shadow on the left side of the box.
-  optional int32 offset_x = 1;
-
-  // Defines the vertical offset of the shadow.
-  //  * A positive value puts the shadow below the box.
-  //  * A negative value puts the shadow above the box.
-  optional int32 offset_y = 2;
-
-  // The blur radius of the shadow. The higher the number, the more blurred the
-  // shadow will be.
-  optional int32 blur_radius = 3;
-
-  // The spread radius of the shadow. A positive value increases the size of the
-  // shadow, a negative value decreases the size of the shadow.
-  // Not supported by iOS.
-  optional int32 spread_radius = 4;
-
-  // Defines whether the shadow should appear on the inside (is_inset == true),
-  // or the outside (is_inset == false).
-  // Not supported by iOS.
-  optional bool is_inset = 5;
-
-  // The color of the shadow.
-  optional fixed32 color = 6;
-}
-
-// Defines a simple elevation-based shadow, as described in Material Design:
-// https://developer.android.com/training/material/shadows-clipping
-message ElevationShadow {
-  // Elevation of the view in dp; higher elevation creates larger shadows.
-  optional int32 elevation = 1;
-}
diff --git a/components/feed/core/proto/ui/piet/styles.proto b/components/feed/core/proto/ui/piet/styles.proto
deleted file mode 100644
index b08c326b..0000000
--- a/components/feed/core/proto/ui/piet/styles.proto
+++ /dev/null
@@ -1,517 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/ui/piet/binding_refs.proto";
-import "components/feed/core/proto/ui/piet/gradients.proto";
-import "components/feed/core/proto/ui/piet/images.proto";
-import "components/feed/core/proto/ui/piet/media_queries.proto";
-import "components/feed/core/proto/ui/piet/rounded_corners.proto";
-import "components/feed/core/proto/ui/piet/shadows.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "StylesProto";
-option cc_enable_arenas = true;
-
-// A Style is a reusable specification of visual layout that can be applied to
-// any Piet visual element.
-//
-// Styles can be applied to visual elements at multiple levels of the visual
-// hierarchy. Only those attributes that make sense for a visual element will be
-// applied. Implementations MUST ignore attributes that cannot be meaningfully
-// applied to a visual element and MUST NOT issue any warnings or errors, to
-// allow for the same style to be reused in other places where those attributes
-// are relevant. E.g. for any style applied to an image-like element, font
-// should be ignored.
-
-// A stack of style_ids used to evaluate the style of an element. The final
-// applicable style is computed by proto-merging each style one by one, in order
-// starting from the first. Later attributes override earlier attributes. If a
-// style_id cannot be found, ERR_MISSING_STYLE is raised.
-//
-// After the style_ids are merged, in case a bound_style is given, its values
-// override the ones produced by the merge.
-message StyleIdsStack {
-  // Style IDs that are proto-merged in order from first to last.
-  repeated string style_ids = 1;
-
-  // Optional style binding that override the styles in the given style_ids.
-  // See message comment for exact use.
-  optional StyleBindingRef style_binding = 2;
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// A collection of attributes describing an element’s visual properties.
-// NextId: 25
-message Style {
-  // Every style must have a name that is unique within the StyleSheet. But
-  // don’t go overboard in naming these with namespaced constructs because
-  // longer strings lead to more bytes on the wire.
-  optional string style_id = 1;
-
-  // This Style is only eligible to be used if *all* the conditions
-  // enumerated below are met. Multiple styles can have the same style id if
-  // their conditions are disjoint.
-  repeated MediaQueryCondition conditions = 16;
-
-  // Foreground color for text elements.
-
-  // When applied to an image, this will replace all non-transparent pixels with
-  // the specified color. This is used for changing the color of icons which are
-  // provided as a monochrome bitmap. If this optional field is not provided,
-  // the image will not be modified.
-  optional fixed32 color = 2 [default = 0xDE000000];
-
-  // Defines the background fill, either as a solid color, or a gradient.
-  optional Fill background = 3;
-
-  // Configuration for image loading behavior (such as fading in)
-  optional ImageLoadingSettings image_loading_settings = 17;
-
-  // Font information applicable to text elements.
-  optional Font font = 4;
-
-  // Text alignment
-  optional TextAlignmentHorizontal text_alignment_horizontal = 21
-      [default = TEXT_ALIGNMENT_START];
-  optional TextAlignmentVertical text_alignment_vertical = 22
-      [default = TEXT_ALIGNMENT_TOP];
-
-  // Margins (if given) are outside the specified width/height.
-  // The background fills all the area up to the margin, excluding the margin.
-  //
-  //    +--------SpecifiedWidth---------+
-  //    |                               |
-  //
-  // +-------------------------------------+
-  // |               Margin                |
-  // |  +-------------------------------+  |  --+
-  // |  |ooooooooooo.Border.oooooooooooo|  |    |
-  // |  |o+---------------------------+o|  |    |
-  // |  |o|          Padding          |o|  |    |
-  // |  |o|  +---------------------+  |o|  |    |
-  // |  |o|  |                     |  |o|  |    |
-  // |  |o|  |       Content       |  |o|  |    +-- SpecifiedHeight
-  // |  |o|  |                     |  |o|  |    |
-  // |  |o|  +---------------------+  |o|  |    |
-  // |  |o|                           |o|  |    |
-  // |  |o+---------------------------+o|  |    |
-  // |  |ooooooooooooooooooooooooooooooo|  |    |
-  // |  +-------------------------------+  |  --+
-  // |                                     |
-  // +-------------------------------------+
-
-  // Margins around the item
-  optional EdgeWidths margins = 5;
-
-  // Borders
-  optional Borders borders = 6;
-
-  // Padding around the item
-  optional EdgeWidths padding = 7;
-
-  // This Element's requested width.
-  // If this is not set, use the parent container's default child width.
-  oneof width_spec {
-    // Width of an element.
-    uint32 width = 8;
-
-    // Width relative to content or parent Element
-    RelativeSize relative_width = 23;
-  }
-
-  // This Element's requested height.
-  // If this is not set, use the parent container's default child height.
-  oneof height_spec {
-    // Constant height in DP
-    uint32 height = 9;
-
-    // Height relative to content or parent Element
-    RelativeSize relative_height = 24;
-  }
-
-  // Minimum height for an element.
-  optional uint32 min_height = 10;
-
-  // Maximum number of text lines to display
-  optional uint32 max_lines = 11;
-
-  // If there is a background fill, allow the background (including borders) to
-  // have rounded corners.
-  optional RoundedCorners rounded_corners = 12;
-
-  // Opacity. This affects the element with the current style, and also all its
-  // descendants. For example, Opacity of a GridRow will affect all the
-  // GridCells under it, and their descendants. This value comes on top of the
-  // alpha value of colors.
-  // Values between [0..1] are valid; those outside this range will be clamped.
-  optional float opacity = 13 [default = 1.0];
-
-  // Defines a shadow for an element.
-  optional Shadow shadow = 14;
-
-  // Scale type for images
-  // This may not be supported for images in ChunkedText for all platforms.
-  optional Image.ScaleType scale_type = 18 [default = CENTER_INSIDE];
-
-  // Horizontal gravity of this element's content within the parent container
-  // Not respected in GridRow
-  optional GravityHorizontal gravity_horizontal = 19;
-
-  // Vertical gravity of this element's content within the parent container
-  // Not respected in ElementList
-  optional GravityVertical gravity_vertical = 20;
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// Various configuration parameters for image loading
-message ImageLoadingSettings {
-  // If this is set, images will fade in after loading asynchronously.
-  // May not be supported on all platforms.
-  optional bool fade_in_image_on_load = 1;
-
-  oneof preload {
-    // Defines a placeholder fill applied before an image loads.
-    // This will be replaced by the Image when it loads asynchronously.
-    // Not relevant for platforms where image loading is synchronous.
-    Fill pre_load_fill = 2;
-
-    // Defines a placeholder image applied before an image loads.
-    // This will be replaced by the Image when it loads asynchronously.
-    // This should be an on-device asset; it doesn't make sense to have the pre-
-    // load image also load asynchronously.
-    // Not relevant for platforms where image loading is synchronous.
-    Image pre_load_image = 3;
-  }
-}
-
-// Style that can be bound to an element. Not all style attributes can be bound
-// due to performance (specifically, this affects view recycling).
-//
-// PLEASE NOTE: Field names inside this message should bear the exact same names
-//     as their counterparts in the Style message.
-// LINT.IfChange
-message BoundStyle {
-  // See comments for Style.color.
-  optional fixed32 color = 1;
-
-  // See comments for Style.background.
-  optional Fill background = 2;
-
-  // See comments for Style.image_loading_settings
-  optional ImageLoadingSettings image_loading_settings = 4;
-
-  // See comments for Style.scale_type
-  optional Image.ScaleType scale_type = 5;
-}
-// LINT.ThenChange
-
-// Set a dimension relative to content or parent.
-// If a parent's size is set to FIT_CONTENT, and the child's size is
-// set to FILL_PARENT, the resulting size of the child should be the size of
-// the child's content.
-enum RelativeSize {
-  // Undefined behavior; use the default dimensions specified by the parent
-  // container.
-  RELATIVE_SIZE_UNDEFINED = 0;
-
-  // Make this Element request just as much space as its content requires.
-  FIT_CONTENT = 1;
-
-  // Make this Element request to fill whatever space is allocated to it.
-  FILL_PARENT = 2;
-}
-
-// Horizontal alignment of text within a TextElement.
-enum TextAlignmentHorizontal {
-  // This value should never be used.
-  TEXT_ALIGNMENT_HORIZONTAL_UNSPECIFIED = 0;
-
-  // Align with the start side (left in LTR layouts)
-  TEXT_ALIGNMENT_START = 1;
-
-  // Align with the end side (right in LTR layouts)
-  TEXT_ALIGNMENT_END = 2;
-
-  // Align centered
-  TEXT_ALIGNMENT_CENTER = 3;
-}
-
-// Vertical alignment of text within a TextElement.
-enum TextAlignmentVertical {
-  // This value should never be used.
-  TEXT_ALIGNMENT_VERTICAL_UNSPECIFIED = 0;
-
-  // Align top edge of text to top edge of element
-  TEXT_ALIGNMENT_TOP = 1;
-
-  // Align bottom edge of text to bottom edge of element
-  TEXT_ALIGNMENT_BOTTOM = 2;
-
-  // Align centered vertically
-  TEXT_ALIGNMENT_MIDDLE = 3;
-}
-
-// Font definitions for text elements. In the interest of preserving
-// consistency, feature authors are highly encouraged to use Fonts as part of a
-// Style, instead of applying font definitions to individual elements.
-message Font {
-  // The size of the text in scaled pixels (sp). For devices with a scaling
-  // factor of 1.0, this size is equivalent to display pixels.
-  // Certain OS-level accessibility features allow users to increase/decrease
-  // font size by a scaling factor (e.g. iOS > Dynamic Type, or Android Settings
-  // > Font Size, or Android > Accessibility > Large Text). If the user has
-  // turned on text scaling, the Host App should apply that scaling factor to
-  // this numeric font size before rendering.
-  // Note that other related metrics such as width and height are NOT
-  // automatically scaled, but line height does scale.
-  optional int32 size = 1 [default = 14];
-
-  // Line height, expressed as a multiple of size (hence the `_ratio` suffix).
-  // The default value of 1.2 is intended to work well for most scenarios
-  // without requiring feature authors to specify this explicitly.
-  // Behavior matches that of CSS: extra space appears between lines and evenly
-  // split above and below a block of text.
-  // For example, if the ratio is 2.0 and the text is 12pt tall, there will be
-  // 12pt of space between each pair of lines, and 6pt of space above and below
-  // the block of text.
-  // This field is deprecated. Please use line_height instead.
-  // TODO Remove this field once the transition to line_height
-  // is complete.
-  optional float line_height_ratio = 2 [default = 1.2, deprecated = true];
-
-  // Line height, expressed as scale-independent pixels (sp), meaning that it
-  // scales with accessibility settings. If no line height is specified, the
-  // default spacing for that font will be used. This is usually
-  // approximately 1.2 times the height of the text, and should work well for
-  // most platforms. Using the default does not guarantee the same height across
-  // platforms; if that is needed, an explicit line height should be set.
-  // Because line_height_ratio is deprecated, if both are specified, only
-  // line_height will be used.
-  optional uint32 line_height = 7;
-
-  // Material Design specifies six weights for a font, in order from thinnest
-  // stroke to thickest stroke. Orthogonal to weight, a font can be either
-  // normal or italic. Not all weights may be supported by every typeface or
-  // every platform; see [INTERNAL LINK]
-  enum FontWeight {
-    // Unspecified font weight.
-    FONT_WEIGHT_UNSPECIFIED = 0;
-
-    // Thinnest font weight.
-    THIN = 1;
-
-    // Light font weight.
-    LIGHT = 2;
-
-    // Regular font weight (this is the default).
-    REGULAR = 3;
-
-    // Medium font weight.
-    MEDIUM = 4;
-
-    // Bold font weight.
-    BOLD = 5;
-
-    // Black (extra-bold) font weight.
-    BLACK = 6;
-  }
-
-  // The font weight (boldness) to apply to the text.
-  // This field is deprecated. Please use a Typeface, and either choose a
-  // CommonFont, which has the weight built in, or include the weight as part of
-  // the style definition for a custom_font.
-  optional FontWeight weight = 3 [default = REGULAR, deprecated = true];
-
-  // Apply the italic style to the Font.
-  optional bool italic = 4;
-
-  // Sets text letter spacing in dp. This indicates how much space will be
-  // added between characters. Negative values tighten text, whereas positive
-  // values increase space between letters. Also known as “tracking” in
-  // typography, or “character spacing” in image editing tools.
-  optional float letter_spacing_dp = 9;
-
-  // The typeface to use, e.g. "roboto", "open-sans", or "product-sans".
-  // Multiple typefaces can be specified by the server, and the first one that
-  // is available on the client will be used. If none match, or if no typefaces
-  // are specified, then ERR_FONT_UNAVAILABLE is raised, and the system default
-  // typeface on each platform will be used. Each typeface’s name is a custom
-  // string, and should be negotiated between server and client to ensure that
-  // typefaces requested by the server are available on the client. Piet
-  // provides no way to request that a particular font face be downloaded at
-  // runtime; this should be done out-of-band if required.
-  // This field is deprecated. Please use the typeface field that uses a
-  // Typeface message instead.
-  repeated string typefaces = 6 [deprecated = true];
-
-  // The typeface to use. Each typeface specified can either be a CommonTypeface
-  // or a string naming a custom typeface. The CommonTypeface actually pairs
-  // commonly-used typefaces with weights. The custom one can be used to
-  // identify any typeface. Multiple typefaces can be specified by the server,
-  // and the first one that is available on the client will be used. If none
-  // match, or if no typefaces are specified, then ERR_FONT_UNAVAILABLE is
-  // raised, and the system default typeface on each platform will be used. Piet
-  // provides no way to request that a particular font face be downloaded at
-  // runtime; this should be done out-of-band if required.
-  repeated Typeface typeface = 8;
-
-  // Deprecated field IDs, do not reuse.
-  reserved 5;
-}
-
-message Typeface {
-  // Defines a commonly-used typeface, paired with a weight. "PLATFORM_DEFAULT_"
-  // uses the system default typeface on each platform, and sets the weight.
-  // Google Sans is a cross-platform typeface that should render well on all
-  // platforms. Note that Google Sans will only work if the client has bundled
-  // it in properly.
-  enum CommonTypeface {
-    // The same as PLATFORM_DEFAULT_REGULAR.
-    UNDEFINED = 0;
-
-    PLATFORM_DEFAULT_LIGHT = 1;
-
-    PLATFORM_DEFAULT_REGULAR = 2;
-
-    PLATFORM_DEFAULT_MEDIUM = 3;
-
-    GOOGLE_SANS_REGULAR = 4;
-
-    GOOGLE_SANS_MEDIUM = 5;
-  }
-
-  oneof typeface_specifier {
-    // Commonly used typefaces (with weights).
-    CommonTypeface common_typeface = 1;
-
-    // Any typeface needed that is not included in CommonTypeface should be
-    // specified as a string here. Piet does not provide these typefaces, or any
-    // way to download them at runtime. The host is meant to perform the lookup
-    // and provide the correct typeface to Piet for rendering. If
-    // platform-specific typefaces are needed, the string can be an identifier
-    // (i.e. "group_of_typefaces_for_feature"), and each platform can look up
-    // what that translates to. Piet will NOT parse the custom_typeface string
-    // to set attributes such as font weight.
-    string custom_typeface = 2;
-  }
-}
-
-// Definition of a Border.
-message Border {
-  option deprecated = true;
-
-  // The color of the border.
-  optional fixed32 color = 1;
-
-  // The thickness of the border in DP.
-  optional int32 width = 2;
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// A set of four Borders for all four edges of a view.
-// NextId: 8
-message Borders {
-  enum Edges {
-    // If unspecified, then all edges will have borders.
-    EDGES_UNSPECIFIED = 0;
-
-    // Indicates that the start side of the item should have a border
-    START = 0x1;
-
-    // Indicates that the top side of the item should have a border
-    TOP = 0x2;
-
-    // Indicates that the end side of the item should have a border
-    END = 0x4;
-
-    // Indicates that the bottom side of the item should have a border
-    BOTTOM = 0x8;
-  }
-
-  // A bitmask representing which sides should have borders. Bit values are
-  // defined by the `Edges` enum. If no sides are specified (the default), then
-  // all sides will have a border.
-  //
-  // NOTICE: having a rounded corner with a border only on one side is strongly
-  // discouraged as it leads to undefined and inconsistent behavior across
-  // platforms.
-  optional int32 bitmask = 5;
-
-  // The color of the border.
-  optional fixed32 color = 6;
-
-  // Width of the border.
-  optional int32 width = 7;
-
-  // Top border.
-  optional Border top = 1 [deprecated = true];
-
-  // Bottom border.
-  optional Border bottom = 2 [deprecated = true];
-
-  // Border for leading edge (left for LTR languages; right for RTL).
-  optional Border start = 3 [deprecated = true];
-
-  // Border for trailing edge (right for LTR languages; left for RTL).
-  optional Border end = 4 [deprecated = true];
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// A set of four values for widths of the edges of a view, used for
-// paddings/margins.
-message EdgeWidths {
-  // Top boundary.
-  optional uint32 top = 1;
-
-  // Bottom boundary.
-  optional uint32 bottom = 2;
-
-  // Boundary for leading edge (left for LTR languages; right for RTL).
-  optional uint32 start = 3;
-
-  // Boundary for trailing edge (right for LTR languages; left for RTL).
-  optional uint32 end = 4;
-}
-
-// Specifies gravity on the horizontal axis.
-enum GravityHorizontal {
-  GRAVITY_HORIZONTAL_UNSPECIFIED = 0;
-
-  // Align with the start side (left in LTR layouts)
-  GRAVITY_START = 1;
-
-  // Align with the end side (right in LTR layouts)
-  GRAVITY_END = 2;
-
-  // Align centered
-  GRAVITY_CENTER = 3;
-}
-
-// Specifies gravity on the vertical axis.
-enum GravityVertical {
-  GRAVITY_VERTICAL_UNSPECIFIED = 0;
-
-  // Align with the top side
-  GRAVITY_TOP = 1;
-
-  // Align vertically centered
-  GRAVITY_MIDDLE = 2;
-
-  // Align with the bottom side
-  GRAVITY_BOTTOM = 3;
-}
diff --git a/components/feed/core/proto/ui/piet/text.proto b/components/feed/core/proto/ui/piet/text.proto
deleted file mode 100644
index 725c4e8..0000000
--- a/components/feed/core/proto/ui/piet/text.proto
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-import "components/feed/core/proto/ui/piet/actions.proto";
-import "components/feed/core/proto/ui/piet/binding_refs.proto";
-import "components/feed/core/proto/ui/piet/images.proto";
-import "components/feed/core/proto/ui/piet/styles.proto";
-
-package components.feed.core.proto.ui.piet;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.piet";
-option java_outer_classname = "TextProto";
-option cc_enable_arenas = true;
-
-// ParameterizedText allows strings to be constructed on the client based on
-// rapidly-changing information for which a server round-trip is not
-// appropriate. Clients will build a string at runtime by combining the
-// parameterized string with the values of the evaluated parameters.
-message ParameterizedText {
-  // A string that may (but need not always) include placeholders for
-  // parameters.
-  //
-  // If parameters are specified, placeholders use the simplest standard C or
-  // Java string format specifier: "%s". All other instances of the "%"
-  // character must be escaped with another "%" character. If there are no
-  // parameters, this string is used directly, without replacements. The number
-  // of placeholders must correspond to the number of parameters provided. The
-  // order of `parameters` is significant; parameters are replaced in the string
-  // in the order specified.
-  //
-  // The server is responsible for localizing this string for the target locale;
-  // the client expects to receive only a single string for the current locale.
-  // Any pluralization (["zero" | "one" | "two" | "few" | "many" | "other"])
-  // should be done by the server at serving time, and is not handled by the
-  // client.
-  optional string text = 1;
-
-  // Strings are considered to be plain text by default, for performance
-  // reasons. A string is parsed as HTML if and only if this field is explicitly
-  // set to true.
-  // TODO: Document the white-listed set of tags, and ensure this
-  // content is correctly sanitized on all supported platforms.
-  optional bool is_html = 2 [default = false];
-
-  // A parameter to be substituted in the ParameterizedText. Every type of
-  // parameter depends on some information only available on the client at
-  // rendering time, and not on the server at card and string creation time. In
-  // particular, if the value can be determined on the server, it should be
-  // inlined in the string on the server.
-  message Parameter {
-    // The parameter type.
-    oneof parameter_types {
-      // An absolute timestamp in seconds since the Unix epoch.
-      int64 timestamp_seconds = 1;
-
-      // A location to be used for computing relative distances or travel times.
-      Location location = 2;
-    }
-  }
-
-  // An ordered list of parameters.
-  repeated Parameter parameters = 3;
-}
-
-// A location, expressed as a { latitude, longitude } tuple. This is used to
-// generate a string that describes the distance between the user’s current
-// location and the specified location in relative terms, e.g. “10 meters away”,
-// or “20 minutes away”.
-//
-// Since Piet is a presentational language (not semantic), this Location should
-// only contain the fields necessary for accurate display. Specifically, other
-// fields such as physical addresses, labels, titles, or feature names should
-// not be added here.
-//
-// Both latitude and longitude are specified as double-precision floats. The
-// worst case real-world distance expressed in this format is ~1-4 meters at the
-// equator.
-message Location {
-  // Latitude for this location.
-  optional double latitude = 1;
-
-  // Longitude for this location.
-  optional double longitude = 2;
-}
-
-// ChunkedText allows composing a single string of multiple chunks with
-// different formatting. In addition to this, a chunk can also be composed of an
-// image that gets inlined with the surrounding text chunks. Image chunks are
-// aligned to the text baseline. Chunked text flows independently from the
-// chunked regions. Line wrapping is supported across different chunks. For
-// example a string composed of three chunks that needs to be wrapped in two
-// lines will be wrapped as follows:
-// [[chunk a] [image] [chunk]]
-// [[b]]
-message ChunkedText {
-  // The set of chunks that compose this chunked text.
-  repeated Chunk chunks = 1;
-}
-
-// A single region of content within a ChunkedText. A chunk can either be
-// composed of an image or a styled text chunk.
-message Chunk {
-  // The content of the Chunk.
-  oneof content {
-    // A styled piece of text content.
-    StyledTextChunk text_chunk = 1;
-
-    // A styled piece of image content.
-    StyledImageChunk image_chunk = 2;
-  }
-
-  // Defines Actions that may be associated with this chunk, e.g. for creating
-  // clickable links or images within text. The server is responsible for
-  // ensuring that the size of this content is large enough to present a clear
-  // click target for the user.
-  // NOTE: on_partial_view is not supported for Chunks.
-  oneof actions_data {
-    // Inlined actions.
-    Actions actions = 3;
-
-    // Actions from a template, bound at runtime.
-    ActionsBindingRef actions_binding = 4;
-  }
-}
-
-// A single region of image content that has a particular style applied to it.
-message StyledImageChunk {
-  // Styles applied to this chunk.
-  optional StyleIdsStack style_references = 1;
-
-  // Content for this StyledImageChunk.
-  oneof content {
-    // The binding to the BindingValue for an Image.
-    ImageBindingRef image_binding = 2;
-
-    // The image to be displayed.
-    Image image = 3;
-  }
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// A single region of text content that has styles applied to it.
-message StyledTextChunk {
-  // Styles applied to this chunk.
-  optional StyleIdsStack style_references = 1;
-
-  // Content for this StyledTextChunk.
-  oneof content {
-    // The binding to the BindingValue for a ParameterizedText.
-    ParameterizedTextBindingRef parameterized_text_binding = 2;
-
-    // The text to display.
-    ParameterizedText parameterized_text = 3;
-  }
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
diff --git a/components/feed/core/proto/ui/stream/stream_offline_extension.proto b/components/feed/core/proto/ui/stream/stream_offline_extension.proto
deleted file mode 100644
index 00af1eb4..0000000
--- a/components/feed/core/proto/ui/stream/stream_offline_extension.proto
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.stream;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/ui/piet/elements.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.ui.stream";
-option java_outer_classname = "StreamOfflineExtensionProto";
-option cc_enable_arenas = true;
-
-// Extension for Piet bindings content based on offline availability status.
-message OfflineExtension {
-  extend components.feed.core.proto.ui.piet.HostBindingData {
-    optional OfflineExtension offline_extension = 208815589;
-  }
-
-  // The URL that determines which binding to use. If the URL is available
-  // offline, then offline_binding should be used, otherwise
-  // not_offline_binding should be used.
-  optional string url = 1;
-
-  optional components.feed.core.proto.ui.piet.BindingValue offline_binding = 2;
-  optional components.feed.core.proto.ui.piet.BindingValue not_offline_binding =
-      3;
-}
diff --git a/components/feed/core/proto/ui/stream/stream_structure.proto b/components/feed/core/proto/ui/stream/stream_structure.proto
deleted file mode 100644
index f7d4389..0000000
--- a/components/feed/core/proto/ui/stream/stream_structure.proto
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.ui.stream;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/ui/piet/piet.proto";
-import "components/feed/core/proto/wire/content_id.proto";
-import "components/feed/core/proto/wire/feature.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.ui.stream";
-option java_outer_classname = "StreamStructureProto";
-option cc_enable_arenas = true;
-
-// Top level feature which shows a stream of cards.  Provides any UI information
-// which may be needed in order to render the stream of cards.
-message Stream {
-  extend feedwire1.Feature { optional Stream stream_extension = 185431437; }
-
-  // Empty for now as don't support any custom information.
-}
-
-// Feature which represents a cluster in a Stream. May have a Card or Content
-// as children.
-message Cluster {
-  extend feedwire1.Feature { optional Cluster cluster_extension = 190812910; }
-
-  // Empty for now as we don't support any custom information.
-}
-
-// Experimental feature which represents a carousel in a Stream. May have a list
-// of Cards or Content as children.
-message Carousel {
-  extend feedwire1.Feature { optional Carousel carousel_extension = 244251946; }
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// Feature which represents a full card in a Stream.  Allows metadata to be sent
-// to describe how to render the card.
-message Card {
-  extend feedwire1.Feature { optional Card card_extension = 185431438; }
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// Metadata object providing basic information for logging content.
-message BasicLoggingMetadata {
-  // Score given by NowStream
-  optional float score = 2;
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-
-  reserved 1;
-}
-
-message RepresentationData {
-  // URI (usually a URL) of what the content links to
-  optional string uri = 1;
-
-  // Time when content was published
-  optional int64 published_time_seconds = 2;
-}
-
-message OfflineMetadata {
-  // Title of the content.
-  optional string title = 1;
-
-  // Url for image for the content.
-  optional string image_url = 2;
-
-  // Publisher of the content.
-  optional string publisher = 3;
-
-  // Url for the favicon for the content.
-  optional string favicon_url = 4;
-
-  // Short string from the content, typically the start of an article.
-  optional string snippet = 5;
-}
-
-// Feature which is able to show actual content in a stream. This could be
-// inside or outside a card. Actual data on what to display will be sent on an
-// extension.
-message Content {
-  extend feedwire1.Feature { optional Content content_extension = 185431439; }
-
-  enum Type {
-    UNKNOWN_CONTENT = 0;
-    PIET = 1;
-  }
-  optional Type type = 1;
-  optional BasicLoggingMetadata basic_logging_metadata = 2;
-  optional RepresentationData representation_data = 3;
-  optional OfflineMetadata offline_metadata = 4;
-
-  // Please use CL numbers you own for extension numbers.
-  extensions 10000 to max;
-}
-
-// Content which is able to show a Piet frame. This includes any data which may
-// be needed to show a Piet frame.
-message PietContent {
-  extend Content { optional PietContent piet_content_extension = 185431440; }
-
-  // Content Ids of Piet Shared States which should be provided to Piet in order
-  // to show its content.
-  repeated feedwire1.ContentId piet_shared_states = 1;
-
-  // The Piet frame to render.
-  optional components.feed.core.proto.ui.piet.Frame frame = 2;
-}
diff --git a/components/feed/core/proto/ui/stream/stream_swipe_extension.proto b/components/feed/core/proto/ui/stream/stream_swipe_extension.proto
deleted file mode 100644
index d5689c7..0000000
--- a/components/feed/core/proto/ui/stream/stream_swipe_extension.proto
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-import "components/feed/core/proto/ui/action/feed_action_payload.proto";
-import "components/feed/core/proto/ui/stream/stream_structure.proto";
-package components.feed.core.proto.ui.stream;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.ui.stream";
-option java_outer_classname = "StreamSwipeExtensionProto";
-option cc_enable_arenas = true;
-
-// Extension for cards that are swipeable. Allows action to be set for execution
-// when the card is swiped.
-message SwipeActionExtension {
-  extend components.feed.core.proto.ui.stream.Card {
-    optional SwipeActionExtension swipe_action_extension = 196559392;
-  }
-
-  optional components.feed.core.proto.ui.action.FeedActionPayload swipe_action =
-      1;
-}
diff --git a/components/feed/core/proto/wire/action_payload.proto b/components/feed/core/proto/wire/action_payload.proto
deleted file mode 100644
index 96c49df5..0000000
--- a/components/feed/core/proto/wire/action_payload.proto
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "ActionPayloadProto";
-
-// The data needed by the server to handle action recording. This information is
-// opaque to the client and will be the information that is roundtripped so the
-// server can properly handle the action. For the Not Interested In action, this
-// data will contain the ids needed to record that the user is not interested
-// in that particular topic or source.
-// NOTE: it is important to keep this to a bare minimum amount of data.
-message ActionPayload {
-  // Reserved fields for renderable unit extensions
-  // Please use CL numbers you own for extension numbers.
-  extensions 1 to 2;
-}
diff --git a/components/feed/core/proto/wire/action_payload_for_test.proto b/components/feed/core/proto/wire/action_payload_for_test.proto
deleted file mode 100644
index 0eef92775..0000000
--- a/components/feed/core/proto/wire/action_payload_for_test.proto
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/wire/action_payload.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "ActionPayloadForTestProto";
-
-// A proto that extends feed_action.ActionPayload and carries data associated
-// with the not interested in action.
-message ActionPayloadForTest {
-  // The mid that represents the topic of the story on the card
-  optional string id = 1;
-
-  extend feedwire1.ActionPayload {
-    optional ActionPayloadForTest action_payload_for_test_extension = 2;
-  }
-}
diff --git a/components/feed/core/proto/wire/action_request.proto b/components/feed/core/proto/wire/action_request.proto
deleted file mode 100644
index 78b000bb..0000000
--- a/components/feed/core/proto/wire/action_request.proto
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "ActionRequestProto";
-
-// Top level request message.
-message ActionRequest {
-  // Supported versions of request messages are specified as extensions to
-  // the top-level request message.  An enum is used to denote the expected
-  // extensions for this request.
-  enum RequestVersion {
-    UNKNOWN_ACTION_REQUEST_VERSION = 0;
-    FEED_UPLOAD_ACTION = 1;
-  }
-  optional RequestVersion request_version = 1;
-
-  // Reserved fields for extensions
-  extensions 1000 to max;
-}
diff --git a/components/feed/core/proto/wire/action_type.proto b/components/feed/core/proto/wire/action_type.proto
deleted file mode 100644
index f0e8fd6..0000000
--- a/components/feed/core/proto/wire/action_type.proto
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "ActionTypeProto";
-
-// The specific action that was performed on an feature described by a ContentId
-// and SemanticProperties.
-enum ActionType {
-  UNKNOWN_ACTION_TYPE = 0;
-  DISMISS = 1;
-}
diff --git a/components/feed/core/proto/wire/capability.proto b/components/feed/core/proto/wire/capability.proto
deleted file mode 100644
index a53a8ea..0000000
--- a/components/feed/core/proto/wire/capability.proto
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "CapabilityProto";
-
-// Feature capability of either the client or the server.
-// Next ID: 16.
-enum Capability {
-  UNKNOWN_CAPABILITY = 0;
-  BASE_UI = 1;
-  FEED_UI = 2;
-  UNDOABLE_ACTIONS = 4;
-  MANAGE_INTERESTS = 5;
-  CARD_MENU_TOOLTIP = 6;
-  USE_SECONDARY_PAGE_REQUEST = 7;
-  ARTICLE_SNIPPETS = 8;
-  CAROUSELS = 9;
-  ELEMENTS = 10;
-  SEND_FEEDBACK = 12;
-  CLICK_ACTION = 13;
-  VIEW_ACTION = 14;
-  REPORT_FEED_USER_ACTIONS_NOTICE_CARD = 15;
-
-  reserved 3, 11;
-}
diff --git a/components/feed/core/proto/wire/chrome_fulfillment_info.proto b/components/feed/core/proto/wire/chrome_fulfillment_info.proto
deleted file mode 100644
index e78acba..0000000
--- a/components/feed/core/proto/wire/chrome_fulfillment_info.proto
+++ /dev/null
@@ -1,20 +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.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "ChromeFulfillmentInfoProto";
-
-// Information on how to do content fulfillment for Chrome.
-message ChromeFulfillmentInfo {
-  // Whether the notice card has already been acknowledged by the user based on
-  // their views and clicks on the card. This is different from when the user
-  // explicitly dismiss the notice card by touching the button.
-  optional bool notice_card_acknowledged = 1;
-}
diff --git a/components/feed/core/proto/wire/client_info.proto b/components/feed/core/proto/wire/client_info.proto
deleted file mode 100644
index c395cca3..0000000
--- a/components/feed/core/proto/wire/client_info.proto
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/wire/display_info.proto";
-import "components/feed/core/proto/wire/version.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "ClientInfoProto";
-
-// Information about the client performing the request similar to a user-agent
-// string in HTTP.
-// Next ID: 7.
-message ClientInfo {
-  enum PlatformType {
-    UNKNOWN_PLATFORM = 0;
-    ANDROID_ID = 1;  // ANDROID collides with a C++ preprocessor macro.
-    IOS = 2;
-  }
-
-  enum AppType {
-    UNKNOWN_APP = 0;
-    GSA = 1;
-    CHROME = 2;
-    TEST_APP = 3;
-  }
-
-  // The type of OS that the client is running.
-  optional PlatformType platform_type = 1;
-
-  // The version of the OS that the client is running.
-  optional Version platform_version = 2;
-
-  // The type of client app.
-  optional AppType app_type = 3;
-
-  // The version of the client app.
-  optional Version app_version = 4;
-
-  // A string identifying the language and region preferences of the client.
-  // Follows the BCP 47 format such as "en-US" or "fr-CA"
-  optional string locale = 5;
-
-  // The information about the screen of the client. This is repeated because
-  // there are some devices that might have multiple display screens.
-  // (Ex foldable phones)
-  repeated DisplayInfo display_info = 6;
-}
diff --git a/components/feed/core/proto/wire/consistency_token.proto b/components/feed/core/proto/wire/consistency_token.proto
deleted file mode 100644
index 4b7b209..0000000
--- a/components/feed/core/proto/wire/consistency_token.proto
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "ConsistencyTokenProto";
-
-// A consistency token.
-message ConsistencyToken {
-  // Indicates the min version of storage to read from.
-  optional bytes token = 1;
-}
diff --git a/components/feed/core/proto/wire/content_id.proto b/components/feed/core/proto/wire/content_id.proto
deleted file mode 100644
index 51ba333..0000000
--- a/components/feed/core/proto/wire/content_id.proto
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "ContentIdProto";
-
-// Feed Wire Protocol version of the ContentId.
-message ContentId {
-  // The "domain" to which this content belongs. A domain specifies the party
-  // responsible for generating the content, and this owner promises to specify
-  // IDs (below) that match the owner's expectations of uniqueness.  The domain
-  // differs from the table because multiple parties can create content which
-  // are stored in the same table.
-  optional string content_domain = 1;
-
-  // In value to make the ContentId unique within the content_domain.
-  optional fixed64 id = 2;
-
-  // This represents namespace for the nodes found in the wire protocol.  The
-  // storage architecture shares the wire protocol based upon the Table
-  // (namespace).  The storage will be sharded into multiple Tables where
-  // related content is stored within a single Table.  For example, Features
-  // define the Structure and Content of the Stream and are stored in a single
-  // table.  Notifications would be stored in their own table.
-  optional string table = 3;
-}
diff --git a/components/feed/core/proto/wire/data_operation.proto b/components/feed/core/proto/wire/data_operation.proto
deleted file mode 100644
index a917619b..0000000
--- a/components/feed/core/proto/wire/data_operation.proto
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-import "components/feed/core/proto/wire/feature.proto";
-import "components/feed/core/proto/wire/payload_metadata.proto";
-import "components/feed/core/proto/ui/piet/piet.proto";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "DataOperationProto";
-
-// An extensible operation to change the state of data on the client.
-message DataOperation {
-  enum Operation {
-    UNKNOWN_OPERATION = 0;
-    // Remove all stored content of all types
-    CLEAR_ALL = 1;
-    // Update content if it exists, else append to the bottom of the feed
-    UPDATE_OR_APPEND = 2;
-    // Remove the item from the stream
-    REMOVE = 3;
-  }
-
-  // The operation to perform on the data.
-  optional Operation operation = 1;
-
-  // Data common to all payload types.
-  optional PayloadMetadata metadata = 2;
-
-  // The actual data being supplied.
-  oneof payload {
-    // A stream UI level feature such as a cluster or card.
-    Feature feature = 3;
-    // Shared state for all Piet cards
-    components.feed.core.proto.ui.piet.PietSharedState piet_shared_state = 4;
-  }
-}
diff --git a/components/feed/core/proto/wire/display_info.proto b/components/feed/core/proto/wire/display_info.proto
deleted file mode 100644
index 7d0a2db..0000000
--- a/components/feed/core/proto/wire/display_info.proto
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "DisplayInfoProto";
-
-// The information about the client's screen.
-// Next id: 4
-message DisplayInfo {
-  // Density of the screen in physical pixels per density independent pixel
-  // (DIP); see:
-  // http://developer.android.com/reference/android/util/DisplayMetrics.html#density
-  optional float screen_density = 1;
-
-  // The width of the screen in pixels.
-  optional uint32 screen_width_in_pixels = 2;
-
-  // The height of the screen in pixels.
-  optional uint32 screen_height_in_pixels = 3;
-}
diff --git a/components/feed/core/proto/wire/feature.proto b/components/feed/core/proto/wire/feature.proto
deleted file mode 100644
index 24741223..0000000
--- a/components/feed/core/proto/wire/feature.proto
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/wire/content_id.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "FeatureProto";
-
-// Features define both the structure and content found in the Stream.
-message Feature {
-  // The ContentId identifying the parent feature for this feature.
-  optional ContentId parent_id = 1;
-
-  // Enum denoting which extension containing the renderable data is associated
-  // with this Feature.
-  enum RenderableUnit {
-    UNKNOWN_RENDERABLE_UNIT = 0;
-    STREAM = 1;
-    CARD = 2;
-    CONTENT = 3;
-    CLUSTER = 4;
-    TOKEN = 5;
-    // Note: This is an experimental feature.
-    CAROUSEL = 6;
-  }
-  optional RenderableUnit renderable_unit = 2;
-
-  // Reserved fields for renderable unit extensions
-  // Please use CL numbers you own for extension numbers.
-  extensions 1000 to max;
-}
diff --git a/components/feed/core/proto/wire/feed_action.proto b/components/feed/core/proto/wire/feed_action.proto
deleted file mode 100644
index 2c6cb942..0000000
--- a/components/feed/core/proto/wire/feed_action.proto
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/wire/action_payload.proto";
-import "components/feed/core/proto/wire/content_id.proto";
-import "components/feed/core/proto/wire/semantic_properties.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "FeedActionProto";
-
-message FeedAction {
-  // The Id for the content that this action was triggered on.
-  optional ContentId content_id = 1;
-  // Additional logging data that is on a per-action level
-  optional ActionPayload action_payload = 4;
-  // Client-generated data that pertains to the action.
-  optional ClientData client_data = 5;
-  // Fields beyond ID needed to determine uniqueness for the card or collection.
-  // Opaque to the client, round-tripped from the server.
-  optional SemanticProperties semantic_properties = 6;
-  // Next Id: 7
-  reserved 2, 3;
-
-  // The data the client provides to the server.
-  message ClientData {
-    // When the action was recorded on the client
-    optional int64 timestamp_seconds = 1;
-
-    // A monotonically-increasing sequence number that increments per
-    // user + device. Used in experiments to measure action loss between client
-    // and server.
-    optional int64 sequence_number = 2;
-
-    // The duration for the action in milliseconds. In case of view actions this
-    // is the duration for which the content is considered "viewed".
-    optional int64 duration_ms = 3;
-
-    enum ActionOrigin {
-      UNKNOWN_ORIGIN = 0;
-      // Action generated from the current session on the client.
-      CLIENT_SESSION = 1;
-      // Action was previously cached on the client.
-      CLIENT_CACHE = 2;
-    }
-
-    // The surface an action was taken on.
-    enum ActionSurface {
-      UNKNOWN_SURFACE = 0;
-      ANDROID_CHROME_NEW_TAB = 7;
-    }
-
-    // What surface the action came from - AGA, iGA, -1, secondary screen etc.
-    optional ActionSurface action_surface = 5;
-
-    // Where the action came from on the client.
-    // Optional: This field is purely for diagnostics.
-    optional ActionOrigin action_origin = 4;
-  }
-}
diff --git a/components/feed/core/proto/wire/feed_action_query_data.proto b/components/feed/core/proto/wire/feed_action_query_data.proto
deleted file mode 100644
index 46cd59c..0000000
--- a/components/feed/core/proto/wire/feed_action_query_data.proto
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-import "components/feed/core/proto/wire/action_type.proto";
-import "components/feed/core/proto/wire/semantic_properties.proto";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "FeedActionQueryDataProto";
-
-// The combination of FeedActionQueryData and FeedActionQueryDataItem provide a
-// transport format that can send each unique action, id, content domain, table,
-// and semantic properties exactly once. This de-duplication allows the maximum
-// amount of data to be sent from the client in the absence of compression.
-// This data can then be mapped back into ContentId and SemanticProperties with
-// high fidelity.
-message FeedActionQueryData {
-  // The specific action that was performed on the client.
-  optional Action action = 1;
-
-  // A unique set of ids associated with the content.
-  repeated fixed64 unique_id = 2;
-
-  // A unique set of content domains associated with the content.
-  repeated string unique_content_domain = 3;
-
-  // A unique set of tables associated with the content.
-  repeated string unique_table = 4;
-
-  // A unique set of SemanticProperties associated with the content that the
-  // action was performed on. This data is not altered by the client.
-  repeated SemanticProperties unique_semantic_properties = 5;
-
-  // The content that the action was performed on. The identity of the content
-  // can be created by combining unique_id, unique_content_domain, and
-  // unique_table.
-  repeated FeedActionQueryDataItem feed_action_query_data_item = 6;
-}
-
-// Data describing the individual content that was acted upon.
-message FeedActionQueryDataItem {
-  // An index into the unique_id field in FeedActionQueryData.
-  optional int32 id_index = 1;
-
-  // An index into the unique_content_domain field in FeedActionQueryData.
-  optional int32 content_domain_index = 2;
-
-  // An index into the unique_table field in FeedActionQueryData.
-  optional int32 table_index = 3;
-
-  // An index into the unique_semantic_properties field in FeedActionQueryData.
-  optional int32 semantic_properties_index = 4;
-}
-
-// Data describing the action that occurred on the client.
-message Action {
-  // The specific action that was performed.
-  optional ActionType action_type = 1;
-}
diff --git a/components/feed/core/proto/wire/feed_action_request.proto b/components/feed/core/proto/wire/feed_action_request.proto
deleted file mode 100644
index eae2935..0000000
--- a/components/feed/core/proto/wire/feed_action_request.proto
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/wire/action_request.proto";
-import "components/feed/core/proto/wire/consistency_token.proto";
-import "components/feed/core/proto/wire/feed_action.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "FeedActionRequestProto";
-
-// Request to upload new actions to the Actions Endpoint
-message FeedActionRequest {
-  extend ActionRequest {
-    optional FeedActionRequest feed_action_request = 1001;
-  }
-  // Data related to recordable actions performed on the client.
-  repeated FeedAction feed_action = 1;
-  // Token used to write to the same storage.
-  optional ConsistencyToken consistency_token = 2;
-
-  // Diagnostic information about the current state of the client.
-  optional DiagnosticInfo diagnostic_info = 3;
-
-  // Diagnostics from the client.
-  message DiagnosticInfo {
-    // Count of un-uploaded actions remaining on the client at the time
-    // of a feed content generation request.
-    optional int32 actions_remaining = 1;
-  }
-}
diff --git a/components/feed/core/proto/wire/feed_action_response.proto b/components/feed/core/proto/wire/feed_action_response.proto
deleted file mode 100644
index 4e20163..0000000
--- a/components/feed/core/proto/wire/feed_action_response.proto
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/wire/consistency_token.proto";
-import "components/feed/core/proto/wire/response.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "FeedActionResponseProto";
-
-// A feed action response returns when an action has been successfully uploaded
-// to the server.
-message FeedActionResponse {
-  extend Response { optional FeedActionResponse feed_action_response = 1001; }
-  // Token used to read or write to the same storage.
-  optional ConsistencyToken consistency_token = 1;
-}
diff --git a/components/feed/core/proto/wire/feed_query.proto b/components/feed/core/proto/wire/feed_query.proto
deleted file mode 100644
index a4bf04eb..0000000
--- a/components/feed/core/proto/wire/feed_query.proto
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/wire/chrome_fulfillment_info.proto";
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "FeedQueryProto";
-
-message FeedQuery {
-  enum RequestReason {
-    // Bucket for any not listed. Should not be used (prefer adding a new
-    // request reason)
-    UNKNOWN_REQUEST_REASON = 0;
-
-    // App is manually triggering a request, outside of scheduling a request.
-    // Should be used rarely.
-    MANUAL_REFRESH = 1;
-
-    // Host wants a request to refresh content.
-    SCHEDULED_REFRESH = 2;
-
-    // Loading more content (should be deprecated soon for more clarity behind
-    // reason).
-    NEXT_PAGE_SCROLL = 4;
-
-    // Refresh after clearing all content
-    CLEAR_ALL = 5;
-
-    // Refresh from zero state (no content)
-    ZERO_STATE_REFRESH = 6;
-
-    // Initial loading of content for a session
-    INITIAL_LOAD = 7;
-
-    // Loading new content (while displaying existing content)
-    WITH_CONTENT = 8;
-
-    reserved 3;
-  }
-
-  // The reason the query is being initiated.
-  optional RequestReason reason = 1;
-
-  // Used to fetch the next page when scrolling copied from
-  // Token.next_page_token
-  optional bytes page_token = 2;
-
-  // Information on how to do content fulfillment for Chrome.
-  optional ChromeFulfillmentInfo chrome_fulfillment_info = 3;
-}
diff --git a/components/feed/core/proto/wire/feed_request.proto b/components/feed/core/proto/wire/feed_request.proto
deleted file mode 100644
index b67a006d..0000000
--- a/components/feed/core/proto/wire/feed_request.proto
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-import "components/feed/core/proto/wire/capability.proto";
-import "components/feed/core/proto/wire/client_info.proto";
-import "components/feed/core/proto/wire/consistency_token.proto";
-import "components/feed/core/proto/wire/feed_action_query_data.proto";
-import "components/feed/core/proto/wire/feed_query.proto";
-import "components/feed/core/proto/wire/request.proto";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "FeedRequestProto";
-
-// Request to fetch new data for the feed
-message FeedRequest {
-  extend Request { optional FeedRequest feed_request = 1000; }
-  // Information about the client making the request.
-  optional ClientInfo client_info = 1;
-
-  // Query parameters to fetch feed data.
-  optional FeedQuery feed_query = 2;
-
-  // Data related to actions performed on the client.
-  repeated FeedActionQueryData feed_action_query_data = 3;
-
-  // The list of client supported capabilities.
-  repeated Capability client_capability = 4;
-
-  // Token used to read from/write to the same storage.
-  optional ConsistencyToken consistency_token = 5;
-}
diff --git a/components/feed/core/proto/wire/feed_response.proto b/components/feed/core/proto/wire/feed_response.proto
deleted file mode 100644
index ec10148..0000000
--- a/components/feed/core/proto/wire/feed_response.proto
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-import "components/feed/core/proto/wire/capability.proto";
-import "components/feed/core/proto/wire/data_operation.proto";
-import "components/feed/core/proto/wire/response.proto";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "FeedResponseProto";
-
-// A feed response is  a series of directives to manipulate backend storage,
-// similar to database commands.  Individual data operations contain all the
-// necessary information to manipulate the client state.
-message FeedResponse {
-  extend Response { optional FeedResponse feed_response = 1000; }
-  // DataOperations are applied on the client in order in which they are
-  // received.
-  repeated DataOperation data_operation = 1;
-  // Metadata for the entire FeedResponse.
-  optional FeedResponseMetadata feed_response_metadata = 2;
-
-  // The list of server-response supported capabilities.
-  repeated Capability server_capabilities = 3;
-}
-
-// Data which is relevant for the whole response made by the server.
-message FeedResponseMetadata {
-  // Time at which the server fulfilled this response. This is needed as client
-  // cannot be the source of truth.
-  optional int64 response_time_ms = 1;
-}
diff --git a/components/feed/core/proto/wire/mockserver/mock_server.proto b/components/feed/core/proto/wire/mockserver/mock_server.proto
deleted file mode 100644
index 7fc41e4..0000000
--- a/components/feed/core/proto/wire/mockserver/mock_server.proto
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package components.feed.core.proto.wire.mockserver;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/wire/response.proto";
-option java_package = "org.chromium.components.feed.core.proto.wire.mockserver";
-option java_outer_classname = "MockServerProto";
-
-message MockServer {
-  // The initial response
-  optional feedwire1.Response initial_response = 1;
-
-  // conditional responses represent responses for paged content
-  repeated ConditionalResponse conditional_responses = 2;
-
-  reserved 3;
-}
-
-/** This represents a response providing updates to the stream. */
-message MockUpdate {
-  // The response with the push update
-  optional feedwire1.Response response = 1;
-
-  // The amount of time to wait, in milliseconds, before the push is triggered.
-  // This is relative to the time the GCL file is loaded.
-  optional int32 update_trigger_time = 2;
-}
-
-// Conditional responses are served based upon a continuation token.
-message ConditionalResponse {
-  // The continuation token in the request must match this value
-  optional bytes continuation_token = 1;
-
-  // The response to use
-  optional feedwire1.Response response = 2;
-}
diff --git a/components/feed/core/proto/wire/payload_metadata.proto b/components/feed/core/proto/wire/payload_metadata.proto
deleted file mode 100644
index d695087..0000000
--- a/components/feed/core/proto/wire/payload_metadata.proto
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-import "components/feed/core/proto/wire/content_id.proto";
-import "components/feed/core/proto/wire/semantic_properties.proto";
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "PayloadMetadataProto";
-
-// Metadata common to all payloads in a DataOperation.
-message PayloadMetadata {
-  // The unique identifier of the payload.
-  optional ContentId content_id = 1;
-
-  // Payload semantic properties
-  optional SemanticProperties semantic_properties = 2;
-
-  reserved 3;
-}
diff --git a/components/feed/core/proto/wire/piet_shared_state_item.proto b/components/feed/core/proto/wire/piet_shared_state_item.proto
deleted file mode 100644
index 99f4d42..0000000
--- a/components/feed/core/proto/wire/piet_shared_state_item.proto
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-import "components/feed/core/proto/ui/piet/piet.proto";
-import "components/feed/core/proto/wire/content_id.proto";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "PietSharedStateItemProto";
-
-// NOTE: This actually shouldn't be part of the wire protocol.  It should be
-// pulled out into a separate package because it's created outside of the
-// wire protocol and is used on clients outside of the processing of the
-// wire protocol.
-
-// This is a metadata payload containing a Piet Shared State.
-message PietSharedStateItem {
-  // ContentId identifying the shared state.
-  optional ContentId content_id = 1;
-
-  // A Piet Shared State which is used by a set of Piet cards.
-  optional components.feed.core.proto.ui.piet.PietSharedState
-      piet_shared_state = 2;
-}
diff --git a/components/feed/core/proto/wire/request.proto b/components/feed/core/proto/wire/request.proto
deleted file mode 100644
index a023720..0000000
--- a/components/feed/core/proto/wire/request.proto
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "RequestProto";
-
-// Top level request message.
-message Request {
-  // Supported versions of request messages are specified as extensions to
-  // the top-level request message.  An enum is used to denote the expected
-  // extensions for this request.
-  enum RequestVersion {
-    UNKNOWN_REQUEST_VERSION = 0;
-    FEED_QUERY = 1;
-  }
-  optional RequestVersion request_version = 1;
-
-  // Reserved fields for extensions
-  extensions 1000 to max;
-}
diff --git a/components/feed/core/proto/wire/response.proto b/components/feed/core/proto/wire/response.proto
deleted file mode 100644
index 1169230..0000000
--- a/components/feed/core/proto/wire/response.proto
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "ResponseProto";
-
-// Top level response message.
-message Response {
-  // Supported versions of response messages are specified as extensions to
-  // the top-level response message.  An enum is used to denote the expected
-  // extensions for this response.
-  enum ResponseVersion {
-    UNKNOWN_RESPONSE_VERSION = 0;
-    FEED_RESPONSE = 1;
-  }
-  optional ResponseVersion response_version = 1;
-
-  // Reserved fields for extensions
-  extensions 1000 to max;
-}
diff --git a/components/feed/core/proto/wire/semantic_properties.proto b/components/feed/core/proto/wire/semantic_properties.proto
deleted file mode 100644
index d478b77..0000000
--- a/components/feed/core/proto/wire/semantic_properties.proto
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "SemanticPropertiesProto";
-
-// SemanticProperties hold semantic information that we want to attach to
-// features for subsequent comparisons. For example, a feature might be
-// associated with a specific "mid".
-message SemanticProperties {
-  // This is kept opaque to Feed - we want to keep it and send it alongside
-  // content ids in requests
-  optional bytes semantic_properties_data = 1;
-}
diff --git a/components/feed/core/proto/wire/token.proto b/components/feed/core/proto/wire/token.proto
deleted file mode 100644
index e14edf2..0000000
--- a/components/feed/core/proto/wire/token.proto
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-import "components/feed/core/proto/wire/feature.proto";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "TokenProto";
-
-// A continuation token (paging token).
-message Token {
-  extend feedwire1.Feature { optional Token token_extension = 194964015; }
-
-  // Indicates the last position of the current content for a parent.  A request
-  // can be made using the next_page_token to get additional features which will
-  // be appended to the parent's list of children.
-  optional bytes next_page_token = 2;
-}
diff --git a/components/feed/core/proto/wire/version.proto b/components/feed/core/proto/wire/version.proto
deleted file mode 100644
index ba9ef17..0000000
--- a/components/feed/core/proto/wire/version.proto
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-package feedwire1;
-
-option optimize_for = LITE_RUNTIME;
-
-option java_package = "org.chromium.components.feed.core.proto.wire";
-option java_outer_classname = "VersionProto";
-
-// Specification of an application or OS version.
-// A version string typically looks like: 'major.minor.build.revision'
-message Version {
-  optional int32 major = 1;
-  optional int32 minor = 2;
-  optional int32 build = 3;
-  optional int32 revision = 4;
-
-  // The CPU architecture that the native libraries support
-  enum Architecture {
-    UNKNOWN_ACHITECTURE = 0;
-    ARM = 1;
-    ARM64 = 2;
-    MIPS = 3;
-    MIPS64 = 4;
-    X86 = 5;
-    X86_64 = 6;
-  }
-  optional Architecture architecture = 5;
-
-  // The release stage of the build
-  enum BuildType {
-    UNKNOWN_BUILD_TYPE = 0;
-    DEV = 1;
-    ALPHA = 2;
-    BETA = 3;
-    RELEASE = 4;
-  }
-  optional BuildType build_type = 6;
-
-  // Specific to Android OS versions. Specifies the API version that the OS
-  // supports.
-  optional int32 api_version = 7;
-}
diff --git a/components/feed/core/time_serialization.cc b/components/feed/core/time_serialization.cc
deleted file mode 100644
index f084ecf..0000000
--- a/components/feed/core/time_serialization.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/time_serialization.h"
-
-namespace feed {
-
-int64_t ToDatabaseTime(base::Time time) {
-  return time.since_origin().InMicroseconds();
-}
-
-base::Time FromDatabaseTime(int64_t serialized_time) {
-  return base::Time() + base::TimeDelta::FromMicroseconds(serialized_time);
-}
-
-}  // namespace feed
diff --git a/components/feed/core/time_serialization.h b/components/feed/core/time_serialization.h
deleted file mode 100644
index c4f1bda40..0000000
--- a/components/feed/core/time_serialization.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_TIME_SERIALIZATION_H_
-#define COMPONENTS_FEED_CORE_TIME_SERIALIZATION_H_
-
-#include <stdint.h>
-
-#include "base/time/time.h"
-
-namespace feed {
-
-int64_t ToDatabaseTime(base::Time time);
-base::Time FromDatabaseTime(int64_t serialized_time);
-
-}  // namespace feed
-
-#endif  // COMPONENTS_FEED_CORE_TIME_SERIALIZATION_H_
diff --git a/components/feed/core/v2/BUILD.gn b/components/feed/core/v2/BUILD.gn
index 9f30546..8e326b6 100644
--- a/components/feed/core/v2/BUILD.gn
+++ b/components/feed/core/v2/BUILD.gn
@@ -80,9 +80,10 @@
   ]
   deps = [
     ":common",
-    "//components/feed/core:feed_core",
-    "//components/feed/core/common:feed_core_common",
+    "//components/feed:feature_list",
+    "//components/feed/core/shared_prefs:feed_shared_prefs",
     "//components/history/core/browser",
+    "//components/leveldb_proto:leveldb_proto",
     "//components/offline_pages/core:core",
     "//components/offline_pages/core/prefetch",
     "//components/offline_pages/task:task",
@@ -145,8 +146,9 @@
     "//base",
     "//base/test:test_support",
     "//build:chromeos_buildflags",
-    "//components/feed/core:feed_core",
+    "//components/feed:feature_list",
     "//components/feed/core/common:feed_core_common",
+    "//components/feed/core/shared_prefs:feed_shared_prefs",
     "//components/history/core/browser",
     "//components/leveldb_proto:test_support",
     "//components/offline_pages/core:core",
diff --git a/components/feed/core/v2/enums.h b/components/feed/core/v2/enums.h
index bbb27a24..596e78a00 100644
--- a/components/feed/core/v2/enums.h
+++ b/components/feed/core/v2/enums.h
@@ -7,8 +7,6 @@
 
 #include <iosfwd>
 
-#include "components/feed/core/common/enums.h"
-
 namespace feed {
 
 enum class NetworkRequestType : int {
diff --git a/components/feed/core/v2/feed_stream.h b/components/feed/core/v2/feed_stream.h
index 782e50e..2b45b09 100644
--- a/components/feed/core/v2/feed_stream.h
+++ b/components/feed/core/v2/feed_stream.h
@@ -14,8 +14,6 @@
 #include "base/sequenced_task_runner.h"
 #include "base/task_runner_util.h"
 #include "base/version.h"
-#include "components/feed/core/common/enums.h"
-#include "components/feed/core/common/user_classifier.h"
 #include "components/feed/core/proto/v2/ui.pb.h"
 #include "components/feed/core/proto/v2/wire/response.pb.h"
 #include "components/feed/core/v2/enums.h"
diff --git a/components/feed/core/v2/feed_stream_unittest.cc b/components/feed/core/v2/feed_stream_unittest.cc
index 5e9249c4..49d5b365 100644
--- a/components/feed/core/v2/feed_stream_unittest.cc
+++ b/components/feed/core/v2/feed_stream_unittest.cc
@@ -491,7 +491,6 @@
   base::Optional<LoadStreamStatus> load_more_status;
   base::Optional<LoadStreamStatus> background_refresh_status;
   base::Optional<base::TimeDelta> time_since_last_clear;
-  base::Optional<TriggerType> refresh_trigger_type;
   base::Optional<UploadActionsStatus> upload_action_status;
 };
 
diff --git a/components/feed/core/v2/public/feed_service.cc b/components/feed/core/v2/public/feed_service.cc
index 4c14bfd..a7be3e4e 100644
--- a/components/feed/core/v2/public/feed_service.cc
+++ b/components/feed/core/v2/public/feed_service.cc
@@ -240,8 +240,7 @@
 
 // static
 bool FeedService::IsEnabled(const PrefService& pref_service) {
-  return feed::IsV2Enabled() &&
-         pref_service.GetBoolean(feed::prefs::kEnableSnippets);
+  return pref_service.GetBoolean(feed::prefs::kEnableSnippets);
 }
 
 #if defined(OS_ANDROID)
diff --git a/components/feed/features.gni b/components/feed/features.gni
index 1d2d7e3..8cb0f0e 100644
--- a/components/feed/features.gni
+++ b/components/feed/features.gni
@@ -10,10 +10,6 @@
 # If both are false, some of the Feed V2 UI classes are still used to display
 # the NTP.
 declare_args() {
-  # Whether version 1 of the NTP feed is enabled in the build.
-  # TODO(crbug.com/1165828): Remove feed v1 code when we're ready.
-  enable_feed_v1 = false
-
   # Whether version 2 of the NTP feed is enabled in the build.
   enable_feed_v2 = is_android
 
@@ -27,8 +23,3 @@
   # doubledown. Provided for use with pinpoint.
   override_use_doubledown_feed = "use_default"
 }
-
-if (is_android && android_channel != "default") {
-  # You probably don't want to build without either version in a Clank release.
-  assert(enable_feed_v1 || enable_feed_v2)
-}
diff --git a/components/feed/feed_feature_list.cc b/components/feed/feed_feature_list.cc
index 8f51f09..7b42df4b 100644
--- a/components/feed/feed_feature_list.cc
+++ b/components/feed/feed_feature_list.cc
@@ -67,21 +67,4 @@
   return referrer.empty() ? kDefaultReferrerUrl : referrer;
 }
 
-// Chrome can be built with or without v1 or v2.
-// If both are built-in, use kInterestFeedV2 to decide whether v2 is used.
-// Otherwise use the version available.
-bool IsV2Enabled() {
-#if BUILDFLAG(ENABLE_FEED_V1) && BUILDFLAG(ENABLE_FEED_V2)
-  return base::FeatureList::IsEnabled(feed::kInterestFeedV2);
-#elif BUILDFLAG(ENABLE_FEED_V1)
-  return false;
-#else
-  return true;
-#endif
-}
-
-bool IsV1Enabled() {
-  return !IsV2Enabled();
-}
-
 }  // namespace feed
diff --git a/components/feed/feed_feature_list.h b/components/feed/feed_feature_list.h
index 52378ab4..f1b38fd 100644
--- a/components/feed/feed_feature_list.h
+++ b/components/feed/feed_feature_list.h
@@ -10,15 +10,14 @@
 #include "base/feature_list.h"
 #include "base/metrics/field_trial_params.h"
 
+// TODO(crbug.com/1165828): Clean up feedv1 features.
+
 namespace feed {
 
 extern const base::Feature kInterestFeedContentSuggestions;
 extern const base::Feature kInterestFeedV2;
 extern const base::Feature kInterestFeedV2Hearts;
 
-bool IsV1Enabled();
-bool IsV2Enabled();
-
 extern const base::FeatureParam<std::string> kDisableTriggerTypes;
 extern const base::FeatureParam<int> kSuppressRefreshDurationMinutes;
 extern const base::FeatureParam<int> kTimeoutDurationSeconds;
diff --git a/components/feed/tools/content_dump.py b/components/feed/tools/content_dump.py
deleted file mode 100755
index 91d5cde..0000000
--- a/components/feed/tools/content_dump.py
+++ /dev/null
@@ -1,169 +0,0 @@
-#!/usr/bin/python3
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Usage:
-# Dump the feed content database from a connected device to a directory on this
-# computer.
-# > content_dump.py --device=FA77D0303076 --apk='com.chrome.canary'
-# > ls /tmp/feed_dump
-#
-# Files are output as textproto.
-#
-# Make any desired modifications, and then upload the dump back to the connected
-# device.
-# > content_dump.py --device=FA77D0303076 --apk='com.chrome.canary' --reverse
-import argparse
-import glob
-import os
-import plyvel
-import protoc_util
-import re
-import subprocess
-import sys
-
-from os.path import join, dirname, realpath
-
-# A dynamic import for encoding and decoding of escaped textproto strings.
-_prototext_mod = None
-
-
-# Import text proto escape/unescape functions from third_party/protobuf.
-def prototext():
-  global _prototext_mod
-  import importlib.util
-  if _prototext_mod:
-    return _prototext_mod
-  source_path = join(
-      dirname(__file__),
-      "../../../third_party/protobuf/python/google/protobuf/text_encoding.py")
-  spec = importlib.util.spec_from_file_location("protobuf.textutil",
-                                                source_path)
-  _prototext_mod = importlib.util.module_from_spec(spec)
-  spec.loader.exec_module(_prototext_mod)
-  return _prototext_mod
-
-
-parser = argparse.ArgumentParser()
-parser.add_argument("--db", help="Path to db", default='/tmp/feed_dump/db')
-parser.add_argument(
-    "--dump_to", help="Dump output directory", default='/tmp/feed_dump')
-parser.add_argument(
-    "--reverse", help="Write dump back to database", action='store_true')
-parser.add_argument("--device", help="adb device to use")
-parser.add_argument(
-    "--apk", help="APK to dump from/to", default='com.chrome.canary')
-
-args = parser.parse_args()
-
-ROOT_DIR = realpath(join(dirname(__file__), "../../.."))
-DUMP_DIR = args.dump_to
-DB_PATH = args.db
-CONTENT_DB_PATH = join(DB_PATH, 'content')
-DEVICE_DB_PATH = "/data/data/{}/app_chrome/Default/feed".format(args.apk)
-CONTENT_STORAGE_PROTO = (
-    'components/feed_library/core/proto/content_storage.proto')
-
-
-def adb_base_args():
-  adb_path = join(ROOT_DIR, "third_party/android_sdk/public/platform-tools/adb")
-  adb_device = args.device
-  if adb_device:
-    return [adb_path, "-s", adb_device]
-  return [adb_path]
-
-
-def adb_pull_db():
-  subprocess.check_call(
-      adb_base_args() +
-      ["pull", join(DEVICE_DB_PATH, 'content'), DB_PATH])
-
-
-def adb_push_db():
-  subprocess.check_call(adb_base_args() +
-                        ["push", CONTENT_DB_PATH, DEVICE_DB_PATH])
-
-
-# Ignore DB entries with the 'sp::' prefix, as they are not yet supported.
-def is_key_supported(key):
-  return not key.startswith('sp::')
-
-
-# Return the proto message stored under the given db key.
-def proto_message_from_db_key(key):
-  if key.startswith('ss::'):
-    return 'search.now.feed.client.StreamSharedState'
-  if key.startswith('FEATURE::') or key.startswith('FSM::'):
-    return 'search.now.feed.client.StreamPayload'
-  print("Unknown Key kind", key)
-  sys.exit(1)
-
-
-# Extract a binary proto database entry into textproto.
-def extract_db_entry(key, data):
-  # DB entries are feed.ContentStorageProto messages. First extract
-  # the content_data contained within.
-  text_proto = protoc_util.decode_proto(data, 'feed.ContentStorageProto',
-                                        ROOT_DIR, CONTENT_STORAGE_PROTO)
-  m = re.search(r"content_data: \"((?:\\\"|[^\"])*)\"", text_proto)
-  raw_data = prototext().CUnescape(m.group(1))
-
-  # Next, convert raw_data into a textproto. The DB key informs which message
-  # is stored.
-  result = protoc_util.decode_proto(raw_data, proto_message_from_db_key(key),
-                                    ROOT_DIR, CONTENT_STORAGE_PROTO)
-  return result
-
-
-# Dump the content database to a local directory as textproto files.
-def dump():
-  os.makedirs(DUMP_DIR, exist_ok=True)
-  os.makedirs(DB_PATH, exist_ok=True)
-  adb_pull_db()
-  db = plyvel.DB(CONTENT_DB_PATH, create_if_missing=False)
-  with db.iterator() as it:
-    for i, (k, v) in enumerate(it):
-      k = k.decode('utf-8')
-      if not is_key_supported(k):
-        continue
-      with open(join(DUMP_DIR, 'entry{:03d}.key'.format(i)), 'w') as f:
-        f.write(k)
-      with open(join(DUMP_DIR, 'entry{:03d}.textproto'.format(i)), 'w') as f:
-        f.write(extract_db_entry(k, v))
-  print('Finished dumping to', DUMP_DIR)
-  db.close()
-
-
-# Reverse of dump().
-def load():
-  db = plyvel.DB(CONTENT_DB_PATH, create_if_missing=False)
-  # For each textproto file, update its database entry.
-  # No attempt is made to delete keys for deleted files.
-  for f in os.listdir(DUMP_DIR):
-    if f.endswith('.textproto'):
-      f_base, _ = os.path.splitext(f)
-      with open(join(DUMP_DIR, f_base + '.key'), 'r') as file:
-        key = file.read().strip()
-      with open(join(DUMP_DIR, f), 'r') as file:
-        value_text_proto = file.read()
-      value_encoded = protoc_util.encode_proto(value_text_proto,
-                                               proto_message_from_db_key(key),
-                                               ROOT_DIR, CONTENT_STORAGE_PROTO)
-      # Create binary feed.ContentStorageProto by encoding its textproto.
-      content_storage_text = 'key: "{}"\ncontent_data: "{}"'.format(
-          prototext().CEscape(key, False),
-          prototext().CEscape(value_encoded, False))
-
-      store_encoded = protoc_util.encode_proto(content_storage_text,
-                                               'feed.ContentStorageProto',
-                                               ROOT_DIR, CONTENT_STORAGE_PROTO)
-      db.put(key.encode(), store_encoded)
-  db.close()
-  adb_push_db()
-
-
-if not args.reverse:
-  dump()
-else:
-  load()
diff --git a/components/feed/tools/mockserver_textpb_to_binary.py b/components/feed/tools/mockserver_textpb_to_binary.py
deleted file mode 100755
index b6d7574..0000000
--- a/components/feed/tools/mockserver_textpb_to_binary.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/python3
-# 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.
-
-# Lint as: python3
-"""The tool converts a textpb into a binary proto using chromium protoc binary.
-
-After converting a feed response textpb file into a mockserver textpb file using
-the proto_convertor script, then a engineer runs this script to encode the
-mockserver textpb file into a binary proto file that is being used by the feed
-card render test (Refers to go/create-a-feed-card-render-test for more).
-
-Make sure you have absl-py installed via 'python3 -m pip install absl-py'.
-
-Usage example:
-    python3 ./mockserver_textpb_to_binary.py
-    --chromium_path ~/chromium/src
-    --output_file /tmp/binary.pb
-    --source_file /tmp/original.textpb
-    --alsologtostderr
-"""
-
-import glob
-import os
-import protoc_util
-import subprocess
-
-from absl import app
-from absl import flags
-
-FLAGS = flags.FLAGS
-FLAGS = flags.FLAGS
-flags.DEFINE_string('chromium_path', '', 'The path of your chromium depot.')
-flags.DEFINE_string('output_file', '', 'The target output binary file path.')
-flags.DEFINE_string('source_file', '',
-                    'The source proto file, in textpb format, path.')
-
-ENCODE_NAMESPACE = 'components.feed.core.proto.wire.mockserver.MockServer'
-COMPONENT_FEED_PROTO_PATH = 'components/feed/core/proto'
-
-
-def main(argv):
-  if len(argv) > 1:
-    raise app.UsageError('Too many command-line arguments.')
-  if not FLAGS.chromium_path:
-    raise app.UsageError('chromium_path flag must be set.')
-  if not FLAGS.source_file:
-    raise app.UsageError('source_file flag must be set.')
-  if not FLAGS.output_file:
-    raise app.UsageError('output_file flag must be set.')
-
-  with open(FLAGS.source_file) as file:
-    value_text_proto = file.read()
-
-  encoded = protoc_util.encode_proto(value_text_proto, ENCODE_NAMESPACE,
-                                     FLAGS.chromium_path,
-                                     COMPONENT_FEED_PROTO_PATH)
-  with open(FLAGS.output_file, 'wb') as file:
-    file.write(encoded)
-
-
-if __name__ == '__main__':
-  app.run(main)
diff --git a/components/js_injection/renderer/js_communication.cc b/components/js_injection/renderer/js_communication.cc
index dd648297..cfc11f7c 100644
--- a/components/js_injection/renderer/js_communication.cc
+++ b/components/js_injection/renderer/js_communication.cc
@@ -117,6 +117,7 @@
 
 void JsCommunication::BindPendingReceiver(
     mojo::PendingAssociatedReceiver<mojom::JsCommunication> pending_receiver) {
+  receiver_.reset();
   receiver_.Bind(std::move(pending_receiver),
                  render_frame()->GetTaskRunner(
                      blink::TaskType::kInternalNavigationAssociated));
diff --git a/components/leveldb_proto/public/shared_proto_database_client_list.h b/components/leveldb_proto/public/shared_proto_database_client_list.h
index 5e88d486..f8b769bc 100644
--- a/components/leveldb_proto/public/shared_proto_database_client_list.h
+++ b/components/leveldb_proto/public/shared_proto_database_client_list.h
@@ -73,7 +73,8 @@
 // Add any obsolete databases in this list so that, if the data is no longer
 // needed.
 constexpr ProtoDbType kObsoleteSharedProtoDbTypeClients[] = {
-    ProtoDbType::DOM_DISTILLER_STORE,
+    ProtoDbType::DOM_DISTILLER_STORE, ProtoDbType::FEED_CONTENT_DATABASE,
+    ProtoDbType::FEED_JOURNAL_DATABASE,
     ProtoDbType::LAST,  // Marks the end of list.
 };
 
diff --git a/components/media_message_center/media_notification_view_modern_impl.cc b/components/media_message_center/media_notification_view_modern_impl.cc
index 6a3dbf2..4974300c 100644
--- a/components/media_message_center/media_notification_view_modern_impl.cc
+++ b/components/media_message_center/media_notification_view_modern_impl.cc
@@ -18,6 +18,7 @@
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/canvas.h"
+#include "ui/gfx/color_palette.h"
 #include "ui/gfx/font.h"
 #include "ui/gfx/font_list.h"
 #include "ui/gfx/paint_vector_icon.h"
@@ -72,7 +73,7 @@
   void OnPaint(gfx::Canvas* canvas) override;
 
  private:
-  SkColor vignette_color_;
+  SkColor vignette_color_ = gfx::kPlaceholderColor;
   float corner_radius_;
 };
 
diff --git a/components/metrics/structured/histogram_util.h b/components/metrics/structured/histogram_util.h
index 3050139..b3926ceb 100644
--- a/components/metrics/structured/histogram_util.h
+++ b/components/metrics/structured/histogram_util.h
@@ -23,7 +23,11 @@
   kMissingLastRotation = 2,
   kMissingRotationPeriod = 3,
   kFailedUintConversion = 4,
-  kMaxValue = kFailedUintConversion,
+  kKeyReadError = 5,
+  kKeyParseError = 6,
+  kKeyWriteError = 7,
+  kKeySerializationError = 8,
+  kMaxValue = kKeySerializationError,
 };
 
 // Whether a single event was recorded correctly, or otherwise what error state
diff --git a/components/metrics/structured/key_data.cc b/components/metrics/structured/key_data.cc
index 8b4b22b..11a0024 100644
--- a/components/metrics/structured/key_data.cc
+++ b/components/metrics/structured/key_data.cc
@@ -6,28 +6,29 @@
 
 #include <memory>
 
+#include "base/logging.h"
 #include "base/rand_util.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
 #include "base/unguessable_token.h"
-#include "base/values.h"
 #include "components/metrics/structured/histogram_util.h"
 #include "components/metrics/structured/structured_events.h"
-#include "components/prefs/json_pref_store.h"
 #include "crypto/hmac.h"
 #include "crypto/sha2.h"
 
 namespace metrics {
 namespace structured {
-namespace internal {
 namespace {
 
 // The expected size of a key, in bytes.
 constexpr size_t kKeySize = 32;
 
 // The default maximum number of days before rotating keys.
-constexpr size_t kDefaultRotationPeriod = 90;
+constexpr int kDefaultRotationPeriod = 90;
+
+// The delay period for the PersistentProto.
+constexpr int kSaveDelayMs = 1000;
 
 // Generates a key, which is the string representation of
 // base::UnguessableToken, and is of size |kKeySize| bytes.
@@ -41,132 +42,112 @@
   return base::HexEncode(&hash, sizeof(uint64_t));
 }
 
-std::string KeyPath(const uint64_t project) {
-  return base::StrCat({"keys.", base::NumberToString(project), ".key"});
-}
-
-std::string LastRotationPath(const uint64_t project) {
-  return base::StrCat(
-      {"keys.", base::NumberToString(project), ".last_rotation"});
-}
-
-std::string RotationPeriodPath(const uint64_t project) {
-  return base::StrCat(
-      {"keys.", base::NumberToString(project), ".rotation_period"});
-}
-
 }  // namespace
 
-KeyData::KeyData(JsonPrefStore* key_store) : key_store_(key_store) {
-  DCHECK(key_store_);
-  ValidateKeys();
+KeyData::KeyData(const base::FilePath& path,
+                 base::OnceCallback<void()> on_initialized)
+    : on_initialized_(std::move(on_initialized)) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  proto_ = std::make_unique<PersistentProto<KeyDataProto>>(
+      path, base::TimeDelta::FromMilliseconds(kSaveDelayMs),
+      base::BindOnce(&KeyData::OnRead, weak_factory_.GetWeakPtr()),
+      base::BindRepeating(&KeyData::OnWrite, weak_factory_.GetWeakPtr()));
 }
 
 KeyData::~KeyData() = default;
 
+void KeyData::OnRead(const ReadStatus status) {
+  is_initialized_ = true;
+  switch (status) {
+    case ReadStatus::kOk:
+    case ReadStatus::kMissing:
+      break;
+    case ReadStatus::kReadError:
+      LogInternalError(StructuredMetricsError::kKeyReadError);
+      break;
+    case ReadStatus::kParseError:
+      LogInternalError(StructuredMetricsError::kKeyParseError);
+      break;
+  }
+  std::move(on_initialized_).Run();
+}
+
+void KeyData::OnWrite(const WriteStatus status) {
+  switch (status) {
+    case WriteStatus::kOk:
+      break;
+    case WriteStatus::kWriteError:
+      LogInternalError(StructuredMetricsError::kKeyWriteError);
+      break;
+    case WriteStatus::kSerializationError:
+      LogInternalError(StructuredMetricsError::kKeySerializationError);
+      break;
+  }
+}
+
+void KeyData::WriteNowForTest() {
+  proto_.get()->StartWrite();
+}
+
+//---------------
+// Key management
+//---------------
+
 base::Optional<std::string> KeyData::ValidateAndGetKey(
     const uint64_t project_name_hash) {
-  DCHECK(key_store_);
+  if (!is_initialized_) {
+    NOTREACHED();
+    return base::nullopt;
+  }
+
   const int now = (base::Time::Now() - base::Time::UnixEpoch()).InDays();
-  bool key_is_valid = true;
+  KeyProto& key = (*(proto_.get()->get()->mutable_keys()))[project_name_hash];
 
-  // If the key for |project_name_hash| doesn't exist, initialize new key data.
-  // Set the last rotation to a uniformly selected day between today and
-  // |kDefaultRotationPeriod| days ago, to uniformly distribute users amongst
-  // rotation cohorts.
-  if (!key_store_->GetValue(KeyPath(project_name_hash), nullptr)) {
-    const int rotation_seed = base::RandInt(0, kDefaultRotationPeriod - 1);
-    SetRotationPeriod(project_name_hash, kDefaultRotationPeriod);
-    SetLastRotation(project_name_hash, now - rotation_seed);
-    SetKey(project_name_hash, GenerateKey());
-
+  // Generate or rotate key.
+  const int last_rotation = key.last_rotation();
+  if (key.key().empty() || last_rotation == 0) {
     LogKeyValidation(KeyValidationState::kCreated);
-    key_is_valid = false;
-  }
-
-  // If the key for |project_name_hash| is outdated, generate a new key and
-  // write it to the |keys| pref store along with updated rotation data. Update
-  // the last rotation such that the user stays in the same cohort.
-  const int rotation_period = GetRotationPeriod(project_name_hash);
-  const int last_rotation = GetLastRotation(project_name_hash);
-  if (now - last_rotation > rotation_period) {
-    const int new_last_rotation = now - (now - last_rotation) % rotation_period;
-    SetLastRotation(project_name_hash, new_last_rotation);
-    SetKey(project_name_hash, GenerateKey());
-
+    // If the key is empty, generate a new one. Set the last rotation to a
+    // uniformly selected day between today and |kDefaultRotationPeriod| days
+    // ago, to uniformly distribute users amongst rotation cohorts.
+    const int rotation_seed = base::RandInt(0, kDefaultRotationPeriod - 1);
+    UpdateKey(&key, now - rotation_seed, kDefaultRotationPeriod);
+  } else if (now - last_rotation > kDefaultRotationPeriod) {
     LogKeyValidation(KeyValidationState::kRotated);
-    key_is_valid = false;
-  }
-
-  if (key_is_valid) {
+    // If the key is outdated, generate a new one. Update the last rotation such
+    // that the user stays in the same cohort.
+    const int new_last_rotation =
+        now - (now - last_rotation) % kDefaultRotationPeriod;
+    UpdateKey(&key, new_last_rotation, kDefaultRotationPeriod);
+  } else {
     LogKeyValidation(KeyValidationState::kValid);
   }
 
-  const base::Value* key_json;
-  if (!(key_store_->GetValue(KeyPath(project_name_hash), &key_json) &&
-        key_json->is_string())) {
-    LogInternalError(StructuredMetricsError::kMissingKey);
-    return base::nullopt;
-  }
-
-  const std::string key = key_json->GetString();
-  if (key.size() != kKeySize) {
+  // Return the key unless it's the wrong size, in which case return nullopt.
+  const std::string key_string = key.key();
+  if (key_string.size() != kKeySize) {
     LogInternalError(StructuredMetricsError::kWrongKeyLength);
     return base::nullopt;
   }
-
-  return key;
+  return key_string;
 }
 
-void KeyData::ValidateKeys() {
-  for (const uint64_t project_name_hash :
-       metrics::structured::events::kProjectNameHashes) {
-    ValidateAndGetKey(project_name_hash);
-  }
+void KeyData::UpdateKey(KeyProto* key,
+                        const int last_rotation,
+                        const int rotation_period) {
+  key->set_key(GenerateKey());
+  key->set_last_rotation(last_rotation);
+  key->set_rotation_period(rotation_period);
+  proto_->QueueWrite();
 }
 
-void KeyData::SetLastRotation(const uint64_t project, const int last_rotation) {
-  return key_store_->SetValue(LastRotationPath(project),
-                              std::make_unique<base::Value>(last_rotation),
-                              WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
-}
+//----------------
+// IDs and hashing
+//----------------
 
-void KeyData::SetRotationPeriod(const uint64_t project,
-                                const int rotation_period) {
-  return key_store_->SetValue(RotationPeriodPath(project),
-                              std::make_unique<base::Value>(rotation_period),
-                              WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
-}
+uint64_t KeyData::Id(const uint64_t project_name_hash) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-void KeyData::SetKey(const uint64_t project_name_hash, const std::string& key) {
-  return key_store_->SetValue(KeyPath(project_name_hash),
-                              std::make_unique<base::Value>(key),
-                              WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
-}
-
-int KeyData::GetLastRotation(const uint64_t project) {
-  const base::Value* value;
-  if (!(key_store_->GetValue(LastRotationPath(project), &value) &&
-        value->is_int())) {
-    LogInternalError(StructuredMetricsError::kMissingLastRotation);
-    NOTREACHED();
-    return 0u;
-  }
-  return value->GetInt();
-}
-
-int KeyData::GetRotationPeriod(const uint64_t project) {
-  const base::Value* value;
-  if (!(key_store_->GetValue(RotationPeriodPath(project), &value) &&
-        value->is_int())) {
-    LogInternalError(StructuredMetricsError::kMissingRotationPeriod);
-    NOTREACHED();
-    return 0u;
-  }
-  return value->GetInt();
-}
-
-uint64_t KeyData::UserProjectId(const uint64_t project_name_hash) {
   // Retrieve the key for |project_name_hash|.
   const base::Optional<std::string> key = ValidateAndGetKey(project_name_hash);
   if (!key) {
@@ -183,6 +164,8 @@
 uint64_t KeyData::HmacMetric(const uint64_t project_name_hash,
                              const uint64_t metric_name_hash,
                              const std::string& value) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   // Retrieve the key for |project_name_hash|.
   const base::Optional<std::string> key = ValidateAndGetKey(project_name_hash);
   if (!key) {
@@ -203,6 +186,5 @@
   return digest;
 }
 
-}  // namespace internal
 }  // namespace structured
 }  // namespace metrics
diff --git a/components/metrics/structured/key_data.h b/components/metrics/structured/key_data.h
index 32359f40..f5bb36eb 100644
--- a/components/metrics/structured/key_data.h
+++ b/components/metrics/structured/key_data.h
@@ -7,20 +7,27 @@
 
 #include <string>
 
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
 #include "base/optional.h"
-
-class JsonPrefStore;
+#include "base/sequence_checker.h"
+#include "base/sequenced_task_runner.h"
+#include "components/metrics/structured/persistent_proto.h"
+#include "components/metrics/structured/storage.pb.h"
 
 namespace metrics {
 namespace structured {
-namespace internal {
+
+class KeyDataTest;
 
 // KeyData is the central class for managing keys and generating hashes for
 // structured metrics.
 //
 // The class maintains one key and its rotation data for every project defined
 // in /tools/metrics/structured.xml. This can be used to generate:
-//  - a user ID for the project with KeyData::UserProjectId.
+//  - a user ID for the project with KeyData::Id.
 //  - a hash of a given value for an event with KeyData::HmacMetric.
 //
 // KeyData performs key rotation. Every project is associated with a rotation
@@ -34,22 +41,12 @@
 // that, for most users, the first rotation period will be shorter than the
 // standard full rotation period for that project.
 //
-// Key storage is backed by a JsonPrefStore which is passed to the ctor and must
-// outlive the KeyData instance. Within the pref store, each project has three
-// pieces of associated data:
-//  - the rotation period for this project in days.
-//  - the day of the last key rotation, as a day since the unix epoch.
-//  - the key itself.
-//
-// This is stored in the structure:
-//   keys.{project_name_hash}.rotation_period
-//                         .last_rotation
-//                         .key
-//
-// TODO(crbug.com/1016655): add ability to override default rotation period
+// Key storage is backed by a PersistentProto, stored at the path given to the
+// constructor.
 class KeyData {
  public:
-  explicit KeyData(JsonPrefStore* key_store);
+  KeyData(const base::FilePath& path,
+          base::OnceCallback<void()> on_initialized);
   ~KeyData();
 
   KeyData(const KeyData&) = delete;
@@ -87,28 +84,43 @@
   // the server. This means events are associated with the client ID when
   // uploaded from the device. See the class comment of
   // StructuredMetricsProvider for more details.
-  uint64_t UserProjectId(uint64_t project_name_hash);
+  uint64_t Id(uint64_t project_name_hash);
+
+  // Returns whether this KeyData instance has finished reading from disk and is
+  // ready to be used. If false, both Id and HmacMetric will return 0u.
+  bool is_initialized() { return is_initialized_; }
 
  private:
-  int GetRotationPeriod(uint64_t project);
-  void SetRotationPeriod(uint64_t project, int rotation_period);
+  friend class KeyDataTest;
 
-  int GetLastRotation(uint64_t project);
-  void SetLastRotation(uint64_t project, int last_rotation);
+  void WriteNowForTest();
+
+  void OnRead(ReadStatus status);
+
+  void OnWrite(WriteStatus status);
 
   // Ensure that a valid key exists for |project|, and return it. Either returns
   // a string of size |kKeySize| or base::nullopt, which indicates an error.
   base::Optional<std::string> ValidateAndGetKey(uint64_t project_name_hash);
-  void SetKey(uint64_t project, const std::string& key);
 
-  // Ensure that valid keys exist for all projects.
-  void ValidateKeys();
+  // Regenerate |key|, also updating the |last_rotation| and |rotation_period|.
+  // This triggers a save.
+  void UpdateKey(KeyProto* key, int last_rotation, int rotation_period);
 
-  // Storage for keys and rotation data. Must outlive the KeyData instance.
-  JsonPrefStore* key_store_;
+  // Storage for keys.
+  std::unique_ptr<PersistentProto<KeyDataProto>> proto_;
+
+  // Whether this instance has finished reading from disk.
+  bool is_initialized_ = false;
+
+  base::OnceCallback<void()> on_initialized_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
+  base::WeakPtrFactory<KeyData> weak_factory_{this};
 };
 
-}  // namespace internal
 }  // namespace structured
 }  // namespace metrics
 
diff --git a/components/metrics/structured/key_data_unittest.cc b/components/metrics/structured/key_data_unittest.cc
index 32c5f1b9..a97ecec 100644
--- a/components/metrics/structured/key_data_unittest.cc
+++ b/components/metrics/structured/key_data_unittest.cc
@@ -11,6 +11,8 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/logging.h"
+#include "base/run_loop.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
@@ -20,14 +22,13 @@
 #include "components/metrics/structured/event_base.h"
 #include "components/metrics/structured/histogram_util.h"
 #include "components/metrics/structured/recorder.h"
+#include "components/metrics/structured/storage.pb.h"
 #include "components/metrics/structured/structured_events.h"
-#include "components/prefs/json_pref_store.h"
 #include "components/prefs/persistent_pref_store.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace metrics {
 namespace structured {
-namespace internal {
 
 namespace {
 
@@ -65,95 +66,62 @@
   return base::HexEncode(&hash, sizeof(uint64_t));
 }
 
-std::string KeyPath(const uint64_t event) {
-  return base::StrCat({"keys.", base::NumberToString(event), ".key"});
-}
-
-std::string LastRotationPath(const uint64_t event) {
-  return base::StrCat({"keys.", base::NumberToString(event), ".last_rotation"});
-}
-
-std::string RotationPeriodPath(const uint64_t event) {
-  return base::StrCat(
-      {"keys.", base::NumberToString(event), ".rotation_period"});
-}
-
-// Returns the total number of events registered in structured.xml. This is used
-// to determine how many keys we expect to load or rotate on initialization.
-int NumberOfEvents() {
-  return sizeof(metrics::structured::events::kProjectNameHashes) /
-         sizeof(uint64_t);
-}
-
 }  // namespace
 
 class KeyDataTest : public testing::Test {
  protected:
   void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
 
-  void StandardSetup() {
-    MakeKeyStore();
-    MakeKeyData();
-    CommitKeyStore();
-  }
-
   void ResetState() {
     key_data_.reset();
-    key_store_.reset();
-    base::DeleteFile(GetKeyStorePath());
-    ASSERT_FALSE(base::PathExists(GetKeyStorePath()));
+    base::DeleteFile(GetPath());
+    ASSERT_FALSE(base::PathExists(GetPath()));
   }
 
-  void MakeKeyStore() {
-    key_store_ = new JsonPrefStore(GetKeyStorePath());
-    key_store_->ReadPrefs();
-  }
+  base::FilePath GetPath() { return temp_dir_.GetPath().Append("keys"); }
 
-  void MakeKeyData() { key_data_ = std::make_unique<KeyData>(GetKeyStore()); }
-
-  void CommitKeyStore() {
-    key_store_->CommitPendingWrite();
+  void MakeKeyData() {
+    key_data_ = std::make_unique<KeyData>(GetPath(), base::DoNothing());
     Wait();
-    ASSERT_TRUE(base::PathExists(GetKeyStorePath()));
   }
 
-  JsonPrefStore* GetKeyStore() { return key_store_.get(); }
-
-  base::FilePath GetKeyStorePath() {
-    return temp_dir_.GetPath().Append("keys.json");
+  void SaveKeyData() {
+    key_data_->WriteNowForTest();
+    Wait();
+    ASSERT_TRUE(base::PathExists(GetPath()));
   }
 
-  std::string GetString(const std::string& path) {
-    const base::Value* value;
-    GetKeyStore()->GetValue(path, &value);
-    return value->GetString();
+  int Today() { return (base::Time::Now() - base::Time::UnixEpoch()).InDays(); }
+
+  // Read the on-disk file and return the information about the key for
+  // |project_name_hash|. Fails if a key does not exist.
+  KeyProto GetKey(const uint64_t project_name_hash) {
+    std::string proto_str;
+    CHECK(base::ReadFileToString(GetPath(), &proto_str));
+    KeyDataProto proto;
+    CHECK(proto.ParseFromString(proto_str));
+
+    const auto it = proto.keys().find(project_name_hash);
+    CHECK(it != proto.keys().end());
+    return it->second;
   }
 
-  int GetInt(const std::string& path) {
-    const base::Value* value;
-    GetKeyStore()->GetValue(path, &value);
-    return value->GetInt();
-  }
+  // Write a KeyDataProto to disk with a single key described by the arguments.
+  void SetupKey(const uint64_t project_name_hash,
+                const std::string& key,
+                const int last_rotation,
+                const int rotation_period) {
+    // It's a test logic error for the key data to exist when calling SetupKey,
+    // because it will desync the in-memory proto from the underlying storage.
+    ASSERT_FALSE(key_data_);
 
-  void SetString(const std::string& path, const std::string& value) {
-    key_store_->SetValue(path, std::make_unique<base::Value>(value),
-                         WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
-    CommitKeyStore();
-  }
+    KeyDataProto proto;
+    KeyProto& key_proto = (*proto.mutable_keys())[project_name_hash];
+    key_proto.set_key(key);
+    key_proto.set_last_rotation(last_rotation);
+    key_proto.set_rotation_period(rotation_period);
 
-  void SetInt(const std::string& path, const int value) {
-    key_store_->SetValue(path, std::make_unique<base::Value>(value),
-                         WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
-    CommitKeyStore();
-  }
-
-  void SetKeyData(const uint64_t event,
-                  const std::string& key,
-                  const int last_rotation,
-                  const int rotation_period) {
-    SetString(KeyPath(event), key);
-    SetInt(LastRotationPath(event), last_rotation);
-    SetInt(RotationPeriodPath(event), rotation_period);
+    ASSERT_TRUE(base::WriteFile(GetPath(), proto.SerializeAsString()));
   }
 
   void Wait() { task_environment_.RunUntilIdle(); }
@@ -163,13 +131,25 @@
                                        0);
   }
 
+  void ExpectKeyValidation(const int valid,
+                           const int created,
+                           const int rotated) {
+    static const std::string histogram =
+        "UMA.StructuredMetrics.KeyValidationState";
+    histogram_tester_.ExpectBucketCount(histogram, KeyValidationState::kValid,
+                                        valid);
+    histogram_tester_.ExpectBucketCount(histogram, KeyValidationState::kCreated,
+                                        created);
+    histogram_tester_.ExpectBucketCount(histogram, KeyValidationState::kRotated,
+                                        rotated);
+  }
+
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::MainThreadType::UI,
       base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED};
   base::ScopedTempDir temp_dir_;
   base::ScopedMockClockOverride time_;
   base::HistogramTester histogram_tester_;
-  scoped_refptr<JsonPrefStore> key_store_;
 
   std::unique_ptr<KeyData> key_data_;
 };
@@ -178,17 +158,21 @@
 // each project, and those keys are of the right length and different from each
 // other.
 TEST_F(KeyDataTest, GeneratesKeysForProjects) {
-  StandardSetup();
-  histogram_tester_.ExpectUniqueSample(
-      "UMA.StructuredMetrics.KeyValidationState", KeyValidationState::kCreated,
-      NumberOfEvents());
+  // Make key data and use two keys, in order to generate them.
+  MakeKeyData();
+  key_data_->Id(kProjectOneHash);
+  key_data_->Id(kProjectTwoHash);
+  SaveKeyData();
 
-  const std::string key_one = GetString(KeyPath(kProjectOneHash));
-  const std::string key_two = GetString(KeyPath(kProjectTwoHash));
+  const std::string key_one = GetKey(kProjectOneHash).key();
+  const std::string key_two = GetKey(kProjectTwoHash).key();
 
   EXPECT_EQ(key_one.size(), 32ul);
   EXPECT_EQ(key_two.size(), 32ul);
   EXPECT_NE(key_one, key_two);
+
+  ExpectNoErrors();
+  ExpectKeyValidation(/*valid=*/0, /*created=*/2, /*rotated=*/0);
 }
 
 // When repeatedly initialized with no key store file present, ensure the keys
@@ -196,42 +180,49 @@
 TEST_F(KeyDataTest, GeneratesDistinctKeys) {
   base::flat_set<std::string> keys;
 
-  for (int i = 0; i < 10; ++i) {
+  for (int i = 1; i <= 10; ++i) {
+    // Reset on-disk and in-memory state, regenerate the key, and save it to
+    // disk.
     ResetState();
-    StandardSetup();
-    keys.insert(GetString(KeyPath(kProjectOneHash)));
-    histogram_tester_.ExpectUniqueSample(
-        "UMA.StructuredMetrics.KeyValidationState",
-        KeyValidationState::kCreated, NumberOfEvents() * (i + 1));
+    MakeKeyData();
+    key_data_->Id(kProjectOneHash);
+    SaveKeyData();
+
+    keys.insert(GetKey(kProjectOneHash).key());
+    ExpectKeyValidation(/*valid=*/0, /*created=*/i, /*rotated=*/0);
   }
 
+  ExpectNoErrors();
   EXPECT_EQ(keys.size(), 10ul);
 }
 
 // If there is an existing key store file, check that its keys are not replaced.
 TEST_F(KeyDataTest, ReuseExistingKeys) {
-  StandardSetup();
-  histogram_tester_.ExpectBucketCount(
-      "UMA.StructuredMetrics.KeyValidationState", KeyValidationState::kCreated,
-      NumberOfEvents());
-  const std::string key_one = GetString(KeyPath(kProjectOneHash));
-  CommitKeyStore();
+  // Create a file with one key.
+  MakeKeyData();
+  const uint64_t id_one = key_data_->Id(kProjectOneHash);
+  SaveKeyData();
+  ExpectKeyValidation(/*valid=*/0, /*created=*/1, /*rotated=*/0);
+  const std::string key_one = GetKey(kProjectOneHash).key();
 
+  // Reset the in-memory state, leave the on-disk state intact.
   key_data_.reset();
-  key_store_.reset();
-  StandardSetup();
-  histogram_tester_.ExpectBucketCount(
-      "UMA.StructuredMetrics.KeyValidationState", KeyValidationState::kValid,
-      NumberOfEvents());
-  const std::string key_two = GetString(KeyPath(kProjectOneHash));
 
+  // Open the file again and check we use the same key.
+  MakeKeyData();
+  const uint64_t id_two = key_data_->Id(kProjectOneHash);
+  ExpectKeyValidation(/*valid=*/1, /*created=*/1, /*rotated=*/0);
+  SaveKeyData();
+  const std::string key_two = GetKey(kProjectOneHash).key();
+
+  EXPECT_EQ(id_one, id_two);
   EXPECT_EQ(key_one, key_two);
 }
 
 // Check that different events have different hashes for the same metric and
 // value.
 TEST_F(KeyDataTest, DifferentEventsDifferentHashes) {
-  StandardSetup();
+  MakeKeyData();
   EXPECT_NE(key_data_->HmacMetric(kProjectOneHash, kMetricOneHash, "value"),
             key_data_->HmacMetric(kProjectTwoHash, kMetricOneHash, "value"));
   ExpectNoErrors();
@@ -240,7 +231,7 @@
 // Check that an event has different hashes for different metrics with the same
 // value.
 TEST_F(KeyDataTest, DifferentMetricsDifferentHashes) {
-  StandardSetup();
+  MakeKeyData();
   EXPECT_NE(key_data_->HmacMetric(kProjectOneHash, kMetricOneHash, "value"),
             key_data_->HmacMetric(kProjectOneHash, kMetricTwoHash, "value"));
   ExpectNoErrors();
@@ -249,7 +240,7 @@
 // Check that an event has different hashes for different values of the same
 // metric.
 TEST_F(KeyDataTest, DifferentValuesDifferentHashes) {
-  StandardSetup();
+  MakeKeyData();
   EXPECT_NE(key_data_->HmacMetric(kProjectOneHash, kMetricOneHash, "first"),
             key_data_->HmacMetric(kProjectOneHash, kMetricOneHash, "second"));
   ExpectNoErrors();
@@ -257,22 +248,18 @@
 
 // Ensure that KeyData::UserId is the expected value of SHA256(key).
 TEST_F(KeyDataTest, CheckUserIDs) {
-  MakeKeyStore();
-  SetKeyData(kProjectOneHash, kKey, 0, 90);
-  CommitKeyStore();
+  SetupKey(kProjectOneHash, kKey, Today(), 90);
 
   MakeKeyData();
-  EXPECT_EQ(HashToHex(key_data_->UserProjectId(kProjectOneHash)), kUserId);
-  EXPECT_NE(HashToHex(key_data_->UserProjectId(kProjectTwoHash)), kUserId);
+  EXPECT_EQ(HashToHex(key_data_->Id(kProjectOneHash)), kUserId);
+  EXPECT_NE(HashToHex(key_data_->Id(kProjectTwoHash)), kUserId);
+  ExpectKeyValidation(/*valid=*/1, /*created=*/1, /*rotated=*/0);
   ExpectNoErrors();
 }
 
 // Ensure that KeyData::Hash returns expected values for a known key and value.
 TEST_F(KeyDataTest, CheckHashes) {
-  MakeKeyStore();
-  SetString(KeyPath(kProjectOneHash), kKey);
-  SetKeyData(kProjectOneHash, kKey, 0, 90);
-  CommitKeyStore();
+  SetupKey(kProjectOneHash, kKey, Today(), 90);
 
   MakeKeyData();
   EXPECT_EQ(HashToHex(key_data_->HmacMetric(kProjectOneHash, kMetricOneHash,
@@ -281,56 +268,56 @@
   EXPECT_EQ(HashToHex(key_data_->HmacMetric(kProjectOneHash, kMetricTwoHash,
                                             kValueTwo)),
             kValueTwoHash);
+  ExpectKeyValidation(/*valid=*/2, /*created=*/0, /*rotated=*/0);
   ExpectNoErrors();
 }
 
 // Check that keys for a event are correctly rotated after the default 90 day
 // rotation period.
 TEST_F(KeyDataTest, KeysRotated) {
-  // This test intentionally doesn't test the key validation metric. Events can
-  // have custom rotation periods, so this test could rotate some arbitrary set
-  // of keys that we don't know ahead of time, which would require too much test
-  // logic.
+  const int start_day = Today();
+  SetupKey(kProjectOneHash, kKey, start_day, 90);
 
-  StandardSetup();
-  const uint64_t first_id = key_data_->UserProjectId(kProjectOneHash);
-  const int start_day = (base::Time::Now() - base::Time::UnixEpoch()).InDays();
-
-  // TestEventOne has a default rotation period of 90 days.
-  EXPECT_EQ(GetInt(RotationPeriodPath(kProjectOneHash)), 90);
-
-  // Set the last rotation to today for testing.
-  SetInt(LastRotationPath(kProjectOneHash), start_day);
+  MakeKeyData();
+  const uint64_t first_id = key_data_->Id(kProjectOneHash);
+  ExpectKeyValidation(/*valid=*/1, /*created=*/0, /*rotated=*/0);
 
   {
     // Advancing by 50 days, the key should not be rotated.
-    key_data_.reset();
     time_.Advance(base::TimeDelta::FromDays(50));
-    StandardSetup();
-    EXPECT_EQ(key_data_->UserProjectId(kProjectOneHash), first_id);
-    EXPECT_EQ(GetInt(LastRotationPath(kProjectOneHash)), start_day);
+    EXPECT_EQ(key_data_->Id(kProjectOneHash), first_id);
+    SaveKeyData();
+
+    ASSERT_EQ(GetKey(kProjectOneHash).last_rotation(), start_day);
+    ExpectKeyValidation(/*valid=*/2, /*created=*/0, /*rotated=*/0);
   }
 
   {
     // Advancing by another 50 days, the key should be rotated and the last
     // rotation day should be incremented by 90.
-    key_data_.reset();
     time_.Advance(base::TimeDelta::FromDays(50));
-    StandardSetup();
-    EXPECT_NE(key_data_->UserProjectId(kProjectOneHash), first_id);
-    EXPECT_EQ(GetInt(LastRotationPath(kProjectOneHash)), start_day + 90);
+    EXPECT_NE(key_data_->Id(kProjectOneHash), first_id);
+    SaveKeyData();
+
+    EXPECT_EQ(GetKey(kProjectOneHash).last_rotation(), start_day + 90);
+    ExpectKeyValidation(/*valid=*/2, /*created=*/0, /*rotated=*/1);
+
+    // The rotation period could change here if it were ever updated in the xml.
+    // This test relies on it being 90 days.
+    ASSERT_EQ(GetKey(kProjectOneHash).rotation_period(), 90);
   }
 
   {
     // Advancing by 453 days, the last rotation day should now 6 periods of 90
     // days ahead.
-    key_data_.reset();
     time_.Advance(base::TimeDelta::FromDays(453));
-    StandardSetup();
-    EXPECT_EQ(GetInt(LastRotationPath(kProjectOneHash)), start_day + 6 * 90);
+    key_data_->Id(kProjectOneHash);
+    SaveKeyData();
+
+    EXPECT_EQ(GetKey(kProjectOneHash).last_rotation(), start_day + 6 * 90);
+    ExpectKeyValidation(/*valid=*/2, /*created=*/0, /*rotated=*/2);
   }
 }
 
-}  // namespace internal
 }  // namespace structured
 }  // namespace metrics
diff --git a/components/metrics/structured/structured_metrics_provider.cc b/components/metrics/structured/structured_metrics_provider.cc
index b7b93cb..6494d7fe 100644
--- a/components/metrics/structured/structured_metrics_provider.cc
+++ b/components/metrics/structured/structured_metrics_provider.cc
@@ -87,6 +87,8 @@
 
 char StructuredMetricsProvider::kStorageFileName[] = "structured_metrics.json";
 
+char StructuredMetricsProvider::kStorageDirectory[] = "structured_metrics";
+
 StructuredMetricsProvider::StructuredMetricsProvider() = default;
 
 StructuredMetricsProvider::~StructuredMetricsProvider() {
@@ -182,38 +184,8 @@
   if (!recording_enabled_ || !initialized_)
     return;
 
-  // Make a list of metrics.
-  base::Value metrics(base::Value::Type::LIST);
-  for (const auto& metric : event.metrics()) {
-    base::Value name_value(base::Value::Type::DICTIONARY);
-    name_value.SetStringKey("name", base::NumberToString(metric.name_hash));
-
-    if (metric.type == EventBase::MetricType::kString) {
-      // Store hashed values as strings, because the JSON parser only retains 53
-      // bits of precision for ints. This would corrupt the hashes.
-      name_value.SetStringKey("value",
-                              base::NumberToString(key_data_->HmacMetric(
-                                  event.project_name_hash(), metric.name_hash,
-                                  metric.string_value)));
-    } else if (metric.type == EventBase::MetricType::kInt) {
-      name_value.SetIntKey("value", metric.int_value);
-    }
-
-    metrics.Append(std::move(name_value));
-  }
-
-  // Create an event value containing the metrics, the event name hash, and the
-  // ID that will eventually be used as the profile_event_id of this event.
-  base::Value event_value(base::Value::Type::DICTIONARY);
-  event_value.SetStringKey("name", base::NumberToString(event.name_hash()));
-  event_value.SetStringKey("id", base::NumberToString(key_data_->UserProjectId(
-                                     event.project_name_hash())));
-  event_value.SetKey("metrics", std::move(metrics));
-
-  // Add the event to |storage_|.
-  // TODO(crbug.com/1016655): Choose the event list based on the identifier type
-  // of the event subclass.
-  GetEventsList(StorageType::kAssociated)->Append(std::move(event_value));
+  // TODO(crbug.com/1148168): Reimplement recording using proto instead of json
+  // storage.
 }
 
 void StructuredMetricsProvider::OnProfileAdded(
@@ -234,7 +206,11 @@
   if (!success)
     return;
   DCHECK(!storage_->ReadOnly());
-  key_data_ = std::make_unique<internal::KeyData>(storage_.get());
+  // TODO(crbug.com/1148168): Replace storage_directory with a member once we
+  // use it for StructuredMetricsProvider as well as KeyData.
+  const base::FilePath storage_directory(kStorageDirectory);
+  key_data_ = std::make_unique<KeyData>(storage_directory.Append("keys"),
+                                        base::DoNothing());
   initialized_ = true;
 }
 
diff --git a/components/metrics/structured/structured_metrics_provider.h b/components/metrics/structured/structured_metrics_provider.h
index 92f1167..3a0a44a 100644
--- a/components/metrics/structured/structured_metrics_provider.h
+++ b/components/metrics/structured/structured_metrics_provider.h
@@ -136,6 +136,10 @@
   // The basename of the file to store key data and unsent logs. A JsonPrefStore
   // is initialized at {profile_path}/{kStorageFileName}.
   static char kStorageFileName[];
+  // TODO(crbug.com/1016655): This is here just for the sake of KeyData. We will
+  // also use it for the provider itself soon. The directory to store keys and
+  // events in. Relative to the user's cryptohome.
+  static char kStorageDirectory[];
 
   // Whether the metrics provider has completed initialization. Initialization
   // occurs across OnProfileAdded and OnInitializationCompleted. No incoming
@@ -173,7 +177,7 @@
 
   // Storage for all event's keys, and hashing logic for values. This stores
   // keys on-disk using the |storage_| JsonPrefStore.
-  std::unique_ptr<internal::KeyData> key_data_;
+  std::unique_ptr<KeyData> key_data_;
 
   base::WeakPtrFactory<StructuredMetricsProvider> weak_factory_{this};
 };
diff --git a/components/metrics/structured/structured_metrics_provider_unittest.cc b/components/metrics/structured/structured_metrics_provider_unittest.cc
index 218a8de..7081aad 100644
--- a/components/metrics/structured/structured_metrics_provider_unittest.cc
+++ b/components/metrics/structured/structured_metrics_provider_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/files/important_file_writer.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/json/json_reader.h"
+#include "base/logging.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
@@ -16,6 +17,7 @@
 #include "base/values.h"
 #include "components/metrics/structured/event_base.h"
 #include "components/metrics/structured/recorder.h"
+#include "components/metrics/structured/storage.pb.h"
 #include "components/metrics/structured/structured_events.h"
 #include "components/prefs/json_pref_store.h"
 #include "components/prefs/persistent_pref_store.h"
@@ -38,26 +40,10 @@
 //   - event: TestEventThree
 //     - metric: TestMetricFour
 
-// To test that the right values are calculated for hashed metrics, we need to
-// set up some fake keys that we know the output hashes for. kKeyData contains
-// the JSON for a simple structured_metrics.json file with keys for the test
-// projects, "TestProjectOne" and "TestProjectTwo".
-// TODO(crbug.com/1016655): Once custom rotation periods have been implemented,
-// change the large constants to 0.
-constexpr char kKeyData[] = R"({
-  "keys":{
-    "16881314472396226433":{
-      "rotation_period":1000000,
-      "last_rotation":1000000,
-      "key":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-    },
-    "5876808001962504629":{
-      "rotation_period":1000000,
-      "last_rotation":1000000,
-      "key":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
-    }
-  }
-})";
+// The name hash of "TestProjectOne".
+constexpr uint64_t kProjectOneHash = UINT64_C(16881314472396226433);
+// The name hash of "TestProjectTwo".
+constexpr uint64_t kProjectTwoHash = UINT64_C(15619026293081468407);
 
 // The name hash of "chrome::TestProjectOne::TestEventOne".
 constexpr uint64_t kEventOneHash = UINT64_C(13593049295042080097);
@@ -72,8 +58,6 @@
 constexpr uint64_t kMetricTwoHash = UINT64_C(14083999144141567134);
 // The name hash of "TestMetricThree".
 constexpr uint64_t kMetricThreeHash = UINT64_C(13469300759843809564);
-// The name hash of "TestMetricFour".
-// constexpr uint64_t kMetricFourHash = UINT64_C(13469300759843809564);
 
 // The hex-encoded first 8 bytes of SHA256("aaa...a")
 constexpr char kProjectOneId[] = "3BA3F5F43B926026";
@@ -101,12 +85,28 @@
 
   base::FilePath TempDirPath() { return temp_dir_.GetPath(); }
 
+  base::FilePath KeyFilePath() {
+    return temp_dir_.GetPath().Append("structured_metrics").Append("keys");
+  }
+
   void Wait() { task_environment_.RunUntilIdle(); }
 
   void WriteTestingKeys() {
-    CHECK(base::ImportantFileWriter::WriteFileAtomically(
-        TempDirPath().Append("structured_metrics.json"), kKeyData,
-        "StructuredMetricsProviderTest"));
+    const int today = (base::Time::Now() - base::Time::UnixEpoch()).InDays();
+
+    KeyDataProto proto;
+    KeyProto& key_one = (*proto.mutable_keys())[kProjectOneHash];
+    key_one.set_key("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+    key_one.set_last_rotation(today);
+    key_one.set_rotation_period(90);
+
+    KeyProto& key_two = (*proto.mutable_keys())[kProjectTwoHash];
+    key_two.set_key("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+    key_two.set_last_rotation(today);
+    key_two.set_rotation_period(90);
+
+    base::CreateDirectory(KeyFilePath().DirName());
+    ASSERT_TRUE(base::WriteFile(KeyFilePath(), proto.SerializeAsString()));
   }
 
   // Simulates the three external events that the structure metrics system cares
@@ -221,7 +221,7 @@
   ExpectOnlyFileReadError();
 }
 
-TEST_F(StructuredMetricsProviderTest, RecordedEventAppearsInReport) {
+TEST_F(StructuredMetricsProviderTest, DISABLED_RecordedEventAppearsInReport) {
   Init();
 
   events::test_project_one::TestEventOne()
@@ -241,7 +241,7 @@
   ExpectOnlyFileReadError();
 }
 
-TEST_F(StructuredMetricsProviderTest, EventsReportedCorrectly) {
+TEST_F(StructuredMetricsProviderTest, DISABLED_EventsReportedCorrectly) {
   WriteTestingKeys();
   Init();
 
@@ -298,7 +298,8 @@
   histogram_tester_.ExpectTotalCount("UMA.StructuredMetrics.PrefReadError", 0);
 }
 
-TEST_F(StructuredMetricsProviderTest, EventsWithinProjectReportedWithSameID) {
+TEST_F(StructuredMetricsProviderTest,
+       DISABLED_EventsWithinProjectReportedWithSameID) {
   WriteTestingKeys();
   Init();
 
@@ -330,7 +331,7 @@
 
 // Test that a call to ProvideCurrentSessionData clears the provided events from
 // the cache, and a subsequent call does not return those events again.
-TEST_F(StructuredMetricsProviderTest, EventsClearedAfterReport) {
+TEST_F(StructuredMetricsProviderTest, DISABLED_EventsClearedAfterReport) {
   Init();
 
   events::test_project_one::TestEventOne().SetTestMetricTwo(1).Record();
@@ -350,7 +351,8 @@
 
 // Test that events recorded in one session are correctly persisted and are
 // uploaded in the first report from a subsequent session.
-TEST_F(StructuredMetricsProviderTest, EventsFromPreviousSessionAreReported) {
+TEST_F(StructuredMetricsProviderTest,
+       DISABLED_EventsFromPreviousSessionAreReported) {
   // Start first session and record one event.
   Init();
   events::test_project_one::TestEventOne().SetTestMetricTwo(1234).Record();
@@ -406,7 +408,7 @@
 
 // Ensure that recording and reporting is re-enabled after recording is disabled
 // and then enabled again.
-TEST_F(StructuredMetricsProviderTest, ReportingResumesWhenEnabled) {
+TEST_F(StructuredMetricsProviderTest, DISABLED_ReportingResumesWhenEnabled) {
   Init();
   events::test_project_one::TestEventOne().SetTestMetricTwo(1).Record();
   events::test_project_one::TestEventOne().SetTestMetricTwo(1).Record();
@@ -433,45 +435,5 @@
   EXPECT_EQ(GetStructuredData().events_size(), 0);
 }
 
-// Ensure an old structured_metrics.json file correctly migrates to the new
-// format
-TEST_F(StructuredMetricsProviderTest, MigrateEventsKey) {
-  const auto json_path = TempDirPath().Append("structured_metrics.json");
-
-  // Write a json file with the old format.
-  const std::string old_json = R"({
-    "events":[
-      {"id":"some_id",
-       "metrics":[{
-          "name":"some_name",
-          "value":"some_value"}]}]
-  })";
-  CHECK(base::ImportantFileWriter::WriteFileAtomically(
-      TempDirPath().Append("structured_metrics.json"), old_json,
-      "StructuredMetricsProviderTest"));
-
-  // Initialize and trigger a migration by recording an event.
-  Init();
-  events::test_project_one::TestEventOne().SetTestMetricTwo(1).Record();
-  CommitPendingWrite();
-
-  // Check that the new format has the structure:
-  // {"events": {"associated": [{...}, {...}]}}
-  std::string new_json;
-  ASSERT_TRUE(base::ReadFileToString(json_path, &new_json));
-  const auto value = base::JSONReader::Read(new_json);
-  ASSERT_TRUE(value.has_value());
-
-  const auto* events = value.value().FindKey("events");
-  ASSERT_TRUE(events != nullptr);
-  ASSERT_TRUE(events->is_dict());
-  ASSERT_EQ(events->DictSize(), 1U);
-
-  const auto* associated = events->FindKey("associated");
-  ASSERT_TRUE(associated != nullptr);
-  ASSERT_TRUE(associated->is_list());
-  ASSERT_EQ(associated->GetList().size(), 2U);
-}
-
 }  // namespace structured
 }  // namespace metrics
diff --git a/components/ntp_snippets_strings.grdp b/components/ntp_snippets_strings.grdp
index 90d7754b..9a1bdba 100644
--- a/components/ntp_snippets_strings.grdp
+++ b/components/ntp_snippets_strings.grdp
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <grit-part>
 
-  <if expr="enable_feed_v1 or is_ios">
+  <if expr="is_ios">
     <message name="IDS_NTP_TITLE_NO_SUGGESTIONS" desc="On the New Tab Page, title text explaining there is no content." formatter_data="android_java">
       That’s all for now
     </message>
diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc
index 8e51df1..eb74ec2 100644
--- a/components/omnibox/browser/autocomplete_match.cc
+++ b/components/omnibox/browser/autocomplete_match.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/check_op.h"
+#include "base/debug/crash_logging.h"
 #include "base/feature_list.h"
 #include "base/i18n/case_conversion.h"
 #include "base/metrics/histogram_macros.h"
@@ -121,6 +122,22 @@
 }
 
 // static
+bool AutocompleteMatch::DocumentTypeFromInteger(int value,
+                                                DocumentType* result) {
+  DCHECK(result);
+
+  // The resulting value may still be invalid after the static_cast.
+  DocumentType document_type = static_cast<DocumentType>(value);
+  if (document_type >= DocumentType::NONE &&
+      document_type < DocumentType::DOCUMENT_TYPE_SIZE) {
+    *result = document_type;
+    return true;
+  }
+
+  return false;
+}
+
+// static
 const base::char16 AutocompleteMatch::kInvalidChars[] = {
   '\n', '\r', '\t',
   0x2028,  // Line separator
@@ -260,6 +277,11 @@
 #if (!defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS)
 const gfx::VectorIcon& AutocompleteMatch::GetVectorIcon(
     bool is_bookmark) const {
+  // TODO(https://crbug.com/1024114): Remove crash logging once fixed.
+  SCOPED_CRASH_KEY_NUMBER("AutocompleteMatch", "type", type);
+  SCOPED_CRASH_KEY_NUMBER("AutocompleteMatch", "provider_type",
+                          provider ? provider->type() : -1);
+
   if (is_bookmark)
     return omnibox::kBookmarkIcon;
   switch (type) {
diff --git a/components/omnibox/browser/autocomplete_match.h b/components/omnibox/browser/autocomplete_match.h
index bf830c96..aecaa093 100644
--- a/components/omnibox/browser/autocomplete_match.h
+++ b/components/omnibox/browser/autocomplete_match.h
@@ -178,6 +178,12 @@
   // Return a string version of the core type values.
   static const char* DocumentTypeString(DocumentType type);
 
+  // Use this function to convert integers to DocumentType enum values.
+  // If you're sure it will be valid, you can call CHECK on the return value.
+  // Returns true if |value| was successfully converted to a valid enum value.
+  // The valid enum value will be written into |result|.
+  static bool DocumentTypeFromInteger(int value, DocumentType* result);
+
   AutocompleteMatch();
   AutocompleteMatch(AutocompleteProvider* provider,
                     int relevance,
diff --git a/components/omnibox/browser/autocomplete_match_type.cc b/components/omnibox/browser/autocomplete_match_type.cc
index b83a9c81..dea3cfc 100644
--- a/components/omnibox/browser/autocomplete_match_type.cc
+++ b/components/omnibox/browser/autocomplete_match_type.cc
@@ -57,6 +57,18 @@
   return strings[type];
 }
 
+// static
+bool AutocompleteMatchType::FromInteger(int value, Type* result) {
+  DCHECK(result);
+
+  if (value < Type::URL_WHAT_YOU_TYPED || value >= Type::NUM_TYPES) {
+    return false;
+  }
+
+  *result = static_cast<Type>(value);
+  return true;
+}
+
 static const wchar_t kAccessibilityLabelPrefixEndSentinal[] =
     L"\uFFFC";  // Embedded object character.
 
diff --git a/components/omnibox/browser/autocomplete_match_type.h b/components/omnibox/browser/autocomplete_match_type.h
index e7a2dfb..cdf2e7d 100644
--- a/components/omnibox/browser/autocomplete_match_type.h
+++ b/components/omnibox/browser/autocomplete_match_type.h
@@ -81,6 +81,12 @@
   // Converts |type| to a string representation. Used in logging.
   static std::string ToString(AutocompleteMatchType::Type type);
 
+  // Use this function to convert integers to AutocompleteMatchType enum values.
+  // If you're sure it will be valid, you can call CHECK on the return value.
+  // Returns true if |value| was successfully converted to a valid enum value.
+  // The valid enum value will be written into |result|.
+  static bool FromInteger(int value, Type* result);
+
   // Returns the accessibility label for an AutocompleteMatch |match|
   // whose text is |match_text| The accessibility label describes the
   // match for use in a screenreader or other assistive technology.
diff --git a/components/omnibox/browser/shortcuts_backend.cc b/components/omnibox/browser/shortcuts_backend.cc
index 926cead7..363b464 100644
--- a/components/omnibox/browser/shortcuts_backend.cc
+++ b/components/omnibox/browser/shortcuts_backend.cc
@@ -178,8 +178,7 @@
 
   return ShortcutsDatabase::Shortcut::MatchCore(
       normalized_match->fill_into_edit, normalized_match->destination_url,
-      static_cast<int>(normalized_match->document_type),
-      normalized_match->contents,
+      normalized_match->document_type, normalized_match->contents,
       StripMatchMarkers(normalized_match->contents_class), description,
       StripMatchMarkers(description_class), normalized_match->transition,
       match_type, normalized_match->keyword);
diff --git a/components/omnibox/browser/shortcuts_database.cc b/components/omnibox/browser/shortcuts_database.cc
index d408bb54..ee0c19e 100644
--- a/components/omnibox/browser/shortcuts_database.cc
+++ b/components/omnibox/browser/shortcuts_database.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "base/guid.h"
 #include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
 #include "components/omnibox/browser/autocomplete_match_type.h"
@@ -36,13 +37,13 @@
   s->BindString16(1, shortcut.text);
   s->BindString16(2, shortcut.match_core.fill_into_edit);
   s->BindString(3, shortcut.match_core.destination_url.spec());
-  s->BindInt(4, shortcut.match_core.document_type);
+  s->BindInt(4, base::checked_cast<int>(shortcut.match_core.document_type));
   s->BindString16(5, shortcut.match_core.contents);
   s->BindString(6, shortcut.match_core.contents_class);
   s->BindString16(7, shortcut.match_core.description);
   s->BindString(8, shortcut.match_core.description_class);
-  s->BindInt(9, shortcut.match_core.transition);
-  s->BindInt(10, shortcut.match_core.type);
+  s->BindInt(9, base::checked_cast<int>(shortcut.match_core.transition));
+  s->BindInt(10, base::checked_cast<int>(shortcut.match_core.type));
   s->BindString16(11, shortcut.match_core.keyword);
   s->BindInt64(12, shortcut.last_access_time.ToInternalValue());
   s->BindInt(13, shortcut.number_of_hits);
@@ -91,13 +92,13 @@
 ShortcutsDatabase::Shortcut::MatchCore::MatchCore(
     const base::string16& fill_into_edit,
     const GURL& destination_url,
-    int document_type,
+    AutocompleteMatch::DocumentType document_type,
     const base::string16& contents,
     const std::string& contents_class,
     const base::string16& description,
     const std::string& description_class,
-    int transition,
-    int type,
+    ui::PageTransition transition,
+    AutocompleteMatchType::Type type,
     const base::string16& keyword)
     : fill_into_edit(fill_into_edit),
       destination_url(destination_url),
@@ -134,13 +135,16 @@
 ShortcutsDatabase::Shortcut::Shortcut()
     : match_core(base::string16(),
                  GURL(),
-                 0,
+                 AutocompleteMatch::DocumentType::NONE,
                  base::string16(),
                  std::string(),
                  base::string16(),
                  std::string(),
-                 0,
-                 0,
+                 ui::PageTransition::PAGE_TRANSITION_FIRST,
+                 // AutocompleteMatchType doesn't have a sentinel or null value,
+                 // so we just use the value equal to 0. This constructor is
+                 // only used by STL anyways, so this is harmless.
+                 AutocompleteMatchType::Type::URL_WHAT_YOU_TYPED,
                  base::string16()),
       last_access_time(base::Time::Now()),
       number_of_hits(0) {}
@@ -234,25 +238,42 @@
 
   shortcuts->clear();
   while (s.Step()) {
+    // Some users have corrupt data in their SQL database. That causes crashes.
+    // Therefore, validate the integral values first. https://crbug.com/1024114
+    AutocompleteMatch::DocumentType document_type;
+    if (!AutocompleteMatch::DocumentTypeFromInteger(s.ColumnInt(4),
+                                                    &document_type)) {
+      continue;
+    }
+
+    AutocompleteMatchType::Type type;
+    if (!AutocompleteMatchType::FromInteger(s.ColumnInt(10), &type))
+      continue;
+
+    const int page_transition_integer = s.ColumnInt(9);
+    if (!ui::PageTransitionIsValidType(page_transition_integer))
+      continue;
+    ui::PageTransition transition =
+        ui::PageTransitionFromInt(page_transition_integer);
+
     shortcuts->insert(std::make_pair(
         s.ColumnString(0),
         Shortcut(
-            s.ColumnString(0),            // id
-            s.ColumnString16(1),          // text
-            Shortcut::MatchCore(
-                s.ColumnString16(2),      // fill_into_edit
-                GURL(s.ColumnString(3)),  // destination_url
-                s.ColumnInt(4),           // document_type
-                s.ColumnString16(5),      // contents
-                s.ColumnString(6),        // contents_class
-                s.ColumnString16(7),      // description
-                s.ColumnString(8),        // description_class
-                s.ColumnInt(9),           // transition
-                s.ColumnInt(10),          // type
-                s.ColumnString16(11)),    // keyword
+            s.ColumnString(0),                            // id
+            s.ColumnString16(1),                          // text
+            Shortcut::MatchCore(s.ColumnString16(2),      // fill_into_edit
+                                GURL(s.ColumnString(3)),  // destination_url
+                                document_type,            // document_type
+                                s.ColumnString16(5),      // contents
+                                s.ColumnString(6),        // contents_class
+                                s.ColumnString16(7),      // description
+                                s.ColumnString(8),        // description_class
+                                transition,               // transition
+                                type,                     // type
+                                s.ColumnString16(11)),    // keyword
             base::Time::FromInternalValue(s.ColumnInt64(12)),
-                                          // last_access_time
-            s.ColumnInt(13))));           // number_of_hits
+            // last_access_time
+            s.ColumnInt(13))));  // number_of_hits
   }
 }
 
diff --git a/components/omnibox/browser/shortcuts_database.h b/components/omnibox/browser/shortcuts_database.h
index ff9f646..3791321 100644
--- a/components/omnibox/browser/shortcuts_database.h
+++ b/components/omnibox/browser/shortcuts_database.h
@@ -13,8 +13,11 @@
 #include "base/gtest_prod_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/strings/string16.h"
+#include "components/omnibox/browser/autocomplete_match.h"
+#include "components/omnibox/browser/autocomplete_match_type.h"
 #include "sql/database.h"
 #include "sql/meta_table.h"
+#include "ui/base/page_transition_types.h"
 #include "url/gurl.h"
 
 // This class manages the shortcut provider table within the SQLite database
@@ -43,20 +46,20 @@
     struct MatchCore {
       MatchCore(const base::string16& fill_into_edit,
                 const GURL& destination_url,
-                int document_type,
+                AutocompleteMatch::DocumentType document_type,
                 const base::string16& contents,
                 const std::string& contents_class,
                 const base::string16& description,
                 const std::string& description_class,
-                int transition,
-                int type,
+                ui::PageTransition transition,
+                AutocompleteMatchType::Type type,
                 const base::string16& keyword);
       MatchCore(const MatchCore& other);
       ~MatchCore();
 
       base::string16 fill_into_edit;
       GURL destination_url;
-      int document_type;
+      AutocompleteMatch::DocumentType document_type;
       base::string16 contents;
       // For both contents_class and description_class, we strip MATCH
       // classifications; the ShortcutsProvider will re-mark MATCH regions based
@@ -64,8 +67,8 @@
       std::string contents_class;
       base::string16 description;
       std::string description_class;
-      int transition;
-      int type;
+      ui::PageTransition transition;
+      AutocompleteMatchType::Type type;
       base::string16 keyword;
     };
 
diff --git a/components/omnibox/browser/shortcuts_database_unittest.cc b/components/omnibox/browser/shortcuts_database_unittest.cc
index da795b0..71d127c 100644
--- a/components/omnibox/browser/shortcuts_database_unittest.cc
+++ b/components/omnibox/browser/shortcuts_database_unittest.cc
@@ -178,10 +178,9 @@
       info.guid, ASCIIToUTF16(info.text),
       ShortcutsDatabase::Shortcut::MatchCore(
           ASCIIToUTF16(info.fill_into_edit), GURL(info.destination_url),
-          static_cast<int>(info.document_type), ASCIIToUTF16(info.contents),
-          info.contents_class, ASCIIToUTF16(info.description),
-          info.description_class, info.transition, info.type,
-          ASCIIToUTF16(info.keyword)),
+          info.document_type, ASCIIToUTF16(info.contents), info.contents_class,
+          ASCIIToUTF16(info.description), info.description_class,
+          info.transition, info.type, ASCIIToUTF16(info.keyword)),
       base::Time::Now() - base::TimeDelta::FromDays(info.days_from_now),
       info.number_of_hits);
 }
diff --git a/components/omnibox/browser/shortcuts_provider.cc b/components/omnibox/browser/shortcuts_provider.cc
index bc5535c..ed773f4 100644
--- a/components/omnibox/browser/shortcuts_provider.cc
+++ b/components/omnibox/browser/shortcuts_provider.cc
@@ -67,7 +67,7 @@
         stripped_destination_url(stripped_destination_url),
         shortcut(shortcut),
         contents(shortcut->match_core.contents),
-        type(static_cast<AutocompleteMatch::Type>(shortcut->match_core.type)) {}
+        type(shortcut->match_core.type) {}
 
   int relevance;
   // To satisfy |CompareWithDemoteByType<>::operator()|.
@@ -253,16 +253,15 @@
   match.fill_into_edit = shortcut.match_core.fill_into_edit;
   match.destination_url = shortcut.match_core.destination_url;
   DCHECK(match.destination_url.is_valid());
-  match.document_type = static_cast<AutocompleteMatch::DocumentType>(
-      shortcut.match_core.document_type);
+  match.document_type = shortcut.match_core.document_type;
   match.contents = shortcut.match_core.contents;
   match.contents_class = AutocompleteMatch::ClassificationsFromString(
       shortcut.match_core.contents_class);
   match.description = shortcut.match_core.description;
   match.description_class = AutocompleteMatch::ClassificationsFromString(
       shortcut.match_core.description_class);
-  match.transition = ui::PageTransitionFromInt(shortcut.match_core.transition);
-  match.type = static_cast<AutocompleteMatch::Type>(shortcut.match_core.type);
+  match.transition = shortcut.match_core.transition;
+  match.type = shortcut.match_core.type;
   match.keyword = shortcut.match_core.keyword;
   match.RecordAdditionalInfo("number of hits", shortcut.number_of_hits);
   match.RecordAdditionalInfo("last access time", shortcut.last_access_time);
diff --git a/components/omnibox/browser/shortcuts_provider_test_util.cc b/components/omnibox/browser/shortcuts_provider_test_util.cc
index d63c82e0..79f36ac 100644
--- a/components/omnibox/browser/shortcuts_provider_test_util.cc
+++ b/components/omnibox/browser/shortcuts_provider_test_util.cc
@@ -57,10 +57,10 @@
         cur.guid, base::ASCIIToUTF16(cur.text),
         ShortcutsDatabase::Shortcut::MatchCore(
             base::ASCIIToUTF16(cur.fill_into_edit), GURL(cur.destination_url),
-            static_cast<int>(cur.document_type),
-            base::ASCIIToUTF16(cur.contents), cur.contents_class,
-            base::ASCIIToUTF16(cur.description), cur.description_class,
-            cur.transition, cur.type, base::ASCIIToUTF16(cur.keyword)),
+            cur.document_type, base::ASCIIToUTF16(cur.contents),
+            cur.contents_class, base::ASCIIToUTF16(cur.description),
+            cur.description_class, cur.transition, cur.type,
+            base::ASCIIToUTF16(cur.keyword)),
         base::Time::Now() - base::TimeDelta::FromDays(cur.days_from_now),
         cur.number_of_hits);
     backend->AddShortcut(shortcut);
diff --git a/components/omnibox/browser/shortcuts_provider_unittest.cc b/components/omnibox/browser/shortcuts_provider_unittest.cc
index 591ebd9..6a78ce8 100644
--- a/components/omnibox/browser/shortcuts_provider_unittest.cc
+++ b/components/omnibox/browser/shortcuts_provider_unittest.cc
@@ -460,10 +460,10 @@
       std::string(), ASCIIToUTF16("test"),
       ShortcutsDatabase::Shortcut::MatchCore(
           ASCIIToUTF16("www.test.com"), GURL("http://www.test.com"),
-          static_cast<int>(AutocompleteMatch::DocumentType::NONE),
-          ASCIIToUTF16("www.test.com"), "0,1,4,3,8,1", ASCIIToUTF16("A test"),
-          "0,0,2,2", ui::PAGE_TRANSITION_TYPED,
-          AutocompleteMatchType::HISTORY_URL, base::string16()),
+          AutocompleteMatch::DocumentType::NONE, ASCIIToUTF16("www.test.com"),
+          "0,1,4,3,8,1", ASCIIToUTF16("A test"), "0,0,2,2",
+          ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_URL,
+          base::string16()),
       base::Time::Now(), 1);
 
   // Maximal score.
diff --git a/components/paint_preview/player/android/BUILD.gn b/components/paint_preview/player/android/BUILD.gn
index 1c8bf82..2a3e015 100644
--- a/components/paint_preview/player/android/BUILD.gn
+++ b/components/paint_preview/player/android/BUILD.gn
@@ -111,7 +111,7 @@
     "//base:jni_java",
     "//components/paint_preview/browser/android:java",
     "//components/signin/core/browser/android:java",
-    "//components/signin/core/browser/android:signin_java_test_support",
+    "//components/signin/public/android:signin_java_test_support",
     "//content/public/android:content_java",
     "//content/public/test/android:content_java_test_support",
     "//third_party/android_support_test_runner:rules_java",
diff --git a/components/password_manager/core/browser/password_save_manager_impl.cc b/components/password_manager/core/browser/password_save_manager_impl.cc
index 5da06625..c66300e 100644
--- a/components/password_manager/core/browser/password_save_manager_impl.cc
+++ b/components/password_manager/core/browser/password_save_manager_impl.cc
@@ -188,8 +188,6 @@
               form_fetcher_->GetAllRelevantMatches(),
               parsed_submitted_form.username_value,
               parsed_submitted_form.password_value);
-      UMA_HISTOGRAM_BOOLEAN("PasswordManager.UsernameCorrectionFound",
-                            username_correction_found);
       if (username_correction_found) {
         metrics_recorder_->RecordDetailedUserAction(
             password_manager::PasswordFormMetricsRecorder::DetailedUserAction::
diff --git a/components/policy/android/BUILD.gn b/components/policy/android/BUILD.gn
index 301b826..c737fd8d 100644
--- a/components/policy/android/BUILD.gn
+++ b/components/policy/android/BUILD.gn
@@ -6,6 +6,7 @@
 
 _jni_sources = [
   "java/src/org/chromium/components/policy/CombinedPolicyProvider.java",
+  "java/src/org/chromium/components/policy/PolicyCacheUpdater.java",
   "java/src/org/chromium/components/policy/PolicyConverter.java",
   "java/src/org/chromium/components/policy/PolicyMap.java",
   "java/src/org/chromium/components/policy/PolicyService.java",
@@ -81,6 +82,7 @@
 }
 
 _test_jni_sources = [
+  "javatests/src/org/chromium/components/policy/test/PolicyCacheUpdaterTestSupporter.java",
   "javatests/src/org/chromium/components/policy/test/PolicyMapTestSupporter.java",
   "javatests/src/org/chromium/components/policy/test/PolicyServiceTestSupporter.java",
 ]
diff --git a/components/policy/android/java/src/org/chromium/components/policy/PolicyCache.java b/components/policy/android/java/src/org/chromium/components/policy/PolicyCache.java
index 7cf2c42..94f127a 100644
--- a/components/policy/android/java/src/org/chromium/components/policy/PolicyCache.java
+++ b/components/policy/android/java/src/org/chromium/components/policy/PolicyCache.java
@@ -222,4 +222,9 @@
     static void resetForTesting() {
         sPolicyCache = null;
     }
+
+    @VisibleForTesting
+    public void setReadableForTesting(boolean readable) {
+        mReadable = readable;
+    }
 }
diff --git a/components/policy/android/java/src/org/chromium/components/policy/PolicyCacheUpdater.java b/components/policy/android/java/src/org/chromium/components/policy/PolicyCacheUpdater.java
new file mode 100644
index 0000000..1103699
--- /dev/null
+++ b/components/policy/android/java/src/org/chromium/components/policy/PolicyCacheUpdater.java
@@ -0,0 +1,33 @@
+// 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.components.policy;
+
+import android.util.Pair;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Helper class to allow native libirary to update policy cache with {@link PolicyCache}
+ */
+
+@JNINamespace("policy::android")
+public class PolicyCacheUpdater {
+    // A list of policies that will be cached. Note that policy won't be cached in case of any error
+    // including but limited to one of following situations:
+    //  1) Dangerous policies is ignored on non-fully managed devices.
+    //  2) Policy is deprecated and overridden by its replacement.
+    //  3) Any error set by ConfigurationPolicyHandler.
+    static List<Pair<String, PolicyCache.Type>> sPolicies =
+            Arrays.asList(Pair.create("BrowserSignin", PolicyCache.Type.Integer));
+
+    @CalledByNative
+    public static void cachePolicies(PolicyMap policyMap) {
+        PolicyCache.get().cachePolicies(policyMap, sPolicies);
+    }
+}
diff --git a/components/policy/android/javatests/src/org/chromium/components/policy/test/PolicyCacheUpdaterTestSupporter.java b/components/policy/android/javatests/src/org/chromium/components/policy/test/PolicyCacheUpdaterTestSupporter.java
new file mode 100644
index 0000000..011b9a0
--- /dev/null
+++ b/components/policy/android/javatests/src/org/chromium/components/policy/test/PolicyCacheUpdaterTestSupporter.java
@@ -0,0 +1,38 @@
+// 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.components.policy.test;
+
+import org.junit.Assert;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.components.policy.PolicyCache;
+import org.chromium.components.policy.PolicyCacheUpdater;
+
+/**
+ * Native unit test helper class for {@link PolicyCacheUpdater}
+ *
+ * It's used by the unit test in
+ * //components/policy/core/browser/android/policy_cache_updater_android_unittest.cc
+ *
+ */
+@JNINamespace("policy::android")
+public class PolicyCacheUpdaterTestSupporter {
+    @CalledByNative
+    private PolicyCacheUpdaterTestSupporter() {}
+
+    @CalledByNative
+    private void verifyPolicyCacheIntValue(String policy, boolean hasValue, int expectedValue) {
+        PolicyCache policyCache = PolicyCache.get();
+        policyCache.setReadableForTesting(true);
+        Integer actualValue = policyCache.getIntValue(policy);
+        if (hasValue) {
+            Assert.assertNotNull(actualValue);
+            Assert.assertEquals(expectedValue, actualValue.intValue());
+        } else {
+            Assert.assertNull(actualValue);
+        }
+    }
+}
diff --git a/components/policy/core/browser/BUILD.gn b/components/policy/core/browser/BUILD.gn
index 8d5486fb..58fd373e 100644
--- a/components/policy/core/browser/BUILD.gn
+++ b/components/policy/core/browser/BUILD.gn
@@ -66,6 +66,14 @@
     "//url",
   ]
 
+  if (is_android) {
+    sources += [
+      "android/policy_cache_updater_android.cc",
+      "android/policy_cache_updater_android.h",
+    ]
+    deps += [ "//components/policy/android:jni_headers" ]
+  }
+
   public_deps += [ "//components/policy/core/common:internal" ]
   deps += [
     "//components/proxy_config",
@@ -115,6 +123,7 @@
     "configuration_policy_handler_list_unittest.cc",
     "configuration_policy_handler_unittest.cc",
     "configuration_policy_pref_store_unittest.cc",
+    "policy_error_map_unittest.cc",
     "proxy_policy_handler_unittest.cc",
     "url_blocklist_manager_unittest.cc",
     "url_blocklist_policy_handler_unittest.cc",
@@ -132,6 +141,12 @@
     "//net",
     "//testing/gmock",
     "//testing/gtest",
+    "//ui/base",
     "//url",
   ]
+
+  if (is_android) {
+    sources += [ "android/policy_cache_updater_android_unittest.cc" ]
+    deps += [ "//components/policy/android:test_jni_headers" ]
+  }
 }
diff --git a/components/policy/core/browser/android/policy_cache_updater_android.cc b/components/policy/core/browser/android/policy_cache_updater_android.cc
new file mode 100644
index 0000000..4e87b34
--- /dev/null
+++ b/components/policy/core/browser/android/policy_cache_updater_android.cc
@@ -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.
+
+#include "components/policy/core/browser/android/policy_cache_updater_android.h"
+
+#include "base/android/jni_android.h"
+#include "base/bind.h"
+#include "components/policy/android/jni_headers/PolicyCacheUpdater_jni.h"
+#include "components/policy/core/browser/policy_error_map.h"
+#include "components/policy/core/common/android/policy_map_android.h"
+#include "components/policy/core/common/policy_namespace.h"
+
+namespace policy {
+namespace android {
+
+namespace {
+
+bool CanCache(PolicyErrorMap* policy_error_map,
+              const std::set<std::string>& future_policies,
+              const PolicyMap::const_iterator iter) {
+  return !policy_error_map->HasError(iter->first) &&
+         future_policies.find(iter->first) == future_policies.end() &&
+         !iter->second.ignored() &&
+         !iter->second.HasMessage(PolicyMap::MessageType::kError);
+}
+
+}  // namespace
+
+PolicyCacheUpdater::PolicyCacheUpdater(
+    PolicyService* policy_service,
+    const ConfigurationPolicyHandlerList* handler_list)
+    : policy_service_(policy_service), handler_list_(handler_list) {
+  policy_service_->AddObserver(POLICY_DOMAIN_CHROME, this);
+}
+
+PolicyCacheUpdater::~PolicyCacheUpdater() {
+  policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this);
+}
+
+void PolicyCacheUpdater::OnPolicyUpdated(const PolicyNamespace& ns,
+                                         const PolicyMap& previous,
+                                         const PolicyMap& current) {
+  PolicyMap policy_map;
+  policy_map.CopyFrom(current);
+  PolicyErrorMap errors;
+  std::set<std::string> future_policies;
+  handler_list_->ApplyPolicySettings(policy_map, /*prefs=*/nullptr, &errors,
+                                     /*deprecated_policies*/ nullptr,
+                                     &future_policies);
+  policy_map.EraseNonmatching(
+      base::BindRepeating(&CanCache, &errors, future_policies));
+  PolicyMapAndroid policy_map_android(policy_map);
+  Java_PolicyCacheUpdater_cachePolicies(base::android::AttachCurrentThread(),
+                                        policy_map_android.GetJavaObject());
+}
+
+}  // namespace android
+}  // namespace policy
diff --git a/components/policy/core/browser/android/policy_cache_updater_android.h b/components/policy/core/browser/android/policy_cache_updater_android.h
new file mode 100644
index 0000000..147951f
--- /dev/null
+++ b/components/policy/core/browser/android/policy_cache_updater_android.h
@@ -0,0 +1,38 @@
+// 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_POLICY_CORE_BROWSER_ANDROID_POLICY_CACHE_UPDATER_ANDROID_H_
+#define COMPONENTS_POLICY_CORE_BROWSER_ANDROID_POLICY_CACHE_UPDATER_ANDROID_H_
+
+#include "components/policy/core/browser/configuration_policy_handler_list.h"
+#include "components/policy/core/common/policy_service.h"
+
+namespace policy {
+
+class ConfigurationPolicyHandlerList;
+
+namespace android {
+
+class POLICY_EXPORT PolicyCacheUpdater : public PolicyService::Observer {
+ public:
+  PolicyCacheUpdater(PolicyService* policy_service,
+                     const ConfigurationPolicyHandlerList* handler_list);
+  PolicyCacheUpdater(const PolicyCacheUpdater&) = delete;
+  PolicyCacheUpdater& operator=(const PolicyCacheUpdater&) = delete;
+  ~PolicyCacheUpdater() override;
+
+  // PolicyService::Observer
+  void OnPolicyUpdated(const PolicyNamespace& ns,
+                       const PolicyMap& previous,
+                       const PolicyMap& current) override;
+
+ private:
+  PolicyService* policy_service_;
+  const ConfigurationPolicyHandlerList* handler_list_;
+};
+
+}  // namespace android
+}  // namespace policy
+
+#endif  // COMPONENTS_POLICY_CORE_BROWSER_ANDROID_POLICY_CACHE_UPDATER_ANDROID_H_
diff --git a/components/policy/core/browser/android/policy_cache_updater_android_unittest.cc b/components/policy/core/browser/android/policy_cache_updater_android_unittest.cc
new file mode 100644
index 0000000..a210f6c9
--- /dev/null
+++ b/components/policy/core/browser/android/policy_cache_updater_android_unittest.cc
@@ -0,0 +1,183 @@
+// 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 "components/policy/core/browser/android/policy_cache_updater_android.h"
+
+#include <jni.h>
+#include <memory>
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/test/task_environment.h"
+#include "base/values.h"
+#include "components/policy/android/test_jni_headers/PolicyCacheUpdaterTestSupporter_jni.h"
+#include "components/policy/core/browser/configuration_policy_handler.h"
+#include "components/policy/core/browser/policy_conversions_client.h"
+#include "components/policy/core/browser/policy_error_map.h"
+#include "components/policy/core/common/configuration_policy_provider.h"
+#include "components/policy/core/common/mock_configuration_policy_provider.h"
+#include "components/policy/core/common/policy_map.h"
+#include "components/policy/core/common/policy_service_impl.h"
+#include "components/strings/grit/components_strings.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::Return;
+
+namespace policy {
+namespace android {
+namespace {
+// The list of policeis that can be cached is controlled by Java library. Hence
+// we use real policy name for testing.
+constexpr char kPolicyName[] = "BrowserSignin";
+constexpr int kPolicyValue = 1;
+
+class StubPolicyHandler : public ConfigurationPolicyHandler {
+ public:
+  StubPolicyHandler(const std::string& policy_name, bool has_error)
+      : policy_name_(policy_name), has_error_(has_error) {}
+  StubPolicyHandler(const StubPolicyHandler&) = delete;
+  StubPolicyHandler& operator=(const StubPolicyHandler&) = delete;
+  ~StubPolicyHandler() override = default;
+
+  bool CheckPolicySettings(const PolicyMap& policies,
+                           PolicyErrorMap* errors) override {
+    if (has_error_) {
+      errors->AddError(policy_name_, IDS_POLICY_BLOCKED);
+    }
+    return policies.GetValue(kPolicyName) && !has_error_;
+  }
+
+ private:
+  void ApplyPolicySettings(const PolicyMap& policies,
+                           PrefValueMap* prefs) override {}
+  std::string policy_name_;
+  bool has_error_;
+};
+
+}  // namespace
+
+class PolicyCacheUpdaterAndroidTest : public ::testing::Test {
+ public:
+  PolicyCacheUpdaterAndroidTest() {
+    ON_CALL(policy_provider_, IsInitializationComplete(_))
+        .WillByDefault(Return(true));
+    ON_CALL(policy_provider_, IsFirstPolicyLoadComplete(_))
+        .WillByDefault(Return(true));
+    j_support_ = Java_PolicyCacheUpdaterTestSupporter_Constructor(env_);
+    policy_service_ = std::make_unique<policy::PolicyServiceImpl>(
+        std::vector<ConfigurationPolicyProvider*>({&policy_provider_}));
+    policy_handler_list_ = std::make_unique<ConfigurationPolicyHandlerList>(
+        ConfigurationPolicyHandlerList::
+            PopulatePolicyHandlerParametersCallback(),
+        GetChromePolicyDetailsCallback(),
+        /*allow_future_policies=*/false);
+  }
+  ~PolicyCacheUpdaterAndroidTest() override = default;
+
+  void SetPolicy(const std::string& policy, int policy_value) {
+    policy_map_.Set(policy, PolicyLevel::POLICY_LEVEL_MANDATORY,
+                    PolicyScope::POLICY_SCOPE_MACHINE,
+                    PolicySource::POLICY_SOURCE_PLATFORM,
+                    base::Value(policy_value),
+                    /*external_data_fetcher=*/nullptr);
+  }
+
+  void UpdatePolicy() { policy_provider_.UpdateChromePolicy(policy_map_); }
+
+  void VerifyPolicyName(const std::string& policy,
+                        bool has_value,
+                        int expected_value) {
+    Java_PolicyCacheUpdaterTestSupporter_verifyPolicyCacheIntValue(
+        env_, j_support_, base::android::ConvertUTF8ToJavaString(env_, policy),
+        has_value, expected_value);
+  }
+
+  ConfigurationPolicyHandlerList* policy_handler_list() {
+    return policy_handler_list_.get();
+  }
+
+  PolicyService* policy_service() { return policy_service_.get(); }
+
+  PolicyMap* policy_map() { return &policy_map_; }
+
+ private:
+  JNIEnv* env_ = base::android::AttachCurrentThread();
+  base::android::ScopedJavaLocalRef<jobject> j_support_;
+  PolicyMap policy_map_;
+  MockConfigurationPolicyProvider policy_provider_;
+  std::unique_ptr<PolicyService> policy_service_;
+  std::unique_ptr<ConfigurationPolicyHandlerList> policy_handler_list_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
+};
+
+TEST_F(PolicyCacheUpdaterAndroidTest, TestCachePolicy) {
+  policy_handler_list()->AddHandler(
+      std::make_unique<StubPolicyHandler>(kPolicyName, /*has_error=*/false));
+
+  PolicyCacheUpdater updater(policy_service(), policy_handler_list());
+  SetPolicy(kPolicyName, kPolicyValue);
+  UpdatePolicy();
+  VerifyPolicyName(kPolicyName, /*has_value=*/true, kPolicyValue);
+}
+
+TEST_F(PolicyCacheUpdaterAndroidTest, TestPolicyNotExist) {
+  policy_handler_list()->AddHandler(
+      std::make_unique<StubPolicyHandler>(kPolicyName, /*has_error=*/false));
+
+  PolicyCacheUpdater updater(policy_service(), policy_handler_list());
+  UpdatePolicy();
+  VerifyPolicyName(kPolicyName, /*has_value=*/false, kPolicyValue);
+}
+
+TEST_F(PolicyCacheUpdaterAndroidTest, TestPolicyErrorPolicy) {
+  policy_handler_list()->AddHandler(
+      std::make_unique<StubPolicyHandler>(kPolicyName, /*has_error=*/true));
+
+  PolicyCacheUpdater updater(policy_service(), policy_handler_list());
+  SetPolicy(kPolicyName, kPolicyValue);
+  UpdatePolicy();
+  VerifyPolicyName(kPolicyName, /*has_value=*/false, kPolicyValue);
+}
+
+TEST_F(PolicyCacheUpdaterAndroidTest, TestPolicyMapIgnoredPolicy) {
+  policy_handler_list()->AddHandler(
+      std::make_unique<StubPolicyHandler>(kPolicyName, /*has_error=*/false));
+
+  PolicyCacheUpdater updater(policy_service(), policy_handler_list());
+  SetPolicy(kPolicyName, kPolicyValue);
+  policy_map()->GetMutable(kPolicyName)->SetIgnored();
+  UpdatePolicy();
+  VerifyPolicyName(kPolicyName, /*has_value=*/false, kPolicyValue);
+}
+
+TEST_F(PolicyCacheUpdaterAndroidTest, TestPolicyMapErrorMessagePolicy) {
+  policy_handler_list()->AddHandler(
+      std::make_unique<StubPolicyHandler>(kPolicyName, /*has_error=*/false));
+
+  PolicyCacheUpdater updater(policy_service(), policy_handler_list());
+  SetPolicy(kPolicyName, kPolicyValue);
+  policy_map()
+      ->GetMutable(kPolicyName)
+      ->AddMessage(PolicyMap::MessageType::kError, IDS_POLICY_BLOCKED);
+  UpdatePolicy();
+  VerifyPolicyName(kPolicyName, /*has_value=*/false, kPolicyValue);
+}
+
+TEST_F(PolicyCacheUpdaterAndroidTest, TestPolicyMapWarningMessagePolicy) {
+  policy_handler_list()->AddHandler(
+      std::make_unique<StubPolicyHandler>(kPolicyName, /*has_error=*/false));
+
+  PolicyCacheUpdater updater(policy_service(), policy_handler_list());
+  SetPolicy(kPolicyName, kPolicyValue);
+  policy_map()
+      ->GetMutable(kPolicyName)
+      ->AddMessage(PolicyMap::MessageType::kWarning, IDS_POLICY_BLOCKED);
+  UpdatePolicy();
+  VerifyPolicyName(kPolicyName, /*has_value=*/true, kPolicyValue);
+}
+
+}  // namespace android
+}  // namespace policy
diff --git a/components/policy/core/browser/policy_error_map.cc b/components/policy/core/browser/policy_error_map.cc
index 9ab339c..152ec0c 100644
--- a/components/policy/core/browser/policy_error_map.cc
+++ b/components/policy/core/browser/policy_error_map.cc
@@ -188,6 +188,18 @@
                                                           message));
 }
 
+bool PolicyErrorMap::HasError(const std::string& policy) {
+  if (IsReady()) {
+    CheckReadyAndConvert();
+    return map_.find(policy) != map_.end();
+  } else {
+    return std::find_if(pending_.begin(), pending_.end(),
+                        [policy](const auto& error) {
+                          return error->policy_name() == policy;
+                        }) != pending_.end();
+  }
+}
+
 base::string16 PolicyErrorMap::GetErrors(const std::string& policy) {
   CheckReadyAndConvert();
   std::pair<const_iterator, const_iterator> range = map_.equal_range(policy);
diff --git a/components/policy/core/browser/policy_error_map.h b/components/policy/core/browser/policy_error_map.h
index 482d723d..d1b0b52 100644
--- a/components/policy/core/browser/policy_error_map.h
+++ b/components/policy/core/browser/policy_error_map.h
@@ -79,6 +79,9 @@
                 const std::string& error_path,
                 const std::string& message);
 
+  // Returns true if there is any error for |policy|.
+  bool HasError(const std::string& policy);
+
   // Returns all the error messages stored for |policy|, separated by a white
   // space. Returns an empty string if there are no errors for |policy|.
   base::string16 GetErrors(const std::string& policy);
diff --git a/components/policy/core/browser/policy_error_map_unittest.cc b/components/policy/core/browser/policy_error_map_unittest.cc
new file mode 100644
index 0000000..e67310d
--- /dev/null
+++ b/components/policy/core/browser/policy_error_map_unittest.cc
@@ -0,0 +1,40 @@
+// 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 "components/policy/core/browser/policy_error_map.h"
+
+#include "components/strings/grit/components_strings.h"
+#include "ui/base/resource/resource_bundle.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+namespace {
+constexpr char kPolicyWithError[] = "policy-error";
+constexpr char kPolicyWithoutError[] = "policy";
+}  // namespace
+
+using PolicyErrorMapTest = ::testing::Test;
+
+TEST_F(PolicyErrorMapTest, HasErrorWithoutResource) {
+  ui::ResourceBundle* original_resource_bundle =
+      ui::ResourceBundle::SwapSharedInstanceForTesting(nullptr);
+  PolicyErrorMap errors;
+  ASSERT_FALSE(errors.IsReady());
+  errors.AddError(kPolicyWithError, IDS_POLICY_BLOCKED);
+
+  EXPECT_TRUE(errors.HasError(kPolicyWithError));
+  EXPECT_FALSE(errors.HasError(kPolicyWithoutError));
+  ui::ResourceBundle::SwapSharedInstanceForTesting(original_resource_bundle);
+}
+TEST_F(PolicyErrorMapTest, HasErrorWithResource) {
+  PolicyErrorMap errors;
+  ASSERT_TRUE(errors.IsReady());
+  errors.AddError(kPolicyWithError, IDS_POLICY_BLOCKED);
+
+  EXPECT_TRUE(errors.HasError(kPolicyWithError));
+  EXPECT_FALSE(errors.HasError(kPolicyWithoutError));
+}
+
+}  // namespace policy
diff --git a/components/policy/core/common/policy_map.cc b/components/policy/core/common/policy_map.cc
index 29d270f..8da2598 100644
--- a/components/policy/core/common/policy_map.cc
+++ b/components/policy/core/common/policy_map.cc
@@ -155,10 +155,14 @@
   ClearMessage(MessageType::kWarning, IDS_POLICY_CONFLICT_DIFF_VALUE);
 }
 
+bool PolicyMap::Entry::HasMessage(MessageType type) const {
+  return message_ids_.find(type) != message_ids_.end();
+}
+
 base::string16 PolicyMap::Entry::GetLocalizedMessages(
     MessageType type,
     L10nLookupFunction lookup) const {
-  if (message_ids_.find(type) == message_ids_.end()) {
+  if (!HasMessage(type)) {
     return base::string16();
   }
   return GetLocalizedString(lookup, message_ids_.at(type));
diff --git a/components/policy/core/common/policy_map.h b/components/policy/core/common/policy_map.h
index ccb4441..8eb5742 100644
--- a/components/policy/core/common/policy_map.h
+++ b/components/policy/core/common/policy_map.h
@@ -127,6 +127,9 @@
     typedef base::RepeatingCallback<base::string16(int message_id)>
         L10nLookupFunction;
 
+    // Returns true if there is any message for |type|.
+    bool HasMessage(MessageType type) const;
+
     // Returns localized messages as UTF-16 separated with LF characters. The
     // messages are organized according to message types (Warning, Error, etc).
     base::string16 GetLocalizedMessages(MessageType type,
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index c2f9bb9..641e2d9 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -24384,7 +24384,7 @@
       'default': 0,
       'example_value': 0,
       'id': 810,
-      'caption': '''Profile picker availabily on startup''',
+      'caption': '''Profile picker availability on startup''',
       'tags': [],
       'desc': '''Specifies whether the profile picker is enabled, disabled or forced at the browser startup.
 
diff --git a/components/policy/resources/policy_templates_id.xtb b/components/policy/resources/policy_templates_id.xtb
index 3dd704a..a447df6 100644
--- a/components/policy/resources/policy_templates_id.xtb
+++ b/components/policy/resources/policy_templates_id.xtb
@@ -884,7 +884,7 @@
 <translation id="2261648512244797294">Nonaktifkan pencetakan privet yang tidak digunakan lagi</translation>
 <translation id="2266422599396179941">Izinkan pengguna mengirim masukan</translation>
 <translation id="2269319728625047531">Aktifkan menampilkan Izin Sinkronisasi saat login</translation>
-<translation id="2270747976331889601">Mengaktifkan fitur keamanan TLS 1.3 untuk penanda kepercayaan lokal.</translation>
+<translation id="2270747976331889601">Mengaktifkan fitur keamanan TLS 1.3 untuk trust anchor lokal.</translation>
 <translation id="2281496157391382819"> Mengontrol peringatan privasi sesi tamu terkelola di <ph name="PRODUCT_OS_NAME" />.
 
       Jika kebijakan ini disetel ke Salah (False), peringatan privasi di layar login dan notifikasi peluncuran otomatis di dalam sesi tamu terkelola akan dinonaktifkan.
@@ -1538,7 +1538,7 @@
       Jika setelan ini dinonaktifkan, pengguna tidak akan diizinkan menggunakan fitur ini. Jika kebijakan PhoneHubAllowed dinonaktifkan, pengguna juga tidak akan diizinkan menggunakan fitur ini.
 
       Jika kebijakan ini tidak disetel, baik pengguna yang dikelola maupun tidak dikelola perusahaan akan diizinkan secara default.</translation>
-<translation id="3177802893484440532">Mewajibkan pemeriksaan OCSP/CRL online untuk sumber tepercaya setempat</translation>
+<translation id="3177802893484440532">Mewajibkan pemeriksaan OCSP/CRL online untuk trust anchor lokal</translation>
 <translation id="3184161739683646075">Mengontrol mode DNS-over-HTTPS</translation>
 <translation id="3185009703220253572">sejak versi <ph name="SINCE_VERSION" /></translation>
 <translation id="3192902750888034827">Jika <ph name="DEFAULT_SEARCH_PROVIDER_ENABLED_POLICY_NAME" /> aktif, menyetel <ph name="DEFAULT_SEARCH_PROVIDER_NEW_TAB_URL_POLICY_NAME" /> akan menentukan URL mesin telusur yang digunakan untuk menyediakan halaman Tab Baru.
@@ -3147,7 +3147,7 @@
 <translation id="5475361623548884387">Aktifkan pencetakan</translation>
 <translation id="547601067149622666">Jangan izinkan iklan di situs yang menayangkan iklan mengganggu</translation>
 <translation id="5480380613778757009">Jika kebijakan ini dinonaktifkan atau tidak disetel, semua setelan tampilan yang disetel di Sesi tamu terkelola akan direset segera setelah sesi selesai. Jika kebijakan ini disetel ke Benar (True), properti tampilan akan tetap tersimpan setelah keluar dari sesi tamu terkelola.</translation>
-<translation id="5483065054530244863">Mengizinkan sertifikat bertanda tangan SHA-1 yang dikeluarkan oleh sumber tepercaya setempat</translation>
+<translation id="5483065054530244863">Mengizinkan sertifikat bertanda tangan SHA-1 yang dikeluarkan oleh trust anchor lokal</translation>
 <translation id="5497565614013170656">Ekspresi reguler untuk mencocokkan id printer.</translation>
 <translation id="5499375345075963939">Kebijakan ini hanya aktif pada mode ritel.
 
@@ -3583,7 +3583,7 @@
       Jika kebijakan disetel ke Nonaktif, output audio pengguna tidak akan diizinkan saat pengguna login.
 
       Catatan: Kebijakan ini memengaruhi semua output audio, termasuk fitur aksesibilitas audio. Jangan menonaktifkan kebijakan jika pengguna memerlukan pembaca layar.</translation>
-<translation id="6221175752766085998">Mengizinkan sertifikat yang dikeluarkan oleh sumber tepercaya setempat tanpa ekstensi subjectAlternativeName</translation>
+<translation id="6221175752766085998">Mengizinkan sertifikat yang dikeluarkan oleh trust anchor lokal tanpa ekstensi subjectAlternativeName</translation>
 <translation id="6224304369267200483">URL/domain otomatis mengizinkan pengesahan langsung Kunci Keamanan</translation>
 <translation id="6230442621691161858">Fitur ini mengaktifkan saran konten baru untuk dijelajahi. Termasuk aplikasi, halaman web, dan lainnya.
       Jika kebijakan ini disetel ke Benar (True), saran konten baru untuk dijelajahi akan diaktifkan.
diff --git a/components/policy/resources/policy_templates_ja.xtb b/components/policy/resources/policy_templates_ja.xtb
index f1f9bba8..9f9aeeb 100644
--- a/components/policy/resources/policy_templates_ja.xtb
+++ b/components/policy/resources/policy_templates_ja.xtb
@@ -60,7 +60,7 @@
 
       使用できる変数のリストについては、https://support.google.com/chrome/a?p=Supported_directory_variables をご覧ください。
 
-      このポリシーを未設定のままにした場合は、デフォルトのプロフィール ディレクトリが使用されます。</translation>
+      このポリシーを未設定のままにした場合は、デフォルトのプロファイル ディレクトリが使用されます。</translation>
 <translation id="1062011392452772310">デバイスのリモート認証を有効にする</translation>
 <translation id="1062407476771304334">置換</translation>
 <translation id="1069489575852947981">このポリシーを有効に設定するか未設定のままにした場合、デバイスのローカル アカウントは遅延なしで自動ログインするように設定されます。ただし、<ph name="PRODUCT_OS_NAME" /> では、自動ログインせずにログイン画面を表示するキーボード ショートカットの Ctrl+Alt+S キーが優先されます。
@@ -1673,7 +1673,7 @@
 
       使用できる変数のリストについては、https://support.google.com/chrome/a?p=Supported_directory_variables をご覧ください。
 
-      このポリシーを未設定のままにした場合は、デフォルトのプロフィール パスが使用され、ユーザーは「--user-data-dir」コマンドライン フラグで設定を上書きできます。</translation>
+      このポリシーを未設定のままにした場合は、デフォルトのプロファイル パスが使用され、ユーザーは「--user-data-dir」コマンドライン フラグで設定を上書きできます。</translation>
 <translation id="3378482432905539452">このポリシーはサポートを終了しました。Flash プラグインを使用できるかどうかを管理するには <ph name="DEFAULT_PLUGINS_SETTING_POLICY_NAME" /> を使用してください。また、PDF ファイルを開く際に組み込みの PDF ビューアを使用するかどうかを管理するには <ph name="ALWAYS_OPEN_PDF_EXTERNALLY_POLICY_NAME" /> を使用してください。
 
       <ph name="PRODUCT_NAME" /> でユーザーが有効または無効にできるプラグインのリストを指定します。
@@ -2958,11 +2958,11 @@
 <translation id="5323200200131319468">ログイン画面で音声フィードバックを有効にする</translation>
 <translation id="532668836479219203">ブラウザのログイン動作を制御するポリシーです。ユーザーが自分のアカウントで <ph name="PRODUCT_NAME" /> にログインして Chrome 同期などのアカウント関連のサービスを使用できるかどうかを指定します。
 
-      このポリシーが「ブラウザのログインを無効にする」に設定されている場合、ユーザーは、ブラウザにログインしてアカウントに基づくサービスを使用することができません。この場合、Chrome 同期のようなブラウザレベルの機能は使用不可となります。ユーザーがすでにログインしている状態でこのポリシーが「無効」に設定された場合は、次回 Chrome を起動するとログアウトの状態になります。ただし、ブックマーク、パスワードといったローカルのプロフィール データは保持されます。Gmail のような Google ウェブサービスは、引き続きログインして使用することができます。
+      このポリシーが「ブラウザのログインを無効にする」に設定されている場合、ユーザーは、ブラウザにログインしてアカウントに基づくサービスを使用することができません。この場合、Chrome 同期のようなブラウザレベルの機能は使用不可となります。ユーザーがすでにログインしている状態でこのポリシーが「無効」に設定された場合は、次回 Chrome を起動するとログアウトの状態になります。ただし、ブックマーク、パスワードといったローカルのプロファイル データは保持されます。Gmail のような Google ウェブサービスは、引き続きログインして使用することができます。
 
       このポリシーが「ブラウザのログインを有効にする」に設定されている場合、ユーザーはブラウザにログインすることができ、また Gmail のような Google ウェブサービスにログインするとブラウザにも自動的にログインした状態になります。ブラウザにログインしているときには、ユーザーのアカウント情報がブラウザで保持されます。ただし、Chrome 同期はデフォルトではオンになりません。Chrome 同期を使用するには、ユーザーが別途この機能をオンにする必要があります。このポリシーを有効にした場合、ブラウザのログインを許可するかどうかの設定をユーザーがオフにすることはできません。Chrome 同期を利用できるかどうかを制御するには、「SyncDisabled」ポリシーを使用します。
 
-      このポリシーが「ブラウザのログインを必須とする」に設定されている場合、ユーザーにはアカウント選択のダイアログが表示されます。ブラウザを使用するには、いずれかのアカウントを選択してログインする必要があります。管理対象アカウントの場合、この設定を使用することで、アカウントに関連付けられているポリシーの適用を徹底できます。対象のアカウントでは Chrome 同期もデフォルトでオンになります(ドメインの管理者または「SyncDisabled」ポリシーによって同期が無効に設定されている場合を除く)。また、BrowserGuestModeEnabled のデフォルト値は false になります。このポリシーを有効にした後、ログインしていない既存のプロフィールはロックされ、アクセスできなくなります。詳しくはヘルプセンター記事(https://support.google.com/chrome/a/answer/7572556)をご覧ください。このオプションは Linux と Android には対応していません。Linux または Android でこのオプションを使用した場合は、「ブラウザのログインを有効にする」の設定に置き換えられます。
+      このポリシーが「ブラウザのログインを必須とする」に設定されている場合、ユーザーにはアカウント選択のダイアログが表示されます。ブラウザを使用するには、いずれかのアカウントを選択してログインする必要があります。管理対象アカウントの場合、この設定を使用することで、アカウントに関連付けられているポリシーの適用を徹底できます。対象のアカウントでは Chrome 同期もデフォルトでオンになります(ドメインの管理者または「SyncDisabled」ポリシーによって同期が無効に設定されている場合を除く)。また、BrowserGuestModeEnabled のデフォルト値は false になります。このポリシーを有効にした後、ログインしていない既存のプロファイルはロックされ、アクセスできなくなります。詳しくはヘルプセンター記事(https://support.google.com/chrome/a/answer/7572556)をご覧ください。このオプションは Linux と Android には対応していません。Linux または Android でこのオプションを使用した場合は、「ブラウザのログインを有効にする」の設定に置き換えられます。
 
       このポリシーが未設定の場合、ユーザーはブラウザのログイン オプションを有効にするかどうかを自分で判断し、状況に応じて使用することができます。</translation>
 <translation id="532848608876725157">DNS-over-HTTPS を有効にする(安全でないフォールバックあり)</translation>
diff --git a/components/policy/resources/policy_templates_zh-TW.xtb b/components/policy/resources/policy_templates_zh-TW.xtb
index 6b2f657..d5b68d1 100644
--- a/components/policy/resources/policy_templates_zh-TW.xtb
+++ b/components/policy/resources/policy_templates_zh-TW.xtb
@@ -476,7 +476,7 @@
 
       如果不設定這項政策,預設狀態下會啟用所有 <ph name="PRODUCT_OS_NAME" />的功能,且使用者皆可存取。
 
-      注意:掃描功能目前已透過功能標記預設為停用。如果使用者透過功能標記啟用該功能,這項政策仍然可以將其停用。</translation>
+      注意:掃描功能目前已透過功能旗標預設為停用。如果使用者透過功能旗標啟用該功能,這項政策仍然可以將其停用。</translation>
 <translation id="1645793986494086629">架構:</translation>
 <translation id="1647558381546345298">設定這項政策後,無論使用者是否指定 --media-cache-size 旗標,<ph name="PRODUCT_NAME" /> 都會使用你設定的快取大小,在磁碟上儲存快取媒體檔案。這項政策所指定的值並非不可變動的界線,而是提供給快取系統的建議值。MB 以下的值會進位為 MB。
 
@@ -1140,7 +1140,7 @@
 <translation id="26023406105317310">設定 Kerberos 帳戶</translation>
 <translation id="2604182581880595781">設定網路檔案共用功能相關政策。</translation>
 <translation id="2615240493030733717">回報時區資訊</translation>
-<translation id="2619966380594000538">如果將這項政策設為啟用或不設定,當你使用具潛在危險的指令列標記啟動 Chrome 時,系統會顯示安全性警告。
+<translation id="2619966380594000538">如果將這項政策設為啟用或不設定,當你使用具潛在危險的指令列旗標啟動 Chrome 時,系統會顯示安全性警告。
 
       如果將這項政策設為停用,在使用具有安全疑慮的指令列旗標啟動 Chrome 時,系統不會顯示安全性警告。
 
@@ -1323,7 +1323,7 @@
           |created_time_millis| 是覆寫作業建立時間的時間戳記 (採世界標準時間),由於時間戳記無法轉換成整數,因此這項參數是採字串的形式傳送。這項參數是用來供系統判定是否仍要執行覆寫作業。如果目前有效的時間限制功能 (時間用量限制或時段限制) 是在覆寫作業建立後才開始,系統就不會採取行動。此外,如果覆寫作業的建立時間早於生效的 time_window_limit 或 time_usage_window 功能上次的變更時間,系統就不會執行覆寫作業。
 
           系統能會傳送多重覆寫作業,並套用最新的有效項目。</translation>
-<translation id="2901725272378498025">啟用指令列標記的安全性警告</translation>
+<translation id="2901725272378498025">啟用指令列旗標的安全性警告</translation>
 <translation id="2905984450136807296">驗證資料快取生命週期</translation>
 <translation id="2906874737073861391">AppPack 擴充功能清單</translation>
 <translation id="2908277604670530363">Proxy 伺服器的並行連線數量上限</translation>
@@ -1724,7 +1724,7 @@
 
       如果企業客戶使用的 SSO 解決方案與新版內嵌登入流程不相容,就很適合使用這項設定。
       如果啟用這項設定,系統將使用舊版網頁登入流程。
-      如果停用這項設定或不設定,則系統會預設使用新的內嵌登入流程。使用者仍可以透過指令列標記「--enable-web-based-signin」來啟用舊的網頁登入流程。
+      如果停用這項設定或不設定,則系統會預設使用新的內嵌登入流程。使用者仍可以透過指令列旗標「--enable-web-based-signin」來啟用舊的網頁登入流程。
 
       未來內嵌登入將完整支援所有 SSO 登入流程,屆時我們會移除這項實驗性設定。</translation>
 <translation id="3435796032110614169">允許刪除列印工作的歷史記錄</translation>
diff --git a/components/policy_strings.grdp b/components/policy_strings.grdp
index d9592b0..fb156de 100644
--- a/components/policy_strings.grdp
+++ b/components/policy_strings.grdp
@@ -612,6 +612,9 @@
   <message name="IDS_POLICY_DLP_CLIPBOARD_WARN_DISMISS_BUTTON" desc="Dismiss dialog button label for warning before paste.">
     Cancel
   </message>
+  <message name="IDS_POLICY_DLP_CLIPBOARD_WARN_ON_COPY_VM" desc="A toast informing the user that pasting the clipboard data to VMs is not recommended.">
+    Copying and pasting this content to <ph name="VM_NAME">$1<ex>Linux</ex></ph> is not recommended by administrator policy
+  </message>
   <message name="IDS_POLICY_DLP_PRINTING_BLOCKED_TITLE" desc="The title for notification informing the user that printing is blocked.">
     Printing is blocked
   </message>
diff --git a/components/policy_strings_grdp/IDS_POLICY_DLP_CLIPBOARD_WARN_ON_COPY_VM.png.sha1 b/components/policy_strings_grdp/IDS_POLICY_DLP_CLIPBOARD_WARN_ON_COPY_VM.png.sha1
new file mode 100644
index 0000000..c1e552d3
--- /dev/null
+++ b/components/policy_strings_grdp/IDS_POLICY_DLP_CLIPBOARD_WARN_ON_COPY_VM.png.sha1
@@ -0,0 +1 @@
+089cbf0a2039791e1fcbfc5a7b9462f61d47ce49
\ No newline at end of file
diff --git a/components/power_scheduler/power_mode_voter.cc b/components/power_scheduler/power_mode_voter.cc
index b0be43e..0a2a2c1e 100644
--- a/components/power_scheduler/power_mode_voter.cc
+++ b/components/power_scheduler/power_mode_voter.cc
@@ -12,6 +12,8 @@
 
 // static
 constexpr base::TimeDelta PowerModeVoter::kResponseTimeout;
+// static
+constexpr base::TimeDelta PowerModeVoter::kLoadingTimeout;
 
 PowerModeVoter::~PowerModeVoter() {
   delegate_->OnVoterDestroyed(this);
diff --git a/components/power_scheduler/power_mode_voter.h b/components/power_scheduler/power_mode_voter.h
index de1a7157..93461a5 100644
--- a/components/power_scheduler/power_mode_voter.h
+++ b/components/power_scheduler/power_mode_voter.h
@@ -27,9 +27,15 @@
                                        base::TimeDelta timeout) = 0;
   };
 
+  // Consider an initial response to a single input to last 100ms.
   static constexpr base::TimeDelta kResponseTimeout =
       base::TimeDelta::FromMilliseconds(100);
 
+  // Avoid getting stuck in loading stage forever. More than 99.9% of
+  // navigations load (to largest contentful paint) in less than a minute.
+  static constexpr base::TimeDelta kLoadingTimeout =
+      base::TimeDelta::FromSeconds(60);
+
   ~PowerModeVoter();
 
   PowerModeVoter(const PowerModeVoter&) = delete;
diff --git a/components/safe_browsing/core/common/safe_browsing_prefs.cc b/components/safe_browsing/core/common/safe_browsing_prefs.cc
index 7d972c3..b218f6a0 100644
--- a/components/safe_browsing/core/common/safe_browsing_prefs.cc
+++ b/components/safe_browsing/core/common/safe_browsing_prefs.cc
@@ -104,6 +104,7 @@
     "safebrowsing.advanced_protection_allowed";
 const char kSafeBrowsingMetricsLastLogTime[] =
     "safebrowsing.metrics_last_log_time";
+const char kSafeBrowsingEventTimestamps[] = "safebrowsing.event_timestamps";
 }  // namespace prefs
 
 namespace safe_browsing {
@@ -221,6 +222,7 @@
   registry->RegisterIntegerPref(
       prefs::kSafeBrowsingEnterpriseRealTimeUrlCheckScope, 0);
   registry->RegisterInt64Pref(prefs::kSafeBrowsingMetricsLastLogTime, 0);
+  registry->RegisterDictionaryPref(prefs::kSafeBrowsingEventTimestamps);
 }
 
 void RegisterLocalStatePrefs(PrefRegistrySimple* registry) {
diff --git a/components/safe_browsing/core/common/safe_browsing_prefs.h b/components/safe_browsing/core/common/safe_browsing_prefs.h
index c89d9d6..dca9002 100644
--- a/components/safe_browsing/core/common/safe_browsing_prefs.h
+++ b/components/safe_browsing/core/common/safe_browsing_prefs.h
@@ -107,6 +107,10 @@
 // Browsing metrics.
 extern const char kSafeBrowsingMetricsLastLogTime[];
 
+// A dictionary of Safe Browsing events and their corresponding timestamps.
+// Used for logging metrics. Structure: go/sb-event-ts-pref-struct.
+extern const char kSafeBrowsingEventTimestamps[];
+
 }  // namespace prefs
 
 namespace safe_browsing {
diff --git a/components/signin/core/browser/account_reconcilor.cc b/components/signin/core/browser/account_reconcilor.cc
index 6fe4fed..35deb45 100644
--- a/components/signin/core/browser/account_reconcilor.cc
+++ b/components/signin/core/browser/account_reconcilor.cc
@@ -501,6 +501,7 @@
     std::vector<gaia::ListedAccount>&& gaia_accounts) {
   DCHECK(IsMultiloginEndpointEnabled());
   DCHECK(!set_accounts_in_progress_);
+  DCHECK(!log_out_in_progress_);
   DCHECK_EQ(AccountReconcilorState::ACCOUNT_RECONCILOR_RUNNING, state_);
 
   bool primary_has_error =
@@ -983,7 +984,12 @@
   VLOG(1) << "AccountReconcilor::OnLogOutFromCookieCompleted: "
           << "Error was " << error.ToString();
 
-  if (is_reconcile_started_) {
+  // When switching the primary account, there is a sequence of calls to
+  // DisableReconclie() followed by EnableReconcile(). This starts a logout call
+  // and then starts a reconcile loop without waiting for the initial logout
+  // to end. The initial logout should not be considered as the end of the
+  // reconcile loop. See crbug.com/1175395
+  if (is_reconcile_started_ && log_out_in_progress_) {
     log_out_in_progress_ = false;
     if (error.state() != GoogleServiceAuthError::State::NONE &&
         !error_during_last_reconcile_.IsPersistentError()) {
diff --git a/components/signin/core/browser/android/BUILD.gn b/components/signin/core/browser/android/BUILD.gn
index 57cbc765..d8796ba 100644
--- a/components/signin/core/browser/android/BUILD.gn
+++ b/components/signin/core/browser/android/BUILD.gn
@@ -7,7 +7,6 @@
 generate_jni("jni_headers") {
   sources = [
     "java/src/org/chromium/components/signin/AccountManagerFacadeProvider.java",
-    "java/src/org/chromium/components/signin/AccountTrackerService.java",
   ]
 }
 
@@ -33,7 +32,6 @@
     "java/src/org/chromium/components/signin/AccountManagerFacadeImpl.java",
     "java/src/org/chromium/components/signin/AccountManagerFacadeProvider.java",
     "java/src/org/chromium/components/signin/AccountManagerResult.java",
-    "java/src/org/chromium/components/signin/AccountTrackerService.java",
     "java/src/org/chromium/components/signin/AccountUtils.java",
     "java/src/org/chromium/components/signin/AccountsChangeObserver.java",
     "java/src/org/chromium/components/signin/AuthException.java",
@@ -50,26 +48,3 @@
 
   annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
 }
-
-android_library("signin_java_test_support") {
-  testonly = true
-  deps = [
-    ":java",
-    ":signin_test_resources",
-    "//base:base_java",
-    "//third_party/android_deps:androidx_annotation_annotation_java",
-  ]
-  sources = [
-    "javatests/src/org/chromium/components/signin/test/util/AccountHolder.java",
-    "javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java",
-    "javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java",
-    "javatests/src/org/chromium/components/signin/test/util/FakeProfileDataSource.java",
-  ]
-  resources_package = "org.chromium.components.signin.core.browser.javatests"
-}
-
-android_resources("signin_test_resources") {
-  testonly = true
-
-  sources = [ "javatests/res/drawable/test_profile_picture.xml" ]
-}
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountTrackerService.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountTrackerService.java
deleted file mode 100644
index 353b3bcd..0000000
--- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountTrackerService.java
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.components.signin;
-
-import android.os.SystemClock;
-
-import androidx.annotation.IntDef;
-
-import org.chromium.base.Log;
-import org.chromium.base.ObserverList;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.NativeMethods;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.base.task.AsyncTask;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Android wrapper of AccountTrackerService which provides access from the java layer.
- * It offers the capability of fetching and seeding system accounts into AccountTrackerService in
- * C++ layer, and notifies observers when it is complete.
- */
-public class AccountTrackerService {
-    private static final String TAG = "AccountService";
-
-    private final long mNativeAccountTrackerService;
-    private @SystemAccountsSeedingStatus int mSystemAccountsSeedingStatus;
-    private boolean mSystemAccountsChanged;
-    private AccountsChangeObserver mAccountsChangeObserver;
-
-    @IntDef({SystemAccountsSeedingStatus.SEEDING_NOT_STARTED,
-            SystemAccountsSeedingStatus.SEEDING_IN_PROGRESS,
-            SystemAccountsSeedingStatus.SEEDING_DONE,
-            SystemAccountsSeedingStatus.SEEDING_VALIDATING})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SystemAccountsSeedingStatus {
-        int SEEDING_NOT_STARTED = 0;
-        int SEEDING_IN_PROGRESS = 1;
-        int SEEDING_DONE = 2;
-        int SEEDING_VALIDATING = 3;
-    }
-
-    /**
-     * Classes that want to listen for system accounts fetching and seeding should implement
-     * this interface and register with {@link #addSystemAccountsSeededListener}.
-     */
-    public interface OnSystemAccountsSeededListener {
-        // Called at the end of seedSystemAccounts().
-        void onSystemAccountsSeedingComplete();
-        // Called in invalidateAccountSeedStatus() indicating that accounts have changed.
-        default void onSystemAccountsChanged() {}
-    }
-
-    private final ObserverList<OnSystemAccountsSeededListener> mSystemAccountsSeedingObservers =
-            new ObserverList<>();
-
-    private AccountTrackerService(long nativeAccountTrackerService) {
-        mNativeAccountTrackerService = nativeAccountTrackerService;
-        mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_NOT_STARTED;
-        mSystemAccountsChanged = false;
-    }
-
-    @CalledByNative
-    private static AccountTrackerService create(long nativeAccountTrackerService) {
-        ThreadUtils.assertOnUiThread();
-        return new AccountTrackerService(nativeAccountTrackerService);
-    }
-
-    /**
-     * Checks whether the account id <-> email mapping has been seeded into C++ layer.
-     * If not, it automatically starts fetching the mapping and seeds it.
-     * @return Whether the accounts have been seeded already.
-     */
-    public boolean checkAndSeedSystemAccounts() {
-        ThreadUtils.assertOnUiThread();
-        if (areSystemAccountsSeeded()) {
-            return true;
-        }
-        if ((mSystemAccountsSeedingStatus == SystemAccountsSeedingStatus.SEEDING_NOT_STARTED
-                    || mSystemAccountsChanged)
-                && mSystemAccountsSeedingStatus
-                        != SystemAccountsSeedingStatus.SEEDING_IN_PROGRESS) {
-            seedSystemAccounts();
-        }
-        return false;
-    }
-
-    /**
-     * Checks whether system accounts are seeded without changing the state.
-     * @return Whether account list in {@link AccountManagerFacade} is consistent with accounts in
-     *         the native AccountTrackerService.
-     */
-    private boolean areSystemAccountsSeeded() {
-        return mSystemAccountsSeedingStatus == SystemAccountsSeedingStatus.SEEDING_DONE
-                && !mSystemAccountsChanged;
-    }
-
-    /**
-     * Register an |observer| to observe system accounts seeding status.
-     */
-    public void addSystemAccountsSeededListener(OnSystemAccountsSeededListener observer) {
-        ThreadUtils.assertOnUiThread();
-        mSystemAccountsSeedingObservers.addObserver(observer);
-    }
-
-    /**
-     * Remove an |observer| from the list of observers.
-     */
-    public void removeSystemAccountsSeededListener(OnSystemAccountsSeededListener observer) {
-        ThreadUtils.assertOnUiThread();
-        mSystemAccountsSeedingObservers.removeObserver(observer);
-    }
-
-    private void seedSystemAccounts() {
-        ThreadUtils.assertOnUiThread();
-        mSystemAccountsChanged = false;
-        final AccountManagerFacade accountManagerFacade =
-                AccountManagerFacadeProvider.getInstance();
-        if (accountManagerFacade.isGooglePlayServicesAvailable()) {
-            mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_IN_PROGRESS;
-        } else {
-            mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_NOT_STARTED;
-            return;
-        }
-
-        if (mAccountsChangeObserver == null) {
-            mAccountsChangeObserver =
-                    () -> invalidateAccountSeedStatus(false /* don't reseed right now */);
-            accountManagerFacade.addObserver(mAccountsChangeObserver);
-        }
-
-        accountManagerFacade.tryGetGoogleAccounts(accounts -> {
-            new AsyncTask<String[][]>() {
-                @Override
-                public String[][] doInBackground() {
-                    Log.d(TAG, "Getting id/email mapping");
-
-                    long seedingStartTime = SystemClock.elapsedRealtime();
-
-                    String[][] accountIdNameMap = new String[2][accounts.size()];
-                    for (int i = 0; i < accounts.size(); ++i) {
-                        accountIdNameMap[0][i] =
-                                accountManagerFacade.getAccountGaiaId(accounts.get(i).name);
-                        accountIdNameMap[1][i] = accounts.get(i).name;
-                    }
-
-                    RecordHistogram.recordTimesHistogram("Signin.AndroidGetAccountIdsTime",
-                            SystemClock.elapsedRealtime() - seedingStartTime);
-
-                    return accountIdNameMap;
-                }
-                @Override
-                public void onPostExecute(String[][] accountIdNameMap) {
-                    if (mSystemAccountsChanged) {
-                        seedSystemAccounts();
-                        return;
-                    }
-                    if (areAccountIdsValid(accountIdNameMap[0])) {
-                        AccountTrackerServiceJni.get().seedAccountsInfo(
-                                mNativeAccountTrackerService, accountIdNameMap[0],
-                                accountIdNameMap[1]);
-                        mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_DONE;
-                        notifyObserversOnSeedingComplete();
-                    } else {
-                        Log.w(TAG, "Invalid mapping of id/email");
-                        seedSystemAccounts();
-                    }
-                }
-            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-        });
-    }
-
-    private boolean areAccountIdsValid(String[] accountIds) {
-        for (String accountId : accountIds) {
-            if (accountId == null) return false;
-        }
-        return true;
-    }
-
-    private void notifyObserversOnSeedingComplete() {
-        for (OnSystemAccountsSeededListener observer : mSystemAccountsSeedingObservers) {
-            observer.onSystemAccountsSeedingComplete();
-        }
-    }
-
-    /**
-     * Notifies the AccountTrackerService about changed system accounts. without actually triggering
-     * @param reSeedAccounts Whether to also start seeding the new account information immediately.
-     */
-    public void invalidateAccountSeedStatus(boolean reSeedAccounts) {
-        ThreadUtils.assertOnUiThread();
-        mSystemAccountsChanged = true;
-        notifyObserversOnAccountsChange();
-        if (reSeedAccounts) checkAndSeedSystemAccounts();
-    }
-
-    /**
-     * Verifies whether seeded accounts in AccountTrackerService are up-to-date with the accounts in
-     * Android. It sets seeding status to SEEDING_VALIDATING temporarily to block services depending
-     * on it and sets it back to SEEDING_DONE after passing the verification. This function is
-     * created because accounts changed notification from Android to Chrome has latency.
-     */
-    public void validateSystemAccounts() {
-        ThreadUtils.assertOnUiThread();
-        if (!checkAndSeedSystemAccounts()) {
-            // Do nothing if seeding is not done.
-            return;
-        }
-
-        mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_VALIDATING;
-        AccountManagerFacadeProvider.getInstance().tryGetGoogleAccounts(accounts -> {
-            if (mSystemAccountsChanged
-                    || mSystemAccountsSeedingStatus
-                            != SystemAccountsSeedingStatus.SEEDING_VALIDATING) {
-                return;
-            }
-
-            String[] accountNames = new String[accounts.size()];
-            for (int i = 0; i < accounts.size(); ++i) {
-                accountNames[i] = accounts.get(i).name;
-            }
-            if (AccountTrackerServiceJni.get().areAccountsSeeded(
-                        mNativeAccountTrackerService, accountNames)) {
-                mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_DONE;
-                notifyObserversOnSeedingComplete();
-            }
-        });
-    }
-
-    private void notifyObserversOnAccountsChange() {
-        for (OnSystemAccountsSeededListener observer : mSystemAccountsSeedingObservers) {
-            observer.onSystemAccountsChanged();
-        }
-    }
-
-    @NativeMethods
-    interface Natives {
-        void seedAccountsInfo(
-                long nativeAccountTrackerService, String[] gaiaIds, String[] accountNames);
-        boolean areAccountsSeeded(long nativeAccountTrackerService, String[] accountNames);
-    }
-}
diff --git a/components/signin/internal/identity_manager/DEPS b/components/signin/internal/identity_manager/DEPS
index 22712ba7..ab4e4b1 100644
--- a/components/signin/internal/identity_manager/DEPS
+++ b/components/signin/internal/identity_manager/DEPS
@@ -3,17 +3,6 @@
   "+components/signin/public/base",
   "+components/signin/public/identity_manager",
   "+components/signin/public/webdata",
+  "+components/signin/public/android/jni_headers",
   "+mojo/public",
 ]
-
-specific_include_rules = {
-  "account_tracker_service.cc": [
-    "+components/signin/core/browser/android/jni_headers/AccountTrackerService_jni.h",
-  ],
-  "child_account_info_fetcher_android.cc": [
-    "+components/signin/public/android/jni_headers/ChildAccountInfoFetcher_jni.h",
-  ],
-  "profile_oauth2_token_service_delegate_android.cc": [
-    "+components/signin/public/android/jni_headers/ProfileOAuth2TokenServiceDelegate_jni.h",
-  ]
-}
diff --git a/components/signin/internal/identity_manager/account_tracker_service.cc b/components/signin/internal/identity_manager/account_tracker_service.cc
index 3cd2254..871dada 100644
--- a/components/signin/internal/identity_manager/account_tracker_service.cc
+++ b/components/signin/internal/identity_manager/account_tracker_service.cc
@@ -33,7 +33,7 @@
 
 #if defined(OS_ANDROID)
 #include "base/android/jni_array.h"
-#include "components/signin/core/browser/android/jni_headers/AccountTrackerService_jni.h"
+#include "components/signin/public/android/jni_headers/AccountTrackerService_jni.h"
 #endif
 
 namespace {
@@ -105,7 +105,8 @@
 #if defined(OS_ANDROID)
   JNIEnv* env = base::android::AttachCurrentThread();
   base::android::ScopedJavaLocalRef<jobject> java_ref =
-      Java_AccountTrackerService_create(env, reinterpret_cast<intptr_t>(this));
+      signin::Java_AccountTrackerService_create(
+          env, reinterpret_cast<intptr_t>(this));
   java_ref_.Reset(env, java_ref.obj());
 #endif
 }
diff --git a/components/signin/public/android/BUILD.gn b/components/signin/public/android/BUILD.gn
index 43aed4af..f9f9280 100644
--- a/components/signin/public/android/BUILD.gn
+++ b/components/signin/public/android/BUILD.gn
@@ -16,6 +16,7 @@
   ]
 
   sources = [
+    "java/src/org/chromium/components/signin/AccountTrackerService.java",
     "java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java",
     "java/src/org/chromium/components/signin/base/AccountInfo.java",
     "java/src/org/chromium/components/signin/base/CoreAccountId.java",
@@ -33,6 +34,7 @@
 generate_jni("jni_headers") {
   namespace = "signin"
   sources = [
+    "java/src/org/chromium/components/signin/AccountTrackerService.java",
     "java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java",
     "java/src/org/chromium/components/signin/base/AccountInfo.java",
     "java/src/org/chromium/components/signin/base/CoreAccountId.java",
@@ -45,14 +47,36 @@
   ]
 }
 
+android_library("signin_java_test_support") {
+  testonly = true
+  deps = [
+    ":signin_test_resources",
+    "//base:base_java",
+    "//components/signin/core/browser/android:java",
+    "//third_party/android_deps:androidx_annotation_annotation_java",
+  ]
+  sources = [
+    "java/src/org/chromium/components/signin/test/util/AccountHolder.java",
+    "java/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java",
+    "java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java",
+    "java/src/org/chromium/components/signin/test/util/FakeProfileDataSource.java",
+  ]
+  resources_package = "org.chromium.components.signin.test.util"
+}
+
+android_resources("signin_test_resources") {
+  testonly = true
+  sources = [ "java/res/drawable/test_profile_picture.xml" ]
+}
+
 android_library("javatests") {
   testonly = true
   deps = [
     ":java",
+    ":signin_java_test_support",
     "//base:base_java",
     "//base:base_java_test_support",
     "//components/signin/core/browser/android:java",
-    "//components/signin/core/browser/android:signin_java_test_support",
     "//third_party/android_deps:androidx_annotation_annotation_java",
     "//third_party/android_deps:androidx_test_runner_java",
     "//third_party/android_support_test_runner:rules_java",
@@ -76,11 +100,11 @@
     "junit/src/org/chromium/components/signin/PatternMatcherTest.java",
   ]
   deps = [
+    ":signin_java_test_support",
     "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//components/signin/core/browser/android:java",
-    "//components/signin/core/browser/android:signin_java_test_support",
     "//testing/android/junit:junit_test_support",
     "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
diff --git a/components/signin/core/browser/android/javatests/res/drawable/test_profile_picture.xml b/components/signin/public/android/java/res/drawable/test_profile_picture.xml
similarity index 100%
rename from components/signin/core/browser/android/javatests/res/drawable/test_profile_picture.xml
rename to components/signin/public/android/java/res/drawable/test_profile_picture.xml
diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/AccountTrackerService.java b/components/signin/public/android/java/src/org/chromium/components/signin/AccountTrackerService.java
new file mode 100644
index 0000000..d4bab9d
--- /dev/null
+++ b/components/signin/public/android/java/src/org/chromium/components/signin/AccountTrackerService.java
@@ -0,0 +1,248 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.signin;
+
+import android.os.SystemClock;
+
+import androidx.annotation.IntDef;
+
+import org.chromium.base.Log;
+import org.chromium.base.ObserverList;
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.NativeMethods;
+import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.base.task.AsyncTask;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Android wrapper of AccountTrackerService which provides access from the java layer.
+ * It offers the capability of fetching and seeding system accounts into AccountTrackerService in
+ * C++ layer, and notifies observers when it is complete.
+ *
+ * TODO(crbug/1176136): Move this class to components/signin/internal
+ */
+public class AccountTrackerService {
+    private static final String TAG = "AccountService";
+
+    private final long mNativeAccountTrackerService;
+    private @SystemAccountsSeedingStatus int mSystemAccountsSeedingStatus;
+    private boolean mSystemAccountsChanged;
+    private AccountsChangeObserver mAccountsChangeObserver;
+
+    @IntDef({SystemAccountsSeedingStatus.SEEDING_NOT_STARTED,
+            SystemAccountsSeedingStatus.SEEDING_IN_PROGRESS,
+            SystemAccountsSeedingStatus.SEEDING_DONE,
+            SystemAccountsSeedingStatus.SEEDING_VALIDATING})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SystemAccountsSeedingStatus {
+        int SEEDING_NOT_STARTED = 0;
+        int SEEDING_IN_PROGRESS = 1;
+        int SEEDING_DONE = 2;
+        int SEEDING_VALIDATING = 3;
+    }
+
+    /**
+     * Classes that want to listen for system accounts fetching and seeding should implement
+     * this interface and register with {@link #addSystemAccountsSeededListener}.
+     */
+    public interface OnSystemAccountsSeededListener {
+        // Called at the end of seedSystemAccounts().
+        void onSystemAccountsSeedingComplete();
+        // Called in invalidateAccountSeedStatus() indicating that accounts have changed.
+        default void onSystemAccountsChanged() {}
+    }
+
+    private final ObserverList<OnSystemAccountsSeededListener> mSystemAccountsSeedingObservers =
+            new ObserverList<>();
+
+    private AccountTrackerService(long nativeAccountTrackerService) {
+        mNativeAccountTrackerService = nativeAccountTrackerService;
+        mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_NOT_STARTED;
+        mSystemAccountsChanged = false;
+    }
+
+    @CalledByNative
+    private static AccountTrackerService create(long nativeAccountTrackerService) {
+        ThreadUtils.assertOnUiThread();
+        return new AccountTrackerService(nativeAccountTrackerService);
+    }
+
+    /**
+     * Checks whether the account id <-> email mapping has been seeded into C++ layer.
+     * If not, it automatically starts fetching the mapping and seeds it.
+     * @return Whether the accounts have been seeded already.
+     */
+    public boolean checkAndSeedSystemAccounts() {
+        ThreadUtils.assertOnUiThread();
+        if (areSystemAccountsSeeded()) {
+            return true;
+        }
+        if ((mSystemAccountsSeedingStatus == SystemAccountsSeedingStatus.SEEDING_NOT_STARTED
+                    || mSystemAccountsChanged)
+                && mSystemAccountsSeedingStatus
+                        != SystemAccountsSeedingStatus.SEEDING_IN_PROGRESS) {
+            seedSystemAccounts();
+        }
+        return false;
+    }
+
+    /**
+     * Checks whether system accounts are seeded without changing the state.
+     * @return Whether account list in {@link AccountManagerFacade} is consistent with accounts in
+     *         the native AccountTrackerService.
+     */
+    private boolean areSystemAccountsSeeded() {
+        return mSystemAccountsSeedingStatus == SystemAccountsSeedingStatus.SEEDING_DONE
+                && !mSystemAccountsChanged;
+    }
+
+    /**
+     * Register an |observer| to observe system accounts seeding status.
+     */
+    public void addSystemAccountsSeededListener(OnSystemAccountsSeededListener observer) {
+        ThreadUtils.assertOnUiThread();
+        mSystemAccountsSeedingObservers.addObserver(observer);
+    }
+
+    /**
+     * Remove an |observer| from the list of observers.
+     */
+    public void removeSystemAccountsSeededListener(OnSystemAccountsSeededListener observer) {
+        ThreadUtils.assertOnUiThread();
+        mSystemAccountsSeedingObservers.removeObserver(observer);
+    }
+
+    private void seedSystemAccounts() {
+        ThreadUtils.assertOnUiThread();
+        mSystemAccountsChanged = false;
+        final AccountManagerFacade accountManagerFacade =
+                AccountManagerFacadeProvider.getInstance();
+        if (accountManagerFacade.isGooglePlayServicesAvailable()) {
+            mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_IN_PROGRESS;
+        } else {
+            mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_NOT_STARTED;
+            return;
+        }
+
+        if (mAccountsChangeObserver == null) {
+            mAccountsChangeObserver =
+                    () -> invalidateAccountSeedStatus(false /* don't reseed right now */);
+            accountManagerFacade.addObserver(mAccountsChangeObserver);
+        }
+
+        accountManagerFacade.tryGetGoogleAccounts(accounts -> {
+            new AsyncTask<String[][]>() {
+                @Override
+                public String[][] doInBackground() {
+                    Log.d(TAG, "Getting id/email mapping");
+
+                    long seedingStartTime = SystemClock.elapsedRealtime();
+
+                    String[][] accountIdNameMap = new String[2][accounts.size()];
+                    for (int i = 0; i < accounts.size(); ++i) {
+                        accountIdNameMap[0][i] =
+                                accountManagerFacade.getAccountGaiaId(accounts.get(i).name);
+                        accountIdNameMap[1][i] = accounts.get(i).name;
+                    }
+
+                    RecordHistogram.recordTimesHistogram("Signin.AndroidGetAccountIdsTime",
+                            SystemClock.elapsedRealtime() - seedingStartTime);
+
+                    return accountIdNameMap;
+                }
+                @Override
+                public void onPostExecute(String[][] accountIdNameMap) {
+                    if (mSystemAccountsChanged) {
+                        seedSystemAccounts();
+                        return;
+                    }
+                    if (areAccountIdsValid(accountIdNameMap[0])) {
+                        AccountTrackerServiceJni.get().seedAccountsInfo(
+                                mNativeAccountTrackerService, accountIdNameMap[0],
+                                accountIdNameMap[1]);
+                        mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_DONE;
+                        notifyObserversOnSeedingComplete();
+                    } else {
+                        Log.w(TAG, "Invalid mapping of id/email");
+                        seedSystemAccounts();
+                    }
+                }
+            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+        });
+    }
+
+    private boolean areAccountIdsValid(String[] accountIds) {
+        for (String accountId : accountIds) {
+            if (accountId == null) return false;
+        }
+        return true;
+    }
+
+    private void notifyObserversOnSeedingComplete() {
+        for (OnSystemAccountsSeededListener observer : mSystemAccountsSeedingObservers) {
+            observer.onSystemAccountsSeedingComplete();
+        }
+    }
+
+    /**
+     * Notifies the AccountTrackerService about changed system accounts. without actually triggering
+     * @param reSeedAccounts Whether to also start seeding the new account information immediately.
+     */
+    public void invalidateAccountSeedStatus(boolean reSeedAccounts) {
+        ThreadUtils.assertOnUiThread();
+        mSystemAccountsChanged = true;
+        notifyObserversOnAccountsChange();
+        if (reSeedAccounts) checkAndSeedSystemAccounts();
+    }
+
+    /**
+     * Verifies whether seeded accounts in AccountTrackerService are up-to-date with the accounts in
+     * Android. It sets seeding status to SEEDING_VALIDATING temporarily to block services depending
+     * on it and sets it back to SEEDING_DONE after passing the verification. This function is
+     * created because accounts changed notification from Android to Chrome has latency.
+     */
+    public void validateSystemAccounts() {
+        ThreadUtils.assertOnUiThread();
+        if (!checkAndSeedSystemAccounts()) {
+            // Do nothing if seeding is not done.
+            return;
+        }
+
+        mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_VALIDATING;
+        AccountManagerFacadeProvider.getInstance().tryGetGoogleAccounts(accounts -> {
+            if (mSystemAccountsChanged
+                    || mSystemAccountsSeedingStatus
+                            != SystemAccountsSeedingStatus.SEEDING_VALIDATING) {
+                return;
+            }
+
+            String[] accountNames = new String[accounts.size()];
+            for (int i = 0; i < accounts.size(); ++i) {
+                accountNames[i] = accounts.get(i).name;
+            }
+            if (AccountTrackerServiceJni.get().areAccountsSeeded(
+                        mNativeAccountTrackerService, accountNames)) {
+                mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_DONE;
+                notifyObserversOnSeedingComplete();
+            }
+        });
+    }
+
+    private void notifyObserversOnAccountsChange() {
+        for (OnSystemAccountsSeededListener observer : mSystemAccountsSeedingObservers) {
+            observer.onSystemAccountsChanged();
+        }
+    }
+
+    @NativeMethods
+    interface Natives {
+        void seedAccountsInfo(
+                long nativeAccountTrackerService, String[] gaiaIds, String[] accountNames);
+        boolean areAccountsSeeded(long nativeAccountTrackerService, String[] accountNames);
+    }
+}
diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java b/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java
index 1e8dc6d..058488e0 100644
--- a/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java
+++ b/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java
@@ -14,6 +14,7 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.components.signin.base.AccountInfo;
+import org.chromium.components.signin.base.CoreAccountId;
 import org.chromium.components.signin.base.CoreAccountInfo;
 
 /**
@@ -165,6 +166,19 @@
     }
 
     /**
+     * Forces refreshing extended {@link AccountInfo} with image for the given
+     * {@link CoreAccountId}.
+     *
+     * This method should only be invoked by {@link ProfileDownloader} to fetch account information
+     * while users are signed out.
+     */
+    public void forceRefreshOfExtendedAccountInfo(CoreAccountId coreAccountId) {
+        assert coreAccountId != null : "coreAccountId shouldn't be null!";
+        IdentityManagerJni.get().forceRefreshOfExtendedAccountInfo(
+                mNativeIdentityManager, coreAccountId);
+    }
+
+    /**
      * Call this method to retrieve an OAuth2 access token for the given account and scope. Please
      * note that this method expects a scope with 'oauth2:' prefix.
      * @param account the account to get the access token for.
@@ -198,5 +212,7 @@
         AccountInfo findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
                 long nativeIdentityManager, String email);
         CoreAccountInfo[] getAccountsWithRefreshTokens(long nativeIdentityManager);
+        void forceRefreshOfExtendedAccountInfo(
+                long nativeIdentityManager, CoreAccountId coreAccountId);
     }
 }
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/AccountHolder.java b/components/signin/public/android/java/src/org/chromium/components/signin/test/util/AccountHolder.java
similarity index 100%
rename from components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/AccountHolder.java
rename to components/signin/public/android/java/src/org/chromium/components/signin/test/util/AccountHolder.java
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java b/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java
similarity index 100%
rename from components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java
rename to components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java b/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java
similarity index 100%
rename from components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java
rename to components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeProfileDataSource.java b/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeProfileDataSource.java
similarity index 100%
rename from components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeProfileDataSource.java
rename to components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeProfileDataSource.java
diff --git a/components/signin/public/identity_manager/identity_manager.cc b/components/signin/public/identity_manager/identity_manager.cc
index c350f835..f218400 100644
--- a/components/signin/public/identity_manager/identity_manager.cc
+++ b/components/signin/public/identity_manager/identity_manager.cc
@@ -391,6 +391,13 @@
   account_fetcher_service_->ForceRefreshOfAccountInfo(account_id);
 }
 
+void IdentityManager::ForceRefreshOfExtendedAccountInfo(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& j_core_account_id) {
+  ForceRefreshOfExtendedAccountInfo(
+      ConvertFromJavaCoreAccountId(env, j_core_account_id));
+}
+
 base::android::ScopedJavaLocalRef<jobject>
 IdentityManager::GetPrimaryAccountInfo(JNIEnv* env, jint consent_level) const {
   CoreAccountInfo account_info =
diff --git a/components/signin/public/identity_manager/identity_manager.h b/components/signin/public/identity_manager/identity_manager.h
index 2623ffda..f0a6a97c 100644
--- a/components/signin/public/identity_manager/identity_manager.h
+++ b/components/signin/public/identity_manager/identity_manager.h
@@ -462,6 +462,12 @@
 
   base::android::ScopedJavaLocalRef<jobjectArray> GetAccountsWithRefreshTokens(
       JNIEnv* env) const;
+
+  // Forces refreshing extended account info with image for the given
+  // core account id.
+  void ForceRefreshOfExtendedAccountInfo(
+      JNIEnv* env,
+      const base::android::JavaParamRef<jobject>& j_core_account_id);
 #endif
 
  private:
diff --git a/components/spellcheck/renderer/spellcheck_unittest.cc b/components/spellcheck/renderer/spellcheck_unittest.cc
index 4b46a419..e85f2cfe 100644
--- a/components/spellcheck/renderer/spellcheck_unittest.cc
+++ b/components/spellcheck/renderer/spellcheck_unittest.cc
@@ -476,9 +476,16 @@
   }
 }
 
+// TODO(crbug.com/1175933): Fix the uninitialized memory and re-enable the test.
+#if defined(MEMORY_SANITIZER)
+#define MAYBE_SpellCheckText DISABLED_SpellCheckText
+#else
+#define MAYBE_SpellCheckText SpellCheckText
+#endif
+
 // This test verifies our spellchecker can split a text into words and check
 // the spelling of each word in the text.
-TEST_F(SpellCheckTest, SpellCheckText) {
+TEST_F(SpellCheckTest, MAYBE_SpellCheckText) {
   static const struct {
     const char* language;
     const wchar_t* input;
diff --git a/components/strings/BUILD.gn b/components/strings/BUILD.gn
index 776127e..15bf6b0 100644
--- a/components/strings/BUILD.gn
+++ b/components/strings/BUILD.gn
@@ -33,7 +33,6 @@
     "enable_arcore=$enable_arcore",
     "enable_plugins=$enable_plugins",
     "enable_print_preview=$enable_print_preview",
-    "enable_feed_v1=$enable_feed_v1",
     "enable_vr=$enable_vr",
   ]
 
@@ -57,11 +56,6 @@
 }
 
 grit("components_chromium_strings") {
-  # TODO(crbug.com/1112471). For reasons I don't understand,
-  # IDS_ERRORPAGES_SUGGESTION_PROXY_DISABLE_PLATFORM is not defined
-  # on desktop linux when this is run under Python3. Fix this.
-  run_under_python2 = true
-
   source = "../components_chromium_strings.grd"
   outputs = [ "grit/components_chromium_strings.h" ]
   foreach(locale, locales_with_fake_bidi) {
diff --git a/components/strings/components_strings_hy.xtb b/components/strings/components_strings_hy.xtb
index d15d2f5..6bf9f87f 100644
--- a/components/strings/components_strings_hy.xtb
+++ b/components/strings/components_strings_hy.xtb
@@ -261,7 +261,7 @@
 <translation id="1871284979644508959">Պարտադիր դաշտ</translation>
 <translation id="1875512691959384712">Google Ձևաթղթեր</translation>
 <translation id="187918866476621466">Բացել մեկնարկի էջերը</translation>
-<translation id="1883255238294161206">Կոծկել ցանկը</translation>
+<translation id="1883255238294161206">Ծալել ցանկը</translation>
 <translation id="1898423065542865115">Զտում</translation>
 <translation id="1901443836186977402">{1,plural, =1{Այս սերվերը չկարողացավ ապացուցել, որ այն իսկապես ներկայացնում է <ph name="DOMAIN" /> տիրույթը: Դրա անվտանգության հավաստագրի ժամկետը նախորդ օրը լրացել է: Պատճառը կարող է լինել ինչպես սերվերի սխալ կազմաձևումը, այնպես էլ ձեր և սերվերի միջև կապուղու վրա հաքերային հարձակումն և գաղտնալսումը: Ձեր համակարգչի ժամացույցն այս պահին ցույց է տալիս <ph name="CURRENT_DATE" />: Սա ճի՞շտ ժամն է։ Եթե ոչ, ուղղեք այն և թարմացրեք այս էջը:}one{Այս սերվերը չկարողացավ ապացուցել, որ այն իսկապես ներկայացնում է <ph name="DOMAIN" /> տիրույթը: Դրա անվտանգության հավաստագրի ժամկետը # օր առաջ սպառվել է: Պատճառը կարող է լինել ինչպես սերվերի սխալ կազմաձևումը, այնպես էլ ձեր և սերվերի միջև կապուղու վրա հաքերային հարձակումն և գաղտնալսումը: Ձեր համակարգչի ժամացույցը այս պահին ցույց է տալիս <ph name="CURRENT_DATE" />: Սա ճի՞շտ ժամն է: Եթե ոչ, ուղղեք այն և թարմացրեք այս էջը:}other{Այս սերվերը չկարողացավ ապացուցել, որ այն իսկապես ներկայացնում է <ph name="DOMAIN" /> տիրույթը: Դրա անվտանգության հավաստագրի ժամկետը # օր առաջ սպառվել է: Պատճառը կարող է լինել ինչպես սերվերի սխալ կազմաձևումը, այնպես էլ ձեր և սերվերի միջև կապուղու վրա հաքերային հարձակումն և գաղտնալսումը: Ձեր համակարգչի ժամացույցը այս պահին ցույց է տալիս <ph name="CURRENT_DATE" />: Սա ճի՞շտ ժամն է: Եթե ոչ, ուղղեք այն և թարմացրեք այս էջը:}}</translation>
 <translation id="1902576642799138955">Վավերության ժամկետ</translation>
diff --git a/components/strings/components_strings_ja.xtb b/components/strings/components_strings_ja.xtb
index 2272fb2..8c80455 100644
--- a/components/strings/components_strings_ja.xtb
+++ b/components/strings/components_strings_ja.xtb
@@ -938,7 +938,7 @@
 <translation id="4660119392514473465">現在、シークレット モードで閲覧しています。あなたのアクティビティは、このデバイスを利用する他のユーザーには表示されません。ただし、ダウンロードしたファイル、ブックマーク、リーディング リストは通常どおり保存されます。</translation>
 <translation id="4668929960204016307">,</translation>
 <translation id="4670064810192446073">バーチャル リアリティ(VR)</translation>
-<translation id="4675657451653251260">ゲストモードでは Chrome プロフィールの情報が表示されません。<ph name="LINK_BEGIN" />ログイン<ph name="LINK_END" />すると、パスワードやお支払い方法などの Google アカウント情報にアクセスできます。</translation>
+<translation id="4675657451653251260">ゲストモードでは Chrome プロファイルの情報が表示されません。<ph name="LINK_BEGIN" />ログイン<ph name="LINK_END" />すると、パスワードやお支払い方法などの Google アカウント情報にアクセスできます。</translation>
 <translation id="467662567472608290">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書にはエラーがあります。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
 <translation id="4677585247300749148"><ph name="URL" /> から、ユーザー補助機能のイベントに応答する許可を求められています</translation>
 <translation id="467809019005607715">Google スライド</translation>
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc
index 7caad8b5..ab4505e 100644
--- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc
+++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc
@@ -71,6 +71,7 @@
 
   void OnSubresourceFilterAgentReceiver(
       mojo::ScopedInterfaceEndpointHandle handle) {
+    receiver_.reset();
     receiver_.Bind(
         mojo::PendingAssociatedReceiver<mojom::SubresourceFilterAgent>(
             std::move(handle)));
diff --git a/components/subresource_filter/content/renderer/subresource_filter_agent.cc b/components/subresource_filter/content/renderer/subresource_filter_agent.cc
index acc1d8d5c..4316804 100644
--- a/components/subresource_filter/content/renderer/subresource_filter_agent.cc
+++ b/components/subresource_filter/content/renderer/subresource_filter_agent.cc
@@ -229,6 +229,7 @@
 
 void SubresourceFilterAgent::OnSubresourceFilterAgentRequest(
     mojo::PendingAssociatedReceiver<mojom::SubresourceFilterAgent> receiver) {
+  receiver_.reset();
   receiver_.Bind(std::move(receiver));
 }
 
diff --git a/components/translate/content/renderer/per_frame_translate_agent.cc b/components/translate/content/renderer/per_frame_translate_agent.cc
index ec2a727..25f0a92 100644
--- a/components/translate/content/renderer/per_frame_translate_agent.cc
+++ b/components/translate/content/renderer/per_frame_translate_agent.cc
@@ -411,6 +411,7 @@
 
 void PerFrameTranslateAgent::BindReceiver(
     mojo::PendingAssociatedReceiver<mojom::TranslateAgent> receiver) {
+  receiver_.reset();
   receiver_.Bind(std::move(receiver));
 }
 
diff --git a/components/ukm/ukm_recorder_impl.cc b/components/ukm/ukm_recorder_impl.cc
index 5799b157..ee326a1 100644
--- a/components/ukm/ukm_recorder_impl.cc
+++ b/components/ukm/ukm_recorder_impl.cc
@@ -73,24 +73,6 @@
                            event_hash & 0x7fffffff);
 }
 
-// Artificially inflates counts of some event types reported to UMA histogram.
-// TODO(crbug/1137922): remove this artificial inflation of counts after alerts
-// are tested.
-void MaybeInflateHistogramCount(const std::string& histogram_name,
-                                uint64_t event_hash) {
-  const static std::map<uint64_t, size_t> event_hash_to_multipliers = {
-      {builders::Media_BasicPlayback::kEntryNameHash, 4},
-      {builders::RendererSchedulerTask::kEntryNameHash, 2},
-      {builders::HistoryNavigation::kEntryNameHash, 99},
-  };
-
-  auto iter = event_hash_to_multipliers.find(event_hash);
-  if (iter != event_hash_to_multipliers.end()) {
-    for (size_t i = 0; i < iter->second; ++i)
-      LogEventHashAsUmaHistogram(histogram_name, event_hash);
-  }
-}
-
 enum class DroppedDataReason {
   NOT_DROPPED = 0,
   RECORDING_DISABLED = 1,
@@ -762,8 +744,6 @@
   // entry counts.
   LogEventHashAsUmaHistogram("UKM.Entries.Recorded.ByEntryHash",
                              entry->event_hash);
-  MaybeInflateHistogramCount("UKM.Entries.Recorded.ByEntryHash",
-                             entry->event_hash);
 
   recordings_.entries.push_back(std::move(entry));
 }
diff --git a/components/webapps/browser/android/add_to_homescreen_data_fetcher.cc b/components/webapps/browser/android/add_to_homescreen_data_fetcher.cc
index 650d88ee..ec31bfc7c 100644
--- a/components/webapps/browser/android/add_to_homescreen_data_fetcher.cc
+++ b/components/webapps/browser/android/add_to_homescreen_data_fetcher.cc
@@ -227,15 +227,15 @@
 
   is_waiting_for_manifest_ = false;
 
-  if (!data.manifest->IsEmpty()) {
+  if (!data.manifest.IsEmpty()) {
     base::RecordAction(base::UserMetricsAction("webapps.AddShortcut.Manifest"));
-    shortcut_info_.UpdateFromManifest(*data.manifest);
+    shortcut_info_.UpdateFromManifest(data.manifest);
     shortcut_info_.manifest_url = data.manifest_url;
   }
 
   // Do this after updating from the manifest for the case where a site has
   // a manifest with name and standalone specified, but no icons.
-  if (data.manifest->IsEmpty() || !data.primary_icon) {
+  if (data.manifest.IsEmpty() || !data.primary_icon) {
     observer_->OnUserTitleAvailable(shortcut_info_.user_title,
                                     shortcut_info_.url,
                                     /*is_webapk_compatible=*/false);
@@ -255,7 +255,7 @@
       WebappsIconUtils::GetMinimumSplashImageSizeInPx();
   shortcut_info_.splash_image_url =
       blink::ManifestIconSelector::FindBestMatchingSquareIcon(
-          data.manifest->icons, shortcut_info_.ideal_splash_image_size_in_px,
+          data.manifest.icons, shortcut_info_.ideal_splash_image_size_in_px,
           shortcut_info_.minimum_splash_image_size_in_px,
           blink::mojom::ManifestImageResource_Purpose::ANY);
 
@@ -274,7 +274,7 @@
 
   bool webapk_compatible =
       (data.NoBlockingErrors() && data.valid_manifest && data.has_worker &&
-       WebappsUtils::AreWebManifestUrlsWebApkCompatible(*data.manifest));
+       WebappsUtils::AreWebManifestUrlsWebApkCompatible(data.manifest));
   observer_->OnUserTitleAvailable(
       webapk_compatible ? shortcut_info_.name : shortcut_info_.user_title,
       shortcut_info_.url, webapk_compatible);
diff --git a/components/webapps/browser/android/add_to_homescreen_data_fetcher_unittest.cc b/components/webapps/browser/android/add_to_homescreen_data_fetcher_unittest.cc
index 5a74bbee..568946d 100644
--- a/components/webapps/browser/android/add_to_homescreen_data_fetcher_unittest.cc
+++ b/components/webapps/browser/android/add_to_homescreen_data_fetcher_unittest.cc
@@ -159,7 +159,7 @@
     if (code != NO_ERROR_DETECTED)
       errors.push_back(code);
     std::move(callback).Run(
-        {std::move(errors), GURL(kDefaultManifestUrl), &manifest_,
+        {std::move(errors), GURL(kDefaultManifestUrl), manifest_,
          params.valid_primary_icon ? primary_icon_url_ : GURL(),
          params.valid_primary_icon ? primary_icon_.get() : nullptr,
          params.prefer_maskable_icon, GURL() /* splash_icon_url */,
diff --git a/components/webapps/browser/banners/app_banner_manager.cc b/components/webapps/browser/banners/app_banner_manager.cc
index 4f8f6e2..3349d68 100644
--- a/components/webapps/browser/banners/app_banner_manager.cc
+++ b/components/webapps/browser/banners/app_banner_manager.cc
@@ -350,10 +350,10 @@
   }
 
   DCHECK(!data.manifest_url.is_empty());
-  DCHECK(!data.manifest->IsEmpty());
+  DCHECK(!data.manifest.IsEmpty());
 
   manifest_url_ = data.manifest_url;
-  manifest_ = *data.manifest;
+  manifest_ = data.manifest;
 
   PerformInstallableChecks();
 }
diff --git a/components/webapps/browser/installable/fake_installable_manager.cc b/components/webapps/browser/installable/fake_installable_manager.cc
index 8fcfab4..b49d5b0c 100644
--- a/components/webapps/browser/installable/fake_installable_manager.cc
+++ b/components/webapps/browser/installable/fake_installable_manager.cc
@@ -48,10 +48,12 @@
     InstallableStatusCode installable_code,
     const GURL& manifest_url,
     std::unique_ptr<blink::Manifest> manifest) {
+  DCHECK(manifest);
+
   FakeInstallableManager* installable_manager =
       FakeInstallableManager::CreateForWebContents(web_contents);
 
-  const bool valid_manifest = manifest && !manifest->IsEmpty();
+  const bool valid_manifest = !manifest->IsEmpty();
   installable_manager->manifest_url_ = manifest_url;
   installable_manager->manifest_ = std::move(manifest);
 
@@ -66,9 +68,9 @@
 
   auto installable_data = std::make_unique<InstallableData>(
       std::move(errors), installable_manager->manifest_url_,
-      installable_manager->manifest_.get(), GURL::EmptyGURL(), icon.get(),
-      false, GURL::EmptyGURL(), icon.get(), std::vector<SkBitmap>(),
-      valid_manifest, has_worker);
+      *installable_manager->manifest_, GURL::EmptyGURL(), icon.get(), false,
+      GURL::EmptyGURL(), icon.get(), std::vector<SkBitmap>(), valid_manifest,
+      has_worker);
 
   installable_manager->data_ = std::move(installable_data);
 
diff --git a/components/webapps/browser/installable/installable_data.cc b/components/webapps/browser/installable/installable_data.cc
index 73386f3..146912a 100644
--- a/components/webapps/browser/installable/installable_data.cc
+++ b/components/webapps/browser/installable/installable_data.cc
@@ -10,7 +10,7 @@
 
 InstallableData::InstallableData(std::vector<InstallableStatusCode> errors,
                                  const GURL& manifest_url,
-                                 const blink::Manifest* manifest,
+                                 const blink::Manifest& manifest,
                                  const GURL& primary_icon_url,
                                  const SkBitmap* primary_icon,
                                  bool has_maskable_primary_icon,
diff --git a/components/webapps/browser/installable/installable_data.h b/components/webapps/browser/installable/installable_data.h
index 69743c2d..5aa44abc 100644
--- a/components/webapps/browser/installable/installable_data.h
+++ b/components/webapps/browser/installable/installable_data.h
@@ -24,7 +24,7 @@
 struct InstallableData {
   InstallableData(std::vector<InstallableStatusCode> errors,
                   const GURL& manifest_url,
-                  const blink::Manifest* manifest,
+                  const blink::Manifest& manifest,
                   const GURL& primary_icon_url,
                   const SkBitmap* primary_icon,
                   bool has_maskable_primary_icon,
@@ -51,9 +51,8 @@
   // <link rel="manifest"> tag.
   const GURL& manifest_url;
 
-  // The parsed web app manifest. nullptr if the site has an unparseable
-  // manifest.
-  const blink::Manifest* manifest;
+  // The parsed web app manifest.
+  const blink::Manifest& manifest;
 
   // The URL of the chosen primary icon.
   const GURL& primary_icon_url;
diff --git a/components/webapps/browser/installable/installable_manager.cc b/components/webapps/browser/installable/installable_manager.cc
index 39ca3679..6e7d1f8 100644
--- a/components/webapps/browser/installable/installable_manager.cc
+++ b/components/webapps/browser/installable/installable_manager.cc
@@ -512,7 +512,7 @@
   InstallableData data = {
       std::move(errors),
       manifest_url(),
-      &manifest(),
+      manifest(),
       primary_icon->url,
       primary_icon->icon.get(),
       has_maskable_primary_icon,
diff --git a/components/webapps/browser/installable/installable_task_queue.cc b/components/webapps/browser/installable/installable_task_queue.cc
index b98ba11..d6e1660 100644
--- a/components/webapps/browser/installable/installable_task_queue.cc
+++ b/components/webapps/browser/installable/installable_task_queue.cc
@@ -75,17 +75,17 @@
   for (InstallableTask& task : tasks) {
     if (task.callback) {
       std::move(task.callback)
-          .Run(InstallableData({code}, GURL(), &manifest, GURL(), nullptr,
-                               false, GURL(), nullptr, std::vector<SkBitmap>(),
-                               false, false));
+          .Run(InstallableData({code}, GURL(), manifest, GURL(), nullptr, false,
+                               GURL(), nullptr, std::vector<SkBitmap>(), false,
+                               false));
     }
   }
   for (InstallableTask& task : paused_tasks) {
     if (task.callback) {
       std::move(task.callback)
-          .Run(InstallableData({code}, GURL(), &manifest, GURL(), nullptr,
-                               false, GURL(), nullptr, std::vector<SkBitmap>(),
-                               false, false));
+          .Run(InstallableData({code}, GURL(), manifest, GURL(), nullptr, false,
+                               GURL(), nullptr, std::vector<SkBitmap>(), false,
+                               false));
     }
   }
 }
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 9293a2b..d099977 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -588,13 +588,6 @@
     "cache_storage/cache_storage_scheduler_types.h",
     "cache_storage/cache_storage_trace_utils.cc",
     "cache_storage/cache_storage_trace_utils.h",
-    "cache_storage/cross_sequence/cross_sequence_cache_storage.cc",
-    "cache_storage/cross_sequence/cross_sequence_cache_storage.h",
-    "cache_storage/cross_sequence/cross_sequence_cache_storage_cache.cc",
-    "cache_storage/cross_sequence/cross_sequence_cache_storage_cache.h",
-    "cache_storage/cross_sequence/cross_sequence_cache_storage_manager.cc",
-    "cache_storage/cross_sequence/cross_sequence_cache_storage_manager.h",
-    "cache_storage/cross_sequence/cross_sequence_utils.h",
     "cache_storage/legacy/legacy_cache_storage.cc",
     "cache_storage/legacy/legacy_cache_storage.h",
     "cache_storage/legacy/legacy_cache_storage_cache.cc",
diff --git a/content/browser/cache_storage/cache_storage_context_impl.cc b/content/browser/cache_storage/cache_storage_context_impl.cc
index 7101503..510177b 100644
--- a/content/browser/cache_storage/cache_storage_context_impl.cc
+++ b/content/browser/cache_storage/cache_storage_context_impl.cc
@@ -15,7 +15,6 @@
 #include "content/browser/cache_storage/blob_storage_context_wrapper.h"
 #include "content/browser/cache_storage/cache_storage_dispatcher_host.h"
 #include "content/browser/cache_storage/cache_storage_quota_client.h"
-#include "content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_manager.h"
 #include "content/browser/cache_storage/legacy/legacy_cache_storage_manager.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -36,11 +35,9 @@
 
 }  // namespace
 
-CacheStorageContextWithManager::CacheStorageContextWithManager()
-    : CacheStorageContext(GetUIThreadTaskRunner({})) {}
-
 CacheStorageContextImpl::CacheStorageContextImpl()
-    : task_runner_(CreateSchedulerTaskRunner()) {
+    : CacheStorageContext(GetUIThreadTaskRunner({})),
+      task_runner_(CreateSchedulerTaskRunner()) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 }
 
@@ -76,14 +73,6 @@
 void CacheStorageContextImpl::Shutdown() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  base::AutoLock lock(shutdown_lock_);
-
-  // Set an atomic flag indicating shutdown has been entered.  This allows us to
-  // avoid creating CrossSequenceCacheStorageManager objects when there will
-  // no longer be an underlying manager.
-  DCHECK(!shutdown_);
-  shutdown_ = true;
-
   // Break reference cycle with |this|.
   if (dispatcher_host_)
     dispatcher_host_.AsyncCall(&CacheStorageDispatcherHost::Shutdown);
@@ -97,11 +86,6 @@
 void CacheStorageContextImpl::Bind(
     mojo::PendingReceiver<storage::mojom::CacheStorageControl> control) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  {
-    base::AutoLock lock(shutdown_lock_);
-    if (shutdown_)
-      return;
-  }
   receivers_.Add(this, std::move(control));
 }
 
@@ -125,38 +109,16 @@
                 owner, std::move(receiver));
 }
 
-scoped_refptr<CacheStorageManager> CacheStorageContextImpl::CacheManager() {
-  // If we're already on the target sequence, then just return the real manager.
-  //
-  // Note, we can't check for nullptr cache_manager_ here because it is not
-  // threadsafe.  In addition we may be creating a cross-sequence manager
-  // wrapper while the task to set cache_manager_ is waiting to run.  This
-  // should be fine since the cross-sequence wrapper will initialize after the
-  // manager is set.  See the comment in Init().
-  if (task_runner_->RunsTasksInCurrentSequence())
-    return cache_manager_;
-  // Always return nullptr once shutdown has begun if we are on a different
-  // sequence.  This check is necessary to avoid creating
-  // CrossSequenceCacheStorageManager wrappers when there will no longer be an
-  // underlying manager.
-  base::AutoLock lock(shutdown_lock_);
-  if (shutdown_)
-    return nullptr;
-  // Otherwise we have to create a cross-sequence wrapper to provide safe
-  // access.
-  return base::MakeRefCounted<CrossSequenceCacheStorageManager>(task_runner_,
-                                                                this);
-}
-
 void CacheStorageContextImpl::GetAllOriginsInfo(
     storage::mojom::CacheStorageControl::GetAllOriginsInfoCallback callback) {
-  // Can be called on any sequence.
   callback = base::BindOnce(
       [](scoped_refptr<base::SequencedTaskRunner> reply_task_runner,
-         storage::mojom::CacheStorageControl::GetAllOriginsInfoCallback inner,
-         std::vector<storage::mojom::StorageUsageInfoPtr> entries) {
+         storage::mojom::CacheStorageControl::GetAllOriginsInfoCallback
+             callback,
+         std::vector<storage::mojom::StorageUsageInfoPtr> usage_info) {
         reply_task_runner->PostTask(
-            FROM_HERE, base::BindOnce(std::move(inner), std::move(entries)));
+            FROM_HERE,
+            base::BindOnce(std::move(callback), std::move(usage_info)));
       },
       base::SequencedTaskRunnerHandle::Get(), std::move(callback));
 
@@ -167,7 +129,7 @@
              storage::mojom::CacheStorageControl::GetAllOriginsInfoCallback
                  callback) {
             scoped_refptr<CacheStorageManager> manager =
-                context->CacheManager();
+                context->cache_manager();
             if (!manager) {
               std::move(callback).Run(
                   std::vector<storage::mojom::StorageUsageInfoPtr>());
@@ -181,14 +143,12 @@
 }
 
 void CacheStorageContextImpl::DeleteForOrigin(const url::Origin& origin) {
-  // Can be called on any sequence.
-
   task_runner_->PostTask(
       FROM_HERE, base::BindOnce(
                      [](scoped_refptr<CacheStorageContextImpl> context,
                         const url::Origin& origin) {
                        scoped_refptr<CacheStorageManager> manager =
-                           context->CacheManager();
+                           context->cache_manager();
                        if (!manager)
                          return;
                        manager->DeleteOriginData(
@@ -200,16 +160,13 @@
 
 void CacheStorageContextImpl::AddObserver(
     mojo::PendingRemote<storage::mojom::CacheStorageObserver> observer) {
-  DCHECK(cache_manager_);
-  // Can be called on any sequence.
-
   task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(
           [](scoped_refptr<CacheStorageContextImpl> context,
              mojo::PendingRemote<storage::mojom::CacheStorageObserver>
                  observer) {
-            auto manager = context->CacheManager();
+            auto manager = context->cache_manager();
             if (!manager)
               return;
             manager->AddObserver(std::move(observer));
@@ -255,7 +212,6 @@
 
 void CacheStorageContextImpl::ShutdownOnTaskRunner() {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
-  DCHECK(shutdown_);
 
   // Delete session-only ("clear on exit") origins.
   if (special_storage_policy_ &&
diff --git a/content/browser/cache_storage/cache_storage_context_impl.h b/content/browser/cache_storage/cache_storage_context_impl.h
index 2fceab1..77cc2f6 100644
--- a/content/browser/cache_storage/cache_storage_context_impl.h
+++ b/content/browser/cache_storage/cache_storage_context_impl.h
@@ -42,28 +42,11 @@
 class CacheStorageDispatcherHost;
 class CacheStorageManager;
 
-// An intermediate abstract interface that exposes the CacheManager() method.
-// This is mainly used in some places instead of the full
-// CacheStorageContextImpl to make it easier to write tests where we want to
-// provide a specific manager instance.
-class CONTENT_EXPORT CacheStorageContextWithManager
-    : public CacheStorageContext {
- public:
-  CacheStorageContextWithManager();
-
-  // Callable on any sequence.  May return nullptr during shutdown.
-  virtual scoped_refptr<CacheStorageManager> CacheManager() = 0;
-
- protected:
-  ~CacheStorageContextWithManager() override = default;
-};
-
 // One instance of this exists per StoragePartition, and services multiple
 // child processes/origins. Most logic is delegated to the owned
 // CacheStorageManager instance, which is only accessed on the target
 // sequence.
-class CONTENT_EXPORT CacheStorageContextImpl
-    : public CacheStorageContextWithManager {
+class CONTENT_EXPORT CacheStorageContextImpl : public CacheStorageContext {
  public:
   CacheStorageContextImpl();
 
@@ -93,14 +76,10 @@
   void AddObserver(mojo::PendingRemote<storage::mojom::CacheStorageObserver>
                        observer) override;
 
-  // If called on the cache_storage target sequence the real manager will be
-  // returned directly.  If called on any other sequence then a cross-sequence
-  // wrapper object will be created and returned instead.
-  //
-  // Note, this may begun returning nullptr at any time if shutdown is initiated
-  // on a separate thread.  Prefer to call CacheManager() once and hold a
-  // reference to the returned object.
-  scoped_refptr<CacheStorageManager> CacheManager() override;
+  scoped_refptr<CacheStorageManager> cache_manager() {
+    DCHECK(task_runner_->RunsTasksInCurrentSequence());
+    return cache_manager_;
+  }
 
   bool is_incognito() const { return is_incognito_; }
 
@@ -120,15 +99,9 @@
   // Initialized at construction.
   const scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
-  // Used to synchronize shutdown state aross multiple threads.
-  base::Lock shutdown_lock_;
-
   // Initialized in Init(); true if the user data directory is empty.
   bool is_incognito_ = false;
 
-  // True once Shutdown() has been called on the UI thread.
-  bool shutdown_ = false;
-
   // Initialized in Init().
   scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_;
 
diff --git a/content/browser/cache_storage/cache_storage_dispatcher_host.cc b/content/browser/cache_storage/cache_storage_dispatcher_host.cc
index be21be6d..9fe5d293 100644
--- a/content/browser/cache_storage/cache_storage_dispatcher_host.cc
+++ b/content/browser/cache_storage/cache_storage_dispatcher_host.cc
@@ -1002,7 +1002,7 @@
   if (!context_ || !OriginCanAccessCacheStorage(origin))
     return CacheStorageHandle();
 
-  scoped_refptr<CacheStorageManager> manager = context_->CacheManager();
+  scoped_refptr<CacheStorageManager> manager = context_->cache_manager();
   if (!manager)
     return CacheStorageHandle();
 
diff --git a/content/browser/cache_storage/cache_storage_manager_unittest.cc b/content/browser/cache_storage/cache_storage_manager_unittest.cc
index 86bbb86..47cfdac84 100644
--- a/content/browser/cache_storage/cache_storage_manager_unittest.cc
+++ b/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -36,7 +36,6 @@
 #include "content/browser/cache_storage/cache_storage_context_impl.h"
 #include "content/browser/cache_storage/cache_storage_quota_client.h"
 #include "content/browser/cache_storage/cache_storage_scheduler.h"
-#include "content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_manager.h"
 #include "content/browser/cache_storage/legacy/legacy_cache_storage.h"
 #include "content/browser/cache_storage/legacy/legacy_cache_storage_manager.h"
 #include "content/common/background_fetch/background_fetch_types.h"
@@ -70,24 +69,11 @@
 namespace content {
 namespace cache_storage_manager_unittest {
 
-enum class TestManager {
-  kLegacy,
-  kCrossSequence,
-};
-
 enum class TestStorage {
   kDisk,
   kMemory,
 };
 
-struct Param {
-  Param(TestManager manager, TestStorage storage)
-      : manager_(manager), storage_(storage) {}
-
-  TestManager manager_;
-  TestStorage storage_;
-};
-
 using blink::mojom::StorageType;
 using ResponseHeaderMap = base::flat_map<std::string, std::string>;
 
@@ -255,40 +241,6 @@
   std::unique_ptr<base::RunLoop> loop_;
 };
 
-class TestCacheStorageContext : public CacheStorageContextWithManager {
- public:
-  explicit TestCacheStorageContext(scoped_refptr<CacheStorageManager> manager)
-      : manager_(std::move(manager)) {}
-
-  scoped_refptr<CacheStorageManager> CacheManager() override {
-    return manager_;
-  }
-
-  void AddReceiver(
-      const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy,
-      mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter>
-          coep_reporter_remote,
-      const url::Origin& origin,
-      storage::mojom::CacheStorageOwner owner,
-      mojo::PendingReceiver<blink::mojom::CacheStorage> receiver) override {
-    NOTREACHED();
-  }
-  void DeleteForOrigin(const url::Origin& origin) override { NOTREACHED(); }
-  void GetAllOriginsInfo(
-      storage::mojom::CacheStorageControl::GetAllOriginsInfoCallback callback)
-      override {
-    NOTREACHED();
-  }
-  void AddObserver(mojo::PendingRemote<storage::mojom::CacheStorageObserver>
-                       observer) override {
-    NOTREACHED();
-  }
-
- private:
-  ~TestCacheStorageContext() override = default;
-  scoped_refptr<CacheStorageManager> manager_;
-};
-
 class CacheStorageManagerTest : public testing::Test {
  public:
   CacheStorageManagerTest()
@@ -312,7 +264,6 @@
   }
 
   virtual bool MemoryOnly() { return false; }
-  virtual TestManager ManagerType() { return TestManager::kLegacy; }
 
   void BoolCallback(base::RunLoop* run_loop, bool value) {
     callback_bool_ = value;
@@ -417,22 +368,10 @@
             mock_quota_manager_.get(),
             base::ThreadTaskRunnerHandle::Get().get());
 
-    auto legacy_manager = LegacyCacheStorageManager::Create(
+    cache_manager_ = LegacyCacheStorageManager::Create(
         temp_dir_path, base::ThreadTaskRunnerHandle::Get(),
         base::ThreadTaskRunnerHandle::Get(), quota_manager_proxy_,
         blob_storage_context_);
-
-    switch (ManagerType()) {
-      case TestManager::kLegacy:
-        cache_manager_ = std::move(legacy_manager);
-        break;
-      case TestManager::kCrossSequence:
-        auto context = base::MakeRefCounted<TestCacheStorageContext>(
-            std::move(legacy_manager));
-        cache_manager_ = base::MakeRefCounted<CrossSequenceCacheStorageManager>(
-            base::ThreadTaskRunnerHandle::Get(), std::move(context));
-        break;
-    }
   }
 
   void RecreateStorageManager() {
@@ -444,7 +383,6 @@
   }
 
   bool FlushCacheStorageIndex(const url::Origin& origin) {
-    DCHECK(ManagerType() == TestManager::kLegacy);
     callback_bool_ = false;
     base::RunLoop loop;
     auto* impl = LegacyCacheStorage::From(CacheStorageForOrigin(origin));
@@ -804,7 +742,6 @@
   }
 
   int64_t GetSizeThenCloseAllCaches(const url::Origin& origin) {
-    DCHECK(ManagerType() == TestManager::kLegacy);
     base::RunLoop loop;
     CacheStorageHandle cache_storage = CacheStorageForOrigin(origin);
     LegacyCacheStorage::From(cache_storage)
@@ -816,7 +753,6 @@
   }
 
   int64_t Size(const url::Origin& origin) {
-    DCHECK(ManagerType() == TestManager::kLegacy);
     base::RunLoop loop;
     CacheStorageHandle cache_storage = CacheStorageForOrigin(origin);
     LegacyCacheStorage::From(cache_storage)
@@ -881,25 +817,10 @@
   bool MemoryOnly() override { return true; }
 };
 
-class CacheStorageManagerTestP : public CacheStorageManagerTest,
-                                 public testing::WithParamInterface<Param> {
- public:
-  bool MemoryOnly() override {
-    return GetParam().storage_ == TestStorage::kMemory;
-  }
-  TestManager ManagerType() override { return GetParam().manager_; }
-};
-
-// Some tests must be run on the LegacyCacheStorageManager.  This could
-// be for a number of reasons:
-//  * The test needs to use internal APIs on the legacy manager.
-//  * The test is checking behavior that is only true for "real" manager's
-//    like that Open() will return the exact same c++ pointer for the
-//    underlying cache.  This assumption is not truee for the cross-sequence
-//    wrapper.
-class CacheStorageManagerLegacyOnlyTestP
+class CacheStorageManagerTestP
     : public CacheStorageManagerTest,
       public testing::WithParamInterface<TestStorage> {
+ public:
   bool MemoryOnly() override { return GetParam() == TestStorage::kMemory; }
 };
 
@@ -939,7 +860,7 @@
   EXPECT_NE(cache_handle.value(), callback_cache_handle_.value());
 }
 
-TEST_P(CacheStorageManagerLegacyOnlyTestP, OpenExistingCache) {
+TEST_P(CacheStorageManagerTestP, OpenExistingCache) {
   EXPECT_TRUE(Open(origin1_, "foo"));
   CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
   EXPECT_TRUE(Open(origin1_, "foo"));
@@ -1194,7 +1115,7 @@
   EXPECT_TRUE(StorageMatchAll(origin1_, GURL("http://example.com/foo")));
 }
 
-TEST_P(CacheStorageManagerLegacyOnlyTestP, Chinese) {
+TEST_P(CacheStorageManagerTestP, Chinese) {
   EXPECT_TRUE(Open(origin1_, "你好"));
   CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
   EXPECT_TRUE(Open(origin1_, "你好"));
@@ -1623,7 +1544,7 @@
   EXPECT_TRUE(callback_cache_handle_.value());
 }
 
-TEST_P(CacheStorageManagerLegacyOnlyTestP, OpenRunsSerially) {
+TEST_P(CacheStorageManagerTestP, OpenRunsSerially) {
   EXPECT_FALSE(Delete(origin1_, "tmp"));  // Init storage.
   CacheStorageHandle cache_storage = CacheStorageForOrigin(origin1_);
   auto* impl = LegacyCacheStorage::From(cache_storage);
@@ -1924,7 +1845,7 @@
   EXPECT_EQ(cache_size_v2, Size(origin1_));
 }
 
-TEST_P(CacheStorageManagerLegacyOnlyTestP, GetSizeThenCloseAllCaches) {
+TEST_P(CacheStorageManagerTestP, GetSizeThenCloseAllCaches) {
   EXPECT_TRUE(Open(origin1_, "foo"));
   EXPECT_TRUE(
       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
@@ -1942,7 +1863,7 @@
       CachePut(callback_cache_handle_.value(), GURL("http://example.com/baz")));
 }
 
-TEST_P(CacheStorageManagerLegacyOnlyTestP, GetSizeThenCloseAllCachesTwoOwners) {
+TEST_P(CacheStorageManagerTestP, GetSizeThenCloseAllCachesTwoOwners) {
   EXPECT_TRUE(
       Open(origin1_, "foo", storage::mojom::CacheStorageOwner::kCacheAPI));
   CacheStorageCacheHandle public_handle = std::move(callback_cache_handle_);
@@ -1961,8 +1882,7 @@
   EXPECT_FALSE(CachePut(public_handle.value(), GURL("http://example.com/baz")));
 }
 
-TEST_P(CacheStorageManagerLegacyOnlyTestP,
-       GetSizeThenCloseAllCachesAfterDelete) {
+TEST_P(CacheStorageManagerTestP, GetSizeThenCloseAllCachesAfterDelete) {
   // Tests that doomed caches are also deleted by GetSizeThenCloseAllCaches.
   EXPECT_TRUE(Open(origin1_, "foo"));
   EXPECT_TRUE(
@@ -2050,14 +1970,14 @@
   EXPECT_EQ(1, quota_manager_proxy_->notify_storage_accessed_count());
 }
 
-TEST_P(CacheStorageManagerLegacyOnlyTestP, SizeStorageAccessed) {
+TEST_P(CacheStorageManagerTestP, SizeStorageAccessed) {
   EXPECT_EQ(0, Size(origin1_));
   // Size is not part of the web API and should not notify the quota manager of
   // an access.
   EXPECT_EQ(0, quota_manager_proxy_->notify_storage_accessed_count());
 }
 
-TEST_P(CacheStorageManagerLegacyOnlyTestP, SizeThenCloseStorageAccessed) {
+TEST_P(CacheStorageManagerTestP, SizeThenCloseStorageAccessed) {
   EXPECT_EQ(0, GetSizeThenCloseAllCaches(origin1_));
   // GetSizeThenCloseAllCaches is not part of the web API and should not notify
   // the quota manager of an access.
@@ -2499,12 +2419,10 @@
   bool MemoryOnly() override { return false; }
 };
 
-class CacheStorageQuotaClientTestP : public CacheStorageQuotaClientTest,
-                                     public testing::WithParamInterface<Param> {
-  bool MemoryOnly() override {
-    return GetParam().storage_ == TestStorage::kMemory;
-  }
-  TestManager ManagerType() override { return GetParam().manager_; }
+class CacheStorageQuotaClientTestP
+    : public CacheStorageQuotaClientTest,
+      public testing::WithParamInterface<TestStorage> {
+  bool MemoryOnly() override { return GetParam() == TestStorage::kMemory; }
 };
 
 TEST_P(CacheStorageQuotaClientTestP, QuotaGetOriginUsage) {
@@ -2663,26 +2581,15 @@
   EXPECT_EQ(total_usage, (upgraded_size + upgraded_padding));
 }
 
-INSTANTIATE_TEST_SUITE_P(
-    CacheStorageManagerTests,
-    CacheStorageManagerTestP,
-    ::testing::Values(Param(TestManager::kLegacy, TestStorage::kMemory),
-                      Param(TestManager::kLegacy, TestStorage::kDisk),
-                      Param(TestManager::kCrossSequence, TestStorage::kMemory),
-                      Param(TestManager::kCrossSequence, TestStorage::kDisk)));
-
 INSTANTIATE_TEST_SUITE_P(CacheStorageManagerTests,
-                         CacheStorageManagerLegacyOnlyTestP,
+                         CacheStorageManagerTestP,
                          ::testing::Values(TestStorage::kMemory,
                                            TestStorage::kDisk));
 
-INSTANTIATE_TEST_SUITE_P(
-    CacheStorageQuotaClientTests,
-    CacheStorageQuotaClientTestP,
-    ::testing::Values(Param(TestManager::kLegacy, TestStorage::kMemory),
-                      Param(TestManager::kLegacy, TestStorage::kDisk),
-                      Param(TestManager::kCrossSequence, TestStorage::kMemory),
-                      Param(TestManager::kCrossSequence, TestStorage::kDisk)));
+INSTANTIATE_TEST_SUITE_P(CacheStorageQuotaClientTests,
+                         CacheStorageQuotaClientTestP,
+                         ::testing::Values(TestStorage::kMemory,
+                                           TestStorage::kDisk));
 
 }  // namespace cache_storage_manager_unittest
 }  // namespace content
diff --git a/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage.cc b/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage.cc
deleted file mode 100644
index 3757871..0000000
--- a/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage.cc
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage.h"
-
-#include "content/browser/cache_storage/cache_storage_context_impl.h"
-#include "content/browser/cache_storage/cache_storage_histogram_utils.h"
-#include "content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_cache.h"
-#include "content/browser/cache_storage/cross_sequence/cross_sequence_utils.h"
-
-namespace content {
-
-// The Inner class is SequenceBound<> to the real target CacheStorage sequence
-// by the outer CrossSequenceCacheStorage.  All CacheStorage operations are
-// proxied to the Inner on the correct sequence via the AsyncCall() method.  The
-// outer storage is responsible for wrapping any callbacks in order to post on
-// the outer's original sequence.
-// TODO(dcheng): See if this can use the Then() helper.
-class CrossSequenceCacheStorage::Inner {
- public:
-  using OpenCacheAdapterCallback =
-      base::OnceCallback<void(scoped_refptr<CrossSequenceCacheStorageCache>,
-                              blink::mojom::CacheStorageError)>;
-
-  Inner(const url::Origin& origin,
-        storage::mojom::CacheStorageOwner owner,
-        scoped_refptr<CacheStorageContextWithManager> context) {
-    scoped_refptr<CacheStorageManager> manager = context->CacheManager();
-    if (manager)
-      handle_ = manager->OpenCacheStorage(origin, owner);
-  }
-
-  void Init() {
-    if (!handle_.value())
-      return;
-    handle_.value()->Init();
-  }
-
-  void OpenCache(scoped_refptr<CrossSequenceCacheStorageCache> cache_wrapper,
-                 const std::string& cache_name,
-                 int64_t trace_id,
-                 OpenCacheAdapterCallback adapter_callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    if (!handle_.value()) {
-      std::move(adapter_callback)
-          .Run(std::move(cache_wrapper),
-               MakeErrorStorage(ErrorStorageType::kStorageHandleNull));
-      return;
-    }
-
-    // Open the cache and set the handle on the wrapper object provided.  The
-    // wrapper will then be sent back to the source sequence to be exposed via
-    // its own handle.
-    handle_.value()->OpenCache(
-        cache_name, trace_id,
-        base::BindOnce(
-            [](scoped_refptr<CrossSequenceCacheStorageCache> cache_wrapper,
-               OpenCacheAdapterCallback adapter_callback,
-               CacheStorageCacheHandle handle,
-               blink::mojom::CacheStorageError error) {
-              // Called on target TaskRunner.
-              if (handle.value())
-                cache_wrapper->SetHandleOnTaskRunner(std::move(handle));
-              // Passing |cache_wrapper| back across the sequence boundary is
-              // safe because we are guaranteed this is the only reference to
-              // the object.
-              std::move(adapter_callback).Run(std::move(cache_wrapper), error);
-            },
-            std::move(cache_wrapper), std::move(adapter_callback)));
-  }
-
-  void HasCache(const std::string& cache_name,
-                int64_t trace_id,
-                BoolAndErrorCallback callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    if (!handle_.value()) {
-      std::move(callback).Run(
-          false, MakeErrorStorage(ErrorStorageType::kStorageHandleNull));
-      return;
-    }
-    handle_.value()->HasCache(cache_name, trace_id, std::move(callback));
-  }
-
-  void DoomCache(const std::string& cache_name,
-                 int64_t trace_id,
-                 ErrorCallback callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    if (!handle_.value()) {
-      std::move(callback).Run(
-          MakeErrorStorage(ErrorStorageType::kStorageHandleNull));
-      return;
-    }
-    handle_.value()->DoomCache(cache_name, trace_id, std::move(callback));
-  }
-
-  void EnumerateCaches(int64_t trace_id, EnumerateCachesCallback callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    if (!handle_.value()) {
-      std::move(callback).Run(std::vector<std::string>());
-      return;
-    }
-    handle_.value()->EnumerateCaches(trace_id, std::move(callback));
-  }
-
-  void MatchCache(const std::string& cache_name,
-                  blink::mojom::FetchAPIRequestPtr request,
-                  blink::mojom::CacheQueryOptionsPtr match_options,
-                  CacheStorageSchedulerPriority priority,
-                  int64_t trace_id,
-                  CacheStorageCache::ResponseCallback callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    if (!handle_.value()) {
-      std::move(callback).Run(
-          MakeErrorStorage(ErrorStorageType::kStorageHandleNull), nullptr);
-      return;
-    }
-    handle_.value()->MatchCache(cache_name, std::move(request),
-                                std::move(match_options), priority, trace_id,
-                                std::move(callback));
-  }
-
-  void MatchAllCaches(blink::mojom::FetchAPIRequestPtr request,
-                      blink::mojom::CacheQueryOptionsPtr match_options,
-                      CacheStorageSchedulerPriority priority,
-                      int64_t trace_id,
-                      CacheStorageCache::ResponseCallback callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    if (!handle_.value()) {
-      std::move(callback).Run(
-          MakeErrorStorage(ErrorStorageType::kStorageHandleNull), nullptr);
-      return;
-    }
-    handle_.value()->MatchAllCaches(std::move(request),
-                                    std::move(match_options), priority,
-                                    trace_id, std::move(callback));
-  }
-
-  void WriteToCache(const std::string& cache_name,
-                    blink::mojom::FetchAPIRequestPtr request,
-                    blink::mojom::FetchAPIResponsePtr response,
-                    int64_t trace_id,
-                    ErrorCallback callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    if (!handle_.value()) {
-      std::move(callback).Run(
-          MakeErrorStorage(ErrorStorageType::kStorageHandleNull));
-      return;
-    }
-    handle_.value()->WriteToCache(cache_name, std::move(request),
-                                  std::move(response), trace_id,
-                                  std::move(callback));
-  }
-
- private:
-  CacheStorageHandle handle_;
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
-CrossSequenceCacheStorage::CrossSequenceCacheStorage(
-    const url::Origin& origin,
-    storage::mojom::CacheStorageOwner owner,
-    scoped_refptr<base::SequencedTaskRunner> target_task_runner,
-    scoped_refptr<CacheStorageContextWithManager> context)
-    : CacheStorage(origin),
-      target_task_runner_(std::move(target_task_runner)),
-      inner_(target_task_runner_,
-             origin,
-             std::move(owner),
-             std::move(context)) {}
-
-CacheStorageHandle CrossSequenceCacheStorage::CreateHandle() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return CacheStorageHandle(weak_factory_.GetWeakPtr());
-}
-
-void CrossSequenceCacheStorage::AddHandleRef() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  handle_ref_count_ += 1;
-  if (handle_ref_count_ == 1)
-    self_ref_ = base::WrapRefCounted(this);
-}
-
-void CrossSequenceCacheStorage::DropHandleRef() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK_GT(handle_ref_count_, 0);
-  handle_ref_count_ -= 1;
-  if (handle_ref_count_ == 0)
-    self_ref_.reset();
-}
-
-void CrossSequenceCacheStorage::Init() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::Init);
-}
-
-void CrossSequenceCacheStorage::OpenCache(const std::string& cache_name,
-                                          int64_t trace_id,
-                                          CacheAndErrorCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  // Create our cross-sequence cache wrapper object first.  This will be sent
-  // down to the target TaskRunner with our open request.  It must already
-  // exist in order for the open request to set the real handle on it on the
-  // target TaskRunner.  If an error occurs the wrapper object is thrown
-  // away.
-  auto cache_wrapper =
-      base::MakeRefCounted<CrossSequenceCacheStorageCache>(target_task_runner_);
-
-  // After the open request sets the real handle on the target TaskRunner our
-  // cache wrapper will be passed back to this sequence.  We then create a
-  // handle to the wrapper and pass that to the external callback.
-  auto adapter_callback = base::BindOnce(
-      [](CacheAndErrorCallback inner_callback,
-         scoped_refptr<CrossSequenceCacheStorageCache> cache_wrapper,
-         blink::mojom::CacheStorageError error) {
-        if (error != blink::mojom::CacheStorageError::kSuccess) {
-          // Don't create a handle to the wrapper if there was an error.
-          // The |cache_wrapper| will be destroyed when it goes out of scope.
-          std::move(inner_callback).Run(CacheStorageCacheHandle(), error);
-          return;
-        }
-        // Called on source TaskRunner (thanks to callback wrapping below).
-        // Note, CreateHandle() will cause the cache to remain strongly
-        // referenced and survive even though |cache_wrapper| goes out of
-        // scope.
-        std::move(inner_callback).Run(cache_wrapper->CreateHandle(), error);
-      },
-      std::move(callback));
-
-  // We use our standard wrapping to ensure that we execute our adapter
-  // callback on the correct current sequence.
-  adapter_callback =
-      WrapCallbackForCurrentSequence(std::move(adapter_callback));
-
-  // Passing |cache_wrapper| across sequence boundaries is safe because
-  // we are guaranteed this is the only reference to the object.
-  inner_.AsyncCall(&Inner::OpenCache)
-      .WithArgs(std::move(cache_wrapper), cache_name, trace_id,
-                std::move(adapter_callback));
-}
-
-void CrossSequenceCacheStorage::HasCache(const std::string& cache_name,
-                                         int64_t trace_id,
-                                         BoolAndErrorCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::HasCache)
-      .WithArgs(cache_name, trace_id,
-                WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-void CrossSequenceCacheStorage::DoomCache(const std::string& cache_name,
-                                          int64_t trace_id,
-                                          ErrorCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::DoomCache)
-      .WithArgs(cache_name, trace_id,
-                WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-void CrossSequenceCacheStorage::EnumerateCaches(
-    int64_t trace_id,
-    EnumerateCachesCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::EnumerateCaches)
-      .WithArgs(trace_id, WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-void CrossSequenceCacheStorage::MatchCache(
-    const std::string& cache_name,
-    blink::mojom::FetchAPIRequestPtr request,
-    blink::mojom::CacheQueryOptionsPtr match_options,
-    CacheStorageSchedulerPriority priority,
-    int64_t trace_id,
-    CacheStorageCache::ResponseCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::MatchCache)
-      .WithArgs(cache_name, std::move(request), std::move(match_options),
-                priority, trace_id,
-                WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-void CrossSequenceCacheStorage::MatchAllCaches(
-    blink::mojom::FetchAPIRequestPtr request,
-    blink::mojom::CacheQueryOptionsPtr match_options,
-    CacheStorageSchedulerPriority priority,
-    int64_t trace_id,
-    CacheStorageCache::ResponseCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::MatchAllCaches)
-      .WithArgs(std::move(request), std::move(match_options), priority,
-                trace_id, WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-void CrossSequenceCacheStorage::WriteToCache(
-    const std::string& cache_name,
-    blink::mojom::FetchAPIRequestPtr request,
-    blink::mojom::FetchAPIResponsePtr response,
-    int64_t trace_id,
-    ErrorCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::WriteToCache)
-      .WithArgs(cache_name, std::move(request), std::move(response), trace_id,
-                WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-CrossSequenceCacheStorage::~CrossSequenceCacheStorage() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-}  // namespace content
diff --git a/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage.h b/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage.h
deleted file mode 100644
index d7ae67bd..0000000
--- a/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_CACHE_STORAGE_CROSS_SEQUENCE_CROSS_SEQUENCE_CACHE_STORAGE_H_
-#define CONTENT_BROWSER_CACHE_STORAGE_CROSS_SEQUENCE_CROSS_SEQUENCE_CACHE_STORAGE_H_
-
-#include "base/memory/weak_ptr.h"
-#include "base/sequence_checker.h"
-#include "base/threading/sequence_bound.h"
-#include "components/services/storage/public/mojom/cache_storage_control.mojom.h"
-#include "content/browser/cache_storage/cache_storage.h"
-#include "content/browser/cache_storage/cache_storage_manager.h"
-
-namespace content {
-
-class CacheStorageContextWithManager;
-
-// A CacheStorage implementation that can be used from one sequence to access
-// a real CacheStorage executing on a different sequence.  The
-// CrossSequenceCacheStorageManager constructs instances of this class in
-// OpenCacheStorage().  Each CrossSequenceCacheStorage is ref-counted and
-// the existence of a CacheStorageHandle will cause the instance to hold a
-// scoped_refptr to itself.  Once all the handles have been dropped the
-// self-reference is also dropped allowing the CrossSequenceCacheStorage to
-// be destroyed.
-class CrossSequenceCacheStorage
-    : public CacheStorage,
-      public base::RefCounted<CrossSequenceCacheStorage> {
- public:
-  CrossSequenceCacheStorage(
-      const url::Origin& origin,
-      storage::mojom::CacheStorageOwner owner,
-      scoped_refptr<base::SequencedTaskRunner> target_task_runner,
-      scoped_refptr<CacheStorageContextWithManager> context);
-
-  // CacheStorage
-  CacheStorageHandle CreateHandle() override;
-  void AddHandleRef() override;
-  void DropHandleRef() override;
-  void Init() override;
-  void OpenCache(const std::string& cache_name,
-                 int64_t trace_id,
-                 CacheAndErrorCallback callback) override;
-  void HasCache(const std::string& cache_name,
-                int64_t trace_id,
-                BoolAndErrorCallback callback) override;
-  void DoomCache(const std::string& cache_name,
-                 int64_t trace_id,
-                 ErrorCallback callback) override;
-  void EnumerateCaches(int64_t trace_id,
-                       EnumerateCachesCallback callback) override;
-  void MatchCache(const std::string& cache_name,
-                  blink::mojom::FetchAPIRequestPtr request,
-                  blink::mojom::CacheQueryOptionsPtr match_options,
-                  CacheStorageSchedulerPriority priority,
-                  int64_t trace_id,
-                  CacheStorageCache::ResponseCallback callback) override;
-  void MatchAllCaches(blink::mojom::FetchAPIRequestPtr request,
-                      blink::mojom::CacheQueryOptionsPtr match_options,
-                      CacheStorageSchedulerPriority priority,
-                      int64_t trace_id,
-                      CacheStorageCache::ResponseCallback callback) override;
-  void WriteToCache(const std::string& cache_name,
-                    blink::mojom::FetchAPIRequestPtr request,
-                    blink::mojom::FetchAPIResponsePtr response,
-                    int64_t trace_id,
-                    ErrorCallback callback) override;
-
- private:
-  friend class base::RefCounted<CrossSequenceCacheStorage>;
-  ~CrossSequenceCacheStorage() override;
-
-  const scoped_refptr<base::SequencedTaskRunner> target_task_runner_;
-
-  // The |inner_| object is SequenceBound<> to the target sequence used by the
-  // real CacheStorage.
-  class Inner;
-  base::SequenceBound<Inner> inner_;
-
-  // |self_ref_| holds a reference to the current |this| as long as
-  // |handle_ref_count_| is greater than zero.  The |handle_ref_count_| is
-  // incremented for every outstanding CacheStorageCacheHandle.
-  scoped_refptr<CrossSequenceCacheStorage> self_ref_;
-  int handle_ref_count_ = 0;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-  base::WeakPtrFactory<CrossSequenceCacheStorage> weak_factory_{this};
-  DISALLOW_COPY_AND_ASSIGN(CrossSequenceCacheStorage);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_CACHE_STORAGE_CROSS_SEQUENCE_CROSS_SEQUENCE_CACHE_STORAGE_H_
diff --git a/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_cache.cc b/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_cache.cc
deleted file mode 100644
index ca1a9780..0000000
--- a/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_cache.cc
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_cache.h"
-
-#include "content/browser/cache_storage/cache_storage_histogram_utils.h"
-#include "content/browser/cache_storage/cross_sequence/cross_sequence_utils.h"
-
-namespace content {
-
-// The Inner class is SequenceBound<> to the real target CacheStorageCache
-// sequence by the outer CrossSequenceCacheStorageCache.  All CacheStorageCache
-// operations are proxied to the Inner on the correct sequence via the
-// AsyncCall() method.  The outer storage is responsible for wrapping any
-// callbacks in order to post on the outer's original sequence.
-// TODO(dcheng): See if this can use the Then() helper.
-class CrossSequenceCacheStorageCache::Inner {
- public:
-  void SetHandle(CacheStorageCacheHandle handle) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    DCHECK(!handle_.value());
-    handle_ = std::move(handle);
-  }
-
-  void Match(blink::mojom::FetchAPIRequestPtr request,
-             blink::mojom::CacheQueryOptionsPtr match_options,
-             CacheStorageSchedulerPriority priority,
-             int64_t trace_id,
-             ResponseCallback callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    if (!handle_.value()) {
-      std::move(callback).Run(
-          MakeErrorStorage(ErrorStorageType::kStorageHandleNull), nullptr);
-      return;
-    }
-    handle_.value()->Match(std::move(request), std::move(match_options),
-                           priority, trace_id, std::move(callback));
-  }
-
-  void MatchAll(blink::mojom::FetchAPIRequestPtr request,
-                blink::mojom::CacheQueryOptionsPtr match_options,
-                int64_t trace_id,
-                ResponsesCallback callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    if (!handle_.value()) {
-      std::move(callback).Run(
-          MakeErrorStorage(ErrorStorageType::kStorageHandleNull),
-          std::vector<blink::mojom::FetchAPIResponsePtr>());
-      return;
-    }
-    handle_.value()->MatchAll(std::move(request), std::move(match_options),
-                              trace_id, std::move(callback));
-  }
-
-  void WriteSideData(ErrorCallback callback,
-                     const GURL& url,
-                     base::Time expected_response_time,
-                     int64_t trace_id,
-                     scoped_refptr<net::IOBuffer> buffer,
-                     int buf_len) {
-    if (!handle_.value()) {
-      std::move(callback).Run(
-          MakeErrorStorage(ErrorStorageType::kStorageHandleNull));
-      return;
-    }
-    handle_.value()->WriteSideData(std::move(callback), url,
-                                   expected_response_time, trace_id,
-                                   std::move(buffer), buf_len);
-  }
-
-  void BatchOperation(std::vector<blink::mojom::BatchOperationPtr> operations,
-                      int64_t trace_id,
-                      VerboseErrorCallback callback,
-                      BadMessageCallback bad_message_callback) {
-    if (!handle_.value()) {
-      std::move(callback).Run(blink::mojom::CacheStorageVerboseError::New(
-          MakeErrorStorage(ErrorStorageType::kStorageHandleNull), nullptr));
-      return;
-    }
-    handle_.value()->BatchOperation(std::move(operations), trace_id,
-                                    std::move(callback),
-                                    std::move(bad_message_callback));
-  }
-
-  void Keys(blink::mojom::FetchAPIRequestPtr request,
-            blink::mojom::CacheQueryOptionsPtr options,
-            int64_t trace_id,
-            RequestsCallback callback) {
-    if (!handle_.value()) {
-      std::move(callback).Run(
-          MakeErrorStorage(ErrorStorageType::kStorageHandleNull), nullptr);
-      return;
-    }
-    handle_.value()->Keys(std::move(request), std::move(options), trace_id,
-                          std::move(callback));
-  }
-
-  void Put(blink::mojom::FetchAPIRequestPtr request,
-           blink::mojom::FetchAPIResponsePtr response,
-           int64_t trace_id,
-           ErrorCallback callback) {
-    if (!handle_.value()) {
-      std::move(callback).Run(
-          MakeErrorStorage(ErrorStorageType::kStorageHandleNull));
-      return;
-    }
-    handle_.value()->Put(std::move(request), std::move(response), trace_id,
-                         std::move(callback));
-  }
-
-  void GetAllMatchedEntries(blink::mojom::FetchAPIRequestPtr request,
-                            blink::mojom::CacheQueryOptionsPtr match_options,
-                            int64_t trace_id,
-                            CacheEntriesCallback callback) {
-    if (!handle_.value()) {
-      std::move(callback).Run(
-          MakeErrorStorage(ErrorStorageType::kStorageHandleNull),
-          std::vector<blink::mojom::CacheEntryPtr>());
-      return;
-    }
-    handle_.value()->GetAllMatchedEntries(std::move(request),
-                                          std::move(match_options), trace_id,
-                                          std::move(callback));
-  }
-
- private:
-  CacheStorageCacheHandle handle_;
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
-CrossSequenceCacheStorageCache::CrossSequenceCacheStorageCache(
-    scoped_refptr<base::SequencedTaskRunner> target_task_runner)
-    : inner_(std::move(target_task_runner)) {}
-
-void CrossSequenceCacheStorageCache::SetHandleOnTaskRunner(
-    CacheStorageCacheHandle handle) {
-  // Called on target sequence.
-  DCHECK(handle.value());
-  // Even though we are already on the correct sequence we still have to
-  // AsyncCall() to the inner object.
-  inner_.AsyncCall(&Inner::SetHandle).WithArgs(std::move(handle));
-}
-
-CacheStorageCacheHandle CrossSequenceCacheStorageCache::CreateHandle() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return CacheStorageCacheHandle(weak_factory_.GetWeakPtr());
-}
-
-void CrossSequenceCacheStorageCache::AddHandleRef() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  handle_ref_count_ += 1;
-  if (handle_ref_count_ == 1)
-    self_ref_ = base::WrapRefCounted(this);
-}
-
-void CrossSequenceCacheStorageCache::DropHandleRef() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK_GT(handle_ref_count_, 0);
-  handle_ref_count_ -= 1;
-  if (handle_ref_count_ == 0)
-    self_ref_.reset();
-}
-
-bool CrossSequenceCacheStorageCache::IsUnreferenced() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return handle_ref_count_ == 0;
-}
-
-void CrossSequenceCacheStorageCache::Match(
-    blink::mojom::FetchAPIRequestPtr request,
-    blink::mojom::CacheQueryOptionsPtr match_options,
-    CacheStorageSchedulerPriority priority,
-    int64_t trace_id,
-    ResponseCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::Match)
-      .WithArgs(std::move(request), std::move(match_options), priority,
-                trace_id, WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-void CrossSequenceCacheStorageCache::MatchAll(
-    blink::mojom::FetchAPIRequestPtr request,
-    blink::mojom::CacheQueryOptionsPtr match_options,
-    int64_t trace_id,
-    ResponsesCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::MatchAll)
-      .WithArgs(std::move(request), std::move(match_options), trace_id,
-                WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-void CrossSequenceCacheStorageCache::WriteSideData(
-    ErrorCallback callback,
-    const GURL& url,
-    base::Time expected_response_time,
-    int64_t trace_id,
-    scoped_refptr<net::IOBuffer> buffer,
-    int buf_len) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::WriteSideData)
-      .WithArgs(WrapCallbackForCurrentSequence(std::move(callback)), url,
-                expected_response_time, trace_id, std::move(buffer), buf_len);
-}
-
-void CrossSequenceCacheStorageCache::BatchOperation(
-    std::vector<blink::mojom::BatchOperationPtr> operations,
-    int64_t trace_id,
-    VerboseErrorCallback callback,
-    BadMessageCallback bad_message_callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::BatchOperation)
-      .WithArgs(
-          std::move(operations), trace_id,
-          WrapCallbackForCurrentSequence(std::move(callback)),
-          WrapCallbackForCurrentSequence(std::move(bad_message_callback)));
-}
-
-void CrossSequenceCacheStorageCache::Keys(
-    blink::mojom::FetchAPIRequestPtr request,
-    blink::mojom::CacheQueryOptionsPtr options,
-    int64_t trace_id,
-    RequestsCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::Keys)
-      .WithArgs(std::move(request), std::move(options), trace_id,
-                WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-void CrossSequenceCacheStorageCache::Put(
-    blink::mojom::FetchAPIRequestPtr request,
-    blink::mojom::FetchAPIResponsePtr response,
-    int64_t trace_id,
-    ErrorCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::Put)
-      .WithArgs(std::move(request), std::move(response), trace_id,
-                WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-void CrossSequenceCacheStorageCache::GetAllMatchedEntries(
-    blink::mojom::FetchAPIRequestPtr request,
-    blink::mojom::CacheQueryOptionsPtr match_options,
-    int64_t trace_id,
-    CacheEntriesCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::GetAllMatchedEntries)
-      .WithArgs(std::move(request), std::move(match_options), trace_id,
-                WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-CacheStorageCache::InitState CrossSequenceCacheStorageCache::GetInitState()
-    const {
-  // We don't really know when the real cache on the other sequence becomes
-  // initialized.
-  return InitState::Unknown;
-}
-
-CrossSequenceCacheStorageCache::~CrossSequenceCacheStorageCache() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-}  // namespace content
diff --git a/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_cache.h b/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_cache.h
deleted file mode 100644
index 09d1f2e..0000000
--- a/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_cache.h
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_CACHE_STORAGE_CROSS_SEQUENCE_CROSS_SEQUENCE_CACHE_STORAGE_CACHE_H_
-#define CONTENT_BROWSER_CACHE_STORAGE_CROSS_SEQUENCE_CROSS_SEQUENCE_CACHE_STORAGE_CACHE_H_
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequence_checker.h"
-#include "base/threading/sequence_bound.h"
-#include "content/browser/cache_storage/cache_storage_cache.h"
-
-namespace content {
-
-// A CacheStorageCache implementation that can be used from one sequence to
-// access a real CacheStorageCache executing on a different sequence.
-// CrossSequenceCacheStorage objects construct instances of this class in
-// OpenCache().  Each CrossSequenceCacheStorageCache is ref-counted and
-// the existence of a CacheStorageCacheHandle will cause the instance to hold a
-// scoped_refptr to itself.  Once all the handles have been dropped the
-// self-reference is also dropped allowing the CrossSequenceCacheStorage to
-// be destroyed.
-class CrossSequenceCacheStorageCache
-    : public CacheStorageCache,
-      public base::RefCounted<CrossSequenceCacheStorageCache> {
- public:
-  // Created on the outer source sequence without any reference to a real
-  // cache yet.  SetHandleOnTaskRunner() must be called before any cache
-  // methods are invoked.
-  explicit CrossSequenceCacheStorageCache(
-      scoped_refptr<base::SequencedTaskRunner> target_task_runner);
-
-  // Called on the inner cache's sequence to set the real cache's handle.
-  void SetHandleOnTaskRunner(CacheStorageCacheHandle handle);
-
-  // CacheStorageCache
-  CacheStorageCacheHandle CreateHandle() override;
-  void AddHandleRef() override;
-  void DropHandleRef() override;
-  bool IsUnreferenced() const override;
-  void Match(blink::mojom::FetchAPIRequestPtr request,
-             blink::mojom::CacheQueryOptionsPtr match_options,
-             CacheStorageSchedulerPriority priority,
-             int64_t trace_id,
-             ResponseCallback callback) override;
-
-  void MatchAll(blink::mojom::FetchAPIRequestPtr request,
-                blink::mojom::CacheQueryOptionsPtr match_options,
-                int64_t trace_id,
-                ResponsesCallback callback) override;
-
-  void WriteSideData(ErrorCallback callback,
-                     const GURL& url,
-                     base::Time expected_response_time,
-                     int64_t trace_id,
-                     scoped_refptr<net::IOBuffer> buffer,
-                     int buf_len) override;
-
-  void BatchOperation(std::vector<blink::mojom::BatchOperationPtr> operations,
-                      int64_t trace_id,
-                      VerboseErrorCallback callback,
-                      BadMessageCallback bad_message_callback) override;
-
-  void Keys(blink::mojom::FetchAPIRequestPtr request,
-            blink::mojom::CacheQueryOptionsPtr options,
-            int64_t trace_id,
-            RequestsCallback callback) override;
-
-  void Put(blink::mojom::FetchAPIRequestPtr request,
-           blink::mojom::FetchAPIResponsePtr response,
-           int64_t trace_id,
-           ErrorCallback callback) override;
-
-  void GetAllMatchedEntries(blink::mojom::FetchAPIRequestPtr request,
-                            blink::mojom::CacheQueryOptionsPtr match_options,
-                            int64_t trace_id,
-                            CacheEntriesCallback callback) override;
-
-  InitState GetInitState() const override;
-
- private:
-  friend class base::RefCounted<CrossSequenceCacheStorageCache>;
-  ~CrossSequenceCacheStorageCache() override;
-
-  // The |inner_| object is SequenceBound<> to the target sequence used by the
-  // real CacheStorageCache.
-  class Inner;
-  base::SequenceBound<Inner> inner_;
-
-  // |self_ref_| holds a reference to the current |this| as long as
-  // |handle_ref_count_| is greater than zero.  The |handle_ref_count_| is
-  // incremented for every outstanding CacheStorageCacheHandle.
-  scoped_refptr<CrossSequenceCacheStorageCache> self_ref_;
-  int handle_ref_count_ = 0;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-  base::WeakPtrFactory<CrossSequenceCacheStorageCache> weak_factory_{this};
-  DISALLOW_COPY_AND_ASSIGN(CrossSequenceCacheStorageCache);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_CACHE_STORAGE_CROSS_SEQUENCE_CROSS_SEQUENCE_CACHE_STORAGE_CACHE_H_
diff --git a/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_manager.cc b/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_manager.cc
deleted file mode 100644
index f1144248..0000000
--- a/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_manager.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_manager.h"
-
-#include "base/callback_helpers.h"
-#include "content/browser/cache_storage/cache_storage.h"
-#include "content/browser/cache_storage/cache_storage_context_impl.h"
-#include "content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage.h"
-#include "content/browser/cache_storage/cross_sequence/cross_sequence_utils.h"
-#include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
-
-namespace content {
-
-// The Inner class is SequenceBound<> to the real target manager sequence by
-// the outer CrossSequenceCacheStorageManager.  All CacheStorageManager
-// operations are proxied to the Inner on the correct sequence via the
-// AsyncCall() method.  The outer manager is responsible for wrapping any
-// callbacks in order to post on the outer's original sequence.
-// TODO(dcheng): See if this can use the Then() helper.
-class CrossSequenceCacheStorageManager::Inner {
- public:
-  explicit Inner(scoped_refptr<CacheStorageContextWithManager> context)
-      : target_manager_(context->CacheManager()) {
-    DCHECK(target_manager_);
-  }
-
-  void GetAllOriginsUsage(
-      storage::mojom::CacheStorageOwner owner,
-      storage::mojom::CacheStorageControl::GetAllOriginsInfoCallback callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    target_manager_->GetAllOriginsUsage(owner, std::move(callback));
-  }
-
-  void GetOriginUsage(
-      const url::Origin& origin_url,
-      storage::mojom::CacheStorageOwner owner,
-      storage::mojom::QuotaClient::GetOriginUsageCallback callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    target_manager_->GetOriginUsage(origin_url, owner, std::move(callback));
-  }
-
-  void GetOrigins(
-      storage::mojom::CacheStorageOwner owner,
-      storage::mojom::QuotaClient::GetOriginsForTypeCallback callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    target_manager_->GetOrigins(owner, std::move(callback));
-  }
-
-  void GetOriginsForHost(
-      const std::string& host,
-      storage::mojom::CacheStorageOwner owner,
-      storage::mojom::QuotaClient::GetOriginsForHostCallback callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    target_manager_->GetOriginsForHost(host, owner, std::move(callback));
-  }
-
-  void DeleteOriginData(
-      const url::Origin& origin,
-      storage::mojom::CacheStorageOwner owner,
-      storage::mojom::QuotaClient::DeleteOriginDataCallback callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    target_manager_->DeleteOriginData(origin, owner, std::move(callback));
-  }
-
-  void AddObserver(
-      mojo::PendingRemote<storage::mojom::CacheStorageObserver> observer) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    target_manager_->AddObserver(std::move(observer));
-  }
-
- private:
-  const scoped_refptr<CacheStorageManager> target_manager_;
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
-CrossSequenceCacheStorageManager::CrossSequenceCacheStorageManager(
-    scoped_refptr<base::SequencedTaskRunner> target_task_runner,
-    scoped_refptr<CacheStorageContextWithManager> context)
-    : target_task_runner_(std::move(target_task_runner)),
-      context_(context),
-      inner_(target_task_runner_, std::move(context)) {}
-
-CacheStorageHandle CrossSequenceCacheStorageManager::OpenCacheStorage(
-    const url::Origin& origin,
-    storage::mojom::CacheStorageOwner owner) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // Construct the CrossSequenceCacheStorage object immediately on our current
-  // sequence.  This is necessary in order to return a Handle synchronously.
-  // The CrossSequenceCacheStorage object will asynchronously open the real
-  // CacheStorage on the correct sequence.
-  auto storage = base::MakeRefCounted<CrossSequenceCacheStorage>(
-      origin, owner, target_task_runner_, context_);
-  return storage->CreateHandle();
-}
-
-void CrossSequenceCacheStorageManager::GetAllOriginsUsage(
-    storage::mojom::CacheStorageOwner owner,
-    storage::mojom::CacheStorageControl::GetAllOriginsInfoCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::GetAllOriginsUsage)
-      .WithArgs(owner, WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-void CrossSequenceCacheStorageManager::GetOriginUsage(
-    const url::Origin& origin_url,
-    storage::mojom::CacheStorageOwner owner,
-    storage::mojom::QuotaClient::GetOriginUsageCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::GetOriginUsage)
-      .WithArgs(origin_url, owner,
-                WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-void CrossSequenceCacheStorageManager::GetOrigins(
-    storage::mojom::CacheStorageOwner owner,
-    storage::mojom::QuotaClient::GetOriginsForTypeCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::GetOrigins)
-      .WithArgs(owner, WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-void CrossSequenceCacheStorageManager::GetOriginsForHost(
-    const std::string& host,
-    storage::mojom::CacheStorageOwner owner,
-    storage::mojom::QuotaClient::GetOriginsForHostCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::GetOriginsForHost)
-      .WithArgs(host, owner,
-                WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-void CrossSequenceCacheStorageManager::DeleteOriginData(
-    const url::Origin& origin,
-    storage::mojom::CacheStorageOwner owner,
-    storage::mojom::QuotaClient::DeleteOriginDataCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::DeleteOriginData)
-      .WithArgs(origin, owner,
-                WrapCallbackForCurrentSequence(std::move(callback)));
-}
-
-void CrossSequenceCacheStorageManager::DeleteOriginData(
-    const url::Origin& origin,
-    storage::mojom::CacheStorageOwner owner) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DeleteOriginData(origin, owner, base::DoNothing());
-}
-
-void CrossSequenceCacheStorageManager::AddObserver(
-    mojo::PendingRemote<storage::mojom::CacheStorageObserver> observer) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  inner_.AsyncCall(&Inner::AddObserver).WithArgs(std::move(observer));
-}
-
-CrossSequenceCacheStorageManager::~CrossSequenceCacheStorageManager() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-}  // namespace content
diff --git a/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_manager.h b/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_manager.h
deleted file mode 100644
index c69aaa9..0000000
--- a/content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_manager.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_CACHE_STORAGE_CROSS_SEQUENCE_CROSS_SEQUENCE_CACHE_STORAGE_MANAGER_H_
-#define CONTENT_BROWSER_CACHE_STORAGE_CROSS_SEQUENCE_CROSS_SEQUENCE_CACHE_STORAGE_MANAGER_H_
-
-#include "base/sequence_checker.h"
-#include "base/threading/sequence_bound.h"
-#include "components/services/storage/public/mojom/cache_storage_control.mojom.h"
-#include "content/browser/cache_storage/cache_storage_manager.h"
-
-namespace content {
-
-class CacheStorageContextWithManager;
-
-// A CacheStorageManager implementation that can be used from one sequence to
-// access the real CacheStorageManager executing on a different sequence.  The
-// CacheStorageContextImpl will create one of these whenever code calls the
-// CacheManager() accessor on the wrong sequence.  The cross-sequence wrapper
-// manager is ref-counted and will only live as long as that client code keeps
-// its reference alive.  Each cross-sequence wrapper is locked to the sequence
-// on which it was created.
-class CONTENT_EXPORT CrossSequenceCacheStorageManager
-    : public CacheStorageManager {
- public:
-  CrossSequenceCacheStorageManager(
-      scoped_refptr<base::SequencedTaskRunner> target_task_runner,
-      scoped_refptr<CacheStorageContextWithManager> context);
-
-  // CacheStorageManager
-  CacheStorageHandle OpenCacheStorage(
-      const url::Origin& origin,
-      storage::mojom::CacheStorageOwner owner) override;
-  void GetAllOriginsUsage(
-      storage::mojom::CacheStorageOwner owner,
-      storage::mojom::CacheStorageControl::GetAllOriginsInfoCallback callback)
-      override;
-  void GetOriginUsage(
-      const url::Origin& origin_url,
-      storage::mojom::CacheStorageOwner owner,
-      storage::mojom::QuotaClient::GetOriginUsageCallback callback) override;
-  void GetOrigins(
-      storage::mojom::CacheStorageOwner owner,
-      storage::mojom::QuotaClient::GetOriginsForTypeCallback callback) override;
-  void GetOriginsForHost(
-      const std::string& host,
-      storage::mojom::CacheStorageOwner owner,
-      storage::mojom::QuotaClient::GetOriginsForHostCallback callback) override;
-  void DeleteOriginData(
-      const url::Origin& origin,
-      storage::mojom::CacheStorageOwner owner,
-      storage::mojom::QuotaClient::DeleteOriginDataCallback callback) override;
-  void DeleteOriginData(const url::Origin& origin,
-                        storage::mojom::CacheStorageOwner owner) override;
-  void AddObserver(mojo::PendingRemote<storage::mojom::CacheStorageObserver>
-                       observer) override;
-
- private:
-  ~CrossSequenceCacheStorageManager() override;
-
-  const scoped_refptr<base::SequencedTaskRunner> target_task_runner_;
-  scoped_refptr<CacheStorageContextWithManager> context_;
-
-  // The |inner_| object is SequenceBound<> to the target sequence used by the
-  // real manager.
-  class Inner;
-  base::SequenceBound<Inner> inner_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-  DISALLOW_COPY_AND_ASSIGN(CrossSequenceCacheStorageManager);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_CACHE_STORAGE_CROSS_SEQUENCE_CROSS_SEQUENCE_CACHE_STORAGE_MANAGER_H_
diff --git a/content/browser/cache_storage/cross_sequence/cross_sequence_utils.h b/content/browser/cache_storage/cross_sequence/cross_sequence_utils.h
deleted file mode 100644
index 5efc734..0000000
--- a/content/browser/cache_storage/cross_sequence/cross_sequence_utils.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_CACHE_STORAGE_CROSS_SEQUENCE_CROSS_SEQUENCE_UTILS_H_
-#define CONTENT_BROWSER_CACHE_STORAGE_CROSS_SEQUENCE_CROSS_SEQUENCE_UTILS_H_
-
-namespace content {
-
-// Helper function for WrapCallbackForCurrentSequence().
-template <typename... Args>
-void RunWrappedCallbackOnTargetSequence(
-    base::OnceCallback<void(Args...)> callback,
-    Args... args) {
-  std::move(callback).Run(std::forward<Args>(args)...);
-}
-
-// Helper function for WrapCallbackForCurrentSequence().
-template <typename... Args>
-void RunWrappedCallbackOnOtherSequence(
-    scoped_refptr<base::SequencedTaskRunner> task_runner,
-    base::OnceCallback<void(Args...)> callback,
-    Args... args) {
-  task_runner->PostTask(
-      FROM_HERE,
-      base::BindOnce(&RunWrappedCallbackOnTargetSequence<Args...>,
-                     std::move(callback), std::forward<Args>(args)...));
-}
-
-// This function wraps a given OnceCallback<> such that it will perform a
-// PostTask() to the current sequence when the callback is invoked.
-template <typename... Args>
-base::OnceCallback<void(Args...)> WrapCallbackForCurrentSequence(
-    base::OnceCallback<void(Args...)> callback) {
-  return base::BindOnce(&RunWrappedCallbackOnOtherSequence<Args...>,
-                        base::SequencedTaskRunnerHandle::Get(),
-                        std::move(callback));
-}
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_CACHE_STORAGE_CROSS_SEQUENCE_CROSS_SEQUENCE_UTILS_H_
diff --git a/content/browser/loader/navigation_url_loader.cc b/content/browser/loader/navigation_url_loader.cc
index 78d7fd7..8758d80 100644
--- a/content/browser/loader/navigation_url_loader.cc
+++ b/content/browser/loader/navigation_url_loader.cc
@@ -32,6 +32,8 @@
     NavigationURLLoaderDelegate* delegate,
     LoaderType loader_type,
     mojo::PendingRemote<network::mojom::CookieAccessObserver> cookie_observer,
+    mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+        auth_cert_observer,
     std::vector<std::unique_ptr<NavigationLoaderInterceptor>>
         initial_interceptors) {
   if (g_loader_factory) {
@@ -48,7 +50,8 @@
       browser_context, storage_partition, std::move(request_info),
       std::move(navigation_ui_data), service_worker_handle, appcache_handle,
       std::move(prefetched_signed_exchange_cache), delegate,
-      std::move(cookie_observer), std::move(initial_interceptors));
+      std::move(cookie_observer), std::move(auth_cert_observer),
+      std::move(initial_interceptors));
 }
 
 void NavigationURLLoader::SetFactoryForTesting(
diff --git a/content/browser/loader/navigation_url_loader.h b/content/browser/loader/navigation_url_loader.h
index 2fe6519..f67e980 100644
--- a/content/browser/loader/navigation_url_loader.h
+++ b/content/browser/loader/navigation_url_loader.h
@@ -68,6 +68,8 @@
       NavigationURLLoaderDelegate* delegate,
       LoaderType loader_type,
       mojo::PendingRemote<network::mojom::CookieAccessObserver> cookie_observer,
+      mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+          auth_cert_observer,
       std::vector<std::unique_ptr<NavigationLoaderInterceptor>>
           initial_interceptors = {});
 
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index d0387bab..6ff889f 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -192,7 +192,9 @@
 std::unique_ptr<network::ResourceRequest> CreateResourceRequest(
     NavigationRequestInfo* request_info,
     int frame_tree_node_id,
-    mojo::PendingRemote<network::mojom::CookieAccessObserver> cookie_observer) {
+    mojo::PendingRemote<network::mojom::CookieAccessObserver> cookie_observer,
+    mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+        auth_cert_observer) {
   auto new_request = std::make_unique<network::ResourceRequest>();
 
   new_request->method = request_info->common_params->method;
@@ -202,6 +204,8 @@
   new_request->trusted_params = network::ResourceRequest::TrustedParams();
   new_request->trusted_params->isolation_info = request_info->isolation_info;
   new_request->trusted_params->cookie_observer = std::move(cookie_observer);
+  new_request->trusted_params->auth_cert_observer =
+      std::move(auth_cert_observer);
   new_request->trusted_params->client_security_state =
       request_info->client_security_state.Clone();
   new_request->is_main_frame = request_info->is_main_frame;
@@ -1083,6 +1087,8 @@
         prefetched_signed_exchange_cache,
     NavigationURLLoaderDelegate* delegate,
     mojo::PendingRemote<network::mojom::CookieAccessObserver> cookie_observer,
+    mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+        auth_cert_observer,
     std::vector<std::unique_ptr<NavigationLoaderInterceptor>>
         initial_interceptors)
     : delegate_(delegate),
@@ -1112,7 +1118,8 @@
               ->signed_exchange_prefetch_metric_recorder();
 
   resource_request_ = CreateResourceRequest(
-      request_info_.get(), frame_tree_node_id_, std::move(cookie_observer));
+      request_info_.get(), frame_tree_node_id_, std::move(cookie_observer),
+      std::move(auth_cert_observer));
 
   std::string accept_langs =
       GetContentClient()->browser()->GetAcceptLangs(browser_context_);
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h
index 3346596..c555562 100644
--- a/content/browser/loader/navigation_url_loader_impl.h
+++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -56,6 +56,8 @@
           prefetched_signed_exchange_cache,
       NavigationURLLoaderDelegate* delegate,
       mojo::PendingRemote<network::mojom::CookieAccessObserver> cookie_observer,
+      mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+          auth_cert_observer,
       std::vector<std::unique_ptr<NavigationLoaderInterceptor>>
           initial_interceptors);
   ~NavigationURLLoaderImpl() override;
diff --git a/content/browser/loader/navigation_url_loader_impl_unittest.cc b/content/browser/loader/navigation_url_loader_impl_unittest.cc
index 4519cc2..85cce04 100644
--- a/content/browser/loader/navigation_url_loader_impl_unittest.cc
+++ b/content/browser/loader/navigation_url_loader_impl_unittest.cc
@@ -104,7 +104,8 @@
         nullptr /* keepalive_statistics_recorder */,
         nullptr /* network_usage_accumulator */, nullptr /* header_client */,
         nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-        kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+        kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
   }
 
   bool MaybeCreateLoaderForResponse(
@@ -223,7 +224,7 @@
         nullptr /* service_worker_handle */, nullptr /* appcache_handle */,
         nullptr /* prefetched_signed_exchange_cache */, delegate,
         mojo::NullRemote() /* cookie_access_obsever */,
-        std::move(interceptors));
+        mojo::NullRemote() /* auth_cert_observer */, std::move(interceptors));
   }
 
   // Requests |redirect_url|, which must return a HTTP 3xx redirect. It's also
diff --git a/content/browser/loader/navigation_url_loader_unittest.cc b/content/browser/loader/navigation_url_loader_unittest.cc
index f7b18dc..10ff6d5 100644
--- a/content/browser/loader/navigation_url_loader_unittest.cc
+++ b/content/browser/loader/navigation_url_loader_unittest.cc
@@ -76,6 +76,9 @@
     common_params->url = url;
     common_params->initiator_origin = url::Origin::Create(url);
 
+    StoragePartition* storage_partition =
+        BrowserContext::GetDefaultStoragePartition(browser_context_.get());
+
     url::Origin origin = url::Origin::Create(url);
     std::unique_ptr<NavigationRequestInfo> request_info(
         new NavigationRequestInfo(
@@ -93,10 +96,11 @@
             false /* obey_origin_policy */, {} /* cors_exempt_headers */,
             nullptr /* client_security_state */));
     return NavigationURLLoader::Create(
-        browser_context_.get(),
-        BrowserContext::GetDefaultStoragePartition(browser_context_.get()),
-        std::move(request_info), nullptr, nullptr, nullptr, nullptr, delegate,
-        NavigationURLLoader::LoaderType::kRegular, mojo::NullRemote());
+        browser_context_.get(), storage_partition, std::move(request_info),
+        nullptr, nullptr, nullptr, nullptr, delegate,
+        NavigationURLLoader::LoaderType::kRegular, mojo::NullRemote(),
+        storage_partition->CreateAuthAndCertObserverForNavigationRequest(
+            -1 /* frame_tree_node_id */));
   }
 
  protected:
diff --git a/content/browser/media/media_web_contents_observer.cc b/content/browser/media/media_web_contents_observer.cc
index 9969ec56..06bd7ab 100644
--- a/content/browser/media/media_web_contents_observer.cc
+++ b/content/browser/media/media_web_contents_observer.cc
@@ -46,8 +46,7 @@
 
 static void OnAudioOutputDeviceIdTranslated(
     base::WeakPtr<MediaWebContentsObserver> observer,
-    RenderFrameHost* render_frame_host,
-    int delegate_id,
+    const MediaPlayerId& player_id,
     const base::Optional<std::string>& raw_device_id) {
   if (!raw_device_id)
     return;
@@ -55,8 +54,7 @@
   content::GetUIThreadTaskRunner({})->PostTask(
       FROM_HERE,
       base::BindOnce(&MediaWebContentsObserver::OnReceivedTranslatedDeviceId,
-                     std::move(observer), render_frame_host, delegate_id,
-                     raw_device_id.value()));
+                     std::move(observer), player_id, raw_device_id.value()));
 }
 
 }  // anonymous namespace
@@ -253,22 +251,6 @@
   return fullscreen_player_;
 }
 
-bool MediaWebContentsObserver::OnMessageReceived(
-    const IPC::Message& msg,
-    RenderFrameHost* render_frame_host) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(MediaWebContentsObserver, msg,
-                                   render_frame_host)
-    IPC_MESSAGE_HANDLER(
-        MediaPlayerDelegateHostMsg_OnMediaEffectivelyFullscreenChanged,
-        OnMediaEffectivelyFullscreenChanged)
-    IPC_MESSAGE_HANDLER(MediaPlayerDelegateHostMsg_OnAudioOutputSinkChanged,
-                        OnAudioOutputSinkChanged);
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
-}
-
 void MediaWebContentsObserver::MediaPictureInPictureChanged(
     bool is_picture_in_picture) {
   session_controllers_manager_->PictureInPictureStateChanged(
@@ -366,6 +348,13 @@
       ->OnMediaPositionStateChanged(media_player_id_, media_position);
 }
 
+void MediaWebContentsObserver::MediaPlayerObserverHostImpl::
+    OnMediaEffectivelyFullscreenChanged(
+        blink::WebFullscreenVideoStatus status) {
+  media_web_contents_observer_->OnMediaEffectivelyFullscreenChanged(
+      media_player_id_, status);
+}
+
 void MediaWebContentsObserver::MediaPlayerObserverHostImpl::OnMediaSizeChanged(
     const ::gfx::Size& size) {
   media_web_contents_observer_->web_contents_impl()->MediaResized(
@@ -379,6 +368,12 @@
 }
 
 void MediaWebContentsObserver::MediaPlayerObserverHostImpl::
+    OnAudioOutputSinkChanged(const std::string& hashed_device_id) {
+  media_web_contents_observer_->session_controllers_manager()
+      ->OnAudioOutputSinkChanged(media_player_id_, hashed_device_id);
+}
+
+void MediaWebContentsObserver::MediaPlayerObserverHostImpl::
     OnAudioOutputSinkChangingDisabled() {
   media_web_contents_observer_->session_controllers_manager()
       ->OnAudioOutputSinkChangingDisabled(media_player_id_);
@@ -453,23 +448,20 @@
 }
 
 void MediaWebContentsObserver::OnMediaEffectivelyFullscreenChanged(
-    RenderFrameHost* render_frame_host,
-    int delegate_id,
+    const MediaPlayerId& player_id,
     blink::WebFullscreenVideoStatus fullscreen_status) {
-  const MediaPlayerId id(render_frame_host, delegate_id);
-
   switch (fullscreen_status) {
     case blink::WebFullscreenVideoStatus::kFullscreenAndPictureInPictureEnabled:
-      fullscreen_player_ = id;
+      fullscreen_player_ = player_id;
       picture_in_picture_allowed_in_fullscreen_ = true;
       break;
     case blink::WebFullscreenVideoStatus::
         kFullscreenAndPictureInPictureDisabled:
-      fullscreen_player_ = id;
+      fullscreen_player_ = player_id;
       picture_in_picture_allowed_in_fullscreen_ = false;
       break;
     case blink::WebFullscreenVideoStatus::kNotEffectivelyFullscreen:
-      if (!fullscreen_player_ || *fullscreen_player_ != id)
+      if (!fullscreen_player_ || *fullscreen_player_ != player_id)
         return;
 
       picture_in_picture_allowed_in_fullscreen_.reset();
@@ -484,12 +476,11 @@
 }
 
 void MediaWebContentsObserver::OnAudioOutputSinkChanged(
-    RenderFrameHost* render_frame_host,
-    int delegate_id,
+    const MediaPlayerId& player_id,
     std::string hashed_device_id) {
   auto salt_and_origin = content::GetMediaDeviceSaltAndOrigin(
-      render_frame_host->GetProcess()->GetID(),
-      render_frame_host->GetRoutingID());
+      player_id.render_frame_host->GetProcess()->GetID(),
+      player_id.render_frame_host->GetRoutingID());
 
   auto callback_on_io_thread = base::BindOnce(
       [](const std::string& salt, const url::Origin& origin,
@@ -504,19 +495,17 @@
       salt_and_origin.device_id_salt, std::move(salt_and_origin.origin),
       hashed_device_id,
       base::BindOnce(&OnAudioOutputDeviceIdTranslated,
-                     weak_ptr_factory_.GetWeakPtr(), render_frame_host,
-                     delegate_id));
+                     weak_ptr_factory_.GetWeakPtr(), player_id));
 
   content::GetIOThreadTaskRunner({})->PostTask(
       FROM_HERE, std::move(callback_on_io_thread));
 }
 
 void MediaWebContentsObserver::OnReceivedTranslatedDeviceId(
-    RenderFrameHost* render_frame_host,
-    int delegate_id,
+    const MediaPlayerId& player_id,
     const std::string& raw_device_id) {
-  session_controllers_manager_->OnAudioOutputSinkChanged(
-      MediaPlayerId(render_frame_host, delegate_id), raw_device_id);
+  session_controllers_manager_->OnAudioOutputSinkChanged(player_id,
+                                                         raw_device_id);
 }
 
 media::mojom::MediaPlayer* MediaWebContentsObserver::GetMediaPlayerRemote(
diff --git a/content/browser/media/media_web_contents_observer.h b/content/browser/media/media_web_contents_observer.h
index 22f1f1d..60994dfc 100644
--- a/content/browser/media/media_web_contents_observer.h
+++ b/content/browser/media/media_web_contents_observer.h
@@ -85,8 +85,6 @@
   // WebContentsObserver implementation.
   void WebContentsDestroyed() override;
   void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
-  bool OnMessageReceived(const IPC::Message& message,
-                         RenderFrameHost* render_frame_host) override;
   void MediaPictureInPictureChanged(bool is_picture_in_picture) override;
   void DidUpdateAudioMutingState(bool muted) override;
 
@@ -107,8 +105,7 @@
     audible_metrics_ = audible_metrics;
   }
 
-  void OnReceivedTranslatedDeviceId(RenderFrameHost* render_frame_host,
-                                    int delegate_id,
+  void OnReceivedTranslatedDeviceId(const MediaPlayerId& player_id,
                                     const std::string& raw_device_id);
 
   // Return an already bound mojo Remote for the MediaPlayer mojo interface.
@@ -199,8 +196,11 @@
         media::MediaContentType media_content_type) override;
     void OnMediaPositionStateChanged(
         const media_session::MediaPosition& media_position) override;
+    void OnMediaEffectivelyFullscreenChanged(
+        blink::WebFullscreenVideoStatus status) override;
     void OnMediaSizeChanged(const ::gfx::Size& size) override;
     void OnPictureInPictureAvailabilityChanged(bool available) override;
+    void OnAudioOutputSinkChanged(const std::string& hashed_device_id) override;
     void OnAudioOutputSinkChangingDisabled() override;
     void OnBufferUnderflow() override;
     void OnSeek() override;
@@ -230,11 +230,9 @@
                               media::MediaContentType media_content_type);
 
   void OnMediaEffectivelyFullscreenChanged(
-      RenderFrameHost* render_frame_host,
-      int delegate_id,
+      const MediaPlayerId& player_id,
       blink::WebFullscreenVideoStatus fullscreen_status);
-  void OnAudioOutputSinkChanged(RenderFrameHost* render_frame_host,
-                                int delegate_id,
+  void OnAudioOutputSinkChanged(const MediaPlayerId& player_id,
                                 std::string hashed_device_id);
 
   // Used to notify when the renderer -> browser mojo connection via the
diff --git a/content/browser/network_context_client_base_impl.cc b/content/browser/network_context_client_base_impl.cc
index 2a2ff0f..2c11dc2 100644
--- a/content/browser/network_context_client_base_impl.cc
+++ b/content/browser/network_context_client_base_impl.cc
@@ -111,17 +111,6 @@
   cert_responder->CancelRequest();
 }
 
-void NetworkContextClientBase::OnSSLCertificateError(
-    int32_t process_id,
-    int32_t routing_id,
-    const GURL& url,
-    int net_error,
-    const net::SSLInfo& ssl_info,
-    bool fatal,
-    OnSSLCertificateErrorCallback response) {
-  std::move(response).Run(net::ERR_ABORTED);
-}
-
 void NetworkContextClientBase::OnFileUploadRequested(
     int32_t process_id,
     bool async,
diff --git a/content/browser/prerender/prerender_browsertest.cc b/content/browser/prerender/prerender_browsertest.cc
index 5151ecb..cf66e76 100644
--- a/content/browser/prerender/prerender_browsertest.cc
+++ b/content/browser/prerender/prerender_browsertest.cc
@@ -333,6 +333,8 @@
 
   // The prerender host should be registered for the initial request URL, not
   // the redirected URL.
+  // TODO(https://crbug.com/1132746): Disallow cross-origin redirection on
+  // prerendering navigation for the initial milestone.
   PrerenderHostRegistry& registry = GetPrerenderHostRegistry();
   EXPECT_TRUE(registry.FindHostByUrlForTesting(kPrerenderingUrl));
   EXPECT_FALSE(registry.FindHostByUrlForTesting(kRedirectedUrl));
diff --git a/content/browser/prerender/prerender_processor.cc b/content/browser/prerender/prerender_processor.cc
index a541644e..7f9a213 100644
--- a/content/browser/prerender/prerender_processor.cc
+++ b/content/browser/prerender/prerender_processor.cc
@@ -48,6 +48,14 @@
       return;
   }
 
+  // Abort cross-origin prerendering.
+  // TODO(https://crbug.com/1176054): This is a tentative behavior. We plan to
+  // support it cross-origin prerendering later.
+  // TODO(https://crbug.com/1176120): Fallback to NoStatePrefetch to avoid
+  // performance degradation.
+  if (!initiator_origin_.IsSameOriginWith(url::Origin::Create(attributes->url)))
+    return;
+
   // TODO(https://crbug.com/1132746): Validate the origin, etc and send
   // mojo::ReportBadMessage() if necessary like the legacy prerender
   // `prerender::PrerenderProcessorImpl::Start()`.
diff --git a/content/browser/prerender/prerender_processor_unittest.cc b/content/browser/prerender/prerender_processor_unittest.cc
index cf01c9582..7ecaad52 100644
--- a/content/browser/prerender/prerender_processor_unittest.cc
+++ b/content/browser/prerender/prerender_processor_unittest.cc
@@ -50,6 +50,14 @@
     return web_contents_->GetMainFrame();
   }
 
+  GURL GetSameOriginUrl(const std::string& path) {
+    return GURL("https://example.com" + path);
+  }
+
+  GURL GetCrossOriginUrl(const std::string& path) {
+    return GURL("https://other.example.com" + path);
+  }
+
   PrerenderHostRegistry* GetPrerenderHostRegistry() const {
     return static_cast<StoragePartitionImpl*>(
                BrowserContext::GetDefaultStoragePartition(
@@ -72,7 +80,7 @@
   render_frame_host->BindPrerenderProcessor(
       render_frame_host, remote.BindNewPipeAndPassReceiver());
 
-  const GURL kPrerenderingUrl("https://example.com/next");
+  const GURL kPrerenderingUrl = GetSameOriginUrl("/next");
   auto attributes = blink::mojom::PrerenderAttributes::New();
   attributes->url = kPrerenderingUrl;
   attributes->referrer = blink::mojom::Referrer::New();
@@ -97,7 +105,7 @@
   render_frame_host->BindPrerenderProcessor(
       render_frame_host, remote.BindNewPipeAndPassReceiver());
 
-  const GURL kPrerenderingUrl("https://example.com/next");
+  const GURL kPrerenderingUrl = GetSameOriginUrl("/next");
   auto attributes = blink::mojom::PrerenderAttributes::New();
   attributes->url = kPrerenderingUrl;
   attributes->referrer = blink::mojom::Referrer::New();
@@ -123,7 +131,7 @@
   render_frame_host->BindPrerenderProcessor(
       render_frame_host, remote.BindNewPipeAndPassReceiver());
 
-  const GURL kPrerenderingUrl("https://example.com/next");
+  const GURL kPrerenderingUrl = GetSameOriginUrl("/next");
   auto attributes = blink::mojom::PrerenderAttributes::New();
   attributes->url = kPrerenderingUrl;
   attributes->referrer = blink::mojom::Referrer::New();
@@ -155,7 +163,7 @@
         bad_message_error = error;
       }));
 
-  const GURL kPrerenderingUrl("https://example.com/next");
+  const GURL kPrerenderingUrl = GetSameOriginUrl("/next");
   auto attributes1 = blink::mojom::PrerenderAttributes::New();
   attributes1->url = kPrerenderingUrl;
   attributes1->referrer = blink::mojom::Referrer::New();
@@ -192,7 +200,7 @@
         bad_message_error = error;
       }));
 
-  const GURL kPrerenderingUrl("https://example.com/next");
+  const GURL kPrerenderingUrl = GetSameOriginUrl("/next");
   auto attributes1 = blink::mojom::PrerenderAttributes::New();
   attributes1->url = kPrerenderingUrl;
   attributes1->referrer = blink::mojom::Referrer::New();
@@ -205,6 +213,48 @@
   EXPECT_EQ(bad_message_error, "PP_CANCEL_BEFORE_START");
 }
 
+// Tests that prerendering a cross-origin URL is aborted. Cross-origin
+// prerendering is not supported for now, but we plan to support it later
+// (https://crbug.com/1176054).
+TEST_F(PrerenderProcessorTest, CrossOrigin) {
+  RenderFrameHostImpl* render_frame_host = GetRenderFrameHost();
+  PrerenderHostRegistry* registry = GetPrerenderHostRegistry();
+
+  mojo::Remote<blink::mojom::PrerenderProcessor> remote;
+  render_frame_host->BindPrerenderProcessor(
+      render_frame_host, remote.BindNewPipeAndPassReceiver());
+
+  // Set up the error handler for bad mojo messages.
+  std::string bad_message_error;
+  mojo::SetDefaultProcessErrorHandler(
+      base::BindLambdaForTesting([&](const std::string& error) {
+        EXPECT_FALSE(error.empty());
+        EXPECT_TRUE(bad_message_error.empty());
+        bad_message_error = error;
+      }));
+
+  const GURL kPrerenderingUrl = GetCrossOriginUrl("/next");
+  auto attributes = blink::mojom::PrerenderAttributes::New();
+  attributes->url = kPrerenderingUrl;
+  attributes->referrer = blink::mojom::Referrer::New();
+
+  // Start() call with the cross-origin URL should be aborted.
+  EXPECT_FALSE(registry->FindHostByUrlForTesting(kPrerenderingUrl));
+  remote->Start(std::move(attributes));
+  remote.FlushForTesting();
+  EXPECT_FALSE(registry->FindHostByUrlForTesting(kPrerenderingUrl));
+
+  // Start() call with the cross-origin URL is a valid request, currently it's
+  // not supported though. The request shouldn't result in a bad message
+  // failure.
+  EXPECT_TRUE(bad_message_error.empty());
+
+  // Cancel() call should not be reported as a bad mojo message as well.
+  remote->Cancel();
+  remote.FlushForTesting();
+  EXPECT_TRUE(bad_message_error.empty());
+}
+
 // Tests that prerendering triggered by <link rel=next> is aborted. This trigger
 // is not supported for now, but we may want to support it if NoStatePrefetch
 // re-enables it again. See https://crbug.com/1161545.
@@ -225,7 +275,7 @@
         bad_message_error = error;
       }));
 
-  const GURL kPrerenderingUrl("https://example.com/next");
+  const GURL kPrerenderingUrl = GetSameOriginUrl("/next");
   auto attributes = blink::mojom::PrerenderAttributes::New();
   attributes->url = kPrerenderingUrl;
   // Set kNext instead of the default kPrerender.
diff --git a/content/browser/renderer_host/keep_alive_handle_factory.cc b/content/browser/renderer_host/keep_alive_handle_factory.cc
index d5d50aa..90f1e61 100644
--- a/content/browser/renderer_host/keep_alive_handle_factory.cc
+++ b/content/browser/renderer_host/keep_alive_handle_factory.cc
@@ -20,8 +20,9 @@
 
 namespace content {
 
-class KeepAliveHandleFactory::KeepAliveHandleImpl final
-    : public blink::mojom::KeepAliveHandle {
+namespace {
+
+class KeepAliveHandleImpl final : public blink::mojom::KeepAliveHandle {
  public:
   explicit KeepAliveHandleImpl(int process_id) : process_id_(process_id) {
     GetContentClient()->browser()->OnKeepaliveRequestStarted();
@@ -48,16 +49,15 @@
   const int process_id_;
 };
 
-class KeepAliveHandleFactory::Context final
-    : public base::RefCounted<Context>,
-      public blink::mojom::KeepAliveHandleFactory {
+}  // namespace
+
+class KeepAliveHandleFactory::Context
+    : public blink::mojom::KeepAliveHandleFactory {
  public:
   explicit Context(int process_id) : process_id_(process_id) {}
-
-  void Clear() {
-    handle_receivers_.Clear();
-    factory_receivers_.Clear();
-  }
+  Context(const Context&) = delete;
+  Context& operator=(const Context&) = delete;
+  ~Context() override = default;
 
   void IssueKeepAliveHandle(
       mojo::PendingReceiver<blink::mojom::KeepAliveHandle> receiver) override {
@@ -70,29 +70,25 @@
     factory_receivers_.Add(this, std::move(receiver));
   }
 
-  void ClearLater(base::TimeDelta timeout) {
-    GetUIThreadTaskRunner({})->PostDelayedTask(
-        FROM_HERE, base::BindOnce(&Context::Clear, this), timeout);
-  }
-
  private:
-  friend class base::RefCounted<Context>;
-  ~Context() override = default;
-
   mojo::UniqueReceiverSet<blink::mojom::KeepAliveHandle> handle_receivers_;
   mojo::ReceiverSet<blink::mojom::KeepAliveHandleFactory> factory_receivers_;
   const int process_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(Context);
 };
 
 KeepAliveHandleFactory::KeepAliveHandleFactory(RenderProcessHost* process_host,
                                                base::TimeDelta timeout)
-    : context_(base::MakeRefCounted<Context>(process_host->GetID())),
+    : context_(std::make_unique<Context>(process_host->GetID())),
       timeout_(timeout) {}
 
 KeepAliveHandleFactory::~KeepAliveHandleFactory() {
-  context_->ClearLater(timeout_);
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  // Extend the lifetime of `context_` a bit. Note that `context_` has an
+  // ability to extend the lifetime of the associated render process.
+  GetUIThreadTaskRunner({})->PostDelayedTask(
+      FROM_HERE,
+      base::BindOnce([](std::unique_ptr<Context>) {}, std::move(context_)),
+      timeout_);
 }
 
 void KeepAliveHandleFactory::Bind(
diff --git a/content/browser/renderer_host/keep_alive_handle_factory.h b/content/browser/renderer_host/keep_alive_handle_factory.h
index 634b611..84e9ea4 100644
--- a/content/browser/renderer_host/keep_alive_handle_factory.h
+++ b/content/browser/renderer_host/keep_alive_handle_factory.h
@@ -5,7 +5,8 @@
 #ifndef CONTENT_BROWSER_RENDERER_HOST_KEEP_ALIVE_HANDLE_FACTORY_H_
 #define CONTENT_BROWSER_RENDERER_HOST_KEEP_ALIVE_HANDLE_FACTORY_H_
 
-#include "base/memory/ref_counted.h"
+#include <memory>
+
 #include "base/time/time.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "third_party/blink/public/mojom/frame/frame.mojom-forward.h"
@@ -28,8 +29,6 @@
   KeepAliveHandleFactory(const KeepAliveHandleFactory&) = delete;
   KeepAliveHandleFactory& operator=(const KeepAliveHandleFactory&) = delete;
 
-  void Create(mojo::PendingReceiver<blink::mojom::KeepAliveHandle> receiver);
-
   // Sets the timeout after which all created handles will be invalidated.
   void set_timeout(base::TimeDelta timeout) { timeout_ = timeout; }
 
@@ -37,10 +36,9 @@
       mojo::PendingReceiver<blink::mojom::KeepAliveHandleFactory> receiver);
 
  private:
-  class KeepAliveHandleImpl;
   class Context;
 
-  scoped_refptr<Context> context_;
+  std::unique_ptr<Context> context_;
   base::TimeDelta timeout_;
 };
 
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index afee877b..72e77e3 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -3047,7 +3047,11 @@
           std::move(cors_exempt_headers), std::move(client_security_state)),
       std::move(navigation_ui_data), service_worker_handle_.get(),
       appcache_handle_.get(), std::move(prefetched_signed_exchange_cache_),
-      this, loader_type, CreateCookieAccessObserver(), std::move(interceptor));
+      this, loader_type, CreateCookieAccessObserver(),
+      static_cast<StoragePartitionImpl*>(partition)
+          ->CreateAuthAndCertObserverForNavigationRequest(
+              frame_tree_node_->frame_tree_node_id()),
+      std::move(interceptor));
 
   DCHECK(!render_frame_host_);
 }
@@ -3298,6 +3302,13 @@
   ComputeSandboxFlagsToCommit(/*response_head=*/nullptr,
                               /*required_csp=*/nullptr);
 
+  // Error pages should not inherit any policies. Initialize a new, default
+  // PolicyContainerHost.
+  //
+  // TODO(https://crbug.com/1175787): We should enforce strict policies on error
+  // pages.
+  policy_container_host_ = base::MakeRefCounted<PolicyContainerHost>();
+
   ReadyToCommitNavigation(true);
   // Use a separate cache shard, and no cookies, for error pages.
   isolation_info_for_subresources_ = net::IsolationInfo::CreateTransient();
diff --git a/content/browser/renderer_host/policy_container_host_browsertest.cc b/content/browser/renderer_host/policy_container_host_browsertest.cc
index 896d101..885cc343 100644
--- a/content/browser/renderer_host/policy_container_host_browsertest.cc
+++ b/content/browser/renderer_host/policy_container_host_browsertest.cc
@@ -810,4 +810,32 @@
             current_frame_host()->policy_container_host()->referrer_policy());
 }
 
+// Test that chrome error pages are loaded with a default policy container and
+// don't inherit policies.
+IN_PROC_BROWSER_TEST_F(PolicyContainerHostBrowserTest, FailedNavigation) {
+  // Perform a navigation setting referrer policy.
+  GURL url = embedded_test_server()->GetURL(
+      "/set-header?Referrer-Policy: no-referrer");
+  EXPECT_TRUE(NavigateToURL(shell(), url));
+  EXPECT_EQ(network::mojom::ReferrerPolicy::kNever,
+            current_frame_host()->policy_container_host()->referrer_policy());
+
+  // Now open a popup with an unreachable url.
+  GURL error_url = embedded_test_server()->GetURL("/close-socket");
+  ShellAddedObserver shell_observer;
+  EXPECT_TRUE(
+      ExecJs(current_frame_host(), JsReplace("window.open($1)", error_url)));
+  WebContentsImpl* popup_webcontents =
+      static_cast<WebContentsImpl*>(shell_observer.GetShell()->web_contents());
+  WaitForLoadStop(popup_webcontents);
+
+  NavigationEntry* entry =
+      popup_webcontents->GetController().GetLastCommittedEntry();
+  EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType());
+  RenderFrameHostImpl* popup_frame =
+      popup_webcontents->GetFrameTree()->root()->current_frame_host();
+  EXPECT_EQ(network::mojom::ReferrerPolicy::kDefault,
+            popup_frame->policy_container_host()->referrer_policy());
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 2ff20ea..ec3aba1 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -5138,6 +5138,9 @@
     mojo::PendingAssociatedReceiver<mojom::DomAutomationControllerHost>
         receiver) {
   DCHECK(receiver.is_valid());
+  // DOM automation controller is reinstalled after a cross-document navigation,
+  // which can reuse the frame.
+  dom_automation_controller_receiver_.reset();
   dom_automation_controller_receiver_.Bind(std::move(receiver));
   dom_automation_controller_receiver_.SetFilter(
       CreateMessageFilterForAssociatedReceiver(
@@ -6889,10 +6892,16 @@
   mojom::NavigationClient* navigation_client =
       navigation_request->GetCommitNavigationClient();
 
+  DCHECK(navigation_request->policy_container_host());
+  blink::mojom::PolicyContainerPtr policy_container =
+      navigation_request->policy_container_host()
+          ->CreatePolicyContainerForBlink();
+
   SendCommitFailedNavigation(
       navigation_client, navigation_request, common_params.Clone(),
       commit_params.Clone(), has_stale_copy_in_cache, error_code,
-      error_page_content, std::move(subresource_loader_factories));
+      error_page_content, std::move(subresource_loader_factories),
+      std::move(policy_container));
 
   // TODO(crbug/1129537): support UKM source creation for failed navigations
   // too.
@@ -7056,6 +7065,7 @@
   frame_.reset();
   frame_bindings_control_.reset();
   frame_host_associated_receiver_.reset();
+  back_forward_cache_controller_host_associated_receiver_.reset();
   local_frame_.reset();
   local_main_frame_.reset();
   high_priority_local_frame_.reset();
@@ -9287,14 +9297,15 @@
     int32_t error_code,
     const base::Optional<std::string>& error_page_content,
     std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
-        subresource_loader_factories) {
+        subresource_loader_factories,
+    blink::mojom::PolicyContainerPtr policy_container) {
   DCHECK(navigation_client && navigation_request);
   DCHECK_NE(GURL(), common_params->url);
   navigation_client->CommitFailedNavigation(
       std::move(common_params), std::move(commit_params),
       has_stale_copy_in_cache, error_code,
       navigation_request->GetResolveErrorInfo(), error_page_content,
-      std::move(subresource_loader_factories),
+      std::move(subresource_loader_factories), std::move(policy_container),
       BuildCommitFailedNavigationCallback(navigation_request));
 }
 
@@ -10415,6 +10426,13 @@
   GetAssociatedLocalFrame()->BindReportingObserver(std::move(receiver));
 }
 
+mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+RenderFrameHostImpl::CreateAuthAndCertObserver() {
+  return static_cast<StoragePartitionImpl*>(GetStoragePartition())
+      ->CreateAuthAndCertObserverForFrame(GetProcess()->GetID(),
+                                          GetRoutingID());
+}
+
 mojo::PendingRemote<network::mojom::CookieAccessObserver>
 RenderFrameHostImpl::CreateCookieAccessObserver() {
   mojo::PendingRemote<network::mojom::CookieAccessObserver> remote;
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h
index 8c25e9c..f23f999 100644
--- a/content/browser/renderer_host/render_frame_host_impl.h
+++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -92,6 +92,7 @@
 #include "services/network/public/cpp/content_security_policy/csp_context.h"
 #include "services/network/public/cpp/cross_origin_embedder_policy.h"
 #include "services/network/public/cpp/cross_origin_opener_policy.h"
+#include "services/network/public/mojom/auth_and_certificate_observer.mojom-forward.h"
 #include "services/network/public/mojom/fetch_api.mojom-forward.h"
 #include "services/network/public/mojom/network_context.mojom.h"
 #include "services/network/public/mojom/trust_tokens.mojom.h"
@@ -1867,6 +1868,9 @@
       RenderFrameHostImpl* old_frame_host,
       const UrlInfo& dest_url_info);
 
+  mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+  CreateAuthAndCertObserver();
+
   mojo::PendingRemote<network::mojom::CookieAccessObserver>
   CreateCookieAccessObserver();
 
@@ -1978,7 +1982,8 @@
       int32_t error_code,
       const base::Optional<std::string>& error_page_content,
       std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
-          subresource_loader_factories);
+          subresource_loader_factories,
+      blink::mojom::PolicyContainerPtr policy_container);
 
   // The Build*Callback functions below are responsible for building the
   // callbacks for either successful or failed commits.
@@ -3030,6 +3035,7 @@
   bool has_committed_any_navigation_ = false;
   bool must_be_replaced_ = false;
 
+  // Receivers must be reset in InvalidateMojoConnection().
   mojo::AssociatedReceiver<mojom::FrameHost> frame_host_associated_receiver_{
       this};
   mojo::AssociatedReceiver<blink::mojom::BackForwardCacheControllerHost>
@@ -3038,9 +3044,7 @@
   mojo::AssociatedRemote<mojom::FrameBindingsControl> frame_bindings_control_;
   mojo::AssociatedReceiver<blink::mojom::LocalFrameHost>
       local_frame_host_receiver_{this};
-
-  // This receiver should only be valid when the frame is a swapped in main
-  // frame.
+  // Should only be bound when the frame is a swapped in main frame.
   mojo::AssociatedReceiver<blink::mojom::LocalMainFrameHost>
       local_main_frame_host_receiver_{this};
 
diff --git a/content/browser/renderer_host/render_frame_proxy_host.cc b/content/browser/renderer_host/render_frame_proxy_host.cc
index 583896b..d3bf2e7 100644
--- a/content/browser/renderer_host/render_frame_proxy_host.cc
+++ b/content/browser/renderer_host/render_frame_proxy_host.cc
@@ -330,15 +330,22 @@
 void RenderFrameProxyHost::OnAssociatedInterfaceRequest(
     const std::string& interface_name,
     mojo::ScopedInterfaceEndpointHandle handle) {
+  // A RenderFrameProxyHost is reused after a crash, so allow reuse of the
+  // receivers by resetting them before binding.
+  // TODO(dcheng): Maybe there should be an equivalent to RenderFrameHostImpl's
+  // InvalidateMojoConnection()?
   if (interface_name == mojom::RenderFrameProxyHost::Name_) {
+    frame_proxy_host_associated_receiver_.reset();
     frame_proxy_host_associated_receiver_.Bind(
         mojo::PendingAssociatedReceiver<mojom::RenderFrameProxyHost>(
             std::move(handle)));
   } else if (interface_name == blink::mojom::RemoteFrameHost::Name_) {
+    remote_frame_host_receiver_.reset();
     remote_frame_host_receiver_.Bind(
         mojo::PendingAssociatedReceiver<blink::mojom::RemoteFrameHost>(
             std::move(handle)));
   } else if (interface_name == blink::mojom::RemoteMainFrameHost::Name_) {
+    remote_main_frame_host_receiver_.reset();
     remote_main_frame_host_receiver_.Bind(
         mojo::PendingAssociatedReceiver<blink::mojom::RemoteMainFrameHost>(
             std::move(handle)));
diff --git a/content/browser/service_worker/service_worker_test_utils.cc b/content/browser/service_worker/service_worker_test_utils.cc
index 1a270333..369bf852 100644
--- a/content/browser/service_worker/service_worker_test_utils.cc
+++ b/content/browser/service_worker/service_worker_test_utils.cc
@@ -151,6 +151,7 @@
       const net::ResolveErrorInfo& resolve_error_info,
       const base::Optional<std::string>& error_page_content,
       std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loaders,
+      blink::mojom::PolicyContainerPtr policy_container,
       CommitFailedNavigationCallback callback) override {
     std::move(callback).Run(MinimalDidCommitNavigationLoadParams(), nullptr);
   }
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index 4809719..887ec06 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -667,8 +667,8 @@
 class SSLErrorDelegate : public SSLErrorHandler::Delegate {
  public:
   explicit SSLErrorDelegate(
-      network::mojom::NetworkContextClient::OnSSLCertificateErrorCallback
-          response)
+      network::mojom::AuthenticationAndCertificateObserver::
+          OnSSLCertificateErrorCallback response)
       : response_(std::move(response)) {}
   ~SSLErrorDelegate() override = default;
   void CancelSSLRequest(int error, const net::SSLInfo* ssl_info) override {
@@ -684,7 +684,8 @@
   }
 
  private:
-  network::mojom::NetworkContextClient::OnSSLCertificateErrorCallback response_;
+  network::mojom::AuthenticationAndCertificateObserver::
+      OnSSLCertificateErrorCallback response_;
   base::WeakPtrFactory<SSLErrorDelegate> weak_factory_{this};
 };
 
@@ -1493,6 +1494,7 @@
 storage::mojom::CacheStorageControl*
 StoragePartitionImpl::GetCacheStorageControl() {
   DCHECK(initialized_);
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   return cache_storage_control_.get();
 }
 
@@ -1756,13 +1758,14 @@
 }
 
 void StoragePartitionImpl::OnSSLCertificateError(
-    int32_t process_id,
-    int32_t routing_id,
     const GURL& url,
     int net_error,
     const net::SSLInfo& ssl_info,
     bool fatal,
     OnSSLCertificateErrorCallback response) {
+  int process_id = auth_cert_observers_.current_context().process_id;
+  int routing_id = auth_cert_observers_.current_context().routing_id;
+
   SSLErrorDelegate* delegate =
       new SSLErrorDelegate(std::move(response));  // deletes self
   bool is_main_frame_request = IsMainFrameRequest(process_id, routing_id);
@@ -1771,6 +1774,33 @@
       GetWebContents(process_id, routing_id), net_error, ssl_info, fatal);
 }
 
+void StoragePartitionImpl::Clone(
+    mojo::PendingReceiver<network::mojom::AuthenticationAndCertificateObserver>
+        observer) {
+  auth_cert_observers_.Add(this, std::move(observer),
+                           auth_cert_observers_.current_context());
+}
+
+mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+StoragePartitionImpl::CreateAuthAndCertObserverForFrame(int process_id,
+                                                        int routing_id) {
+  mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+      remote;
+  auth_cert_observers_.Add(this, remote.InitWithNewPipeAndPassReceiver(),
+                           {process_id, routing_id});
+  return remote;
+}
+
+mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+StoragePartitionImpl::CreateAuthAndCertObserverForNavigationRequest(
+    int frame_tree_id) {
+  mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+      remote;
+  auth_cert_observers_.Add(this, remote.InitWithNewPipeAndPassReceiver(),
+                           {network::mojom::kBrowserProcessId, frame_tree_id});
+  return remote;
+}
+
 void StoragePartitionImpl::OnFileUploadRequested(
     int32_t process_id,
     bool async,
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index 23f1c62..4b53cda 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -92,7 +92,8 @@
 class CONTENT_EXPORT StoragePartitionImpl
     : public StoragePartition,
       public blink::mojom::DomStorage,
-      public network::mojom::NetworkContextClient {
+      public network::mojom::NetworkContextClient,
+      public network::mojom::AuthenticationAndCertificateObserver {
  public:
   // It is guaranteed that storage partitions are destructed before the
   // browser context starts shutting down its corresponding IO thread residents
@@ -142,6 +143,10 @@
   void CreateHasTrustTokensAnswerer(
       mojo::PendingReceiver<network::mojom::HasTrustTokensAnswerer> receiver,
       const url::Origin& top_frame_origin) override;
+  mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+  CreateAuthAndCertObserverForFrame(int process_id, int routing_id) override;
+  mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+  CreateAuthAndCertObserverForNavigationRequest(int frame_tree_id) override;
   storage::QuotaManager* GetQuotaManager() override;
   ChromeAppCacheService* GetAppCacheService() override;
   BackgroundSyncContextImpl* GetBackgroundSyncContext() override;
@@ -256,13 +261,6 @@
       const scoped_refptr<net::SSLCertRequestInfo>& cert_info,
       mojo::PendingRemote<network::mojom::ClientCertificateResponder>
           cert_responder) override;
-  void OnSSLCertificateError(int32_t process_id,
-                             int32_t routing_id,
-                             const GURL& url,
-                             int net_error,
-                             const net::SSLInfo& ssl_info,
-                             bool fatal,
-                             OnSSLCertificateErrorCallback response) override;
   void OnFileUploadRequested(int32_t process_id,
                              bool async,
                              const std::vector<base::FilePath>& file_paths,
@@ -294,6 +292,16 @@
       network::mojom::FulfillTrustTokenIssuanceRequestPtr request,
       OnTrustTokenIssuanceDivertedToSystemCallback callback) override;
 
+  // network::mojom::AuthenticationAndCertificateObserver interface.
+  void OnSSLCertificateError(const GURL& url,
+                             int net_error,
+                             const net::SSLInfo& ssl_info,
+                             bool fatal,
+                             OnSSLCertificateErrorCallback response) override;
+  void Clone(mojo::PendingReceiver<
+             network::mojom::AuthenticationAndCertificateObserver> listener)
+      override;
+
   scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter() {
     return url_loader_factory_getter_;
   }
@@ -618,6 +626,14 @@
   mojo::UniqueReceiverSet<network::mojom::CookieAccessObserver>
       service_worker_cookie_observers_;
 
+  struct AuthAndCertContext {
+    int process_id;
+    int routing_id;
+  };
+  mojo::ReceiverSet<network::mojom::AuthenticationAndCertificateObserver,
+                    AuthAndCertContext>
+      auth_cert_observers_;
+
   // |local_trust_token_fulfiller_| provides responses to certain Trust Tokens
   // operations, for instance via the content embedder calling into a system
   // service ("platform-provided Trust Tokens operations").
diff --git a/content/browser/url_loader_factory_params_helper.cc b/content/browser/url_loader_factory_params_helper.cc
index 3b5c7595..4e0ef74 100644
--- a/content/browser/url_loader_factory_params_helper.cc
+++ b/content/browser/url_loader_factory_params_helper.cc
@@ -46,6 +46,8 @@
     bool allow_universal_access_from_file_urls,
     bool is_for_isolated_world,
     mojo::PendingRemote<network::mojom::CookieAccessObserver> cookie_observer,
+    mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+        auth_cert_observer,
     network::mojom::TrustTokenRedemptionPolicy trust_token_redemption_policy,
     base::StringPiece debug_tag) {
   DCHECK(process);
@@ -91,6 +93,7 @@
       params.get());
 
   params->cookie_observer = std::move(cookie_observer);
+  params->auth_cert_observer = std::move(auth_cert_observer);
 
   params->debug_tag = debug_tag.as_string();
 
@@ -111,19 +114,19 @@
     RenderProcessHost* process,
     network::mojom::TrustTokenRedemptionPolicy trust_token_redemption_policy,
     base::StringPiece debug_tag) {
-  return CreateParams(process,
-                      frame_origin,  // origin
-                      frame_origin,  // request_initiator_origin_lock
-                      false,         // is_trusted
-                      frame->GetTopFrameToken(), isolation_info,
-                      std::move(client_security_state),
-                      std::move(coep_reporter),
-                      WebContents::FromRenderFrameHost(frame)
-                          ->GetOrCreateWebPreferences()
-                          .allow_universal_access_from_file_urls,
-                      false,  // is_for_isolated_world
-                      frame->CreateCookieAccessObserver(),
-                      trust_token_redemption_policy, debug_tag);
+  return CreateParams(
+      process,
+      frame_origin,  // origin
+      frame_origin,  // request_initiator_origin_lock
+      false,         // is_trusted
+      frame->GetTopFrameToken(), isolation_info,
+      std::move(client_security_state), std::move(coep_reporter),
+      WebContents::FromRenderFrameHost(frame)
+          ->GetOrCreateWebPreferences()
+          .allow_universal_access_from_file_urls,
+      false,  // is_for_isolated_world
+      frame->CreateCookieAccessObserver(), frame->CreateAuthAndCertObserver(),
+      trust_token_redemption_policy, debug_tag);
 }
 
 // static
@@ -135,20 +138,20 @@
     const net::IsolationInfo& isolation_info,
     network::mojom::ClientSecurityStatePtr client_security_state,
     network::mojom::TrustTokenRedemptionPolicy trust_token_redemption_policy) {
-  return CreateParams(frame->GetProcess(),
-                      isolated_world_origin,  // origin
-                      main_world_origin,      // request_initiator_origin_lock
-                      false,                  // is_trusted
-                      frame->GetTopFrameToken(), isolation_info,
-                      std::move(client_security_state),
-                      mojo::NullRemote(),  // coep_reporter
-                      WebContents::FromRenderFrameHost(frame)
-                          ->GetOrCreateWebPreferences()
-                          .allow_universal_access_from_file_urls,
-                      true,  // is_for_isolated_world
-                      frame->CreateCookieAccessObserver(),
-                      trust_token_redemption_policy,
-                      "ParamHelper::CreateForIsolatedWorld");
+  return CreateParams(
+      frame->GetProcess(),
+      isolated_world_origin,  // origin
+      main_world_origin,      // request_initiator_origin_lock
+      false,                  // is_trusted
+      frame->GetTopFrameToken(), isolation_info,
+      std::move(client_security_state),
+      mojo::NullRemote(),  // coep_reporter
+      WebContents::FromRenderFrameHost(frame)
+          ->GetOrCreateWebPreferences()
+          .allow_universal_access_from_file_urls,
+      true,  // is_for_isolated_world
+      frame->CreateCookieAccessObserver(), frame->CreateAuthAndCertObserver(),
+      trust_token_redemption_policy, "ParamHelper::CreateForIsolatedWorld");
 }
 
 network::mojom::URLLoaderFactoryParamsPtr
@@ -172,6 +175,7 @@
                           .allow_universal_access_from_file_urls,
                       false,  // is_for_isolated_world
                       frame->CreateCookieAccessObserver(),
+                      frame->CreateAuthAndCertObserver(),
                       network::mojom::TrustTokenRedemptionPolicy::kForbid,
                       "ParamHelper::CreateForPrefetch");
 }
@@ -198,6 +202,7 @@
       false,  // is_for_isolated_world
       static_cast<StoragePartitionImpl*>(process->GetStoragePartition())
           ->CreateCookieAccessObserverForServiceWorker(),
+      mojo::NullRemote(),
       // Since ExecutionContext::IsFeatureEnabled returns
       // false in non-Document contexts, no worker should ever
       // execute a trust token redemption or signing operation,
@@ -234,7 +239,8 @@
       mojo::NullRemote(),  // coep_reporter
       false,               // allow_universal_access_from_file_urls
       false,               // is_for_isolated_world
-      mojo::NullRemote(), network::mojom::TrustTokenRedemptionPolicy::kForbid,
+      mojo::NullRemote(), mojo::NullRemote(),
+      network::mojom::TrustTokenRedemptionPolicy::kForbid,
       "ParamHelper::CreateForRendererProcess");
 }
 
diff --git a/content/browser/websockets/websocket_connector_impl.cc b/content/browser/websockets/websocket_connector_impl.cc
index 214315b..453c7ef 100644
--- a/content/browser/websockets/websocket_connector_impl.cc
+++ b/content/browser/websockets/websocket_connector_impl.cc
@@ -85,9 +85,12 @@
   }
   process->GetStoragePartition()->GetNetworkContext()->CreateWebSocket(
       url, requested_protocols, site_for_cookies, isolation_info_,
-      std::move(headers), process_id_, frame_id_, origin_, options,
+      std::move(headers), process_id_, origin_, options,
       net::MutableNetworkTrafficAnnotationTag(kTrafficAnnotation),
-      std::move(handshake_client), mojo::NullRemote(), mojo::NullRemote());
+      std::move(handshake_client),
+      process->GetStoragePartition()->CreateAuthAndCertObserverForFrame(
+          process_id_, frame_id_),
+      mojo::NullRemote(), mojo::NullRemote());
 }
 
 void WebSocketConnectorImpl::ConnectCalledByContentBrowserClient(
@@ -102,7 +105,8 @@
     std::vector<network::mojom::HttpHeaderPtr> additional_headers,
     mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
         handshake_client,
-    mojo::PendingRemote<network::mojom::AuthenticationHandler> auth_handler,
+    mojo::PendingRemote<network::mojom::WebSocketAuthenticationHandler>
+        auth_handler,
     mojo::PendingRemote<network::mojom::TrustedHeaderClient>
         trusted_header_client) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -112,10 +116,12 @@
   }
   process->GetStoragePartition()->GetNetworkContext()->CreateWebSocket(
       url, requested_protocols, site_for_cookies, isolation_info,
-      std::move(additional_headers), process_id, frame_id, origin, options,
+      std::move(additional_headers), process_id, origin, options,
       net::MutableNetworkTrafficAnnotationTag(kTrafficAnnotation),
-      std::move(handshake_client), std::move(auth_handler),
-      std::move(trusted_header_client));
+      std::move(handshake_client),
+      process->GetStoragePartition()->CreateAuthAndCertObserverForFrame(
+          process_id, frame_id),
+      std::move(auth_handler), std::move(trusted_header_client));
 }
 
 }  // namespace content
diff --git a/content/browser/websockets/websocket_connector_impl.h b/content/browser/websockets/websocket_connector_impl.h
index 18dde8e..bdf0fc3 100644
--- a/content/browser/websockets/websocket_connector_impl.h
+++ b/content/browser/websockets/websocket_connector_impl.h
@@ -56,7 +56,8 @@
       std::vector<network::mojom::HttpHeaderPtr> additional_headers,
       mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
           handshake_client,
-      mojo::PendingRemote<network::mojom::AuthenticationHandler> auth_handler,
+      mojo::PendingRemote<network::mojom::WebSocketAuthenticationHandler>
+          auth_handler,
       mojo::PendingRemote<network::mojom::TrustedHeaderClient>
           trusted_header_client);
 
diff --git a/content/browser/webui/web_ui_data_source_impl.cc b/content/browser/webui/web_ui_data_source_impl.cc
index 6adf2b9..d927979 100644
--- a/content/browser/webui/web_ui_data_source_impl.cc
+++ b/content/browser/webui/web_ui_data_source_impl.cc
@@ -145,6 +145,12 @@
 }
 
 void WebUIDataSourceImpl::AddLocalizedStrings(
+    base::span<const webui::LocalizedString> strings) {
+  for (const auto& str : strings)
+    AddLocalizedString(str.name, str.id);
+}
+
+void WebUIDataSourceImpl::AddLocalizedStrings(
     const base::DictionaryValue& localized_strings) {
   localized_strings_.MergeDictionary(&localized_strings);
   ui::TemplateReplacementsFromDictionaryValue(localized_strings,
diff --git a/content/browser/webui/web_ui_data_source_impl.h b/content/browser/webui/web_ui_data_source_impl.h
index 8485b44..9fb2447e 100644
--- a/content/browser/webui/web_ui_data_source_impl.h
+++ b/content/browser/webui/web_ui_data_source_impl.h
@@ -34,6 +34,8 @@
   void AddString(base::StringPiece name, const std::string& value) override;
   void AddLocalizedString(base::StringPiece name, int ids) override;
   void AddLocalizedStrings(
+      base::span<const webui::LocalizedString> strings) override;
+  void AddLocalizedStrings(
       const base::DictionaryValue& localized_strings) override;
   void AddBoolean(base::StringPiece name, bool value) override;
   void AddInteger(base::StringPiece name, int32_t value) override;
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index e75e0854..8083822 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -283,6 +283,8 @@
     {wf::EnableIdleDetection, features::kIdleDetection, kSetOnlyIfOverridden},
     {wf::EnableSkipTouchEventFilter, blink::features::kSkipTouchEventFilter},
     {wf::EnableWebOTP, features::kWebOTP, kSetOnlyIfOverridden},
+    {wf::EnableCapabilityDelegationPaymentRequest,
+     features::kCapabilityDelegationPaymentRequest},
     {wf::EnableClickPointerEvent, features::kClickPointerEvent},
     {wf::EnableCompositeBGColorAnimation, features::kCompositeBGColorAnimation},
     {wf::EnableConsolidatedMovementXY, features::kConsolidatedMovementXY},
diff --git a/content/common/media/media_player_delegate_messages.h b/content/common/media/media_player_delegate_messages.h
index 2f7c2c24..5ce85fe4 100644
--- a/content/common/media/media_player_delegate_messages.h
+++ b/content/common/media/media_player_delegate_messages.h
@@ -15,16 +15,12 @@
 
 #include "content/common/content_export.h"
 #include "ipc/ipc_message_macros.h"
-#include "third_party/blink/public/platform/web_fullscreen_video_status.h"
 #include "ui/gfx/ipc/geometry/gfx_param_traits.h"
 
 #undef IPC_MESSAGE_EXPORT
 #define IPC_MESSAGE_EXPORT CONTENT_EXPORT
 #define IPC_MESSAGE_START MediaPlayerDelegateMsgStart
 
-IPC_ENUM_TRAITS_MAX_VALUE(blink::WebFullscreenVideoStatus,
-                          blink::WebFullscreenVideoStatus::kMaxValue)
-
 // ----------------------------------------------------------------------------
 // Messages from the browser to the renderer requesting playback state changes.
 // ----------------------------------------------------------------------------
@@ -43,17 +39,4 @@
                     int /* delegate_id, distinguishes instances */,
                     bool /* is experiment starting (true) or stopping? */)
 
-// ----------------------------------------------------------------------------
-// Messages from the renderer notifying the browser of playback state changes.
-// ----------------------------------------------------------------------------
-
-IPC_MESSAGE_ROUTED2(
-    MediaPlayerDelegateHostMsg_OnMediaEffectivelyFullscreenChanged,
-    int /* delegate_id, distinguishes instances */,
-    blink::WebFullscreenVideoStatus /* fullscreen_video_status */)
-
-IPC_MESSAGE_ROUTED2(MediaPlayerDelegateHostMsg_OnAudioOutputSinkChanged,
-                    int /* delegate_id, distinguishes instances */,
-                    std::string /* hashed_device_id */)
-
 #endif  // CONTENT_COMMON_MEDIA_MEDIA_PLAYER_DELEGATE_MESSAGES_H_
diff --git a/content/common/navigation_client.mojom b/content/common/navigation_client.mojom
index e3d8d18..d416df22 100644
--- a/content/common/navigation_client.mojom
+++ b/content/common/navigation_client.mojom
@@ -258,7 +258,8 @@
       int32 error_code,
       network.mojom.ResolveErrorInfo resolve_error_info,
       string? error_page_content,
-      blink.mojom.URLLoaderFactoryBundle? subresource_loader_factories)
+      blink.mojom.URLLoaderFactoryBundle? subresource_loader_factories,
+      blink.mojom.PolicyContainer policy_container)
       => (DidCommitProvisionalLoadParams params,
           DidCommitProvisionalLoadInterfaceParams? interface_params);
 };
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn
index 1e0970ec..bb81b96d 100644
--- a/content/public/android/BUILD.gn
+++ b/content/public/android/BUILD.gn
@@ -552,6 +552,10 @@
     "javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellTestData.java",
     "javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellTestUtils.java",
     "javatests/src/org/chromium/content/browser/accessibility/AccessibilityEventDispatcherTest.java",
+    "javatests/src/org/chromium/content/browser/accessibility/AssistViewStructureTest.java",
+    "javatests/src/org/chromium/content/browser/accessibility/TestViewStructure.java",
+    "javatests/src/org/chromium/content/browser/accessibility/TestViewStructureFactory.java",
+    "javatests/src/org/chromium/content/browser/accessibility/TestViewStructureInterface.java",
     "javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java",
     "javatests/src/org/chromium/content/browser/accessibility/captioning/CaptioningChangeDelegateTest.java",
     "javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplPixelTest.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java
index 090c2fb66..f158602 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java
@@ -21,9 +21,11 @@
 import org.chromium.base.CollectionUtil;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.CpuFeatures;
+import org.chromium.base.EarlyTraceEvent;
 import org.chromium.base.JavaExceptionReporter;
 import org.chromium.base.Log;
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.TraceEvent;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.NativeMethods;
@@ -119,6 +121,10 @@
     // Tracks reporting exception from child process to avoid reporting it more than once.
     private boolean mReportedException;
 
+    // Enables early Java tracing in child process before native is initialized.
+    private static final String TRACE_EARLY_JAVA_IN_CHILD_SWITCH =
+            "--" + EarlyTraceEvent.TRACE_EARLY_JAVA_IN_CHILD_SWITCH;
+
     private final ChildProcessLauncher.Delegate mLauncherDelegate =
             new ChildProcessLauncher.Delegate() {
                 @Override
@@ -233,6 +239,10 @@
         String processType =
                 ContentSwitchUtils.getSwitchValue(commandLine, ContentSwitches.SWITCH_PROCESS_TYPE);
 
+        if (TraceEvent.enabled()) {
+            commandLine = Arrays.copyOf(commandLine, commandLine.length + 1);
+            commandLine[commandLine.length - 1] = TRACE_EARLY_JAVA_IN_CHILD_SWITCH;
+        }
         boolean sandboxed = true;
         if (!ContentSwitches.SWITCH_RENDERER_PROCESS.equals(processType)) {
             if (ContentSwitches.SWITCH_GPU_PROCESS.equals(processType)) {
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AssistViewStructureTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AssistViewStructureTest.java
new file mode 100644
index 0000000..b94d1f3
--- /dev/null
+++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AssistViewStructureTest.java
@@ -0,0 +1,104 @@
+// 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.content.browser.accessibility;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+
+import androidx.test.filters.MediumTest;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.BaseJUnit4ClassRunner;
+import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.base.test.util.DisableIf;
+import org.chromium.base.test.util.MinAndroidSdkLevel;
+import org.chromium.base.test.util.UrlUtils;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.content_shell_apk.ContentShellActivityTestRule;
+
+/**
+ * Tests for the implementation of onProvideVirtualStructure in
+ * WebContentsAccessibility.
+ */
+@RunWith(BaseJUnit4ClassRunner.class)
+public class AssistViewStructureTest {
+    @Rule
+    public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule();
+
+    /**
+     * Helper to call onProvideVirtualStructure and block until the results are received.
+     */
+    private TestViewStructureInterface getViewStructureFromHtml(String htmlContent) {
+        mActivityTestRule.launchContentShellWithUrl(UrlUtils.encodeHtmlDataUri(htmlContent));
+        mActivityTestRule.waitForActiveShellToBeDoneLoading();
+
+        final WebContentsAccessibilityImpl wcax = mActivityTestRule.getWebContentsAccessibility();
+
+        TestViewStructureInterface testViewStructure =
+                TestViewStructureFactory.createTestViewStructure();
+
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> wcax.onProvideVirtualStructure((TestViewStructure) testViewStructure, false));
+
+        CriteriaHelper.pollUiThread(()
+                                            -> testViewStructure.isDone(),
+                "Timed out waiting for onProvideVirtualStructure");
+        return testViewStructure;
+    }
+
+    /**
+     * Test simple paragraph.
+     */
+    @Test
+    @MediumTest
+    @MinAndroidSdkLevel(Build.VERSION_CODES.M)
+    @TargetApi(Build.VERSION_CODES.M)
+    @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.M)
+    public void testSimpleParagraph() throws Throwable {
+        TestViewStructureInterface testViewStructure =
+                getViewStructureFromHtml("<p>Hello World</p>");
+        Assert.assertEquals(testViewStructure.toString(),
+                "\n"
+                        + "  android.webkit.WebView\n"
+                        + "    android.view.View text='Hello World'\n"
+                        + "      android.widget.TextView text='Hello World'\n");
+    }
+
+    /**
+     * Test static list.
+     */
+    @Test
+    @MediumTest
+    @MinAndroidSdkLevel(Build.VERSION_CODES.M)
+    @TargetApi(Build.VERSION_CODES.M)
+    @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.M)
+    public void testStaticList() throws Throwable {
+        TestViewStructureInterface testViewStructure = getViewStructureFromHtml("<ol>"
+                + "  <li>Kirk</li>"
+                + "  <li>Picard</li>"
+                + "  <li>Janeway</li>"
+                + "</ol>");
+        Assert.assertEquals(testViewStructure.toString(),
+                "\n"
+                        + "  android.webkit.WebView\n"
+                        + "    android.widget.ListView\n"
+                        + "      android.view.View\n"
+                        + "        android.view.View text='1. '\n"
+                        + "          android.widget.TextView text='1. '\n"
+                        + "        android.widget.TextView text='Kirk'\n"
+                        + "      android.view.View\n"
+                        + "        android.view.View text='2. '\n"
+                        + "          android.widget.TextView text='2. '\n"
+                        + "        android.widget.TextView text='Picard'\n"
+                        + "      android.view.View\n"
+                        + "        android.view.View text='3. '\n"
+                        + "          android.widget.TextView text='3. '\n"
+                        + "        android.widget.TextView text='Janeway'\n");
+    }
+}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/TestViewStructure.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/TestViewStructure.java
new file mode 100644
index 0000000..6762614a
--- /dev/null
+++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/TestViewStructure.java
@@ -0,0 +1,268 @@
+// 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.content.browser.accessibility;
+
+import android.graphics.Matrix;
+import android.os.Bundle;
+import android.os.LocaleList;
+import android.text.TextUtils;
+import android.view.ViewStructure;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+
+import java.util.ArrayList;
+
+/**
+ * Implementation of ViewStructure that allows us to print it out as a
+ * string and assert that the data in the structure is correct.
+ */
+public class TestViewStructure extends ViewStructure implements TestViewStructureInterface {
+    private CharSequence mText;
+    private String mClassName;
+    private Bundle mBundle;
+    private int mChildCount;
+    private ArrayList<TestViewStructure> mChildren = new ArrayList<TestViewStructure>();
+    private boolean mDone = true;
+
+    public TestViewStructure() {}
+
+    @Override
+    public boolean isDone() {
+        if (!mDone) return false;
+
+        for (TestViewStructure child : mChildren) {
+            if (!child.isDone()) return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        recursiveDumpToString(builder, 0);
+        return builder.toString();
+    }
+
+    private void recursiveDumpToString(StringBuilder builder, int indent) {
+        for (int i = 0; i < indent; i++) {
+            builder.append("  ");
+        }
+
+        if (!TextUtils.isEmpty(mClassName)) {
+            builder.append(mClassName);
+        }
+
+        if (!TextUtils.isEmpty(mText)) {
+            builder.append(" text='");
+            builder.append(mText);
+            builder.append("'");
+        }
+        builder.append("\n");
+
+        for (TestViewStructure child : mChildren) {
+            child.recursiveDumpToString(builder, indent + 1);
+        }
+    }
+
+    @Override
+    public void setAlpha(float alpha) {}
+
+    @Override
+    public void setAccessibilityFocused(boolean state) {}
+
+    @Override
+    public void setCheckable(boolean state) {}
+
+    @Override
+    public void setChecked(boolean state) {}
+
+    @Override
+    public void setActivated(boolean state) {}
+
+    @Override
+    public CharSequence getText() {
+        return mText;
+    }
+
+    @Override
+    public int getTextSelectionStart() {
+        return 0;
+    }
+
+    @Override
+    public int getTextSelectionEnd() {
+        return 0;
+    }
+
+    @Override
+    public CharSequence getHint() {
+        return null;
+    }
+
+    @Override
+    public Bundle getExtras() {
+        if (mBundle == null) mBundle = new Bundle();
+        return mBundle;
+    }
+
+    @Override
+    public boolean hasExtras() {
+        return mBundle != null;
+    }
+
+    @Override
+    public void setChildCount(int num) {}
+
+    @Override
+    public int addChildCount(int num) {
+        int index = mChildCount;
+        mChildCount += num;
+        mChildren.ensureCapacity(mChildCount);
+        return index;
+    }
+
+    @Override
+    public int getChildCount() {
+        return mChildren.size();
+    }
+
+    @Override
+    public ViewStructure newChild(int index) {
+        TestViewStructure viewStructure = new TestViewStructure();
+        if (index < mChildren.size()) {
+            mChildren.set(index, viewStructure);
+        } else if (index == mChildren.size()) {
+            mChildren.add(viewStructure);
+        } else {
+            // Failed intentionally, we shouldn't run into this case.
+            mChildren.add(index, viewStructure);
+        }
+        return viewStructure;
+    }
+
+    public TestViewStructure getChild(int index) {
+        return mChildren.get(index);
+    }
+
+    @Override
+    public ViewStructure asyncNewChild(int index) {
+        TestViewStructure result = (TestViewStructure) newChild(index);
+        result.mDone = false;
+        return result;
+    }
+
+    @Override
+    public void asyncCommit() {
+        mDone = true;
+    }
+
+    @Override
+    public AutofillId getAutofillId() {
+        return null;
+    }
+
+    @Override
+    public HtmlInfo.Builder newHtmlInfoBuilder(String tag) {
+        return null;
+    }
+
+    @Override
+    public void setAutofillHints(String[] arg0) {}
+
+    @Override
+    public void setAutofillId(AutofillId arg0) {}
+
+    @Override
+    public void setAutofillId(AutofillId arg0, int arg1) {}
+
+    @Override
+    public void setAutofillOptions(CharSequence[] arg0) {}
+
+    @Override
+    public void setAutofillType(int arg0) {}
+
+    @Override
+    public void setAutofillValue(AutofillValue arg0) {}
+
+    @Override
+    public void setId(int id, String packageName, String typeName, String entryName) {}
+
+    @Override
+    public void setDimens(int left, int top, int scrollX, int scrollY, int width, int height) {}
+
+    @Override
+    public void setElevation(float elevation) {}
+
+    @Override
+    public void setEnabled(boolean state) {}
+
+    @Override
+    public void setClickable(boolean state) {}
+
+    @Override
+    public void setLongClickable(boolean state) {}
+
+    @Override
+    public void setContextClickable(boolean state) {}
+
+    @Override
+    public void setFocusable(boolean state) {}
+
+    @Override
+    public void setFocused(boolean state) {}
+
+    @Override
+    public void setClassName(String className) {
+        mClassName = className;
+    }
+
+    @Override
+    public void setContentDescription(CharSequence contentDescription) {}
+
+    @Override
+    public void setDataIsSensitive(boolean arg0) {}
+
+    @Override
+    public void setHint(CharSequence hint) {}
+
+    @Override
+    public void setHtmlInfo(HtmlInfo arg0) {}
+
+    @Override
+    public void setInputType(int arg0) {}
+
+    @Override
+    public void setLocaleList(LocaleList arg0) {}
+
+    @Override
+    public void setOpaque(boolean arg0) {}
+
+    @Override
+    public void setTransformation(Matrix matrix) {}
+
+    @Override
+    public void setVisibility(int visibility) {}
+
+    @Override
+    public void setSelected(boolean state) {}
+
+    @Override
+    public void setText(CharSequence text) {
+        mText = text;
+    }
+
+    @Override
+    public void setText(CharSequence text, int selectionStart, int selectionEnd) {}
+
+    @Override
+    public void setTextStyle(float size, int fgColor, int bgColor, int style) {}
+
+    @Override
+    public void setTextLines(int[] charOffsets, int[] baselines) {}
+
+    @Override
+    public void setWebDomain(String webDomain) {}
+}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/TestViewStructureFactory.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/TestViewStructureFactory.java
new file mode 100644
index 0000000..1046f1d0
--- /dev/null
+++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/TestViewStructureFactory.java
@@ -0,0 +1,22 @@
+// 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.content.browser.accessibility;
+
+import android.os.Build;
+
+/**
+ * Factory to construct a TestViewStructure only on "M" and higher,
+ * otherwise AssistViewStructureTest fails to run because of the
+ * reference to TestViewStructure.
+ */
+public class TestViewStructureFactory {
+    static TestViewStructureInterface createTestViewStructure() {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            return new TestViewStructure();
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/TestViewStructureInterface.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/TestViewStructureInterface.java
new file mode 100644
index 0000000..ba95019
--- /dev/null
+++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/TestViewStructureInterface.java
@@ -0,0 +1,23 @@
+// 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.content.browser.accessibility;
+
+/**
+ * Interface for an implementation of ViewStructure that allows us
+ * to print it out as a string and assert that the data in the
+ * structure is correct.
+ *
+ * This is needed because if AssistViewStructureTest references
+ * TestViewStructure in any way, the entire test APK fails to run
+ * if the SDK version is less than M.
+ */
+interface TestViewStructureInterface {
+    /**
+     * Because ViewStructure can be populated asynchronously,
+     * returns true if it's complete - i.e. if every call to
+     * asyncNewChild has been balanced by a call to asyncCommit.
+     */
+    public boolean isDone();
+}
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index a2ae9cb..49da693f 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -1428,7 +1428,7 @@
       const GURL& /* url */,
       std::vector<network::mojom::HttpHeaderPtr> /* additional_headers */,
       mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>,
-      mojo::PendingRemote<network::mojom::AuthenticationHandler>,
+      mojo::PendingRemote<network::mojom::WebSocketAuthenticationHandler>,
       mojo::PendingRemote<network::mojom::TrustedHeaderClient>)>;
 
   // Allows the embedder to intercept a WebSocket connection. This is called
diff --git a/content/public/browser/network_context_client_base.h b/content/public/browser/network_context_client_base.h
index b320398..8dc223428 100644
--- a/content/public/browser/network_context_client_base.h
+++ b/content/public/browser/network_context_client_base.h
@@ -42,13 +42,6 @@
       const scoped_refptr<net::SSLCertRequestInfo>& cert_info,
       mojo::PendingRemote<network::mojom::ClientCertificateResponder>
           cert_responder) override;
-  void OnSSLCertificateError(int32_t process_id,
-                             int32_t routing_id,
-                             const GURL& url,
-                             int net_error,
-                             const net::SSLInfo& ssl_info,
-                             bool fatal,
-                             OnSSLCertificateErrorCallback response) override;
   void OnFileUploadRequested(int32_t process_id,
                              bool async,
                              const std::vector<base::FilePath>& file_paths,
diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h
index a15ef32..7ca2c9a3 100644
--- a/content/public/browser/storage_partition.h
+++ b/content/public/browser/storage_partition.h
@@ -118,6 +118,14 @@
       mojo::PendingReceiver<network::mojom::HasTrustTokensAnswerer> receiver,
       const url::Origin& top_frame_origin) = 0;
 
+  virtual mojo::PendingRemote<
+      network::mojom::AuthenticationAndCertificateObserver>
+  CreateAuthAndCertObserverForFrame(int process_id, int frame_routing_id) = 0;
+
+  virtual mojo::PendingRemote<
+      network::mojom::AuthenticationAndCertificateObserver>
+  CreateAuthAndCertObserverForNavigationRequest(int frame_tree_node_id) = 0;
+
   virtual storage::QuotaManager* GetQuotaManager() = 0;
   virtual AppCacheService* GetAppCacheService() = 0;
   virtual BackgroundSyncContext* GetBackgroundSyncContext() = 0;
diff --git a/content/public/browser/web_ui_data_source.h b/content/public/browser/web_ui_data_source.h
index 84e9cab..f8e0b20 100644
--- a/content/public/browser/web_ui_data_source.h
+++ b/content/public/browser/web_ui_data_source.h
@@ -12,10 +12,12 @@
 #include <vector>
 
 #include "base/callback.h"
+#include "base/containers/span.h"
 #include "base/strings/string16.h"
 #include "base/strings/string_piece.h"
 #include "content/common/content_export.h"
 #include "services/network/public/mojom/content_security_policy.mojom-forward.h"
+#include "ui/base/webui/web_ui_util.h"
 #include "url/gurl.h"
 
 namespace base {
@@ -23,6 +25,10 @@
 class RefCountedMemory;
 }  // namespace base
 
+namespace webui {
+struct LocalizedString;
+}  // namespace webui
+
 namespace content {
 class BrowserContext;
 
@@ -57,6 +63,11 @@
   // dictionary.
   virtual void AddLocalizedString(base::StringPiece name, int ids) = 0;
 
+  // Calls AddLocalizedString() in a for-loop for |strings|. Reduces code size
+  // vs. reimplementing the same for-loop.
+  virtual void AddLocalizedStrings(
+      base::span<const webui::LocalizedString> strings) = 0;
+
   // Add strings from |localized_strings| to our dictionary.
   virtual void AddLocalizedStrings(
       const base::DictionaryValue& localized_strings) = 0;
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 4bedd23..15aa2b0e 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -163,6 +163,9 @@
     "ClearCrossBrowsingContextGroupMainFrameName",
     base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kCapabilityDelegationPaymentRequest{
+    "CapabilityDelegationPaymentRequest", base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kClickPointerEvent{"ClickPointerEvent",
                                        base::FEATURE_DISABLED_BY_DEFAULT};
 
@@ -967,7 +970,7 @@
     "RetryGetVideoCaptureDeviceInfos", base::FEATURE_DISABLED_BY_DEFAULT};
 
 const base::Feature kDesktopCaptureMacV2{"DesktopCaptureMacV2",
-                                         base::FEATURE_DISABLED_BY_DEFAULT};
+                                         base::FEATURE_ENABLED_BY_DEFAULT};
 
 #endif  // defined(OS_MAC)
 
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 23cdfda..a66f9b8 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -36,6 +36,7 @@
 CONTENT_EXPORT extern const base::Feature kBrowserVerifiedUserActivationMouse;
 CONTENT_EXPORT extern const base::Feature kCacheInlineScriptCode;
 CONTENT_EXPORT extern const base::Feature kCanvas2DImageChromium;
+CONTENT_EXPORT extern const base::Feature kCapabilityDelegationPaymentRequest;
 CONTENT_EXPORT extern const base::Feature
     kClearCrossBrowsingContextGroupMainFrameName;
 CONTENT_EXPORT extern const base::Feature kClickPointerEvent;
diff --git a/content/public/test/test_storage_partition.cc b/content/public/test/test_storage_partition.cc
index 9e42c18d..5bc8fb3 100644
--- a/content/public/test/test_storage_partition.cc
+++ b/content/public/test/test_storage_partition.cc
@@ -47,6 +47,18 @@
   NOTREACHED() << "Not implemented.";
 }
 
+mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+TestStoragePartition::CreateAuthAndCertObserverForFrame(int process_id,
+                                                        int routing_id) {
+  return mojo::NullRemote();
+}
+
+mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+TestStoragePartition::CreateAuthAndCertObserverForNavigationRequest(
+    int frame_tree_id) {
+  return mojo::NullRemote();
+}
+
 storage::QuotaManager* TestStoragePartition::GetQuotaManager() {
   return quota_manager_;
 }
diff --git a/content/public/test/test_storage_partition.h b/content/public/test/test_storage_partition.h
index f28e822..1b841ad 100644
--- a/content/public/test/test_storage_partition.h
+++ b/content/public/test/test_storage_partition.h
@@ -71,6 +71,12 @@
       mojo::PendingReceiver<network::mojom::HasTrustTokensAnswerer> receiver,
       const url::Origin& top_frame_origin) override;
 
+  mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+  CreateAuthAndCertObserverForFrame(int process_id, int routing_id) override;
+
+  mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+  CreateAuthAndCertObserverForNavigationRequest(int frame_tree_id) override;
+
   void set_quota_manager(storage::QuotaManager* manager) {
     quota_manager_ = manager;
   }
diff --git a/content/renderer/media/android/media_player_renderer_client.cc b/content/renderer/media/android/media_player_renderer_client.cc
index c567550..967f562 100644
--- a/content/renderer/media/android/media_player_renderer_client.cc
+++ b/content/renderer/media/android/media_player_renderer_client.cc
@@ -108,8 +108,10 @@
     // Signal that we're using MediaPlayer so that we can properly differentiate
     // within our metrics.
     media::PipelineStatistics stats;
-    stats.video_decoder_info =
-        stats.audio_decoder_info = {true, false, "MediaPlayer"};
+    stats.video_decoder_info = {true, false,
+                                media::VideoDecoderType::kMediaCodec};
+    stats.audio_decoder_info = {true, false,
+                                media::AudioDecoderType::kMediaCodec};
     client_->OnStatisticsUpdate(stats);
   }
   std::move(init_cb_).Run(status);
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.cc b/content/renderer/media/renderer_webmediaplayer_delegate.cc
index c46f58d..27a2347 100644
--- a/content/renderer/media/renderer_webmediaplayer_delegate.cc
+++ b/content/renderer/media/renderer_webmediaplayer_delegate.cc
@@ -187,20 +187,6 @@
   return stale_players_.count(player_id);
 }
 
-void RendererWebMediaPlayerDelegate::SetIsEffectivelyFullscreen(
-    int player_id,
-    blink::WebFullscreenVideoStatus fullscreen_video_status) {
-  Send(new MediaPlayerDelegateHostMsg_OnMediaEffectivelyFullscreenChanged(
-      routing_id(), player_id, fullscreen_video_status));
-}
-
-void RendererWebMediaPlayerDelegate::DidAudioOutputSinkChange(
-    int delegate_id,
-    const std::string& hashed_device_id) {
-  Send(new MediaPlayerDelegateHostMsg_OnAudioOutputSinkChanged(
-      routing_id(), delegate_id, hashed_device_id));
-}
-
 void RendererWebMediaPlayerDelegate::WasHidden() {
   RecordAction(base::UserMetricsAction("Media.Hidden"));
 
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.h b/content/renderer/media/renderer_webmediaplayer_delegate.h
index c96e986..907b955a 100644
--- a/content/renderer/media/renderer_webmediaplayer_delegate.h
+++ b/content/renderer/media/renderer_webmediaplayer_delegate.h
@@ -63,11 +63,6 @@
   bool IsIdle(int player_id) override;
   void ClearStaleFlag(int player_id) override;
   bool IsStale(int player_id) override;
-  void SetIsEffectivelyFullscreen(
-      int player_id,
-      blink::WebFullscreenVideoStatus fullscreen_video_status) override;
-  void DidAudioOutputSinkChange(int delegate_id,
-                                const std::string& hashed_device_id) override;
 
   // content::RenderFrameObserver overrides.
   void WasHidden() override;
diff --git a/content/renderer/navigation_client.cc b/content/renderer/navigation_client.cc
index a3a2f74..7c91430 100644
--- a/content/renderer/navigation_client.cc
+++ b/content/renderer/navigation_client.cc
@@ -54,12 +54,14 @@
     const net::ResolveErrorInfo& resolve_error_info,
     const base::Optional<std::string>& error_page_content,
     std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loaders,
+    blink::mojom::PolicyContainerPtr policy_container,
     CommitFailedNavigationCallback callback) {
   ResetDisconnectionHandler();
   render_frame_->CommitFailedNavigation(
       std::move(common_params), std::move(commit_params),
       has_stale_copy_in_cache, error_code, resolve_error_info,
-      error_page_content, std::move(subresource_loaders), std::move(callback));
+      error_page_content, std::move(subresource_loaders),
+      std::move(policy_container), std::move(callback));
 }
 
 void NavigationClient::Bind(
diff --git a/content/renderer/navigation_client.h b/content/renderer/navigation_client.h
index 95a31d3..5a278fb 100644
--- a/content/renderer/navigation_client.h
+++ b/content/renderer/navigation_client.h
@@ -44,6 +44,7 @@
       const net::ResolveErrorInfo& resolve_error_info,
       const base::Optional<std::string>& error_page_content,
       std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loaders,
+      blink::mojom::PolicyContainerPtr policy_container,
       CommitFailedNavigationCallback callback) override;
 
   void Bind(mojo::PendingAssociatedReceiver<mojom::NavigationClient> receiver);
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index b1e870d..f1d3369 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -2217,6 +2217,7 @@
 void RenderFrameImpl::BindAutoplayConfiguration(
     mojo::PendingAssociatedReceiver<blink::mojom::AutoplayConfigurationClient>
         receiver) {
+  autoplay_configuration_receiver_.reset();
   autoplay_configuration_receiver_.Bind(
       std::move(receiver),
       GetTaskRunner(blink::TaskType::kInternalNavigationAssociated));
@@ -3161,6 +3162,7 @@
     const base::Optional<std::string>& error_page_content,
     std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
         subresource_loader_factories,
+    blink::mojom::PolicyContainerPtr policy_container,
     mojom::NavigationClient::CommitFailedNavigationCallback callback) {
   TRACE_EVENT1("navigation,benchmark,rail",
                "RenderFrameImpl::CommitFailedNavigation", "id", routing_id_);
@@ -3315,6 +3317,9 @@
     navigation_params->pre_redirect_url_for_failed_navigations = error.url();
   }
 
+  navigation_params->policy_container =
+      ToWebPolicyContainer(std::move(policy_container));
+
   // The error page load (not to confuse with a failed load of original page)
   // was not initiated through BeginNavigation, therefore
   // |was_initiated_in_this_frame| is false.
@@ -5940,6 +5945,7 @@
 }
 
 void RenderFrameImpl::RegisterMojoInterfaces() {
+  // TODO(dcheng): Fold this interface into mojom::Frame.
   GetAssociatedInterfaceRegistry()->AddInterface(base::BindRepeating(
       &RenderFrameImpl::BindAutoplayConfiguration, weak_factory_.GetWeakPtr()));
 
@@ -5949,6 +5955,7 @@
   GetAssociatedInterfaceRegistry()->AddInterface(base::BindRepeating(
       &RenderFrameImpl::BindNavigationClient, weak_factory_.GetWeakPtr()));
 
+  // TODO(dcheng): Fold this interface into mojom::Frame.
   GetAssociatedInterfaceRegistry()->AddInterface(base::BindRepeating(
       &RenderFrameImpl::BindMhtmlFileWriter, base::Unretained(this)));
 
@@ -5959,6 +5966,7 @@
 
 void RenderFrameImpl::BindMhtmlFileWriter(
     mojo::PendingAssociatedReceiver<mojom::MhtmlFileWriter> receiver) {
+  mhtml_file_writer_receiver_.reset();
   mhtml_file_writer_receiver_.Bind(
       std::move(receiver), GetTaskRunner(blink::TaskType::kInternalDefault));
 }
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 7e663c7f..64d7f76d 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -461,6 +461,7 @@
       const base::Optional<std::string>& error_page_content,
       std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
           subresource_loader_factories,
+      blink::mojom::PolicyContainerPtr policy_container,
       mojom::NavigationClient::CommitFailedNavigationCallback
           per_navigation_mojo_interface_callback);
 
diff --git a/content/services/isolated_xr_device/xr_runtime_provider.cc b/content/services/isolated_xr_device/xr_runtime_provider.cc
index d5b0153..9bf67133 100644
--- a/content/services/isolated_xr_device/xr_runtime_provider.cc
+++ b/content/services/isolated_xr_device/xr_runtime_provider.cc
@@ -172,6 +172,14 @@
                    &openxr_device_);
 }
 
+// A repeating callback to CreateContextProviderAsync is created in
+// SetOpenXrRuntimeStatus and passed to OpenXrDevice. OpenXrRenderLoop posts a
+// task with this callback onto the main thread's task runner while it is
+// running on the render loop thread's task runner. The context provider and its
+// supporting object, viz::Gpu, are required to be created on the main thread's
+// task runner. Upon creating the context provider, CreateContextProviderAsync
+// posts a callback back to the render loop's thread runner with the newly
+// created context provider.
 void IsolatedXRRuntimeProvider::CreateContextProviderAsync(
     VizContextProviderCallback viz_context_provider_callback,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
diff --git a/content/test/data/gpu/vc/videos_mxn.html b/content/test/data/gpu/vc/videos_mxn.html
index 322f0b11..f58de45 100644
--- a/content/test/data/gpu/vc/videos_mxn.html
+++ b/content/test/data/gpu/vc/videos_mxn.html
@@ -90,6 +90,7 @@
       // similate the one from the local camera.
       const video_src = GetVideoSource(video_count, video_count);
       createOneVideo(0, _total_video_width - 89, 89, 50, video_src);
+      createOneIcon(0, _total_video_width - 89, 89, 50);
     }
 
     function createOneVideo(top, left, width, height, video_src) {
@@ -117,8 +118,8 @@
       icon.style.position = "absolute";
       icon.style.width = icon_width;
       icon.style.height = icon_height;
-      icon.style.top = video_top + video_height - icon_width;
-      icon.style.left = video_left + icon_height;
+      icon.style.top = video_top + video_height - icon_height * 2;
+      icon.style.left = video_left + icon_width;
 
       container.appendChild(icon);
     }
diff --git a/content/test/data/gpu/vc/webgpu_video.js b/content/test/data/gpu/vc/webgpu_video.js
index 70861f6..85192c3 100644
--- a/content/test/data/gpu/vc/webgpu_video.js
+++ b/content/test/data/gpu/vc/webgpu_video.js
@@ -2,17 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-async function webGpuInit() {
-  const canvas = document.createElement('canvas');
-
-  if (!navigator.gpu) {
-    console.warn('Webgpu not supported. navigator.gpu fails!');
-    return null;
-  }
-
-  const adapter = await navigator.gpu.requestAdapter();
+async function webGpuInit(canvasWidth, canvasHeight) {
+  const adapter = navigator.gpu && await navigator.gpu.requestAdapter();
   if (!adapter) {
-    console.warn('Webgpu not supported. navigator.gpu.requestAdapter fails!');
+    console.warn('navigator.gpu && navigator.gpu.requestAdapter fails!');
     return null;
   }
 
@@ -22,18 +15,23 @@
     return null;
   }
 
+  const container = document.getElementById('container');
+  const canvas = container.appendChild(document.createElement('canvas'));
+  canvas.width = canvasWidth;
+  canvas.height = canvasHeight;
+
   const context = canvas.getContext('gpupresent');
   if (!context) {
     console.warn('Webgpu not supported. canvas.getContext(gpupresent) fails!');
     return null;
   }
 
-  return { device, canvas, context };
+  return { device, context };
 }
 
   const wgslShaders = {
     vertex: `
-[[location(0)]] var<in> position : vec3<f32>;
+[[location(0)]] var<in> position : vec2<f32>;
 [[location(1)]] var<in> uv : vec2<f32>;
 
 [[location(0)]] var<out> fragUV : vec2<f32>;
@@ -41,7 +39,7 @@
 
 [[stage(vertex)]]
 fn main() -> void {
-  Position = vec4<f32>(position, 1.0);
+  Position = vec4<f32>(position, 0.0, 1.0);
   fragUV = uv;
   return;
 }
@@ -60,32 +58,70 @@
   return;
 }
 `,
+    vertex_icons: `
+[[location(0)]] var<in> position : vec2<f32>;
+[[builtin(position)]] var<out> Position : vec4<f32>;
+
+[[stage(vertex)]]
+fn main() -> void {
+  Position = vec4<f32>(position, 0.0, 1.0);
+  return;
+}
+`,
+
+    fragment_output_red: `
+[[location(0)]] var<out> outColor : vec4<f32>;
+
+[[stage(fragment)]]
+fn main() -> void {
+  outColor = vec4<f32>(1.0, 0.0, 0.0, 1.0);
+  return;
+}
+`,
   };
 
-function createVertexBuffer(device, videoRows, videoColumns) {
-  // Each video takes 6 vertices (2 triangles). Each vertice has 5 floats.
-  // Therefore, each video needs 30 floats.
-  const rectVerts = new Float32Array(videoRows * videoColumns * 30);
+function createVertexBuffer(device, videos, videoRows, videoColumns) {
+  // Each video takes 6 vertices (2 triangles). Each vertice has 4 floats.
+  // Therefore, each video needs 24 floats.
+  // The small video at the corner is included in the vertex buffer.
+  const rectVerts = new Float32Array(videos.length * 24);
 
-  for (let row = 0; row < videoRows; row++) {
-    for (let column = 0; column < videoColumns; column++) {
-      const index = (row * videoColumns + column) * 30;
-      const w = 2.0 / videoColumns;
-      const h = 2.0 / videoRows;
+  let w = 2.0 / videoColumns;
+  let h = 2.0 / videoRows;
+  for (let row = 0; row < videoRows; ++row) {
+    for (let column = 0; column < videoColumns; ++column) {
+      const array_index = (row * videoColumns + column) * 24;
       const x = -1.0 + w * column;
       const y = 1.0 - h * row;
 
       rectVerts.set([
-        (x + w), y, 0.0, 1.0, 0.0,
-        (x + w), (y - h), 0.0, 1.0, 1.0,
-        x, (y - h), 0.0, 0.0, 1.0,
-        (x + w), y, 0.0, 1.0, 0.0,
-        x, (y - h), 0.0, 0.0, 1.0,
-        x, y, 0.0, 0.0, 0.0,
-      ], index);
+        (x + w), y, 1.0, 0.0,
+        (x + w), (y - h), 1.0, 1.0,
+        x, (y - h), 0.0, 1.0,
+        (x + w), y, 1.0, 0.0,
+        x, (y - h), 0.0, 1.0,
+        x, y, 0.0, 0.0,
+      ], array_index);
     }
   }
 
+  // For the small video at the corner, the last one in |videos|.
+  w = w / videos[0].width * videos[videos.length - 1].width;
+  h = h / videos[0].height * videos[videos.length - 1].height;
+  const x = 1.0 - w;
+  const y = 1.0;
+  const array_index = (videos.length - 1) * 24;
+
+  rectVerts.set([
+    (x + w), y, 1.0, 0.0,
+    (x + w), (y - h), 1.0, 1.0,
+    x, (y - h), 0.0, 1.0,
+    (x + w), y, 1.0, 0.0,
+    x, (y - h), 0.0, 1.0,
+    x, y, 0.0, 0.0,
+  ], array_index);
+
+
   const verticesBuffer = device.createBuffer({
     size: rectVerts.byteLength,
     usage: GPUBufferUsage.VERTEX,
@@ -98,14 +134,74 @@
   return verticesBuffer;
 }
 
-function webGpuDrawVideoFrames(gpuSetting, videos, videoRows, videoColumns) {
-  const { canvas, context, device } = gpuSetting;
-  const container = document.getElementById('container');
-  canvas.width = videos[0].width * videoColumns;
-  canvas.height = videos[0].height * videoRows;
-  container.appendChild(canvas);
+function createVertexBufferForIcons(device, videos, videoRows, videoColumns) {
+  // Each video takes 6 vertices (2 triangles). Each vertice has 2 floats.
+  // Therefore, each video needs 12 floats.
+  const rectVerts = new Float32Array(videos.length * 12);
 
-  const verticesBuffer = createVertexBuffer(device, videoRows, videoColumns);
+  let w = 2.0 / videoColumns;
+  let h = 2.0 / videoRows;
+  let wIcon = w / 10.0;
+  let hIcon = h / 10.0;
+
+  for (let row = 0; row < videoRows; ++row) {
+    for (let column = 0; column < videoColumns; ++column) {
+      const array_index = (row * videoColumns + column) * 12;
+      const x = -1.0 + w * column;
+      const y = 1.0 - h * row;
+      const xIcon = x + wIcon;
+      const yIcon = y - h + hIcon * 2;
+
+      rectVerts.set([
+        (xIcon + wIcon), yIcon,
+        (xIcon + wIcon), (yIcon - hIcon),
+        xIcon, (yIcon - hIcon),
+        (xIcon + wIcon), yIcon,
+        xIcon, (yIcon - hIcon),
+        xIcon, yIcon,
+      ], array_index);
+    }
+  }
+
+  // For the small video at the corner, the last one in |videos|.
+  w = w / videos[0].width * videos[videos.length - 1].width;
+  h = h / videos[0].height * videos[videos.length - 1].height;
+  wIcon = w / 10.0;
+  hIcon = h / 10.0;
+
+  const x = 1.0 - w;
+  const y = 1.0;
+  const xIcon = x + wIcon;
+  const yIcon = y - h + hIcon * 2;
+
+  array_index = (videos.length - 1) * 12;
+  rectVerts.set([
+    (xIcon + wIcon), yIcon,
+    (xIcon + wIcon), (yIcon - hIcon),
+    xIcon, (yIcon - hIcon),
+    (xIcon + wIcon), yIcon,
+    xIcon, (yIcon - hIcon),
+    xIcon, yIcon,
+  ], array_index);
+
+  const verticesBuffer = device.createBuffer({
+    size: rectVerts.byteLength,
+    usage: GPUBufferUsage.VERTEX,
+    mappedAtCreation: true,
+  });
+
+  new Float32Array(verticesBuffer.getMappedRange()).set(rectVerts);
+  verticesBuffer.unmap();
+
+  return verticesBuffer;
+}
+
+function webGpuDrawVideoFrames(gpuSetting, videos, videoRows, videoColumns,
+                               addUI, useImportTextureApi) {
+  const { device, context } = gpuSetting;
+
+  const verticesBuffer = createVertexBuffer(device, videos, videoRows,
+                         videoColumns);
 
   const swapChainFormat = 'bgra8unorm';
   const swapChain = context.configureSwapChain({
@@ -131,18 +227,18 @@
     vertexState: {
       vertexBuffers: [
         {
-          arrayStride: 20,
+          arrayStride: 16,
           attributes: [
             {
               // position
               shaderLocation: 0,
               offset: 0,
-              format: 'float3',
+              format: 'float2',
             },
             {
               // uv
               shaderLocation: 1,
-              offset: 12,
+              offset: 8,
               format: 'float2',
             },
           ],
@@ -157,13 +253,22 @@
     ],
   });
 
+  const renderPassDescriptor = {
+    colorAttachments: [
+      {
+        attachment: undefined, // Assigned later
+        loadValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 },
+      },
+    ],
+  };
+
   const sampler = device.createSampler({
     magFilter: 'linear',
     minFilter: 'linear',
   });
 
   const videoTextures = [];
-  for (let i = 0; i < videoRows * videoColumns; ++i) {
+  for (let i = 0; i < videos.length; ++i) {
     videoTextures[i] = device.createTexture({
       size: {
         width: videos[i].videoWidth,
@@ -176,7 +281,7 @@
   }
 
   const bindGroups = [];
-  for (let i = 0; i < videoRows * videoColumns; ++i) {
+  for (let i = 0; i < videos.length; ++i) {
     bindGroups[i] = device.createBindGroup({
       layout: pipeline.getBindGroupLayout(0),
       entries: [
@@ -192,16 +297,50 @@
     });
   }
 
-  const drawOneFrame = () => {
-    const textureView = swapChain.getCurrentTexture().createView();
-    const renderPassDescriptor = {
-      colorAttachments: [
+  // For rendering the icons
+  const verticesBufferForIcons =
+    createVertexBufferForIcons(device, videos, videoRows, videoColumns);
+
+  const pipelineForIcons = device.createRenderPipeline({
+    vertexStage: {
+      module: device.createShaderModule({
+        code: wgslShaders.vertex_icons,
+      }),
+      entryPoint: 'main',
+    },
+    fragmentStage: {
+      module: device.createShaderModule({
+        code: wgslShaders.fragment_output_red,
+      }),
+      entryPoint: 'main',
+    },
+    primitiveTopology: 'triangle-list',
+    vertexState: {
+      vertexBuffers: [
         {
-          attachment: textureView,
-          loadValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 },
+          arrayStride: 8,
+          attributes: [
+            {
+              // position
+              shaderLocation: 0,
+              offset: 0,
+              format: 'float2',
+            },
+          ],
         },
       ],
-    };
+    },
+    colorStates: [
+      {
+        format: swapChainFormat,
+      },
+    ],
+  });
+
+  const oneFrame = () => {
+    renderPassDescriptor.colorAttachments[0].attachment = swapChain
+      .getCurrentTexture()
+      .createView();
 
     const commandEncoder = device.createCommandEncoder();
     const passEncoder =
@@ -211,26 +350,34 @@
 
     Promise.all(videos.map(video => createImageBitmap(video))).
       then((videoFrames) => {
-      for (let i = 0; i < videoRows * videoColumns; ++i) {
-        const firstVertex = i * 6;
-        device.queue.copyImageBitmapToTexture(
-          { imageBitmap: videoFrames[i], origin: { x: 0, y: 0 } },
-          { texture: videoTextures[i] },
-          { width: videos[i].videoWidth, height: videos[i].videoHeight, depth: 1 }
-        );
+        for (let i = 0; i < videos.length; ++i) {
+          device.queue.copyImageBitmapToTexture(
+            { imageBitmap: videoFrames[i], origin: { x: 0, y: 0 } },
+            { texture: videoTextures[i] },
+            { width: videos[i].videoWidth, height: videos[i].videoHeight, depth: 1 }
+          );
 
-        passEncoder.setBindGroup(0, bindGroups[i]);
-        passEncoder.draw(6, 1, firstVertex, 0);
-      }
-      passEncoder.endPass();
-      device.queue.submit([commandEncoder.finish()]);
+          const firstVertex = i * 6;
+          passEncoder.setBindGroup(0, bindGroups[i]);
+          passEncoder.draw(6, 1, firstVertex, 0);
+        }
 
-      window.requestAnimationFrame(drawOneFrame);
-    });
+        // Add UI on Top of (videoRows * videoColumns) videos.
+        if (addUI) {
+          passEncoder.setPipeline(pipelineForIcons);
+          passEncoder.setVertexBuffer(0, verticesBufferForIcons);
+          passEncoder.draw(videos.length * 6, 1, 0, 0);
+        }
+
+        passEncoder.endPass();
+        device.queue.submit([commandEncoder.finish()]);
+      });
   }
-  window.requestAnimationFrame(drawOneFrame);
+
+  setInterval(oneFrame, 143);
+
+  // TODO(magchen@): Render frames at different fps.
+  // 4 videos at 30 fps, oneFrame() should be called every 33 milliseconds.
+  // 12 videos at 30 fps, oneFrame() should be called 33 milliseconds.
+  // The rest at 7 fps, oneFrame() should be called 143 milliseconds.
 }
-
-
-
-
diff --git a/content/test/data/gpu/vc/webgpu_videos_mxn.html b/content/test/data/gpu/vc/webgpu_videos_mxn.html
index b9556085f..17c78ae 100644
--- a/content/test/data/gpu/vc/webgpu_videos_mxn.html
+++ b/content/test/data/gpu/vc/webgpu_videos_mxn.html
@@ -6,15 +6,27 @@
 <html>
 <head>
   <title>WebGpu MxN Video playbacks</title>
+  <style>
+    #message {
+      position: absolute;
+      width: 1600px;
+      height: 900px;
+      top: 200px;
+      left: 400px;
+    }
+  </style>
   <script type="text/javascript" src="webgpu_video.js"></script>
   <script>
     const _defaultRows = 7;
     const _defaultColumns = 7;
     const _totalVideoWidth = 1600;
     const _totalVideoHeight = 900;
+    var hasUIOnTop = true;
+    var useWebGpuForUI = true;
+    var useImportTextureApi = false;
 
-    const parseString = (function (names) {
-      var pairs = {};
+    const parsedString = (function (names) {
+      const pairs = {};
       for (let i = 0; i < names.length; ++i) {
         var keyValue = names[i].split('=', 2);
         if (keyValue.length == 1)
@@ -40,16 +52,11 @@
 
     async function startMxNVideos() {
       const container = document.getElementById('container');
+      const p = document.getElementById('message');
 
       // Initialize WebGpu
-      const gpuSetting = await webGpuInit();
+      const gpuSetting = await webGpuInit(_totalVideoWidth, _totalVideoHeight);
       if (!gpuSetting) {
-        var p = container.appendChild(document.createElement('p'));
-        p.style.position = "absolute";
-        p.style.top = 0;
-        p.style.left = 0;
-        p.style.width = _totalVideoWidth;
-        p.style.height = _totalVideoHeight;
         p.innerHTML = "Webgpu not supported!" + "<br />" + "<br />" +
           "Did you forget to add command line switch --enable-unsafe-webgpu ?" +
           "<br />" +
@@ -57,9 +64,18 @@
         return;
       }
 
+      // Get the UI rendering options from the string.
+      const uiOption = parsedString['ui'];
+      if (uiOption == 'none')
+        hasUIOnTop = false;
+      else if (uiOption == 'css')
+        useWebGpuForUI = false;
+      if (parsedString['import_texture_api'] == '1')
+        useImportTextureApi = true;
+
       // Get the number of video rows and columns from the string.
-      var videoRows = parseString['rows'];
-      var videoColumns = parseString['columns'];
+      var videoRows = parsedString['rows'];
+      var videoColumns = parsedString['columns'];
       if (videoRows == undefined)
         videoRows = _defaultRows;
       if (videoColumns == undefined)
@@ -69,26 +85,21 @@
       // The video will not load when the number is too big.
       const maxColRow = Math.max(videoRows, videoColumns);
       if (maxColRow > 20) {
-        var p = container.appendChild(document.createElement('p'));
-        p.style.position = "absolute";
-        p.style.top = 0;
-        p.style.left = 0;
-        p.style.width = _totalVideoWidth;
-        p.style.height = _totalVideoHeight;
         p.innerHTML = "Cannot support videos more than 20 x 20 !" + "<br />" +
           "Please change the number of rows/columns.";
         return;
       }
 
-      // Calculate the video size
+      // Calculate the video onscreen size
       const videoWidth = _totalVideoWidth / maxColRow;
       const videoHeight = _totalVideoHeight / maxColRow;
 
-      // Create MxN videos and TODO(magchen@)- a small video(size = 89x50) at
-      // the upper right corner to similate the one from the local camera.
+      // Create MxN videos and a small video (size = 89x50) at the upper right
+      // corner to similate the one from the local camera.
+      p.innerHTML = "Uploading videos...";
       var videos = [];
       const videoCount = videoRows * videoColumns;
-      for (let i = 0; i < videoCount; i++) {
+      for (let i = 0; i < videoCount + 1; i++) {
         const video = document.createElement('video');
         video.id = 'video_' + i;
         video.loop = true;
@@ -97,19 +108,54 @@
         video.src = GetVideoSource(videoCount, i);
         video.width = videoWidth;
         video.height = videoHeight;
-        await video.play();
+        video.crossorigin = "anonymous";
         videos.push(video);
       }
+      // For the small video.
+      videos[videoRows * videoColumns].width = 89;
+      videos[videoRows * videoColumns].height = 50;
 
-      webGpuDrawVideoFrames(gpuSetting, videos, videoRows, videoColumns);
+      await Promise.all(videos.map(video => video.play()));
+      p.innerHTML = "";
 
-      // TODO(magchen@): Add icons on top of video.
+      // Simulate video playback by WebGpu rendering.
+      webGpuDrawVideoFrames(gpuSetting, videos, videoRows, videoColumns,
+        hasUIOnTop && useWebGpuForUI, useImportTextureApi);
+
+      // Add CSS icons on top of videos if this is preferred.
+      if (hasUIOnTop && !useWebGpuForUI) {
+        for (let row = 0; row < videoRows; ++row) {
+          for (let column = 0; column < videoColumns; ++column) {
+            const video_top = row * videoHeight;
+            const video_left = column * videoWidth;
+            // Create an icon on top of each video.
+            createOneIcon(video_top, video_left, videoWidth, videoHeight);
+          }
+        }
+      }
+      // Create an icon for the samll video at the corner.
+      createOneIcon(0, _totalVideoWidth - 89, 89, 50);
     }
 
+    function createOneIcon(video_top, video_left, video_width, video_height) {
+      const icon = document.createElement('icon');
+      const icon_width = video_width / 10;
+      const icon_height = video_height / 10;
+
+      icon.style.backgroundColor = "red";
+      icon.style.position = "absolute";
+      icon.style.width = icon_width;
+      icon.style.height = icon_height;
+      icon.style.top = video_top + video_height - icon_height * 2;
+      icon.style.left = video_left + icon_width;
+
+      container.appendChild(icon);
+    }
   </script>
 </head>
 <body onload="startMxNVideos()">
   <div id="container" style="position:absolute; top:0px; left:0px">
+    <p id="message"></p>
   </div>
 </body>
 </html>
diff --git a/content/test/data/gpu/webgpu-import-video.html b/content/test/data/gpu/webgpu-import-video.html
index 570ab5a..77a77246 100644
--- a/content/test/data/gpu/webgpu-import-video.html
+++ b/content/test/data/gpu/webgpu-import-video.html
@@ -1,12 +1,20 @@
 <html>
   <body>
-    <canvas id="canvas" width=960 height=540></canvas>
+    <canvas id="canvas" width=960 height=1080></canvas>
     <script type="module">
         const video = document.createElement('video');
         video.src = './vc/teddy1_vp9_640x360_30fps.webm';
         video.loop = true;
         video.muted = true;
 
+        // Test with two videos. The original implementation had a bug
+        // where importing a second video would result in improper
+        // synchronization. The mailbox would be used before it was created.
+        const video2 = document.createElement('video');
+        video2.src = './vc/teddy2_vp9_320x180_15fps.webm';
+        video2.loop = true;
+        video2.muted = true;
+
         const adapter = navigator.gpu && await navigator.gpu.requestAdapter();
         const device = await adapter.requestDevice();
 
@@ -40,15 +48,14 @@
   );
   const uv : array<vec2<f32>, 6> = array<vec2<f32>, 6>(
     vec2<f32>(1.0, 0.0),
-    vec2<f32>(1.0, 1.0),
-    vec2<f32>(0.0, 1.0),
+    vec2<f32>(1.0, 2.0),
+    vec2<f32>(0.0, 2.0),
     vec2<f32>(1.0, 0.0),
-    vec2<f32>(0.0, 1.0),
+    vec2<f32>(0.0, 2.0),
     vec2<f32>(0.0, 0.0)
   );
   Position = vec4<f32>(pos[VertexIndex], 1.0);
   fragUV = uv[VertexIndex];
-  return;
 }
 `,
             }),
@@ -59,14 +66,19 @@
               code: `
 [[binding(0), group(0)]] var<uniform_constant> mySampler: sampler;
 [[binding(1), group(0)]] var<uniform_constant> myTexture: texture_2d<f32>;
+[[binding(2), group(0)]] var<uniform_constant> myTexture2: texture_2d<f32>;
 
 [[location(0)]] var<in> fragUV : vec2<f32>;
 [[location(0)]] var<out> outColor : vec4<f32>;
 
 [[stage(fragment)]]
 fn main() -> void {
-  outColor = textureSample(myTexture, mySampler, fragUV);
-  return;
+  if (fragUV.y <= 1.0) {
+    outColor = textureSample(myTexture, mySampler, fragUV);
+  } else {
+    var uv : vec2<f32> = vec2<f32>(fragUV.x, fragUV.y - 1.0);
+    outColor = textureSample(myTexture2, mySampler, uv);
+  }
 }
 `,
             }),
@@ -102,6 +114,9 @@
           const videoTexture = device.experimentalImportTexture(
             video, GPUTextureUsage.SAMPLED);
 
+          const videoTexture2 = device.experimentalImportTexture(
+            video2, GPUTextureUsage.SAMPLED);
+
           const bindGroup = device.createBindGroup({
             layout: pipeline.getBindGroupLayout(0),
             entries: [
@@ -113,6 +128,10 @@
                 binding: 1,
                 resource: videoTexture.createView(),
               },
+              {
+                binding: 2,
+                resource: videoTexture2.createView(),
+              },
             ],
           });
 
@@ -126,11 +145,13 @@
 
           // Destroy the texture after submit to promptly recycle resources.
           videoTexture.destroy();
+          videoTexture2.destroy();
 
           requestAnimationFrame(frame);
         }
 
         await video.play();
+        await video2.play();
         requestAnimationFrame(frame);
     </script>
   </body>
diff --git a/content/test/test_render_frame.cc b/content/test/test_render_frame.cc
index 9eb68ee..0529f0d 100644
--- a/content/test/test_render_frame.cc
+++ b/content/test/test_render_frame.cc
@@ -294,6 +294,7 @@
       std::move(common_params), std::move(commit_params),
       false /* has_stale_copy_in_cache */, error_code, resolve_error_info,
       error_page_content, std::move(pending_factory_bundle),
+      CreateStubPolicyContainer(),
       base::BindOnce(&MockFrameHost::DidCommitProvisionalLoad,
                      base::Unretained(mock_frame_host_.get())));
 }
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc
index 572796d8..d8056fe0 100644
--- a/content/test/test_render_frame_host.cc
+++ b/content/test/test_render_frame_host.cc
@@ -503,7 +503,8 @@
     int32_t error_code,
     const base::Optional<std::string>& error_page_content,
     std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
-        subresource_loader_factories) {
+        subresource_loader_factories,
+    blink::mojom::PolicyContainerPtr policy_container) {
   CHECK(navigation_client);
   commit_failed_callback_[navigation_request] =
       BuildCommitFailedNavigationCallback(navigation_request);
diff --git a/content/test/test_render_frame_host.h b/content/test/test_render_frame_host.h
index 632a1c8..2127fa1 100644
--- a/content/test/test_render_frame_host.h
+++ b/content/test/test_render_frame_host.h
@@ -232,7 +232,8 @@
       int32_t error_code,
       const base::Optional<std::string>& error_page_content,
       std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
-          subresource_loader_factories) override;
+          subresource_loader_factories,
+      blink::mojom::PolicyContainerPtr policy_container) override;
 
  private:
   void SendNavigateWithParameters(int nav_entry_id,
diff --git a/content/web_test/renderer/web_frame_test_proxy.cc b/content/web_test/renderer/web_frame_test_proxy.cc
index beabfcd..24f6951 100644
--- a/content/web_test/renderer/web_frame_test_proxy.cc
+++ b/content/web_test/renderer/web_frame_test_proxy.cc
@@ -768,6 +768,7 @@
 
 void WebFrameTestProxy::BindReceiver(
     mojo::PendingAssociatedReceiver<mojom::WebTestRenderFrame> receiver) {
+  web_test_render_frame_receiver_.reset();
   web_test_render_frame_receiver_.Bind(
       std::move(receiver),
       GetWebFrame()->GetTaskRunner(blink::TaskType::kInternalTest));
diff --git a/device/fido/cable/fido_tunnel_device.cc b/device/fido/cable/fido_tunnel_device.cc
index c76a042..bf631b2 100644
--- a/device/fido/cable/fido_tunnel_device.cc
+++ b/device/fido/cable/fido_tunnel_device.cc
@@ -103,12 +103,13 @@
   network_context->CreateWebSocket(
       url, {kCableWebSocketProtocol}, net::SiteForCookies(),
       net::IsolationInfo(), /*additional_headers=*/{},
-      network::mojom::kBrowserProcessId,
-      /*render_frame_id=*/0, url::Origin::Create(url),
+      network::mojom::kBrowserProcessId, url::Origin::Create(url),
       network::mojom::kWebSocketOptionBlockAllCookies,
       net::MutableNetworkTrafficAnnotationTag(kTrafficAnnotation),
-      websocket_client_->BindNewHandshakeClientPipe(), mojo::NullRemote(),
-      mojo::NullRemote());
+      websocket_client_->BindNewHandshakeClientPipe(),
+      /*auth_cert_observer=*/mojo::NullRemote(),
+      /*auth_handler=*/mojo::NullRemote(),
+      /*header_client=*/mojo::NullRemote());
 }
 
 FidoTunnelDevice::FidoTunnelDevice(
@@ -148,12 +149,13 @@
   network_context->CreateWebSocket(
       url, {kCableWebSocketProtocol}, net::SiteForCookies(),
       net::IsolationInfo(), std::move(headers),
-      network::mojom::kBrowserProcessId,
-      /*render_frame_id=*/0, url::Origin::Create(url),
+      network::mojom::kBrowserProcessId, url::Origin::Create(url),
       network::mojom::kWebSocketOptionBlockAllCookies,
       net::MutableNetworkTrafficAnnotationTag(kTrafficAnnotation),
-      websocket_client_->BindNewHandshakeClientPipe(), mojo::NullRemote(),
-      mojo::NullRemote());
+      websocket_client_->BindNewHandshakeClientPipe(),
+      /*auth_cert_observer=*/mojo::NullRemote(),
+      /*auth_handler=*/mojo::NullRemote(),
+      /*header_client=*/mojo::NullRemote());
 }
 
 FidoTunnelDevice::~FidoTunnelDevice() {
@@ -170,13 +172,6 @@
     return false;
   }
 
-  const eid::Components components = eid::ToComponents(*plaintext);
-  static_assert(EXTENT(components.routing_id) == 3, "");
-  if (components.routing_id[0] || components.routing_id[1] ||
-      components.routing_id[2]) {
-    return false;
-  }
-
   info.psk = Derive<EXTENT(*info.psk)>(info.secret, *plaintext,
                                        DerivedValueType::kPSK);
 
diff --git a/device/fido/cable/v2_authenticator.cc b/device/fido/cable/v2_authenticator.cc
index 2ca0bcd1..a5a2007 100644
--- a/device/fido/cable/v2_authenticator.cc
+++ b/device/fido/cable/v2_authenticator.cc
@@ -225,7 +225,6 @@
       base::span<const uint8_t, device::kP256X962Length> peer_identity,
       GeneratePairingDataCallback generate_pairing_data)
       : platform_(platform),
-        nonce_(RandomNonce()),
         tunnel_id_(device::cablev2::Derive<EXTENT(tunnel_id_)>(
             secret,
             base::span<uint8_t>(),
@@ -258,7 +257,6 @@
       base::span<const uint8_t, 16> tunnel_id,
       bssl::UniquePtr<EC_KEY> local_identity)
       : platform_(platform),
-        nonce_(RandomNonce()),
         tunnel_id_(fido_parsing_utils::Materialize(tunnel_id)),
         eid_key_(device::cablev2::Derive<EXTENT(eid_key_)>(
             secret,
@@ -290,12 +288,14 @@
 
     network_context_->CreateWebSocket(
         target_, {device::kCableWebSocketProtocol}, net::SiteForCookies(),
-        net::IsolationInfo(), /*headers=*/{}, network::mojom::kBrowserProcessId,
-        /*render_frame_id=*/0, url::Origin::Create(target_),
+        net::IsolationInfo(), /*additional_headers=*/{},
+        network::mojom::kBrowserProcessId, url::Origin::Create(target_),
         network::mojom::kWebSocketOptionBlockAllCookies,
         net::MutableNetworkTrafficAnnotationTag(kTrafficAnnotation),
-        websocket_client_->BindNewHandshakeClientPipe(), mojo::NullRemote(),
-        mojo::NullRemote());
+        websocket_client_->BindNewHandshakeClientPipe(),
+        /*auth_cert_observer=*/mojo::NullRemote(),
+        /*auth_handler=*/mojo::NullRemote(),
+        /*header_client=*/mojo::NullRemote());
     FIDO_LOG(DEBUG) << "Creating WebSocket to " << target_.spec();
   }
 
@@ -341,18 +341,26 @@
 
     FIDO_LOG(DEBUG) << "WebSocket connection established.";
 
+    CableEidArray plaintext_eid;
     if (state_ == State::kConnecting) {
+      const device::cablev2::eid::Components components{
+          .tunnel_server_domain = kTunnelServer,
+          .routing_id = *routing_id,
+          .nonce = RandomNonce(),
+      };
+      plaintext_eid = device::cablev2::eid::FromComponents(components);
       state_ = State::kConnected;
     } else {
       DCHECK_EQ(state_, State::kConnectingPaired);
+      crypto::RandBytes(plaintext_eid);
+      // The first byte is reserved to ensure that the format can be changed in
+      // the future.
+      plaintext_eid[0] = 0;
       state_ = State::kConnectedPaired;
     }
 
-    static constexpr std::array<uint8_t, device::cablev2::kRoutingIdSize>
-        kZeroRoutingID = {0, 0, 0};
-    const device::CableEidArray plaintext_eid =
-        StartAdvertising(routing_id.value_or(kZeroRoutingID));
-
+    ble_advert_ =
+        platform_->SendBLEAdvert(eid::Encrypt(plaintext_eid, eid_key_));
     psk_ = device::cablev2::Derive<EXTENT(psk_)>(
         secret_, plaintext_eid, device::cablev2::DerivedValueType::kPSK);
 
@@ -431,22 +439,8 @@
     }
   }
 
-  device::CableEidArray StartAdvertising(
-      std::array<uint8_t, device::cablev2::kRoutingIdSize> routing_id) {
-    const device::cablev2::eid::Components components{
-        .tunnel_server_domain = kTunnelServer,
-        .routing_id = routing_id,
-        .nonce = nonce_,
-    };
-    const device::CableEidArray eid =
-        device::cablev2::eid::FromComponents(components);
-    ble_advert_ = platform_->SendBLEAdvert(eid::Encrypt(eid, eid_key_));
-    return eid;
-  }
-
   Platform* const platform_;
   State state_ = State::kNone;
-  const std::array<uint8_t, kNonceSize> nonce_;
   const std::array<uint8_t, kTunnelIdSize> tunnel_id_;
   const std::array<uint8_t, kEIDKeySize> eid_key_;
   std::unique_ptr<WebSocketAdapter> websocket_client_;
diff --git a/device/fido/cable/v2_test_util.cc b/device/fido/cable/v2_test_util.cc
index c4731c7..b07212c 100644
--- a/device/fido/cable/v2_test_util.cc
+++ b/device/fido/cable/v2_test_util.cc
@@ -48,13 +48,15 @@
       const net::IsolationInfo& isolation_info,
       std::vector<network::mojom::HttpHeaderPtr> additional_headers,
       int32_t process_id,
-      int32_t render_frame_id,
       const url::Origin& origin,
       uint32_t options,
       const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
       mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
           handshake_client,
-      mojo::PendingRemote<network::mojom::AuthenticationHandler> auth_handler,
+      mojo::PendingRemote<network::mojom::AuthenticationAndCertificateObserver>
+          auth_cert_observer,
+      mojo::PendingRemote<network::mojom::WebSocketAuthenticationHandler>
+          auth_handler,
       mojo::PendingRemote<network::mojom::TrustedHeaderClient> header_client)
       override {
     CHECK(url.has_path());
diff --git a/device/vr/openxr/openxr_device.cc b/device/vr/openxr/openxr_device.cc
index 236f9b2e..198c55b 100644
--- a/device/vr/openxr/openxr_device.cc
+++ b/device/vr/openxr/openxr_device.cc
@@ -79,6 +79,13 @@
   if (render_loop_ && render_loop_->IsRunning()) {
     render_loop_->Stop();
   }
+
+  // request_session_callback_ may still be active if we're tearing down the
+  // OpenXrDevice while we're still making asynchronous calls to setup the GPU
+  // process connection. Ensure the callback is run regardless.
+  if (request_session_callback_) {
+    std::move(request_session_callback_).Run(nullptr, mojo::NullRemote());
+  }
 }
 
 mojo::PendingRemote<mojom::XRCompositorHost>
@@ -99,6 +106,8 @@
 void OpenXrDevice::RequestSession(
     mojom::XRRuntimeSessionOptionsPtr options,
     mojom::XRRuntime::RequestSessionCallback callback) {
+  DCHECK(!request_session_callback_);
+
   // Check feature support and reject session request if we cannot fulfil it
   // TODO(https://crbug.com/995377): Currently OpenXR features are declared
   // statically, but we may only know a runtime's true support for a feature
@@ -138,9 +147,8 @@
     }
   }
 
-  auto my_callback =
-      base::BindOnce(&OpenXrDevice::OnRequestSessionResult,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback));
+  auto my_callback = base::BindOnce(&OpenXrDevice::OnRequestSessionResult,
+                                    weak_ptr_factory_.GetWeakPtr());
 
   auto on_visibility_state_changed = base::BindRepeating(
       &OpenXrDevice::OnVisibilityStateChanged, weak_ptr_factory_.GetWeakPtr());
@@ -155,14 +163,17 @@
                                 base::DoNothing::Once(),
                                 std::move(on_visibility_state_changed),
                                 std::move(options), std::move(my_callback)));
+
+  request_session_callback_ = std::move(callback);
 }
 
 void OpenXrDevice::OnRequestSessionResult(
-    mojom::XRRuntime::RequestSessionCallback callback,
     bool result,
     mojom::XRSessionPtr session) {
+  DCHECK(request_session_callback_);
+
   if (!result) {
-    std::move(callback).Run(nullptr, mojo::NullRemote());
+    std::move(request_session_callback_).Run(nullptr, mojo::NullRemote());
     return;
   }
 
@@ -170,9 +181,9 @@
 
   session->display_info = display_info_.Clone();
 
-  std::move(callback).Run(
-      std::move(session),
-      exclusive_controller_receiver_.BindNewPipeAndPassRemote());
+  std::move(request_session_callback_)
+      .Run(std::move(session),
+           exclusive_controller_receiver_.BindNewPipeAndPassRemote());
 
   // Use of Unretained is safe because the callback will only occur if the
   // binding is not destroyed.
diff --git a/device/vr/openxr/openxr_device.h b/device/vr/openxr/openxr_device.h
index f81111e..eb0fff4 100644
--- a/device/vr/openxr/openxr_device.h
+++ b/device/vr/openxr/openxr_device.h
@@ -50,9 +50,7 @@
 
   void EnsureRenderLoop();
 
-  void OnRequestSessionResult(mojom::XRRuntime::RequestSessionCallback callback,
-                              bool result,
-                              mojom::XRSessionPtr session);
+  void OnRequestSessionResult(bool result, mojom::XRSessionPtr session);
   void OnPresentingControllerMojoConnectionError();
   bool IsArBlendModeSupported(OpenXrStatics* openxr_statics);
 
@@ -68,6 +66,8 @@
 
   VizContextProviderFactoryAsync context_provider_factory_async_;
 
+  mojom::XRRuntime::RequestSessionCallback request_session_callback_;
+
   base::WeakPtrFactory<OpenXrDevice> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(OpenXrDevice);
diff --git a/device/vr/openxr/openxr_render_loop.cc b/device/vr/openxr/openxr_render_loop.cc
index cb28d1f..737de2f9 100644
--- a/device/vr/openxr/openxr_render_loop.cc
+++ b/device/vr/openxr/openxr_render_loop.cc
@@ -108,7 +108,13 @@
   return frame_data;
 }
 
-bool OpenXrRenderLoop::StartRuntime() {
+// StartRuntime is called by XRCompositorCommon::RequestSession. When the
+// runtime is fully started, start_runtime_callback.Run must be called with a
+// success boolean, or false on failure. OpenXrRenderLoop::StartRuntime waits
+// until the Viz context provider is fully started before running
+// start_runtime_callback.
+void OpenXrRenderLoop::StartRuntime(
+    StartRuntimeCallback start_runtime_callback) {
   DCHECK(instance_ != XR_NULL_HANDLE);
   DCHECK(!openxr_);
   DCHECK(!input_helper_);
@@ -121,7 +127,7 @@
   std::unique_ptr<OpenXrApiWrapper> openxr =
       OpenXrApiWrapper::Create(instance_);
   if (!openxr)
-    return false;
+    return std::move(start_runtime_callback).Run(false);
 
   texture_helper_.SetUseBGRA(true);
   LUID luid;
@@ -131,7 +137,7 @@
       XR_FAILED(openxr->InitSession(texture_helper_.GetDevice(), &input_helper_,
                                     extension_helper_))) {
     texture_helper_.Reset();
-    return false;
+    return std::move(start_runtime_callback).Run(false);
   }
 
   // Starting session succeeded so we can set the member variable.
@@ -148,12 +154,7 @@
       &OpenXrRenderLoop::ExitPresent, weak_ptr_factory_.GetWeakPtr()));
   InitializeDisplayInfo();
 
-  // TODO(https://crbug.com/1131616): In a subsequent change, refactor
-  // StartContextProviderIfNeeded such that we do not start the session until
-  // the context provider has been created.
-  StartContextProviderIfNeeded();
-
-  return true;
+  StartContextProviderIfNeeded(std::move(start_runtime_callback));
 }
 
 void OpenXrRenderLoop::StopRuntime() {
@@ -165,6 +166,7 @@
   openxr_ = nullptr;
   current_display_info_ = nullptr;
   texture_helper_.Reset();
+  context_provider_.reset();
 }
 
 void OpenXrRenderLoop::EnableSupportedFeatures(
@@ -475,17 +477,22 @@
   anchor_manager->DetachAnchor(AnchorId(anchor_id));
 }
 
-void OpenXrRenderLoop::StartContextProviderIfNeeded() {
+void OpenXrRenderLoop::StartContextProviderIfNeeded(
+    StartRuntimeCallback start_runtime_callback) {
   DCHECK(task_runner()->BelongsToCurrentThread());
-  // We could arrive here in scenarios where we've shutdown the render loop.
-  // In that case, there is no need to start the context provider.
-  if (!context_provider_ && !HasSessionEnded()) {
+  DCHECK_EQ(context_provider_, nullptr);
+  // We could arrive here in scenarios where we've shutdown the render loop or
+  // runtime. In that case, there is no need to start the context provider.
+  // If openxr_ has been torn down the context provider is unnecessary as
+  // there is nothing to connect to the GPU process.
+  if (openxr_) {
     main_thread_task_runner_->PostTask(
         FROM_HERE,
         base::BindOnce(
             context_provider_factory_async_,
             base::BindOnce(&OpenXrRenderLoop::OnContextProviderCreated,
-                           weak_ptr_factory_.GetWeakPtr()),
+                           weak_ptr_factory_.GetWeakPtr(),
+                           std::move(start_runtime_callback)),
             task_runner()));
   }
 }
@@ -511,22 +518,30 @@
                                 std::move(context_provider_)));
 }
 
-// Called on the render loop thread as a continuation of OnContextLost
+// Called on the render loop thread as a continuation of OnContextLost.
 void OpenXrRenderLoop::OnContextLostCallback(
-    scoped_refptr<viz::ContextProvider> context_provider) {
+    scoped_refptr<viz::ContextProvider> lost_context_provider) {
   DCHECK(task_runner()->BelongsToCurrentThread());
   DCHECK_EQ(context_provider_, nullptr);
 
-  // context_provider is required to be released on the context thread it was
-  // bound to.
-  context_provider.reset();
+  // Context providers are required to be released on the context thread they
+  // were bound to.
+  lost_context_provider.reset();
 
-  StartContextProviderIfNeeded();
+  StartContextProviderIfNeeded(base::DoNothing());
 }
 
-// Called on the render loop thread by IsolatedXRRuntimeProvider when it has
-// finished creating the context provider.
+// OpenXrRenderLoop::StartContextProvider queues a task on the main thread's
+// task runner to run IsolatedXRRuntimeProvider::CreateContextProviderAsync.
+// When CreateContextProviderAsync finishes creating the Viz context provider,
+// it will queue a task onto the render loop's task runner to run
+// OnContextProviderCreated, passing it the newly created context provider.
+// StartContextProvider uses BindOnce to passthrough the start_runtime_callback
+// given to it from it's caller OnContextProviderCreated must run the
+// start_runtime_callback, passing true on successful call to
+// BindToCurrentThread and false if not.
 void OpenXrRenderLoop::OnContextProviderCreated(
+    StartRuntimeCallback start_runtime_callback,
     scoped_refptr<viz::ContextProvider> context_provider) {
   DCHECK(task_runner()->BelongsToCurrentThread());
   DCHECK_EQ(context_provider_, nullptr);
@@ -534,13 +549,14 @@
   const gpu::ContextResult context_result =
       context_provider->BindToCurrentThread();
   if (context_result != gpu::ContextResult::kSuccess) {
-    // TODO(https://crbug.com/1131616): Handle this by creating the context
-    // provider again.
+    std::move(start_runtime_callback).Run(false);
     return;
   }
 
   context_provider->AddObserver(this);
   context_provider_ = std::move(context_provider);
+
+  std::move(start_runtime_callback).Run(true);
 }
 
 }  // namespace device
diff --git a/device/vr/openxr/openxr_render_loop.h b/device/vr/openxr/openxr_render_loop.h
index 724fe21..b59d295 100644
--- a/device/vr/openxr/openxr_render_loop.h
+++ b/device/vr/openxr/openxr_render_loop.h
@@ -51,7 +51,7 @@
 
   // XRDeviceAbstraction:
   mojom::XRFrameDataPtr GetNextFrameData() override;
-  bool StartRuntime() override;
+  void StartRuntime(StartRuntimeCallback start_runtime_callback) override;
   void StopRuntime() override;
   void OnSessionStart() override;
   bool HasSessionEnded() override;
@@ -126,9 +126,10 @@
       const mojom::XRNativeOriginInformation& native_origin_information,
       const gfx::Transform& native_origin_from_anchor) const;
 
-  // viz::ContextLostObserver
-  void StartContextProviderIfNeeded();
+  void StartContextProviderIfNeeded(
+      StartRuntimeCallback start_runtime_callback);
   void OnContextProviderCreated(
+      StartRuntimeCallback start_runtime_callback,
       scoped_refptr<viz::ContextProvider> context_provider);
   void OnContextLostCallback(
       scoped_refptr<viz::ContextProvider> context_provider);
diff --git a/device/vr/windows/compositor_base.cc b/device/vr/windows/compositor_base.cc
index 1d86421..6ef8f6a4 100644
--- a/device/vr/windows/compositor_base.cc
+++ b/device/vr/windows/compositor_base.cc
@@ -206,7 +206,25 @@
   EnableSupportedFeatures(options->required_features,
                           options->optional_features);
 
-  if (!StartRuntime()) {
+  // Call the subclass's StartRuntime method. Upon completion, StartRuntime will
+  // call the callback passed to its first parameter, start_runtime_callback.
+  // XRCompositorCommon::StartRuntimeFinish. We setup BindOnce such that all of
+  // the parameters give to us here in XRCompositorCommon::RequestSession are
+  // passed through to StartRuntimeFinish so that it can finish the job.
+  StartRuntime(base::BindOnce(
+      &XRCompositorCommon::StartRuntimeFinish, base::Unretained(this),
+      std::move(on_presentation_ended), std::move(on_visibility_state_changed),
+      std::move(options), std::move(callback)));
+}
+
+void XRCompositorCommon::StartRuntimeFinish(
+    base::OnceCallback<void()> on_presentation_ended,
+    base::RepeatingCallback<void(mojom::XRVisibilityState)>
+        on_visibility_state_changed,
+    mojom::XRRuntimeSessionOptionsPtr options,
+    RequestSessionCallback callback,
+    bool success) {
+  if (!success) {
     TRACE_EVENT_INSTANT0("xr", "Failed to start runtime",
                          TRACE_EVENT_SCOPE_THREAD);
     main_thread_task_runner_->PostTask(
diff --git a/device/vr/windows/compositor_base.h b/device/vr/windows/compositor_base.h
index 76df031..50ac38d5 100644
--- a/device/vr/windows/compositor_base.h
+++ b/device/vr/windows/compositor_base.h
@@ -31,7 +31,9 @@
 class XRDeviceAbstraction {
  public:
   virtual mojom::XRFrameDataPtr GetNextFrameData();
-  virtual bool StartRuntime() = 0;
+
+  using StartRuntimeCallback = base::OnceCallback<void(bool success)>;
+  virtual void StartRuntime(StartRuntimeCallback start_runtime_callback) = 0;
   virtual void StopRuntime() = 0;
   virtual void OnSessionStart();
   virtual bool HasSessionEnded();
@@ -113,6 +115,14 @@
   void ClearPendingFrame();
   void StartPendingFrame();
 
+  void StartRuntimeFinish(
+      base::OnceCallback<void()> on_presentation_ended,
+      base::RepeatingCallback<void(mojom::XRVisibilityState)>
+          on_visibility_state_changed,
+      mojom::XRRuntimeSessionOptionsPtr options,
+      RequestSessionCallback callback,
+      bool success);
+
   // Will Submit if we have textures submitted from the Overlay (if it is
   // visible), and WebXR (if it is visible).  We decide what to wait for during
   // StartPendingFrame, may mark things as ready after SubmitFrameMissing and
diff --git a/docs/android_dynamic_feature_modules.md b/docs/android_dynamic_feature_modules.md
index 7bdf050..af97751 100644
--- a/docs/android_dynamic_feature_modules.md
+++ b/docs/android_dynamic_feature_modules.md
@@ -14,9 +14,6 @@
 
 * **WebView:** We don't support DFMs for WebView. If your feature is used by
   WebView you cannot put it into a DFM.
-* **Android K:** DFMs are based on split APKs, a feature introduced in Android
-  L. Therefore, we don't support DFMs on Android K. As a workaround
-  you can add your feature to the Android K APK build. See below for details.
 
 ## Getting started
 
@@ -29,6 +26,13 @@
 `YOUR_FEATURE_NAME`.
 ***
 
+*** note
+**Note:** Chrome's bundles use the [android:isolatedSplits](https://developer.android.com/reference/android/R.attr#isolatedSplits)
+attribute. For more details and advice on when to create a DFM, see
+[go/isolated-splits-dev-guide](http://go/isolated-splits-dev-guide)
+**(Googlers only)**.
+***
+
 ### Reference DFM
 
 In addition to this guide, the
diff --git a/docs/code_reviews.md b/docs/code_reviews.md
index 6353a18..3f18122 100644
--- a/docs/code_reviews.md
+++ b/docs/code_reviews.md
@@ -166,108 +166,35 @@
 per-file *_messages*.h=file://ipc/SECURITY_OWNERS
 ```
 
-## TBR ("To Be Reviewed")
+### Owners-Override
 
-"TBR" is our mechanism for post-commit review. It should be used rarely and
-only in cases where a normal review is unnecessary, as described under
-"When to TBR", below.
+Setting the `Owners-Override` label will bypass OWNERS enforcement. Active
+sheriffs and Large Scale Changes (see below) reviewers have this power.
 
-TBR does not mean "no review." A reviewer TBR-ed on a change should still
-review the change. If there are comments after landing, the author is obligated
-to address them in a followup patch.
+## Mechanical changes
 
-Do not use TBR just because a change is urgent or the reviewer is being slow.
-Contact the reviewer directly or find somebody else to review your change.
+You can use the [Large Scale Changes](process/lsc/large_scale_changes.md)
+process to get approval to bypass OWNERS enforcement for large changes like
+refactoring, architectural changes, or other repetitive code changes across the
+whole codebase.
 
-### How to TBR
+## Documentation updates
 
-To send a change TBR, annotate the description and send email like normal.
-Otherwise the reviewer won't know to review the patch.
+Documentation updates require code review. We may revisit this decision in the
+future.
 
-  * Add the reviewer's email address in the code review tool's reviewer field
-    like normal.
+## Automated code-review
 
-  * Add a line "Tbr: <reviewer's email>" to the bottom of the change list
-    description. e.g. `Tbr: reviewer1@chromium.org,reviewer2@chromium.org`
+For verifiably safe changes like translation files, clean reverts, and clean
+cherry-picks, we have automation that will vote +1 on the `Bot-Commit` label
+allowing the CL to be submitted without human code-review. Add `Rubber Stamper`
+(rubber-stamper@appspot.gserviceaccount.com) to your CL as a reviewer to
+activate this automation. It will scan the CL after about 1 minute and reply
+with its verdict. `Bot-Commit` votes are not sticky between patchsets and so
+only add the bot once the CL is finalized.
 
-  * Type a message so that the owners in the TBR list can understand who is
-    responsible for reviewing what, as part of their post-commit review
-    responsibility. e.g.
-    ```
-    TBRing reviewers:
-    reviewer1: Please review changes to foo/
-    reviewer2: Please review changes to bar/
-    ```
+When combined with the [`Owners-Override`](#owners_override) power discussed
+above, sheriffs can effectively revert and reland on their own.
 
-### When to TBR
-
-#### Reverts and relands
-
-The most common use of TBR is to revert patches that broke the build. Clean
-reverts of recent patches may be submitted TBR. However, TBR should not be used
-if the revert required non-trivial conflict resolution, or if the patch being
-reverted is older than a few days.
-
-A developer relanding a patch can TBR the OWNERS for changes which are identical
-to the original (reverted) patch.  If the reland patch contains any new changes
-(such as bug fixes) on top of the original, those changes should go through the
-normal review process.
-
-When creating a reland patch, you should first upload an up-to-date patchset
-with the exact content of the original (reverted) patch, and then upload the
-patchset to be relanded. This is important for the reviewers to understand what
-the fix for relanding was.
-
-#### Mechanical changes
-
-You can use TBR with certain mechanical changes that affect many callers in
-different directories. For example, adding a parameter to a common function in
-`//base`, with callers in `//chrome/browser/foo`, `//net/bar`, and many other
-directories. If the updates to the callers is mechanical, you can:
-
-  1. Get a normal owner of the lower-level code you're changing (in this
-     example, the function in `//base`) to do a proper review of those changes.
-
-  2. Get _somebody_ to review the downstream changes made to the callers as a
-     result of the `//base` change. This is often the same person from the
-     previous step but could be somebody else.
-
-  3. TBR the owners of the calling code, after the API change is LGTM'ed.
-
-This process ensures that all code is reviewed prior to checkin and that the
-concept of the change is reviewed by a qualified person, without having to ping
-many owners with little say in the trivial side-effects they incur.
-
-**Note:** The above policy is only viable for strictly mechanical changes. For
-large-scale scripted changes you should:
-
-  1. Have an owner of the core change review the script.
-
-  2. Use `git cl split` to shard the large change into many small CLs with a
-     clear description of what each reviewer is expected to verify
-     ([example](https://chromium-review.googlesource.com/1191225)).
-
-#### Documentation updates
-
-You can TBR documentation updates. Documentation means markdown files, text
-documents, and high-level comments in code. At finer levels of detail, comments
-in source files become more like code and should be reviewed normally (not
-using TBR). Non-TBR-able stuff includes things like function contracts and most
-comments inside functions.
-
-  * Use good judgement. If you're changing something very important, tricky,
-    or something you may not be very familiar with, ask for the code review
-    up-front.
-
-  * Don't TBR changes to policy documents like the style guide or this document.
-
-  * Don't mix unrelated documentation updates with code changes.
-
-  * Be sure to actually send out the email for the code review. If you get one,
-    please actually read the changes.
-
-## Automated code-review workflows
-
-For verifiably safe changes like translation files, we have automation that
-will vote +1 on the `Bot-Commit` and `Owners-Override` labels, allowing the
-CL to be submitted without human code-review.
+Changes not supported by Rubber Stamper still need a +1 from another
+committer.
diff --git a/docs/sheriff.md b/docs/sheriff.md
index d804d0c0..44d1a902 100644
--- a/docs/sheriff.md
+++ b/docs/sheriff.md
@@ -20,8 +20,14 @@
 
 * Revert changes that you know or suspect are causing breakages
 * Disable or otherwise mark misbehaving tests
-* Use TBRs freely as part of your sheriffing duties
+* Use Owners-Override label to override OWNERS checks freely as part of your
+  sheriffing duties
 * Pull in any other engineer or team you need to help you do these duties
+* For clean reverts and cherry-picks, add the
+  [Rubber Stamper bot](code_reviews.md#automated-code_review). All other
+  changes require a +1 from another committer.
+
+TBRs were removed in Q1 2021.
 
 ## How to be a Sheriff
 
diff --git a/docs/speed/perf_lab_platforms.md b/docs/speed/perf_lab_platforms.md
index 1b8c406..6d563af 100644
--- a/docs/speed/perf_lab_platforms.md
+++ b/docs/speed/perf_lab_platforms.md
@@ -21,6 +21,7 @@
 ## Linux
 
  * [linux-perf](https://ci.chromium.org/p/chrome/builders/ci/linux-perf): Ubuntu-14.04, 8 core, NVIDIA Quadro P400.
+ * [linux-perf-rel](https://ci.chromium.org/p/chrome/builders/ci/linux-perf-rel): Ubuntu-14.04, 8 core, NVIDIA Quadro P400.
 
 ## Mac
 
diff --git a/docs/webui_explainer.md b/docs/webui_explainer.md
index 3b84308..df98e41 100644
--- a/docs/webui_explainer.md
+++ b/docs/webui_explainer.md
@@ -361,11 +361,11 @@
 common configuration tasks.
 
 <a name="AddLocalizedStringsBulk"></a>
-### webui::AddLocalizedStringsBulk()
+### WebUIDataSource::AddLocalizedStrings()
 
 Many Web UI data sources need to be set up with a large number of localized
 strings. Instead of repeatedly calling <code>AddLocalizedString()</code>, create
-an array of all the strings and use <code>AddLocalizedStringsBulk()</code>:
+an array of all the strings and use <code>AddLocalizedStrings()</code>:
 
 ```c++
   static constexpr webui::LocalizedString kStrings[] = {
@@ -374,7 +374,7 @@
       {"ariaRoleDescription", IDS_HISTORY_ARIA_ROLE_DESCRIPTION},
       {"bookmarked", IDS_HISTORY_ENTRY_BOOKMARKED},
   };
-  AddLocalizedStringsBulk(source, kStrings);
+  source->AddLocalizedStrings(kStrings);
 ```
 
 <a name="AddResourcePathsBulk"></a>
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn
index 4ff00422..81dbdfe 100644
--- a/extensions/browser/BUILD.gn
+++ b/extensions/browser/BUILD.gn
@@ -37,6 +37,7 @@
     "//extensions/browser:browser_sources",
     "//extensions/browser/api",
     "//extensions/browser/api:api_implementations",
+    "//extensions/browser/updater",
   ]
 }
 
@@ -352,8 +353,6 @@
     "task_queue_util.h",
     "ui_util.cc",
     "ui_util.h",
-    "uninstall_ping_sender.cc",
-    "uninstall_ping_sender.h",
     "uninstall_reason.h",
     "unloaded_extension_reason.h",
     "update_observer.h",
@@ -430,7 +429,6 @@
     "//content/public/common",
     "//extensions/browser/install",
     "//extensions/browser/kiosk",
-    "//extensions/browser/updater",
     "//extensions/browser/value_store",
     "//ipc",
   ]
diff --git a/extensions/browser/api/BUILD.gn b/extensions/browser/api/BUILD.gn
index 4d60f90..8d5579ea 100644
--- a/extensions/browser/api/BUILD.gn
+++ b/extensions/browser/api/BUILD.gn
@@ -72,12 +72,6 @@
     "//extensions/browser/api/power",
     "//extensions/browser/api/printer_provider",
     "//extensions/browser/api/runtime",
-    "//extensions/browser/api/system_cpu",
-    "//extensions/browser/api/system_display",
-    "//extensions/browser/api/system_info",
-    "//extensions/browser/api/system_memory",
-    "//extensions/browser/api/system_network",
-    "//extensions/browser/api/system_storage",
     "//extensions/browser/api/test",
     "//extensions/browser/api/usb",
     "//extensions/browser/api/virtual_keyboard_private:virtual_keyboard_delegate",
diff --git a/extensions/browser/api/system_cpu/BUILD.gn b/extensions/browser/api/system_cpu/BUILD.gn
index ded77971..a6e6304 100644
--- a/extensions/browser/api/system_cpu/BUILD.gn
+++ b/extensions/browser/api/system_cpu/BUILD.gn
@@ -18,6 +18,7 @@
 
   deps = [
     "//build:chromeos_buildflags",
+    "//extensions/browser/api/system_info",
     "//extensions/common/api",
   ]
 
diff --git a/extensions/browser/api/system_display/BUILD.gn b/extensions/browser/api/system_display/BUILD.gn
index 0457828f..d4b6a73 100644
--- a/extensions/browser/api/system_display/BUILD.gn
+++ b/extensions/browser/api/system_display/BUILD.gn
@@ -18,6 +18,8 @@
   deps = [
     "//build:chromeos_buildflags",
     "//content/public/browser",
+    "//extensions/browser/api",
+    "//extensions/common",
     "//extensions/common/api",
   ]
 
diff --git a/extensions/browser/api/system_info/BUILD.gn b/extensions/browser/api/system_info/BUILD.gn
index c3eacc5..fca98bb0 100644
--- a/extensions/browser/api/system_info/BUILD.gn
+++ b/extensions/browser/api/system_info/BUILD.gn
@@ -15,7 +15,12 @@
     "system_info_provider.h",
   ]
 
-  deps = [ "//extensions/common/api" ]
+  deps = [
+    "//components/storage_monitor",
+    "//content/public/browser",
+    "//extensions/browser/api/system_display",
+    "//extensions/common/api",
+  ]
 
   public_deps = [ "//extensions/browser:browser_sources" ]
 }
diff --git a/extensions/browser/api/system_memory/BUILD.gn b/extensions/browser/api/system_memory/BUILD.gn
index 6f2e35e8..5b71a4f 100644
--- a/extensions/browser/api/system_memory/BUILD.gn
+++ b/extensions/browser/api/system_memory/BUILD.gn
@@ -15,7 +15,10 @@
     "system_memory_api.h",
   ]
 
-  deps = [ "//extensions/common/api" ]
+  deps = [
+    "//extensions/browser/api/system_info",
+    "//extensions/common/api",
+  ]
 
   public_deps = [ "//extensions/browser:browser_sources" ]
 }
diff --git a/extensions/browser/api/system_network/BUILD.gn b/extensions/browser/api/system_network/BUILD.gn
index 95671ea7..bf3e36f6 100644
--- a/extensions/browser/api/system_network/BUILD.gn
+++ b/extensions/browser/api/system_network/BUILD.gn
@@ -13,7 +13,10 @@
     "system_network_api.h",
   ]
 
-  deps = [ "//extensions/common/api" ]
+  deps = [
+    "//content/public/browser",
+    "//extensions/common/api",
+  ]
 
   public_deps = [ "//extensions/browser:browser_sources" ]
 }
diff --git a/extensions/browser/api/system_storage/BUILD.gn b/extensions/browser/api/system_storage/BUILD.gn
index 03957f7..16fbf02 100644
--- a/extensions/browser/api/system_storage/BUILD.gn
+++ b/extensions/browser/api/system_storage/BUILD.gn
@@ -15,7 +15,12 @@
     "system_storage_api.h",
   ]
 
-  deps = [ "//extensions/common/api" ]
+  deps = [
+    "//components/storage_monitor",
+    "//content/public/browser",
+    "//extensions/browser/api/system_info",
+    "//extensions/common/api",
+  ]
 
   public_deps = [ "//extensions/browser:browser_sources" ]
 }
diff --git a/extensions/browser/api/web_request/web_request_event_details.cc b/extensions/browser/api/web_request/web_request_event_details.cc
index 288f998..ec84376 100644
--- a/extensions/browser/api/web_request/web_request_event_details.cc
+++ b/extensions/browser/api/web_request/web_request_event_details.cc
@@ -162,7 +162,7 @@
     result->SetKey(keys::kResponseHeadersKey, std::move(response_headers));
   }
 
-  // Only listeners with a permission for the initiator should recieve it.
+  // Only listeners with a permission for the initiator should receive it.
   if (initiator_) {
     int tab_id = -1;
     dict_.GetInteger(keys::kTabIdKey, &tab_id);
diff --git a/extensions/browser/api/web_request/web_request_proxying_websocket.h b/extensions/browser/api/web_request/web_request_proxying_websocket.h
index 3d81d75..609f2de 100644
--- a/extensions/browser/api/web_request/web_request_proxying_websocket.h
+++ b/extensions/browser/api/web_request/web_request_proxying_websocket.h
@@ -38,7 +38,7 @@
 class WebRequestProxyingWebSocket
     : public WebRequestAPI::Proxy,
       public network::mojom::WebSocketHandshakeClient,
-      public network::mojom::AuthenticationHandler,
+      public network::mojom::WebSocketAuthenticationHandler,
       public network::mojom::TrustedHeaderClient {
  public:
   using WebSocketFactory = content::ContentBrowserClient::WebSocketFactory;
@@ -70,7 +70,7 @@
       mojo::ScopedDataPipeConsumerHandle readable,
       mojo::ScopedDataPipeProducerHandle writable) override;
 
-  // network::mojom::AuthenticationHandler method:
+  // network::mojom::WebSocketAuthenticationHandler method:
   void OnAuthRequired(const net::AuthChallengeInfo& auth_info,
                       const scoped_refptr<net::HttpResponseHeaders>& headers,
                       const net::IPEndPoint& remote_endpoint,
@@ -130,7 +130,7 @@
       forwarding_handshake_client_;
   mojo::Receiver<network::mojom::WebSocketHandshakeClient>
       receiver_as_handshake_client_{this};
-  mojo::Receiver<network::mojom::AuthenticationHandler>
+  mojo::Receiver<network::mojom::WebSocketAuthenticationHandler>
       receiver_as_auth_handler_{this};
   mojo::Receiver<network::mojom::TrustedHeaderClient>
       receiver_as_header_client_{this};
diff --git a/extensions/browser/app_window/app_delegate.h b/extensions/browser/app_window/app_delegate.h
index 7b504823..2685e9d1 100644
--- a/extensions/browser/app_window/app_delegate.h
+++ b/extensions/browser/app_window/app_delegate.h
@@ -23,7 +23,6 @@
 class ColorChooser;
 class FileSelectListener;
 class RenderFrameHost;
-class RenderViewHost;
 class WebContents;
 struct OpenURLParams;
 }
@@ -49,7 +48,7 @@
 
   // General initialization.
   virtual void InitWebContents(content::WebContents* web_contents) = 0;
-  virtual void RenderViewCreated(content::RenderViewHost* render_view_host) = 0;
+  virtual void RenderFrameCreated(content::RenderFrameHost* frame_host) = 0;
 
   // Resizes WebContents.
   virtual void ResizeWebContents(content::WebContents* web_contents,
diff --git a/extensions/browser/app_window/app_window.cc b/extensions/browser/app_window/app_window.cc
index c61355e..7971ea1 100644
--- a/extensions/browser/app_window/app_window.cc
+++ b/extensions/browser/app_window/app_window.cc
@@ -464,8 +464,8 @@
   return handled;
 }
 
-void AppWindow::RenderViewCreated(content::RenderViewHost* render_view_host) {
-  app_delegate_->RenderViewCreated(render_view_host);
+void AppWindow::RenderFrameCreated(content::RenderFrameHost* frame_host) {
+  app_delegate_->RenderFrameCreated(frame_host);
 }
 
 void AppWindow::AddOnDidFinishFirstNavigationCallback(
diff --git a/extensions/browser/app_window/app_window.h b/extensions/browser/app_window/app_window.h
index 36f9a05..ec1e74aa 100644
--- a/extensions/browser/app_window/app_window.h
+++ b/extensions/browser/app_window/app_window.h
@@ -453,7 +453,7 @@
   // content::WebContentsObserver implementation.
   bool OnMessageReceived(const IPC::Message& message,
                          content::RenderFrameHost* render_frame_host) override;
-  void RenderViewCreated(content::RenderViewHost* render_view_host) override;
+  void RenderFrameCreated(content::RenderFrameHost* frame_host) override;
 
   // ExtensionFunctionDispatcher::Delegate implementation.
   WindowController* GetExtensionWindowController() const override;
diff --git a/extensions/browser/install/sandboxed_unpacker_failure_reason.h b/extensions/browser/install/sandboxed_unpacker_failure_reason.h
index d122e22..8c280c8 100644
--- a/extensions/browser/install/sandboxed_unpacker_failure_reason.h
+++ b/extensions/browser/install/sandboxed_unpacker_failure_reason.h
@@ -8,7 +8,9 @@
 namespace extensions {
 
 // Enumerate all the ways SandboxedUnpacker can fail.
-// Don't change the order or change the value of the enums.
+// Note: enum used for UMA. Do NOT reorder or remove entries. Don't forget to
+// update enums.xml (name: ExtensionUnpackFailureReason) when adding new
+// entries.
 // Don't forget to update device_management_backend.proto (name:
 // ExtensionInstallReportLogEvent::SandboxedUnpackerFailureReason) when adding
 // new entries. Don't forget to update ConvertUnpackerFailureReasonToProto
diff --git a/extensions/browser/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc
index b606681..aee6928 100644
--- a/extensions/browser/sandboxed_unpacker.cc
+++ b/extensions/browser/sandboxed_unpacker.cc
@@ -876,7 +876,7 @@
   DCHECK(unpacker_io_task_runner_->RunsTasksInCurrentSequence());
 
   UMA_HISTOGRAM_ENUMERATION(
-      "Extensions.SandboxUnpackFailureReason", reason,
+      "Extensions.SandboxUnpackFailureReason2", reason,
       SandboxedUnpackerFailureReason::NUM_FAILURE_REASONS);
   Cleanup();
 
diff --git a/extensions/browser/uninstall_ping_sender.cc b/extensions/browser/uninstall_ping_sender.cc
deleted file mode 100644
index 6442557c..0000000
--- a/extensions/browser/uninstall_ping_sender.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "extensions/browser/uninstall_ping_sender.h"
-
-#include "base/version.h"
-#include "extensions/browser/updater/update_service.h"
-
-namespace extensions {
-
-UninstallPingSender::UninstallPingSender(ExtensionRegistry* registry,
-                                         Filter filter)
-    : filter_(std::move(filter)) {
-  observer_.Add(registry);
-}
-
-UninstallPingSender::~UninstallPingSender() {}
-
-void UninstallPingSender::OnExtensionUninstalled(
-    content::BrowserContext* browser_context,
-    const Extension* extension,
-    UninstallReason reason) {
-  if (filter_.Run(extension, reason) == SEND_PING) {
-    UpdateService* updater = UpdateService::Get(browser_context);
-    updater->SendUninstallPing(extension->id(), extension->version(), reason);
-  }
-}
-
-}  // namespace extensions
diff --git a/extensions/browser/uninstall_ping_sender.h b/extensions/browser/uninstall_ping_sender.h
deleted file mode 100644
index 8a11ea9..0000000
--- a/extensions/browser/uninstall_ping_sender.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef EXTENSIONS_BROWSER_UNINSTALL_PING_SENDER_H_
-#define EXTENSIONS_BROWSER_UNINSTALL_PING_SENDER_H_
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/scoped_observer.h"
-#include "extensions/browser/extension_registry.h"
-#include "extensions/browser/extension_registry_observer.h"
-
-namespace content {
-class BrowserContext;
-}
-
-namespace extensions {
-
-// A class that watches the ExtensionRegistry for uninstall events, and
-// uses the UpdateService to send uninstall pings.
-class UninstallPingSender : public ExtensionRegistryObserver {
- public:
-  enum FilterResult { SEND_PING, DO_NOT_SEND_PING };
-
-  // A callback function that will be called each time an extension is
-  // uninstalled, with the result used to determine if a ping should be
-  // sent or not.
-  using Filter =
-      base::RepeatingCallback<FilterResult(const Extension* extension,
-                                           UninstallReason reason)>;
-
-  UninstallPingSender(ExtensionRegistry* registry, Filter filter);
-  ~UninstallPingSender() override;
-
- protected:
-  // ExtensionRegistryObserver:
-  void OnExtensionUninstalled(content::BrowserContext* browser_context,
-                              const Extension* extension,
-                              UninstallReason reason) override;
-
- private:
-  // Callback for determining whether to send uninstall pings.
-  Filter filter_;
-
-  ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> observer_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(UninstallPingSender);
-};
-
-}  // namespace extensions
-
-#endif  // EXTENSIONS_BROWSER_UNINSTALL_PING_SENDER_H_
diff --git a/extensions/browser/updater/BUILD.gn b/extensions/browser/updater/BUILD.gn
index 8e682d4..6c7d326 100644
--- a/extensions/browser/updater/BUILD.gn
+++ b/extensions/browser/updater/BUILD.gn
@@ -27,6 +27,8 @@
     "request_queue_impl.h",
     "safe_manifest_parser.cc",
     "safe_manifest_parser.h",
+    "uninstall_ping_sender.cc",
+    "uninstall_ping_sender.h",
     "update_data_provider.cc",
     "update_data_provider.h",
     "update_service.cc",
@@ -41,8 +43,13 @@
   ]
 
   deps = [
+    "//components/crx_file",
+    "//components/keyed_service/content",
     "//components/signin/public/identity_manager",
-    "//content/public/browser:browser",
+    "//components/update_client",
+    "//content/public/browser",
+    "//extensions/browser:browser_sources",
+    "//extensions/browser/install",
     "//extensions/common",
     "//extensions/strings",
     "//services/data_decoder/public/cpp",
diff --git a/extensions/browser/updater/uninstall_ping_sender.cc b/extensions/browser/updater/uninstall_ping_sender.cc
new file mode 100644
index 0000000..6eeb0ec
--- /dev/null
+++ b/extensions/browser/updater/uninstall_ping_sender.cc
@@ -0,0 +1,30 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/browser/updater/uninstall_ping_sender.h"
+
+#include "base/version.h"
+#include "extensions/browser/updater/update_service.h"
+
+namespace extensions {
+
+UninstallPingSender::UninstallPingSender(ExtensionRegistry* registry,
+                                         Filter filter)
+    : filter_(std::move(filter)) {
+  observer_.Observe(registry);
+}
+
+UninstallPingSender::~UninstallPingSender() {}
+
+void UninstallPingSender::OnExtensionUninstalled(
+    content::BrowserContext* browser_context,
+    const Extension* extension,
+    UninstallReason reason) {
+  if (filter_.Run(extension, reason) == SEND_PING) {
+    UpdateService* updater = UpdateService::Get(browser_context);
+    updater->SendUninstallPing(extension->id(), extension->version(), reason);
+  }
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/updater/uninstall_ping_sender.h b/extensions/browser/updater/uninstall_ping_sender.h
new file mode 100644
index 0000000..290ac3d
--- /dev/null
+++ b/extensions/browser/updater/uninstall_ping_sender.h
@@ -0,0 +1,54 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_BROWSER_UPDATER_UNINSTALL_PING_SENDER_H_
+#define EXTENSIONS_BROWSER_UPDATER_UNINSTALL_PING_SENDER_H_
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/scoped_observation.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_registry_observer.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace extensions {
+
+// A class that watches the ExtensionRegistry for uninstall events, and
+// uses the UpdateService to send uninstall pings.
+class UninstallPingSender : public ExtensionRegistryObserver {
+ public:
+  enum FilterResult { SEND_PING, DO_NOT_SEND_PING };
+
+  // A callback function that will be called each time an extension is
+  // uninstalled, with the result used to determine if a ping should be
+  // sent or not.
+  using Filter =
+      base::RepeatingCallback<FilterResult(const Extension* extension,
+                                           UninstallReason reason)>;
+
+  UninstallPingSender(ExtensionRegistry* registry, Filter filter);
+  ~UninstallPingSender() override;
+
+ protected:
+  // ExtensionRegistryObserver:
+  void OnExtensionUninstalled(content::BrowserContext* browser_context,
+                              const Extension* extension,
+                              UninstallReason reason) override;
+
+ private:
+  // Callback for determining whether to send uninstall pings.
+  Filter filter_;
+
+  base::ScopedObservation<ExtensionRegistry, ExtensionRegistryObserver>
+      observer_{this};
+
+  DISALLOW_COPY_AND_ASSIGN(UninstallPingSender);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_BROWSER_UPDATER_UNINSTALL_PING_SENDER_H_
diff --git a/extensions/browser/updater/update_service_unittest.cc b/extensions/browser/updater/update_service_unittest.cc
index 5fcbe03..517a456 100644
--- a/extensions/browser/updater/update_service_unittest.cc
+++ b/extensions/browser/updater/update_service_unittest.cc
@@ -33,9 +33,9 @@
 #include "extensions/browser/mock_extension_system.h"
 #include "extensions/browser/notification_types.h"
 #include "extensions/browser/test_extensions_browser_client.h"
-#include "extensions/browser/uninstall_ping_sender.h"
 #include "extensions/browser/updater/extension_downloader.h"
 #include "extensions/browser/updater/extension_update_data.h"
+#include "extensions/browser/updater/uninstall_ping_sender.h"
 #include "extensions/browser/updater/update_service.h"
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/extension_features.h"
diff --git a/extensions/components/native_app_window/native_app_window_views.cc b/extensions/components/native_app_window/native_app_window_views.cc
index 6277ea4..30bc290 100644
--- a/extensions/components/native_app_window/native_app_window_views.cc
+++ b/extensions/components/native_app_window/native_app_window_views.cc
@@ -13,6 +13,7 @@
 #include "third_party/skia/include/core/SkRegion.h"
 #include "ui/views/controls/webview/webview.h"
 #include "ui/views/layout/fill_layout.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/window/non_client_view.h"
 
@@ -42,8 +43,8 @@
   web_view_->SetWebContents(app_window_->web_contents());
 
   SetCanMinimize(!app_window_->show_on_lock_screen());
-  SetCanMaximize(CanMaximizeWindow());
-  SetCanResize(CanResizeWindow());
+  SetCanMaximize(GetCanMaximizeWindow());
+  SetCanResize(GetCanResizeWindow());
 
   widget_ = new views::Widget;
   widget_->AddObserver(this);
@@ -365,8 +366,8 @@
     const gfx::Size& max_size) {
   size_constraints_.set_minimum_size(min_size);
   size_constraints_.set_maximum_size(max_size);
-  SetCanMaximize(CanMaximizeWindow());
-  SetCanResize(CanResizeWindow());
+  SetCanMaximize(GetCanMaximizeWindow());
+  SetCanResize(GetCanResizeWindow());
   widget_->OnSizeConstraintsChanged();
 }
 
@@ -404,8 +405,8 @@
 }
 
 void NativeAppWindowViews::OnWidgetHasHitTestMaskChanged() {
-  SetCanMaximize(CanMaximizeWindow());
-  SetCanResize(CanResizeWindow());
+  SetCanMaximize(GetCanMaximizeWindow());
+  SetCanResize(GetCanResizeWindow());
 }
 
 void NativeAppWindowViews::OnViewWasResized() {
@@ -413,14 +414,19 @@
     observer.OnPositionRequiresUpdate();
 }
 
-bool NativeAppWindowViews::CanResizeWindow() const {
+bool NativeAppWindowViews::GetCanResizeWindow() const {
   return resizable_ && !size_constraints_.HasFixedSize() &&
          !WidgetHasHitTestMask();
 }
 
-bool NativeAppWindowViews::CanMaximizeWindow() const {
+bool NativeAppWindowViews::GetCanMaximizeWindow() const {
   return resizable_ && !size_constraints_.HasMaximumSize() &&
          !WidgetHasHitTestMask();
 }
 
+BEGIN_METADATA(NativeAppWindowViews, views::WidgetDelegateView)
+ADD_READONLY_PROPERTY_METADATA(bool, CanMaximizeWindow)
+ADD_READONLY_PROPERTY_METADATA(bool, CanResizeWindow)
+END_METADATA
+
 }  // namespace native_app_window
diff --git a/extensions/components/native_app_window/native_app_window_views.h b/extensions/components/native_app_window/native_app_window_views.h
index c78a5ee2..9d580f24 100644
--- a/extensions/components/native_app_window/native_app_window_views.h
+++ b/extensions/components/native_app_window/native_app_window_views.h
@@ -15,6 +15,7 @@
 #include "extensions/browser/app_window/size_constraints.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
+#include "ui/views/metadata/metadata_header_macros.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
 #include "ui/views/widget/widget_observer.h"
@@ -34,7 +35,10 @@
                              public views::WidgetDelegateView,
                              public views::WidgetObserver {
  public:
+  METADATA_HEADER(NativeAppWindowViews);
   NativeAppWindowViews();
+  NativeAppWindowViews(const NativeAppWindowViews&) = delete;
+  NativeAppWindowViews& operator=(const NativeAppWindowViews&) = delete;
   ~NativeAppWindowViews() override;
   void Init(extensions::AppWindow* app_window,
             const extensions::AppWindow::CreateParams& create_params);
@@ -147,8 +151,8 @@
   // Informs modal dialogs that they need to update their positions.
   void OnViewWasResized();
 
-  bool CanMaximizeWindow() const;
-  bool CanResizeWindow() const;
+  bool GetCanMaximizeWindow() const;
+  bool GetCanResizeWindow() const;
 
   extensions::AppWindow* app_window_ = nullptr;  // Not owned.
   views::WebView* web_view_ = nullptr;
@@ -164,8 +168,6 @@
 
   base::ObserverList<web_modal::ModalDialogHostObserver>::Unchecked
       observer_list_;
-
-  DISALLOW_COPY_AND_ASSIGN(NativeAppWindowViews);
 };
 
 }  // namespace native_app_window
diff --git a/extensions/shell/BUILD.gn b/extensions/shell/BUILD.gn
index 91515c4..1b176d8e 100644
--- a/extensions/shell/BUILD.gn
+++ b/extensions/shell/BUILD.gn
@@ -61,7 +61,9 @@
     "//extensions/browser",
     "//extensions/browser:core_api_provider",
     "//extensions/browser/api/messaging",
+    "//extensions/browser/api/system_display",
     "//extensions/browser/kiosk",
+    "//extensions/browser/updater",
     "//extensions/common",
     "//extensions/common:core_api_provider",
     "//extensions/common/api",
diff --git a/extensions/shell/browser/shell_app_delegate.cc b/extensions/shell/browser/shell_app_delegate.cc
index 516dfa9..40a49e7 100644
--- a/extensions/shell/browser/shell_app_delegate.cc
+++ b/extensions/shell/browser/shell_app_delegate.cc
@@ -23,11 +23,16 @@
   ShellExtensionWebContentsObserver::CreateForWebContents(web_contents);
 }
 
-void ShellAppDelegate::RenderViewCreated(
-    content::RenderViewHost* render_view_host) {
-  // The views implementation of AppWindow takes focus via SetInitialFocus()
-  // and views::WebView but app_shell is aura-only and must do it manually.
-  content::WebContents::FromRenderViewHost(render_view_host)->Focus();
+void ShellAppDelegate::RenderFrameCreated(
+    content::RenderFrameHost* frame_host) {
+  content::WebContents* contents =
+      content::WebContents::FromRenderFrameHost(frame_host);
+  // Only do this for the initial main frame.
+  if (frame_host == contents->GetMainFrame()) {
+    // The views implementation of AppWindow takes focus via SetInitialFocus()
+    // and views::WebView but app_shell is aura-only and must do it manually.
+    contents->Focus();
+  }
 }
 
 void ShellAppDelegate::ResizeWebContents(content::WebContents* web_contents,
diff --git a/extensions/shell/browser/shell_app_delegate.h b/extensions/shell/browser/shell_app_delegate.h
index 4ca4d50e..db2032f3 100644
--- a/extensions/shell/browser/shell_app_delegate.h
+++ b/extensions/shell/browser/shell_app_delegate.h
@@ -20,7 +20,7 @@
 
   // AppDelegate overrides:
   void InitWebContents(content::WebContents* web_contents) override;
-  void RenderViewCreated(content::RenderViewHost* render_view_host) override;
+  void RenderFrameCreated(content::RenderFrameHost* frame_host) override;
   void ResizeWebContents(content::WebContents* web_contents,
                          const gfx::Size& size) override;
   content::WebContents* OpenURLFromTab(
diff --git a/fuchsia/runners/cast/cast_runner_integration_test.cc b/fuchsia/runners/cast/cast_runner_integration_test.cc
index a233214b..0de9807 100644
--- a/fuchsia/runners/cast/cast_runner_integration_test.cc
+++ b/fuchsia/runners/cast/cast_runner_integration_test.cc
@@ -521,13 +521,11 @@
     if (component_controller_) {
       component_controller_.set_error_handler(
           [&controller_loop](zx_status_t status) {
-            EXPECT_EQ(status, ZX_ERR_PEER_CLOSED);
             controller_loop.Quit();
+            EXPECT_EQ(status, ZX_ERR_PEER_CLOSED);
           });
     }
 
-    web_engine_controller_->Kill();
-
     if (component_controller_) {
       controller_loop.Run();
     }
@@ -595,27 +593,35 @@
 // crashed. Regression test for https://crbug.com/1066826).
 // TODO(https://crbug.com/1066833): Make this a WebRunner test.
 TEST_F(CastRunnerIntegrationTest, CanRecreateContext) {
-  // Execute two iterations of launching the component and verifying that it
-  // reaches the expected URL.
-  for (int i = 0; i < 2; ++i) {
-    SCOPED_TRACE(testing::Message() << "Test iteration " << i);
+  const GURL app_url = test_server_.GetURL(kBlankAppUrl);
+  app_config_manager_.AddApp(kTestAppId, app_url);
 
-    const GURL app_url = test_server_.GetURL(kBlankAppUrl);
-    app_config_manager_.AddApp(kTestAppId, app_url);
+  // Create a Cast component and verify that it has loaded.
+  CreateComponentContextAndStartComponent();
+  CheckAppUrl(app_url);
 
-    CreateComponentContextAndStartComponent();
+  // Disconnect the CastRunner's web.Context, by killing the ContextProvider.
+  base::RunLoop loop;
+  web_engine_controller_->Kill();
+  web_engine_controller_.set_error_handler([&loop](zx_status_t status) {
+    loop.Quit();
+    EXPECT_EQ(status, ZX_ERR_PEER_CLOSED);
+  });
 
-    CheckAppUrl(app_url);
+  // Wait for the component to be torn down.
+  WaitForComponentDestroyed();
 
-    web_engine_controller_->Kill();
+  // Start a new WebEngine instance for the second component.
+  StartAndPublishWebEngine();
 
-    // Wait for the component and the Context to be torn down.
-    WaitForComponentDestroyed();
-
-    // Start a new WebEngine instance for the next iteration.
-    if (i < 1)
-      StartAndPublishWebEngine();
-  }
+  // Create a second Cast component and verify that it has loaded.
+  // There is no guarantee that the CastRunner has detected the old web.Context
+  // disconnecting yet, so attempts to launch Cast components could fail.
+  // WebContentRunner::CreateFrameWithParams() will synchronously verify that
+  // the web.Context is not-yet-closed, to work-around that.
+  app_config_manager_.AddApp(kTestAppId, app_url);
+  CreateComponentContextAndStartComponent();
+  CheckAppUrl(app_url);
 }
 
 TEST_F(CastRunnerIntegrationTest, ApiBindings) {
diff --git a/fuchsia/runners/common/web_content_runner.cc b/fuchsia/runners/common/web_content_runner.cc
index 9fdd51b..d2b6634 100644
--- a/fuchsia/runners/common/web_content_runner.cc
+++ b/fuchsia/runners/common/web_content_runner.cc
@@ -35,6 +35,13 @@
   return web_context;
 }
 
+bool IsChannelClosed(const zx::channel& channel) {
+  zx_signals_t observed = 0u;
+  zx_status_t status =
+      channel.wait_one(ZX_ERR_PEER_CLOSED, zx::time(), &observed);
+  return status == ZX_OK;
+}
+
 }  // namespace
 
 WebContentRunner::WebContentRunner(
@@ -54,6 +61,12 @@
 void WebContentRunner::CreateFrameWithParams(
     fuchsia::web::CreateFrameParams params,
     fidl::InterfaceRequest<fuchsia::web::Frame> request) {
+  // Synchronously check whether the web.Context channel has closed, to reduce
+  // the chance of issuing CreateFrameWithParams() to an already-closed channel.
+  // This avoids potentially flaking a test - see crbug.com/1173418.
+  if (context_ && IsChannelClosed(context_.channel()))
+    context_.Unbind();
+
   if (!context_) {
     DCHECK(get_context_params_callback_);
     context_ = CreateWebContext(get_context_params_callback_.Run());
diff --git a/google_apis/gaia/gaia_auth_fetcher.cc b/google_apis/gaia/gaia_auth_fetcher.cc
index e50f7be8..e71393a 100644
--- a/google_apis/gaia/gaia_auth_fetcher.cc
+++ b/google_apis/gaia/gaia_auth_fetcher.cc
@@ -991,8 +991,7 @@
     if (net_error == net::ERR_ABORTED) {
       return GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
     }
-    DLOG(WARNING) << "Could not reach Google Accounts servers: errno "
-                  << net_error;
+    DVLOG(1) << "Could not reach Google Accounts servers: errno " << net_error;
     return GoogleServiceAuthError::FromConnectionError(net_error);
   }
 
diff --git a/google_apis/gaia/oauth2_mint_token_flow.cc b/google_apis/gaia/oauth2_mint_token_flow.cc
index ac02a9c2..3d17919 100644
--- a/google_apis/gaia/oauth2_mint_token_flow.cc
+++ b/google_apis/gaia/oauth2_mint_token_flow.cc
@@ -52,16 +52,10 @@
 const char kOAuth2IssueTokenBodyFormatConsentResultAddendum[] =
     "&consent_result=%s";
 const char kIssueAdviceKey[] = "issueAdvice";
-const char kIssueAdviceValueConsent[] = "consent";
 const char kIssueAdviceValueRemoteConsent[] = "remoteConsent";
 const char kAccessTokenKey[] = "token";
-const char kConsentKey[] = "consent";
 const char kExpiresInKey[] = "expiresIn";
-const char kScopesKey[] = "scopes";
 const char kGrantedScopesKey[] = "grantedScopes";
-const char kDescriptionKey[] = "description";
-const char kDetailKey[] = "detail";
-const char kDetailSeparators[] = "\n";
 const char kError[] = "error";
 const char kMessage[] = "message";
 
@@ -119,18 +113,6 @@
 const char kOAuth2MintTokenApiCallResultHistogram[] =
     "Signin.OAuth2MintToken.ApiCallResult";
 
-IssueAdviceInfoEntry::IssueAdviceInfoEntry() = default;
-IssueAdviceInfoEntry::~IssueAdviceInfoEntry() = default;
-
-IssueAdviceInfoEntry::IssueAdviceInfoEntry(const IssueAdviceInfoEntry& other) =
-    default;
-IssueAdviceInfoEntry& IssueAdviceInfoEntry::operator=(
-    const IssueAdviceInfoEntry& other) = default;
-
-bool IssueAdviceInfoEntry::operator ==(const IssueAdviceInfoEntry& rhs) const {
-  return description == rhs.description && details == rhs.details;
-}
-
 RemoteConsentResolutionData::RemoteConsentResolutionData() = default;
 RemoteConsentResolutionData::~RemoteConsentResolutionData() = default;
 RemoteConsentResolutionData::RemoteConsentResolutionData(
@@ -188,14 +170,6 @@
   // |this| may already be deleted.
 }
 
-void OAuth2MintTokenFlow::ReportIssueAdviceSuccess(
-    const IssueAdviceInfo& issue_advice) {
-  if (delegate_)
-    delegate_->OnIssueAdviceSuccess(issue_advice);
-
-  // |this| may already be deleted.
-}
-
 void OAuth2MintTokenFlow::ReportRemoteConsentSuccess(
     const RemoteConsentResolutionData& resolution_data) {
   if (delegate_)
@@ -281,21 +255,6 @@
     return;
   }
 
-  if (*issue_advice_value == kIssueAdviceValueConsent) {
-    IssueAdviceInfo issue_advice;
-    if (ParseIssueAdviceResponse(&(*value), &issue_advice)) {
-      RecordApiCallResult(OAuth2MintTokenApiCallResult::kIssueAdviceSuccess);
-      ReportIssueAdviceSuccess(issue_advice);
-    } else {
-      RecordApiCallResult(
-          OAuth2MintTokenApiCallResult::kParseIssueAdviceFailure);
-      ReportFailure(GoogleServiceAuthError::FromUnexpectedServiceResponse(
-          "Not able to parse the contents of consent "
-          "from a service response."));
-    }
-    return;
-  }
-
   if (*issue_advice_value == kIssueAdviceValueRemoteConsent) {
     RemoteConsentResolutionData resolution_data;
     if (ParseRemoteConsentResponse(&(*value), &resolution_data)) {
@@ -389,52 +348,6 @@
 }
 
 // static
-bool OAuth2MintTokenFlow::ParseIssueAdviceResponse(
-    const base::Value* dict,
-    IssueAdviceInfo* issue_advice) {
-  CHECK(dict);
-  CHECK(dict->is_dict());
-  CHECK(issue_advice);
-
-  const base::Value* consent_dict = dict->FindDictKey(kConsentKey);
-  if (!consent_dict)
-    return false;
-
-  const base::Value* scopes_list = consent_dict->FindListKey(kScopesKey);
-  if (!scopes_list)
-    return false;
-
-  bool success = true;
-  for (const auto& scopes_entry : scopes_list->GetList()) {
-    if (!scopes_entry.is_dict()) {
-      success = false;
-      break;
-    }
-
-    const std::string* description =
-        scopes_entry.FindStringKey(kDescriptionKey);
-    const std::string* detail = scopes_entry.FindStringKey(kDetailKey);
-    if (!description || !detail) {
-      success = false;
-      break;
-    }
-
-    IssueAdviceInfoEntry entry;
-    entry.description = base::UTF8ToUTF16(*description);
-    base::TrimWhitespace(entry.description, base::TRIM_ALL, &entry.description);
-    entry.details = base::SplitString(
-        base::UTF8ToUTF16(*detail), base::ASCIIToUTF16(kDetailSeparators),
-        base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
-    issue_advice->push_back(std::move(entry));
-  }
-
-  if (!success)
-    issue_advice->clear();
-
-  return success;
-}
-
-// static
 bool OAuth2MintTokenFlow::ParseRemoteConsentResponse(
     const base::Value* dict,
     RemoteConsentResolutionData* resolution_data) {
diff --git a/google_apis/gaia/oauth2_mint_token_flow.h b/google_apis/gaia/oauth2_mint_token_flow.h
index f515949..d8309ce4 100644
--- a/google_apis/gaia/oauth2_mint_token_flow.h
+++ b/google_apis/gaia/oauth2_mint_token_flow.h
@@ -32,13 +32,15 @@
 // numeric values should never be reused.
 enum class OAuth2MintTokenApiCallResult {
   kMintTokenSuccess = 0,
-  kIssueAdviceSuccess = 1,
+  // DEPRECATED:
+  // kIssueAdviceSuccess = 1,
   kRemoteConsentSuccess = 2,
   kApiCallFailure = 3,
   kParseJsonFailure = 4,
   kIssueAdviceKeyNotFoundFailure = 5,
   kParseMintTokenFailure = 6,
-  kParseIssueAdviceFailure = 7,
+  // DEPRECATED:
+  // kParseIssueAdviceFailure = 7,
   // DEPRECATED:
   // kRemoteConsentFallback = 8
   kParseRemoteConsentFailure = 9,
@@ -46,33 +48,6 @@
   kMaxValue = kMintTokenSuccessWithFallbackScopes
 };
 
-// IssueAdvice: messages to show to the user to get a user's approval.
-// The structure is as follows:
-// * Description 1
-//   - Detail 1.1
-//   - Details 1.2
-// * Description 2
-//   - Detail 2.1
-//   - Detail 2.2
-//   - Detail 2.3
-// * Description 3
-//   - Detail 3.1
-struct IssueAdviceInfoEntry {
- public:
-  IssueAdviceInfoEntry();
-  ~IssueAdviceInfoEntry();
-
-  IssueAdviceInfoEntry(const IssueAdviceInfoEntry& other);
-  IssueAdviceInfoEntry& operator=(const IssueAdviceInfoEntry& other);
-
-  base::string16 description;
-  std::vector<base::string16> details;
-
-  bool operator==(const IssueAdviceInfoEntry& rhs) const;
-};
-
-typedef std::vector<IssueAdviceInfoEntry> IssueAdviceInfo;
-
 // Data for the remote consent resolution:
 // - URL of the consent page to be displayed to the user.
 // - Cookies that should be set before navigating to that URL.
@@ -142,7 +117,6 @@
     virtual void OnMintTokenSuccess(const std::string& access_token,
                                     const std::set<std::string>& granted_scopes,
                                     int time_to_live) {}
-    virtual void OnIssueAdviceSuccess(const IssueAdviceInfo& issue_advice)  {}
     virtual void OnMintTokenFailure(const GoogleServiceAuthError& error) {}
     virtual void OnRemoteConsentSuccess(
         const RemoteConsentResolutionData& resolution_data) {}
@@ -201,13 +175,10 @@
   void ReportSuccess(const std::string& access_token,
                      const std::set<std::string>& granted_scopes,
                      int time_to_live);
-  void ReportIssueAdviceSuccess(const IssueAdviceInfo& issue_advice);
   void ReportRemoteConsentSuccess(
       const RemoteConsentResolutionData& resolution_data);
   void ReportFailure(const GoogleServiceAuthError& error);
 
-  static bool ParseIssueAdviceResponse(const base::Value* dict,
-                                       IssueAdviceInfo* issue_advice);
   static bool ParseRemoteConsentResponse(
       const base::Value* dict,
       RemoteConsentResolutionData* resolution_data);
diff --git a/google_apis/gaia/oauth2_mint_token_flow_unittest.cc b/google_apis/gaia/oauth2_mint_token_flow_unittest.cc
index 11afb0cf..4b529dc 100644
--- a/google_apis/gaia/oauth2_mint_token_flow_unittest.cc
+++ b/google_apis/gaia/oauth2_mint_token_flow_unittest.cc
@@ -60,70 +60,6 @@
     "  \"issueAdvice\": \"Auto\""
     "}";
 
-static const char kValidIssueAdviceResponse[] =
-    "{"
-    "  \"issueAdvice\": \"consent\","
-    "  \"consent\": {"
-    "    \"oauthClient\": {"
-    "      \"name\": \"Test app\","
-    "      \"iconUri\": \"\","
-    "      \"developerEmail\": \"munjal@chromium.org\""
-    "    },"
-    "    \"scopes\": ["
-    "      {"
-    "        \"description\": \"Manage your calendars\","
-    "        \"detail\": \"\nView and manage your calendars\n\""
-    "      },"
-    "      {"
-    "        \"description\": \"Manage your documents\","
-    "        \"detail\": \"\nView your documents\nUpload new documents\n\""
-    "      }"
-    "    ]"
-    "  }"
-    "}";
-
-static const char kIssueAdviceResponseNoDescription[] =
-    "{"
-    "  \"issueAdvice\": \"consent\","
-    "  \"consent\": {"
-    "    \"oauthClient\": {"
-    "      \"name\": \"Test app\","
-    "      \"iconUri\": \"\","
-    "      \"developerEmail\": \"munjal@chromium.org\""
-    "    },"
-    "    \"scopes\": ["
-    "      {"
-    "        \"description\": \"Manage your calendars\","
-    "        \"detail\": \"\nView and manage your calendars\n\""
-    "      },"
-    "      {"
-    "        \"detail\": \"\nView your documents\nUpload new documents\n\""
-    "      }"
-    "    ]"
-    "  }"
-    "}";
-
-static const char kIssueAdviceResponseNoDetail[] =
-    "{"
-    "  \"issueAdvice\": \"consent\","
-    "  \"consent\": {"
-    "    \"oauthClient\": {"
-    "      \"name\": \"Test app\","
-    "      \"iconUri\": \"\","
-    "      \"developerEmail\": \"munjal@chromium.org\""
-    "    },"
-    "    \"scopes\": ["
-    "      {"
-    "        \"description\": \"Manage your calendars\","
-    "        \"detail\": \"\nView and manage your calendars\n\""
-    "      },"
-    "      {"
-    "        \"description\": \"Manage your documents\""
-    "      }"
-    "    ]"
-    "  }"
-    "}";
-
 static const char kValidRemoteConsentResponse[] =
     "{"
     "  \"issueAdvice\": \"remoteConsent\","
@@ -165,20 +101,6 @@
   return scopes;
 }
 
-static IssueAdviceInfo CreateIssueAdvice() {
-  IssueAdviceInfo ia;
-  IssueAdviceInfoEntry e1;
-  e1.description = base::ASCIIToUTF16("Manage your calendars");
-  e1.details.push_back(base::ASCIIToUTF16("View and manage your calendars"));
-  ia.push_back(e1);
-  IssueAdviceInfoEntry e2;
-  e2.description = base::ASCIIToUTF16("Manage your documents");
-  e2.details.push_back(base::ASCIIToUTF16("View your documents"));
-  e2.details.push_back(base::ASCIIToUTF16("Upload new documents"));
-  ia.push_back(e2);
-  return ia;
-}
-
 static RemoteConsentResolutionData CreateRemoteConsentResolutionData() {
   RemoteConsentResolutionData resolution_data;
   resolution_data.url = GURL("https://test.com/consent?param=value");
@@ -205,8 +127,6 @@
                void(const std::string& access_token,
                     const std::set<std::string>& granted_scopes,
                     int time_to_live));
-  MOCK_METHOD1(OnIssueAdviceSuccess,
-               void (const IssueAdviceInfo& issue_advice));
   MOCK_METHOD1(OnRemoteConsentSuccess,
                void(const RemoteConsentResolutionData& resolution_data));
   MOCK_METHOD1(OnMintTokenFailure,
@@ -467,32 +387,6 @@
   }
 }
 
-TEST_F(OAuth2MintTokenFlowTest, ParseIssueAdviceResponse) {
-  {  // Description missing.
-    std::unique_ptr<base::Value> json =
-        ParseJson(kIssueAdviceResponseNoDescription);
-    IssueAdviceInfo ia;
-    EXPECT_FALSE(OAuth2MintTokenFlow::ParseIssueAdviceResponse(
-        json.get(), &ia));
-    EXPECT_TRUE(ia.empty());
-  }
-  {  // Detail missing.
-    std::unique_ptr<base::Value> json = ParseJson(kIssueAdviceResponseNoDetail);
-    IssueAdviceInfo ia;
-    EXPECT_FALSE(OAuth2MintTokenFlow::ParseIssueAdviceResponse(
-        json.get(), &ia));
-    EXPECT_TRUE(ia.empty());
-  }
-  {  // All good.
-    std::unique_ptr<base::Value> json = ParseJson(kValidIssueAdviceResponse);
-    IssueAdviceInfo ia;
-    EXPECT_TRUE(OAuth2MintTokenFlow::ParseIssueAdviceResponse(
-        json.get(), &ia));
-    IssueAdviceInfo ia_expected(CreateIssueAdvice());
-    EXPECT_EQ(ia_expected, ia);
-  }
-}
-
 TEST_F(OAuth2MintTokenFlowTest, ParseRemoteConsentResponse) {
   std::unique_ptr<base::Value> json = ParseJson(kValidRemoteConsentResponse);
   RemoteConsentResolutionData resolution_data;
@@ -674,37 +568,6 @@
       OAuth2MintTokenApiCallResult::kMintTokenSuccess, 1);
 }
 
-TEST_F(OAuth2MintTokenFlowTest, ProcessApiCallSuccess_NoDescription) {
-  CreateFlow(OAuth2MintTokenFlow::MODE_ISSUE_ADVICE);
-  EXPECT_CALL(delegate_, OnMintTokenFailure(_));
-  ProcessApiCallSuccess(
-      head_200_.get(),
-      std::make_unique<std::string>(kIssueAdviceResponseNoDescription));
-  histogram_tester_.ExpectUniqueSample(
-      kOAuth2MintTokenApiCallResultHistogram,
-      OAuth2MintTokenApiCallResult::kParseIssueAdviceFailure, 1);
-}
-
-TEST_F(OAuth2MintTokenFlowTest, ProcessApiCallSuccess_NoDetail) {
-  CreateFlow(OAuth2MintTokenFlow::MODE_ISSUE_ADVICE);
-  EXPECT_CALL(delegate_, OnMintTokenFailure(_));
-  ProcessApiCallSuccess(head_200_.get(), std::make_unique<std::string>(
-                                             kIssueAdviceResponseNoDetail));
-  histogram_tester_.ExpectUniqueSample(
-      kOAuth2MintTokenApiCallResultHistogram,
-      OAuth2MintTokenApiCallResult::kParseIssueAdviceFailure, 1);
-}
-TEST_F(OAuth2MintTokenFlowTest, ProcessApiCallSuccess_GoodIssueAdvice) {
-  CreateFlow(OAuth2MintTokenFlow::MODE_ISSUE_ADVICE);
-  IssueAdviceInfo ia(CreateIssueAdvice());
-  EXPECT_CALL(delegate_, OnIssueAdviceSuccess(ia));
-  ProcessApiCallSuccess(head_200_.get(), std::make_unique<std::string>(
-                                             kValidIssueAdviceResponse));
-  histogram_tester_.ExpectUniqueSample(
-      kOAuth2MintTokenApiCallResultHistogram,
-      OAuth2MintTokenApiCallResult::kIssueAdviceSuccess, 1);
-}
-
 TEST_F(OAuth2MintTokenFlowTest, ProcessApiCallSuccess_GoodRemoteConsent) {
   CreateFlow(OAuth2MintTokenFlow::MODE_ISSUE_ADVICE);
   RemoteConsentResolutionData resolution_data =
diff --git a/gpu/command_buffer/client/webgpu_implementation.cc b/gpu/command_buffer/client/webgpu_implementation.cc
index 579c3c19..136958e 100644
--- a/gpu/command_buffer/client/webgpu_implementation.cc
+++ b/gpu/command_buffer/client/webgpu_implementation.cc
@@ -200,6 +200,8 @@
   ImplementationBase::VerifySyncTokens(sync_tokens, count);
 }
 void WebGPUImplementation::WaitSyncTokenCHROMIUM(const GLbyte* sync_token) {
+  // Flush any commands before this, so we don't block more than necessary.
+  FlushCommands();
   ImplementationBase::WaitSyncToken(sync_token);
 }
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
index b04f0c5..87eb496 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -2854,6 +2854,21 @@
   }
 }
 
+void GLES2DecoderPassthroughImpl::UpdateCurrentlyBoundElementArrayBuffer() {
+  GLint service_element_array_buffer = 0;
+  api_->glGetIntegervFn(GL_ELEMENT_ARRAY_BUFFER_BINDING,
+                        &service_element_array_buffer);
+
+  GLuint client_element_array_buffer = 0;
+  if (service_element_array_buffer != 0) {
+    GetClientID(&resources_->buffer_id_map,
+                static_cast<GLuint>(service_element_array_buffer),
+                &client_element_array_buffer);
+  }
+
+  bound_buffers_[GL_ELEMENT_ARRAY_BUFFER] = client_element_array_buffer;
+}
+
 error::Error GLES2DecoderPassthroughImpl::HandleSetActiveURLCHROMIUM(
     uint32_t immediate_data_size,
     const volatile void* cmd_data) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
index 7ff062e..f4c69fc9 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -455,6 +455,10 @@
   void UpdateTextureSizeFromTarget(GLenum target);
   void UpdateTextureSizeFromClientID(GLuint client_id);
 
+  // Some operations like binding a VAO will update the element array buffer
+  // binding without an explicit glBindBuffer.
+  void UpdateCurrentlyBoundElementArrayBuffer();
+
   error::Error BindTexImage2DCHROMIUMImpl(GLenum target,
                                           GLenum internalformat,
                                           GLint image_id);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
index a26b4417..87a32de 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -3813,6 +3813,7 @@
 error::Error GLES2DecoderPassthroughImpl::DoBindVertexArrayOES(GLuint array) {
   api()->glBindVertexArrayOESFn(
       GetVertexArrayServiceID(array, &vertex_array_id_map_));
+  UpdateCurrentlyBoundElementArrayBuffer();
   return error::kNoError;
 }
 
diff --git a/gpu/vulkan/vulkan_image.cc b/gpu/vulkan/vulkan_image.cc
index 5db12a6..d89d050 100644
--- a/gpu/vulkan/vulkan_image.cc
+++ b/gpu/vulkan/vulkan_image.cc
@@ -279,7 +279,6 @@
   if (image_tiling_ != VK_IMAGE_TILING_LINEAR)
     return true;
 
-  plane_count_ = 1;
   const VkImageSubresource image_subresource = {
       .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
       .mipLevel = 0,
diff --git a/gpu/vulkan/vulkan_image.h b/gpu/vulkan/vulkan_image.h
index d2b8b3c..3afbbd4 100644
--- a/gpu/vulkan/vulkan_image.h
+++ b/gpu/vulkan/vulkan_image.h
@@ -191,7 +191,7 @@
   VkExternalMemoryHandleTypeFlags handle_types_ = 0;
   scoped_refptr<gfx::NativePixmap> native_pixmap_;
   uint64_t modifier_ = gfx::NativePixmapHandle::kNoModifier;
-  size_t plane_count_ = 0;
+  size_t plane_count_ = 1;
   std::array<VkSubresourceLayout, 4> layouts_ = {};
 };
 
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg
index 78491cad..61eedd2e 100644
--- a/infra/config/generated/cr-buildbucket.cfg
+++ b/infra/config/generated/cr-buildbucket.cfg
@@ -26951,7 +26951,7 @@
       swarming_host: "chromium-swarm.appspot.com"
       swarming_tags: "vpython:native-python-wrapper"
       dimensions: "builderless:1"
-      dimensions: "cores:8"
+      dimensions: "cores:32"
       dimensions: "cpu:x86-64"
       dimensions: "os:Ubuntu-16.04"
       dimensions: "pool:luci.chromium.ci"
@@ -26962,7 +26962,7 @@
         cmd: "luciexe"
       }
       properties: "{\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.packager\",\"recipe\":\"chromium_rts/create_model\"}"
-      execution_timeout_secs: 10800
+      execution_timeout_secs: 21600
       build_numbers: YES
       service_account: "chromium-cipd-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star
index bdea91c..0ca3f6a 100644
--- a/infra/config/subprojects/chromium/ci.star
+++ b/infra/config/subprojects/chromium/ci.star
@@ -5783,5 +5783,6 @@
     executable = "recipe:chromium_rts/create_model",
     schedule = "0 10 * * *",  # at 2 AM PST, once a day.
     triggered_by = [],
-    execution_timeout = 3 * time.hour,
+    cores = 32,
+    execution_timeout = 6 * time.hour,
 )
diff --git a/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-device.json b/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-device.json
index 78ae25d..a9cc0b0 100644
--- a/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-device.json
+++ b/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-device.json
@@ -7,6 +7,7 @@
   "gn_args": [
     "goma_dir=\"$(goma_dir)\"",
     "ios_enable_code_signing=false",
+    "ios_set_attributes_for_xcode_project_generation=false",
     "ios_use_goma_rbe=true",
     "is_component_build=false",
     "is_debug=false",
diff --git a/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-simulator.json b/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-simulator.json
index 60c56d3e..25f0efae 100644
--- a/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-simulator.json
+++ b/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-simulator.json
@@ -6,6 +6,7 @@
   "gn_args": [
     "goma_dir=\"$(goma_dir)\"",
     "ios_enable_code_signing=false",
+    "ios_set_attributes_for_xcode_project_generation=false",
     "ios_use_goma_rbe=true",
     "is_component_build=false",
     "is_debug=true",
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index 18197a3..d420cd4 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -405,12 +405,6 @@
       <message name="IDS_IOS_BOOKMARK_DELETE" desc="Title of button that deletes currently edited bookmark. [Length: 20em.]">
         Delete
       </message>
-      <message name="IDS_IOS_BOOKMARK_DONE_BUTTON" desc="Title of the Done button in the Bookmarks editor UI. [Length: 10em.] [iOS only]">
-        Done
-      </message>
-      <message name="IDS_IOS_BOOKMARK_EDIT_MODE_EXIT_MOBILE" desc="Exit the bookmark panel edit mode [Length: Unknown. Keep it short.]">
-        Done
-      </message>
       <message name="IDS_IOS_BOOKMARK_EDIT_PARENT_FOLDER_BUTTON_HINT" desc="The accessibility hint spoken when hovering over the parent folder of a bookmark in the editor. [iOS only]">
         Double tap to change the parent folder.
       </message>
diff --git a/ios/chrome/app/strings/resources/ios_strings_az.xtb b/ios/chrome/app/strings/resources/ios_strings_az.xtb
index e950dee..3def4b3 100644
--- a/ios/chrome/app/strings/resources/ios_strings_az.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_az.xtb
@@ -195,7 +195,7 @@
 <translation id="2952581218264071393">1. Chrome Ayarlarını açın</translation>
 <translation id="2958718410589002129">Parollar</translation>
 <translation id="2964349545761222050">Üçüncü Tərəf Kukiləri Bloklayın</translation>
-<translation id="2969979262385602596">Hesaba daxil olmaq uğursuz oldu. Lütfən, daha sonra yenidən cəhd edin.</translation>
+<translation id="2969979262385602596">Hesaba girmək olmur. Sonra cəhd edin.</translation>
 <translation id="2975121486251958312">Yalnız Anonim rejim əlçatandır</translation>
 <translation id="298306318844797842">Ödəniş metodu əlavə edin...</translation>
 <translation id="2989805286512600854">Yeni Paneldə açın</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_fa.xtb b/ios/chrome/app/strings/resources/ios_strings_fa.xtb
index bd4563f4..62b0b81 100644
--- a/ios/chrome/app/strings/resources/ios_strings_fa.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_fa.xtb
@@ -395,7 +395,7 @@
 <translation id="5118764316110575523">خاموش</translation>
 <translation id="5127805178023152808">همگام‌سازی خاموش است</translation>
 <translation id="5132942445612118989">همگام‌سازی گذرواژه‌ها، سابقه و موارد دیگر در همه دستگاه‌ها</translation>
-<translation id="5140288047769711648">‏Chrome به جای شما گذرواژه‌تان را به‌خاطر می‌سپارد. لازم نیست آن را به‌خاطر بسپارید.</translation>
+<translation id="5140288047769711648">‏Chrome به‌جای شما گذرواژه‌تان را به‌خاطر می‌سپارد. لازم نیست آن را به‌خاطر بسپارید.</translation>
 <translation id="5150492518600715772">ارسال به دستگاه شما</translation>
 <translation id="5181140330217080051">در حال بارگیری</translation>
 <translation id="5186185447130319458">خصوصی</translation>
diff --git a/ios/chrome/browser/context_menu/context_menu_egtest.mm b/ios/chrome/browser/context_menu/context_menu_egtest.mm
index 669b4be..aececf6 100644
--- a/ios/chrome/browser/context_menu/context_menu_egtest.mm
+++ b/ios/chrome/browser/context_menu/context_menu_egtest.mm
@@ -62,7 +62,7 @@
 const char kDestinationPageText[] = "You made it!";
 
 // URL to a page with a link to the destination page.
-const char kInitialPageUrl[] = "/scenarioContextMenuOpenInNewTab";
+const char kInitialPageUrl[] = "/scenarioContextMenuOpenInNewSurface";
 // HTML content of a page with a link to the destination page.
 const char kInitialPageHtml[] =
     "<html><body><a style='margin-left:150px' href='/destination' id='link'>"
@@ -187,6 +187,7 @@
 
 + (void)tearDown {
   [ChromeEarlGrey setContentSettings:CONTENT_SETTING_DEFAULT];
+  [ChromeEarlGrey closeAllExtraWindows];
   [super tearDown];
 }
 
@@ -446,4 +447,31 @@
   }
 }
 
+// Checks that "open in new window" shows up on a long press of a url link
+// and that it actually opens in a new window.
+- (void)testOpenLinkInNewWindow {
+  if (![ChromeEarlGrey areMultipleWindowsSupported])
+    EARL_GREY_TEST_DISABLED(@"Multiple windows can't be opened.");
+
+  // Loads url in first window.
+  const GURL initialURL = self.testServer->GetURL(kInitialPageUrl);
+  [ChromeEarlGrey loadURL:initialURL inWindowWithNumber:0];
+
+  [ChromeEarlGrey waitForWebStateContainingText:kInitialPageDestinationLinkText
+                             inWindowWithNumber:0];
+
+  // Display the context menu.
+  LongPressElement(kInitialPageDestinationLinkId);
+
+  // Open link in new window.
+  [[EarlGrey
+      selectElementWithMatcher:chrome_test_util::OpenLinkInNewWindowButton()]
+      performAction:grey_tap()];
+
+  // Assert there's a second window with expected content.
+  [ChromeEarlGrey waitForForegroundWindowCount:2];
+  [ChromeEarlGrey waitForWebStateContainingText:kDestinationPageText
+                             inWindowWithNumber:1];
+}
+
 @end
diff --git a/ios/chrome/browser/passwords/DEPS b/ios/chrome/browser/passwords/DEPS
deleted file mode 100644
index 606637e4..0000000
--- a/ios/chrome/browser/passwords/DEPS
+++ /dev/null
@@ -1,7 +0,0 @@
-specific_include_rules = {
-  # web::HttpServer is deprecated in favor of net::EmbeddedTestServer.
-  # TODO:(crbug.com/891834) Remove this exception.
-  "credential_manager_egtest\.mm": [
-    "+ios/web/public/test/http_server",
-  ],
-}
diff --git a/ios/chrome/browser/ui/authentication/signin/user_signin/BUILD.gn b/ios/chrome/browser/ui/authentication/signin/user_signin/BUILD.gn
index c2abc04..293e3a3 100644
--- a/ios/chrome/browser/ui/authentication/signin/user_signin/BUILD.gn
+++ b/ios/chrome/browser/ui/authentication/signin/user_signin/BUILD.gn
@@ -29,6 +29,7 @@
     "//components/sync/base",
     "//components/unified_consent",
     "//ios/chrome/app/strings",
+    "//ios/chrome/browser:chrome_url_constants",
     "//ios/chrome/browser/main:public",
     "//ios/chrome/browser/policy/resources:enterprise_icon_blue_large",
     "//ios/chrome/browser/signin",
diff --git a/ios/chrome/browser/ui/authentication/signin/user_signin/user_policy_signout_coordinator.h b/ios/chrome/browser/ui/authentication/signin/user_signin/user_policy_signout_coordinator.h
index c714e57..4829460 100644
--- a/ios/chrome/browser/ui/authentication/signin/user_signin/user_policy_signout_coordinator.h
+++ b/ios/chrome/browser/ui/authentication/signin/user_signin/user_policy_signout_coordinator.h
@@ -7,14 +7,18 @@
 
 #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
 
+@protocol ApplicationCommands;
 @protocol PolicySignoutPromptCommands;
 
 // Coordinates the user sign-out prompt when the user is signed out due to
 // the BrowserSignin policy disabling browser sign-in.
 @interface UserPolicySignoutCoordinator : ChromeCoordinator
 
-// Handler for all actions of this coordinator.
-@property(nonatomic, weak) id<PolicySignoutPromptCommands> handler;
+// Handler for commands related to the sign-out prompt for this coordinator.
+@property(nonatomic, weak) id<PolicySignoutPromptCommands> signoutPromptHandler;
+
+// Handler for application commands for this coordinator.
+@property(nonatomic, weak) id<ApplicationCommands> applicationHandler;
 
 @end
 
diff --git a/ios/chrome/browser/ui/authentication/signin/user_signin/user_policy_signout_coordinator.mm b/ios/chrome/browser/ui/authentication/signin/user_signin/user_policy_signout_coordinator.mm
index 246c5e1..bc754af 100644
--- a/ios/chrome/browser/ui/authentication/signin/user_signin/user_policy_signout_coordinator.mm
+++ b/ios/chrome/browser/ui/authentication/signin/user_signin/user_policy_signout_coordinator.mm
@@ -5,9 +5,13 @@
 #import "ios/chrome/browser/ui/authentication/signin/user_signin/user_policy_signout_coordinator.h"
 
 #include "base/notreached.h"
+#import "ios/chrome/browser/chrome_url_constants.h"
 #import "ios/chrome/browser/ui/authentication/signin/user_signin/policy_signout_commands.h"
 #import "ios/chrome/browser/ui/authentication/signin/user_signin/user_policy_signout_view_controller.h"
+#import "ios/chrome/browser/ui/commands/application_commands.h"
+#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_action_handler.h"
+#include "url/gurl.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -55,12 +59,15 @@
 }
 
 - (void)confirmationAlertPrimaryAction {
-  [self.handler hidePolicySignoutPrompt];
+  [self.signoutPromptHandler hidePolicySignoutPrompt];
 }
 
 - (void)confirmationAlertSecondaryAction {
-  // There should be no secondary action button for this UI.
-  NOTREACHED();
+  [self.signoutPromptHandler hidePolicySignoutPrompt];
+  OpenNewTabCommand* command =
+      [OpenNewTabCommand commandWithURLFromChrome:GURL(kChromeUIManagementURL)];
+  command.userInitiated = YES;
+  [self.applicationHandler openURLInNewTab:command];
 }
 
 - (void)confirmationAlertTertiaryAction {
diff --git a/ios/chrome/browser/ui/authentication/signin/user_signin/user_policy_signout_view_controller.mm b/ios/chrome/browser/ui/authentication/signin/user_signin/user_policy_signout_view_controller.mm
index 030b265a..4203dc7 100644
--- a/ios/chrome/browser/ui/authentication/signin/user_signin/user_policy_signout_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/signin/user_signin/user_policy_signout_view_controller.mm
@@ -22,12 +22,15 @@
   self.customSpacingAfterImage = 30;
 
   self.primaryActionAvailable = YES;
+  self.secondaryActionAvailable = YES;
   self.showDismissBarButton = NO;
   self.titleString = l10n_util::GetNSString(IDS_IOS_ENTERPRISE_SIGNED_OUT);
   self.subtitleString =
       l10n_util::GetNSString(IDS_IOS_ENTERPRISE_SIGNED_OUT_SUBTEXT);
   self.primaryActionString =
       l10n_util::GetNSString(IDS_IOS_ENTERPRISE_SIGNED_OUT_CONTINUE);
+  self.secondaryActionString =
+      l10n_util::GetNSString(IDS_IOS_ENTERPRISE_SIGNED_OUT_LEARN_MORE);
   self.dismissBarButtonSystemItem = UIBarButtonSystemItemDone;
 
   if (@available(iOS 13.4, *)) {
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
index 2ee3813..06af64aa 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
@@ -194,23 +194,26 @@
   self = [super initWithStyle:style];
   if (self) {
     DCHECK(!bookmark->is_folder());
-    DCHECK(!browser->GetBrowserState()->IsOffTheRecord());
-    _bookmark = bookmark;
-    _bookmarkModel = ios::BookmarkModelFactory::GetForBrowserState(
-        browser->GetBrowserState());
 
-    _folder = bookmark->parent();
+    // Browser may be OTR, which is why the original browser state is being
+    // explicitly requested.
+    _browser = browser;
+    _browserState = browser->GetBrowserState()->GetOriginalChromeBrowserState();
+
+    _bookmark = bookmark;
+    _bookmarkModel =
+        ios::BookmarkModelFactory::GetForBrowserState(_browserState);
+
+    _folder = _bookmark->parent();
 
     // Set up the bookmark model oberver.
     _modelBridge.reset(
         new bookmarks::BookmarkModelBridge(self, _bookmarkModel));
 
-    _browser = browser;
-    _browserState = browser->GetBrowserState()->GetOriginalChromeBrowserState();
     // TODO(crbug.com/1045047): Use HandlerForProtocol after commands protocol
     // clean up.
     _dispatcher =
-        static_cast<id<BrowserCommands>>(browser->GetCommandDispatcher());
+        static_cast<id<BrowserCommands>>(_browser->GetCommandDispatcher());
   }
   return self;
 }
@@ -249,10 +252,9 @@
   self.cancelItem = cancelItem;
 
   UIBarButtonItem* doneItem = [[UIBarButtonItem alloc]
-      initWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_DONE_BUTTON)
-              style:UIBarButtonItemStylePlain
-             target:self
-             action:@selector(save)];
+      initWithBarButtonSystemItem:UIBarButtonSystemItemDone
+                           target:self
+                           action:@selector(save)];
   doneItem.accessibilityIdentifier =
       kBookmarkEditNavigationBarDoneButtonIdentifier;
   self.navigationItem.rightBarButtonItem = doneItem;
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm
index eab9b99..832c140 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm
@@ -192,11 +192,9 @@
 
   // Add Done button.
   UIBarButtonItem* doneItem = [[UIBarButtonItem alloc]
-      initWithTitle:l10n_util::GetNSString(
-                        IDS_IOS_BOOKMARK_EDIT_MODE_EXIT_MOBILE)
-              style:UIBarButtonItemStylePlain
-             target:self
-             action:@selector(saveFolder)];
+      initWithBarButtonSystemItem:UIBarButtonSystemItemDone
+                           target:self
+                           action:@selector(saveFolder)];
   doneItem.accessibilityIdentifier =
       kBookmarkFolderEditNavigationBarDoneButtonIdentifier;
   self.navigationItem.rightBarButtonItem = doneItem;
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
index 39095f1..38206911 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
@@ -1788,6 +1788,8 @@
                            BookmarkHomeViewController* strongSelf = weakSelf;
                            if (!strongSelf)
                              return;
+                           if ([strongSelf isIncognitoForced])
+                             return;
                            auto nodes = [strongSelf editNodes];
                            [strongSelf openAllURLs:GetUrlsToOpen(nodes)
                                        inIncognito:NO
@@ -1802,6 +1804,8 @@
                            BookmarkHomeViewController* strongSelf = weakSelf;
                            if (!strongSelf)
                              return;
+                           if (![strongSelf isIncognitoAvailable])
+                             return;
                            auto nodes = [strongSelf editNodes];
                            [strongSelf openAllURLs:GetUrlsToOpen(nodes)
                                        inIncognito:YES
@@ -1864,6 +1868,8 @@
   titleString = GetNSString(IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB);
   [coordinator addItemWithTitle:titleString
                          action:^{
+                           if ([weakSelf isIncognitoForced])
+                             return;
                            [weakSelf openAllURLs:{nodeURL}
                                      inIncognito:NO
                                           newTab:YES];
@@ -1882,13 +1888,14 @@
     };
     [coordinator addItemWithTitle:titleString
                            action:action
-                            style:UIAlertActionStyleDefault
-                          enabled:![self isIncognitoForced]];
+                            style:UIAlertActionStyleDefault];
   }
 
   titleString = GetNSString(IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB);
   [coordinator addItemWithTitle:titleString
                          action:^{
+                           if (![weakSelf isIncognitoAvailable])
+                             return;
                            [weakSelf openAllURLs:{nodeURL}
                                      inIncognito:YES
                                           newTab:YES];
@@ -2355,6 +2362,8 @@
           [[NSMutableArray alloc] init];
 
       UIAction* openAction = [actionFactory actionToOpenInNewTabWithBlock:^{
+        if ([weakSelf isIncognitoForced])
+          return;
         [weakSelf openAllURLs:{nodeURL} inIncognito:NO newTab:YES];
       }];
       if ([self isIncognitoForced]) {
@@ -2364,6 +2373,8 @@
 
       UIAction* openInIncognito =
           [actionFactory actionToOpenInNewIncognitoTabWithBlock:^{
+            if (![weakSelf isIncognitoAvailable])
+              return;
             [weakSelf openAllURLs:{nodeURL} inIncognito:YES newTab:YES];
           }];
       if (![self isIncognitoAvailable]) {
@@ -2372,13 +2383,11 @@
       [menuElements addObject:openInIncognito];
 
       if (base::ios::IsMultipleScenesSupported()) {
-        UIAction* openInWindow = [actionFactory
-            actionToOpenInNewWindowWithURL:nodeURL
-                            activityOrigin:WindowActivityBookmarksOrigin];
-        if ([self isIncognitoForced]) {
-          openInWindow.attributes = UIMenuElementAttributesDisabled;
-        }
-        [menuElements addObject:openInWindow];
+        [menuElements
+            addObject:[actionFactory
+                          actionToOpenInNewWindowWithURL:nodeURL
+                                          activityOrigin:
+                                              WindowActivityBookmarksOrigin]];
       }
 
       [menuElements addObject:[actionFactory actionToCopyURL:nodeURL]];
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
index 847c887..61fa29e 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -979,7 +979,9 @@
     self.policySignoutPromptCoordinator = [[UserPolicySignoutCoordinator alloc]
         initWithBaseViewController:self.viewController
                            browser:self.browser];
-    self.policySignoutPromptCoordinator.handler = self;
+    self.policySignoutPromptCoordinator.signoutPromptHandler = self;
+    self.policySignoutPromptCoordinator.applicationHandler = HandlerForProtocol(
+        self.browser->GetCommandDispatcher(), ApplicationCommands);
   }
   [self.policySignoutPromptCoordinator start];
 }
diff --git a/ios/chrome/browser/ui/browser_view/hider/browser_view_hider_view_controller.mm b/ios/chrome/browser/ui/browser_view/hider/browser_view_hider_view_controller.mm
index 68d1c60..e1807aa1 100644
--- a/ios/chrome/browser/ui/browser_view/hider/browser_view_hider_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/hider/browser_view_hider_view_controller.mm
@@ -34,6 +34,10 @@
   self.view.layer.cornerRadius = kTopCornerRadius;
   self.view.hidden = YES;
 
+  [self.view addGestureRecognizer:[[UITapGestureRecognizer alloc]
+                                      initWithTarget:self
+                                              action:@selector(handleTap:)]];
+
   self.steadyView = [[LocationBarSteadyView alloc] init];
   self.steadyView.translatesAutoresizingMaskIntoConstraints = NO;
   [self.view addSubview:self.steadyView];
@@ -50,6 +54,13 @@
   AddSameConstraints(guide, self.steadyView);
 }
 
+- (void)handleTap:(UITapGestureRecognizer*)sender {
+  if (sender.state != UIGestureRecognizerStateEnded) {
+    return;
+  }
+  [self.panGestureHandler setNextState:ViewRevealState::Hidden animated:YES];
+}
+
 - (void)setPanGestureHandler:
     (ViewRevealingVerticalPanHandler*)panGestureHandler {
   _panGestureHandler = panGestureHandler;
@@ -87,7 +98,7 @@
   [self.steadyView setLocationLabelText:@""];
 }
 
-#pragma mark - viewRevealingAnimatee
+#pragma mark - ViewRevealingAnimatee
 
 - (void)willAnimateViewRevealFromState:(ViewRevealState)currentViewRevealState
                                toState:(ViewRevealState)nextViewRevealState {
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm
index 7d1d1ba7..c960993 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm
@@ -122,7 +122,8 @@
   if (self.collectionView.decelerating) {
     // Stop the scrolling if the scroll view is decelerating to prevent the
     // focus to be immediately lost.
-    [self.collectionView setContentOffset:[self adjustedOffset] animated:NO];
+    [self.collectionView setContentOffset:self.collectionView.contentOffset
+                                 animated:NO];
   }
 
   if (self.collectionController.scrolledToTop) {
@@ -137,7 +138,7 @@
 
   CGFloat pinnedOffsetY = [self.headerController pinnedOffsetY];
   self.collectionShiftingOffset =
-      MAX(0, pinnedOffsetY - [self adjustedOffset].y);
+      MAX(-self.additionalOffset, pinnedOffsetY - [self adjustedOffset].y);
 
   self.collectionController.scrolledToTop = YES;
   self.shouldAnimateHeader = YES;
@@ -152,14 +153,14 @@
                 return;
 
               __typeof(weakSelf) strongSelf = weakSelf;
-              if ((strongSelf.collectionView.contentOffset.y +
-                   self.additionalOffset) < pinnedOffsetY) {
+              if (strongSelf.collectionView.contentOffset.y <
+                  [self pinnedOffsetY]) {
                 if (animations)
                   animations();
                 // Changing the contentOffset of the collection results in a
                 // scroll and a change in the constraints of the header.
                 strongSelf.collectionView.contentOffset =
-                    CGPointMake(0, pinnedOffsetY - self.additionalOffset);
+                    CGPointMake(0, [self pinnedOffsetY]);
                 // Layout the header for the constraints to be animated.
                 [strongSelf.headerController layoutHeader];
                 [strongSelf.collectionView
@@ -313,11 +314,10 @@
     percentComplete = 1.0;
 
   // Find how much the collection view should be scrolled up in the next frame.
-  CGFloat yOffset =
-      (1.0 - percentComplete) * [self.headerController pinnedOffsetY] +
-      percentComplete * MAX([self.headerController pinnedOffsetY] -
-                                self.collectionShiftingOffset,
-                            0);
+  CGFloat yOffset = (1.0 - percentComplete) * [self pinnedOffsetY] +
+                    percentComplete * MAX([self pinnedOffsetY] -
+                                              self.collectionShiftingOffset,
+                                          -self.additionalOffset);
   self.collectionView.contentOffset = CGPointMake(0, yOffset);
 
   if (percentComplete == 1.0) {
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm
index 8a28e82f..ecefebf5 100644
--- a/ios/chrome/browser/ui/main/scene_controller.mm
+++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -1395,6 +1395,15 @@
         [[UISceneActivationRequestOptions alloc] init];
     options.requestingScene = self.sceneState.scene;
 
+    if (self.mainInterface) {
+      PrefService* prefs = self.mainInterface.browserState->GetPrefs();
+      if (IsIncognitoModeForced(prefs)) {
+        userActivity = AdaptUserActivityToIncognito(userActivity, true);
+      } else if (IsIncognitoModeDisabled(prefs)) {
+        userActivity = AdaptUserActivityToIncognito(userActivity, false);
+      }
+    }
+
     [UIApplication.sharedApplication
         requestSceneSessionActivation:nil /* make a new scene */
                          userActivity:userActivity
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
index c7643b5..a0d6b0c 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -311,7 +311,7 @@
 }
 
 - (void)stopScrolling {
-  if (IsRefactoredNTP()) {
+  if ([self isNTPRefactoredAndFeedVisible]) {
     [self.ntpViewController stopScrolling];
   } else {
     [self.contentSuggestionsCoordinator stopScrolling];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
index c12129a..c7fe6d9 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
@@ -203,6 +203,7 @@
     "//ios/chrome/browser/ui:feature_flags",
     "//ios/chrome/browser/ui/fullscreen:feature_flags",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid:features",
+    "//ios/chrome/browser/ui/tab_switcher/tab_grid/grid:grid_ui_constants",
     "//ios/chrome/browser/ui/thumb_strip:feature_flags",
     "//ios/chrome/browser/ui/util",
     "//ios/chrome/test/earl_grey:eg_test_support+eg2",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
index 0de5d99..9117cb2 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
@@ -5,12 +5,14 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/features.h"
+#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.h"
 #import "ios/chrome/browser/ui/util/ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
+#import "ios/chrome/test/earl_grey/chrome_xcui_actions.h"
 #import "ios/chrome/test/earl_grey/web_http_server_chrome_test_case.h"
 #import "ios/testing/earl_grey/earl_grey_test.h"
 #import "ios/web/public/test/http_server/http_server.h"
@@ -22,6 +24,7 @@
 #endif
 
 using chrome_test_util::TabGridOtherDevicesPanelButton;
+using chrome_test_util::LongPressAndDragToEdge;
 
 namespace {
 char kURL1[] = "http://firstURL";
@@ -42,6 +45,11 @@
   return grey_allOf(grey_accessibilityLabel(closeTabs),
                     grey_accessibilityTrait(UIAccessibilityTraitButton), nil);
 }
+
+// Identifer for cell at given |index| in the tab grid.
+NSString* IdentifierForCellAtIndex(unsigned int index) {
+  return [NSString stringWithFormat:@"%@%u", kGridCellIdentifierPrefix, index];
+}
 }  // namespace
 
 @interface TabGridTestCase : WebHttpServerChromeTestCase {
@@ -69,6 +77,12 @@
   web::test::SetUpSimpleHttpServer(responses);
 }
 
+- (void)tearDown {
+  [ChromeEarlGrey closeAllExtraWindows];
+  [EarlGrey setRootMatcherForSubsequentInteractions:nil];
+  [super tearDown];
+}
+
 // Tests entering and leaving the tab grid.
 - (void)testEnteringAndLeavingTabGrid {
   [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
@@ -240,8 +254,6 @@
   [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                           _URL1.GetContent())]
       assertWithMatcher:grey_notNil()];
-
-  [ChromeEarlGrey closeAllExtraWindows];
 }
 
 // Tests the Share action on a recent tab's context menu.
@@ -303,15 +315,120 @@
       assertWithMatcher:grey_sufficientlyVisible()];
 }
 
+#pragma mark - Drag and drop in Multiwindow
+
+// Tests that dragging a tab grid item to the edge opens a new window and that
+// the tab is properly transferred, incuding navigation stack.
+- (void)testDragAndDropAtEdgeToCreateNewWindow {
+  if (![ChromeEarlGrey areMultipleWindowsSupported])
+    EARL_GREY_TEST_DISABLED(@"Multiple windows can't be opened.");
+
+  [ChromeEarlGrey loadURL:_URL1];
+  [ChromeEarlGrey waitForWebStateContainingText:kResponse1];
+  [ChromeEarlGrey loadURL:_URL3];
+  [ChromeEarlGrey waitForWebStateContainingText:kResponse3];
+
+  [ChromeEarlGrey openNewTab];
+  [ChromeEarlGrey loadURL:_URL2];
+  [ChromeEarlGrey waitForWebStateContainingText:kResponse2];
+
+  [ChromeEarlGrey waitForMainTabCount:2 inWindowWithNumber:0];
+
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
+      performAction:grey_tap()];
+
+  GREYWaitForAppToIdle(@"App failed to idle");
+
+  LongPressAndDragToEdge(IdentifierForCellAtIndex(0), kGREYContentEdgeRight);
+
+  GREYWaitForAppToIdle(@"App failed to idle");
+
+  // Assert two windows and the expected tabs in each.
+  [ChromeEarlGrey waitForForegroundWindowCount:2];
+  [ChromeEarlGrey waitForMainTabCount:1 inWindowWithNumber:0];
+  [ChromeEarlGrey waitForMainTabCount:1 inWindowWithNumber:1];
+  [ChromeEarlGrey waitForWebStateContainingText:kResponse2
+                             inWindowWithNumber:0];
+  [ChromeEarlGrey waitForWebStateContainingText:kResponse3
+                             inWindowWithNumber:1];
+
+  // Navigate back on second window to check the navigation stack is intact.
+  [EarlGrey setRootMatcherForSubsequentInteractions:chrome_test_util::
+                                                        WindowWithNumber(1)];
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()]
+      performAction:grey_tap()];
+  [ChromeEarlGrey waitForWebStateContainingText:kResponse1
+                             inWindowWithNumber:1];
+
+  [EarlGrey setRootMatcherForSubsequentInteractions:chrome_test_util::
+                                                        WindowWithNumber(0)];
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
+      performAction:grey_tap()];
+}
+
+// Tests that dragging a tab grid incognito item to the edge opens a new window
+// and that the tab is properly transferred, incuding navigation stack.
+// TODO(crbug.com/1176180): re-eable when it is fixed.
+- (void)DISABLED_testIncognitoDragAndDropAtEdgeToCreateNewWindow {
+  if (![ChromeEarlGrey areMultipleWindowsSupported])
+    EARL_GREY_TEST_DISABLED(@"Multiple windows can't be opened.");
+
+  [ChromeEarlGrey closeAllNormalTabs];
+  [ChromeEarlGrey openNewIncognitoTab];
+  [ChromeEarlGrey loadURL:_URL1];
+  [ChromeEarlGrey waitForWebStateContainingText:kResponse1];
+  [ChromeEarlGrey loadURL:_URL3];
+  [ChromeEarlGrey waitForWebStateContainingText:kResponse3];
+
+  [ChromeEarlGrey openNewIncognitoTab];
+  [ChromeEarlGrey loadURL:_URL2];
+  [ChromeEarlGrey waitForWebStateContainingText:kResponse2];
+
+  [ChromeEarlGrey waitForIncognitoTabCount:2 inWindowWithNumber:0];
+
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
+      performAction:grey_tap()];
+
+  GREYWaitForAppToIdle(@"App failed to idle");
+
+  LongPressAndDragToEdge(IdentifierForCellAtIndex(0), kGREYContentEdgeRight);
+
+  GREYWaitForAppToIdle(@"App failed to idle");
+
+  // Assert two windows and the expected tabs in each.
+  [ChromeEarlGrey waitForForegroundWindowCount:2];
+  [ChromeEarlGrey waitForIncognitoTabCount:1 inWindowWithNumber:0];
+  [ChromeEarlGrey waitForIncognitoTabCount:1 inWindowWithNumber:1];
+  [ChromeEarlGrey waitForWebStateContainingText:kResponse2
+                             inWindowWithNumber:0];
+  [ChromeEarlGrey waitForWebStateContainingText:kResponse3
+                             inWindowWithNumber:1];
+
+  // Navigate back on second window to check the navigation stack is intact.
+  [EarlGrey setRootMatcherForSubsequentInteractions:chrome_test_util::
+                                                        WindowWithNumber(1)];
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()]
+      performAction:grey_tap()];
+  [ChromeEarlGrey waitForWebStateContainingText:kResponse1
+                             inWindowWithNumber:1];
+
+  [EarlGrey setRootMatcherForSubsequentInteractions:chrome_test_util::
+                                                        WindowWithNumber(0)];
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
+      performAction:grey_tap()];
+}
+
 #pragma mark - Helper Methods
 
 - (void)loadTestURLs {
   [ChromeEarlGrey loadURL:_URL1];
   [ChromeEarlGrey waitForWebStateContainingText:kResponse1];
 
+  [ChromeEarlGrey openNewTab];
   [ChromeEarlGrey loadURL:_URL2];
   [ChromeEarlGrey waitForWebStateContainingText:kResponse2];
 
+  [ChromeEarlGrey openNewTab];
   [ChromeEarlGrey loadURL:_URL3];
   [ChromeEarlGrey waitForWebStateContainingText:kResponse3];
 }
diff --git a/ios/chrome/browser/ui/util/ui_util.mm b/ios/chrome/browser/ui/util/ui_util.mm
index b7e1580..6c4057f 100644
--- a/ios/chrome/browser/ui/util/ui_util.mm
+++ b/ios/chrome/browser/ui/util/ui_util.mm
@@ -23,7 +23,7 @@
 
 // The em-width value used to differentiate small and large devices.
 // With Larger Text Off, Bold Text Off and the device orientation in portrait:
-// iPhone 6s is considered as a small device, unlike iPhone 8 or iPhone 12 mini.
+// iPhone 5s is considered as a small device, unlike iPhone 8 or iPhone 12 mini.
 const CGFloat kSmallDeviceThreshold = 22.0;
 
 }  // namespace
diff --git a/ios/chrome/browser/web/resources/credential_manager.js b/ios/chrome/browser/web/resources/credential_manager.js
deleted file mode 100644
index 2c0d83d..0000000
--- a/ios/chrome/browser/web/resources/credential_manager.js
+++ /dev/null
@@ -1,506 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview JavaScript implementation of the credential management API
- * defined at http://w3c.github.io/webappsec-credential-management
- * This is a minimal implementation that sends data to the app side to
- * integrate with the password manager. When loaded, installs the API onto
- * the window.navigator.object.
- */
-
-// TODO(crbug.com/435046) After get, store, preventSilentAccess are
-// implemented app-side, make sure that all tests at
-// https://w3c-test.org/credential-management/idl.https.html
-// pass.
-
-// TODO(crbug.com/435046) Declare Credential, PasswordCredential,
-// FederatedCredential and CredentialsContainer as classes once iOS9 is no
-// longer supported.
-
-// Namespace for credential management. __gCrWeb must have already
-// been defined.
-__gCrWeb.credentialManager = {
-
-  /**
-   * Used to apply unique promiseId fields to messages sent to host.
-   * Those IDs can be later used to call a corresponding resolver/rejecter.
-   * @private {number}
-   */
-  nextId_: 0,
-
-  /**
-   * Stores the functions for resolving Promises returned by
-   * navigator.credentials method calls. A resolver for a call with
-   * promiseId: |id| is stored at resolvers_[id].
-   * @type {!Object<number, function(?Credential)|function()>}
-   * @private
-   */
-  resolvers_: {},
-
-  /**
-   * Stores the functions for rejecting Promises returned by
-   * navigator.credentials method calls. A rejecter for a call with
-   * promiseId: |id| is stored at rejecters_[id].
-   * @type {!Object<number, function(?Error)>}
-   * @private
-   */
-  rejecters_: {}
-};
-
-__gCrWeb['credentialManager'] = __gCrWeb.credentialManager;
-
-/**
- * Creates and returns a Promise with given |promiseId|. The Promise's executor
- * function stores resolver and rejecter functions in
- * __gCrWeb['credentialManager'] under the key |promiseId| so they can be called
- * from the host after executing app side code.
- * @param {number} promiseId The number assigned to newly created Promise.
- * @return {!Promise<?Credential>|!Promise<!Credential>|!Promise<void>}
- *     The created Promise.
- * @private
- */
-__gCrWeb.credentialManager.createPromise_ = function(promiseId) {
-  return new Promise(function(resolve, reject) {
-    __gCrWeb.credentialManager.resolvers_[promiseId] = resolve;
-    __gCrWeb.credentialManager.rejecters_[promiseId] = reject;
-  });
-};
-
-/**
- * Sends a message to the app side, invoking |command| with the given |options|.
- * @param {string} command The name of the invoked command.
- * @param {Object} options A dictionary of additional properties to forward to
- *     the app.
- * @return {!Promise<?Credential>|!Promise<!Credential>|!Promise<void>}
- *     A promise to be returned by the calling method.
- * @private
- */
-__gCrWeb.credentialManager.invokeOnHost_ = function(command, options) {
-  var promiseId = __gCrWeb.credentialManager.nextId_++;
-  var message = {
-    'command': command,
-    'promiseId': promiseId
-  };
-  if (options) {
-    Object.assign(message, options);
-  }
-  __gCrWeb.message.invokeOnHost(message);
-  return __gCrWeb.credentialManager.createPromise_(promiseId);
-};
-
-/**
- * The Credential interface, for more information see
- * https://w3c.github.io/webappsec-credential-management/#the-credential-interface
- * @constructor
- */
-function Credential() {
-  /** @type {string} */
-  this.id;
-  /** @type {string} */
-  this.type;
-}
-Object.defineProperty(Credential.prototype, Symbol.toStringTag,
-    { value: 'Credential' });
-
-/**
- * PasswordCredential interace, for more information see
- * https://w3c.github.io/webappsec-credential-management/#passwordcredential-interface
- * @extends {Credential}
- * @param {PasswordCredentialInit} init Either a PasswordCredentialData or
- *     HTMLFormElement to create PasswordCredential from.
- * @constructor
- */
-function PasswordCredential(init) {
-  // TODO(crbug.com/435046): When iOS9 is no longer supported, change vars to
-  // |let| and |const| and declare at assignment.
-  /** @type {!PasswordCredentialData} */
-  var data;
-  var elements;
-  var elementIndex;
-  var newPasswordObserved;
-  var field;
-  var name;
-  var autocompleteTokens;
-  var token;
-  var tokenIndex;
-
-  if (init instanceof HTMLFormElement) {
-    // Performs following steps:
-    // https://www.w3.org/TR/credential-management-1/#abstract-opdef-create-a-passwordcredential-from-an-htmlformelement
-    data = /** @type {!PasswordCredentialData} */ ({});
-    elements = init.querySelectorAll( // all submittable elements
-        'button, input, object, select, textarea');
-    newPasswordObserved = false;
-    for (elementIndex = 0; elementIndex < elements.length;
-        elementIndex++) {
-      field = elements.item(elementIndex);
-      if (!field.hasAttribute('autocomplete')) {
-        continue;
-      }
-      name = field.name;
-      if (!init[name]) {
-        continue;
-      }
-      autocompleteTokens = field.getAttribute('autocomplete').split(' ');
-      for (tokenIndex = 0; tokenIndex < autocompleteTokens.length;
-          tokenIndex++) {
-        token = autocompleteTokens[tokenIndex];
-        if (token.toLowerCase() === 'new-password') {
-          data.password = init[name].value;
-          newPasswordObserved = true;
-        }
-        if (token.toLowerCase() === 'current-password') {
-          if (!newPasswordObserved) {
-            data.password = init[name].value;
-          }
-        }
-        if (token.toLowerCase() === 'photo') {
-          data.iconURL = init[name].value;
-        }
-        if (token.toLowerCase() === 'name') {
-          data.name = init[name].value;
-        }
-        if (token.toLowerCase() === 'nickname') {
-          data.name = init[name].value;
-        }
-        if (token.toLowerCase() === 'username') {
-          data.id = init[name].value;
-        }
-      }
-    }
-  } else {
-    // |init| was not HTMLFormElement so assuming it is PasswordCredentialData.
-    // Not checking with instanceof because any dictionary with required fields
-    // should be accepted.
-    data = /** @type {!PasswordCredentialData} */ (init);
-  }
-
-  // Perform following steps:
-  // https://w3c.github.io/webappsec-credential-management/#abstract-opdef-create-a-passwordcredential-from-passwordcredentialdata
-  if (!data.id || typeof data.id != 'string') {
-    throw new TypeError('id must be a non-empty string');
-  }
-  if (!data.password || typeof data.password != 'string') {
-    throw new TypeError('password must be a non-empty string');
-  }
-  if (data.iconURL && !data.iconURL.startsWith('https://')) {
-    throw new SyntaxError('invalid iconURL');
-  }
-  /** @type {string} */
-  this._id = data.id;
-  /** @type {string} */
-  this._type = 'password';
-  /** @type {string} */
-  this._password = data.password;
-  /** @type {string} */
-  this._iconURL = (data.iconURL ? data.iconURL : '');
-  /** @type {string} */
-  this._name = (data.name ? data.name : '');
-}
-
-PasswordCredential.prototype = {
-  __proto__: Credential.prototype
-};
-Object.defineProperty(PasswordCredential, 'prototype', { writable: false });
-
-PasswordCredential.prototype.constructor = PasswordCredential;
-Object.defineProperties(
-  PasswordCredential.prototype,
-  {
-    'constructor': {
-      enumerable: false
-    },
-    'id' : {
-      get: /** @this {PasswordCredential} */ function() {
-        return this._id;
-      }
-    },
-    'type' : {
-      get: /** @this {PasswordCredential} */ function() {
-        return this._type;
-      }
-    },
-    'password': {
-      get: /** @this {PasswordCredential} */ function() {
-        if (!(this instanceof PasswordCredential)) {
-          throw new TypeError('attempting to get a property on prototype');
-        }
-        return this._password;
-      },
-      configurable: true,
-      enumerable: true
-    },
-    'iconURL' : {
-      get: /** @this {PasswordCredential} */ function() {
-        return this._iconURL;
-      }
-    },
-    'name' : {
-      get: /** @this {PasswordCredential} */ function() {
-        return this._name;
-      }
-    }
-  }
-);
-Object.defineProperty(PasswordCredential.prototype, Symbol.toStringTag,
-    { value: 'PasswordCredential' });
-
-/**
- * FederatedCredential interface, for more information see
- * https://w3c.github.io/webappsec-credential-management/#federatedcredential-interface
- * @param {FederatedCredentialInit} init Dictionary to create
- *     FederatedCredential from.
- * @extends {Credential}
- * @constructor
- */
-function FederatedCredential(init) {
-  if (!init.id || typeof init.id != 'string') {
-    throw new TypeError('id must be a non-empty string');
-  }
-  if (!init.provider || typeof init.provider != 'string') {
-    throw new TypeError('provider must be a non-empty string');
-  }
-  if (!init.provider.startsWith('https://') &&
-      !init.provider.startsWith('http://')) {
-    throw new SyntaxError('invalid provider URL');
-  }
-  if (init.iconURL && !init.iconURL.startsWith('https://')) {
-    throw new SyntaxError('invalid iconURL');
-  }
-  /** @type {string} */
-  this._id = init.id;
-  /** @type {string} */
-  this._type = 'federated';
-  /** @type {string} */
-  this._name = (init.name ? init.name : '');
-  /** @type {string} */
-  this._iconURL = (init.iconURL ? init.iconURL : '');
-  /** @type {string} */
-  this._provider = init.provider.replace(/\/$/, ''); // strip trailing slash
-  /** @type {?string} */
-  this._protocol = (init.protocol ? init.protocol : '');
-}
-
-FederatedCredential.prototype = {
-  __proto__: Credential.prototype
-};
-Object.defineProperty(FederatedCredential, 'prototype', { writable: false });
-
-FederatedCredential.prototype.constructor = FederatedCredential;
-Object.defineProperties(
-  FederatedCredential.prototype,
-  {
-    'constructor': {
-      enumerable: false
-    },
-    'id' : {
-      get: /** @this {FederatedCredential} */ function() {
-        return this._id;
-      }
-    },
-    'type' : {
-      get: /** @this {FederatedCredential} */ function() {
-        return this._type;
-      }
-    },
-    'provider': {
-      get: /** @this {FederatedCredential} */ function() {
-        if (!(this instanceof FederatedCredential)) {
-          throw new TypeError('attempting to get a property on prototype');
-        }
-        return this._provider;
-      },
-      configurable: true,
-      enumerable: true
-    },
-    'protocol': {
-      get: /** @this {FederatedCredential} */ function() {
-        if (!(this instanceof FederatedCredential)) {
-          throw new TypeError('attempting to get a property on prototype');
-        }
-        return this._protocol;
-      },
-      configurable: true,
-      enumerable: true
-    },
-    'iconURL' : {
-      get: /** @this {FederatedCredential} */ function() {
-        return this._iconURL;
-      }
-    },
-    'name' : {
-      get: /** @this {FederatedCredential} */ function() {
-        return this._name;
-      }
-    }
-  }
-);
-Object.defineProperty(FederatedCredential.prototype, Symbol.toStringTag,
-    { value: 'FederatedCredential' });
-
-/**
- * CredentialData dictionary
- * https://w3c.github.io/webappsec-credential-management/#dictdef-credentialdata
- * @dict
- * @typedef {{id: string}}
- */
-var CredentialData;
-
-/**
- * PasswordCredentialData used for constructing PasswordCredential objects
- * https://w3c.github.io/webappsec-credential-management/#dictdef-passwordcredentialdata
- * @dict
- * @typedef {{
- *     id: string,
- *     name: string,
- *     iconURL: string,
- *     password: string
- * }}
- */
-var PasswordCredentialData;
-
-/**
- * Either PasswordCredentialData or HTMLFormElement used for constructing
- * a new PasswordCredential
- * https://www.w3.org/TR/credential-management-1/#typedefdef-passwordcredentialinit
- * @typedef {!PasswordCredentialData|HTMLFormElement}
- */
-var PasswordCredentialInit;
-
-/**
- * FederatedCredentialInit used for constructing FederatedCredential objects
- * https://w3c.github.io/webappsec-credential-management/#dictdef-federatedcredentialinit
- * @dict
- * @typedef {{
- *     id: string,
- *     name: string,
- *     iconURL: string,
- *     provider: string,
- *     protocol: string
- * }}
- */
-var FederatedCredentialInit;
-
-/**
- * The CredentialRequestOptions dictionary, for more information see
- * https://w3c.github.io/webappsec-credential-management/#credentialrequestoptions-dictionary
- * @dict
- * @typedef {{mediation: string}}
- */
-var CredentialRequestOptions;
-
-/**
- * The FederatedCredentialRequestOptions dictionary, for more information see
- * https://w3c.github.io/webappsec-credential-management/#dictdef-federatedcredentialrequestoptions
- * @dict
- * @typedef {{
- *     providers: !Array<string>,
- *     protocols: !Array<string>
- * }}
- */
-var FederatedCredentialRequestOptions;
-
-/**
- * The CredentialCreationOptions dictionary, for more information see
- * https://w3c.github.io/webappsec-credential-management/#credentialcreationoptions-dictionary
- * @dict
- * @typedef {{
- *     password: ?PasswordCredentialInit,
- *     federated: ?FederatedCredentialInit
- * }}
- */
-var CredentialCreationOptions;
-
-/**
- * Implements the public Credential Management API. For more information, see
- * https://w3c.github.io/webappsec-credential-management/#credentialscontainer
- * @constructor
- */
-function CredentialsContainer() {}
-
-Object.defineProperty(CredentialsContainer, 'prototype', { writable: false });
-
-CredentialsContainer.prototype.constructor = CredentialsContainer;
-Object.defineProperty(
-    CredentialsContainer.prototype, 'constructor', { enumerable: false });
-Object.defineProperty(CredentialsContainer.prototype, Symbol.toStringTag,
-    { value: 'CredentialsContainer' });
-
-/**
- * Performs the Request A Credential action described at
- * https://w3c.github.io/webappsec-credential-management/#abstract-opdef-request-a-credential
- * @param {!CredentialRequestOptions} options An optional dictionary of
- *     parameters for the request.
- * @return {!Promise<?Credential>} A promise for retrieving the result
- *     of the request.
- */
-CredentialsContainer.prototype.get = function(options) {
-  return __gCrWeb.credentialManager.invokeOnHost_(
-      'credentials.get', options);
-};
-
-/**
- * Performs the Store A Credential action described at
- * https://w3c.github.io/webappsec-credential-management/#abstract-opdef-store-a-credential
- * @param {!Credential} credential A credential object to store.
- * @return {!Promise<void>} A promise for retrieving the result
- *     of the request.
- */
-CredentialsContainer.prototype.store = function(credential) {
-  return __gCrWeb.credentialManager.invokeOnHost_(
-      'credentials.store', credential);
-};
-
-/**
- * Performs the Prevent Silent Access action described at
- * https://w3c.github.io/webappsec-credential-management/#abstract-opdef-prevent-silent-access
- * @return {!Promise<void>} A promise for retrieving the result
- *     of the request.
- */
-CredentialsContainer.prototype.preventSilentAccess = function() {
-  return __gCrWeb.credentialManager.invokeOnHost_(
-      'credentials.preventSilentAccess', {});
-};
-
-/**
- * Performs the Create A Credential action described at
- * https://w3c.github.io/webappsec-credential-management/#abstract-opdef-create-a-credential
- * @param {!CredentialCreationOptions} options An optional dictionary of
- *     of params for creating a new Credential object.
- * @return {!Promise<?Credential>} A promise for retrieving the result
- *     of the request.
- */
-CredentialsContainer.prototype.create = function(options) {
-  // According to
-  // https://w3c.github.io/webappsec-credential-management/#abstract-opdef-create-a-credential,
-  // we should also check for secure context. Instead it is done only in
-  // browser-side methods. Since public JS interface is exposed, user can create
-  // a Credential using a constructor anyway.
-  return new Promise(function(resolve, reject) {
-    try {
-      if (options && options.password && !options.federated) {
-        resolve(new PasswordCredential(options.password));
-        return;
-      }
-      if (options && options.federated && !options.password) {
-        resolve(new FederatedCredential(options.federated));
-        return;
-      }
-    } catch (err) {
-      reject(err);
-      return;
-    }
-    reject(Object.create(DOMException.prototype, {
-      name: {value: DOMException.NOT_SUPPORTED_ERR},
-      message: {value: 'Invalid CredentialRequestOptions'}
-    }));
-  });
-};
-
-/**
- * Install the public interface.
- * @type {!CredentialsContainer}
- */
-window.navigator.credentials = new CredentialsContainer();
diff --git a/ios/chrome/browser/window_activities/window_activity_helpers.h b/ios/chrome/browser/window_activities/window_activity_helpers.h
index d525c5a..d0ed36e5 100644
--- a/ios/chrome/browser/window_activities/window_activity_helpers.h
+++ b/ios/chrome/browser/window_activities/window_activity_helpers.h
@@ -62,6 +62,11 @@
 // within a browser.
 NSUserActivity* ActivityToMoveTab(NSString* tab_id);
 
+// Returns an activity based on |activity_to_adapt| info, changing its mode to
+// follow |incognito|.
+NSUserActivity* AdaptUserActivityToIncognito(NSUserActivity* activity_to_adapt,
+                                             bool incognito);
+
 // true if |activity| is one that indicates a URL load (including loading the
 // new tab page in a new tab).
 bool ActivityIsURLLoad(NSUserActivity* activity);
diff --git a/ios/chrome/browser/window_activities/window_activity_helpers.mm b/ios/chrome/browser/window_activities/window_activity_helpers.mm
index 82fced4..29d98f69 100644
--- a/ios/chrome/browser/window_activities/window_activity_helpers.mm
+++ b/ios/chrome/browser/window_activities/window_activity_helpers.mm
@@ -80,6 +80,21 @@
   return activity;
 }
 
+NSUserActivity* AdaptUserActivityToIncognito(NSUserActivity* activity_to_adapt,
+                                             bool incognito) {
+  if (([activity_to_adapt.activityType
+           isEqualToString:kLoadIncognitoURLActivityType] &&
+       !incognito) ||
+      ([activity_to_adapt.activityType isEqualToString:kLoadURLActivityType] &&
+       incognito)) {
+    NSUserActivity* activity = BaseActivityForURLOpening(incognito);
+    [activity addUserInfoEntriesFromDictionary:activity_to_adapt.userInfo];
+    return activity;
+  }
+
+  return activity_to_adapt;
+}
+
 bool ActivityIsURLLoad(NSUserActivity* activity) {
   return [activity.activityType isEqualToString:kLoadURLActivityType] ||
          [activity.activityType isEqualToString:kLoadIncognitoURLActivityType];
diff --git a/ios/chrome/test/app/window_test_util.h b/ios/chrome/test/app/window_test_util.h
index 2389e11b..7c8de60 100644
--- a/ios/chrome/test/app/window_test_util.h
+++ b/ios/chrome/test/app/window_test_util.h
@@ -6,6 +6,8 @@
 #ifndef IOS_CHROME_TEST_APP_WINDOW_TEST_UTIL_H_
 #define IOS_CHROME_TEST_APP_WINDOW_TEST_UTIL_H_
 
+#import <Foundation/Foundation.h>
+
 #include "base/compiler_specific.h"
 
 namespace web {
@@ -17,6 +19,12 @@
 // Gets current active WebState, in window with given number.
 web::WebState* GetCurrentWebStateForWindowWithNumber(int windowNumber);
 
+// Returns the number of main tabs, in window with given number.
+NSUInteger GetMainTabCountForWindowWithNumber(int windowNumber);
+
+// Returns the number of incognito tabs, in window with given number.
+NSUInteger GetIncognitoTabCountForWindowWithNumber(int windowNumber);
+
 }  // namespace chrome_test_util
 
 #endif
diff --git a/ios/chrome/test/app/window_test_util.mm b/ios/chrome/test/app/window_test_util.mm
index f423ca7..2e38fcf1 100644
--- a/ios/chrome/test/app/window_test_util.mm
+++ b/ios/chrome/test/app/window_test_util.mm
@@ -53,4 +53,16 @@
   return web_state_list ? web_state_list->GetActiveWebState() : nullptr;
 }
 
+NSUInteger GetMainTabCountForWindowWithNumber(int windowNumber) {
+  return GetInterfaceProviderForWindowWithNumber(windowNumber)
+      .mainInterface.browser->GetWebStateList()
+      ->count();
+}
+
+NSUInteger GetIncognitoTabCountForWindowWithNumber(int windowNumber) {
+  return GetInterfaceProviderForWindowWithNumber(windowNumber)
+      .incognitoInterface.browser->GetWebStateList()
+      ->count();
+}
+
 }  // namespace chrome_test_util
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn
index d2e2efc..46d29082 100644
--- a/ios/chrome/test/earl_grey/BUILD.gn
+++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -203,6 +203,8 @@
     "chrome_test_case.h",
     "chrome_test_case.mm",
     "chrome_test_case_app_interface.h",
+    "chrome_xcui_actions.h",
+    "chrome_xcui_actions.mm",
     "earl_grey_scoped_block_swizzler.h",
     "earl_grey_scoped_block_swizzler.mm",
     "earl_grey_scoped_block_swizzler_app_interface.h",
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.h b/ios/chrome/test/earl_grey/chrome_earl_grey.h
index 69a3f4a..99ecbeec 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey.h
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey.h
@@ -413,6 +413,16 @@
                               timeout:(NSTimeInterval)timeout
                    inWindowWithNumber:(int)windowNumber;
 
+// Waits for there to be |count| number of non-incognito tabs within a timeout,
+// or a GREYAssert is induced.
+- (void)waitForMainTabCount:(NSUInteger)count
+         inWindowWithNumber:(int)windowNumber;
+
+// Waits for there to be |count| number of incognito tabs within a timeout, or a
+// GREYAssert is induced.
+- (void)waitForIncognitoTabCount:(NSUInteger)count
+              inWindowWithNumber:(int)windowNumber;
+
 #pragma mark - SignIn Utilities (EG2)
 
 // Signs the user out, clears the known accounts entirely and checks whether the
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.mm b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
index 98b60b8..4c3eaed 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey.mm
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
@@ -932,8 +932,10 @@
                               timeout:(NSTimeInterval)timeout
                    inWindowWithNumber:(int)windowNumber {
   NSString* text = base::SysUTF8ToNSString(UTF8Text);
-  NSString* errorString = [NSString
-      stringWithFormat:@"Failed waiting for web state containing %@", text];
+  NSString* errorString =
+      [NSString stringWithFormat:@"Failed waiting for web state containing %@ "
+                                 @"in window with number %d",
+                                 text, windowNumber];
 
   GREYCondition* waitForText =
       [GREYCondition conditionWithName:errorString
@@ -946,6 +948,66 @@
   EG_TEST_HELPER_ASSERT_TRUE(containsText, errorString);
 }
 
+- (void)waitForMainTabCount:(NSUInteger)count
+         inWindowWithNumber:(int)windowNumber {
+  __block NSUInteger actualCount =
+      [ChromeEarlGreyAppInterface mainTabCountInWindowWithNumber:windowNumber];
+  NSString* conditionName = [NSString
+      stringWithFormat:@"Waiting for main tab count to become %" PRIuNS
+                        " from %" PRIuNS " in window with number %d",
+                       count, actualCount, windowNumber];
+
+  // Allow the UI to become idle, in case any tabs are being opened or closed.
+  GREYWaitForAppToIdle(@"App failed to idle");
+
+  GREYCondition* tabCountCheck = [GREYCondition
+      conditionWithName:conditionName
+                  block:^{
+                    actualCount = [ChromeEarlGreyAppInterface
+                        mainTabCountInWindowWithNumber:windowNumber];
+                    return actualCount == count;
+                  }];
+  bool tabCountEqual = [tabCountCheck waitWithTimeout:kWaitForUIElementTimeout];
+
+  NSString* errorString = [NSString
+      stringWithFormat:@"Failed waiting for main tab count to become %" PRIuNS
+                        " in window with number %d"
+                        "; actual count: %" PRIuNS,
+                       count, windowNumber, actualCount];
+  EG_TEST_HELPER_ASSERT_TRUE(tabCountEqual, errorString);
+}
+
+- (void)waitForIncognitoTabCount:(NSUInteger)count
+              inWindowWithNumber:(int)windowNumber {
+  __block NSUInteger actualCount =
+      [ChromeEarlGreyAppInterface mainTabCountInWindowWithNumber:windowNumber];
+  NSString* conditionName =
+      [NSString stringWithFormat:
+                    @"Failed waiting for incognito tab count to become %" PRIuNS
+                     " from %" PRIuNS " in window with number %d",
+                    count, actualCount, windowNumber];
+
+  // Allow the UI to become idle, in case any tabs are being opened or closed.
+  GREYWaitForAppToIdle(@"App failed to idle");
+
+  GREYCondition* tabCountCheck = [GREYCondition
+      conditionWithName:conditionName
+                  block:^{
+                    actualCount = [ChromeEarlGreyAppInterface
+                        incognitoTabCountInWindowWithNumber:windowNumber];
+                    return actualCount == count;
+                  }];
+  bool tabCountEqual = [tabCountCheck waitWithTimeout:kWaitForUIElementTimeout];
+
+  NSString* errorString =
+      [NSString stringWithFormat:
+                    @"Failed waiting for incognito tab count to become %" PRIuNS
+                     " in window with number %d"
+                     "; actual count: %" PRIuNS,
+                    count, windowNumber, actualCount];
+  EG_TEST_HELPER_ASSERT_TRUE(tabCountEqual, errorString);
+}
+
 #pragma mark - SignIn Utilities (EG2)
 
 - (void)signOutAndClearIdentities {
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h
index 425e9809..26ced42 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h
@@ -212,6 +212,12 @@
 + (BOOL)webStateContainsText:(NSString*)text
           inWindowWithNumber:(int)windowNumber;
 
+// Returns the number of open non-incognito tabs, in window with given number.
++ (NSUInteger)mainTabCountInWindowWithNumber:(int)windowNumber;
+
+// Returns the number of open incognito tabs, in window with given number.
++ (NSUInteger)incognitoTabCountInWindowWithNumber:(int)windowNumber;
+
 #pragma mark - WebState Utilities (EG2)
 
 // Attempts to tap the element with |element_id| within window.frames[0] of the
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
index 8fe584f..4e36e902 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
@@ -468,9 +468,20 @@
 
 + (BOOL)webStateContainsText:(NSString*)text
           inWindowWithNumber:(int)windowNumber {
-  return web::test::IsWebViewContainingText(
-      chrome_test_util::GetCurrentWebStateForWindowWithNumber(windowNumber),
-      base::SysNSStringToUTF8(text));
+  web::WebState* webState =
+      chrome_test_util::GetCurrentWebStateForWindowWithNumber(windowNumber);
+  return webState ? web::test::IsWebViewContainingText(
+                        webState, base::SysNSStringToUTF8(text))
+                  : NO;
+}
+
++ (NSUInteger)mainTabCountInWindowWithNumber:(int)windowNumber {
+  return chrome_test_util::GetMainTabCountForWindowWithNumber(windowNumber);
+}
+
++ (NSUInteger)incognitoTabCountInWindowWithNumber:(int)windowNumber {
+  return chrome_test_util::GetIncognitoTabCountForWindowWithNumber(
+      windowNumber);
 }
 
 #pragma mark - WebState Utilities (EG2)
diff --git a/ios/chrome/test/earl_grey/chrome_xcui_actions.h b/ios/chrome/test/earl_grey/chrome_xcui_actions.h
new file mode 100644
index 0000000..2429c3c
--- /dev/null
+++ b/ios/chrome/test/earl_grey/chrome_xcui_actions.h
@@ -0,0 +1,23 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_TEST_EARL_GREY_CHROME_XCUI_ACTIONS_H_
+#define IOS_CHROME_TEST_EARL_GREY_CHROME_XCUI_ACTIONS_H_
+
+#import <Foundation/Foundation.h>
+
+#import "ios/testing/earl_grey/earl_grey_test.h"
+
+namespace chrome_test_util {
+
+// Action (XCUI, hence local) to long press an item and drag it to the given
+// |edge| (which probably will trigger a new window) before dropping it.
+// Returns YES on success (finding the element with given
+// |accessibilityIdentifier|).
+BOOL LongPressAndDragToEdge(NSString* accessibilityIdentifier,
+                            GREYContentEdge edge);
+
+}  // namespace chrome_test_util
+
+#endif  // IOS_CHROME_TEST_EARL_GREY_CHROME_XCUI_ACTIONS_H_
diff --git a/ios/chrome/test/earl_grey/chrome_xcui_actions.mm b/ios/chrome/test/earl_grey/chrome_xcui_actions.mm
new file mode 100644
index 0000000..7adb71d
--- /dev/null
+++ b/ios/chrome/test/earl_grey/chrome_xcui_actions.mm
@@ -0,0 +1,55 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/test/earl_grey/chrome_xcui_actions.h"
+
+#import "base/mac/foundation_util.h"
+#import "ios/testing/earl_grey/earl_grey_test.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace chrome_test_util {
+
+BOOL LongPressAndDragToEdge(NSString* accessibilityIdentifier,
+                            GREYContentEdge edge) {
+  XCUIApplication* app = [[XCUIApplication alloc] init];
+  XCUIElementQuery* query =
+      [[app.windows descendantsMatchingType:XCUIElementTypeAny]
+          matchingIdentifier:accessibilityIdentifier];
+
+  if (query.count == 0)
+    return NO;
+  XCUIElement* dragElement = [query elementBoundByIndex:0];
+
+  CGVector edgeCenter;
+  switch (edge) {
+    case kGREYContentEdgeLeft:
+      edgeCenter = CGVectorMake(0.0, 0.5);
+      break;
+    case kGREYContentEdgeRight:
+      edgeCenter = CGVectorMake(1.0, 0.5);
+      break;
+    case kGREYContentEdgeTop:
+      edgeCenter = CGVectorMake(0.5, 0.0);
+      break;
+    case kGREYContentEdgeBottom:
+      edgeCenter = CGVectorMake(0.5, 1.0);
+      break;
+  }
+
+  XCUICoordinate* startPoint =
+      [dragElement coordinateWithNormalizedOffset:CGVectorMake(0.5, 0.5)];
+  XCUICoordinate* endPoint = [app coordinateWithNormalizedOffset:edgeCenter];
+
+  [startPoint pressForDuration:1.5
+          thenDragToCoordinate:endPoint
+                  withVelocity:XCUIGestureVelocityDefault
+           thenHoldForDuration:1.0];
+
+  return YES;
+}
+
+}  // namespace chrome_test_util
diff --git a/ios/web/js_messaging/java_script_feature_manager_unittest.mm b/ios/web/js_messaging/java_script_feature_manager_unittest.mm
index ac705966..4b6e5e7 100644
--- a/ios/web/js_messaging/java_script_feature_manager_unittest.mm
+++ b/ios/web/js_messaging/java_script_feature_manager_unittest.mm
@@ -62,7 +62,7 @@
 
   std::vector<const web::JavaScriptFeature::FeatureScript> feature_scripts = {
       web::JavaScriptFeature::FeatureScript::CreateWithFilename(
-          "java_script_feature_test_js",
+          "java_script_feature_test_inject_once_js",
           web::JavaScriptFeature::FeatureScript::InjectionTime::kDocumentStart,
           web::JavaScriptFeature::FeatureScript::TargetFrames::kAllFrames)};
 
@@ -94,7 +94,7 @@
 
   std::vector<const web::JavaScriptFeature::FeatureScript> feature_scripts = {
       web::JavaScriptFeature::FeatureScript::CreateWithFilename(
-          "java_script_feature_test_js",
+          "java_script_feature_test_inject_once_js",
           web::JavaScriptFeature::FeatureScript::InjectionTime::kDocumentEnd,
           web::JavaScriptFeature::FeatureScript::TargetFrames::kMainFrame)};
 
diff --git a/ios/web_view/internal/cwv_web_view.mm b/ios/web_view/internal/cwv_web_view.mm
index 269ad0e..c53fc21 100644
--- a/ios/web_view/internal/cwv_web_view.mm
+++ b/ios/web_view/internal/cwv_web_view.mm
@@ -356,9 +356,16 @@
 - (void)webState:(web::WebState*)webState
     didStartNavigation:(web::NavigationContext*)navigation {
   [self updateNavigationAvailability];
-  SEL selector = @selector(webViewDidStartProvisionalNavigation:);
-  if ([_navigationDelegate respondsToSelector:selector]) {
-    [_navigationDelegate webViewDidStartProvisionalNavigation:self];
+
+  if (!navigation->IsSameDocument()) {
+    SEL oldSelector = @selector(webViewDidStartProvisionalNavigation:);
+    if ([_navigationDelegate respondsToSelector:oldSelector]) {
+      [_navigationDelegate webViewDidStartProvisionalNavigation:self];
+    }
+    SEL newSelector = @selector(webViewDidStartNavigation:);
+    if ([_navigationDelegate respondsToSelector:newSelector]) {
+      [_navigationDelegate webViewDidStartNavigation:self];
+    }
   }
 }
 
@@ -370,7 +377,7 @@
   // TODO(crbug.com/898357): Remove this once crbug.com/898357 is fixed.
   [self updateVisibleSSLStatus];
 
-  if (navigation->HasCommitted() &&
+  if (navigation->HasCommitted() && !navigation->IsSameDocument() &&
       [_navigationDelegate
           respondsToSelector:@selector(webViewDidCommitNavigation:)]) {
     [_navigationDelegate webViewDidCommitNavigation:self];
diff --git a/ios/web_view/public/cwv_navigation_delegate.h b/ios/web_view/public/cwv_navigation_delegate.h
index 730a11c..6ad1615 100644
--- a/ios/web_view/public/cwv_navigation_delegate.h
+++ b/ios/web_view/public/cwv_navigation_delegate.h
@@ -48,8 +48,12 @@
                       forMainFrame:(BOOL)forMainFrame;
 
 // Notifies the delegate that main frame navigation has started.
+// Deprecated, use |webViewDidStartNavigation| instead.
 - (void)webViewDidStartProvisionalNavigation:(CWVWebView*)webView;
 
+// Notifies the delegate that main frame navigation has started.
+- (void)webViewDidStartNavigation:(CWVWebView*)webView;
+
 // Notifies the delegate that response data started arriving for
 // the main frame.
 - (void)webViewDidCommitNavigation:(CWVWebView*)webView;
diff --git a/ios/web_view/test/navigation_delegate_inttest.mm b/ios/web_view/test/navigation_delegate_inttest.mm
index 94f20df..44f18153f 100644
--- a/ios/web_view/test/navigation_delegate_inttest.mm
+++ b/ios/web_view/test/navigation_delegate_inttest.mm
@@ -59,6 +59,7 @@
                             navigationType:CWVNavigationTypeTyped])
       .andReturn(YES);
   OCMExpect([mock_delegate_ webViewDidStartProvisionalNavigation:web_view_]);
+  OCMExpect([mock_delegate_ webViewDidStartNavigation:web_view_]);
   OCMExpect([mock_delegate_ webView:web_view_
                 shouldContinueLoadWithResponse:ArgWithURL(GetEchoURL())
                                   forMainFrame:YES])
@@ -77,6 +78,7 @@
                             navigationType:CWVNavigationTypeTyped])
       .andReturn(YES);
   OCMExpect([mock_delegate_ webViewDidStartProvisionalNavigation:web_view_]);
+  OCMExpect([mock_delegate_ webViewDidStartNavigation:web_view_]);
   OCMExpect([mock_delegate_ webViewDidCommitNavigation:web_view_]);
   OCMExpect([mock_delegate_ webView:web_view_
          didFailNavigationWithError:[OCMArg any]]);
@@ -110,6 +112,7 @@
                             navigationType:CWVNavigationTypeTyped])
       .andReturn(YES);
   OCMExpect([mock_delegate_ webViewDidStartProvisionalNavigation:web_view_]);
+  OCMExpect([mock_delegate_ webViewDidStartNavigation:web_view_]);
   OCMExpect([mock_delegate_ webView:web_view_
                 shouldContinueLoadWithResponse:ArgWithURL(GetEchoURL())
                                   forMainFrame:YES])
@@ -119,4 +122,33 @@
   [(id)mock_delegate_ verify];
 }
 
+// Tests that same document navigations do not trigger delegate methods.
+TEST_F(NavigationDelegateTest, SameDocumentNavigations) {
+  // A request made with -loadRequest: has type CWVNavigationTypeTyped.
+  OCMExpect([mock_delegate_ webView:web_view_
+                shouldStartLoadWithRequest:ArgWithURL(GetEchoURL())
+                            navigationType:CWVNavigationTypeTyped])
+      .andReturn(YES);
+  OCMExpect([mock_delegate_ webViewDidStartProvisionalNavigation:web_view_]);
+  OCMExpect([mock_delegate_ webViewDidStartNavigation:web_view_]);
+  OCMExpect([mock_delegate_ webView:web_view_
+                shouldContinueLoadWithResponse:ArgWithURL(GetEchoURL())
+                                  forMainFrame:YES])
+      .andReturn(YES);
+  OCMExpect([mock_delegate_ webViewDidCommitNavigation:web_view_]);
+  OCMExpect([mock_delegate_ webViewDidFinishNavigation:web_view_]);
+
+  ASSERT_TRUE(test::LoadUrl(web_view_, GetEchoURL()));
+
+  [(id)mock_delegate_ verify];
+
+  // Same document navigations should not trigger the delegate methods.
+  NSError* error;
+  ASSERT_NSEQ(nil, test::EvaluateJavaScript(
+                       web_view_, @"history.pushState({}, \"\");", &error));
+  ASSERT_NSEQ(nil, error);
+
+  [(id)mock_delegate_ verify];
+}
+
 }  // namespace ios_web_view
diff --git a/media/base/async_destroy_video_decoder.h b/media/base/async_destroy_video_decoder.h
index 921109b0..948fa8c 100644
--- a/media/base/async_destroy_video_decoder.h
+++ b/media/base/async_destroy_video_decoder.h
@@ -35,6 +35,11 @@
       T::DestroyAsync(std::move(wrapped_decoder_));
   }
 
+  VideoDecoderType GetDecoderType() const override {
+    DCHECK(wrapped_decoder_);
+    return wrapped_decoder_->GetDecoderType();
+  }
+
   std::string GetDisplayName() const override {
     DCHECK(wrapped_decoder_);
     return wrapped_decoder_->GetDisplayName();
diff --git a/media/base/audio_decoder.h b/media/base/audio_decoder.h
index 7361e251..245ac29 100644
--- a/media/base/audio_decoder.h
+++ b/media/base/audio_decoder.h
@@ -87,6 +87,9 @@
   // Returns true if the decoder needs bitstream conversion before decoding.
   virtual bool NeedsBitstreamConversion() const;
 
+  // Returns the type of the decoder for statistics recording purposes.
+  virtual AudioDecoderType GetDecoderType() const = 0;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(AudioDecoder);
 };
diff --git a/media/base/decoder.cc b/media/base/decoder.cc
index 50c2b8d..8e06f1e2 100644
--- a/media/base/decoder.cc
+++ b/media/base/decoder.cc
@@ -18,4 +18,56 @@
   return false;
 }
 
+std::string GetDecoderName(VideoDecoderType type) {
+  switch (type) {
+    case VideoDecoderType::kUnknown:
+      return "Unknown Video Decoder";
+    case VideoDecoderType::kFFmpeg:
+      return "FFmpegVideoDecoder";
+    case VideoDecoderType::kVpx:
+      return "VpxVideoDecoder";
+    case VideoDecoderType::kAom:
+      return "AomVideoDecoder";
+    case VideoDecoderType::kMojo:
+      return "MojoVideoDecoder";
+    case VideoDecoderType::kDecrypting:
+      return "DecryptingVideoDecoder";
+    case VideoDecoderType::kDav1d:
+      return "Dav1dVideoDecoder";
+    case VideoDecoderType::kFuchsia:
+      return "FuchsiaVideoDecoder";
+    case VideoDecoderType::kMediaCodec:
+      return "MediaCodecVideoDecoder";
+    case VideoDecoderType::kGav1:
+      return "Gav1VideoDecoder";
+    case VideoDecoderType::kD3D11:
+      return "D3D11VideoDecoder";
+    case VideoDecoderType::kVaapi:
+      return "VaapiVideoDecodeAccelerator";
+    case VideoDecoderType::kBroker:
+      return "VideoDecoderBroker";
+    case VideoDecoderType::kChromeOs:
+      return "VideoDecoderPipeline (ChromeOs)";
+    case VideoDecoderType::kVda:
+      return "VideoDecodeAccelerator";
+  }
+}
+
+std::string GetDecoderName(AudioDecoderType type) {
+  switch (type) {
+    case AudioDecoderType::kUnknown:
+      return "Unknown Audio Decoder";
+    case AudioDecoderType::kFFmpeg:
+      return "FFmpegAudioDecoder";
+    case AudioDecoderType::kMojo:
+      return "MojoAudioDecoder";
+    case AudioDecoderType::kDecrypting:
+      return "DecryptingAudioDecoder";
+    case AudioDecoderType::kMediaCodec:
+      return "MediaCodecAudioDecoder";
+    case AudioDecoderType::kBroker:
+      return "AudioDecoderBroker";
+  }
+}
+
 }  // namespace media
diff --git a/media/base/decoder.h b/media/base/decoder.h
index 8ebec52..fb43f9c 100644
--- a/media/base/decoder.h
+++ b/media/base/decoder.h
@@ -14,6 +14,47 @@
 
 namespace media {
 
+// List of known AudioDecoder implementations; recorded to UKM, always add new
+// values to the end and do not reorder or delete values from this list.
+enum class AudioDecoderType : int {
+  kUnknown = 0,     // Decoder name string is not recognized or n/a.
+  kFFmpeg = 1,      // FFmpegAudioDecoder
+  kMojo = 2,        // MojoAudioDecoder
+  kDecrypting = 3,  // DecryptingAudioDecoder
+  kMediaCodec = 4,  // MediaCodecAudioDecoder (Android)
+  kBroker = 5,      // AudioDecoderBroker
+
+  kMaxValue = kBroker  // Keep this at the end and equal to the last entry.
+};
+
+// List of known VideoDecoder implementations; recorded to UKM, always add new
+// values to the end and do not reorder or delete values from this list.
+enum class VideoDecoderType : int {
+  kUnknown = 0,  // Decoder name string is not recognized or n/a.
+  // kGpu = 1,      // GpuVideoDecoder (DEPRECATED)
+  kFFmpeg = 2,      // FFmpegVideoDecoder
+  kVpx = 3,         // VpxVideoDecoder
+  kAom = 4,         // AomVideoDecoder
+  kMojo = 5,        // MojoVideoDecoder
+  kDecrypting = 6,  // DecryptingVideoDecoder
+  kDav1d = 7,       // Dav1dVideoDecoder
+  kFuchsia = 8,     // FuchsiaVideoDecoder
+  kMediaCodec = 9,  // MediaCodecVideoDecoder (Android)
+  kGav1 = 10,       // Gav1VideoDecoder
+  kD3D11 = 11,      // D3D11VideoDecoder
+  kVaapi = 12,      // VaapiVideoDecodeAccelerator
+  kBroker = 13,     // VideoDecoderBroker (Webcodecs)
+  kVda = 14,        // VDAVideoDecoder
+
+  // Chromeos uses VideoDecoderPipeline. This could potentially become more
+  // granulated in the future.
+  kChromeOs = 15,
+  kMaxValue = kChromeOs  // Keep this at the end and equal to the last entry.
+};
+
+MEDIA_EXPORT std::string GetDecoderName(AudioDecoderType type);
+MEDIA_EXPORT std::string GetDecoderName(VideoDecoderType type);
+
 class MEDIA_EXPORT Decoder {
  public:
   virtual ~Decoder();
diff --git a/media/base/ipc/DEPS b/media/base/ipc/DEPS
index 5d8ba2b..27ed9d9 100644
--- a/media/base/ipc/DEPS
+++ b/media/base/ipc/DEPS
@@ -2,3 +2,9 @@
   "+ipc",
   "-media/base/media_export.h",
 ]
+
+specific_include_rules = {
+  "media_param_traits_macros.h": [
+    "+third_party/blink/public/platform/web_fullscreen_video_status.h",
+  ]
+}
diff --git a/media/base/ipc/media_param_traits_macros.h b/media/base/ipc/media_param_traits_macros.h
index 53a4ea2f..70d23a0 100644
--- a/media/base/ipc/media_param_traits_macros.h
+++ b/media/base/ipc/media_param_traits_macros.h
@@ -17,6 +17,7 @@
 #include "media/base/container_names.h"
 #include "media/base/content_decryption_module.h"
 #include "media/base/decode_status.h"
+#include "media/base/decoder.h"
 #include "media/base/decrypt_config.h"
 #include "media/base/decryptor.h"
 #include "media/base/demuxer_stream.h"
@@ -39,6 +40,7 @@
 #include "media/base/watch_time_keys.h"
 #include "media/media_buildflags.h"
 #include "media/video/supported_video_decoder_config.h"
+#include "third_party/blink/public/platform/web_fullscreen_video_status.h"
 #include "ui/gfx/hdr_metadata.h"
 #include "ui/gfx/ipc/color/gfx_param_traits_macros.h"
 
@@ -48,6 +50,9 @@
 
 // Enum traits.
 
+IPC_ENUM_TRAITS_MAX_VALUE(blink::WebFullscreenVideoStatus,
+                          blink::WebFullscreenVideoStatus::kMaxValue)
+
 IPC_ENUM_TRAITS_MAX_VALUE(media::AudioCodec, media::AudioCodec::kAudioCodecMax)
 IPC_ENUM_TRAITS_MAX_VALUE(media::AudioCodecProfile,
                           media::AudioCodecProfile::kMaxValue)
@@ -126,6 +131,12 @@
 IPC_ENUM_TRAITS_MAX_VALUE(media::VideoDecoderImplementation,
                           media::VideoDecoderImplementation::kMaxValue)
 
+IPC_ENUM_TRAITS_MAX_VALUE(media::VideoDecoderType,
+                          media::VideoDecoderType::kMaxValue)
+
+IPC_ENUM_TRAITS_MAX_VALUE(media::AudioDecoderType,
+                          media::AudioDecoderType::kMaxValue)
+
 IPC_ENUM_TRAITS_MAX_VALUE(media::VideoPixelFormat, media::PIXEL_FORMAT_MAX)
 
 IPC_ENUM_TRAITS_MAX_VALUE(media::VideoRotation, media::VIDEO_ROTATION_MAX)
diff --git a/media/base/media_log_properties.cc b/media/base/media_log_properties.cc
index cdfbd8a..a21cf88 100644
--- a/media/base/media_log_properties.cc
+++ b/media/base/media_log_properties.cc
@@ -28,6 +28,8 @@
     STRINGIFY(kIsRangeHeaderSupported);
     STRINGIFY(kIsVideoDecryptingDemuxerStream);
     STRINGIFY(kIsAudioDecryptingDemuxerStream);
+    STRINGIFY(kVideoEncoderName);
+    STRINGIFY(kIsPlatformVideoEncoder);
     STRINGIFY(kAudioDecoderName);
     STRINGIFY(kIsPlatformAudioDecoder);
     STRINGIFY(kAudioTracks);
diff --git a/media/base/media_log_properties.h b/media/base/media_log_properties.h
index 5f6a1084..0f8a018 100644
--- a/media/base/media_log_properties.h
+++ b/media/base/media_log_properties.h
@@ -59,8 +59,8 @@
   kIsRangeHeaderSupported,
 
   // The name of the decoder implementation currently being used to play the
-  // media stream. All audio/video decoders have names, such as
-  // FFMpegVideoDecoder or D3D11VideoDecoder.
+  // media stream. All audio/video decoders have id numbers defined in
+  // decoder.h.
   kVideoDecoderName,
   kAudioDecoderName,
 
@@ -68,6 +68,10 @@
   kIsPlatformVideoDecoder,
   kIsPlatformAudioDecoder,
 
+  // Webcodecs supports encoding video streams.
+  kVideoEncoderName,
+  kIsPlatformVideoEncoder,
+
   // Whether this media player is using a decrypting demuxer for the given
   // audio or video stream.
   kIsVideoDecryptingDemuxerStream,
@@ -101,12 +105,14 @@
 MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kFrameUrl, std::string);
 MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kFrameTitle, std::string);
 MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kIsSingleOrigin, bool);
-MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kVideoDecoderName, std::string);
+MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kVideoDecoderName, VideoDecoderType);
 MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kIsPlatformVideoDecoder, bool);
 MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kIsRangeHeaderSupported, bool);
 MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kIsVideoDecryptingDemuxerStream, bool);
-MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kAudioDecoderName, std::string);
+MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kAudioDecoderName, AudioDecoderType);
 MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kIsPlatformAudioDecoder, bool);
+MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kVideoEncoderName, std::string);
+MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kIsPlatformVideoEncoder, bool);
 MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kIsAudioDecryptingDemuxerStream, bool);
 MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kAudioTracks, std::vector<AudioDecoderConfig>);
 MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kTextTracks, std::vector<TextTrackConfig>);
diff --git a/media/base/media_serializers.h b/media/base/media_serializers.h
index 42f89c0..5dbff1b 100644
--- a/media/base/media_serializers.h
+++ b/media/base/media_serializers.h
@@ -12,6 +12,7 @@
 #include "base/strings/stringprintf.h"
 #include "media/base/audio_decoder_config.h"
 #include "media/base/buffering_state.h"
+#include "media/base/decoder.h"
 #include "media/base/media_serializers_base.h"
 #include "media/base/status.h"
 #include "media/base/status_codes.h"
@@ -135,6 +136,22 @@
 
 // Enum (simple)
 template <>
+struct MediaSerializer<VideoDecoderType> {
+  static inline base::Value Serialize(VideoDecoderType value) {
+    return base::Value(GetDecoderName(value));
+  }
+};
+
+// Enum (simple)
+template <>
+struct MediaSerializer<AudioDecoderType> {
+  static inline base::Value Serialize(AudioDecoderType value) {
+    return base::Value(GetDecoderName(value));
+  }
+};
+
+// Enum (simple)
+template <>
 struct MediaSerializer<AudioCodec> {
   static inline base::Value Serialize(AudioCodec value) {
     return base::Value(GetCodecName(value));
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index f83450b7..1fde203 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -381,7 +381,7 @@
 // Show Cast sessions in Global Media Controls. It is no-op if
 // kGlobalMediaControls is not enabled.
 const base::Feature kGlobalMediaControlsForCast{
-    "GlobalMediaControlsForCast", base::FEATURE_DISABLED_BY_DEFAULT};
+    "GlobalMediaControlsForCast", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Allow Global Media Controls in system tray of CrOS.
 const base::Feature kGlobalMediaControlsForChromeOS{
diff --git a/media/base/mock_filters.cc b/media/base/mock_filters.cc
index 827694d..6fee057 100644
--- a/media/base/mock_filters.cc
+++ b/media/base/mock_filters.cc
@@ -101,6 +101,10 @@
   return decoder_name_;
 }
 
+VideoDecoderType MockVideoDecoder::GetDecoderType() const {
+  return VideoDecoderType::kUnknown;
+}
+
 MockVideoEncoder::MockVideoEncoder() = default;
 MockVideoEncoder::~MockVideoEncoder() {
   Dtor();
@@ -132,6 +136,10 @@
   return decoder_name_;
 }
 
+AudioDecoderType MockAudioDecoder::GetDecoderType() const {
+  return AudioDecoderType::kUnknown;
+}
+
 MockRendererClient::MockRendererClient() = default;
 
 MockRendererClient::~MockRendererClient() = default;
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index 5d1adb0d..3c4c764a 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -70,8 +70,8 @@
   MOCK_METHOD1(OnVideoOpacityChange, void(bool));
   MOCK_METHOD1(OnVideoFrameRateChange, void(base::Optional<int>));
   MOCK_METHOD0(OnVideoAverageKeyframeDistanceUpdate, void());
-  MOCK_METHOD1(OnAudioDecoderChange, void(const PipelineDecoderInfo&));
-  MOCK_METHOD1(OnVideoDecoderChange, void(const PipelineDecoderInfo&));
+  MOCK_METHOD1(OnAudioDecoderChange, void(const AudioDecoderInfo&));
+  MOCK_METHOD1(OnVideoDecoderChange, void(const VideoDecoderInfo&));
   MOCK_METHOD1(OnRemotePlayStateChange, void(MediaStatus::State state));
 };
 
@@ -229,6 +229,7 @@
   bool IsPlatformDecoder() const override;
   bool SupportsDecryption() const override;
   std::string GetDisplayName() const override;
+  VideoDecoderType GetDecoderType() const override;
 
   // VideoDecoder implementation.
   void Initialize(const VideoDecoderConfig& config,
@@ -314,6 +315,7 @@
   bool IsPlatformDecoder() const override;
   bool SupportsDecryption() const override;
   std::string GetDisplayName() const override;
+  AudioDecoderType GetDecoderType() const override;
 
   // AudioDecoder implementation.
   void Initialize(const AudioDecoderConfig& config,
diff --git a/media/base/pipeline.h b/media/base/pipeline.h
index 0fe23a7..3e1180fb 100644
--- a/media/base/pipeline.h
+++ b/media/base/pipeline.h
@@ -79,8 +79,8 @@
 
     // Executed whenever the underlying AudioDecoder or VideoDecoder changes
     // during playback.
-    virtual void OnAudioDecoderChange(const PipelineDecoderInfo& info) = 0;
-    virtual void OnVideoDecoderChange(const PipelineDecoderInfo& info) = 0;
+    virtual void OnAudioDecoderChange(const AudioDecoderInfo& info) = 0;
+    virtual void OnVideoDecoderChange(const VideoDecoderInfo& info) = 0;
 
     // Executed whenever the video frame rate changes.  |fps| will be unset if
     // the frame rate is unstable.  The duration used for the frame rate is
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc
index e3a33879..ea4df51a 100644
--- a/media/base/pipeline_impl.cc
+++ b/media/base/pipeline_impl.cc
@@ -20,6 +20,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "media/base/bind_to_current_loop.h"
 #include "media/base/cdm_context.h"
+#include "media/base/decoder.h"
 #include "media/base/demuxer.h"
 #include "media/base/media_log.h"
 #include "media/base/media_switches.h"
@@ -776,7 +777,7 @@
   shared_state_.statistics.audio_memory_usage += stats.audio_memory_usage;
   shared_state_.statistics.video_memory_usage += stats.video_memory_usage;
 
-  if (!stats.audio_decoder_info.decoder_name.empty() &&
+  if (stats.audio_decoder_info.decoder_type != AudioDecoderType::kUnknown &&
       stats.audio_decoder_info != shared_state_.statistics.audio_decoder_info) {
     shared_state_.statistics.audio_decoder_info = stats.audio_decoder_info;
     main_task_runner_->PostTask(
@@ -784,7 +785,7 @@
                                   weak_pipeline_, stats.audio_decoder_info));
   }
 
-  if (!stats.video_decoder_info.decoder_name.empty() &&
+  if (stats.video_decoder_info.decoder_type != VideoDecoderType::kUnknown &&
       stats.video_decoder_info != shared_state_.statistics.video_decoder_info) {
     shared_state_.statistics.video_decoder_info = stats.video_decoder_info;
     main_task_runner_->PostTask(
@@ -1631,7 +1632,7 @@
   client_->OnVideoAverageKeyframeDistanceUpdate();
 }
 
-void PipelineImpl::OnAudioDecoderChange(const PipelineDecoderInfo& info) {
+void PipelineImpl::OnAudioDecoderChange(const AudioDecoderInfo& info) {
   DVLOG(2) << __func__ << ": info=" << info;
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(IsRunning());
@@ -1640,7 +1641,7 @@
   client_->OnAudioDecoderChange(info);
 }
 
-void PipelineImpl::OnVideoDecoderChange(const PipelineDecoderInfo& info) {
+void PipelineImpl::OnVideoDecoderChange(const VideoDecoderInfo& info) {
   DVLOG(2) << __func__ << ": info=" << info;
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(IsRunning());
diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h
index 02d69d4..beb88ad 100644
--- a/media/base/pipeline_impl.h
+++ b/media/base/pipeline_impl.h
@@ -162,8 +162,8 @@
   void OnVideoNaturalSizeChange(const gfx::Size& size);
   void OnVideoOpacityChange(bool opaque);
   void OnVideoAverageKeyframeDistanceUpdate();
-  void OnAudioDecoderChange(const PipelineDecoderInfo& info);
-  void OnVideoDecoderChange(const PipelineDecoderInfo& info);
+  void OnAudioDecoderChange(const AudioDecoderInfo& info);
+  void OnVideoDecoderChange(const VideoDecoderInfo& info);
   void OnRemotePlayStateChange(MediaStatus::State state);
   void OnVideoFrameRateChange(base::Optional<int> fps);
 
diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc
index cb31db0..c3f41158 100644
--- a/media/base/pipeline_impl_unittest.cc
+++ b/media/base/pipeline_impl_unittest.cc
@@ -724,14 +724,14 @@
   StartPipelineAndExpect(PIPELINE_OK);
 
   PipelineStatistics stats;
-  stats.audio_decoder_info.decoder_name = "TestAudioDecoderName";
+  stats.audio_decoder_info.decoder_type = AudioDecoderType::kMojo;
   stats.audio_decoder_info.is_platform_decoder = false;
   EXPECT_CALL(callbacks_, OnAudioDecoderChange(_));
   renderer_client_->OnStatisticsUpdate(stats);
   base::RunLoop().RunUntilIdle();
 
   // VideoDecoderInfo changed and we expect OnVideoDecoderChange() to be called.
-  stats.video_decoder_info.decoder_name = "TestVideoDecoderName";
+  stats.video_decoder_info.decoder_type = VideoDecoderType::kMojo;
   stats.video_decoder_info.is_platform_decoder = true;
   EXPECT_CALL(callbacks_, OnVideoDecoderChange(_));
   renderer_client_->OnStatisticsUpdate(stats);
@@ -749,7 +749,7 @@
   base::RunLoop().RunUntilIdle();
 
   // Both info changed.
-  stats.audio_decoder_info.decoder_name = "NewTestAudioDecoderName";
+  stats.audio_decoder_info.decoder_type = AudioDecoderType::kFFmpeg;
   stats.video_decoder_info.has_decrypting_demuxer_stream = true;
   EXPECT_CALL(callbacks_, OnAudioDecoderChange(_));
   EXPECT_CALL(callbacks_, OnVideoDecoderChange(_));
diff --git a/media/base/pipeline_status.cc b/media/base/pipeline_status.cc
index a8e2487..ab7dfbe 100644
--- a/media/base/pipeline_status.cc
+++ b/media/base/pipeline_status.cc
@@ -162,24 +162,4 @@
   return !(first == second);
 }
 
-bool operator==(const PipelineDecoderInfo& first,
-                const PipelineDecoderInfo& second) {
-  return first.decoder_name == second.decoder_name &&
-         first.is_platform_decoder == second.is_platform_decoder &&
-         first.has_decrypting_demuxer_stream ==
-             second.has_decrypting_demuxer_stream;
-}
-
-bool operator!=(const PipelineDecoderInfo& first,
-                const PipelineDecoderInfo& second) {
-  return !(first == second);
-}
-
-std::ostream& operator<<(std::ostream& out, const PipelineDecoderInfo& info) {
-  return out << "{decoder_name:" << info.decoder_name << ","
-             << "is_platform_decoder:" << info.is_platform_decoder << ","
-             << "has_decrypting_demuxer_stream:"
-             << info.has_decrypting_demuxer_stream << "}";
-}
-
 }  // namespace media
diff --git a/media/base/pipeline_status.h b/media/base/pipeline_status.h
index f0ed3be..a9e4480 100644
--- a/media/base/pipeline_status.h
+++ b/media/base/pipeline_status.h
@@ -12,6 +12,7 @@
 #include "base/callback.h"
 #include "base/optional.h"
 #include "base/time/time.h"
+#include "media/base/decoder.h"
 #include "media/base/media_export.h"
 #include "media/base/status.h"
 #include "media/base/timestamp_constants.h"
@@ -77,18 +78,44 @@
 using PipelineStatusCB = base::RepeatingCallback<void(PipelineStatus)>;
 using PipelineStatusCallback = base::OnceCallback<void(PipelineStatus)>;
 
+template <typename DecoderTypeId>
 struct PipelineDecoderInfo {
   bool is_platform_decoder = false;
   bool has_decrypting_demuxer_stream = false;
-  std::string decoder_name;
+  DecoderTypeId decoder_type = DecoderTypeId::kUnknown;
 };
 
-MEDIA_EXPORT bool operator==(const PipelineDecoderInfo& first,
-                             const PipelineDecoderInfo& second);
-MEDIA_EXPORT bool operator!=(const PipelineDecoderInfo& first,
-                             const PipelineDecoderInfo& second);
-MEDIA_EXPORT std::ostream& operator<<(std::ostream& out,
-                                      const PipelineDecoderInfo& info);
+using AudioDecoderInfo = PipelineDecoderInfo<AudioDecoderType>;
+using VideoDecoderInfo = PipelineDecoderInfo<VideoDecoderType>;
+
+template <typename DecoderTypeId>
+MEDIA_EXPORT inline bool operator==(
+    const PipelineDecoderInfo<DecoderTypeId>& first,
+    const PipelineDecoderInfo<DecoderTypeId>& second) {
+  return first.decoder_type == second.decoder_type &&
+         first.is_platform_decoder == second.is_platform_decoder &&
+         first.has_decrypting_demuxer_stream ==
+             second.has_decrypting_demuxer_stream;
+}
+
+template <typename DecoderTypeId>
+MEDIA_EXPORT inline bool operator!=(
+    const PipelineDecoderInfo<DecoderTypeId>& first,
+    const PipelineDecoderInfo<DecoderTypeId>& second) {
+  return !(first == second);
+}
+
+template <typename DecoderTypeId>
+MEDIA_EXPORT inline std::ostream& operator<<(
+    std::ostream& out,
+    const PipelineDecoderInfo<DecoderTypeId>& info) {
+  // TODO(IN THIS CL DON'T FORGET) make a converter to print name.
+  return out << "{decoder_type:" << static_cast<int64_t>(info.decoder_type)
+             << ","
+             << "is_platform_decoder:" << info.is_platform_decoder << ","
+             << "has_decrypting_demuxer_stream:"
+             << info.has_decrypting_demuxer_stream << "}";
+}
 
 struct MEDIA_EXPORT PipelineStatistics {
   PipelineStatistics();
@@ -111,8 +138,8 @@
 
   // Note: Keep these fields at the end of the structure, if you move them you
   // need to also update the test ProtoUtilsTest::PipelineStatisticsConversion.
-  PipelineDecoderInfo audio_decoder_info;
-  PipelineDecoderInfo video_decoder_info;
+  AudioDecoderInfo audio_decoder_info;
+  VideoDecoderInfo video_decoder_info;
 
   // NOTE: always update operator== implementation in pipeline_status.cc when
   // adding a field to this struct. Leave this comment at the end.
diff --git a/media/base/video_decoder.h b/media/base/video_decoder.h
index 7f89465..8c6cb29 100644
--- a/media/base/video_decoder.h
+++ b/media/base/video_decoder.h
@@ -126,6 +126,12 @@
   // [|limits::kMinVideoDecodeThreads|, |limits::kMaxVideoDecodeThreads|].
   static int GetRecommendedThreadCount(int desired_threads);
 
+  // Returns the type of the decoder for statistics recording purposes.
+  // For meta-decoders (those which wrap other decoders, ie, MojoVideoDecoder)
+  // this should return the underlying type, if it is known, otherwise return
+  // its own type.
+  virtual VideoDecoderType GetDecoderType() const = 0;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(VideoDecoder);
 };
diff --git a/media/base/video_util.cc b/media/base/video_util.cc
index 7ed9735..5f26611 100644
--- a/media/base/video_util.cc
+++ b/media/base/video_util.cc
@@ -96,6 +96,166 @@
   return {kUnknown_SkColorType, 0};
 }
 
+scoped_refptr<VideoFrame> ReadbackTextureBackedFrameToMemorySyncGLES(
+    const VideoFrame& txt_frame,
+    gpu::raster::RasterInterface* ri,
+    GrDirectContext* gr_context,
+    VideoFramePool* pool) {
+  DCHECK(gr_context);
+
+  if (txt_frame.NumTextures() > 2 || txt_frame.NumTextures() < 1) {
+    DLOG(ERROR) << "Readback is not possible for this frame: "
+                << txt_frame.AsHumanReadableString();
+    return nullptr;
+  }
+
+  VideoPixelFormat result_format = txt_frame.format();
+  if (txt_frame.NumTextures() == 1 && result_format == PIXEL_FORMAT_NV12) {
+    // Even though |txt_frame| format is NV12 and it is NV12 in GPU memory,
+    // the texture is a RGB view that is produced by a shader on the fly.
+    // So we currently we currently can only read it back as RGB.
+    result_format = PIXEL_FORMAT_ARGB;
+  }
+
+  scoped_refptr<VideoFrame> result =
+      pool
+          ? pool->CreateFrame(result_format, txt_frame.coded_size(),
+                              txt_frame.visible_rect(),
+                              txt_frame.natural_size(), txt_frame.timestamp())
+          : VideoFrame::CreateFrame(
+                result_format, txt_frame.coded_size(), txt_frame.visible_rect(),
+                txt_frame.natural_size(), txt_frame.timestamp());
+  result->set_color_space(txt_frame.ColorSpace());
+  result->metadata().MergeMetadataFrom(txt_frame.metadata());
+
+  size_t planes = VideoFrame::NumPlanes(result->format());
+  for (size_t plane = 0; plane < planes; plane++) {
+    const gpu::MailboxHolder& holder = txt_frame.mailbox_holder(plane);
+    if (holder.mailbox.IsZero())
+      return nullptr;
+    ri->WaitSyncTokenCHROMIUM(holder.sync_token.GetConstData());
+
+    int width = VideoFrame::Columns(plane, result->format(),
+                                    result->coded_size().width());
+    int height = result->rows(plane);
+
+    auto texture_id = ri->CreateAndConsumeForGpuRaster(holder.mailbox);
+    if (holder.mailbox.IsSharedImage()) {
+      ri->BeginSharedImageAccessDirectCHROMIUM(
+          texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
+    }
+
+    auto cleanup_fn = [](GLuint texture_id, bool shared,
+                         gpu::raster::RasterInterface* ri) {
+      if (shared)
+        ri->EndSharedImageAccessDirectCHROMIUM(texture_id);
+      ri->DeleteGpuRasterTexture(texture_id);
+    };
+    base::ScopedClosureRunner cleanup(base::BindOnce(
+        cleanup_fn, texture_id, holder.mailbox.IsSharedImage(), ri));
+
+    GrGLenum texture_format;
+    SkColorType sk_color_type;
+    std::tie(sk_color_type, texture_format) =
+        GetSkiaAndGlColorTypesForPlane(result->format(), plane);
+    GrGLTextureInfo gl_texture_info;
+    gl_texture_info.fID = texture_id;
+    gl_texture_info.fTarget = holder.texture_target;
+    gl_texture_info.fFormat = texture_format;
+
+    GrBackendTexture texture(width, height, GrMipMapped::kNo, gl_texture_info);
+    auto image = SkImage::MakeFromTexture(
+        gr_context, texture, kTopLeft_GrSurfaceOrigin, sk_color_type,
+        kOpaque_SkAlphaType, nullptr /* colorSpace */);
+
+    if (!image) {
+      DLOG(ERROR) << "Can't create SkImage from texture!"
+                  << " plane:" << plane;
+      return nullptr;
+    }
+
+    auto info =
+        SkImageInfo::Make(width, height, sk_color_type, kOpaque_SkAlphaType);
+    SkPixmap pixmap(info, result->data(plane), result->row_bytes(plane));
+    if (!image->readPixels(gr_context, pixmap, 0, 0,
+                           SkImage::kDisallow_CachingHint)) {
+      DLOG(ERROR) << "Plane readback failed."
+                  << " plane:" << plane << " width: " << width
+                  << " height: " << height
+                  << " minRowBytes: " << info.minRowBytes();
+      return nullptr;
+    }
+  }
+
+  return result;
+}
+
+scoped_refptr<VideoFrame> ReadbackTextureBackedFrameToMemorySyncOOP(
+    const VideoFrame& txt_frame,
+    gpu::raster::RasterInterface* ri,
+    VideoFramePool* pool) {
+  if (txt_frame.NumTextures() > 2 || txt_frame.NumTextures() < 1) {
+    DLOG(ERROR) << "Readback is not possible for this frame: "
+                << txt_frame.AsHumanReadableString();
+    return nullptr;
+  }
+
+  VideoPixelFormat result_format = txt_frame.format();
+  if (txt_frame.NumTextures() == 1 && result_format == PIXEL_FORMAT_NV12) {
+    // Even though |txt_frame| format is NV12 and it is NV12 in GPU memory,
+    // the texture is a RGB view that is produced by a shader on the fly.
+    // So we currently we currently can only read it back as RGB.
+    result_format = PIXEL_FORMAT_ARGB;
+  }
+
+  scoped_refptr<VideoFrame> result =
+      pool
+          ? pool->CreateFrame(result_format, txt_frame.coded_size(),
+                              txt_frame.visible_rect(),
+                              txt_frame.natural_size(), txt_frame.timestamp())
+          : VideoFrame::CreateFrame(
+                result_format, txt_frame.coded_size(), txt_frame.visible_rect(),
+                txt_frame.natural_size(), txt_frame.timestamp());
+  result->set_color_space(txt_frame.ColorSpace());
+  result->metadata().MergeMetadataFrom(txt_frame.metadata());
+
+  size_t planes = VideoFrame::NumPlanes(result->format());
+  for (size_t plane = 0; plane < planes; plane++) {
+    const gpu::MailboxHolder& holder = txt_frame.mailbox_holder(plane);
+    if (holder.mailbox.IsZero()) {
+      DLOG(ERROR) << "Can't readback video frame with Zero texture on plane "
+                  << plane;
+      return nullptr;
+    }
+    ri->WaitSyncTokenCHROMIUM(holder.sync_token.GetConstData());
+
+    int width = VideoFrame::Columns(plane, result->format(),
+                                    result->coded_size().width());
+    int height = result->rows(plane);
+
+    GrGLenum texture_format;
+    SkColorType sk_color_type;
+    std::tie(sk_color_type, texture_format) =
+        GetSkiaAndGlColorTypesForPlane(result->format(), plane);
+
+    auto info =
+        SkImageInfo::Make(width, height, sk_color_type, kOpaque_SkAlphaType);
+
+    ri->ReadbackImagePixels(holder.mailbox, info, info.minRowBytes(), 0, 0,
+                            result->data(plane));
+    if (ri->GetError() != GL_NO_ERROR) {
+      DLOG(ERROR) << "Plane readback failed."
+                  << " plane:" << plane << " width: " << width
+                  << " height: " << height
+                  << " minRowBytes: " << info.minRowBytes()
+                  << " error: " << ri->GetError();
+      return nullptr;
+    }
+  }
+
+  return result;
+}
+
 }  // namespace
 
 double GetPixelAspectRatio(const gfx::Rect& visible_rect,
@@ -551,93 +711,12 @@
     GrDirectContext* gr_context,
     VideoFramePool* pool) {
   DCHECK(ri);
-  DCHECK(gr_context);
 
-  if (txt_frame.NumTextures() > 2 || txt_frame.NumTextures() < 1) {
-    DLOG(ERROR) << "Readback is not possible for this frame: "
-                << txt_frame.AsHumanReadableString();
-    return nullptr;
+  if (gr_context) {
+    return ReadbackTextureBackedFrameToMemorySyncGLES(txt_frame, ri, gr_context,
+                                                      pool);
   }
-
-  VideoPixelFormat result_format = txt_frame.format();
-  if (txt_frame.NumTextures() == 1 && result_format == PIXEL_FORMAT_NV12) {
-    // Even though |txt_frame| format is NV12 and it is NV12 in GPU memory,
-    // the texture is a RGB view that is produced by a shader on the fly.
-    // So we currently we currently can only read it back as RGB.
-    result_format = PIXEL_FORMAT_ARGB;
-  }
-
-  scoped_refptr<VideoFrame> result =
-      pool
-          ? pool->CreateFrame(result_format, txt_frame.coded_size(),
-                              txt_frame.visible_rect(),
-                              txt_frame.natural_size(), txt_frame.timestamp())
-          : VideoFrame::CreateFrame(
-                result_format, txt_frame.coded_size(), txt_frame.visible_rect(),
-                txt_frame.natural_size(), txt_frame.timestamp());
-  result->set_color_space(txt_frame.ColorSpace());
-  result->metadata().MergeMetadataFrom(txt_frame.metadata());
-
-  size_t planes = VideoFrame::NumPlanes(result->format());
-  for (size_t plane = 0; plane < planes; plane++) {
-    const gpu::MailboxHolder& holder = txt_frame.mailbox_holder(plane);
-    if (holder.mailbox.IsZero())
-      return nullptr;
-    ri->WaitSyncTokenCHROMIUM(holder.sync_token.GetConstData());
-
-    int width = VideoFrame::Columns(plane, result->format(),
-                                    result->coded_size().width());
-    int height = result->rows(plane);
-
-    auto texture_id = ri->CreateAndConsumeForGpuRaster(holder.mailbox);
-    if (holder.mailbox.IsSharedImage()) {
-      ri->BeginSharedImageAccessDirectCHROMIUM(
-          texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
-    }
-
-    auto cleanup_fn = [](GLuint texture_id, bool shared,
-                         gpu::raster::RasterInterface* ri) {
-      if (shared)
-        ri->EndSharedImageAccessDirectCHROMIUM(texture_id);
-      ri->DeleteGpuRasterTexture(texture_id);
-    };
-    base::ScopedClosureRunner cleanup(base::BindOnce(
-        cleanup_fn, texture_id, holder.mailbox.IsSharedImage(), ri));
-
-    GrGLenum texture_format;
-    SkColorType sk_color_type;
-    std::tie(sk_color_type, texture_format) =
-        GetSkiaAndGlColorTypesForPlane(result->format(), plane);
-    GrGLTextureInfo gl_texture_info;
-    gl_texture_info.fID = texture_id;
-    gl_texture_info.fTarget = holder.texture_target;
-    gl_texture_info.fFormat = texture_format;
-
-    GrBackendTexture texture(width, height, GrMipMapped::kNo, gl_texture_info);
-    auto image = SkImage::MakeFromTexture(
-        gr_context, texture, kTopLeft_GrSurfaceOrigin, sk_color_type,
-        kOpaque_SkAlphaType, nullptr /* colorSpace */);
-
-    if (!image) {
-      DLOG(ERROR) << "Can't create SkImage from texture!"
-                  << " plane:" << plane;
-      return nullptr;
-    }
-
-    auto info =
-        SkImageInfo::Make(width, height, sk_color_type, kOpaque_SkAlphaType);
-    SkPixmap pixmap(info, result->data(plane), result->row_bytes(plane));
-    if (!image->readPixels(gr_context, pixmap, 0, 0,
-                           SkImage::kDisallow_CachingHint)) {
-      DLOG(ERROR) << "Plane readback failed."
-                  << " plane:" << plane << " width: " << width
-                  << " height: " << height
-                  << " minRowBytes: " << info.minRowBytes();
-      return nullptr;
-    }
-  }
-
-  return result;
+  return ReadbackTextureBackedFrameToMemorySyncOOP(txt_frame, ri, pool);
 }
 
 Status ConvertAndScaleFrame(const VideoFrame& src_frame,
diff --git a/media/blink/watch_time_reporter_unittest.cc b/media/blink/watch_time_reporter_unittest.cc
index 7626b30c..6c3a63cb 100644
--- a/media/blink/watch_time_reporter_unittest.cc
+++ b/media/blink/watch_time_reporter_unittest.cc
@@ -277,8 +277,8 @@
     void SetHaveEnough() override {}
     void SetHasAudio(AudioCodec audio_codec) override {}
     void SetHasVideo(VideoCodec video_codec) override {}
-    void SetVideoPipelineInfo(const PipelineDecoderInfo& info) override {}
-    void SetAudioPipelineInfo(const PipelineDecoderInfo& info) override {}
+    void SetVideoPipelineInfo(const VideoDecoderInfo& info) override {}
+    void SetAudioPipelineInfo(const AudioDecoderInfo& info) override {}
 
    private:
     WatchTimeReporterTest* parent_;
@@ -1106,8 +1106,8 @@
       has_video_ ? kCodecH264 : kUnknownVideoCodec,
       has_audio_ ? AudioCodecProfile::kXHE_AAC : AudioCodecProfile::kUnknown,
       has_video_ ? H264PROFILE_MAIN : VIDEO_CODEC_PROFILE_UNKNOWN,
-      has_audio_ ? "FirstAudioDecoder" : "",
-      has_video_ ? "FirstVideoDecoder" : "",
+      has_audio_ ? AudioDecoderType::kMojo : AudioDecoderType::kUnknown,
+      has_video_ ? VideoDecoderType::kMojo : VideoDecoderType::kUnknown,
       has_audio_ ? EncryptionScheme::kCenc : EncryptionScheme::kUnencrypted,
       has_video_ ? EncryptionScheme::kCbcs : EncryptionScheme::kUnencrypted,
       has_video_ ? gfx::Size(800, 600) : gfx::Size());
@@ -1143,7 +1143,8 @@
       .Times((has_audio_ && has_video_) ? 3 : 2);
   wtr_->UpdateSecondaryProperties(mojom::SecondaryPlaybackProperties::New(
       kUnknownAudioCodec, kUnknownVideoCodec, AudioCodecProfile::kUnknown,
-      VIDEO_CODEC_PROFILE_UNKNOWN, "", "", EncryptionScheme::kUnencrypted,
+      VIDEO_CODEC_PROFILE_UNKNOWN, AudioDecoderType::kUnknown,
+      VideoDecoderType::kUnknown, EncryptionScheme::kUnencrypted,
       EncryptionScheme::kUnencrypted, kSizeJustRight));
   EXPECT_TRUE(IsMonitoring());
 
@@ -1165,7 +1166,8 @@
       .Times((has_audio_ && has_video_) ? 3 : 2);
   wtr_->UpdateSecondaryProperties(mojom::SecondaryPlaybackProperties::New(
       kUnknownAudioCodec, kUnknownVideoCodec, AudioCodecProfile::kUnknown,
-      VIDEO_CODEC_PROFILE_UNKNOWN, "", "", EncryptionScheme::kUnencrypted,
+      VIDEO_CODEC_PROFILE_UNKNOWN, AudioDecoderType::kUnknown,
+      VideoDecoderType::kUnknown, EncryptionScheme::kUnencrypted,
       EncryptionScheme::kUnencrypted, kSizeTooSmall));
   EXPECT_WATCH_TIME_FINALIZED();
   CycleReportingTimer();
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index 54b081e..bf944a5 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -668,8 +668,6 @@
 
 void WebMediaPlayerImpl::SetIsEffectivelyFullscreen(
     blink::WebFullscreenVideoStatus fullscreen_video_status) {
-  delegate_->SetIsEffectivelyFullscreen(delegate_id_, fullscreen_video_status);
-
   if (power_status_helper_) {
     // We don't care about pip, so anything that's "not fullscreen" is good
     // enough for us.
@@ -1065,7 +1063,7 @@
   DCHECK(bridge_->GetSurfaceId().is_valid());
 }
 
-void WebMediaPlayerImpl::SetSinkId(
+bool WebMediaPlayerImpl::SetSinkId(
     const blink::WebString& sink_id,
     blink::WebSetSinkIdCompleteCallback completion_callback) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
@@ -1077,7 +1075,7 @@
   media_task_runner_->PostTask(
       FROM_HERE, base::BindOnce(&SetSinkIdOnMediaThread, audio_source_provider_,
                                 sink_id_utf8, std::move(callback)));
-  delegate_->DidAudioOutputSinkChange(delegate_id_, sink_id_utf8);
+  return true;
 }
 
 STATIC_ASSERT_ENUM(WebMediaPlayer::kPreloadNone, MultibufferDataSource::NONE);
@@ -2484,12 +2482,12 @@
   UpdateBackgroundVideoOptimizationState();
 }
 
-void WebMediaPlayerImpl::OnAudioDecoderChange(const PipelineDecoderInfo& info) {
+void WebMediaPlayerImpl::OnAudioDecoderChange(const AudioDecoderInfo& info) {
   media_metrics_provider_->SetAudioPipelineInfo(info);
-  if (info.decoder_name == audio_decoder_name_)
+  if (info.decoder_type == audio_decoder_type_)
     return;
 
-  audio_decoder_name_ = info.decoder_name;
+  audio_decoder_type_ = info.decoder_type;
 
   // If there's no current reporter, there's nothing to be done.
   if (!watch_time_reporter_)
@@ -2498,12 +2496,12 @@
   UpdateSecondaryProperties();
 }
 
-void WebMediaPlayerImpl::OnVideoDecoderChange(const PipelineDecoderInfo& info) {
+void WebMediaPlayerImpl::OnVideoDecoderChange(const VideoDecoderInfo& info) {
   media_metrics_provider_->SetVideoPipelineInfo(info);
-  if (info.decoder_name == video_decoder_name_)
+  if (info.decoder_type == video_decoder_type_)
     return;
 
-  video_decoder_name_ = info.decoder_name;
+  video_decoder_type_ = info.decoder_type;
 
   // If there's no current reporter, there's nothing to be done.
   if (!watch_time_reporter_)
@@ -3439,7 +3437,7 @@
           pipeline_metadata_.video_decoder_config.codec(),
           pipeline_metadata_.audio_decoder_config.profile(),
           pipeline_metadata_.video_decoder_config.profile(),
-          audio_decoder_name_, video_decoder_name_,
+          audio_decoder_type_, video_decoder_type_,
           pipeline_metadata_.audio_decoder_config.encryption_scheme(),
           pipeline_metadata_.video_decoder_config.encryption_scheme(),
           pipeline_metadata_.natural_size));
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h
index eb16f17..d78bd9a0 100644
--- a/media/blink/webmediaplayer_impl.h
+++ b/media/blink/webmediaplayer_impl.h
@@ -136,7 +136,7 @@
   void SetAutoplayInitiated(bool autoplay_initiated) override;
   void OnRequestPictureInPicture() override;
   void OnTimeUpdate() override;
-  void SetSinkId(
+  bool SetSinkId(
       const blink::WebString& sink_id,
       blink::WebSetSinkIdCompleteCallback completion_callback) override;
   void SetPoster(const blink::WebURL& poster) override;
@@ -360,8 +360,8 @@
   void OnVideoOpacityChange(bool opaque) override;
   void OnVideoFrameRateChange(base::Optional<int> fps) override;
   void OnVideoAverageKeyframeDistanceUpdate() override;
-  void OnAudioDecoderChange(const PipelineDecoderInfo& info) override;
-  void OnVideoDecoderChange(const PipelineDecoderInfo& info) override;
+  void OnAudioDecoderChange(const AudioDecoderInfo& info) override;
+  void OnVideoDecoderChange(const VideoDecoderInfo& info) override;
 
   // Simplified watch time reporting.
   void OnSimpleWatchTimerTick();
@@ -892,8 +892,8 @@
 
   // Monitors the watch time of the played content.
   std::unique_ptr<blink::WatchTimeReporter> watch_time_reporter_;
-  std::string audio_decoder_name_;
-  std::string video_decoder_name_;
+  AudioDecoderType audio_decoder_type_ = AudioDecoderType::kUnknown;
+  VideoDecoderType video_decoder_type_ = VideoDecoderType::kUnknown;
 
   // The time at which DoLoad() is executed.
   base::TimeTicks load_start_time_;
diff --git a/media/blink/webmediaplayer_impl_unittest.cc b/media/blink/webmediaplayer_impl_unittest.cc
index 44898c1e..f312861 100644
--- a/media/blink/webmediaplayer_impl_unittest.cc
+++ b/media/blink/webmediaplayer_impl_unittest.cc
@@ -240,12 +240,6 @@
     return is_stale_;
   }
 
-  void SetIsEffectivelyFullscreen(
-      int player_id,
-      blink::WebFullscreenVideoStatus fullscreen_video_status) override {
-    DCHECK_EQ(player_id_, player_id);
-  }
-
   bool IsFrameHidden() override { return is_hidden_; }
 
   bool IsFrameClosed() override { return is_closed_; }
@@ -273,8 +267,6 @@
 
   int player_id() { return player_id_; }
 
-  MOCK_METHOD2(DidAudioOutputSinkChange, void(int, const std::string&));
-
  private:
   Observer* observer_ = nullptr;
   int player_id_ = 1234;
diff --git a/media/capture/video/mac/sample_buffer_transformer_mac.cc b/media/capture/video/mac/sample_buffer_transformer_mac.cc
index 80670d8d..043381c 100644
--- a/media/capture/video/mac/sample_buffer_transformer_mac.cc
+++ b/media/capture/video/mac/sample_buffer_transformer_mac.cc
@@ -434,13 +434,17 @@
 }  // namespace
 
 // static
+const SampleBufferTransformer::Transformer
+    SampleBufferTransformer::kBestTransformerForPixelBufferToNv12Output =
+        SampleBufferTransformer::Transformer::kPixelBufferTransfer;
+
+// static
 SampleBufferTransformer::Transformer
 SampleBufferTransformer::GetBestTransformerForNv12Output(
     CMSampleBufferRef sample_buffer) {
-  if (CMSampleBufferGetImageBuffer(sample_buffer)) {
-    // Pixel transfers are more efficient for converting to NV12 and is
-    // supported for any pixel buffer.
-    return Transformer::kPixelBufferTransfer;
+  if (CVPixelBufferRef pixel_buffer =
+          CMSampleBufferGetImageBuffer(sample_buffer)) {
+    return kBestTransformerForPixelBufferToNv12Output;
   }
   // When we don't have a pixel buffer (e.g. it's MJPEG or we get a SW-backed
   // byte buffer) only libyuv is able to perform the transform.
@@ -502,21 +506,20 @@
 }
 
 base::ScopedCFTypeRef<CVPixelBufferRef> SampleBufferTransformer::Transform(
-    CMSampleBufferRef sample_buffer) {
+    CVPixelBufferRef pixel_buffer) {
   DCHECK(transformer_ != Transformer::kNotConfigured);
-  CVPixelBufferRef source_pixel_buffer =
-      CMSampleBufferGetImageBuffer(sample_buffer);
+  DCHECK(pixel_buffer);
   // Fast path: If source and destination formats are identical, return the
   // source pixel buffer.
-  if (source_pixel_buffer &&
+  if (pixel_buffer &&
       static_cast<size_t>(destination_size_.width()) ==
-          CVPixelBufferGetWidth(source_pixel_buffer) &&
+          CVPixelBufferGetWidth(pixel_buffer) &&
       static_cast<size_t>(destination_size_.height()) ==
-          CVPixelBufferGetHeight(source_pixel_buffer) &&
+          CVPixelBufferGetHeight(pixel_buffer) &&
       destination_pixel_format_ ==
-          CVPixelBufferGetPixelFormatType(source_pixel_buffer) &&
-      CVPixelBufferGetIOSurface(source_pixel_buffer)) {
-    return base::ScopedCFTypeRef<CVPixelBufferRef>(source_pixel_buffer,
+          CVPixelBufferGetPixelFormatType(pixel_buffer) &&
+      CVPixelBufferGetIOSurface(pixel_buffer)) {
+    return base::ScopedCFTypeRef<CVPixelBufferRef>(pixel_buffer,
                                                    base::scoped_policy::RETAIN);
   }
   // Create destination buffer from pool.
@@ -528,10 +531,28 @@
     LOG(ERROR) << "Maximum destination buffers exceeded";
     return base::ScopedCFTypeRef<CVPixelBufferRef>();
   }
-  if (source_pixel_buffer) {
-    // Pixel buffer path. Do pixel transfer or libyuv conversion + rescale.
-    TransformPixelBuffer(source_pixel_buffer, destination_pixel_buffer);
-    return destination_pixel_buffer;
+  // Do pixel transfer or libyuv conversion + rescale.
+  TransformPixelBuffer(pixel_buffer, destination_pixel_buffer);
+  return destination_pixel_buffer;
+}
+
+base::ScopedCFTypeRef<CVPixelBufferRef> SampleBufferTransformer::Transform(
+    CMSampleBufferRef sample_buffer) {
+  DCHECK(transformer_ != Transformer::kNotConfigured);
+  DCHECK(sample_buffer);
+  // If the sample buffer has a pixel buffer, run the pixel buffer path instead.
+  if (CVPixelBufferRef pixel_buffer =
+          CMSampleBufferGetImageBuffer(sample_buffer)) {
+    return Transform(pixel_buffer);
+  }
+  // Create destination buffer from pool.
+  base::ScopedCFTypeRef<CVPixelBufferRef> destination_pixel_buffer =
+      destination_pixel_buffer_pool_->CreateBuffer();
+  if (!destination_pixel_buffer) {
+    // Maximum destination buffers exceeded. Old buffers are not being released
+    // (and thus not returned to the pool) in time.
+    LOG(ERROR) << "Maximum destination buffers exceeded";
+    return base::ScopedCFTypeRef<CVPixelBufferRef>();
   }
   // Sample buffer path - it's MJPEG. Do libyuv conversion + rescale.
   if (!TransformSampleBuffer(sample_buffer, destination_pixel_buffer)) {
diff --git a/media/capture/video/mac/sample_buffer_transformer_mac.h b/media/capture/video/mac/sample_buffer_transformer_mac.h
index 2565b6e..24d42cf 100644
--- a/media/capture/video/mac/sample_buffer_transformer_mac.h
+++ b/media/capture/video/mac/sample_buffer_transformer_mac.h
@@ -38,6 +38,12 @@
     kLibyuv,
   };
 
+  // TODO(https://crbug.com/1175763): Make determining the optimal Transformer
+  // an implementation detail determined at Transform()-time, making
+  // Reconfigure() only care about destination resolution and pixel format. Then
+  // make it possible to override this decision explicitly but only do that for
+  // testing and measurements purposes, not in default capturer integration.
+  static const Transformer kBestTransformerForPixelBufferToNv12Output;
   static Transformer GetBestTransformerForNv12Output(
       CMSampleBufferRef sample_buffer);
 
@@ -56,10 +62,11 @@
                    const gfx::Size& destination_size,
                    base::Optional<size_t> buffer_pool_size = base::nullopt);
 
-  // Converts the sample buffer to an IOSurface-backed pixel buffer according to
+  // Converts the input buffer to an IOSurface-backed pixel buffer according to
   // current configurations. If no transformation is needed (input format is the
-  // same as the configured output format), the sample buffer's pixel buffer is
-  // returned.
+  // same as the configured output format), the input pixel buffer is returned.
+  base::ScopedCFTypeRef<CVPixelBufferRef> Transform(
+      CVPixelBufferRef pixel_buffer);
   base::ScopedCFTypeRef<CVPixelBufferRef> Transform(
       CMSampleBufferRef sample_buffer);
 
diff --git a/media/capture/video/mac/sample_buffer_transformer_mac_unittest.mm b/media/capture/video/mac/sample_buffer_transformer_mac_unittest.mm
index 915e0ba8..3c83dd24 100644
--- a/media/capture/video/mac/sample_buffer_transformer_mac_unittest.mm
+++ b/media/capture/video/mac/sample_buffer_transformer_mac_unittest.mm
@@ -726,7 +726,7 @@
                          TestParametersOSTypeToString);
 
 TEST(SampleBufferTransformerBestTransformerForNv12OutputTest,
-     SourceAndDestinationResolutionMatches) {
+     SourceAndDestinationResolutionMatches_InputSampleBuffer) {
   std::unique_ptr<SampleBufferTransformer> transformer =
       SampleBufferTransformer::Create();
 
@@ -735,7 +735,7 @@
       kColorG, kColorB, PixelBufferType::kIoSurfaceMissing);
 
   transformer->Reconfigure(
-      media::SampleBufferTransformer::GetBestTransformerForNv12Output(sample0),
+      SampleBufferTransformer::GetBestTransformerForNv12Output(sample0),
       kPixelFormatNv12, media::GetSampleBufferSize(sample0));
   base::ScopedCFTypeRef<CVPixelBufferRef> output_buffer =
       transformer->Transform(sample0);
@@ -754,7 +754,7 @@
       kColorR, kColorG, kColorB, PixelBufferType::kIoSurfaceBacked);
 
   transformer->Reconfigure(
-      media::SampleBufferTransformer::GetBestTransformerForNv12Output(sample1),
+      SampleBufferTransformer::GetBestTransformerForNv12Output(sample1),
       kPixelFormatNv12, media::GetSampleBufferSize(sample1));
   output_buffer = transformer->Transform(sample1);
 
@@ -767,6 +767,79 @@
   EXPECT_EQ(output_buffer.get(), CMSampleBufferGetImageBuffer(sample1.get()));
 }
 
+// Same test as above, verifying that Transform() methods work on pixel buffers
+// directly (so that there's no need to have a sample buffer).
+TEST(SampleBufferTransformerBestTransformerForNv12OutputTest,
+     SourceAndDestinationResolutionMatches_InputPixelBuffer) {
+  std::unique_ptr<SampleBufferTransformer> transformer =
+      SampleBufferTransformer::Create();
+
+  base::ScopedCFTypeRef<CMSampleBufferRef> sample0 = CreateSampleBuffer(
+      kPixelFormatNv12, kFullResolutionWidth, kFullResolutionHeight, kColorR,
+      kColorG, kColorB, PixelBufferType::kIoSurfaceMissing);
+  CVPixelBufferRef pixel0 = CMSampleBufferGetImageBuffer(sample0);
+  ASSERT_TRUE(pixel0);
+
+  transformer->Reconfigure(
+      SampleBufferTransformer::kBestTransformerForPixelBufferToNv12Output,
+      kPixelFormatNv12, media::GetPixelBufferSize(pixel0));
+  base::ScopedCFTypeRef<CVPixelBufferRef> output_buffer =
+      transformer->Transform(pixel0);
+
+  EXPECT_EQ(gfx::Size(kFullResolutionWidth, kFullResolutionHeight),
+            transformer->destination_size());
+  EXPECT_EQ(kFullResolutionWidth, CVPixelBufferGetWidth(output_buffer));
+  EXPECT_EQ(kFullResolutionHeight, CVPixelBufferGetHeight(output_buffer));
+  EXPECT_TRUE(CVPixelBufferGetIOSurface(output_buffer));
+  // Because pixel0 has no underlying IOSurface, it should not be returned from
+  // the transformer.
+  EXPECT_NE(output_buffer.get(), pixel0);
+
+  base::ScopedCFTypeRef<CMSampleBufferRef> sample1 = CreateSampleBuffer(
+      kPixelFormatNv12, kScaledDownResolutionWidth, kScaledDownResolutionHeight,
+      kColorR, kColorG, kColorB, PixelBufferType::kIoSurfaceBacked);
+  CVPixelBufferRef pixel1 = CMSampleBufferGetImageBuffer(sample1);
+  ASSERT_TRUE(pixel1);
+
+  transformer->Reconfigure(
+      SampleBufferTransformer::kBestTransformerForPixelBufferToNv12Output,
+      kPixelFormatNv12, media::GetPixelBufferSize(pixel1));
+  output_buffer = transformer->Transform(pixel1);
+
+  EXPECT_EQ(gfx::Size(kScaledDownResolutionWidth, kScaledDownResolutionHeight),
+            transformer->destination_size());
+  EXPECT_EQ(kScaledDownResolutionWidth, CVPixelBufferGetWidth(output_buffer));
+  EXPECT_EQ(kScaledDownResolutionHeight, CVPixelBufferGetHeight(output_buffer));
+  EXPECT_TRUE(CVPixelBufferGetIOSurface(output_buffer));
+  // Because pixel1 does have an IOSurface, it can be returned directly.
+  EXPECT_EQ(output_buffer.get(), pixel1);
+}
+
+TEST(SampleBufferTransformerBestTransformerForNv12OutputTest,
+     CanConvertAndScaleDown_InputPixelBuffer) {
+  std::unique_ptr<SampleBufferTransformer> transformer =
+      SampleBufferTransformer::Create();
+
+  base::ScopedCFTypeRef<CMSampleBufferRef> sample_buffer = CreateSampleBuffer(
+      kPixelFormatNv12, kFullResolutionWidth, kFullResolutionHeight, kColorR,
+      kColorG, kColorB, PixelBufferType::kIoSurfaceBacked);
+  CVPixelBufferRef pixel_buffer = CMSampleBufferGetImageBuffer(sample_buffer);
+  ASSERT_TRUE(pixel_buffer);
+
+  transformer->Reconfigure(
+      SampleBufferTransformer::kBestTransformerForPixelBufferToNv12Output,
+      kPixelFormatNv12,
+      gfx::Size(kScaledDownResolutionWidth, kScaledDownResolutionHeight));
+  base::ScopedCFTypeRef<CVPixelBufferRef> output_buffer =
+      transformer->Transform(pixel_buffer);
+
+  EXPECT_TRUE(CVPixelBufferGetIOSurface(output_buffer));
+  EXPECT_EQ(kScaledDownResolutionWidth, CVPixelBufferGetWidth(output_buffer));
+  EXPECT_EQ(kScaledDownResolutionHeight, CVPixelBufferGetHeight(output_buffer));
+  EXPECT_TRUE(
+      PixelBufferIsSingleColor(output_buffer, kColorR, kColorG, kColorB));
+}
+
 TEST(SampleBufferTransformerBestTransformerForNv12OutputTest,
      DestinationPixelFormatIsAlwaysNv12) {
   std::unique_ptr<SampleBufferTransformer> transformer =
@@ -776,7 +849,7 @@
       kPixelFormatNv12, kScaledDownResolutionWidth, kScaledDownResolutionHeight,
       kColorR, kColorG, kColorB, PixelBufferType::kIoSurfaceBacked);
   transformer->Reconfigure(
-      media::SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
+      SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
       kPixelFormatNv12, media::GetSampleBufferSize(sample));
   base::ScopedCFTypeRef<CVPixelBufferRef> output_buffer =
       transformer->Transform(sample);
@@ -788,7 +861,7 @@
                               kScaledDownResolutionHeight, kColorR, kColorG,
                               kColorB, PixelBufferType::kIoSurfaceBacked);
   transformer->Reconfigure(
-      media::SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
+      SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
       kPixelFormatNv12, media::GetSampleBufferSize(sample));
   output_buffer = transformer->Transform(sample);
   EXPECT_EQ(kPixelFormatNv12, transformer->destination_pixel_format());
@@ -799,7 +872,7 @@
                               kScaledDownResolutionHeight, kColorR, kColorG,
                               kColorB, PixelBufferType::kIoSurfaceBacked);
   transformer->Reconfigure(
-      media::SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
+      SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
       kPixelFormatNv12, media::GetSampleBufferSize(sample));
   output_buffer = transformer->Transform(sample);
   EXPECT_EQ(kPixelFormatNv12, transformer->destination_pixel_format());
@@ -810,7 +883,7 @@
                               kScaledDownResolutionHeight, kColorR, kColorG,
                               kColorB, PixelBufferType::kIoSurfaceBacked);
   transformer->Reconfigure(
-      media::SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
+      SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
       kPixelFormatNv12, media::GetSampleBufferSize(sample));
   output_buffer = transformer->Transform(sample);
   EXPECT_EQ(kPixelFormatNv12, transformer->destination_pixel_format());
@@ -819,7 +892,7 @@
 
   sample = CreateExampleMjpegSampleBuffer();
   transformer->Reconfigure(
-      media::SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
+      SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
       kPixelFormatNv12, media::GetSampleBufferSize(sample));
   output_buffer = transformer->Transform(sample);
   EXPECT_EQ(kPixelFormatNv12, transformer->destination_pixel_format());
@@ -836,7 +909,7 @@
       kPixelFormatNv12, kScaledDownResolutionWidth, kScaledDownResolutionHeight,
       kColorR, kColorG, kColorB, PixelBufferType::kIoSurfaceBacked);
   transformer->Reconfigure(
-      media::SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
+      SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
       kPixelFormatNv12, media::GetSampleBufferSize(sample));
   base::ScopedCFTypeRef<CVPixelBufferRef> output_buffer =
       transformer->Transform(sample);
@@ -848,7 +921,7 @@
                               kScaledDownResolutionHeight, kColorR, kColorG,
                               kColorB, PixelBufferType::kIoSurfaceBacked);
   transformer->Reconfigure(
-      media::SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
+      SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
       kPixelFormatNv12, media::GetSampleBufferSize(sample));
   output_buffer = transformer->Transform(sample);
   EXPECT_EQ(SampleBufferTransformer::Transformer::kPixelBufferTransfer,
@@ -859,7 +932,7 @@
                               kScaledDownResolutionHeight, kColorR, kColorG,
                               kColorB, PixelBufferType::kIoSurfaceBacked);
   transformer->Reconfigure(
-      media::SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
+      SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
       kPixelFormatNv12, media::GetSampleBufferSize(sample));
   output_buffer = transformer->Transform(sample);
   EXPECT_EQ(SampleBufferTransformer::Transformer::kPixelBufferTransfer,
@@ -870,7 +943,7 @@
                               kScaledDownResolutionHeight, kColorR, kColorG,
                               kColorB, PixelBufferType::kIoSurfaceBacked);
   transformer->Reconfigure(
-      media::SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
+      SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
       kPixelFormatNv12, media::GetSampleBufferSize(sample));
   output_buffer = transformer->Transform(sample);
   EXPECT_EQ(SampleBufferTransformer::Transformer::kPixelBufferTransfer,
@@ -879,7 +952,7 @@
 
   sample = CreateExampleMjpegSampleBuffer();
   transformer->Reconfigure(
-      media::SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
+      SampleBufferTransformer::GetBestTransformerForNv12Output(sample),
       kPixelFormatNv12, media::GetSampleBufferSize(sample));
   output_buffer = transformer->Transform(sample);
   EXPECT_EQ(SampleBufferTransformer::Transformer::kLibyuv,
diff --git a/media/capture/video/mac/video_capture_device_avfoundation_utils_mac.h b/media/capture/video/mac/video_capture_device_avfoundation_utils_mac.h
index 6fb7e91..b5fa0a71 100644
--- a/media/capture/video/mac/video_capture_device_avfoundation_utils_mac.h
+++ b/media/capture/video/mac/video_capture_device_avfoundation_utils_mac.h
@@ -39,7 +39,7 @@
 // on if |kMacNextGenerationCapturer| is enabled or disabled.
 Class GetVideoCaptureDeviceAVFoundationImplementationClass();
 
-gfx::Size GetPixelBufferSize(CVPixelBufferRef pixel_buffer);
+gfx::Size CAPTURE_EXPORT GetPixelBufferSize(CVPixelBufferRef pixel_buffer);
 gfx::Size CAPTURE_EXPORT GetSampleBufferSize(CMSampleBufferRef sample_buffer);
 
 }  // namespace media
diff --git a/media/filters/android/media_codec_audio_decoder.cc b/media/filters/android/media_codec_audio_decoder.cc
index 587b78c..5119af0 100644
--- a/media/filters/android/media_codec_audio_decoder.cc
+++ b/media/filters/android/media_codec_audio_decoder.cc
@@ -52,6 +52,10 @@
   return "MediaCodecAudioDecoder";
 }
 
+AudioDecoderType MediaCodecAudioDecoder::GetDecoderType() const {
+  return AudioDecoderType::kMediaCodec;
+}
+
 void MediaCodecAudioDecoder::Initialize(const AudioDecoderConfig& config,
                                         CdmContext* cdm_context,
                                         InitCB init_cb,
diff --git a/media/filters/android/media_codec_audio_decoder.h b/media/filters/android/media_codec_audio_decoder.h
index 5441459..f5d7238 100644
--- a/media/filters/android/media_codec_audio_decoder.h
+++ b/media/filters/android/media_codec_audio_decoder.h
@@ -86,6 +86,7 @@
 
   // AudioDecoder implementation.
   std::string GetDisplayName() const override;
+  AudioDecoderType GetDecoderType() const override;
   void Initialize(const AudioDecoderConfig& config,
                   CdmContext* cdm_context,
                   InitCB init_cb,
diff --git a/media/filters/audio_decoder_unittest.cc b/media/filters/audio_decoder_unittest.cc
index 52f96cf..d54d50b2 100644
--- a/media/filters/audio_decoder_unittest.cc
+++ b/media/filters/audio_decoder_unittest.cc
@@ -62,7 +62,7 @@
 // The number of packets to read and then decode from each file.
 const size_t kDecodeRuns = 3;
 
-enum AudioDecoderType {
+enum TestAudioDecoderType {
   FFMPEG,
 #if defined(OS_ANDROID)
   MEDIA_CODEC,
@@ -123,7 +123,7 @@
 }  // namespace
 
 class AudioDecoderTest
-    : public TestWithParam<std::tuple<AudioDecoderType, TestParams>> {
+    : public TestWithParam<std::tuple<TestAudioDecoderType, TestParams>> {
  public:
   AudioDecoderTest()
       : decoder_type_(std::get<0>(GetParam())),
@@ -392,7 +392,7 @@
   const Status& last_decode_status() const { return last_decode_status_; }
 
  private:
-  const AudioDecoderType decoder_type_;
+  const TestAudioDecoderType decoder_type_;
 
   // Current TestParams used to initialize the test and decoder. The initial
   // valie is std::get<1>(GetParam()). Could be overridden by set_param() so
diff --git a/media/filters/dav1d_video_decoder.cc b/media/filters/dav1d_video_decoder.cc
index 9776413..bb21490b8 100644
--- a/media/filters/dav1d_video_decoder.cc
+++ b/media/filters/dav1d_video_decoder.cc
@@ -145,6 +145,10 @@
   return "Dav1dVideoDecoder";
 }
 
+VideoDecoderType Dav1dVideoDecoder::GetDecoderType() const {
+  return VideoDecoderType::kDav1d;
+}
+
 void Dav1dVideoDecoder::Initialize(const VideoDecoderConfig& config,
                                    bool low_delay,
                                    CdmContext* /* cdm_context */,
diff --git a/media/filters/dav1d_video_decoder.h b/media/filters/dav1d_video_decoder.h
index 22c4e1fd..4f6aa185 100644
--- a/media/filters/dav1d_video_decoder.h
+++ b/media/filters/dav1d_video_decoder.h
@@ -29,6 +29,7 @@
   ~Dav1dVideoDecoder() override;
 
   // VideoDecoder implementation.
+  VideoDecoderType GetDecoderType() const override;
   std::string GetDisplayName() const override;
   void Initialize(const VideoDecoderConfig& config,
                   bool low_delay,
diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc
index 61c500c2..8baa53b 100644
--- a/media/filters/decoder_stream.cc
+++ b/media/filters/decoder_stream.cc
@@ -410,7 +410,7 @@
   media_log_->SetProperty<StreamTraits::kIsDecryptingDemuxerStream>(
       !!decrypting_demuxer_stream_);
   media_log_->SetProperty<StreamTraits::kDecoderName>(
-      decoder_->GetDisplayName());
+      decoder_->GetDecoderType());
   media_log_->SetProperty<StreamTraits::kIsPlatformDecoder>(
       decoder_->IsPlatformDecoder());
 
diff --git a/media/filters/decoder_stream_traits.cc b/media/filters/decoder_stream_traits.cc
index 0670f28..1222c80 100644
--- a/media/filters/decoder_stream_traits.cc
+++ b/media/filters/decoder_stream_traits.cc
@@ -48,7 +48,9 @@
 DecoderStreamTraits<DemuxerStream::AUDIO>::DecoderStreamTraits(
     MediaLog* media_log,
     ChannelLayout initial_hw_layout)
-    : media_log_(media_log), initial_hw_layout_(initial_hw_layout) {}
+    : media_log_(media_log), initial_hw_layout_(initial_hw_layout) {
+  weak_this_ = weak_factory_.GetWeakPtr();
+}
 
 DecoderStreamTraits<DemuxerStream::AUDIO>::DecoderConfigType
 DecoderStreamTraits<DemuxerStream::AUDIO>::GetDecoderConfig(
@@ -80,9 +82,24 @@
     OnConfigChanged(config);
   config_ = config;
 
-  stats_.audio_decoder_info.decoder_name = decoder->GetDisplayName();
-  decoder->Initialize(config, cdm_context, std::move(init_cb), output_cb,
-                      waiting_cb);
+  stats_.audio_decoder_info.decoder_type = AudioDecoderType::kUnknown;
+  // Both |this| and |decoder| are owned by a DecoderSelector and will stay
+  // alive at least until |init_cb| is finished executing.
+  decoder->Initialize(
+      config, cdm_context,
+      base::BindOnce(
+          &DecoderStreamTraits<DemuxerStream::AUDIO>::OnDecoderInitialized,
+          weak_this_, base::Unretained(decoder), std::move(init_cb)),
+      output_cb, waiting_cb);
+}
+
+void DecoderStreamTraits<DemuxerStream::AUDIO>::OnDecoderInitialized(
+    DecoderType* decoder,
+    InitCB cb,
+    Status result) {
+  if (result.is_ok())
+    stats_.audio_decoder_info.decoder_type = decoder->GetDecoderType();
+  std::move(cb).Run(result);
 }
 
 void DecoderStreamTraits<DemuxerStream::AUDIO>::OnStreamReset(
@@ -147,7 +164,9 @@
 DecoderStreamTraits<DemuxerStream::VIDEO>::DecoderStreamTraits(
     MediaLog* media_log)
     // Randomly selected number of samples to keep.
-    : keyframe_distance_average_(16) {}
+    : keyframe_distance_average_(16) {
+  weak_this_ = weak_factory_.GetWeakPtr();
+}
 
 DecoderStreamTraits<DemuxerStream::VIDEO>::DecoderConfigType
 DecoderStreamTraits<DemuxerStream::VIDEO>::GetDecoderConfig(
@@ -181,10 +200,25 @@
     const OutputCB& output_cb,
     const WaitingCB& waiting_cb) {
   DCHECK(config.IsValidConfig());
-  stats_.video_decoder_info.decoder_name = decoder->GetDisplayName();
-  DVLOG(2) << stats_.video_decoder_info.decoder_name;
-  decoder->Initialize(config, low_delay, cdm_context, std::move(init_cb),
-                      output_cb, waiting_cb);
+  stats_.video_decoder_info.decoder_type = VideoDecoderType::kUnknown;
+  DVLOG(2) << decoder->GetDisplayName();
+  // |decoder| is owned by a DecoderSelector and will stay
+  // alive at least until |init_cb| is finished executing.
+  decoder->Initialize(
+      config, low_delay, cdm_context,
+      base::BindOnce(
+          &DecoderStreamTraits<DemuxerStream::VIDEO>::OnDecoderInitialized,
+          weak_this_, base::Unretained(decoder), std::move(init_cb)),
+      output_cb, waiting_cb);
+}
+
+void DecoderStreamTraits<DemuxerStream::VIDEO>::OnDecoderInitialized(
+    DecoderType* decoder,
+    InitCB cb,
+    Status result) {
+  if (result.is_ok())
+    stats_.video_decoder_info.decoder_type = decoder->GetDecoderType();
+  std::move(cb).Run(result);
 }
 
 void DecoderStreamTraits<DemuxerStream::VIDEO>::OnStreamReset(
diff --git a/media/filters/decoder_stream_traits.h b/media/filters/decoder_stream_traits.h
index 66fe7cd8..08aa211 100644
--- a/media/filters/decoder_stream_traits.h
+++ b/media/filters/decoder_stream_traits.h
@@ -65,6 +65,7 @@
                          InitCB init_cb,
                          const OutputCB& output_cb,
                          const WaitingCB& waiting_cb);
+  void OnDecoderInitialized(DecoderType* decoder, InitCB cb, Status status);
   DecoderConfigType GetDecoderConfig(DemuxerStream* stream);
   void OnDecode(const DecoderBuffer& buffer);
   PostDecodeAction OnDecodeDone(OutputType* buffer);
@@ -84,6 +85,10 @@
   ChannelLayout initial_hw_layout_;
   PipelineStatistics stats_;
   AudioDecoderConfig config_;
+
+  base::WeakPtr<DecoderStreamTraits<DemuxerStream::AUDIO>> weak_this_;
+  base::WeakPtrFactory<DecoderStreamTraits<DemuxerStream::AUDIO>> weak_factory_{
+      this};
 };
 
 template <>
@@ -118,6 +123,7 @@
                          InitCB init_cb,
                          const OutputCB& output_cb,
                          const WaitingCB& waiting_cb);
+  void OnDecoderInitialized(DecoderType* decoder, InitCB cb, Status status);
   void OnDecode(const DecoderBuffer& buffer);
   PostDecodeAction OnDecodeDone(OutputType* buffer);
   void OnStreamReset(DemuxerStream* stream);
@@ -136,6 +142,10 @@
   base::flat_map<base::TimeDelta, FrameMetadata> frame_metadata_;
 
   PipelineStatistics stats_;
+
+  base::WeakPtr<DecoderStreamTraits<DemuxerStream::VIDEO>> weak_this_;
+  base::WeakPtrFactory<DecoderStreamTraits<DemuxerStream::VIDEO>> weak_factory_{
+      this};
 };
 
 }  // namespace media
diff --git a/media/filters/decrypting_audio_decoder.cc b/media/filters/decrypting_audio_decoder.cc
index e42c00d..9415f532 100644
--- a/media/filters/decrypting_audio_decoder.cc
+++ b/media/filters/decrypting_audio_decoder.cc
@@ -46,6 +46,10 @@
   return "DecryptingAudioDecoder";
 }
 
+AudioDecoderType DecryptingAudioDecoder::GetDecoderType() const {
+  return AudioDecoderType::kDecrypting;
+}
+
 void DecryptingAudioDecoder::Initialize(const AudioDecoderConfig& config,
                                         CdmContext* cdm_context,
                                         InitCB init_cb,
diff --git a/media/filters/decrypting_audio_decoder.h b/media/filters/decrypting_audio_decoder.h
index aff41e2..9c77c521 100644
--- a/media/filters/decrypting_audio_decoder.h
+++ b/media/filters/decrypting_audio_decoder.h
@@ -42,6 +42,7 @@
 
   // Decoder implementation
   bool SupportsDecryption() const override;
+  AudioDecoderType GetDecoderType() const override;
   std::string GetDisplayName() const override;
 
   // AudioDecoder implementation.
diff --git a/media/filters/decrypting_video_decoder.cc b/media/filters/decrypting_video_decoder.cc
index 00455e3..548d9ba 100644
--- a/media/filters/decrypting_video_decoder.cc
+++ b/media/filters/decrypting_video_decoder.cc
@@ -28,6 +28,10 @@
   DETACH_FROM_SEQUENCE(sequence_checker_);
 }
 
+VideoDecoderType DecryptingVideoDecoder::GetDecoderType() const {
+  return VideoDecoderType::kDecrypting;
+}
+
 std::string DecryptingVideoDecoder::GetDisplayName() const {
   return kDecoderName;
 }
diff --git a/media/filters/decrypting_video_decoder.h b/media/filters/decrypting_video_decoder.h
index 6f7c924..e8715db8 100644
--- a/media/filters/decrypting_video_decoder.h
+++ b/media/filters/decrypting_video_decoder.h
@@ -41,6 +41,7 @@
   bool SupportsDecryption() const override;
 
   // VideoDecoder implementation.
+  VideoDecoderType GetDecoderType() const override;
   std::string GetDisplayName() const override;
   void Initialize(const VideoDecoderConfig& config,
                   bool low_delay,
diff --git a/media/filters/fake_video_decoder.cc b/media/filters/fake_video_decoder.cc
index e2f4726..4e8593f 100644
--- a/media/filters/fake_video_decoder.cc
+++ b/media/filters/fake_video_decoder.cc
@@ -68,6 +68,10 @@
   return decoder_name_;
 }
 
+VideoDecoderType FakeVideoDecoder::GetDecoderType() const {
+  return VideoDecoderType::kUnknown;
+}
+
 void FakeVideoDecoder::Initialize(const VideoDecoderConfig& config,
                                   bool low_delay,
                                   CdmContext* cdm_context,
diff --git a/media/filters/fake_video_decoder.h b/media/filters/fake_video_decoder.h
index 898f4da..45e920a 100644
--- a/media/filters/fake_video_decoder.h
+++ b/media/filters/fake_video_decoder.h
@@ -49,6 +49,7 @@
   bool SupportsDecryption() const override;
   bool IsPlatformDecoder() const override;
   std::string GetDisplayName() const override;
+  VideoDecoderType GetDecoderType() const override;
 
   // VideoDecoder implementation
   void Initialize(const VideoDecoderConfig& config,
diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc
index e5daea4..7ff037a 100644
--- a/media/filters/ffmpeg_audio_decoder.cc
+++ b/media/filters/ffmpeg_audio_decoder.cc
@@ -69,6 +69,10 @@
   return "FFmpegAudioDecoder";
 }
 
+AudioDecoderType FFmpegAudioDecoder::GetDecoderType() const {
+  return AudioDecoderType::kFFmpeg;
+}
+
 void FFmpegAudioDecoder::Initialize(const AudioDecoderConfig& config,
                                     CdmContext* /* cdm_context */,
                                     InitCB init_cb,
diff --git a/media/filters/ffmpeg_audio_decoder.h b/media/filters/ffmpeg_audio_decoder.h
index 2111b89a..5b3d203 100644
--- a/media/filters/ffmpeg_audio_decoder.h
+++ b/media/filters/ffmpeg_audio_decoder.h
@@ -40,6 +40,7 @@
   ~FFmpegAudioDecoder() override;
 
   // AudioDecoder implementation.
+  AudioDecoderType GetDecoderType() const override;
   std::string GetDisplayName() const override;
   void Initialize(const AudioDecoderConfig& config,
                   CdmContext* cdm_context,
diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc
index 0b7d95e..5dfff95 100644
--- a/media/filters/ffmpeg_video_decoder.cc
+++ b/media/filters/ffmpeg_video_decoder.cc
@@ -196,6 +196,10 @@
   return 0;
 }
 
+VideoDecoderType FFmpegVideoDecoder::GetDecoderType() const {
+  return VideoDecoderType::kFFmpeg;
+}
+
 std::string FFmpegVideoDecoder::GetDisplayName() const {
   return "FFmpegVideoDecoder";
 }
diff --git a/media/filters/ffmpeg_video_decoder.h b/media/filters/ffmpeg_video_decoder.h
index 4ea3045..669ec9e 100644
--- a/media/filters/ffmpeg_video_decoder.h
+++ b/media/filters/ffmpeg_video_decoder.h
@@ -38,6 +38,7 @@
   void set_decode_nalus(bool decode_nalus) { decode_nalus_ = decode_nalus; }
 
   // VideoDecoder implementation.
+  VideoDecoderType GetDecoderType() const override;
   std::string GetDisplayName() const override;
   void Initialize(const VideoDecoderConfig& config,
                   bool low_delay,
diff --git a/media/filters/fuchsia/fuchsia_video_decoder.cc b/media/filters/fuchsia/fuchsia_video_decoder.cc
index 3cf29e7..76149fd 100644
--- a/media/filters/fuchsia/fuchsia_video_decoder.cc
+++ b/media/filters/fuchsia/fuchsia_video_decoder.cc
@@ -197,6 +197,7 @@
   bool IsPlatformDecoder() const override;
   bool SupportsDecryption() const override;
   std::string GetDisplayName() const override;
+  VideoDecoderType GetDecoderType() const override;
 
   // VideoDecoder implementation.
   void Initialize(const VideoDecoderConfig& config,
@@ -362,6 +363,10 @@
   return "FuchsiaVideoDecoder";
 }
 
+VideoDecoderType FuchsiaVideoDecoder::GetDecoderType() const {
+  return VideoDecoderType::kFuchsia;
+}
+
 void FuchsiaVideoDecoder::Initialize(const VideoDecoderConfig& config,
                                      bool low_delay,
                                      CdmContext* cdm_context,
diff --git a/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc b/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc
index 574acb3d..2b319ea 100644
--- a/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc
+++ b/media/filters/fuchsia/fuchsia_video_decoder_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/containers/flat_set.h"
 #include "base/fuchsia/fuchsia_logging.h"
 #include "base/fuchsia/process_context.h"
+#include "base/process/process_handle.h"
 #include "base/test/bind.h"
 #include "base/test/task_environment.h"
 #include "components/viz/common/gpu/raster_context_provider.h"
@@ -41,6 +42,8 @@
       ZX_LOG(FATAL, status)
           << "The fuchsia.sysmem.Allocator channel was terminated.";
     });
+    sysmem_allocator_->SetDebugClientInfo("CrTestBufferCollection",
+                                          base::GetCurrentProcId());
 
     sysmem_allocator_->BindSharedCollection(
         fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>(
diff --git a/media/filters/gav1_video_decoder.cc b/media/filters/gav1_video_decoder.cc
index 900e20e..41a42b8 100644
--- a/media/filters/gav1_video_decoder.cc
+++ b/media/filters/gav1_video_decoder.cc
@@ -247,6 +247,10 @@
   return "Gav1VideoDecoder";
 }
 
+VideoDecoderType Gav1VideoDecoder::GetDecoderType() const {
+  return VideoDecoderType::kGav1;
+}
+
 void Gav1VideoDecoder::Initialize(const VideoDecoderConfig& config,
                                   bool low_delay,
                                   CdmContext* /* cdm_context */,
diff --git a/media/filters/gav1_video_decoder.h b/media/filters/gav1_video_decoder.h
index 22cd005..e7265d08 100644
--- a/media/filters/gav1_video_decoder.h
+++ b/media/filters/gav1_video_decoder.h
@@ -36,6 +36,7 @@
 
   // VideoDecoder implementation.
   std::string GetDisplayName() const override;
+  VideoDecoderType GetDecoderType() const override;
   void Initialize(const VideoDecoderConfig& config,
                   bool low_delay,
                   CdmContext* cdm_context,
diff --git a/media/filters/offloading_video_decoder.cc b/media/filters/offloading_video_decoder.cc
index 242190f8..c5379eb 100644
--- a/media/filters/offloading_video_decoder.cc
+++ b/media/filters/offloading_video_decoder.cc
@@ -75,6 +75,11 @@
     offload_task_runner_->DeleteSoon(FROM_HERE, std::move(helper_));
 }
 
+VideoDecoderType OffloadingVideoDecoder::GetDecoderType() const {
+  // This call is expected to be static and safe to call from any thread.
+  return helper_->decoder()->GetDecoderType();
+}
+
 std::string OffloadingVideoDecoder::GetDisplayName() const {
   // This call is expected to be static and safe to call from any thread.
   return helper_->decoder()->GetDisplayName();
diff --git a/media/filters/offloading_video_decoder.h b/media/filters/offloading_video_decoder.h
index 0ff14bb3..5caf478 100644
--- a/media/filters/offloading_video_decoder.h
+++ b/media/filters/offloading_video_decoder.h
@@ -88,6 +88,7 @@
   ~OffloadingVideoDecoder() override;
 
   // VideoDecoder implementation.
+  VideoDecoderType GetDecoderType() const override;
   std::string GetDisplayName() const override;
   void Initialize(const VideoDecoderConfig& config,
                   bool low_delay,
diff --git a/media/filters/offloading_video_decoder_unittest.cc b/media/filters/offloading_video_decoder_unittest.cc
index 29813ad..b6d2abf 100644
--- a/media/filters/offloading_video_decoder_unittest.cc
+++ b/media/filters/offloading_video_decoder_unittest.cc
@@ -39,6 +39,11 @@
   std::string GetDisplayName() const override {
     return "MockOffloadableVideoDecoder";
   }
+
+  VideoDecoderType GetDecoderType() const override {
+    return VideoDecoderType::kUnknown;
+  }
+
   void Initialize(const VideoDecoderConfig& config,
                   bool low_delay,
                   CdmContext* cdm_context,
diff --git a/media/filters/pipeline_controller_unittest.cc b/media/filters/pipeline_controller_unittest.cc
index 0bced42..390dbc69 100644
--- a/media/filters/pipeline_controller_unittest.cc
+++ b/media/filters/pipeline_controller_unittest.cc
@@ -152,8 +152,8 @@
   void OnVideoOpacityChange(bool opaque) override {}
   void OnVideoFrameRateChange(base::Optional<int>) override {}
   void OnVideoAverageKeyframeDistanceUpdate() override {}
-  void OnAudioDecoderChange(const PipelineDecoderInfo& info) override {}
-  void OnVideoDecoderChange(const PipelineDecoderInfo& info) override {}
+  void OnAudioDecoderChange(const AudioDecoderInfo& info) override {}
+  void OnVideoDecoderChange(const VideoDecoderInfo& info) override {}
 
   base::test::SingleThreadTaskEnvironment task_environment_;
 
diff --git a/media/filters/vpx_video_decoder.cc b/media/filters/vpx_video_decoder.cc
index 8930b7b..5335f86 100644
--- a/media/filters/vpx_video_decoder.cc
+++ b/media/filters/vpx_video_decoder.cc
@@ -108,6 +108,10 @@
   CloseDecoder();
 }
 
+VideoDecoderType VpxVideoDecoder::GetDecoderType() const {
+  return VideoDecoderType::kVpx;
+}
+
 std::string VpxVideoDecoder::GetDisplayName() const {
   return "VpxVideoDecoder";
 }
diff --git a/media/filters/vpx_video_decoder.h b/media/filters/vpx_video_decoder.h
index 98eff915..1edf239 100644
--- a/media/filters/vpx_video_decoder.h
+++ b/media/filters/vpx_video_decoder.h
@@ -33,6 +33,7 @@
   ~VpxVideoDecoder() override;
 
   // VideoDecoder implementation.
+  VideoDecoderType GetDecoderType() const override;
   std::string GetDisplayName() const override;
   void Initialize(const VideoDecoderConfig& config,
                   bool low_delay,
diff --git a/media/gpu/android/media_codec_video_decoder.cc b/media/gpu/android/media_codec_video_decoder.cc
index 3bae356..97baa9d 100644
--- a/media/gpu/android/media_codec_video_decoder.cc
+++ b/media/gpu/android/media_codec_video_decoder.cc
@@ -1159,6 +1159,10 @@
   return "MediaCodecVideoDecoder";
 }
 
+VideoDecoderType MediaCodecVideoDecoder::GetDecoderType() const {
+  return VideoDecoderType::kMediaCodec;
+}
+
 bool MediaCodecVideoDecoder::NeedsBitstreamConversion() const {
   return true;
 }
diff --git a/media/gpu/android/media_codec_video_decoder.h b/media/gpu/android/media_codec_video_decoder.h
index 8c98495..d3e3f210 100644
--- a/media/gpu/android/media_codec_video_decoder.h
+++ b/media/gpu/android/media_codec_video_decoder.h
@@ -80,6 +80,7 @@
 
   // VideoDecoder implementation:
   std::string GetDisplayName() const override;
+  VideoDecoderType GetDecoderType() const override;
   void Initialize(const VideoDecoderConfig& config,
                   bool low_delay,
                   CdmContext* cdm_context,
diff --git a/media/gpu/chromeos/video_decoder_pipeline.cc b/media/gpu/chromeos/video_decoder_pipeline.cc
index 53a5700..aed6668 100644
--- a/media/gpu/chromeos/video_decoder_pipeline.cc
+++ b/media/gpu/chromeos/video_decoder_pipeline.cc
@@ -157,10 +157,14 @@
 
 std::string VideoDecoderPipeline::GetDisplayName() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
-
   return "VideoDecoderPipeline";
 }
 
+VideoDecoderType VideoDecoderPipeline::GetDecoderType() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+  return VideoDecoderType::kChromeOs;
+}
+
 bool VideoDecoderPipeline::IsPlatformDecoder() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
 
diff --git a/media/gpu/chromeos/video_decoder_pipeline.h b/media/gpu/chromeos/video_decoder_pipeline.h
index 3978f6b..c658efb 100644
--- a/media/gpu/chromeos/video_decoder_pipeline.h
+++ b/media/gpu/chromeos/video_decoder_pipeline.h
@@ -148,6 +148,7 @@
   static void DestroyAsync(std::unique_ptr<VideoDecoderPipeline>);
 
   // VideoDecoder implementation
+  VideoDecoderType GetDecoderType() const override;
   std::string GetDisplayName() const override;
   bool IsPlatformDecoder() const override;
   int GetMaxDecodeRequests() const override;
diff --git a/media/gpu/ipc/service/vda_video_decoder.cc b/media/gpu/ipc/service/vda_video_decoder.cc
index 820ab74a..d79cdfc3 100644
--- a/media/gpu/ipc/service/vda_video_decoder.cc
+++ b/media/gpu/ipc/service/vda_video_decoder.cc
@@ -210,10 +210,17 @@
 std::string VdaVideoDecoder::GetDisplayName() const {
   DVLOG(3) << __func__;
   DCHECK(parent_task_runner_->BelongsToCurrentThread());
-
   return "VdaVideoDecoder";
 }
 
+VideoDecoderType VdaVideoDecoder::GetDecoderType() const {
+  DVLOG(3) << __func__;
+  DCHECK(parent_task_runner_->BelongsToCurrentThread());
+  // TODO(tmathmeyer) query the accelerator for it's implementation type and
+  // return that instead.
+  return VideoDecoderType::kVda;
+}
+
 void VdaVideoDecoder::Initialize(const VideoDecoderConfig& config,
                                  bool low_delay,
                                  CdmContext* cdm_context,
diff --git a/media/gpu/ipc/service/vda_video_decoder.h b/media/gpu/ipc/service/vda_video_decoder.h
index 37746ca..d766bcc 100644
--- a/media/gpu/ipc/service/vda_video_decoder.h
+++ b/media/gpu/ipc/service/vda_video_decoder.h
@@ -77,6 +77,7 @@
   static void DestroyAsync(std::unique_ptr<VdaVideoDecoder>);
 
   // media::VideoDecoder implementation.
+  VideoDecoderType GetDecoderType() const override;
   std::string GetDisplayName() const override;
   void Initialize(const VideoDecoderConfig& config,
                   bool low_delay,
diff --git a/media/gpu/test/video_encoder/bitstream_validator.cc b/media/gpu/test/video_encoder/bitstream_validator.cc
index cbf01dd..4208a4fd 100644
--- a/media/gpu/test/video_encoder/bitstream_validator.cc
+++ b/media/gpu/test/video_encoder/bitstream_validator.cc
@@ -121,6 +121,9 @@
 }
 
 BitstreamValidator::~BitstreamValidator() {
+  // Make sure no buffer is being validated and processed.
+  WaitUntilDone();
+
   // Since |decoder_| has to be destroyed on the sequence that executes
   // Initialize(). Destroys it on the validator thread task runner.
   if (validator_thread_.IsRunning())
@@ -131,6 +134,17 @@
                                           size_t frame_index) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(validator_sequence_checker_);
   base::AutoLock lock(validator_lock_);
+  // If many pending buffers are accumulated in this validator class and the
+  // allocated memory size becomes large, the test process is killed by the
+  // system due to out of memory.
+  // To avoid the issue, wait until the number of buffers being validated is
+  // less than or equal to 16. The number is arbitrary chosen.
+  if (frame_index != last_frame_index_) {
+    constexpr size_t kMaxNumPendingBuffers = 16;
+    while (num_buffers_validating_ > kMaxNumPendingBuffers)
+      validator_cv_.Wait();
+  }
+
   num_buffers_validating_++;
   validator_thread_.task_runner()->PostTask(
       FROM_HERE, base::BindOnce(&BitstreamValidator::ProcessBitstreamTask,
@@ -195,6 +209,14 @@
   it->second.second.reset();
 }
 
+void BitstreamValidator::OutputFrameProcessed() {
+  // This function can be called on any sequence because the written variables
+  // are guarded by a lock.
+  base::AutoLock lock(validator_lock_);
+  num_buffers_validating_--;
+  validator_cv_.Signal();
+}
+
 void BitstreamValidator::VerifyOutputFrame(scoped_refptr<VideoFrame> frame) {
   SEQUENCE_CHECKER(validator_thread_sequence_checker_);
   auto it = decoding_buffers_.Peek(frame->timestamp().InMicroseconds());
@@ -206,14 +228,19 @@
   size_t frame_index = it->second.first;
   decoding_buffers_.Erase(it);
 
+  // Wraps VideoFrame because the reference of |frame| might be kept in
+  // VideoDecoder and thus |frame| is not released unless |decoder_| is
+  // destructed.
+  auto wrapped_video_frame =
+      VideoFrame::WrapVideoFrame(frame, frame->format(), frame->visible_rect(),
+                                 frame->visible_rect().size());
+  LOG_ASSERT(wrapped_video_frame) << "Failed creating a wrapped VideoFrame";
+  wrapped_video_frame->AddDestructionObserver(base::BindOnce(
+      &BitstreamValidator::OutputFrameProcessed, base::Unretained(this)));
   // Send the decoded frame to the configured video frame processors to perform
   // additional verification.
   for (const auto& processor : video_frame_processors_)
-    processor->ProcessVideoFrame(frame, frame_index);
-
-  base::AutoLock lock(validator_lock_);
-  num_buffers_validating_--;
-  validator_cv_.Signal();
+    processor->ProcessVideoFrame(wrapped_video_frame, frame_index);
 }
 
 bool BitstreamValidator::WaitUntilDone() {
diff --git a/media/gpu/test/video_encoder/bitstream_validator.h b/media/gpu/test/video_encoder/bitstream_validator.h
index 5996bd4..cd364d1 100644
--- a/media/gpu/test/video_encoder/bitstream_validator.h
+++ b/media/gpu/test/video_encoder/bitstream_validator.h
@@ -68,6 +68,7 @@
                               VideoDecoder::InitCB init_cb);
   void ProcessBitstreamTask(scoped_refptr<BitstreamRef> decoder_buffer,
                             size_t frame_index);
+  void OutputFrameProcessed();
 
   // Functions for media::VideoDecoder.
   void DecodeDone(int64_t timestamp, Status status);
diff --git a/media/gpu/test/video_player/test_vda_video_decoder.cc b/media/gpu/test/video_player/test_vda_video_decoder.cc
index 31442b6..61323a0d 100644
--- a/media/gpu/test/video_player/test_vda_video_decoder.cc
+++ b/media/gpu/test/video_player/test_vda_video_decoder.cc
@@ -82,6 +82,10 @@
   return "TestVDAVideoDecoder";
 }
 
+VideoDecoderType TestVDAVideoDecoder::GetDecoderType() const {
+  return VideoDecoderType::kUnknown;
+}
+
 bool TestVDAVideoDecoder::IsPlatformDecoder() const {
   return true;
 }
diff --git a/media/gpu/test/video_player/test_vda_video_decoder.h b/media/gpu/test/video_player/test_vda_video_decoder.h
index 1a6e74d..5aeb39c 100644
--- a/media/gpu/test/video_player/test_vda_video_decoder.h
+++ b/media/gpu/test/video_player/test_vda_video_decoder.h
@@ -46,6 +46,7 @@
 
   // media::VideoDecoder implementation
   std::string GetDisplayName() const override;
+  VideoDecoderType GetDecoderType() const override;
   bool IsPlatformDecoder() const override;
   void Initialize(const VideoDecoderConfig& config,
                   bool low_delay,
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc
index 1c46e34..669ae99 100644
--- a/media/gpu/windows/d3d11_video_decoder.cc
+++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -150,6 +150,10 @@
   return "D3D11VideoDecoder";
 }
 
+VideoDecoderType D3D11VideoDecoder::GetDecoderType() const {
+  return VideoDecoderType::kD3D11;
+}
+
 HRESULT D3D11VideoDecoder::InitializeAcceleratedDecoder(
     const VideoDecoderConfig& config,
     ComD3D11VideoDecoder video_decoder) {
diff --git a/media/gpu/windows/d3d11_video_decoder.h b/media/gpu/windows/d3d11_video_decoder.h
index 958e848..3f1cfe5 100644
--- a/media/gpu/windows/d3d11_video_decoder.h
+++ b/media/gpu/windows/d3d11_video_decoder.h
@@ -68,6 +68,7 @@
 
   // VideoDecoder implementation:
   std::string GetDisplayName() const override;
+  VideoDecoderType GetDecoderType() const override;
   void Initialize(const VideoDecoderConfig& config,
                   bool low_delay,
                   CdmContext* cdm_context,
diff --git a/media/mojo/clients/mojo_audio_decoder.cc b/media/mojo/clients/mojo_audio_decoder.cc
index 092c50f..2bf1b1a 100644
--- a/media/mojo/clients/mojo_audio_decoder.cc
+++ b/media/mojo/clients/mojo_audio_decoder.cc
@@ -47,6 +47,10 @@
 #endif
 }
 
+AudioDecoderType MojoAudioDecoder::GetDecoderType() const {
+  return decoder_type_;
+}
+
 std::string MojoAudioDecoder::GetDisplayName() const {
   return "MojoAudioDecoder";
 }
@@ -199,11 +203,13 @@
 }
 
 void MojoAudioDecoder::OnInitialized(const Status& status,
-                                     bool needs_bitstream_conversion) {
+                                     bool needs_bitstream_conversion,
+                                     AudioDecoderType decoder_type) {
   DVLOG(1) << __func__ << ": success:" << status.is_ok();
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   needs_bitstream_conversion_ = needs_bitstream_conversion;
+  decoder_type_ = decoder_type;
 
   if (status.is_ok() && !mojo_decoder_buffer_writer_) {
     mojo::ScopedDataPipeConsumerHandle remote_consumer_handle;
diff --git a/media/mojo/clients/mojo_audio_decoder.h b/media/mojo/clients/mojo_audio_decoder.h
index ded8cd2..fbb85ab 100644
--- a/media/mojo/clients/mojo_audio_decoder.h
+++ b/media/mojo/clients/mojo_audio_decoder.h
@@ -36,7 +36,8 @@
   // Decoder implementation
   bool IsPlatformDecoder() const final;
   bool SupportsDecryption() const final;
-  std::string GetDisplayName() const final;
+  std::string GetDisplayName() const override;
+  AudioDecoderType GetDecoderType() const override;
 
   // AudioDecoder implementation.
   void Initialize(const AudioDecoderConfig& config,
@@ -66,7 +67,9 @@
   void FailInit(InitCB init_cb, Status err);
 
   // Called when |remote_decoder_| finished initialization.
-  void OnInitialized(const Status& status, bool needs_bitstream_conversion);
+  void OnInitialized(const Status& status,
+                     bool needs_bitstream_conversion,
+                     AudioDecoderType decoder_type);
 
   // Called when |remote_decoder_| accepted or rejected DecoderBuffer.
   void OnDecodeStatus(const Status& decode_status);
@@ -103,6 +106,7 @@
   // Flag telling whether this decoder requires bitstream conversion.
   // Passed from |remote_decoder_| as a result of its initialization.
   bool needs_bitstream_conversion_ = false;
+  AudioDecoderType decoder_type_ = AudioDecoderType::kUnknown;
 
   DISALLOW_COPY_AND_ASSIGN(MojoAudioDecoder);
 };
diff --git a/media/mojo/clients/mojo_video_decoder.cc b/media/mojo/clients/mojo_video_decoder.cc
index 5d18f04d..a093a37 100644
--- a/media/mojo/clients/mojo_video_decoder.cc
+++ b/media/mojo/clients/mojo_video_decoder.cc
@@ -143,6 +143,10 @@
 #endif
 }
 
+VideoDecoderType MojoVideoDecoder::GetDecoderType() const {
+  return decoder_type_;
+}
+
 std::string MojoVideoDecoder::GetDisplayName() const {
   return "MojoVideoDecoder";
 }
@@ -207,12 +211,14 @@
 
 void MojoVideoDecoder::OnInitializeDone(const Status& status,
                                         bool needs_bitstream_conversion,
-                                        int32_t max_decode_requests) {
+                                        int32_t max_decode_requests,
+                                        VideoDecoderType decoder_type) {
   DVLOG(1) << __func__ << ": status = " << std::hex << status.code();
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   initialized_ = status.is_ok();
   needs_bitstream_conversion_ = needs_bitstream_conversion;
   max_decode_requests_ = max_decode_requests;
+  decoder_type_ = decoder_type;
   std::move(init_cb_).Run(status);
 }
 
diff --git a/media/mojo/clients/mojo_video_decoder.h b/media/mojo/clients/mojo_video_decoder.h
index 1a25f19..b5fdef8 100644
--- a/media/mojo/clients/mojo_video_decoder.h
+++ b/media/mojo/clients/mojo_video_decoder.h
@@ -60,7 +60,8 @@
   // Decoder implementation
   bool IsPlatformDecoder() const final;
   bool SupportsDecryption() const final;
-  std::string GetDisplayName() const final;
+  std::string GetDisplayName() const override;
+  VideoDecoderType GetDecoderType() const final;
 
   // VideoDecoder implementation.
   void Initialize(const VideoDecoderConfig& config,
@@ -92,7 +93,8 @@
   void FailInit(InitCB init_cb, Status err);
   void OnInitializeDone(const Status& status,
                         bool needs_bitstream_conversion,
-                        int32_t max_decode_requests);
+                        int32_t max_decode_requests,
+                        VideoDecoderType decoder_type);
   void OnDecodeDone(uint64_t decode_id, const Status& status);
   void OnResetDone();
 
@@ -147,6 +149,7 @@
   bool initialized_ = false;
   bool needs_bitstream_conversion_ = false;
   bool can_read_without_stalling_ = true;
+  VideoDecoderType decoder_type_ = VideoDecoderType::kUnknown;
 
   // True if UMA metrics of success/failure after first few seconds of playback
   // have been already reported.
diff --git a/media/mojo/mojom/BUILD.gn b/media/mojo/mojom/BUILD.gn
index f1323fb..44e9f73 100644
--- a/media/mojo/mojom/BUILD.gn
+++ b/media/mojo/mojom/BUILD.gn
@@ -101,6 +101,15 @@
     {
       types = [
         {
+          mojom = "media.mojom.FullscreenVideoStatus"
+          cpp = "::blink::WebFullscreenVideoStatus"
+        },
+      ]
+      traits_headers = [ "//media/base/ipc/media_param_traits_macros.h" ]
+    },
+    {
+      types = [
+        {
           mojom = "media.mojom.MediaContentType"
           cpp = "::media::MediaContentType"
         },
@@ -131,6 +140,10 @@
           mojom = "media.mojom.AudioDecoderConfig"
           cpp = "::media::AudioDecoderConfig"
         },
+        {
+          mojom = "media.mojom.AudioDecoderType"
+          cpp = "::media::AudioDecoderType"
+        },
       ]
       traits_headers = [ "audio_decoder_config_mojom_traits.h" ]
       traits_sources = [ "audio_decoder_config_mojom_traits.cc" ]
@@ -253,8 +266,20 @@
           cpp = "::media::PipelineStatistics"
         },
         {
-          mojom = "media.mojom.PipelineDecoderInfo"
-          cpp = "::media::PipelineDecoderInfo"
+          mojom = "media.mojom.AudioDecoderInfo"
+          cpp = "::media::AudioDecoderInfo"
+        },
+        {
+          mojom = "media.mojom.VideoDecoderInfo"
+          cpp = "::media::VideoDecoderInfo"
+        },
+        {
+          mojom = "media.mojom.AudioDecoderType"
+          cpp = "::media::AudioDecoderType"
+        },
+        {
+          mojom = "media.mojom.VideoDecoderType"
+          cpp = "::media::VideoDecoderType"
         },
       ]
       traits_headers = [ "pipeline_status_mojom_traits.h" ]
@@ -308,6 +333,10 @@
           mojom = "media.mojom.VideoDecoderImplementation"
           cpp = "::media::VideoDecoderImplementation"
         },
+        {
+          mojom = "media.mojom.VideoDecoderType"
+          cpp = "::media::VideoDecoderType"
+        },
       ]
       traits_headers = [
         "supported_video_decoder_config_mojom_traits.h",
diff --git a/media/mojo/mojom/audio_decoder.mojom b/media/mojo/mojom/audio_decoder.mojom
index 599834e8..25029a8 100644
--- a/media/mojo/mojom/audio_decoder.mojom
+++ b/media/mojo/mojom/audio_decoder.mojom
@@ -20,7 +20,9 @@
   // bitstream conversion.
   Initialize(AudioDecoderConfig config,
              mojo_base.mojom.UnguessableToken? cdm_id)
-      => (Status success, bool needs_bitstream_conversion);
+      => (Status success,
+          bool needs_bitstream_conversion,
+          AudioDecoderType decoder_type);
 
   // Establishes data connection. Should be called before Decode().
   SetDataSource(handle<data_pipe_consumer> receive_pipe);
diff --git a/media/mojo/mojom/media_metrics_provider.mojom b/media/mojo/mojom/media_metrics_provider.mojom
index 526e2b1..c09433c 100644
--- a/media/mojo/mojom/media_metrics_provider.mojom
+++ b/media/mojo/mojom/media_metrics_provider.mojom
@@ -76,6 +76,6 @@
   // Can be called multiple times to set properties about a playback.
   SetHasAudio(AudioCodec codec);
   SetHasVideo(VideoCodec codec);
-  SetVideoPipelineInfo(PipelineDecoderInfo info);
-  SetAudioPipelineInfo(PipelineDecoderInfo info);
+  SetVideoPipelineInfo(VideoDecoderInfo info);
+  SetAudioPipelineInfo(AudioDecoderInfo info);
 };
diff --git a/media/mojo/mojom/media_player.mojom b/media/mojo/mojom/media_player.mojom
index 745c17e3..df92a69 100644
--- a/media/mojo/mojom/media_player.mojom
+++ b/media/mojo/mojom/media_player.mojom
@@ -59,12 +59,21 @@
   // and reports the new current position via |media_position|.
   OnMediaPositionStateChanged(media_session.mojom.MediaPosition media_position);
 
+  // Notifies that the player has entered fullscreen.
+  // This does not differentiate native controls fullscreen and custom controls
+  // fullscreen. |status| is used by MediaWebContentsObserver to trigger
+  // automatically Picture-in-Picture for fullscreen videos.
+  OnMediaEffectivelyFullscreenChanged(FullscreenVideoStatus status);
+
   // Notifies that the size of the media player has changed.
   OnMediaSizeChanged(gfx.mojom.Size size);
 
   // Notifies the browser process of PictureinPicture playback's availability.
   OnPictureInPictureAvailabilityChanged(bool available);
 
+  // Notifies that the audio output sink has changed.
+  OnAudioOutputSinkChanged(string hashed_device_id);
+
   // Notifies the browser process that the ability to switch audio output
   // devices for the associated media player has been disabled.
   OnAudioOutputSinkChangingDisabled();
diff --git a/media/mojo/mojom/media_types.mojom b/media/mojo/mojom/media_types.mojom
index 7e492be..2c75c4b 100644
--- a/media/mojo/mojom/media_types.mojom
+++ b/media/mojo/mojom/media_types.mojom
@@ -70,6 +70,14 @@
 [Native]
 enum VideoPixelFormat;
 
+// See media/base/decoder.h for descriptions.
+[Native]
+enum VideoDecoderType;
+
+// See media/base/decoder.h for descriptions.
+[Native]
+enum AudioDecoderType;
+
 // See media/base/video_transformation.h for descriptions.
 enum VideoRotation {
   kVideoRotation0,
@@ -84,6 +92,11 @@
   kCopyMailboxesOnly,
 };
 
+// see third_party/blink/public/platform/web_fullscreen_video_status.h for
+// descriptions.
+[Native]
+enum FullscreenVideoStatus;
+
 // See media/base/video_transformation.h for descriptions.
 struct VideoTransformation {
   VideoRotation rotation;
@@ -431,9 +444,16 @@
   uint32 frames_power_efficient = 0;
 };
 
-// See media/base/pipeline/status.h for descriptions.
-struct PipelineDecoderInfo {
-  string decoder_name;
+// See media/base/pipeline_status.h for descriptions.
+struct AudioDecoderInfo {
+  AudioDecoderType decoder_type;
+  bool is_platform_decoder = false;
+  bool has_decrypting_demuxer_stream = false;
+};
+
+// See media/base/pipeline_status.h for descriptions.
+struct VideoDecoderInfo {
+  VideoDecoderType decoder_type;
   bool is_platform_decoder = false;
   bool has_decrypting_demuxer_stream = false;
 };
diff --git a/media/mojo/mojom/pipeline_status_mojom_traits.h b/media/mojo/mojom/pipeline_status_mojom_traits.h
index 43cb23f6..d2893e2 100644
--- a/media/mojo/mojom/pipeline_status_mojom_traits.h
+++ b/media/mojo/mojom/pipeline_status_mojom_traits.h
@@ -47,27 +47,54 @@
 };
 
 template <>
-struct StructTraits<media::mojom::PipelineDecoderInfoDataView,
-                    media::PipelineDecoderInfo> {
-  static std::string decoder_name(const media::PipelineDecoderInfo& input) {
-    return input.decoder_name;
+struct StructTraits<media::mojom::AudioDecoderInfoDataView,
+                    media::AudioDecoderInfo> {
+  static media::AudioDecoderType decoder_type(
+      const media::AudioDecoderInfo& input) {
+    return input.decoder_type;
   }
 
-  static bool is_platform_decoder(const media::PipelineDecoderInfo& input) {
+  static bool is_platform_decoder(const media::AudioDecoderInfo& input) {
     return input.is_platform_decoder;
   }
 
   static bool has_decrypting_demuxer_stream(
-      const media::PipelineDecoderInfo& input) {
+      const media::AudioDecoderInfo& input) {
     return input.has_decrypting_demuxer_stream;
   }
 
-  static bool Read(media::mojom::PipelineDecoderInfoDataView data,
-                   media::PipelineDecoderInfo* output) {
+  static bool Read(media::mojom::AudioDecoderInfoDataView data,
+                   media::AudioDecoderInfo* output) {
     output->is_platform_decoder = data.is_platform_decoder();
     output->has_decrypting_demuxer_stream =
         data.has_decrypting_demuxer_stream();
-    return data.ReadDecoderName(&output->decoder_name);
+    return data.ReadDecoderType(&output->decoder_type);
+  }
+};
+
+template <>
+struct StructTraits<media::mojom::VideoDecoderInfoDataView,
+                    media::VideoDecoderInfo> {
+  static media::VideoDecoderType decoder_type(
+      const media::VideoDecoderInfo& input) {
+    return input.decoder_type;
+  }
+
+  static bool is_platform_decoder(const media::VideoDecoderInfo& input) {
+    return input.is_platform_decoder;
+  }
+
+  static bool has_decrypting_demuxer_stream(
+      const media::VideoDecoderInfo& input) {
+    return input.has_decrypting_demuxer_stream;
+  }
+
+  static bool Read(media::mojom::VideoDecoderInfoDataView data,
+                   media::VideoDecoderInfo* output) {
+    output->is_platform_decoder = data.is_platform_decoder();
+    output->has_decrypting_demuxer_stream =
+        data.has_decrypting_demuxer_stream();
+    return data.ReadDecoderType(&output->decoder_type);
   }
 };
 
diff --git a/media/mojo/mojom/video_decoder.mojom b/media/mojo/mojom/video_decoder.mojom
index 1ff471e..1a3f89d 100644
--- a/media/mojo/mojom/video_decoder.mojom
+++ b/media/mojo/mojom/video_decoder.mojom
@@ -128,7 +128,8 @@
              mojo_base.mojom.UnguessableToken? cdm_id)
       => (Status status,
           bool needs_bitstream_conversion,
-          int32 max_decode_requests);
+          int32 max_decode_requests,
+          VideoDecoderType decoder_type);
 
   // Request decoding of exactly one frame or an EOS buffer. This must not be
   // called while there are pending Initialize(), Reset(), or Decode(EOS)
diff --git a/media/mojo/mojom/watch_time_recorder.mojom b/media/mojo/mojom/watch_time_recorder.mojom
index 9f9a917..0232d9ee 100644
--- a/media/mojo/mojom/watch_time_recorder.mojom
+++ b/media/mojo/mojom/watch_time_recorder.mojom
@@ -28,8 +28,8 @@
   VideoCodec video_codec;  // playbacks (HLS, remoting, etc).
   AudioCodecProfile audio_codec_profile;
   VideoCodecProfile video_codec_profile;
-  string audio_decoder_name;
-  string video_decoder_name;
+  AudioDecoderType audio_decoder;
+  VideoDecoderType video_decoder;
   EncryptionScheme audio_encryption_scheme;
   EncryptionScheme video_encryption_scheme;
   gfx.mojom.Size natural_size;  // Size of video frame; (0, 0) if audio only.
diff --git a/media/mojo/services/media_metrics_provider.cc b/media/mojo/services/media_metrics_provider.cc
index 3b64108..4f4d4e2 100644
--- a/media/mojo/services/media_metrics_provider.cc
+++ b/media/mojo/services/media_metrics_provider.cc
@@ -102,10 +102,9 @@
     return uma_name + "Other";
 
 #if !defined(OS_ANDROID)
-  if (player_info.video_pipeline_info.decoder_name ==
-      DecryptingVideoDecoder::kDecoderName) {
+  if (player_info.video_pipeline_info.decoder_type ==
+      VideoDecoderType::kDecrypting)
     return uma_name + "DVD";
-  }
 #endif
 
   if (player_info.video_pipeline_info.has_decrypting_demuxer_stream)
@@ -142,7 +141,8 @@
 
   // Report whether video decoder fallback happened, but only if a video decoder
   // was reported.
-  if (!uma_info_.video_pipeline_info.decoder_name.empty()) {
+  if (uma_info_.video_pipeline_info.decoder_type !=
+      VideoDecoderType::kUnknown) {
     base::UmaHistogramBoolean("Media.VideoDecoderFallback",
                               uma_info_.video_decoder_changed);
   }
@@ -195,16 +195,15 @@
   uma_info_.has_reached_have_enough = true;
 }
 
-void MediaMetricsProvider::SetVideoPipelineInfo(
-    const PipelineDecoderInfo& info) {
-  auto old_name = uma_info_.video_pipeline_info.decoder_name;
-  if (!old_name.empty() && old_name != info.decoder_name)
+void MediaMetricsProvider::SetVideoPipelineInfo(const VideoDecoderInfo& info) {
+  auto old_decoder = uma_info_.video_pipeline_info.decoder_type;
+  if (old_decoder != VideoDecoderType::kUnknown &&
+      old_decoder != info.decoder_type)
     uma_info_.video_decoder_changed = true;
   uma_info_.video_pipeline_info = info;
 }
 
-void MediaMetricsProvider::SetAudioPipelineInfo(
-    const PipelineDecoderInfo& info) {
+void MediaMetricsProvider::SetAudioPipelineInfo(const AudioDecoderInfo& info) {
   uma_info_.audio_pipeline_info = info;
 }
 
diff --git a/media/mojo/services/media_metrics_provider.h b/media/mojo/services/media_metrics_provider.h
index ef0ce4b..e0d18e9e 100644
--- a/media/mojo/services/media_metrics_provider.h
+++ b/media/mojo/services/media_metrics_provider.h
@@ -95,15 +95,15 @@
     bool video_decoder_changed = false;
     AudioCodec audio_codec;
     VideoCodec video_codec;
-    PipelineDecoderInfo video_pipeline_info;
-    PipelineDecoderInfo audio_pipeline_info;
+    VideoDecoderInfo video_pipeline_info;
+    AudioDecoderInfo audio_pipeline_info;
     PipelineStatus last_pipeline_status = PIPELINE_OK;
   };
 
   // mojom::MediaMetricsProvider implementation:
   void Initialize(bool is_mse, mojom::MediaURLScheme url_scheme) override;
   void OnError(PipelineStatus status) override;
-  void SetAudioPipelineInfo(const PipelineDecoderInfo& info) override;
+  void SetAudioPipelineInfo(const AudioDecoderInfo& info) override;
   void SetContainerName(
       container_names::MediaContainerName container_name) override;
   void SetHasAudio(AudioCodec audio_codec) override;
@@ -114,7 +114,7 @@
   void SetTimeToMetadata(base::TimeDelta elapsed) override;
   void SetTimeToFirstFrame(base::TimeDelta elapsed) override;
   void SetTimeToPlayReady(base::TimeDelta elapsed) override;
-  void SetVideoPipelineInfo(const PipelineDecoderInfo& info) override;
+  void SetVideoPipelineInfo(const VideoDecoderInfo& info) override;
 
   void AcquireWatchTimeRecorder(
       mojom::PlaybackPropertiesPtr properties,
diff --git a/media/mojo/services/media_metrics_provider_unittest.cc b/media/mojo/services/media_metrics_provider_unittest.cc
index af54242..8107fb6 100644
--- a/media/mojo/services/media_metrics_provider_unittest.cc
+++ b/media/mojo/services/media_metrics_provider_unittest.cc
@@ -157,8 +157,8 @@
 TEST_F(MediaMetricsProviderTest, TestPipelineUMA) {
   base::HistogramTester histogram_tester;
   Initialize(false, false, false, kTestOrigin, mojom::MediaURLScheme::kHttps);
-  provider_->SetAudioPipelineInfo({false, false, "TestAudioDecoder"});
-  provider_->SetVideoPipelineInfo({false, false, "TestVideoDecoder"});
+  provider_->SetAudioPipelineInfo({false, false, AudioDecoderType::kMojo});
+  provider_->SetVideoPipelineInfo({false, false, VideoDecoderType::kMojo});
   provider_->SetHasAudio(AudioCodec::kCodecVorbis);
   provider_->SetHasVideo(VideoCodec::kCodecVP9);
   provider_->SetHasPlayed();
@@ -175,7 +175,7 @@
   base::HistogramTester histogram_tester;
   Initialize(false, false, false, kTestOrigin, mojom::MediaURLScheme::kHttps);
   provider_->SetIsEME();
-  provider_->SetVideoPipelineInfo({true, true, "TestEMEVideoDecoder"});
+  provider_->SetVideoPipelineInfo({true, true, VideoDecoderType::kMojo});
   provider_->SetHasVideo(VideoCodec::kCodecAV1);
   provider_->SetHasPlayed();
   provider_->SetHaveEnough();
@@ -192,13 +192,13 @@
   base::HistogramTester histogram_tester;
   Initialize(false, false, false, kTestOrigin, mojom::MediaURLScheme::kHttps);
   provider_->SetIsEME();
-  provider_->SetAudioPipelineInfo({false, false, "TestAudioDecoder"});
-  provider_->SetVideoPipelineInfo({true, false, "D3D11VideoDecoder"});
+  provider_->SetAudioPipelineInfo({false, false, AudioDecoderType::kMojo});
+  provider_->SetVideoPipelineInfo({true, false, VideoDecoderType::kD3D11});
   provider_->SetHasVideo(VideoCodec::kCodecVP9);
   provider_->SetHasAudio(AudioCodec::kCodecVorbis);
   provider_->SetHasPlayed();
   provider_->SetHaveEnough();
-  provider_->SetVideoPipelineInfo({true, false, "DXVAVideoDecoder"});
+  provider_->SetVideoPipelineInfo({true, false, VideoDecoderType::kFFmpeg});
   provider_.reset();
   base::RunLoop().RunUntilIdle();
   histogram_tester.ExpectBucketCount("Media.PipelineStatus.AudioVideo.VP9.HW",
diff --git a/media/mojo/services/mojo_audio_decoder_service.cc b/media/mojo/services/mojo_audio_decoder_service.cc
index e46ec68..3ac7ae1 100644
--- a/media/mojo/services/mojo_audio_decoder_service.cc
+++ b/media/mojo/services/mojo_audio_decoder_service.cc
@@ -110,12 +110,14 @@
 
   if (!status.is_ok()) {
     // Do not call decoder_->NeedsBitstreamConversion() if init failed.
-    std::move(callback).Run(std::move(status), false);
+    std::move(callback).Run(std::move(status), false,
+                            AudioDecoderType::kUnknown);
     return;
   }
 
   std::move(callback).Run(std::move(status),
-                          decoder_->NeedsBitstreamConversion());
+                          decoder_->NeedsBitstreamConversion(),
+                          decoder_->GetDecoderType());
 }
 
 // The following methods are needed so that we can bind them with a weak pointer
diff --git a/media/mojo/services/mojo_video_decoder_service.cc b/media/mojo/services/mojo_video_decoder_service.cc
index db13749..450d27e 100644
--- a/media/mojo/services/mojo_video_decoder_service.cc
+++ b/media/mojo/services/mojo_video_decoder_service.cc
@@ -280,9 +280,13 @@
   TRACE_EVENT_ASYNC_END1("media", kInitializeTraceName, this, "success",
                          status.code());
 
-  std::move(init_cb_).Run(
-      status, status.is_ok() ? decoder_->NeedsBitstreamConversion() : false,
-      status.is_ok() ? decoder_->GetMaxDecodeRequests() : 1);
+  if (!status.is_ok()) {
+    std::move(init_cb_).Run(status, false, 1, VideoDecoderType::kUnknown);
+    return;
+  }
+  std::move(init_cb_).Run(status, decoder_->NeedsBitstreamConversion(),
+                          decoder_->GetMaxDecodeRequests(),
+                          decoder_->GetDecoderType());
 }
 
 void MojoVideoDecoderService::OnReaderRead(
diff --git a/media/mojo/services/watch_time_recorder.cc b/media/mojo/services/watch_time_recorder.cc
index 4b79356..0bc3514 100644
--- a/media/mojo/services/watch_time_recorder.cc
+++ b/media/mojo/services/watch_time_recorder.cc
@@ -26,84 +26,6 @@
 constexpr base::TimeDelta kMinimumElapsedWatchTime =
     base::TimeDelta::FromSeconds(limits::kMinimumElapsedWatchTimeSecs);
 
-// List of known AudioDecoder implementations; recorded to UKM, always add new
-// values to the end and do not reorder or delete values from this list.
-enum class AudioDecoderName : int {
-  kUnknown = 0,      // Decoder name string is not recognized or n/a.
-  kFFmpeg = 1,       // FFmpegAudioDecoder
-  kMojo = 2,         // MojoAudioDecoder
-  kDecrypting = 3,   // DecryptingAudioDecoder
-  kMediaPlayer = 4,  // MediaPlayer
-};
-
-// List of known VideoDecoder implementations; recorded to UKM, always add new
-// values to the end and do not reorder or delete values from this list.
-enum class VideoDecoderName : int {
-  kUnknown = 0,      // Decoder name string is not recognized or n/a.
-  kGpu = 1,          // GpuVideoDecoder
-  kFFmpeg = 2,       // FFmpegVideoDecoder
-  kVpx = 3,          // VpxVideoDecoder
-  kAom = 4,          // AomVideoDecoder
-  kMojo = 5,         // MojoVideoDecoder
-  kDecrypting = 6,   // DecryptingVideoDecoder
-  kDav1d = 7,        // Dav1dVideoDecoder
-  kFuchsia = 8,      // FuchsiaVideoDecoder
-  kMediaPlayer = 9,  // MediaPlayer
-  kLibgav1 = 10,     // Gav1VideoDecoder
-};
-
-static AudioDecoderName ConvertAudioDecoderNameToEnum(const std::string& name) {
-  // See the unittest DISABLED_PrintExpectedDecoderNameHashes() for how these
-  // values are computed.
-  switch (base::PersistentHash(name)) {
-    case 0xd39e0c2d:
-      return AudioDecoderName::kFFmpeg;
-    case 0xdaceafdb:
-      return AudioDecoderName::kMojo;
-    case 0xd39a2eda:
-      return AudioDecoderName::kDecrypting;
-    case 0x667dc202:
-      return AudioDecoderName::kMediaPlayer;
-    default:
-      DLOG_IF(WARNING, !name.empty())
-          << "Unknown decoder name encountered; metrics need updating: "
-          << name;
-  }
-  return AudioDecoderName::kUnknown;
-}
-
-static VideoDecoderName ConvertVideoDecoderNameToEnum(const std::string& name) {
-  // See the unittest DISABLED_PrintExpectedDecoderNameHashes() for how these
-  // values are computed.
-  switch (base::PersistentHash(name)) {
-    case 0xacdee563:
-      return VideoDecoderName::kFFmpeg;
-    case 0x943f016f:
-      return VideoDecoderName::kMojo;
-    case 0xf66241b8:
-      return VideoDecoderName::kGpu;
-    case 0xb3802adb:
-      return VideoDecoderName::kVpx;
-    case 0xcff23b85:
-      return VideoDecoderName::kAom;
-    case 0xb52d52f5:
-      return VideoDecoderName::kDecrypting;
-    case 0xcd46efa0:
-      return VideoDecoderName::kDav1d;
-    case 0x27b31c6a:
-      return VideoDecoderName::kFuchsia;
-    case 0x667dc202:
-      return VideoDecoderName::kMediaPlayer;
-    case 0x0cd14d5b:
-      return VideoDecoderName::kLibgav1;
-    default:
-      DLOG_IF(WARNING, !name.empty())
-          << "Unknown decoder name encountered; metrics need updating: "
-          << name;
-  }
-  return VideoDecoderName::kUnknown;
-}
-
 static void RecordWatchTimeInternal(
     base::StringPiece key,
     base::TimeDelta value,
@@ -284,8 +206,10 @@
             AudioCodecProfile::kUnknown ||
         last_record.secondary_properties->video_codec_profile ==
             VIDEO_CODEC_PROFILE_UNKNOWN ||
-        last_record.secondary_properties->audio_decoder_name.empty() ||
-        last_record.secondary_properties->video_decoder_name.empty()) {
+        last_record.secondary_properties->audio_decoder ==
+            AudioDecoderType::kUnknown ||
+        last_record.secondary_properties->video_decoder ==
+            VideoDecoderType::kUnknown) {
       auto temp_props = last_record.secondary_properties.Clone();
       if (last_record.secondary_properties->audio_codec == kUnknownAudioCodec)
         temp_props->audio_codec = secondary_properties->audio_codec;
@@ -301,13 +225,13 @@
         temp_props->video_codec_profile =
             secondary_properties->video_codec_profile;
       }
-      if (last_record.secondary_properties->audio_decoder_name.empty()) {
-        temp_props->audio_decoder_name =
-            secondary_properties->audio_decoder_name;
+      if (last_record.secondary_properties->audio_decoder ==
+          AudioDecoderType::kUnknown) {
+        temp_props->audio_decoder = secondary_properties->audio_decoder;
       }
-      if (last_record.secondary_properties->video_decoder_name.empty()) {
-        temp_props->video_decoder_name =
-            secondary_properties->video_decoder_name;
+      if (last_record.secondary_properties->video_decoder ==
+          VideoDecoderType::kUnknown) {
+        temp_props->video_decoder = secondary_properties->video_decoder;
       }
       if (temp_props->Equals(*secondary_properties)) {
         last_record.secondary_properties = std::move(temp_props);
@@ -512,24 +436,10 @@
     if (ukm_record.secondary_properties->audio_codec == kCodecAAC)
       aac_profiles.insert(ukm_record.secondary_properties->audio_codec_profile);
 
-    // We convert decoder names to a hash and then translate that hash to a zero
-    // valued enum to avoid burdening the rest of the decoder code base. This
-    // was the simplest and most effective solution for the following reasons:
-    //
-    // - We can't report hashes to UKM since the privacy team worries they may
-    //   end up as hashes of user data.
-    // - Given that decoders are defined and implemented all over the code base
-    //   it's unwieldly to have a single location which defines all decoder
-    //   names.
-    // - Due to the above, no single media/ location has access to all names.
-    //
     builder.SetAudioDecoderName(
-        static_cast<int64_t>(ConvertAudioDecoderNameToEnum(
-            ukm_record.secondary_properties->audio_decoder_name)));
+        static_cast<int64_t>(ukm_record.secondary_properties->audio_decoder));
     builder.SetVideoDecoderName(
-        static_cast<int64_t>(ConvertVideoDecoderNameToEnum(
-            ukm_record.secondary_properties->video_decoder_name)));
-
+        static_cast<int64_t>(ukm_record.secondary_properties->video_decoder));
     builder.SetAudioEncryptionScheme(static_cast<int64_t>(
         ukm_record.secondary_properties->audio_encryption_scheme));
     builder.SetVideoEncryptionScheme(static_cast<int64_t>(
diff --git a/media/mojo/services/watch_time_recorder_unittest.cc b/media/mojo/services/watch_time_recorder_unittest.cc
index bf1e96c8..649a300 100644
--- a/media/mojo/services/watch_time_recorder_unittest.cc
+++ b/media/mojo/services/watch_time_recorder_unittest.cc
@@ -177,7 +177,8 @@
   mojom::SecondaryPlaybackPropertiesPtr CreateSecondaryProperties() {
     return mojom::SecondaryPlaybackProperties::New(
         kCodecAAC, kCodecH264, AudioCodecProfile::kUnknown, H264PROFILE_MAIN,
-        "", "", EncryptionScheme::kUnencrypted, EncryptionScheme::kUnencrypted,
+        AudioDecoderType::kUnknown, VideoDecoderType::kUnknown,
+        EncryptionScheme::kUnencrypted, EncryptionScheme::kUnencrypted,
         gfx::Size(800, 600));
   }
 
@@ -601,7 +602,8 @@
   mojom::SecondaryPlaybackPropertiesPtr secondary_properties =
       mojom::SecondaryPlaybackProperties::New(
           kCodecAAC, kCodecH264, AudioCodecProfile::kXHE_AAC, H264PROFILE_MAIN,
-          "", "", EncryptionScheme::kCenc, EncryptionScheme::kCbcs,
+          AudioDecoderType::kUnknown, VideoDecoderType::kUnknown,
+          EncryptionScheme::kCenc, EncryptionScheme::kCbcs,
           gfx::Size(800, 600));
   Initialize(properties.Clone());
   wtr_->UpdateSecondaryProperties(secondary_properties.Clone());
@@ -668,7 +670,8 @@
   mojom::SecondaryPlaybackPropertiesPtr secondary_properties =
       mojom::SecondaryPlaybackProperties::New(
           kCodecOpus, kCodecVP9, AudioCodecProfile::kUnknown,
-          VP9PROFILE_PROFILE0, "", "", EncryptionScheme::kUnencrypted,
+          VP9PROFILE_PROFILE0, AudioDecoderType::kUnknown,
+          VideoDecoderType::kUnknown, EncryptionScheme::kUnencrypted,
           EncryptionScheme::kUnencrypted, gfx::Size(800, 600));
   Initialize(properties.Clone());
   wtr_->UpdateSecondaryProperties(secondary_properties.Clone());
@@ -699,8 +702,8 @@
   wtr_->UpdateVideoDecodeStats(10, 2);
   wtr_->OnError(PIPELINE_ERROR_DECODE);
 
-  secondary_properties->audio_decoder_name = "MojoAudioDecoder";
-  secondary_properties->video_decoder_name = "MojoVideoDecoder";
+  secondary_properties->audio_decoder = AudioDecoderType::kMojo;
+  secondary_properties->video_decoder = VideoDecoderType::kMojo;
   wtr_->UpdateSecondaryProperties(secondary_properties.Clone());
 
   wtr_->SetAutoplayInitiated(true);
@@ -992,7 +995,8 @@
   mojom::SecondaryPlaybackPropertiesPtr secondary_properties1 =
       mojom::SecondaryPlaybackProperties::New(
           kUnknownAudioCodec, kUnknownVideoCodec, AudioCodecProfile::kUnknown,
-          VIDEO_CODEC_PROFILE_UNKNOWN, "", "", EncryptionScheme::kUnencrypted,
+          VIDEO_CODEC_PROFILE_UNKNOWN, AudioDecoderType::kUnknown,
+          VideoDecoderType::kUnknown, EncryptionScheme::kUnencrypted,
           EncryptionScheme::kUnencrypted, gfx::Size(800, 600));
   Initialize(properties.Clone());
   wtr_->UpdateSecondaryProperties(secondary_properties1.Clone());
@@ -1003,7 +1007,7 @@
   mojom::SecondaryPlaybackPropertiesPtr secondary_properties2 =
       mojom::SecondaryPlaybackProperties::New(
           kCodecAAC, kCodecH264, AudioCodecProfile::kXHE_AAC, H264PROFILE_MAIN,
-          "FFmpegAudioDecoder", "FFmpegVideoDecoder",
+          AudioDecoderType::kFFmpeg, VideoDecoderType::kFFmpeg,
           EncryptionScheme::kUnencrypted, EncryptionScheme::kUnencrypted,
           gfx::Size(800, 600));
   wtr_->UpdateSecondaryProperties(secondary_properties2.Clone());
@@ -1059,7 +1063,7 @@
   mojom::SecondaryPlaybackPropertiesPtr secondary_properties1 =
       mojom::SecondaryPlaybackProperties::New(
           kCodecOpus, kCodecVP9, AudioCodecProfile::kUnknown,
-          VP9PROFILE_PROFILE0, "MojoAudioDecoder", "MojoVideoDecoder",
+          VP9PROFILE_PROFILE0, AudioDecoderType::kMojo, VideoDecoderType::kMojo,
           EncryptionScheme::kUnencrypted, EncryptionScheme::kUnencrypted,
           gfx::Size(400, 300));
   Initialize(properties.Clone());
@@ -1080,8 +1084,9 @@
   mojom::SecondaryPlaybackPropertiesPtr secondary_properties2 =
       mojom::SecondaryPlaybackProperties::New(
           kCodecAAC, kCodecH264, AudioCodecProfile::kUnknown, H264PROFILE_MAIN,
-          "FFmpegAudioDecoder", "FFmpegVideoDecoder", EncryptionScheme::kCenc,
-          EncryptionScheme::kCenc, gfx::Size(800, 600));
+          AudioDecoderType::kFFmpeg, VideoDecoderType::kFFmpeg,
+          EncryptionScheme::kCenc, EncryptionScheme::kCenc,
+          gfx::Size(800, 600));
   wtr_->UpdateSecondaryProperties(secondary_properties2.Clone());
 
   constexpr base::TimeDelta kWatchTime2 = base::TimeDelta::FromSeconds(25);
@@ -1189,7 +1194,7 @@
   mojom::SecondaryPlaybackPropertiesPtr secondary_properties1 =
       mojom::SecondaryPlaybackProperties::New(
           kCodecOpus, kCodecVP9, AudioCodecProfile::kUnknown,
-          VP9PROFILE_PROFILE0, "MojoAudioDecoder", "MojoVideoDecoder",
+          VP9PROFILE_PROFILE0, AudioDecoderType::kMojo, VideoDecoderType::kMojo,
           EncryptionScheme::kUnencrypted, EncryptionScheme::kUnencrypted,
           gfx::Size(400, 300));
   Initialize(properties.Clone());
@@ -1210,7 +1215,7 @@
   mojom::SecondaryPlaybackPropertiesPtr secondary_properties2 =
       mojom::SecondaryPlaybackProperties::New(
           kCodecAAC, kCodecH264, AudioCodecProfile::kXHE_AAC, H264PROFILE_MAIN,
-          "FFmpegAudioDecoder", "FFmpegVideoDecoder",
+          AudioDecoderType::kFFmpeg, VideoDecoderType::kFFmpeg,
           EncryptionScheme::kUnencrypted, EncryptionScheme::kUnencrypted,
           gfx::Size(800, 600));
   wtr_->UpdateSecondaryProperties(secondary_properties2.Clone());
@@ -1302,7 +1307,7 @@
   mojom::SecondaryPlaybackPropertiesPtr secondary_properties1 =
       mojom::SecondaryPlaybackProperties::New(
           kCodecOpus, kCodecVP9, AudioCodecProfile::kUnknown,
-          VP9PROFILE_PROFILE0, "MojoAudioDecoder", "MojoVideoDecoder",
+          VP9PROFILE_PROFILE0, AudioDecoderType::kMojo, VideoDecoderType::kMojo,
           EncryptionScheme::kCbcs, EncryptionScheme::kCbcs,
           gfx::Size(400, 300));
   Initialize(properties.Clone());
@@ -1327,7 +1332,7 @@
   mojom::SecondaryPlaybackPropertiesPtr secondary_properties2 =
       mojom::SecondaryPlaybackProperties::New(
           kCodecAAC, kCodecH264, AudioCodecProfile::kXHE_AAC, H264PROFILE_MAIN,
-          "FFmpegAudioDecoder", "FFmpegVideoDecoder",
+          AudioDecoderType::kFFmpeg, VideoDecoderType::kFFmpeg,
           EncryptionScheme::kUnencrypted, EncryptionScheme::kUnencrypted,
           gfx::Size(800, 600));
   wtr_->UpdateSecondaryProperties(secondary_properties2.Clone());
@@ -1427,7 +1432,7 @@
   mojom::SecondaryPlaybackPropertiesPtr secondary_properties1 =
       mojom::SecondaryPlaybackProperties::New(
           kCodecOpus, kCodecVP9, AudioCodecProfile::kUnknown,
-          VP9PROFILE_PROFILE0, "MojoAudioDecoder", "MojoVideoDecoder",
+          VP9PROFILE_PROFILE0, AudioDecoderType::kMojo, VideoDecoderType::kMojo,
           EncryptionScheme::kCbcs, EncryptionScheme::kCbcs,
           gfx::Size(400, 300));
   Initialize(properties.Clone());
@@ -1446,7 +1451,7 @@
   mojom::SecondaryPlaybackPropertiesPtr secondary_properties2 =
       mojom::SecondaryPlaybackProperties::New(
           kCodecAAC, kCodecH264, AudioCodecProfile::kXHE_AAC, H264PROFILE_MAIN,
-          "FFmpegAudioDecoder", "FFmpegVideoDecoder",
+          AudioDecoderType::kFFmpeg, VideoDecoderType::kFFmpeg,
           EncryptionScheme::kUnencrypted, EncryptionScheme::kUnencrypted,
           gfx::Size(800, 600));
   wtr_->UpdateSecondaryProperties(secondary_properties2.Clone());
@@ -1551,16 +1556,4 @@
 #undef EXPECT_NO_UKM
 #undef EXPECT_HAS_UKM
 
-TEST_F(WatchTimeRecorderTest, DISABLED_PrintExpectedDecoderNameHashes) {
-  const std::string kDecoderNames[] = {
-      "FFmpegAudioDecoder", "FFmpegVideoDecoder",     "GpuVideoDecoder",
-      "MojoVideoDecoder",   "MojoAudioDecoder",       "VpxVideoDecoder",
-      "AomVideoDecoder",    "DecryptingAudioDecoder", "DecryptingVideoDecoder",
-      "Dav1dVideoDecoder",  "FuchsiaVideoDecoder",    "MediaPlayer",
-      "Gav1VideoDecoder"};
-  printf("%18s = 0\n", "None");
-  for (const auto& name : kDecoderNames)
-    printf("%18s = 0x%08x\n", name.c_str(), base::PersistentHash(name));
-}
-
 }  // namespace media
diff --git a/media/mojo/test/mojo_video_decoder_integration_test.cc b/media/mojo/test/mojo_video_decoder_integration_test.cc
index 6ab33c92..d3dae55 100644
--- a/media/mojo/test/mojo_video_decoder_integration_test.cc
+++ b/media/mojo/test/mojo_video_decoder_integration_test.cc
@@ -69,6 +69,8 @@
     // Treat const getters like a NiceMock.
     EXPECT_CALL(*this, GetDisplayName())
         .WillRepeatedly(Return("MockVideoDecoder"));
+    EXPECT_CALL(*this, GetDecoderType())
+        .WillRepeatedly(Return(VideoDecoderType::kUnknown));
     EXPECT_CALL(*this, NeedsBitstreamConversion())
         .WillRepeatedly(Return(false));
     EXPECT_CALL(*this, CanReadWithoutStalling()).WillRepeatedly(Return(true));
@@ -87,6 +89,7 @@
 
   // media::VideoDecoder implementation
   MOCK_CONST_METHOD0(GetDisplayName, std::string());
+  MOCK_CONST_METHOD0(GetDecoderType, VideoDecoderType());
 
   // Initialize() records values before delegating to the mock method.
   void Initialize(const VideoDecoderConfig& config,
diff --git a/media/remoting/courier_renderer_unittest.cc b/media/remoting/courier_renderer_unittest.cc
index e4c2ea9..edb73477 100644
--- a/media/remoting/courier_renderer_unittest.cc
+++ b/media/remoting/courier_renderer_unittest.cc
@@ -53,8 +53,8 @@
   stats.audio_memory_usage = 5678;
   stats.video_memory_usage = 6789;
   stats.video_keyframe_distance_average = base::TimeDelta::Max();
-  stats.audio_decoder_info = {false, false, "Default"};
-  stats.video_decoder_info = {false, false, "Default"};
+  stats.audio_decoder_info = {false, false, AudioDecoderType::kUnknown};
+  stats.video_decoder_info = {false, false, VideoDecoderType::kUnknown};
   return stats;
 }
 
@@ -419,12 +419,12 @@
     message->set_video_memory_usage(stats.video_memory_usage);
     message->mutable_audio_decoder_info()->set_is_platform_decoder(
         stats.audio_decoder_info.is_platform_decoder);
-    message->mutable_audio_decoder_info()->set_decoder_name(
-        stats.audio_decoder_info.decoder_name);
+    message->mutable_audio_decoder_info()->set_decoder_type(
+        static_cast<int64_t>(stats.audio_decoder_info.decoder_type));
     message->mutable_video_decoder_info()->set_is_platform_decoder(
         stats.video_decoder_info.is_platform_decoder);
-    message->mutable_video_decoder_info()->set_decoder_name(
-        stats.video_decoder_info.decoder_name);
+    message->mutable_video_decoder_info()->set_decoder_type(
+        static_cast<int64_t>(stats.video_decoder_info.decoder_type));
     OnReceivedRpc(std::move(rpc));
     RunPendingTasks();
   }
diff --git a/media/remoting/media_remoting_rpc.proto b/media/remoting/media_remoting_rpc.proto
index b194081..2375db4 100644
--- a/media/remoting/media_remoting_rpc.proto
+++ b/media/remoting/media_remoting_rpc.proto
@@ -271,8 +271,14 @@
   optional uint32 skip_byte_block = 6 [deprecated = true];
 }
 
-message PipelineDecoderInfo {
-  optional string decoder_name = 1;
+message AudioDecoderInfo {
+  optional int64 decoder_type = 1;
+  optional bool is_platform_decoder = 2;
+  optional bool has_decrypting_demuxer_stream = 3 [deprecated = true];
+};
+
+message VideoDecoderInfo {
+  optional int64 decoder_type = 1;
   optional bool is_platform_decoder = 2;
   optional bool has_decrypting_demuxer_stream = 3 [deprecated = true];
 };
@@ -285,8 +291,8 @@
   optional int64 audio_memory_usage = 5;
   optional int64 video_memory_usage = 6;
   optional int64 video_frame_duration_average_usec = 7;
-  optional PipelineDecoderInfo audio_decoder_info = 8;
-  optional PipelineDecoderInfo video_decoder_info = 9;
+  optional AudioDecoderInfo audio_decoder_info = 8;
+  optional VideoDecoderInfo video_decoder_info = 9;
 };
 
 message CdmKeyInformation {
diff --git a/media/remoting/proto_utils.cc b/media/remoting/proto_utils.cc
index 59270d9..17c8640 100644
--- a/media/remoting/proto_utils.cc
+++ b/media/remoting/proto_utils.cc
@@ -311,14 +311,16 @@
   // that sender provided the values.
   if (stats_message.has_audio_decoder_info()) {
     auto audio_info = stats_message.audio_decoder_info();
-    stats->audio_decoder_info.decoder_name = audio_info.decoder_name();
+    stats->audio_decoder_info.decoder_type =
+        static_cast<AudioDecoderType>(audio_info.decoder_type());
     stats->audio_decoder_info.is_platform_decoder =
         audio_info.is_platform_decoder();
     stats->audio_decoder_info.has_decrypting_demuxer_stream = false;
   }
   if (stats_message.has_video_decoder_info()) {
     auto video_info = stats_message.video_decoder_info();
-    stats->video_decoder_info.decoder_name = video_info.decoder_name();
+    stats->video_decoder_info.decoder_type =
+        static_cast<VideoDecoderType>(video_info.decoder_type());
     stats->video_decoder_info.is_platform_decoder =
         video_info.is_platform_decoder();
     stats->video_decoder_info.has_decrypting_demuxer_stream = false;
diff --git a/media/remoting/proto_utils_unittest.cc b/media/remoting/proto_utils_unittest.cc
index a322fcc..04e6fb3 100644
--- a/media/remoting/proto_utils_unittest.cc
+++ b/media/remoting/proto_utils_unittest.cc
@@ -126,15 +126,15 @@
   original.video_memory_usage = 43;
   original.video_keyframe_distance_average = base::TimeDelta::Max();
   original.video_frame_duration_average = base::TimeDelta::Max();
-  original.audio_decoder_info = {false, false, "TestAudioDecoder"};
-  original.video_decoder_info = {false, false, "TestVideoDecoder"};
+  original.audio_decoder_info = {false, false,
+                                 media::AudioDecoderType::kUnknown};
+  original.video_decoder_info = {false, false,
+                                 media::VideoDecoderType::kUnknown};
 
   // There is no convert-to-proto function, so just do that here.
   pb::PipelineStatistics pb_stats;
-  pb::PipelineDecoderInfo* pb_video_info =
-      pb_stats.mutable_video_decoder_info();
-  pb::PipelineDecoderInfo* pb_audio_info =
-      pb_stats.mutable_audio_decoder_info();
+  pb::VideoDecoderInfo* pb_video_info = pb_stats.mutable_video_decoder_info();
+  pb::AudioDecoderInfo* pb_audio_info = pb_stats.mutable_audio_decoder_info();
   pb_stats.set_audio_bytes_decoded(original.audio_bytes_decoded);
   pb_stats.set_video_bytes_decoded(original.video_bytes_decoded);
   pb_stats.set_video_frames_decoded(original.video_frames_decoded);
@@ -144,11 +144,13 @@
   pb_stats.set_video_frame_duration_average_usec(
       original.video_frame_duration_average.InMicroseconds());
 
-  pb_video_info->set_decoder_name(original.video_decoder_info.decoder_name);
+  pb_video_info->set_decoder_type(
+      static_cast<int64_t>(original.video_decoder_info.decoder_type));
   pb_video_info->set_is_platform_decoder(
       original.video_decoder_info.is_platform_decoder);
 
-  pb_audio_info->set_decoder_name(original.audio_decoder_info.decoder_name);
+  pb_audio_info->set_decoder_type(
+      static_cast<int64_t>(original.audio_decoder_info.decoder_type));
   pb_audio_info->set_is_platform_decoder(
       original.audio_decoder_info.is_platform_decoder);
 
@@ -157,11 +159,11 @@
   // NOTE: fields will all be initialized with 0xcd. Forcing the conversion to
   // properly assigned them. Since nested structs have strings, memsetting must
   // be done infividually for them.
-  memset(&converted, 0xcd, sizeof(converted) - sizeof(PipelineDecoderInfo) * 2);
-  memset(&converted.audio_decoder_info, 0xcd,
-         sizeof(PipelineDecoderInfo) - sizeof(std::string));
-  memset(&converted.video_decoder_info, 0xcd,
-         sizeof(PipelineDecoderInfo) - sizeof(std::string));
+  memset(
+      &converted, 0xcd,
+      sizeof(converted) - sizeof(AudioDecoderInfo) - sizeof(VideoDecoderInfo));
+  memset(&converted.audio_decoder_info, 0xcd, sizeof(AudioDecoderInfo));
+  memset(&converted.video_decoder_info, 0xcd, sizeof(VideoDecoderInfo));
 
   ConvertProtoToPipelineStatistics(pb_stats, &converted);
 
diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc
index 96ec9ea..5a3d8c1 100644
--- a/media/test/pipeline_integration_test.cc
+++ b/media/test/pipeline_integration_test.cc
@@ -351,6 +351,9 @@
 class FailingVideoDecoder : public VideoDecoder {
  public:
   std::string GetDisplayName() const override { return "FailingVideoDecoder"; }
+  VideoDecoderType GetDecoderType() const override {
+    return VideoDecoderType::kUnknown;
+  }
   void Initialize(const VideoDecoderConfig& config,
                   bool low_delay,
                   CdmContext* cdm_context,
diff --git a/media/test/pipeline_integration_test_base.h b/media/test/pipeline_integration_test_base.h
index a841b48..6d4d957 100644
--- a/media/test/pipeline_integration_test_base.h
+++ b/media/test/pipeline_integration_test_base.h
@@ -247,8 +247,8 @@
   MOCK_METHOD1(OnVideoOpacityChange, void(bool));
   MOCK_METHOD1(OnVideoFrameRateChange, void(base::Optional<int>));
   MOCK_METHOD0(OnVideoAverageKeyframeDistanceUpdate, void());
-  MOCK_METHOD1(OnAudioDecoderChange, void(const PipelineDecoderInfo&));
-  MOCK_METHOD1(OnVideoDecoderChange, void(const PipelineDecoderInfo&));
+  MOCK_METHOD1(OnAudioDecoderChange, void(const AudioDecoderInfo&));
+  MOCK_METHOD1(OnVideoDecoderChange, void(const VideoDecoderInfo&));
   MOCK_METHOD1(OnRemotePlayStateChange, void(MediaStatus::State state));
 
  private:
diff --git a/mojo/public/cpp/bindings/associated_receiver.h b/mojo/public/cpp/bindings/associated_receiver.h
index c36e24e..3e0d68c0 100644
--- a/mojo/public/cpp/bindings/associated_receiver.h
+++ b/mojo/public/cpp/bindings/associated_receiver.h
@@ -17,7 +17,6 @@
 #include "mojo/public/cpp/bindings/pending_associated_remote.h"
 #include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h"
 #include "mojo/public/cpp/bindings/receiver.h"
-#include "mojo/public/cpp/system/message_pipe.h"
 
 namespace mojo {
 
@@ -63,14 +62,20 @@
 
 }  // namespace internal
 
-// An AssociatedReceiver is used to receive and dispatch Interface method calls
-// to a local implementation of Interface. Every AssociatedReceiver object is
-// permanently linked to an implementation of Interface at construction time.
+// An AssociatedReceiver is similar to a Receiver (see receiver.h): it receives
+// incoming mojom interface method calls (sent over a message pipe from its
+// entangled AssociatedRemote) and dispatches them to a concrete C++
+// implementation.
 //
-// Unlike Receiver, an AssociatedReceiver cannot immediately begin receiving
-// messages from its entangled AssociatedRemote. One of the two endpoints must
-// be transmitted across a concrete Remote first, at which point the endpoints
-// begin piggybacking on that Remote's interface pipe.
+// An AssociatedReceiver is needed when it is important to preserve the relative
+// ordering of calls with another mojom interface. This is implemented by
+// sharing the underlying message pipe between the mojom interfaces where
+// ordering must be preserved.
+//
+// Because of this, an AssociatedReceiver will not receive any mojom interface
+// method calls until one of its endpoints (either the AssociatedRemote itself
+// or its entangled AssociatedReceiver) is sent over a Remote/Receiver pair
+// or an already-established AssociatedRemote/AssociatedReceiver pair.
 template <typename Interface,
           typename ImplRefTraits = RawPtrImplRefTraits<Interface>>
 class AssociatedReceiver : public internal::AssociatedReceiverBase {
@@ -148,82 +153,36 @@
   // about why this end is hanging up.
   using AssociatedReceiverBase::ResetWithReason;
 
-  // Binds this AssociatedReceiver, connecting it to a new
-  // PendingAssociatedRemote which is returned for transmission elsewhere
-  // (typically to an AssociatedRemote who will consume it to start making
-  // calls).
-  //
-  // The AssociatedReceiver will schedule incoming |impl| method calls and
-  // disconnection notifications on the default SequencedTaskRunner (i.e.
-  // base::SequencedTaskRunnerHandle::Get() at the time of this call). Must only
-  // be called on an unbound AssociatedReceiver.
-  PendingAssociatedRemote<Interface> BindNewEndpointAndPassRemote()
-      WARN_UNUSED_RESULT {
-    return BindNewEndpointAndPassRemote(nullptr);
-  }
+  // Helpers for binding and unbinding the AssociatedReceiver. Only an unbound
+  // AssociatedReceiver (i.e. |is_bound()| is false) may be bound. Similarly,
+  // only a bound AssociatedReceiver may be unbound.
 
-  // Like above, but the AssociatedReceiver will schedule incoming |impl| method
-  // calls and disconnection notifications on |task_runner| rather than on the
-  // default SequencedTaskRunner. Must only be called on an unbound
-  // AssociatedReceiver. |task_runner| must run tasks on the same sequence that
-  // owns this AssociatedReceiver.
+  // Binds this AssociatedReceiver with the returned PendingAssociatedRemote.
+  // Mojom interface method calls made via the returned remote will be routed
+  // and dispatched to |impl()|.
+  //
+  // Any incoming method calls or disconnection notifications will be scheduled
+  // to run on |task_runner|. If |task_runner| is null, this defaults to the
+  // current SequencedTaskRunner.
   PendingAssociatedRemote<Interface> BindNewEndpointAndPassRemote(
-      scoped_refptr<base::SequencedTaskRunner> task_runner) WARN_UNUSED_RESULT {
+      scoped_refptr<base::SequencedTaskRunner> task_runner = nullptr)
+      WARN_UNUSED_RESULT {
     DCHECK(!is_bound()) << "AssociatedReceiver is already bound";
+
     PendingAssociatedRemote<Interface> remote;
     Bind(remote.InitWithNewEndpointAndPassReceiver(), std::move(task_runner));
     return remote;
   }
 
-  // Like BindNewEndpointAndPassRemote() above, but it creates a dedicated
-  // message pipe. The returned remote can be bound directly to an
-  // implementation, without being first passed through a message pipe endpoint.
+  // Binds this AssociatedReceiver by consuming |pending_receiver|.
   //
-  // For testing, where the returned request is bound to e.g. a mock and there
-  // are no other interfaces involved.
-  PendingAssociatedRemote<Interface> BindNewEndpointAndPassDedicatedRemote()
-      WARN_UNUSED_RESULT {
+  // Any incoming method calls or disconnection notifications will be scheduled
+  // to run on |task_runner|. If |task_runner| is null, this defaults to the
+  // current SequencedTaskRunner.
+  void Bind(PendingAssociatedReceiver<Interface> pending_receiver,
+            scoped_refptr<base::SequencedTaskRunner> task_runner = nullptr) {
     DCHECK(!is_bound()) << "AssociatedReceiver is already bound";
 
-    MessagePipe pipe;
-    scoped_refptr<internal::MultiplexRouter> router0 =
-        new internal::MultiplexRouter(
-            std::move(pipe.handle0), internal::MultiplexRouter::MULTI_INTERFACE,
-            false, base::SequencedTaskRunnerHandle::Get());
-    scoped_refptr<internal::MultiplexRouter> router1 =
-        new internal::MultiplexRouter(
-            std::move(pipe.handle1), internal::MultiplexRouter::MULTI_INTERFACE,
-            true, base::SequencedTaskRunnerHandle::Get());
-
-    ScopedInterfaceEndpointHandle remote_handle;
-    ScopedInterfaceEndpointHandle receiver_handle;
-    ScopedInterfaceEndpointHandle::CreatePairPendingAssociation(
-        &remote_handle, &receiver_handle);
-    InterfaceId id = router1->AssociateInterface(std::move(receiver_handle));
-    receiver_handle = router0->CreateLocalEndpointHandle(id);
-
-    Bind(PendingAssociatedReceiver<Interface>(std::move(receiver_handle)),
-         nullptr);
-    return PendingAssociatedRemote<Interface>(std::move(remote_handle), 0);
-  }
-
-  // Binds this AssociatedReceiver by consuming |pending_receiver|. Must only be
-  // called on an unbound AssociatedReceiver.
-  //
-  // The newly bound AssociatedReceiver will schedule incoming |impl| method
-  // calls and disconnection notifications on the default SequencedTaskRunner
-  // (i.e. base::SequencedTaskRunnerHandle::Get() at the time of this call).
-  void Bind(PendingAssociatedReceiver<Interface> pending_receiver) {
-    Bind(std::move(pending_receiver), nullptr);
-  }
-
-  // Like above, but the newly bound AssociatedReceiver will schedule incoming
-  // |impl| method calls and disconnection notifications on |task_runner|
-  // instead of the default SequencedTaskRunner. Must only be called on an
-  // unbound AssociatedReceiver. |task_runner| must run tasks on the same
-  // sequence that owns this AssociatedReceiver.
-  void Bind(PendingAssociatedReceiver<Interface> pending_receiver,
-            scoped_refptr<base::SequencedTaskRunner> task_runner) {
     if (pending_receiver) {
       BindImpl(pending_receiver.PassHandle(), &stub_,
                base::WrapUnique(new typename Interface::RequestValidator_()),
@@ -234,6 +193,24 @@
     }
   }
 
+  // Binds this AssociatedReceiver with the returned PendingAssociatedRemote
+  // using a dedicated message pipe. This allows the entangled
+  // AssociatedReceiver/AssociatedRemote endpoints to be used without ever being
+  // associated with any other mojom interfaces.
+  //
+  // Needless to say, messages sent between the two entangled endpoints will not
+  // be ordered with respect to any other mojom interfaces. This is generally
+  // useful for ignoring calls on an associated remote or for binding associated
+  // endpoints in tests.
+  PendingAssociatedRemote<Interface> BindNewEndpointAndPassDedicatedRemote()
+      WARN_UNUSED_RESULT {
+    DCHECK(!is_bound()) << "AssociatedReceiver is already bound";
+
+    PendingAssociatedRemote<Interface> remote = BindNewEndpointAndPassRemote();
+    remote.EnableUnassociatedUsage();
+    return remote;
+  }
+
   // Unbinds this AssociatedReceiver, preventing any further |impl| method calls
   // or disconnection notifications from being scheduled by it. Any such tasks
   // that were scheduled prior to unbinding are effectively cancelled.
diff --git a/mojo/public/cpp/bindings/associated_remote.h b/mojo/public/cpp/bindings/associated_remote.h
index f4b6b1a..988aaef 100644
--- a/mojo/public/cpp/bindings/associated_remote.h
+++ b/mojo/public/cpp/bindings/associated_remote.h
@@ -16,20 +16,25 @@
 #include "base/sequenced_task_runner.h"
 #include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
 #include "mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h"
-#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
 #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
 #include "mojo/public/cpp/bindings/pending_associated_remote.h"
 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
-#include "mojo/public/cpp/system/message_pipe.h"
 
 namespace mojo {
 
-// An AssociatedRemote is similar to a Remote (see remote.h) in that it is used
-// to transmit mojom interface method calls to a remote (Associated) Receiver.
+// An AssociatedRemote is similar to a Remote (see remote.h): it is used to
+// issue mojom interface method calls that will be sent over a message pipe to
+// be handled by the entangled AssociatedReceiver.
 //
-// Unlike Remote, an entangled AssociatedRemote/AssociatedReceiver pair cannot
-// operate on its own and requires a concrete Remote/Receiver pair upon which
-// to piggyback.
+// An AssociatedRemote is needed when it is important to preserve the relative
+// ordering of calls with another mojom interface. This is implemented by
+// sharing the underlying message pipe between the mojom interfaces where
+// ordering must be preserved.
+//
+// Because of this, an AssociatedRemote cannot be used to issue mojom interface
+// method calls until one of its endpoints (either the AssociatedRemote itself
+// or its entangled AssociatedReceiver) is sent over a Remote/Receiver pair
+// or an already-established AssociatedRemote/AssociatedReceiver pair.
 template <typename Interface>
 class AssociatedRemote {
  public:
@@ -148,25 +153,22 @@
     reset();
   }
 
-  // Binds this AssociatedRemote, connecting it to a new
-  // PendingAssociatedReceiver which is returned for transmission to some
-  // AssociatedReceiver which can bind it. The AssociatedRemote will schedule
-  // any response callbacks or disconnection notifications on the default
-  // SequencedTaskRunner (i.e. base::SequencedTaskRunnerHandle::Get() at the
-  // time of this call). Must only be called on an unbound AssociatedRemote.
-  PendingAssociatedReceiver<Interface> BindNewEndpointAndPassReceiver()
+  // Helpers for binding and unbinding the AssociatedRemote. Only an unbound
+  // AssociatedRemote (i.e. |is_bound()| is false) may be bound. Similarly, only
+  // a bound AssociatedRemote may be unbound.
+
+  // Binds this AssociatedRemote with the returned PendingAssociatedReceiver.
+  // Mojom interface method calls made through |this| will be routed to the
+  // object that ends up binding the returned PendingAssociatedReceiver.
+  //
+  // Any response callbacks or disconnection notifications will be scheduled to
+  // run on |task_runner|. If |task_runner| is null, defaults to the current
+  // SequencedTaskRunner.
+  PendingAssociatedReceiver<Interface> BindNewEndpointAndPassReceiver(
+      scoped_refptr<base::SequencedTaskRunner> task_runner = nullptr)
       WARN_UNUSED_RESULT {
     DCHECK(!is_bound()) << "AssociatedRemote is already bound";
-    return BindNewEndpointAndPassReceiver(nullptr);
-  }
 
-  // Like above, but the AssociatedRemote will schedule response callbacks and
-  // disconnection notifications on |task_runner| instead of the default
-  // SequencedTaskRunner. |task_runner| must run tasks on the same sequence that
-  // owns this AssociatedRemote.
-  PendingAssociatedReceiver<Interface> BindNewEndpointAndPassReceiver(
-      scoped_refptr<base::SequencedTaskRunner> task_runner) WARN_UNUSED_RESULT {
-    DCHECK(!is_bound()) << "AssociatedRemote is already bound";
     ScopedInterfaceEndpointHandle remote_handle;
     ScopedInterfaceEndpointHandle receiver_handle;
     ScopedInterfaceEndpointHandle::CreatePairPendingAssociation(
@@ -176,56 +178,15 @@
     return PendingAssociatedReceiver<Interface>(std::move(receiver_handle));
   }
 
-  // Like BindNewEndpointAndPassReceiver() above, but it creates a dedicated
-  // message pipe. The returned receiver can be bound directly to an
-  // implementation, without being first passed through a message pipe endpoint.
+  // Binds this AssociatedRemote by consuming |pending_remote|.
   //
-  // For testing, where the returned request is bound to e.g. a mock and there
-  // are no other interfaces involved.
-  PendingAssociatedReceiver<Interface> BindNewEndpointAndPassDedicatedReceiver()
-      WARN_UNUSED_RESULT {
-    DCHECK(!is_bound()) << "AssociatedRemote is already bound";
-    MessagePipe pipe;
-    scoped_refptr<internal::MultiplexRouter> router0 =
-        new internal::MultiplexRouter(
-            std::move(pipe.handle0), internal::MultiplexRouter::MULTI_INTERFACE,
-            false, base::SequencedTaskRunnerHandle::Get());
-    scoped_refptr<internal::MultiplexRouter> router1 =
-        new internal::MultiplexRouter(
-            std::move(pipe.handle1), internal::MultiplexRouter::MULTI_INTERFACE,
-            true, base::SequencedTaskRunnerHandle::Get());
-
-    ScopedInterfaceEndpointHandle remote_handle;
-    ScopedInterfaceEndpointHandle receiver_handle;
-    ScopedInterfaceEndpointHandle::CreatePairPendingAssociation(
-        &remote_handle, &receiver_handle);
-    InterfaceId id = router1->AssociateInterface(std::move(remote_handle));
-    remote_handle = router0->CreateLocalEndpointHandle(id);
-
-    Bind(PendingAssociatedRemote<Interface>(std::move(remote_handle), 0),
-         nullptr);
-    return PendingAssociatedReceiver<Interface>(std::move(receiver_handle));
-  }
-
-  // Binds this AssociatedRemote by consuming |pending_remote|, which must be
-  // valid. The AssociatedRemote will schedule any response callbacks or
-  // disconnection notifications on the default SequencedTaskRunner (i.e.
-  // base::SequencedTaskRunnerHandle::Get() at the time of this call). Must only
-  // be called on an unbound AssociatedRemote.
-  void Bind(PendingAssociatedRemote<Interface> pending_remote) {
-    DCHECK(!is_bound()) << "AssociatedRemote is already bound";
-    DCHECK(pending_remote.is_valid());
-    Bind(std::move(pending_remote), nullptr);
-  }
-
-  // Like above, but the AssociatedRemote will schedule response callbacks and
-  // disconnection notifications on |task_runner| instead of the default
-  // SequencedTaskRunner. Must only be called on an unbound AssociatedRemote.
-  // |task_runner| must run tasks on the same sequence that owns this
-  // AssociatedRemote.
+  // Any response callbacks or disconnection notifications will be scheduled to
+  // run on |task_runner|. If |task_runner| is null, defaults ot the current
+  // SequencedTaskRunner.
   void Bind(PendingAssociatedRemote<Interface> pending_remote,
-            scoped_refptr<base::SequencedTaskRunner> task_runner) {
+            scoped_refptr<base::SequencedTaskRunner> task_runner = nullptr) {
     DCHECK(!is_bound()) << "AssociatedRemote is already bound";
+
     if (!pending_remote) {
       reset();
       return;
@@ -243,6 +204,25 @@
     ignore_result(internal_state_.instance());
   }
 
+  // Binds this AssociatedRemote with the returned PendingAssociatedReceiver
+  // using a dedicated message pipe. This allows the entangled
+  // AssociatedReceiver/AssociatedRemote endpoints to be used without ever being
+  // associated with any other mojom interfaces.
+  //
+  // Needless to say, messages sent between the two entangled endpoints will not
+  // be ordered with respect to any other mojom interfaces. This is generally
+  // useful for ignoring calls on an associated remote or for binding associated
+  // endpoints in tests.
+  PendingAssociatedReceiver<Interface> BindNewEndpointAndPassDedicatedReceiver()
+      WARN_UNUSED_RESULT {
+    DCHECK(!is_bound()) << "AssociatedReceiver is already bound";
+
+    PendingAssociatedReceiver<Interface> receiver =
+        BindNewEndpointAndPassReceiver();
+    receiver.EnableUnassociatedUsage();
+    return receiver;
+  }
+
   // Unbinds this AssociatedRemote, rendering it unable to issue further
   // Interface method calls. Returns a PendingAssociatedRemote which may be
   // passed across threads or processes and consumed by another AssociatedRemote
diff --git a/mojo/public/cpp/bindings/pending_associated_receiver.h b/mojo/public/cpp/bindings/pending_associated_receiver.h
index 3569747..5797f2a 100644
--- a/mojo/public/cpp/bindings/pending_associated_receiver.h
+++ b/mojo/public/cpp/bindings/pending_associated_receiver.h
@@ -12,7 +12,9 @@
 #include "base/macros.h"
 #include "build/build_config.h"
 #include "mojo/public/cpp/bindings/associated_interface_request.h"
+#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
+#include "mojo/public/cpp/system/message_pipe.h"
 
 namespace mojo {
 
@@ -85,6 +87,31 @@
     handle_.ResetWithReason(custom_reason, description);
   }
 
+  // Associates this endpoint with a dedicated message pipe. This allows the
+  // entangled AssociatedReceiver/AssociatedRemote endpoints to be used without
+  // ever being associated with any other mojom interfaces.
+  //
+  // Needless to say, messages sent between the two entangled endpoints will not
+  // be ordered with respect to any other mojom interfaces. This is generally
+  // useful for ignoring calls on an associated remote or for binding associated
+  // endpoints in tests.
+  void EnableUnassociatedUsage() {
+    DCHECK(is_valid());
+
+    MessagePipe pipe;
+    scoped_refptr<internal::MultiplexRouter> router0 =
+        new internal::MultiplexRouter(
+            std::move(pipe.handle0), internal::MultiplexRouter::MULTI_INTERFACE,
+            false, base::SequencedTaskRunnerHandle::Get());
+    scoped_refptr<internal::MultiplexRouter> router1 =
+        new internal::MultiplexRouter(
+            std::move(pipe.handle1), internal::MultiplexRouter::MULTI_INTERFACE,
+            true, base::SequencedTaskRunnerHandle::Get());
+
+    InterfaceId id = router1->AssociateInterface(PassHandle());
+    set_handle(router0->CreateLocalEndpointHandle(id));
+  }
+
  private:
   ScopedInterfaceEndpointHandle handle_;
 
diff --git a/mojo/public/cpp/bindings/pending_associated_remote.h b/mojo/public/cpp/bindings/pending_associated_remote.h
index dae0088c..e4022e2 100644
--- a/mojo/public/cpp/bindings/pending_associated_remote.h
+++ b/mojo/public/cpp/bindings/pending_associated_remote.h
@@ -12,8 +12,10 @@
 #include "base/macros.h"
 #include "build/build_config.h"
 #include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
+#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
 #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
+#include "mojo/public/cpp/system/message_pipe.h"
 
 namespace mojo {
 
@@ -90,6 +92,31 @@
     return PendingAssociatedReceiver<Interface>(std::move(receiver_handle));
   }
 
+  // Associates this endpoint with a dedicated message pipe. This allows the
+  // entangled AssociatedReceiver/AssociatedRemote endpoints to be used without
+  // ever being associated with any other mojom interfaces.
+  //
+  // Needless to say, messages sent between the two entangled endpoints will not
+  // be ordered with respect to any other mojom interfaces. This is generally
+  // useful for ignoring calls on an associated remote or for binding associated
+  // endpoints in tests.
+  void EnableUnassociatedUsage() {
+    DCHECK(is_valid());
+
+    MessagePipe pipe;
+    scoped_refptr<internal::MultiplexRouter> router0 =
+        new internal::MultiplexRouter(
+            std::move(pipe.handle0), internal::MultiplexRouter::MULTI_INTERFACE,
+            false, base::SequencedTaskRunnerHandle::Get());
+    scoped_refptr<internal::MultiplexRouter> router1 =
+        new internal::MultiplexRouter(
+            std::move(pipe.handle1), internal::MultiplexRouter::MULTI_INTERFACE,
+            true, base::SequencedTaskRunnerHandle::Get());
+
+    InterfaceId id = router1->AssociateInterface(PassHandle());
+    set_handle(router0->CreateLocalEndpointHandle(id));
+  }
+
  private:
   ScopedInterfaceEndpointHandle handle_;
   uint32_t version_ = 0;
diff --git a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
index 72be186d..97487eb 100644
--- a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
@@ -1108,6 +1108,64 @@
   SetDefaultProcessErrorHandler(base::NullCallback());
 }
 
+TEST_F(AssociatedInterfaceTest, AssociatedReceiverDedicatedPipe) {
+  PendingAssociatedRemote<IntegerSender> pending_remote;
+  PendingAssociatedReceiver<IntegerSender> pending_receiver =
+      pending_remote.InitWithNewEndpointAndPassReceiver();
+  pending_receiver.EnableUnassociatedUsage();
+  IntegerSenderImpl impl(std::move(pending_receiver));
+  AssociatedRemote<IntegerSender> remote(std::move(pending_remote));
+
+  {
+    base::RunLoop run_loop;
+    impl.set_notify_send_method_called(
+        base::BindLambdaForTesting([&](int32_t x) {
+          EXPECT_EQ(88, x);
+          run_loop.Quit();
+        }));
+
+    remote->Send(88);
+    run_loop.Run();
+  }
+
+  {
+    base::RunLoop run_loop;
+    remote->Echo(888, base::BindLambdaForTesting([&](int32_t x) {
+                   EXPECT_EQ(888, x);
+                   run_loop.Quit();
+                 }));
+  }
+}
+
+TEST_F(AssociatedInterfaceTest, AssociatedRemoteDedicatedPipe) {
+  PendingAssociatedRemote<IntegerSender> pending_remote;
+  PendingAssociatedReceiver<IntegerSender> pending_receiver =
+      pending_remote.InitWithNewEndpointAndPassReceiver();
+  IntegerSenderImpl impl(std::move(pending_receiver));
+  pending_remote.EnableUnassociatedUsage();
+  AssociatedRemote<IntegerSender> remote(std::move(pending_remote));
+
+  {
+    base::RunLoop run_loop;
+    impl.set_notify_send_method_called(
+        base::BindLambdaForTesting([&](int32_t x) {
+          EXPECT_EQ(88, x);
+          run_loop.Quit();
+        }));
+
+    remote->Send(88);
+    run_loop.Run();
+  }
+
+  {
+    base::RunLoop run_loop;
+    remote->Echo(888, base::BindLambdaForTesting([&](int32_t x) {
+                   EXPECT_EQ(888, x);
+                   run_loop.Quit();
+                 }));
+  }
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace mojo
diff --git a/net/android/BUILD.gn b/net/android/BUILD.gn
index ff9c6688..f795a71e 100644
--- a/net/android/BUILD.gn
+++ b/net/android/BUILD.gn
@@ -170,6 +170,7 @@
   testonly = true
   sources = [
     "javatests/src/org/chromium/net/AndroidKeyStoreTestUtil.java",
+    "javatests/src/org/chromium/net/AndroidNetworkLibraryTest.java",
     "javatests/src/org/chromium/net/AndroidNetworkLibraryTestUtil.java",
     "javatests/src/org/chromium/net/AndroidProxyConfigServiceTestUtil.java",
     "javatests/src/org/chromium/net/AndroidProxySelectorTest.java",
diff --git a/net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java b/net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java
index f2446e8..596bd92 100644
--- a/net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java
+++ b/net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java
@@ -397,11 +397,12 @@
             return null;
         }
         List<InetAddress> dnsServersList = linkProperties.getDnsServers();
+        String searchDomains = linkProperties.getDomains();
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
             return new DnsStatus(dnsServersList, ApiHelperForP.isPrivateDnsActive(linkProperties),
-                    ApiHelperForP.getPrivateDnsServerName(linkProperties));
+                    ApiHelperForP.getPrivateDnsServerName(linkProperties), searchDomains);
         } else {
-            return new DnsStatus(dnsServersList, false, "");
+            return new DnsStatus(dnsServersList, false, "", searchDomains);
         }
     }
 
diff --git a/net/android/java/src/org/chromium/net/DnsStatus.java b/net/android/java/src/org/chromium/net/DnsStatus.java
index 758ac8d..1861191 100644
--- a/net/android/java/src/org/chromium/net/DnsStatus.java
+++ b/net/android/java/src/org/chromium/net/DnsStatus.java
@@ -21,11 +21,14 @@
 
     private final String mPrivateDnsServerName;
 
-    public DnsStatus(
-            List<InetAddress> dnsServers, boolean privateDnsActive, String privateDnsServerName) {
+    private final String mSearchDomains;
+
+    public DnsStatus(List<InetAddress> dnsServers, boolean privateDnsActive,
+            String privateDnsServerName, String searchDomains) {
         mDnsServers = dnsServers;
         mPrivateDnsActive = privateDnsActive;
         mPrivateDnsServerName = (privateDnsServerName != null) ? privateDnsServerName : "";
+        mSearchDomains = (searchDomains != null) ? searchDomains : "";
     }
 
     @CalledByNative
@@ -46,4 +49,9 @@
     public String getPrivateDnsServerName() {
         return mPrivateDnsServerName;
     }
+
+    @CalledByNative
+    public String getSearchDomains() {
+        return mSearchDomains;
+    }
 }
diff --git a/net/android/javatests/src/org/chromium/net/AndroidNetworkLibraryTest.java b/net/android/javatests/src/org/chromium/net/AndroidNetworkLibraryTest.java
new file mode 100644
index 0000000..b4d06a4
--- /dev/null
+++ b/net/android/javatests/src/org/chromium/net/AndroidNetworkLibraryTest.java
@@ -0,0 +1,42 @@
+// 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.net;
+
+import android.os.Build;
+
+import androidx.test.filters.MediumTest;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.BaseJUnit4ClassRunner;
+import org.chromium.base.test.util.Batch;
+import org.chromium.base.test.util.MinAndroidSdkLevel;
+
+@RunWith(BaseJUnit4ClassRunner.class)
+@Batch(Batch.UNIT_TESTS)
+public class AndroidNetworkLibraryTest {
+    @Test
+    @MediumTest
+    @MinAndroidSdkLevel(Build.VERSION_CODES.M)
+    public void testGetDnsStatus_searchDomains() {
+        DnsStatus dnsStatus = AndroidNetworkLibrary.getDnsStatus(/*network=*/null);
+        if (dnsStatus == null) {
+            return;
+        }
+
+        String searchDomains = dnsStatus.getSearchDomains();
+        if (searchDomains == null || searchDomains.isEmpty()) {
+            return;
+        }
+
+        // Expect a comma-separated list of unknown length.
+        String[] domains = searchDomains.split(",");
+        for (String domain : domains) {
+            Assert.assertNotEquals("", domain);
+        }
+    }
+}
\ No newline at end of file
diff --git a/net/android/network_library.cc b/net/android/network_library.cc
index c7d06c3f2..fa302cd 100644
--- a/net/android/network_library.cc
+++ b/net/android/network_library.cc
@@ -4,11 +4,16 @@
 
 #include "net/android/network_library.h"
 
+#include <string>
+#include <vector>
+
+#include "base/android/build_info.h"
 #include "base/android/jni_android.h"
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/android/scoped_java_ref.h"
 #include "base/check_op.h"
+#include "base/strings/string_split.h"
 #include "net/dns/public/dns_protocol.h"
 #include "net/net_jni_headers/AndroidNetworkLibrary_jni.h"
 #include "net/net_jni_headers/DnsStatus_jni.h"
@@ -132,7 +137,11 @@
 
 bool GetDnsServers(std::vector<IPEndPoint>* dns_servers,
                    bool* dns_over_tls_active,
-                   std::string* dns_over_tls_hostname) {
+                   std::string* dns_over_tls_hostname,
+                   std::vector<std::string>* search_suffixes) {
+  DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(),
+            base::android::SDK_VERSION_MARSHMALLOW);
+
   JNIEnv* env = AttachCurrentThread();
   // Get the DNS status for the active network.
   ScopedJavaLocalRef<jobject> result =
@@ -154,6 +163,12 @@
   *dns_over_tls_hostname = base::android::ConvertJavaStringToUTF8(
       Java_DnsStatus_getPrivateDnsServerName(env, result));
 
+  std::string search_suffixes_str = base::android::ConvertJavaStringToUTF8(
+      Java_DnsStatus_getSearchDomains(env, result));
+  *search_suffixes =
+      base::SplitString(search_suffixes_str, ",", base::TRIM_WHITESPACE,
+                        base::SPLIT_WANT_NONEMPTY);
+
   return !dns_servers->empty();
 }
 
diff --git a/net/android/network_library.h b/net/android/network_library.h
index 1a9e8935..f2ae1c0a 100644
--- a/net/android/network_library.h
+++ b/net/android/network_library.h
@@ -93,13 +93,16 @@
 // |dns_over_tls_active| is true.
 // Only callable on Marshmallow and newer releases.
 // Returns false when a valid server config could not be read.
-NET_EXPORT_PRIVATE bool GetDnsServers(std::vector<IPEndPoint>* dns_servers,
-                                      bool* dns_over_tls_active,
-                                      std::string* dns_over_tls_hostname);
+NET_EXPORT_PRIVATE bool GetDnsServers(
+    std::vector<IPEndPoint>* dns_servers,
+    bool* dns_over_tls_active,
+    std::string* dns_over_tls_hostname,
+    std::vector<std::string>* search_suffixes);
 using DnsServerGetter =
     base::RepeatingCallback<bool(std::vector<IPEndPoint>* dns_servers,
                                  bool* dns_over_tls_active,
-                                 std::string* dns_over_tls_hostname)>;
+                                 std::string* dns_over_tls_hostname,
+                                 std::vector<std::string>* search_suffixes)>;
 
 // Reports to the framework that the current default network appears to have
 // connectivity issues. This may serve as a signal for the OS to consider
diff --git a/net/android/network_library_unittest.cc b/net/android/network_library_unittest.cc
index bc0e536f..713364d 100644
--- a/net/android/network_library_unittest.cc
+++ b/net/android/network_library_unittest.cc
@@ -4,6 +4,11 @@
 
 #include "net/android/network_library.h"
 
+#include <string>
+#include <vector>
+
+#include "base/android/build_info.h"
+#include "net/base/ip_endpoint.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace net {
@@ -22,6 +27,27 @@
   EXPECT_GE(4, signal_strength.value());
 }
 
+TEST(NetworkLibraryTest, GetDnsSearchDomains) {
+  if (base::android::BuildInfo::GetInstance()->sdk_int() <
+      base::android::SDK_VERSION_MARSHMALLOW) {
+    GTEST_SKIP() << "Cannot call or test GetDnsServers() in pre-M.";
+  }
+
+  std::vector<IPEndPoint> dns_servers;
+  bool dns_over_tls_active;
+  std::string dns_over_tls_hostname;
+  std::vector<std::string> search_suffixes;
+
+  if (!GetDnsServers(&dns_servers, &dns_over_tls_active, &dns_over_tls_hostname,
+                     &search_suffixes)) {
+    return;
+  }
+
+  for (std::string suffix : search_suffixes) {
+    EXPECT_FALSE(suffix.empty());
+  }
+}
+
 }  // namespace android
 
 }  // namespace net
diff --git a/net/base/port_util.cc b/net/base/port_util.cc
index cfbebfc..b5614fe 100644
--- a/net/base/port_util.cc
+++ b/net/base/port_util.cc
@@ -18,7 +18,7 @@
 namespace {
 
 // The general list of blocked ports. Will be blocked unless a specific
-// protocol overrides it. (Ex: ftp can use ports 20 and 21)
+// protocol overrides it. (Ex: ftp can use port 21)
 const int kRestrictedPorts[] = {
     1,     // tcpmux
     7,     // echo
@@ -98,11 +98,6 @@
     6697,  // IRC + TLS
 };
 
-// FTP overrides the following restricted port.
-const int kAllowedFtpPorts[] = {
-    21,  // ftp data
-};
-
 base::LazyInstance<std::multiset<int>>::Leaky g_explicitly_allowed_ports =
     LAZY_INSTANCE_INITIALIZER;
 
@@ -125,12 +120,9 @@
   if (g_explicitly_allowed_ports.Get().count(port) > 0)
     return true;
 
-  // FTP requests have an extra set of allowed schemes.
-  if (base::LowerCaseEqualsASCII(url_scheme, url::kFtpScheme)) {
-    for (int allowed_ftp_port : kAllowedFtpPorts) {
-      if (allowed_ftp_port == port)
-        return true;
-    }
+  // FTP requests are permitted to use port 21.
+  if (base::LowerCaseEqualsASCII(url_scheme, url::kFtpScheme) && port == 21) {
+    return true;
   }
 
   // Finally check against the generic list of restricted ports for all
diff --git a/net/base/schemeful_site_fuzzer.cc b/net/base/schemeful_site_fuzzer.cc
index eff99d6..4d62f2c 100644
--- a/net/base/schemeful_site_fuzzer.cc
+++ b/net/base/schemeful_site_fuzzer.cc
@@ -36,7 +36,5 @@
     if (scheme == "http" || scheme == "https") {
       CHECK_NE(site.registrable_domain_or_host_for_testing().front(), '.');
     }
-  } else {
-    CHECK(!site.has_registrable_domain_or_host());
   }
 }
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc
index 55245f3..9b1980f 100644
--- a/net/cookies/cookie_monster_unittest.cc
+++ b/net/cookies/cookie_monster_unittest.cc
@@ -66,11 +66,20 @@
 
 namespace {
 
+using testing::ElementsAre;
+
 // False means 'less than or equal', so we test both ways for full equal.
 MATCHER_P(CookieEquals, expected, "") {
   return !(arg.FullCompare(expected) || expected.FullCompare(arg));
 }
 
+MATCHER_P2(MatchesCookieNameDomain, name, domain, "") {
+  return testing::ExplainMatchResult(
+      testing::AllOf(testing::Property(&net::CanonicalCookie::Name, name),
+                     testing::Property(&net::CanonicalCookie::Domain, domain)),
+      arg, result_listener);
+}
+
 const char kTopLevelDomainPlus1[] = "http://www.harvard.edu";
 const char kTopLevelDomainPlus2[] = "http://www.math.harvard.edu";
 const char kTopLevelDomainPlus2Secure[] = "https://www.math.harvard.edu";
@@ -1550,55 +1559,45 @@
                                  http_www_bar_.Format("G=H; domain=.%D"),
                                  options));
 
+  EXPECT_TRUE(CreateAndSetCookie(
+      cm.get(), https_www_foo_.url(),
+      https_www_foo_.Format("I=J; domain=.%D; secure; sameparty"), options));
+
+  base::HistogramTester histogram_tester;
+
   const Time last_access_date(GetFirstCookieAccessDate(cm.get()));
 
   base::PlatformThread::Sleep(kAccessDelay);
 
   // Check cookies for url.
-  CookieList cookies = GetAllCookiesForURL(cm.get(), http_www_foo_.url());
-  auto it = cookies.begin();
-
-  ASSERT_TRUE(it != cookies.end());
-  EXPECT_EQ(http_www_foo_.host(), it->Domain());
-  EXPECT_EQ("A", it->Name());
-
-  ASSERT_TRUE(++it != cookies.end());
-  EXPECT_EQ(http_www_foo_.Format(".%D"), it->Domain());
-  EXPECT_EQ("C", it->Name());
-
-  ASSERT_TRUE(++it == cookies.end());
+  EXPECT_THAT(
+      GetAllCookiesForURL(cm.get(), http_www_foo_.url()),
+      ElementsAre(MatchesCookieNameDomain("A", http_www_foo_.host()),
+                  MatchesCookieNameDomain("C", http_www_foo_.Format(".%D"))));
 
   // Check cookies for url excluding http-only cookies.
   CookieOptions exclude_httponly = options;
   exclude_httponly.set_exclude_httponly();
 
-  cookies = GetAllCookiesForURLWithOptions(cm.get(), http_www_foo_.url(),
-                                           exclude_httponly);
-  it = cookies.begin();
-
-  ASSERT_TRUE(it != cookies.end());
-  EXPECT_EQ(http_www_foo_.Format(".%D"), it->Domain());
-  EXPECT_EQ("C", it->Name());
-
-  ASSERT_TRUE(++it == cookies.end());
+  EXPECT_THAT(
+      GetAllCookiesForURLWithOptions(cm.get(), http_www_foo_.url(),
+                                     exclude_httponly),
+      ElementsAre(MatchesCookieNameDomain("C", http_www_foo_.Format(".%D"))));
 
   // Test secure cookies.
-  cookies = GetAllCookiesForURL(cm.get(), https_www_foo_.url());
-  it = cookies.begin();
+  EXPECT_THAT(
+      GetAllCookiesForURL(cm.get(), https_www_foo_.url()),
+      ElementsAre(MatchesCookieNameDomain("A", http_www_foo_.host()),
+                  MatchesCookieNameDomain("C", http_www_foo_.Format(".%D")),
+                  MatchesCookieNameDomain("E", http_www_foo_.Format(".%D")),
+                  MatchesCookieNameDomain("I", http_www_foo_.Format(".%D"))));
 
-  ASSERT_TRUE(it != cookies.end());
-  EXPECT_EQ(http_www_foo_.host(), it->Domain());
-  EXPECT_EQ("A", it->Name());
-
-  ASSERT_TRUE(++it != cookies.end());
-  EXPECT_EQ(http_www_foo_.Format(".%D"), it->Domain());
-  EXPECT_EQ("C", it->Name());
-
-  ASSERT_TRUE(++it != cookies.end());
-  EXPECT_EQ(http_www_foo_.Format(".%D"), it->Domain());
-  EXPECT_EQ("E", it->Name());
-
-  ASSERT_TRUE(++it == cookies.end());
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples("Cookie.SamePartyReadIncluded.IsHTTP"),
+      testing::ElementsAre(base::Bucket(1 /* min */, 1 /* samples */)));
+  EXPECT_THAT(histogram_tester.GetAllSamples(
+                  "Cookie.SamePartyReadIncluded.PartyContextSize"),
+              testing::ElementsAre(base::Bucket(0 /* min */, 1 /* samples */)));
 
   // Reading after a short wait should not update the access date.
   EXPECT_EQ(last_access_date, GetFirstCookieAccessDate(cm.get()));
@@ -3272,6 +3271,8 @@
   GURL https_foo_url("https://www.foo.com/foo");
   GURL http_foo_url("http://www.foo.com/foo");
 
+  base::HistogramTester histogram_tester;
+
   // A non-SameParty cookie can be created from either a URL with a secure or
   // insecure scheme.
   EXPECT_TRUE(
@@ -3307,6 +3308,12 @@
   EXPECT_TRUE(CreateAndSetCookieReturnStatus(&cm, https_url,
                                              "A=C; Secure; path=/; SameParty")
                   .IsInclude());
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples("Cookie.SamePartySetIncluded.IsHTTP"),
+      testing::ElementsAre(base::Bucket(0 /* min */, 3 /* samples */)));
+  EXPECT_THAT(histogram_tester.GetAllSamples(
+                  "Cookie.SamePartySetIncluded.PartyContextSize"),
+              testing::ElementsAre(base::Bucket(0 /* min */, 3 /* samples */)));
 }
 
 // Tests the behavior of "Leave Secure Cookies Alone" in
diff --git a/net/dns/dns_config_service_android.cc b/net/dns/dns_config_service_android.cc
index 1896a88..25afa68b 100644
--- a/net/dns/dns_config_service_android.cc
+++ b/net/dns/dns_config_service_android.cc
@@ -101,9 +101,9 @@
 
     if (base::android::BuildInfo::GetInstance()->sdk_int() >=
         base::android::SDK_VERSION_MARSHMALLOW) {
-      if (!dns_server_getter_.Run(&dns_config_->nameservers,
-                                  &dns_config_->dns_over_tls_active,
-                                  &dns_config_->dns_over_tls_hostname)) {
+      if (!dns_server_getter_.Run(
+              &dns_config_->nameservers, &dns_config_->dns_over_tls_active,
+              &dns_config_->dns_over_tls_hostname, &dns_config_->search)) {
         dns_config_.reset();
       }
       return;
diff --git a/net/dns/dns_config_service_android_unittest.cc b/net/dns/dns_config_service_android_unittest.cc
index 59ccfa1..553e58b 100644
--- a/net/dns/dns_config_service_android_unittest.cc
+++ b/net/dns/dns_config_service_android_unittest.cc
@@ -60,6 +60,10 @@
     dns_over_tls_hostname_ = std::move(dns_over_tls_hostname);
   }
 
+  void set_search_suffixes(std::vector<std::string> search_suffixes) {
+    search_suffixes_ = std::move(search_suffixes);
+  }
+
   android::DnsServerGetter ConstructGetter() {
     return base::BindRepeating(&MockDnsServerGetter::GetDnsServers, this);
   }
@@ -70,11 +74,13 @@
 
   bool GetDnsServers(std::vector<IPEndPoint>* dns_servers,
                      bool* dns_over_tls_active,
-                     std::string* dns_over_tls_hostname) {
+                     std::string* dns_over_tls_hostname,
+                     std::vector<std::string>* search_suffixes) {
     if (retval_) {
       *dns_servers = dns_servers_;
       *dns_over_tls_active = dns_over_tls_active_;
       *dns_over_tls_hostname = dns_over_tls_hostname_;
+      *search_suffixes = search_suffixes_;
     }
     return retval_;
   }
@@ -83,6 +89,7 @@
   std::vector<IPEndPoint> dns_servers_;
   bool dns_over_tls_active_ = false;
   std::string dns_over_tls_hostname_;
+  std::vector<std::string> search_suffixes_;
 };
 
 class DnsConfigServiceAndroidTest : public testing::Test,
@@ -234,6 +241,37 @@
   }
 }
 
+TEST_F(DnsConfigServiceAndroidTest, ReadsSearchSuffixes) {
+  SKIP_ANDROID_VERSIONS_BEFORE_M();
+
+  const std::vector<std::string> kSuffixes{"name1.test", "name2.test"};
+
+  mock_dns_server_getter_->set_retval(true);
+  mock_dns_server_getter_->set_dns_servers({kNameserver1});
+  mock_dns_server_getter_->set_search_suffixes(kSuffixes);
+
+  service_->ReadConfig(base::BindRepeating(
+      &DnsConfigServiceAndroidTest::OnConfigChanged, base::Unretained(this)));
+  FastForwardBy(DnsConfigServiceAndroid::kConfigChangeDelay);
+  RunUntilIdle();
+  ASSERT_TRUE(seen_config_);
+  EXPECT_EQ(real_config_.search, kSuffixes);
+}
+
+TEST_F(DnsConfigServiceAndroidTest, ReadsEmptySearchSuffixes) {
+  SKIP_ANDROID_VERSIONS_BEFORE_M();
+
+  mock_dns_server_getter_->set_retval(true);
+  mock_dns_server_getter_->set_dns_servers({kNameserver1});
+
+  service_->ReadConfig(base::BindRepeating(
+      &DnsConfigServiceAndroidTest::OnConfigChanged, base::Unretained(this)));
+  FastForwardBy(DnsConfigServiceAndroid::kConfigChangeDelay);
+  RunUntilIdle();
+  ASSERT_TRUE(seen_config_);
+  EXPECT_TRUE(real_config_.search.empty());
+}
+
 }  // namespace
 }  // namespace internal
 }  // namespace net
diff --git a/pdf/accessibility.cc b/pdf/accessibility.cc
index 03bb905..ddcc518c 100644
--- a/pdf/accessibility.cc
+++ b/pdf/accessibility.cc
@@ -11,8 +11,6 @@
 #include "base/numerics/safe_math.h"
 #include "pdf/accessibility_structs.h"
 #include "pdf/pdf_engine.h"
-#include "pdf/ppapi_migration/geometry_conversions.h"
-#include "ppapi/cpp/rect.h"
 #include "ui/gfx/geometry/rect_f.h"
 
 namespace chrome_pdf {
@@ -162,79 +160,24 @@
   return text_field_infos;
 }
 
-std::vector<pp::PDF::PrivateAccessibilityTextFieldInfo>
-ToPrivateAccessibilityTextFieldInfo(
-    const std::vector<AccessibilityTextFieldInfo>& text_field_infos) {
-  std::vector<pp::PDF::PrivateAccessibilityTextFieldInfo> pp_text_field_infos;
-  pp_text_field_infos.reserve(text_field_infos.size());
-  for (const auto& text_field_info : text_field_infos) {
-    pp_text_field_infos.push_back(
-        {text_field_info.name, text_field_info.value,
-         text_field_info.is_read_only, text_field_info.is_required,
-         text_field_info.is_password, text_field_info.index_in_page,
-         text_field_info.text_run_index,
-         PPFloatRectFromRectF(text_field_info.bounds)});
-  }
-  return pp_text_field_infos;
-}
-
-void GetAccessibilityFormFieldInfo(
+AccessibilityFormFieldInfo GetAccessibilityFormFieldInfo(
     PDFEngine* engine,
     int32_t page_index,
-    uint32_t text_run_count,
-    pp::PDF::PrivateAccessibilityFormFieldInfo* form_fields) {
-  form_fields->text_fields = ToPrivateAccessibilityTextFieldInfo(
-      GetAccessibilityTextFieldInfo(engine, page_index, text_run_count));
-}
-
-std::vector<pp::PDF::PrivateAccessibilityLinkInfo>
-ToPrivateAccessibilityLinkInfo(
-    const std::vector<AccessibilityLinkInfo>& link_infos) {
-  std::vector<pp::PDF::PrivateAccessibilityLinkInfo> pp_link_infos;
-  pp_link_infos.reserve(link_infos.size());
-  for (const auto& link_info : link_infos) {
-    pp_link_infos.push_back(
-        {link_info.url, link_info.index_in_page, link_info.text_range.index,
-         link_info.text_range.count, PPFloatRectFromRectF(link_info.bounds)});
-  }
-  return pp_link_infos;
-}
-
-std::vector<pp::PDF::PrivateAccessibilityImageInfo>
-ToPrivateAccessibilityImageInfo(
-    const std::vector<AccessibilityImageInfo>& image_infos) {
-  std::vector<pp::PDF::PrivateAccessibilityImageInfo> pp_image_infos;
-  pp_image_infos.reserve(image_infos.size());
-  for (const auto& image_info : image_infos) {
-    pp_image_infos.push_back({image_info.alt_text, image_info.text_run_index,
-                              PPFloatRectFromRectF(image_info.bounds)});
-  }
-  return pp_image_infos;
-}
-
-std::vector<pp::PDF::PrivateAccessibilityHighlightInfo>
-ToPrivateAccessibilityHighlightInfo(
-    const std::vector<AccessibilityHighlightInfo>& highlight_infos) {
-  std::vector<pp::PDF::PrivateAccessibilityHighlightInfo> pp_highlight_infos;
-  pp_highlight_infos.reserve(highlight_infos.size());
-  for (const auto& highlight_info : highlight_infos) {
-    pp_highlight_infos.push_back(
-        {highlight_info.note_text, highlight_info.index_in_page,
-         highlight_info.text_range.index, highlight_info.text_range.count,
-         PPFloatRectFromRectF(highlight_info.bounds), highlight_info.color});
-  }
-  return pp_highlight_infos;
+    uint32_t text_run_count) {
+  AccessibilityFormFieldInfo form_field_info;
+  form_field_info.text_fields =
+      GetAccessibilityTextFieldInfo(engine, page_index, text_run_count);
+  return form_field_info;
 }
 
 }  // namespace
 
-bool GetAccessibilityInfo(
-    PDFEngine* engine,
-    int32_t page_index,
-    AccessibilityPageInfo& page_info,
-    std::vector<AccessibilityTextRunInfo>& text_runs,
-    std::vector<AccessibilityCharInfo>& chars,
-    pp::PDF::PrivateAccessibilityPageObjects* page_objects) {
+bool GetAccessibilityInfo(PDFEngine* engine,
+                          int32_t page_index,
+                          AccessibilityPageInfo& page_info,
+                          std::vector<AccessibilityTextRunInfo>& text_runs,
+                          std::vector<AccessibilityCharInfo>& chars,
+                          AccessibilityPageObjects& page_objects) {
   int page_count = engine->GetNumberOfPages();
   if (page_index < 0 || page_index >= page_count)
     return false;
@@ -308,14 +251,13 @@
   }
 
   page_info.text_run_count = text_runs.size();
-  page_objects->links = ToPrivateAccessibilityLinkInfo(
-      GetAccessibilityLinkInfo(engine, page_index, text_runs));
-  page_objects->images = ToPrivateAccessibilityImageInfo(
-      GetAccessibilityImageInfo(engine, page_index, page_info.text_run_count));
-  page_objects->highlights = ToPrivateAccessibilityHighlightInfo(
-      GetAccessibilityHighlightInfo(engine, page_index, text_runs));
-  GetAccessibilityFormFieldInfo(engine, page_index, page_info.text_run_count,
-                                &page_objects->form_fields);
+  page_objects.links = GetAccessibilityLinkInfo(engine, page_index, text_runs);
+  page_objects.images =
+      GetAccessibilityImageInfo(engine, page_index, page_info.text_run_count);
+  page_objects.highlights =
+      GetAccessibilityHighlightInfo(engine, page_index, text_runs);
+  page_objects.form_fields = GetAccessibilityFormFieldInfo(
+      engine, page_index, page_info.text_run_count);
   return true;
 }
 
diff --git a/pdf/accessibility.h b/pdf/accessibility.h
index 5d21cd6..52c6ffc 100644
--- a/pdf/accessibility.h
+++ b/pdf/accessibility.h
@@ -9,26 +9,24 @@
 
 #include <vector>
 
-#include "ppapi/cpp/private/pdf.h"
-
 namespace chrome_pdf {
 
 class PDFEngine;
 struct AccessibilityCharInfo;
 struct AccessibilityPageInfo;
+struct AccessibilityPageObjects;
 struct AccessibilityTextRunInfo;
 
 // Retrieve |page_info|, |text_runs|, |chars|, and |page_objects| from
 // |engine| for the page at 0-indexed |page_index|. Returns true on success with
 // all out parameters filled, or false on failure with all out parameters
 // untouched.
-bool GetAccessibilityInfo(
-    PDFEngine* engine,
-    int32_t page_index,
-    AccessibilityPageInfo& page_info,
-    std::vector<AccessibilityTextRunInfo>& text_runs,
-    std::vector<AccessibilityCharInfo>& chars,
-    pp::PDF::PrivateAccessibilityPageObjects* page_objects);
+bool GetAccessibilityInfo(PDFEngine* engine,
+                          int32_t page_index,
+                          AccessibilityPageInfo& page_info,
+                          std::vector<AccessibilityTextRunInfo>& text_runs,
+                          std::vector<AccessibilityCharInfo>& chars,
+                          AccessibilityPageObjects& page_objects);
 
 }  // namespace chrome_pdf
 
diff --git a/pdf/accessibility_structs.cc b/pdf/accessibility_structs.cc
index e2f8d12..d074104 100644
--- a/pdf/accessibility_structs.cc
+++ b/pdf/accessibility_structs.cc
@@ -144,4 +144,64 @@
 
 AccessibilityChoiceFieldInfo::~AccessibilityChoiceFieldInfo() = default;
 
+AccessibilityButtonInfo::AccessibilityButtonInfo() = default;
+
+AccessibilityButtonInfo::AccessibilityButtonInfo(const std::string& name,
+                                                 const std::string& value,
+                                                 ButtonType type,
+                                                 bool is_read_only,
+                                                 bool is_checked,
+                                                 uint32_t control_count,
+                                                 uint32_t control_index,
+                                                 uint32_t index_in_page,
+                                                 uint32_t text_run_index,
+                                                 const gfx::RectF& bounds)
+    : name(name),
+      value(value),
+      type(type),
+      is_read_only(is_read_only),
+      is_checked(is_checked),
+      control_count(control_count),
+      control_index(control_index),
+      index_in_page(index_in_page),
+      text_run_index(text_run_index),
+      bounds(bounds) {}
+
+AccessibilityButtonInfo::AccessibilityButtonInfo(
+    const AccessibilityButtonInfo& other) = default;
+
+AccessibilityButtonInfo::~AccessibilityButtonInfo() = default;
+
+AccessibilityFormFieldInfo::AccessibilityFormFieldInfo() = default;
+
+AccessibilityFormFieldInfo::AccessibilityFormFieldInfo(
+    const std::vector<AccessibilityTextFieldInfo>& text_fields,
+    const std::vector<AccessibilityChoiceFieldInfo>& choice_fields,
+    const std::vector<AccessibilityButtonInfo>& buttons)
+    : text_fields(text_fields),
+      choice_fields(choice_fields),
+      buttons(buttons) {}
+
+AccessibilityFormFieldInfo::AccessibilityFormFieldInfo(
+    const AccessibilityFormFieldInfo& other) = default;
+
+AccessibilityFormFieldInfo::~AccessibilityFormFieldInfo() = default;
+
+AccessibilityPageObjects::AccessibilityPageObjects() = default;
+
+AccessibilityPageObjects::AccessibilityPageObjects(
+    const std::vector<AccessibilityLinkInfo>& links,
+    const std::vector<AccessibilityImageInfo>& images,
+    const std::vector<AccessibilityHighlightInfo>& highlights,
+    const AccessibilityFormFieldInfo& form_fields)
+    : links(links),
+      images(images),
+      highlights(highlights),
+      form_fields(form_fields) {}
+
+AccessibilityPageObjects::AccessibilityPageObjects(
+    const AccessibilityPageObjects& other) = default;
+
+AccessibilityPageObjects::~AccessibilityPageObjects() = default;
+
 }  // namespace chrome_pdf
diff --git a/pdf/accessibility_structs.h b/pdf/accessibility_structs.h
index 2d747a75..4a375498 100644
--- a/pdf/accessibility_structs.h
+++ b/pdf/accessibility_structs.h
@@ -252,6 +252,91 @@
   gfx::RectF bounds;
 };
 
+// TODO(crbug.com/702993): Remove next line comment after PDF migrates away
+// from Pepper.
+// Explicitly set all enum values to match enum values in PP_PrivateButtonType.
+enum class ButtonType {
+  kPushButton = 1,
+  kCheckBox = 2,
+  kRadioButton = 3,
+  kMaxValue = kRadioButton,
+};
+
+struct AccessibilityButtonInfo {
+  AccessibilityButtonInfo();
+  AccessibilityButtonInfo(const std::string& name,
+                          const std::string& value,
+                          ButtonType type,
+                          bool is_read_only,
+                          bool is_checked,
+                          uint32_t control_count,
+                          uint32_t control_index,
+                          uint32_t index_in_page,
+                          uint32_t text_run_index,
+                          const gfx::RectF& bounds);
+  AccessibilityButtonInfo(const AccessibilityButtonInfo& other);
+  ~AccessibilityButtonInfo();
+
+  // Represents the name property of button, if present.
+  std::string name;
+  // Represents the value property of button, if present.
+  std::string value;
+  // Represents the button type.
+  ButtonType type;
+  // Represents if the button is non-editable.
+  bool is_read_only = false;
+  // Represents if the radio button or check box is checked or not.
+  bool is_checked = false;
+  // Represents count of controls in the control group. A group of interactive
+  // form annotations is collectively called a form control group. Here, an
+  // interactive form annotation, should be either a radio button or a
+  // checkbox. Value of |control_count| is >= 1.
+  uint32_t control_count = 0;
+  // Represents index of the control in the control group. A group of
+  // interactive form annotations is collectively called a form control group.
+  // Here, an interactive form annotation, should be either a radio button or
+  // a checkbox. Value of |control_index| should always be less than
+  // |control_count|.
+  uint32_t control_index = 0;
+  // Index of this button in the collection of buttons in the page.
+  uint32_t index_in_page = 0;
+  // We anchor the button to a text run index, this denotes the text run
+  // before which the button should be inserted in the accessibility tree.
+  uint32_t text_run_index = 0;
+  // Bounding box of the button.
+  gfx::RectF bounds;
+};
+
+struct AccessibilityFormFieldInfo {
+  AccessibilityFormFieldInfo();
+  AccessibilityFormFieldInfo(
+      const std::vector<AccessibilityTextFieldInfo>& text_fields,
+      const std::vector<AccessibilityChoiceFieldInfo>& choice_fields,
+      const std::vector<AccessibilityButtonInfo>& buttons);
+  AccessibilityFormFieldInfo(const AccessibilityFormFieldInfo& other);
+  ~AccessibilityFormFieldInfo();
+
+  std::vector<AccessibilityTextFieldInfo> text_fields;
+  std::vector<AccessibilityChoiceFieldInfo> choice_fields;
+  std::vector<AccessibilityButtonInfo> buttons;
+};
+
+struct AccessibilityPageObjects {
+  AccessibilityPageObjects();
+  AccessibilityPageObjects(
+      const std::vector<AccessibilityLinkInfo>& links,
+      const std::vector<AccessibilityImageInfo>& images,
+      const std::vector<AccessibilityHighlightInfo>& highlights,
+      const AccessibilityFormFieldInfo& form_fields);
+  AccessibilityPageObjects(const AccessibilityPageObjects& other);
+  ~AccessibilityPageObjects();
+
+  std::vector<AccessibilityLinkInfo> links;
+  std::vector<AccessibilityImageInfo> images;
+  std::vector<AccessibilityHighlightInfo> highlights;
+  AccessibilityFormFieldInfo form_fields;
+};
+
 }  // namespace chrome_pdf
 
 #endif  // PDF_ACCESSIBILITY_STRUCTS_H_
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc
index 7a3acfb..b0e11e2 100644
--- a/pdf/out_of_process_instance.cc
+++ b/pdf/out_of_process_instance.cc
@@ -460,8 +460,7 @@
   return size > 0 && size <= kMaximumSavedFileSize;
 }
 
-PP_PrivateAccessibilityPageInfo
-PrivateAccessibilityPageInfoFromAccessibilityPageInfo(
+PP_PrivateAccessibilityPageInfo ToPrivateAccessibilityPageInfo(
     const AccessibilityPageInfo& page_info) {
   PP_PrivateAccessibilityPageInfo pp_page_info;
   pp_page_info.page_index = page_info.page_index;
@@ -471,8 +470,7 @@
   return pp_page_info;
 }
 
-std::vector<PP_PrivateAccessibilityCharInfo>
-PrivateAccessibilityCharInfoFromAccessibilityCharInfo(
+std::vector<PP_PrivateAccessibilityCharInfo> ToPrivateAccessibilityCharInfo(
     const std::vector<AccessibilityCharInfo>& chars) {
   std::vector<PP_PrivateAccessibilityCharInfo> pp_chars;
   pp_chars.reserve(chars.size());
@@ -481,8 +479,7 @@
   return pp_chars;
 }
 
-pp::PDF::PrivateAccessibilityTextStyleInfo
-PrivateAccessibilityTextStyleInfoFromAccessibilityTextStyleInfo(
+pp::PDF::PrivateAccessibilityTextStyleInfo ToPrivateAccessibilityTextStyleInfo(
     const AccessibilityTextStyleInfo& style) {
   pp::PDF::PrivateAccessibilityTextStyleInfo pp_style;
   pp_style.font_name = style.font_name;
@@ -497,7 +494,7 @@
 }
 
 std::vector<pp::PDF::PrivateAccessibilityTextRunInfo>
-PrivateAccessibilityCharInfoFromAccessibilityTextRunInfo(
+ToPrivateAccessibilityCharInfo(
     const std::vector<AccessibilityTextRunInfo>& text_runs) {
   std::vector<pp::PDF::PrivateAccessibilityTextRunInfo> pp_text_runs;
   pp_text_runs.reserve(text_runs.size());
@@ -505,13 +502,84 @@
     pp::PDF::PrivateAccessibilityTextRunInfo pp_text_run = {
         text_run.len, PPFloatRectFromRectF(text_run.bounds),
         static_cast<PP_PrivateDirection>(text_run.direction),
-        PrivateAccessibilityTextStyleInfoFromAccessibilityTextStyleInfo(
-            text_run.style)};
+        ToPrivateAccessibilityTextStyleInfo(text_run.style)};
     pp_text_runs.push_back(std::move(pp_text_run));
   }
   return pp_text_runs;
 }
 
+pp::PDF::PrivateAccessibilityPageObjects ToPrivateAccessibilityPageObjects(
+    const AccessibilityPageObjects& page_objects) {
+  pp::PDF::PrivateAccessibilityPageObjects pp_page_objects;
+
+  pp_page_objects.links.reserve(page_objects.links.size());
+  for (const auto& link_info : page_objects.links) {
+    pp_page_objects.links.push_back(
+        {link_info.url, link_info.index_in_page, link_info.text_range.index,
+         link_info.text_range.count, PPFloatRectFromRectF(link_info.bounds)});
+  }
+
+  pp_page_objects.images.reserve(page_objects.images.size());
+  for (const auto& image_info : page_objects.images) {
+    pp_page_objects.images.push_back({image_info.alt_text,
+                                      image_info.text_run_index,
+                                      PPFloatRectFromRectF(image_info.bounds)});
+  }
+
+  pp_page_objects.highlights.reserve(page_objects.highlights.size());
+  for (const auto& highlight_info : page_objects.highlights) {
+    pp_page_objects.highlights.push_back(
+        {highlight_info.note_text, highlight_info.index_in_page,
+         highlight_info.text_range.index, highlight_info.text_range.count,
+         PPFloatRectFromRectF(highlight_info.bounds), highlight_info.color});
+  }
+
+  pp_page_objects.form_fields.text_fields.reserve(
+      page_objects.form_fields.text_fields.size());
+  for (const auto& text_field_info : page_objects.form_fields.text_fields) {
+    pp_page_objects.form_fields.text_fields.push_back(
+        {text_field_info.name, text_field_info.value,
+         text_field_info.is_read_only, text_field_info.is_required,
+         text_field_info.is_password, text_field_info.index_in_page,
+         text_field_info.text_run_index,
+         PPFloatRectFromRectF(text_field_info.bounds)});
+  }
+
+  pp_page_objects.form_fields.choice_fields.reserve(
+      page_objects.form_fields.choice_fields.size());
+  for (const auto& choice_field_info : page_objects.form_fields.choice_fields) {
+    std::vector<pp::PDF::PrivateAccessibilityChoiceFieldOptionInfo>
+        pp_choice_field_option_infos;
+    pp_choice_field_option_infos.reserve(choice_field_info.options.size());
+    for (const auto& option : choice_field_info.options) {
+      pp_choice_field_option_infos.push_back(
+          {option.name, option.is_selected,
+           PPFloatRectFromRectF(option.bounds)});
+    }
+    pp_page_objects.form_fields.choice_fields.push_back(
+        {choice_field_info.name, pp_choice_field_option_infos,
+         static_cast<PP_PrivateChoiceFieldType>(choice_field_info.type),
+         choice_field_info.is_read_only, choice_field_info.is_multi_select,
+         choice_field_info.has_editable_text_box,
+         choice_field_info.index_in_page, choice_field_info.text_run_index,
+         PPFloatRectFromRectF(choice_field_info.bounds)});
+  }
+
+  pp_page_objects.form_fields.buttons.reserve(
+      page_objects.form_fields.buttons.size());
+  for (const auto& button_info : page_objects.form_fields.buttons) {
+    pp_page_objects.form_fields.buttons.push_back(
+        {button_info.name, button_info.value,
+         static_cast<PP_PrivateButtonType>(button_info.type),
+         button_info.is_read_only, button_info.is_checked,
+         button_info.control_count, button_info.control_index,
+         button_info.index_in_page, button_info.text_run_index,
+         PPFloatRectFromRectF(button_info.bounds)});
+  }
+
+  return pp_page_objects;
+}
+
 // Converts |version| to a formatted string.
 base::string16 GetFormattedVersion(PdfVersion version) {
   double value = 0;
@@ -883,21 +951,23 @@
   AccessibilityPageInfo page_info;
   std::vector<AccessibilityTextRunInfo> text_runs;
   std::vector<AccessibilityCharInfo> chars;
-  pp::PDF::PrivateAccessibilityPageObjects page_objects;
+  AccessibilityPageObjects page_objects;
 
   if (!GetAccessibilityInfo(engine(), page_index, page_info, text_runs, chars,
-                            &page_objects)) {
+                            page_objects)) {
     return;
   }
 
   PP_PrivateAccessibilityPageInfo pp_page_info =
-      PrivateAccessibilityPageInfoFromAccessibilityPageInfo(page_info);
+      ToPrivateAccessibilityPageInfo(page_info);
   std::vector<PP_PrivateAccessibilityCharInfo> pp_chars =
-      PrivateAccessibilityCharInfoFromAccessibilityCharInfo(chars);
+      ToPrivateAccessibilityCharInfo(chars);
   std::vector<pp::PDF::PrivateAccessibilityTextRunInfo> pp_text_runs =
-      PrivateAccessibilityCharInfoFromAccessibilityTextRunInfo(text_runs);
+      ToPrivateAccessibilityCharInfo(text_runs);
+  pp::PDF::PrivateAccessibilityPageObjects pp_page_objects =
+      ToPrivateAccessibilityPageObjects(page_objects);
   pp::PDF::SetAccessibilityPageInfo(GetPluginInstance(), &pp_page_info,
-                                    pp_text_runs, pp_chars, page_objects);
+                                    pp_text_runs, pp_chars, pp_page_objects);
 
   // Schedule loading the next page.
   ScheduleTaskOnMainThread(
diff --git a/pdf/pdfium/accessibility_unittest.cc b/pdf/pdfium/accessibility_unittest.cc
index 38724f5..941402c 100644
--- a/pdf/pdfium/accessibility_unittest.cc
+++ b/pdf/pdfium/accessibility_unittest.cc
@@ -9,7 +9,6 @@
 #include "pdf/accessibility_structs.h"
 #include "pdf/pdfium/pdfium_engine.h"
 #include "pdf/pdfium/pdfium_test_base.h"
-#include "pdf/ppapi_migration/geometry_conversions.h"
 #include "pdf/test/test_client.h"
 #include "ppapi/c/private/ppp_pdf.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -77,9 +76,9 @@
   AccessibilityPageInfo page_info;
   std::vector<AccessibilityTextRunInfo> text_runs;
   std::vector<AccessibilityCharInfo> chars;
-  pp::PDF::PrivateAccessibilityPageObjects page_objects;
+  AccessibilityPageObjects page_objects;
   ASSERT_TRUE(GetAccessibilityInfo(engine.get(), 0, page_info, text_runs, chars,
-                                   &page_objects));
+                                   page_objects));
   EXPECT_EQ(0u, page_info.page_index);
   EXPECT_EQ(gfx::Rect(5, 3, 266, 266), page_info.bounds);
   EXPECT_EQ(text_runs.size(), page_info.text_run_count);
@@ -126,9 +125,9 @@
   AccessibilityPageInfo page_info;
   std::vector<AccessibilityTextRunInfo> text_runs;
   std::vector<AccessibilityCharInfo> chars;
-  pp::PDF::PrivateAccessibilityPageObjects page_objects;
+  AccessibilityPageObjects page_objects;
   ASSERT_TRUE(GetAccessibilityInfo(engine.get(), 0, page_info, text_runs, chars,
-                                   &page_objects));
+                                   page_objects));
   EXPECT_EQ(0u, page_info.page_index);
   EXPECT_EQ(gfx::Rect(5, 3, 816, 1056), page_info.bounds);
   EXPECT_EQ(text_runs.size(), page_info.text_run_count);
@@ -137,8 +136,7 @@
 
   for (size_t i = 0; i < page_objects.images.size(); ++i) {
     EXPECT_EQ(page_objects.images[i].alt_text, kExpectedImageInfo[i].alt_text);
-    EXPECT_EQ(kExpectedImageInfo[i].bounds,
-              RectFFromPPFloatRect(page_objects.images[i].bounds));
+    EXPECT_EQ(kExpectedImageInfo[i].bounds, page_objects.images[i].bounds);
     EXPECT_EQ(page_objects.images[i].text_run_index,
               kExpectedImageInfo[i].text_run_index);
   }
@@ -463,9 +461,9 @@
   AccessibilityPageInfo page_info;
   std::vector<AccessibilityTextRunInfo> text_runs;
   std::vector<AccessibilityCharInfo> chars;
-  pp::PDF::PrivateAccessibilityPageObjects page_objects;
+  AccessibilityPageObjects page_objects;
   ASSERT_TRUE(GetAccessibilityInfo(engine.get(), 0, page_info, text_runs, chars,
-                                   &page_objects));
+                                   page_objects));
   EXPECT_EQ(0u, page_info.page_index);
   EXPECT_EQ(gfx::Rect(5, 3, 533, 266), page_info.bounds);
   EXPECT_EQ(text_runs.size(), page_info.text_run_count);
@@ -473,14 +471,14 @@
   ASSERT_EQ(page_objects.links.size(), base::size(expected_link_info));
 
   for (size_t i = 0; i < page_objects.links.size(); ++i) {
-    const pp::PDF::PrivateAccessibilityLinkInfo& link_info =
-        page_objects.links[i];
+    const AccessibilityLinkInfo& link_info = page_objects.links[i];
     EXPECT_EQ(link_info.url, expected_link_info[i].url);
     EXPECT_EQ(link_info.index_in_page, expected_link_info[i].index_in_page);
-    EXPECT_EQ(expected_link_info[i].bounds,
-              RectFFromPPFloatRect(link_info.bounds));
-    EXPECT_EQ(link_info.text_run_index, expected_link_info[i].text_range.index);
-    EXPECT_EQ(link_info.text_run_count, expected_link_info[i].text_range.count);
+    EXPECT_EQ(expected_link_info[i].bounds, link_info.bounds);
+    EXPECT_EQ(link_info.text_range.index,
+              expected_link_info[i].text_range.index);
+    EXPECT_EQ(link_info.text_range.count,
+              expected_link_info[i].text_range.count);
   }
 }
 
@@ -502,9 +500,9 @@
   AccessibilityPageInfo page_info;
   std::vector<AccessibilityTextRunInfo> text_runs;
   std::vector<AccessibilityCharInfo> chars;
-  pp::PDF::PrivateAccessibilityPageObjects page_objects;
+  AccessibilityPageObjects page_objects;
   ASSERT_TRUE(GetAccessibilityInfo(engine.get(), 0, page_info, text_runs, chars,
-                                   &page_objects));
+                                   page_objects));
   EXPECT_EQ(0u, page_info.page_index);
   EXPECT_EQ(gfx::Rect(5, 3, 533, 266), page_info.bounds);
   EXPECT_EQ(text_runs.size(), page_info.text_run_count);
@@ -512,15 +510,14 @@
   ASSERT_EQ(page_objects.highlights.size(), base::size(kExpectedHighlightInfo));
 
   for (size_t i = 0; i < page_objects.highlights.size(); ++i) {
-    const pp::PDF::PrivateAccessibilityHighlightInfo& highlight_info =
+    const AccessibilityHighlightInfo& highlight_info =
         page_objects.highlights[i];
     EXPECT_EQ(highlight_info.index_in_page,
               kExpectedHighlightInfo[i].index_in_page);
-    EXPECT_EQ(kExpectedHighlightInfo[i].bounds,
-              RectFFromPPFloatRect(highlight_info.bounds));
-    EXPECT_EQ(highlight_info.text_run_index,
+    EXPECT_EQ(kExpectedHighlightInfo[i].bounds, highlight_info.bounds);
+    EXPECT_EQ(highlight_info.text_range.index,
               kExpectedHighlightInfo[i].text_range.index);
-    EXPECT_EQ(highlight_info.text_run_count,
+    EXPECT_EQ(highlight_info.text_range.count,
               kExpectedHighlightInfo[i].text_range.count);
     EXPECT_EQ(highlight_info.color, kExpectedHighlightInfo[i].color);
     EXPECT_EQ(highlight_info.note_text, kExpectedHighlightInfo[i].note_text);
@@ -550,9 +547,9 @@
   AccessibilityPageInfo page_info;
   std::vector<AccessibilityTextRunInfo> text_runs;
   std::vector<AccessibilityCharInfo> chars;
-  pp::PDF::PrivateAccessibilityPageObjects page_objects;
+  AccessibilityPageObjects page_objects;
   ASSERT_TRUE(GetAccessibilityInfo(engine.get(), 0, page_info, text_runs, chars,
-                                   &page_objects));
+                                   page_objects));
   EXPECT_EQ(0u, page_info.page_index);
   EXPECT_EQ(gfx::Rect(5, 3, 400, 400), page_info.bounds);
   EXPECT_EQ(text_runs.size(), page_info.text_run_count);
@@ -561,7 +558,7 @@
             base::size(kExpectedTextFieldInfo));
 
   for (size_t i = 0; i < page_objects.form_fields.text_fields.size(); ++i) {
-    const pp::PDF::PrivateAccessibilityTextFieldInfo& text_field_info =
+    const AccessibilityTextFieldInfo& text_field_info =
         page_objects.form_fields.text_fields[i];
     EXPECT_EQ(kExpectedTextFieldInfo[i].name, text_field_info.name);
     EXPECT_EQ(kExpectedTextFieldInfo[i].value, text_field_info.value);
@@ -575,8 +572,7 @@
               text_field_info.index_in_page);
     EXPECT_EQ(kExpectedTextFieldInfo[i].text_run_index,
               text_field_info.text_run_index);
-    EXPECT_EQ(kExpectedTextFieldInfo[i].bounds,
-              RectFFromPPFloatRect(text_field_info.bounds));
+    EXPECT_EQ(kExpectedTextFieldInfo[i].bounds, text_field_info.bounds);
   }
 }
 
diff --git a/pdf/pdfium/pdfium_assert_matching_enums.cc b/pdf/pdfium/pdfium_assert_matching_enums.cc
index 5f3b546..804ae0a 100644
--- a/pdf/pdfium/pdfium_assert_matching_enums.cc
+++ b/pdf/pdfium/pdfium_assert_matching_enums.cc
@@ -337,3 +337,12 @@
                    PP_PRIVATECHOICEFIELD_COMBOBOX);
 STATIC_ASSERT_ENUM(chrome_pdf::ChoiceFieldType::kMaxValue,
                    PP_PRIVATECHOICEFIELD_LAST);
+
+STATIC_ASSERT_ENUM(chrome_pdf::ButtonType::kPushButton,
+                   PP_PRIVATEBUTTON_PUSHBUTTON);
+STATIC_ASSERT_ENUM(chrome_pdf::ButtonType::kPushButton, PP_PRIVATEBUTTON_FIRST);
+STATIC_ASSERT_ENUM(chrome_pdf::ButtonType::kCheckBox,
+                   PP_PRIVATEBUTTON_CHECKBOX);
+STATIC_ASSERT_ENUM(chrome_pdf::ButtonType::kRadioButton,
+                   PP_PRIVATEBUTTON_RADIOBUTTON);
+STATIC_ASSERT_ENUM(chrome_pdf::ButtonType::kMaxValue, PP_PRIVATEBUTTON_LAST);
diff --git a/remoting/signaling/BUILD.gn b/remoting/signaling/BUILD.gn
index f24a8a53..5301ec0 100644
--- a/remoting/signaling/BUILD.gn
+++ b/remoting/signaling/BUILD.gn
@@ -64,7 +64,9 @@
     "//jingle:webrtc_glue",
     "//net",
     "//remoting/base",
+    "//remoting/base:authorization",
     "//remoting/proto/ftl/v1:ftl_messages",
+    "//services/network/public/cpp:cpp",
   ]
 }
 
@@ -82,6 +84,8 @@
 
   public_deps = [
     ":signaling",
+    "//remoting/base:test_support",
+    "//remoting/proto/ftl/v1:ftl_messages",
     "//testing/gmock",
   ]
 }
@@ -107,6 +111,8 @@
   deps = [
     ":test_support",
     "//net:test_support",
+    "//remoting/base:base",
+    "//services/network/public/cpp:cpp",
     "//testing/gmock",
     "//testing/gtest",
   ]
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
index 85bbe657..3880d2a 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
@@ -299,8 +299,13 @@
   }
 
   if (!(rv & PR_SPEC_PRCTL)) {
+// TODO(crbug.com/1171027): Revert https://crrev.com/c/2677242 to re-enable this
+// DCHECK on CrOS. See go/chrome-dcheck-on-cros or http://crbug.com/1113456 for
+// more details.
+#if !(defined(OS_CHROMEOS) && DCHECK_IS_ON())
     DLOG(INFO) << "Indirect branch speculation can not be controled by prctl."
                << rv;
+#endif
     return;
   }
 
diff --git a/services/device/generic_sensor/platform_sensor_util.cc b/services/device/generic_sensor/platform_sensor_util.cc
index 1638639..c204574 100644
--- a/services/device/generic_sensor/platform_sensor_util.cc
+++ b/services/device/generic_sensor/platform_sensor_util.cc
@@ -101,24 +101,29 @@
 void RoundSensorReading(SensorReading* reading, mojom::SensorType sensor_type) {
   switch (sensor_type) {
     case mojom::SensorType::ACCELEROMETER:
-      FALLTHROUGH;
+    case mojom::SensorType::GRAVITY:
     case mojom::SensorType::LINEAR_ACCELERATION:
       RoundAccelerometerReading(&reading->accel);
       break;
+
     case mojom::SensorType::GYROSCOPE:
       RoundGyroscopeReading(&reading->gyro);
       break;
+
     case mojom::SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES:
-      FALLTHROUGH;
     case mojom::SensorType::RELATIVE_ORIENTATION_EULER_ANGLES:
       RoundOrientationEulerReading(&reading->orientation_euler);
       break;
+
     case mojom::SensorType::ABSOLUTE_ORIENTATION_QUATERNION:
-      FALLTHROUGH;
     case mojom::SensorType::RELATIVE_ORIENTATION_QUATERNION:
       RoundOrientationQuaternionReading(&reading->orientation_quat);
       break;
-    default:
+
+    case mojom::SensorType::AMBIENT_LIGHT:
+    case mojom::SensorType::MAGNETOMETER:
+    case mojom::SensorType::PRESSURE:
+    case mojom::SensorType::PROXIMITY:
       break;
   }
 }
diff --git a/services/network/BUILD.gn b/services/network/BUILD.gn
index 8cc414e..6a6aed1 100644
--- a/services/network/BUILD.gn
+++ b/services/network/BUILD.gn
@@ -447,6 +447,8 @@
     "mojo_socket_test_util.h",
     "test/fake_test_cert_verifier_params_factory.cc",
     "test/fake_test_cert_verifier_params_factory.h",
+    "test/test_auth_cert_observer.cc",
+    "test/test_auth_cert_observer.h",
     "test/test_cookie_manager.cc",
     "test/test_cookie_manager.h",
     "test/test_data_pipe_getter.cc",
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index de647c8..dc1d135d 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -1309,29 +1309,26 @@
     const net::IsolationInfo& isolation_info,
     std::vector<mojom::HttpHeaderPtr> additional_headers,
     int32_t process_id,
-    int32_t render_frame_id,
     const url::Origin& origin,
     uint32_t options,
     const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
     mojo::PendingRemote<mojom::WebSocketHandshakeClient> handshake_client,
-    mojo::PendingRemote<mojom::AuthenticationHandler> auth_handler,
+    mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>
+        auth_cert_observer,
+    mojo::PendingRemote<mojom::WebSocketAuthenticationHandler> auth_handler,
     mojo::PendingRemote<mojom::TrustedHeaderClient> header_client) {
 #if !defined(OS_IOS)
   if (!websocket_factory_)
     websocket_factory_ = std::make_unique<WebSocketFactory>(this);
 
   DCHECK_GE(process_id, 0);
-  if (process_id == mojom::kBrowserProcessId) {
-    DCHECK_EQ(render_frame_id, 0);
-  }
 
   websocket_factory_->CreateWebSocket(
       url, requested_protocols, site_for_cookies, isolation_info,
-      std::move(additional_headers), process_id, render_frame_id, origin,
-      options,
+      std::move(additional_headers), process_id, origin, options,
       static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation),
-      std::move(handshake_client), std::move(auth_handler),
-      std::move(header_client));
+      std::move(handshake_client), std::move(auth_cert_observer),
+      std::move(auth_handler), std::move(header_client));
 #endif  // !defined(OS_IOS)
 }
 
diff --git a/services/network/network_context.h b/services/network/network_context.h
index 8c7a354..102548a7 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -313,12 +313,13 @@
       const net::IsolationInfo& isolation_info,
       std::vector<mojom::HttpHeaderPtr> additional_headers,
       int32_t process_id,
-      int32_t render_frame_id,
       const url::Origin& origin,
       uint32_t options,
       const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
       mojo::PendingRemote<mojom::WebSocketHandshakeClient> handshake_client,
-      mojo::PendingRemote<mojom::AuthenticationHandler> auth_handler,
+      mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>
+          auth_cert_observer,
+      mojo::PendingRemote<mojom::WebSocketAuthenticationHandler> auth_handler,
       mojo::PendingRemote<mojom::TrustedHeaderClient> header_client) override;
   void CreateQuicTransport(
       const GURL& url,
@@ -644,13 +645,6 @@
   std::set<std::unique_ptr<ProxyLookupRequest>, base::UniquePtrComparator>
       proxy_lookup_requests_;
 
-  // This must be below |url_request_context_| so that the URLRequestContext
-  // outlives all the URLLoaderFactories and URLLoaders that depend on it;
-  // for the same reason, it must also be below |network_context_|.
-  std::set<std::unique_ptr<cors::CorsURLLoaderFactory>,
-           base::UniquePtrComparator>
-      url_loader_factories_;
-
   std::set<std::unique_ptr<QuicTransport>, base::UniquePtrComparator>
       quic_transports_;
 
@@ -769,6 +763,19 @@
   // DCHECKs on APIs used by external callers.
   bool require_network_isolation_key_ = false;
 
+  // CorsURLLoaderFactory assumes that fields owned by the NetworkContext always
+  // live longer than the factory.  Therefore we want the factories to be
+  // destroyed before other fields above.  In particular:
+  // - This must be below |url_request_context_| so that the URLRequestContext
+  //   outlives all the URLLoaderFactories and URLLoaders that depend on it;
+  //   for the same reason, it must also be below |network_context_|.
+  // - This must be below |loader_count_per_process_| that is touched by
+  //   CorsURLLoaderFactory::DestroyURLLoader (see also
+  //   https://crbug.com/1174943).
+  std::set<std::unique_ptr<cors::CorsURLLoaderFactory>,
+           base::UniquePtrComparator>
+      url_loader_factories_;
+
   base::WeakPtrFactory<NetworkContext> weak_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(NetworkContext);
diff --git a/services/network/public/cpp/BUILD.gn b/services/network/public/cpp/BUILD.gn
index 45d5287..0165c1e 100644
--- a/services/network/public/cpp/BUILD.gn
+++ b/services/network/public/cpp/BUILD.gn
@@ -186,6 +186,23 @@
   defines = [ "IS_NETWORK_CPP_BASE_IMPL" ]
 }
 
+component("network_param_mojom_support") {
+  sources = [
+    "net_ipc_param_traits.cc",
+    "net_ipc_param_traits.h",
+    "network_param_mojom_traits.cc",
+    "network_param_mojom_traits.h",
+  ]
+  deps = [
+    "//ipc",
+    "//mojo/public/cpp/base:shared_typemap_traits",
+    "//net",
+    "//services/network/public/mojom:mojom_network_param_shared",
+    "//url/ipc:url_ipc",
+  ]
+  defines = [ "IS_NETWORK_CPP_BASE_IMPL" ]
+}
+
 # This component is separate from cpp_base as it is a dependency of
 # //services/network/public/mojom:url_loader_base.
 component("cross_origin_embedder_policy") {
@@ -240,8 +257,6 @@
     "isolation_info_mojom_traits.h",
     "mutable_network_traffic_annotation_tag_mojom_traits.h",
     "mutable_partial_network_traffic_annotation_tag_mojom_traits.h",
-    "net_ipc_param_traits.cc",
-    "net_ipc_param_traits.h",
     "network_interface_mojom_traits.cc",
     "network_interface_mojom_traits.h",
     "network_ipc_param_traits.cc",
@@ -279,6 +294,7 @@
     ":crash_keys",
     ":cross_origin_embedder_policy",
     ":ip_address_mojom_support",
+    ":network_param_mojom_support",
     ":schemeful_site_mojom_support",
     "//services/network/public/mojom:url_loader_base",
     "//third_party/webrtc_overrides:webrtc_component",
diff --git a/services/network/public/cpp/network_param_mojom_traits.h b/services/network/public/cpp/network_param_mojom_traits.h
index 81e3d82..a9b9234 100644
--- a/services/network/public/cpp/network_param_mojom_traits.h
+++ b/services/network/public/cpp/network_param_mojom_traits.h
@@ -5,14 +5,16 @@
 #ifndef SERVICES_NETWORK_PUBLIC_CPP_NETWORK_PARAM_MOJOM_TRAITS_H_
 #define SERVICES_NETWORK_PUBLIC_CPP_NETWORK_PARAM_MOJOM_TRAITS_H_
 
+#include "base/component_export.h"
 #include "mojo/public/cpp/bindings/struct_traits.h"
 #include "net/http/http_version.h"
-#include "services/network/public/mojom/network_param.mojom.h"
+#include "services/network/public/mojom/network_param.mojom-shared.h"
 
 namespace mojo {
 
 template <>
-class StructTraits<network::mojom::HttpVersionDataView, net::HttpVersion> {
+class COMPONENT_EXPORT(NETWORK_CPP_BASE)
+    StructTraits<network::mojom::HttpVersionDataView, net::HttpVersion> {
  public:
   static int16_t major_value(net::HttpVersion version) {
     return version.major_value();
diff --git a/services/network/public/cpp/resource_request.cc b/services/network/public/cpp/resource_request.cc
index f7edb27..d812cba 100644
--- a/services/network/public/cpp/resource_request.cc
+++ b/services/network/public/cpp/resource_request.cc
@@ -24,6 +24,19 @@
   return new_remote;
 }
 
+mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver> Clone(
+    mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>*
+        observer) {
+  if (!*observer)
+    return mojo::NullRemote();
+  mojo::Remote<mojom::AuthenticationAndCertificateObserver> remote(
+      std::move(*observer));
+  mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver> new_remote;
+  remote->Clone(new_remote.InitWithNewPipeAndPassReceiver());
+  *observer = remote.Unbind();
+  return new_remote;
+}
+
 // Returns true iff either holds true:
 //
 //  - both |lhs| and |rhs| are nullopt, or
@@ -59,6 +72,10 @@
   cookie_observer =
       Clone(&const_cast<mojo::PendingRemote<mojom::CookieAccessObserver>&>(
           other.cookie_observer));
+  auth_cert_observer =
+      Clone(&const_cast<
+            mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>&>(
+          other.auth_cert_observer));
   client_security_state = other.client_security_state.Clone();
   return *this;
 }
diff --git a/services/network/public/cpp/resource_request.h b/services/network/public/cpp/resource_request.h
index 32904e95..521d6871c 100644
--- a/services/network/public/cpp/resource_request.h
+++ b/services/network/public/cpp/resource_request.h
@@ -20,6 +20,7 @@
 #include "net/url_request/referrer_policy.h"
 #include "services/network/public/cpp/optional_trust_token_params.h"
 #include "services/network/public/cpp/resource_request_body.h"
+#include "services/network/public/mojom/auth_and_certificate_observer.mojom.h"
 #include "services/network/public/mojom/client_security_state.mojom.h"
 #include "services/network/public/mojom/cookie_access_observer.mojom.h"
 #include "services/network/public/mojom/cors.mojom-shared.h"
@@ -55,6 +56,8 @@
     bool disable_secure_dns = false;
     bool has_user_activation = false;
     mojo::PendingRemote<mojom::CookieAccessObserver> cookie_observer;
+    mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>
+        auth_cert_observer;
     mojom::ClientSecurityStatePtr client_security_state;
   };
 
diff --git a/services/network/public/cpp/url_request_mojom_traits.cc b/services/network/public/cpp/url_request_mojom_traits.cc
index 5d43a2f..1fa3a05 100644
--- a/services/network/public/cpp/url_request_mojom_traits.cc
+++ b/services/network/public/cpp/url_request_mojom_traits.cc
@@ -158,6 +158,8 @@
   out->has_user_activation = data.has_user_activation();
   out->cookie_observer = data.TakeCookieObserver<
       mojo::PendingRemote<network::mojom::CookieAccessObserver>>();
+  out->auth_cert_observer = data.TakeAuthCertObserver<mojo::PendingRemote<
+      network::mojom::AuthenticationAndCertificateObserver>>();
   if (!data.ReadClientSecurityState(&out->client_security_state)) {
     return false;
   }
diff --git a/services/network/public/cpp/url_request_mojom_traits.h b/services/network/public/cpp/url_request_mojom_traits.h
index 12a8156..12bdd85 100644
--- a/services/network/public/cpp/url_request_mojom_traits.h
+++ b/services/network/public/cpp/url_request_mojom_traits.h
@@ -25,6 +25,7 @@
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/resource_request_body.h"
 #include "services/network/public/cpp/site_for_cookies_mojom_traits.h"
+#include "services/network/public/mojom/auth_and_certificate_observer.mojom.h"
 #include "services/network/public/mojom/chunked_data_pipe_getter.mojom.h"
 #include "services/network/public/mojom/client_security_state.mojom-forward.h"
 #include "services/network/public/mojom/cookie_access_observer.mojom.h"
@@ -78,6 +79,16 @@
         const_cast<network::ResourceRequest::TrustedParams&>(trusted_params)
             .cookie_observer);
   }
+  static mojo::PendingRemote<
+      network::mojom::AuthenticationAndCertificateObserver>
+  auth_cert_observer(
+      const network::ResourceRequest::TrustedParams& trusted_params) {
+    if (!trusted_params.auth_cert_observer)
+      return mojo::NullRemote();
+    return std::move(
+        const_cast<network::ResourceRequest::TrustedParams&>(trusted_params)
+            .auth_cert_observer);
+  }
   static const network::mojom::ClientSecurityStatePtr& client_security_state(
       const network::ResourceRequest::TrustedParams& trusted_params) {
     return trusted_params.client_security_state;
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn
index e51b87b..c38cc21 100644
--- a/services/network/public/mojom/BUILD.gn
+++ b/services/network/public/mojom/BUILD.gn
@@ -156,6 +156,7 @@
 mojom("url_loader_base") {
   generate_java = true
   sources = [
+    "auth_and_certificate_observer.mojom",
     "chunked_data_pipe_getter.mojom",
     "client_security_state.mojom",
     "cross_origin_embedder_policy.mojom",
@@ -169,6 +170,7 @@
   ]
 
   public_deps = [
+    ":mojom_network_param",
     "//mojo/public/mojom/base",
     "//url/mojom:url_mojom_gurl",
     "//url/mojom:url_mojom_origin",
@@ -251,21 +253,11 @@
   ]
 }
 
-# This target is split from "mojom" target as the lazy serialization may
-# cause problems. See https://crbug.com/822732.
-mojom("websocket_mojom") {
+mojom("mojom_network_param") {
   generate_java = true
-  sources = [
-    "network_param.mojom",
-    "websocket.mojom",
-  ]
+  sources = [ "network_param.mojom" ]
 
-  public_deps = [
-    ":mojom_ip_address",
-    "//mojo/public/mojom/base",
-    "//url/mojom:url_mojom_gurl",
-    "//url/mojom:url_mojom_origin",
-  ]
+  public_deps = [ "//mojo/public/mojom/base" ]
 
   if (!is_ios) {
     export_class_attribute_blink = "BLINK_PLATFORM_EXPORT"
@@ -324,17 +316,33 @@
         "//services/network/public/cpp/net_ipc_param_traits.h",
         "//services/network/public/cpp/network_param_mojom_traits.h",
       ]
-      traits_sources =
-          [ "//services/network/public/cpp/network_param_mojom_traits.cc" ]
-      traits_public_deps = [
-        "//ipc",
-        "//net",
-        "//services/network/public/cpp:cpp_base",
-      ]
+      traits_public_deps =
+          [ "//services/network/public/cpp:network_param_mojom_support" ]
     },
   ]
 }
 
+# This target is split from "mojom" target as the lazy serialization may
+# cause problems. See https://crbug.com/822732.
+mojom("websocket_mojom") {
+  generate_java = true
+  sources = [ "websocket.mojom" ]
+
+  if (!is_ios) {
+    export_class_attribute_blink = "BLINK_PLATFORM_EXPORT"
+    export_define_blink = "BLINK_PLATFORM_IMPLEMENTATION=1"
+    export_header_blink = "third_party/blink/public/platform/web_common.h"
+  }
+
+  public_deps = [
+    ":mojom_ip_address",
+    ":mojom_network_param",
+    "//mojo/public/mojom/base",
+    "//url/mojom:url_mojom_gurl",
+    "//url/mojom:url_mojom_origin",
+  ]
+}
+
 mojom("cookies_mojom") {
   generate_java = true
   sources = [
@@ -522,6 +530,7 @@
     ":cookies_mojom",
     ":mojom_ip_address",
     ":mojom_network_isolation_key",
+    ":mojom_network_param",
     ":mojom_schemeful_site",
     ":url_loader_base",
     ":websocket_mojom",
diff --git a/services/network/public/mojom/auth_and_certificate_observer.mojom b/services/network/public/mojom/auth_and_certificate_observer.mojom
new file mode 100644
index 0000000..9a286bdc
--- /dev/null
+++ b/services/network/public/mojom/auth_and_certificate_observer.mojom
@@ -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.
+
+module network.mojom;
+
+import "services/network/public/mojom/network_param.mojom";
+import "url/mojom/url.mojom";
+
+// This interface is used by an URLLoaderFactory to provide notification
+// of authentication and certificate events. This is typically implemented
+// by a trusted process such as the browser process.
+interface AuthenticationAndCertificateObserver {
+  // Called when an SSL certificate is encountered.
+  // The callback argument is a net::ERROR value. If it's net::OK, then the
+  // request is resumed. Otherwise it's cancelled with the given error.
+  OnSSLCertificateError(url.mojom.Url url,
+                        int32 net_error,
+                        SSLInfo ssl_info,
+                        bool fatal) => (int32 net_error);
+
+  // Used by the NetworkService to create a copy of this observer.
+  // (e.g. when creating an observer for URLLoader from URLLoaderFactory's
+  // observer).
+  Clone(pending_receiver<AuthenticationAndCertificateObserver> listener);
+};
\ No newline at end of file
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index 441af8e..6f5abd0 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -11,6 +11,7 @@
 import "mojo/public/mojom/base/unguessable_token.mojom";
 import "mojo/public/mojom/base/values.mojom";
 import "services/network/public/mojom/address_list.mojom";
+import "services/network/public/mojom/auth_and_certificate_observer.mojom";
 import "services/network/public/mojom/cert_verifier_service.mojom";
 import "services/network/public/mojom/client_security_state.mojom";
 import "services/network/public/mojom/cookie_access_observer.mojom";
@@ -681,6 +682,9 @@
   // Used to notify clients about cookie reads or writes.
   pending_remote<CookieAccessObserver>? cookie_observer;
 
+  // Used to notify clients about authentication and certificate events.
+  pending_remote<AuthenticationAndCertificateObserver>? auth_cert_observer;
+
   // If this equals kForbid, the context to which this loader is bound does not
   // allow any Trust Tokens (https://github.com/wicg/trust-token-api)
   // redemption or signing operations.
@@ -803,16 +807,6 @@
       network.mojom.SSLCertRequestInfo cert_info,
       pending_remote<ClientCertificateResponder> cert_responder);
 
-  // Called when an SSL certificate is encountered.
-  // The callback argument is a net::ERROR value. If it's net::OK, then the
-  // request is resumed. Otherwise it's cancelled with the given error.
-  OnSSLCertificateError(int32 process_id,
-                        int32 routing_id,
-                        url.mojom.Url url,
-                        int32 net_error,
-                        SSLInfo ssl_info,
-                        bool fatal) => (int32 net_error);
-
   // Called when file uploading was requested.
   // If the process that requested the uploads has permission to read all of
   // the files referenced by |file_paths|, the callback arguments will be
@@ -1234,19 +1228,19 @@
   // the connection is established, and due to message ordering uncertainty we
   // cannot know what happened.
   CreateWebSocket(
-        url.mojom.Url url,
-        array<string> requested_protocols,
-        SiteForCookies site_for_cookies,
-        IsolationInfo isolation_info,
-        array<HttpHeader> additional_headers,
-        int32 process_id,
-        int32 render_frame_id,
-        url.mojom.Origin origin,
-        uint32 options,
-        MutableNetworkTrafficAnnotationTag traffic_annotation,
-        pending_remote<WebSocketHandshakeClient> handshake_client,
-        pending_remote<AuthenticationHandler>? auth_handler,
-        pending_remote<TrustedHeaderClient>? header_client);
+      url.mojom.Url url,
+      array<string> requested_protocols,
+      SiteForCookies site_for_cookies,
+      IsolationInfo isolation_info,
+      array<HttpHeader> additional_headers,
+      int32 process_id,
+      url.mojom.Origin origin,
+      uint32 options,
+      MutableNetworkTrafficAnnotationTag traffic_annotation,
+      pending_remote<WebSocketHandshakeClient> handshake_client,
+      pending_remote<AuthenticationAndCertificateObserver>? auth_cert_observer,
+      pending_remote<WebSocketAuthenticationHandler>? auth_handler,
+      pending_remote<TrustedHeaderClient>? header_client);
 
   // Creates a QuicTransport connection to |url|. |origin| is used for the
   // client indication - see
diff --git a/services/network/public/mojom/url_loader.mojom b/services/network/public/mojom/url_loader.mojom
index 9360724..0fda925 100644
--- a/services/network/public/mojom/url_loader.mojom
+++ b/services/network/public/mojom/url_loader.mojom
@@ -8,6 +8,7 @@
 import "mojo/public/mojom/base/file_path.mojom";
 import "mojo/public/mojom/base/time.mojom";
 import "mojo/public/mojom/base/unguessable_token.mojom";
+import "services/network/public/mojom/auth_and_certificate_observer.mojom";
 import "services/network/public/mojom/client_security_state.mojom";
 import "services/network/public/mojom/cors.mojom";
 import "services/network/public/mojom/cookie_access_observer.mojom";
@@ -75,6 +76,11 @@
   // URLLoaderFactory will be ignored.
   pending_remote<CookieAccessObserver>? cookie_observer;
 
+  // Observer which should be notified when this URLRequest has authentication
+  // and certificate events. If this is set to non-null, the observer passed to
+  // URLLoaderFactory will be ignored.
+  pending_remote<AuthenticationAndCertificateObserver>? auth_cert_observer;
+
   // Specifies the security state of the client, for cases when the
   // URLLoaderFactory is shared among multiple clients.
   //
diff --git a/services/network/public/mojom/websocket.mojom b/services/network/public/mojom/websocket.mojom
index 2128df90..004228d 100644
--- a/services/network/public/mojom/websocket.mojom
+++ b/services/network/public/mojom/websocket.mojom
@@ -45,7 +45,7 @@
 };
 
 // This interface is for HTTP Authentication.
-interface AuthenticationHandler {
+interface WebSocketAuthenticationHandler {
   // Returns null credentials when it wants to cancel authentication, and
   // returns a non-null credentials when it wants to use the credentials for
   // authentication.
diff --git a/services/network/test/test_auth_cert_observer.cc b/services/network/test/test_auth_cert_observer.cc
new file mode 100644
index 0000000..ec5aa72
--- /dev/null
+++ b/services/network/test/test_auth_cert_observer.cc
@@ -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.
+
+#include "services/network/test/test_auth_cert_observer.h"
+
+#include "net/base/net_errors.h"
+
+namespace network {
+
+TestAuthCertObserver::TestAuthCertObserver() = default;
+TestAuthCertObserver::~TestAuthCertObserver() = default;
+
+mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>
+TestAuthCertObserver::Bind() {
+  mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver> remote;
+  receivers_.Add(this, remote.InitWithNewPipeAndPassReceiver());
+  return remote;
+}
+
+void TestAuthCertObserver::OnSSLCertificateError(
+    const GURL& url,
+    int net_error,
+    const net::SSLInfo& ssl_info,
+    bool fatal,
+    OnSSLCertificateErrorCallback response) {
+  std::move(response).Run(ignore_certificate_errors_ ? net::OK : net_error);
+}
+
+void TestAuthCertObserver::Clone(
+    mojo::PendingReceiver<AuthenticationAndCertificateObserver> observer) {
+  receivers_.Add(this, std::move(observer));
+}
+
+}  // namespace network
diff --git a/services/network/test/test_auth_cert_observer.h b/services/network/test/test_auth_cert_observer.h
new file mode 100644
index 0000000..4116699
--- /dev/null
+++ b/services/network/test/test_auth_cert_observer.h
@@ -0,0 +1,45 @@
+// 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 SERVICES_NETWORK_TEST_TEST_AUTH_CERT_OBSERVER_H_
+#define SERVICES_NETWORK_TEST_TEST_AUTH_CERT_OBSERVER_H_
+
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "services/network/public/mojom/auth_and_certificate_observer.mojom.h"
+
+namespace network {
+
+// A helper class with a basic AuthenticationAndCertificateObserver
+// implementation for use in unittests, so they can just override the parts they
+// need.
+class TestAuthCertObserver
+    : public mojom::AuthenticationAndCertificateObserver {
+ public:
+  TestAuthCertObserver();
+  ~TestAuthCertObserver() override;
+
+  mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver> Bind();
+
+  void set_ignore_certificate_errors(bool ignore_certificate_errors) {
+    ignore_certificate_errors_ = ignore_certificate_errors;
+  }
+
+  // mojom::AuthenticationAndCertificateObserver overrides:
+  void OnSSLCertificateError(const GURL& url,
+                             int net_error,
+                             const net::SSLInfo& ssl_info,
+                             bool fatal,
+                             OnSSLCertificateErrorCallback response) override;
+  void Clone(mojo::PendingReceiver<AuthenticationAndCertificateObserver>
+                 observer) override;
+
+ private:
+  mojo::ReceiverSet<mojom::AuthenticationAndCertificateObserver> receivers_;
+  bool ignore_certificate_errors_ = false;
+};
+
+}  // namespace network
+
+#endif  // SERVICES_NETWORK_TEST_TEST_AUTH_CERT_OBSERVER_H_
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h
index 3b1c2b4..e3f7acf 100644
--- a/services/network/test/test_network_context.h
+++ b/services/network/test/test_network_context.h
@@ -21,6 +21,7 @@
 #include "net/base/isolation_info.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/cpp/network_service_buildflags.h"
+#include "services/network/public/mojom/auth_and_certificate_observer.mojom.h"
 #include "services/network/public/mojom/cookie_access_observer.mojom.h"
 #include "services/network/public/mojom/cookie_manager.mojom.h"
 #include "services/network/public/mojom/host_resolver.mojom.h"
@@ -166,12 +167,13 @@
       const net::IsolationInfo& isolation_info,
       std::vector<mojom::HttpHeaderPtr> additional_headers,
       int32_t process_id,
-      int32_t render_frame_id,
       const url::Origin& origin,
       uint32_t options,
       const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
       mojo::PendingRemote<mojom::WebSocketHandshakeClient> handshake_client,
-      mojo::PendingRemote<mojom::AuthenticationHandler> auth_handler,
+      mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>
+          auth_cert_observer,
+      mojo::PendingRemote<mojom::WebSocketAuthenticationHandler> auth_handler,
       mojo::PendingRemote<mojom::TrustedHeaderClient> header_client) override {}
   void CreateQuicTransport(
       const GURL& url,
diff --git a/services/network/test/test_network_context_client.cc b/services/network/test/test_network_context_client.cc
index 5f977d6e..e4a3b512 100644
--- a/services/network/test/test_network_context_client.cc
+++ b/services/network/test/test_network_context_client.cc
@@ -52,15 +52,4 @@
   std::move(callback).Run(net::OK, std::move(files));
 }
 
-void TestNetworkContextClient::OnSSLCertificateError(
-    int32_t process_id,
-    int32_t routing_id,
-    const GURL& url,
-    int net_error,
-    const net::SSLInfo& ssl_info,
-    bool fatal,
-    OnSSLCertificateErrorCallback response) {
-  std::move(response).Run(ignore_certificate_errors_ ? net::OK : net_error);
-}
-
 }  // namespace network
diff --git a/services/network/test/test_network_context_client.h b/services/network/test/test_network_context_client.h
index c050130..f94e802 100644
--- a/services/network/test/test_network_context_client.h
+++ b/services/network/test/test_network_context_client.h
@@ -29,9 +29,6 @@
   void set_ignore_last_upload_file(bool ignore_last_upload_file) {
     ignore_last_upload_file_ = ignore_last_upload_file;
   }
-  void set_ignore_certificate_errors(bool ignore_certificate_errors) {
-    ignore_certificate_errors_ = ignore_certificate_errors;
-  }
 
   void OnAuthRequired(const base::Optional<base::UnguessableToken>& window_id,
                       int32_t process_id,
@@ -51,13 +48,6 @@
       const scoped_refptr<net::SSLCertRequestInfo>& cert_info,
       mojo::PendingRemote<mojom::ClientCertificateResponder>
           client_cert_responder) override {}
-  void OnSSLCertificateError(int32_t process_id,
-                             int32_t routing_id,
-                             const GURL& url,
-                             int net_error,
-                             const net::SSLInfo& ssl_info,
-                             bool fatal,
-                             OnSSLCertificateErrorCallback response) override;
   void OnFileUploadRequested(int32_t process_id,
                              bool async,
                              const std::vector<base::FilePath>& file_paths,
@@ -95,7 +85,6 @@
   mojo::Receiver<mojom::NetworkContextClient> receiver_;
   bool upload_files_invalid_ = false;
   bool ignore_last_upload_file_ = false;
-  bool ignore_certificate_errors_ = false;
 };
 
 }  // namespace network
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index e2bcb05..350a57c5 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -465,7 +465,9 @@
     mojom::OriginPolicyManager* origin_policy_manager,
     std::unique_ptr<TrustTokenRequestHelperFactory> trust_token_helper_factory,
     const cors::OriginAccessList& origin_access_list,
-    mojo::PendingRemote<mojom::CookieAccessObserver> cookie_observer)
+    mojo::PendingRemote<mojom::CookieAccessObserver> cookie_observer,
+    mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>
+        auth_cert_observer)
     : url_request_context_(url_request_context),
       network_service_client_(network_service_client),
       network_context_client_(network_context_client),
@@ -506,6 +508,7 @@
       trust_token_helper_factory_(std::move(trust_token_helper_factory)),
       origin_access_list_(origin_access_list),
       cookie_observer_(std::move(cookie_observer)),
+      auth_cert_observer_(std::move(auth_cert_observer)),
       has_fetch_streaming_upload_body_(HasFetchStreamingUploadBody(&request)),
       allow_http1_for_streaming_upload_(
           request.request_body &&
@@ -1238,13 +1241,12 @@
                                       int net_error,
                                       const net::SSLInfo& ssl_info,
                                       bool fatal) {
-  if (!network_context_client_) {
+  if (!auth_cert_observer_) {
     OnSSLCertificateErrorResponse(ssl_info, net::ERR_INSECURE_RESPONSE);
     return;
   }
-  network_context_client_->OnSSLCertificateError(
-      factory_params_->process_id, render_frame_id_, url_request_->url(),
-      net_error, ssl_info, fatal,
+  auth_cert_observer_->OnSSLCertificateError(
+      url_request_->url(), net_error, ssl_info, fatal,
       base::BindOnce(&URLLoader::OnSSLCertificateErrorResponse,
                      weak_ptr_factory_.GetWeakPtr(), ssl_info));
 }
diff --git a/services/network/url_loader.h b/services/network/url_loader.h
index 3a717c0..e350761 100644
--- a/services/network/url_loader.h
+++ b/services/network/url_loader.h
@@ -134,7 +134,9 @@
       std::unique_ptr<TrustTokenRequestHelperFactory>
           trust_token_helper_factory,
       const cors::OriginAccessList& origin_access_list,
-      mojo::PendingRemote<mojom::CookieAccessObserver> cookie_observer);
+      mojo::PendingRemote<mojom::CookieAccessObserver> cookie_observer,
+      mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>
+          auth_cert_observer);
   ~URLLoader() override;
 
   // mojom::URLLoader implementation:
@@ -526,6 +528,8 @@
   // Observer listening to all cookie reads and writes made by this request.
   mojo::Remote<mojom::CookieAccessObserver> cookie_observer_;
 
+  mojo::Remote<mojom::AuthenticationAndCertificateObserver> auth_cert_observer_;
+
   // Client security state copied from the input ResourceRequest.
   //
   // If |factory_params_->client_security_state| is non-null, this is null.
diff --git a/services/network/url_loader_factory.cc b/services/network/url_loader_factory.cc
index f4011cf..6cda209 100644
--- a/services/network/url_loader_factory.cc
+++ b/services/network/url_loader_factory.cc
@@ -78,7 +78,8 @@
       header_client_(std::move(params_->header_client)),
       coep_reporter_(std::move(params_->coep_reporter)),
       cors_url_loader_factory_(cors_url_loader_factory),
-      cookie_observer_(std::move(params_->cookie_observer)) {
+      cookie_observer_(std::move(params_->cookie_observer)),
+      auth_cert_observer_(std::move(params_->auth_cert_observer)) {
   DCHECK(context);
   DCHECK_NE(mojom::kInvalidProcessId, params_->process_id);
   DCHECK(!params_->factory_override);
@@ -268,6 +269,18 @@
   } else if (cookie_observer_) {
     cookie_observer_->Clone(cookie_observer.InitWithNewPipeAndPassReceiver());
   }
+  mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>
+      auth_cert_observer;
+  if (url_request.trusted_params &&
+      url_request.trusted_params->auth_cert_observer) {
+    auth_cert_observer = std::move(
+        const_cast<
+            mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>&>(
+            url_request.trusted_params->auth_cert_observer));
+  } else if (auth_cert_observer_) {
+    auth_cert_observer_->Clone(
+        auth_cert_observer.InitWithNewPipeAndPassReceiver());
+  }
 
   if (url_request.destination ==
       network::mojom::RequestDestination::kWebBundle) {
@@ -294,7 +307,8 @@
       std::move(network_usage_accumulator),
       header_client_.is_bound() ? header_client_.get() : nullptr,
       context_->origin_policy_manager(), std::move(trust_token_factory),
-      context_->cors_origin_access_list(), std::move(cookie_observer));
+      context_->cors_origin_access_list(), std::move(cookie_observer),
+      std::move(auth_cert_observer));
 
   cors_url_loader_factory_->OnLoaderCreated(std::move(loader));
 }
diff --git a/services/network/url_loader_factory.h b/services/network/url_loader_factory.h
index 182b268..14bf983 100644
--- a/services/network/url_loader_factory.h
+++ b/services/network/url_loader_factory.h
@@ -79,6 +79,7 @@
   cors::CorsURLLoaderFactory* cors_url_loader_factory_;
 
   mojo::Remote<mojom::CookieAccessObserver> cookie_observer_;
+  mojo::Remote<mojom::AuthenticationAndCertificateObserver> auth_cert_observer_;
 
   DISALLOW_COPY_AND_ASSIGN(URLLoaderFactory);
 };
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc
index 9fd4a99..9981e01 100644
--- a/services/network/url_loader_unittest.cc
+++ b/services/network/url_loader_unittest.cc
@@ -89,6 +89,7 @@
 #include "services/network/public/mojom/trust_tokens.mojom-shared.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 #include "services/network/resource_scheduler/resource_scheduler_client.h"
+#include "services/network/test/test_auth_cert_observer.h"
 #include "services/network/test/test_data_pipe_getter.h"
 #include "services/network/test/test_network_context_client.h"
 #include "services/network/test/test_network_service_client.h"
@@ -600,6 +601,7 @@
       options |= mojom::kURLLoadOptionSendSSLInfoForCertificateError;
 
     std::unique_ptr<TestNetworkContextClient> network_context_client;
+    std::unique_ptr<TestAuthCertObserver> auth_cert_observer;
     if (allow_file_uploads_) {
       network_context_client = std::make_unique<TestNetworkContextClient>();
       network_context_client->set_upload_files_invalid(upload_files_invalid_);
@@ -607,10 +609,8 @@
           ignore_last_upload_file_);
     }
     if (ignore_certificate_errors_) {
-      if (!network_context_client) {
-        network_context_client = std::make_unique<TestNetworkContextClient>();
-      }
-      network_context_client->set_ignore_certificate_errors(true);
+      auth_cert_observer = std::make_unique<TestAuthCertObserver>();
+      auth_cert_observer->set_ignore_certificate_errors(true);
     }
 
     base::RunLoop delete_run_loop;
@@ -639,7 +639,9 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        auth_cert_observer ? auth_cert_observer->Bind()
+                           : mojo::NullRemote() /* auth_cert_observer */);
 
     ran_ = true;
 
@@ -1580,7 +1582,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   // Run until the response body pipe arrives, to make sure that a live body
   // pipe does not result in keeping the loader alive when the URLLoader pipe is
@@ -1638,7 +1641,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilResponseBodyArrived();
   EXPECT_TRUE(client()->has_received_response());
@@ -1697,7 +1701,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   // Pausing reading response body from network stops future reads from the
   // underlying URLRequest. So no data should be sent using the response body
@@ -1778,7 +1783,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   response_controller.WaitForRequest();
   response_controller.Send(
@@ -1848,7 +1854,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   loader->PauseReadingBodyFromNet();
   loader.FlushForTesting();
@@ -1913,7 +1920,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   // It is okay to call ResumeReadingBodyFromNet() even if there is no prior
   // PauseReadingBodyFromNet().
@@ -2169,7 +2177,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   mojom::NetworkContextClient::OnFileUploadRequestedCallback callback;
   network_context_client->RunUntilUploadRequested(&callback);
@@ -2302,7 +2311,8 @@
       nullptr /* keepalive_statistics_reporter */,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   mojom::ChunkedDataPipeGetter::GetSizeCallback get_size_callback =
       data_pipe_getter.WaitForGetSize();
@@ -2354,7 +2364,8 @@
       nullptr /* keepalive_statistics_reporter */,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   mojom::ChunkedDataPipeGetter::GetSizeCallback get_size_callback =
       data_pipe_getter.WaitForGetSize();
@@ -2450,7 +2461,8 @@
   params.process_id = mojom::kBrowserProcessId;
   params.is_corb_enabled = false;
   auto network_context_client = std::make_unique<TestNetworkContextClient>();
-  network_context_client->set_ignore_certificate_errors(true);
+  TestAuthCertObserver auth_cert_observer;
+  auth_cert_observer.set_ignore_certificate_errors(true);
   url_loader = std::make_unique<URLLoader>(
       context(), nullptr /* network_service_client */,
       network_context_client.get(),
@@ -2466,7 +2478,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      auth_cert_observer.Bind() /* auth_cert_observer */);
 
   client.RunUntilRedirectReceived();
   ASSERT_TRUE(client.response_head()->ssl_info.has_value());
@@ -2500,7 +2513,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilRedirectReceived();
 
@@ -2559,7 +2573,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     client.RunUntilRedirectReceived();
 
@@ -2602,7 +2617,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client.RunUntilRedirectReceived();
 
@@ -2659,7 +2675,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilRedirectReceived();
 
@@ -2706,7 +2723,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilRedirectReceived();
 
@@ -2757,7 +2775,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilRedirectReceived();
 
@@ -2812,7 +2831,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilRedirectReceived();
 
@@ -2876,7 +2896,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilRedirectReceived();
 
@@ -2947,7 +2968,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilRedirectReceived();
 
@@ -2984,7 +3006,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilRedirectReceived();
 
@@ -3091,7 +3114,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     loaders.emplace_back(
         std::make_pair(std::move(url_loader), std::move(loader_remote)));
@@ -3117,7 +3141,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
   base::RunLoop().RunUntilIdle();
 
   // Make sure that the ResourceScheduler throttles this request.
@@ -3159,7 +3184,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilResponseBodyArrived();
   client()->response_body_release();
@@ -3562,7 +3588,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
   base::RunLoop().RunUntilIdle();
 
   ASSERT_TRUE(url_loader);
@@ -3610,7 +3637,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
   base::RunLoop().RunUntilIdle();
 
   ASSERT_TRUE(url_loader);
@@ -3658,7 +3686,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
   base::RunLoop().RunUntilIdle();
 
   ASSERT_TRUE(url_loader);
@@ -3707,7 +3736,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
   base::RunLoop().RunUntilIdle();
 
   ASSERT_TRUE(url_loader);
@@ -3755,7 +3785,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
   base::RunLoop().RunUntilIdle();
 
   ASSERT_TRUE(url_loader);
@@ -3800,7 +3831,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilResponseBodyArrived();
   std::string body = ReadBody();
@@ -3845,7 +3877,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilResponseBodyArrived();
   std::string body = ReadBody();
@@ -3885,7 +3918,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilRedirectReceived();
 
@@ -3991,7 +4025,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   EXPECT_EQ(0, network_context_client.on_certificate_requested_counter());
   EXPECT_EQ(0, private_key->sign_count());
@@ -4045,7 +4080,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
   network_context_client.set_url_loader_remote(&loader);
 
   RunUntilIdle();
@@ -4090,7 +4126,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
   network_context_client.set_url_loader_remote(&loader);
 
   RunUntilIdle();
@@ -4135,7 +4172,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   RunUntilIdle();
   ASSERT_TRUE(url_loader);
@@ -4189,7 +4227,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   RunUntilIdle();
   ASSERT_TRUE(url_loader);
@@ -4248,7 +4287,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   RunUntilIdle();
   ASSERT_TRUE(url_loader);
@@ -4309,7 +4349,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   RunUntilIdle();
   ASSERT_TRUE(url_loader);
@@ -4351,7 +4392,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   EXPECT_FALSE(url_loader->AllowCookies(first_party_url, site_for_cookies));
   EXPECT_FALSE(url_loader->AllowCookies(third_party_url, site_for_cookies));
@@ -4383,7 +4425,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   EXPECT_TRUE(url_loader->AllowCookies(first_party_url, site_for_cookies));
   EXPECT_FALSE(url_loader->AllowCookies(third_party_url, site_for_cookies));
@@ -4415,7 +4458,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   EXPECT_TRUE(url_loader->AllowCookies(first_party_url, site_for_cookies));
   EXPECT_TRUE(url_loader->AllowCookies(third_party_url, site_for_cookies));
@@ -4471,7 +4515,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilComplete();
   delete_run_loop.Run();
@@ -4529,7 +4574,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilComplete();
   delete_run_loop.Run();
@@ -4589,7 +4635,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilComplete();
   delete_run_loop.Run();
@@ -4626,7 +4673,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        cookie_observer.GetRemote());
+        cookie_observer.GetRemote(),
+        mojo::NullRemote() /* auth_cert_observer */);
 
     delete_run_loop.Run();
     loader_client.RunUntilComplete();
@@ -4663,7 +4711,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        cookie_observer.GetRemote());
+        cookie_observer.GetRemote(),
+        mojo::NullRemote() /* auth_cert_observer */);
 
     delete_run_loop.Run();
     loader_client.RunUntilComplete();
@@ -4700,7 +4749,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        cookie_observer.GetRemote());
+        cookie_observer.GetRemote(),
+        mojo::NullRemote() /* auth_cert_observer */);
 
     delete_run_loop.Run();
     loader_client.RunUntilComplete();
@@ -4749,7 +4799,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, cookie_observer.GetRemote());
+      kEmptyOriginAccessList, cookie_observer.GetRemote(),
+      mojo::NullRemote() /* auth_cert_observer */);
 
   loader_client.RunUntilRedirectReceived();
   loader->FollowRedirect({}, {}, {}, base::nullopt);
@@ -4799,7 +4850,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        cookie_observer.GetRemote());
+        cookie_observer.GetRemote(),
+        mojo::NullRemote() /* auth_cert_observer */);
 
     loader_client.RunUntilComplete();
     delete_run_loop.Run();
@@ -4849,7 +4901,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     delete_run_loop.Run();
     loader_client.RunUntilComplete();
@@ -4903,7 +4956,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     delete_run_loop.Run();
     loader_client.RunUntilComplete();
@@ -4949,7 +5003,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     delete_run_loop.Run();
     loader_client.RunUntilComplete();
@@ -4999,7 +5054,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     delete_run_loop.Run();
     loader_client.RunUntilComplete();
@@ -5049,7 +5105,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     loader_client.RunUntilRedirectReceived();
 
@@ -5105,7 +5162,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     loader_client.RunUntilRedirectReceived();
     loader->FollowRedirect({}, {}, {}, base::nullopt);
@@ -5155,7 +5213,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     loader_client.RunUntilComplete();
     delete_run_loop.Run();
@@ -5203,7 +5262,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     loader_client.RunUntilComplete();
     delete_run_loop.Run();
@@ -5248,7 +5308,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     delete_run_loop.Run();
     loader_client.RunUntilComplete();
@@ -5305,7 +5366,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        cookie_observer.GetRemote());
+        cookie_observer.GetRemote(),
+        mojo::NullRemote() /* auth_cert_observer */);
 
     delete_run_loop.Run();
     loader_client.RunUntilComplete();
@@ -5364,7 +5426,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        cookie_observer.GetRemote());
+        cookie_observer.GetRemote(),
+        mojo::NullRemote() /* auth_cert_observer */);
 
     delete_run_loop.Run();
     loader_client.RunUntilComplete();
@@ -5411,7 +5474,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, nullptr /* origin_policy_manager */,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        cookie_observer.GetRemote());
+        cookie_observer.GetRemote(),
+        mojo::NullRemote() /* auth_cert_observer */);
 
     delete_run_loop.Run();
     loader_client.RunUntilComplete();
@@ -5509,7 +5573,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, &mock_origin_policy_manager,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     loader_client.RunUntilComplete();
     delete_run_loop.Run();
@@ -5565,7 +5630,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, &mock_origin_policy_manager,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     loader_client.RunUntilComplete();
     delete_run_loop.Run();
@@ -5608,7 +5674,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, &mock_origin_policy_manager,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     loader_client.RunUntilResponseBodyArrived();
     delete_run_loop.Run();
@@ -5657,7 +5724,8 @@
         nullptr, nullptr /* network_usage_accumulator */,
         nullptr /* header_client */, &mock_origin_policy_manager,
         nullptr /* trust_token_helper */, kEmptyOriginAccessList,
-        mojo::NullRemote() /* cookie_observer */);
+        mojo::NullRemote() /* cookie_observer */,
+        mojo::NullRemote() /* auth_cert_observer */);
 
     loader_client.RunUntilComplete();
     delete_run_loop.Run();
@@ -5956,7 +6024,8 @@
           mojom::TrustTokenOperationStatus::kOk /* on_begin */,
           mojom::TrustTokenOperationStatus::kOk /* on_finalize */, GetParam(),
           &outbound_trust_token_operation_was_successful_),
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilComplete();
   delete_run_loop.Run();
@@ -6013,7 +6082,8 @@
           mojom::TrustTokenOperationStatus::kAlreadyExists /* on_begin */,
           base::nullopt /* on_finalize */, GetParam(),
           &outbound_trust_token_operation_was_successful_),
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */
   );
 
   client()->RunUntilComplete();
@@ -6059,7 +6129,8 @@
           mojom::TrustTokenOperationStatus::kFailedPrecondition /* on_begin */,
           base::nullopt /* on_finalize */, GetParam(),
           &outbound_trust_token_operation_was_successful_),
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilComplete();
   delete_run_loop.Run();
@@ -6104,7 +6175,8 @@
           mojom::TrustTokenOperationStatus::kOk /* on_begin */,
           mojom::TrustTokenOperationStatus::kBadResponse /* on_finalize */,
           GetParam(), &outbound_trust_token_operation_was_successful_),
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilComplete();
   delete_run_loop.Run();
@@ -6148,7 +6220,8 @@
           mojom::TrustTokenOperationStatus::
               kInternalError /* helper_creation_error */,
           GetParam()),
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   client()->RunUntilComplete();
   delete_run_loop.Run();
@@ -6192,7 +6265,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
 
   delete_run_loop.Run();
   client()->RunUntilComplete();
@@ -6241,7 +6315,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
   delete_run_loop.Run();
   client()->RunUntilComplete();
   EXPECT_EQ(net::OK, client()->completion_status().error_code);
@@ -6282,7 +6357,8 @@
       resource_scheduler_client(), nullptr,
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
-      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */);
+      kEmptyOriginAccessList, mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
   delete_run_loop.Run();
   client()->RunUntilComplete();
   EXPECT_EQ(net::OK, client()->completion_status().error_code);
@@ -6316,7 +6392,8 @@
       nullptr /* network_usage_accumulator */, nullptr /* header_client */,
       nullptr /* origin_policy_manager */, nullptr /* trust_token_helper */,
       kEmptyOriginAccessList /* origin_access_list */,
-      mojo::NullRemote() /* cookie_observer */);
+      mojo::NullRemote() /* cookie_observer */,
+      mojo::NullRemote() /* auth_cert_observer */);
   delete_run_loop.Run();
   client()->RunUntilComplete();
   EXPECT_EQ(net::OK, client()->completion_status().error_code);
diff --git a/services/network/websocket.cc b/services/network/websocket.cc
index 66406b29..50b457c 100644
--- a/services/network/websocket.cc
+++ b/services/network/websocket.cc
@@ -353,11 +353,16 @@
   DVLOG(3) << "WebSocketEventHandler::OnSSLCertificateError"
            << reinterpret_cast<void*>(this) << " url=" << url.spec()
            << " cert_status=" << ssl_info.cert_status << " fatal=" << fatal;
-  impl_->factory_->OnSSLCertificateError(
+  if (!impl_->auth_cert_observer_) {
+    impl_->OnSSLCertificateErrorResponse(std::move(callbacks), ssl_info,
+                                         net::ERR_INSECURE_RESPONSE);
+    return;
+  }
+  impl_->auth_cert_observer_->OnSSLCertificateError(
+      url, net_error, ssl_info, fatal,
       base::BindOnce(&WebSocket::OnSSLCertificateErrorResponse,
                      impl_->weak_ptr_factory_.GetWeakPtr(),
-                     std::move(callbacks), ssl_info),
-      url, impl_->child_id_, impl_->frame_id_, net_error, ssl_info, fatal);
+                     std::move(callbacks), ssl_info));
 }
 
 int WebSocket::WebSocketEventHandler::OnAuthRequired(
@@ -396,20 +401,21 @@
     const net::SiteForCookies& site_for_cookies,
     const net::IsolationInfo& isolation_info,
     std::vector<mojom::HttpHeaderPtr> additional_headers,
-    int32_t child_id,
-    int32_t frame_id,
     const url::Origin& origin,
     uint32_t options,
     net::NetworkTrafficAnnotationTag traffic_annotation,
     HasRawHeadersAccess has_raw_headers_access,
     mojo::PendingRemote<mojom::WebSocketHandshakeClient> handshake_client,
-    mojo::PendingRemote<mojom::AuthenticationHandler> auth_handler,
+    mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>
+        auth_cert_observer,
+    mojo::PendingRemote<mojom::WebSocketAuthenticationHandler> auth_handler,
     mojo::PendingRemote<mojom::TrustedHeaderClient> header_client,
     base::Optional<WebSocketThrottler::PendingConnection>
         pending_connection_tracker,
     DataPipeUseTracker data_pipe_use_tracker,
     base::TimeDelta delay)
     : factory_(factory),
+      auth_cert_observer_(std::move(auth_cert_observer)),
       handshake_client_(std::move(handshake_client)),
       auth_handler_(std::move(auth_handler)),
       header_client_(std::move(header_client)),
@@ -417,8 +423,6 @@
       delay_(delay),
       options_(options),
       traffic_annotation_(traffic_annotation),
-      child_id_(child_id),
-      frame_id_(frame_id),
       origin_(std::move(origin)),
       site_for_cookies_(site_for_cookies),
       has_raw_headers_access_(has_raw_headers_access),
diff --git a/services/network/websocket.h b/services/network/websocket.h
index e14c5616..91880b5 100644
--- a/services/network/websocket.h
+++ b/services/network/websocket.h
@@ -61,14 +61,14 @@
       const net::SiteForCookies& site_for_cookies,
       const net::IsolationInfo& isolation_info,
       std::vector<mojom::HttpHeaderPtr> additional_headers,
-      int32_t process_id,
-      int32_t render_frame_id,
       const url::Origin& origin,
       uint32_t options,
       net::NetworkTrafficAnnotationTag traffic_annotation,
       HasRawHeadersAccess has_raw_cookie_access,
       mojo::PendingRemote<mojom::WebSocketHandshakeClient> handshake_client,
-      mojo::PendingRemote<mojom::AuthenticationHandler> auth_handler,
+      mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>
+          auth_cert_observer,
+      mojo::PendingRemote<mojom::WebSocketAuthenticationHandler> auth_handler,
       mojo::PendingRemote<mojom::TrustedHeaderClient> header_client,
       base::Optional<WebSocketThrottler::PendingConnection>
           pending_connection_tracker,
@@ -179,9 +179,10 @@
   WebSocketFactory* const factory_;
   mojo::Receiver<mojom::WebSocket> receiver_{this};
 
+  mojo::Remote<mojom::AuthenticationAndCertificateObserver> auth_cert_observer_;
   mojo::Remote<mojom::WebSocketHandshakeClient> handshake_client_;
   mojo::Remote<mojom::WebSocketClient> client_;
-  mojo::Remote<mojom::AuthenticationHandler> auth_handler_;
+  mojo::Remote<mojom::WebSocketAuthenticationHandler> auth_handler_;
   mojo::Remote<mojom::TrustedHeaderClient> header_client_;
 
   base::Optional<WebSocketThrottler::PendingConnection>
@@ -197,9 +198,6 @@
 
   const net::NetworkTrafficAnnotationTag traffic_annotation_;
 
-  const int32_t child_id_;
-  const int32_t frame_id_;
-
   // The web origin to use for the WebSocket.
   const url::Origin origin_;
 
diff --git a/services/network/websocket_factory.cc b/services/network/websocket_factory.cc
index 6cd881c..4cbecc0 100644
--- a/services/network/websocket_factory.cc
+++ b/services/network/websocket_factory.cc
@@ -34,12 +34,13 @@
     const net::IsolationInfo& isolation_info,
     std::vector<mojom::HttpHeaderPtr> additional_headers,
     int32_t process_id,
-    int32_t render_frame_id,
     const url::Origin& origin,
     uint32_t options,
     net::NetworkTrafficAnnotationTag traffic_annotation,
     mojo::PendingRemote<mojom::WebSocketHandshakeClient> handshake_client,
-    mojo::PendingRemote<mojom::AuthenticationHandler> auth_handler,
+    mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>
+        auth_cert_observer,
+    mojo::PendingRemote<mojom::WebSocketAuthenticationHandler> auth_handler,
     mojo::PendingRemote<mojom::TrustedHeaderClient> header_client) {
   if (isolation_info.request_type() !=
       net::IsolationInfo::RequestType::kOther) {
@@ -67,9 +68,9 @@
           process_id, net::ChangeWebSocketSchemeToHttpScheme(url)));
   connections_.insert(std::make_unique<WebSocket>(
       this, url, requested_protocols, site_for_cookies, isolation_info,
-      std::move(additional_headers), process_id, render_frame_id, origin,
-      options, traffic_annotation, has_raw_headers_access,
-      std::move(handshake_client), std::move(auth_handler),
+      std::move(additional_headers), origin, options, traffic_annotation,
+      has_raw_headers_access, std::move(handshake_client),
+      std::move(auth_cert_observer), std::move(auth_handler),
       std::move(header_client),
       throttler_.IssuePendingConnectionTracker(process_id),
       DataPipeUseTracker(context_->network_service(), DataPipeUser::kWebSocket),
@@ -80,19 +81,6 @@
   return context_->url_request_context();
 }
 
-void WebSocketFactory::OnSSLCertificateError(
-    base::OnceCallback<void(int)> callback,
-    const GURL& url,
-    int process_id,
-    int render_frame_id,
-    int net_error,
-    const net::SSLInfo& ssl_info,
-    bool fatal) {
-  context_->client()->OnSSLCertificateError(process_id, render_frame_id, url,
-                                            net_error, ssl_info, fatal,
-                                            std::move(callback));
-}
-
 void WebSocketFactory::Remove(WebSocket* impl) {
   auto it = connections_.find(impl);
   if (it == connections_.end()) {
diff --git a/services/network/websocket_factory.h b/services/network/websocket_factory.h
index 87af5ae2..550371ca 100644
--- a/services/network/websocket_factory.h
+++ b/services/network/websocket_factory.h
@@ -46,12 +46,13 @@
       const net::IsolationInfo& isolation_info,
       std::vector<mojom::HttpHeaderPtr> additional_headers,
       int32_t process_id,
-      int32_t render_frame_id,
       const url::Origin& origin,
       uint32_t options,
       net::NetworkTrafficAnnotationTag traffic_annotation,
       mojo::PendingRemote<mojom::WebSocketHandshakeClient> handshake_client,
-      mojo::PendingRemote<mojom::AuthenticationHandler> auth_handler,
+      mojo::PendingRemote<mojom::AuthenticationAndCertificateObserver>
+          auth_cert_observer,
+      mojo::PendingRemote<mojom::WebSocketAuthenticationHandler> auth_handler,
       mojo::PendingRemote<mojom::TrustedHeaderClient> header_client);
 
   // Returns a URLRequestContext associated with this factory.
diff --git a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc
index 8b4fea1..3ed89e3 100644
--- a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc
+++ b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc
@@ -120,6 +120,11 @@
         annotation->set_string_value(value.as_string ? value.as_string
                                                      : "NULL");
         break;
+      case TRACE_VALUE_TYPE_PROTO: {
+        auto data = value.as_proto->SerializeAsArray();
+        annotation->AppendRawProtoBytes(data.data(), data.size());
+      } break;
+
       default:
         NOTREACHED() << "Don't know how to serialize this value";
         break;
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json
index c1eae3e..813faec5 100644
--- a/testing/buildbot/chromium.perf.json
+++ b/testing/buildbot/chromium.perf.json
@@ -1102,6 +1102,12 @@
       "chromium_builder_perf"
     ]
   },
+  "linux-builder-perf-rel": {
+    "additional_compile_targets": [
+      "chromedriver",
+      "chromium_builder_perf"
+    ]
+  },
   "linux-perf": {
     "isolated_scripts": [
       {
@@ -1152,6 +1158,52 @@
       }
     ]
   },
+  "linux-perf-rel": {
+    "isolated_scripts": [
+      {
+        "args": [
+          "-v",
+          "--browser=release",
+          "--upload-results",
+          "--test-shard-map-filename=linux-perf-rel_map.json",
+          "--assert-gpu-compositing"
+        ],
+        "isolate_name": "performance_test_suite",
+        "merge": {
+          "script": "//tools/perf/process_perf_results.py"
+        },
+        "name": "performance_test_suite",
+        "override_compile_targets": [
+          "performance_test_suite"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:1cb3-440.100",
+              "os": "Ubuntu-18.04",
+              "pool": "chrome.tests.perf",
+              "synthetic_product_name": "PowerEdge R230 (Dell Inc.)"
+            }
+          ],
+          "expiration": 7200,
+          "hard_timeout": 21600,
+          "ignore_task_failure": false,
+          "io_timeout": 21600,
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "trigger_script": {
+          "args": [
+            "--multiple-dimension-script-verbose",
+            "True"
+          ],
+          "requires_simultaneous_shard_dispatch": true,
+          "script": "//testing/trigger_scripts/perf_device_trigger.py"
+        }
+      }
+    ]
+  },
   "linux-processor-perf": {
     "merge": {
       "args": [
@@ -1406,8 +1458,8 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
-              "gpu": "8086:5912-23.20.16.4877",
-              "os": "Windows-10-16299.309",
+              "gpu": "8086:5912-27.20.100.8681",
+              "os": "Windows-10-18363.476",
               "pool": "chrome.tests.perf",
               "synthetic_product_name": "OptiPlex 7050 (Dell Inc.)"
             }
diff --git a/testing/scripts/check_static_initializers.py b/testing/scripts/check_static_initializers.py
index 8366dbb..e8f3be4 100755
--- a/testing/scripts/check_static_initializers.py
+++ b/testing/scripts/check_static_initializers.py
@@ -19,7 +19,8 @@
         'InstrProfilingRuntime.cpp',  # Only in coverage builds, not production.
         'atomicops_internals_x86.cc',  # TODO(crbug.com/973551): Remove.
         'debugallocation_shim.cc',  # TODO(crbug.com/973552): Remove.
-        'iostream.cpp',  # TODO(crbug.com/973554): Remove.
+        'iostream.cpp:',  # TODO(crbug.com/973554): Remove.
+        '000101',   # libc++ uses init_priority 101 for iostreams.
         'spinlock.cc',  # TODO(crbug.com/973556): Remove.
     ],
     'nacl_helper_bootstrap': [],
@@ -34,7 +35,8 @@
         'InstrProfilingRuntime.cpp',  # Only in coverage builds, not production.
         'atomicops_internals_x86.cc',  # TODO(crbug.com/973551): Remove.
         'debugallocation_shim.cc',  # TODO(crbug.com/973552): Remove.
-        'iostream.cpp',  # TODO(crbug.com/973554): Remove.
+        'iostream.cpp:',  # TODO(crbug.com/973554): Remove.
+        '000101',   # libc++ uses init_priority 101 for iostreams.
         'spinlock.cc',  # TODO(crbug.com/973556): Remove.
         'rpc.pb.cc',  # TODO(crbug.com/537099): Remove.
     ],
@@ -48,14 +50,16 @@
     'InstrProfilingRuntime.cpp', # Only in coverage builds, not in production.
     'sysinfo.cc', # Only in coverage builds, not in production.
     'iostream.cpp', # Used to setup std::cin/cout/cerr.
+    '000101', # Used to setup std::cin/cout/cerr
 ]
 
-# A static initializer is needed on Mac for libc++ to set up std::cin/cout/cerr
-# before main() runs. Only iostream.cpp needs to be counted here.
-FALLBACK_EXPECTED_MAC_SI_COUNT = 1
+# Two static initializers are needed on Mac for libc++ to set up
+# std::cin/cout/cerr before main() runs. Only iostream.cpp needs to be counted
+# here.
+FALLBACK_EXPECTED_MAC_SI_COUNT = 2
 
 # For coverage builds, also allow 'IntrProfilingRuntime.cpp'
-COVERAGE_BUILD_FALLBACK_EXPECTED_MAC_SI_COUNT = 2;
+COVERAGE_BUILD_FALLBACK_EXPECTED_MAC_SI_COUNT = 3
 
 
 def run_process(command):
diff --git a/third_party/abseil-cpp/symbols_arm64_dbg.def b/third_party/abseil-cpp/symbols_arm64_dbg.def
index be9681d..3eb6ce74 100644
--- a/third_party/abseil-cpp/symbols_arm64_dbg.def
+++ b/third_party/abseil-cpp/symbols_arm64_dbg.def
@@ -2,13 +2,6 @@
     ??$?0$$CBD$0A@@VoidPtr@str_format_internal@absl@@QEAA@PEBD@Z
     ??$?0$$CBU?$atomic@_N@__1@std@@@Condition@absl@@QEAA@P6A_NPEBU?$atomic@_N@__1@std@@@Z0@Z
     ??$?0$$CBVFormatArgImpl@str_format_internal@absl@@$$CBV012@@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEAA@V?$initializer_list@VFormatArgImpl@str_format_internal@absl@@@std@@@Z
-    ??$?0$$T$00@?$__compressed_pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PEAPEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PEAUTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PEAUTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PEAUViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PEAVFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T@Z
     ??$?0$$T@?$Storage@PEAH$00$0A@@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@3@$$QEA$$T@Z
     ??$?0$$T@?$Storage@PEAPEAUCordRep@cord_internal@absl@@$00$0A@@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@3@$$QEA$$T@Z
     ??$?0$$T@?$Storage@PEAPEBUCordRep@cord_internal@absl@@$00$0A@@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@3@$$QEA$$T@Z
@@ -20,6 +13,13 @@
     ??$?0$$TAEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@?$__compressed_pair@PEAUTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$TAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
     ??$?0$$TAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@?$__compressed_pair@PEAUTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$TAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
     ??$?0$$TAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@?$__compressed_pair@PEAUViableSubstitution@strings_internal@absl@@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$TAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T$$QEAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PEAPEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T$$QEAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T$$QEAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PEAUTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T$$QEAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PEAUTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T$$QEAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PEAUViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T$$QEAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PEAVFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T$$QEAU__default_init_tag@12@@Z
     ??$?0$$TX@?$__compressed_pair_elem@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@$$QEA$$T@Z
     ??$?0$$TX@?$__compressed_pair_elem@PEAPEAUCordRep@cord_internal@absl@@$0A@$0A@@__1@std@@QEAA@$$QEA$$T@Z
     ??$?0$$TX@?$__compressed_pair_elem@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@$0A@@__1@std@@QEAA@$$QEA$$T@Z
@@ -49,15 +49,15 @@
     ??$?0AEAPEAUCordRep@cord_internal@absl@@AEAPEAU012@$0A@@?$pair@PEAUCordRep@cord_internal@absl@@PEAU123@@__1@std@@QEAA@AEAPEAUCordRep@cord_internal@absl@@0@Z
     ??$?0AEAPEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@?$__compressed_pair@PEAUThreadIdentity@base_internal@absl@@P6AXPEAX@Z@__1@std@@QEAA@AEAPEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@Z
     ??$?0AEAPEAUThreadIdentity@base_internal@absl@@X@?$__compressed_pair_elem@PEAUThreadIdentity@base_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAUThreadIdentity@base_internal@absl@@@Z
-    ??$?0AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$00@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
+    ??$?0AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$QEAU__default_init_tag@12@@Z
     ??$?0AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@X@?$__compressed_pair_elem@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
-    ??$?0AEAPEAVTimeZoneIf@cctz@time_internal@absl@@$00@?$__compressed_pair@PEAVTimeZoneIf@cctz@time_internal@absl@@U?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAVTimeZoneIf@cctz@time_internal@absl@@@Z
+    ??$?0AEAPEAVTimeZoneIf@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEAVTimeZoneIf@cctz@time_internal@absl@@U?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAVTimeZoneIf@cctz@time_internal@absl@@$$QEAU__default_init_tag@12@@Z
     ??$?0AEAPEAVTimeZoneIf@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PEAVTimeZoneIf@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAVTimeZoneIf@cctz@time_internal@absl@@@Z
-    ??$?0AEAPEAVTimeZoneInfo@cctz@time_internal@absl@@$00@?$__compressed_pair@PEAVTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAVTimeZoneInfo@cctz@time_internal@absl@@@Z
+    ??$?0AEAPEAVTimeZoneInfo@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEAVTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAVTimeZoneInfo@cctz@time_internal@absl@@$$QEAU__default_init_tag@12@@Z
     ??$?0AEAPEAVTimeZoneInfo@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PEAVTimeZoneInfo@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAVTimeZoneInfo@cctz@time_internal@absl@@@Z
-    ??$?0AEAPEAVZoneInfoSource@cctz@time_internal@absl@@$00@?$__compressed_pair@PEAVZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAVZoneInfoSource@cctz@time_internal@absl@@@Z
+    ??$?0AEAPEAVZoneInfoSource@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEAVZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAVZoneInfoSource@cctz@time_internal@absl@@$$QEAU__default_init_tag@12@@Z
     ??$?0AEAPEAVZoneInfoSource@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PEAVZoneInfoSource@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAVZoneInfoSource@cctz@time_internal@absl@@@Z
-    ??$?0AEAPEBVImpl@time_zone@cctz@time_internal@absl@@$00@?$__compressed_pair@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
+    ??$?0AEAPEBVImpl@time_zone@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAU__default_init_tag@12@@Z
     ??$?0AEAPEBVImpl@time_zone@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PEBVImpl@time_zone@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??$?0AEAV?$allocator@H@__1@std@@$$T$00@?$CompressedTuple@V?$allocator@H@__1@std@@PEAH@container_internal@absl@@QEAA@AEAV?$allocator@H@__1@std@@$$QEA$$T@Z
     ??$?0AEAV?$allocator@H@__1@std@@$$T@?$CompressedTupleImpl@V?$CompressedTuple@V?$allocator@H@__1@std@@PEAH@container_internal@absl@@U?$integer_sequence@_K$0A@$00@3@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@3@AEAV?$allocator@H@__1@std@@$$QEA$$T@Z
@@ -94,20 +94,20 @@
     ??$?0AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$$Z$$V@?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAA@Upiecewise_construct_t@12@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@V?$tuple@$$V@12@@Z
     ??$?0AEBVCord@absl@@$0A@@?$optional@VCord@absl@@@absl@@QEAA@AEBVCord@1@@Z
     ??$?0AEBVCord@absl@@@?$optional_data_dtor_base@VCord@absl@@$0A@@optional_internal@absl@@IEAA@Uin_place_t@2@AEBVCord@2@@Z
-    ??$?0H$00@?$__compressed_pair@_KV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAA@$$QEAH@Z
-    ??$?0H$00@?$__compressed_pair@_KV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEAA@$$QEAH@Z
-    ??$?0H$00@?$__compressed_pair@_KV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEAH@Z
     ??$?0H@?$Storage@_K$00$0A@@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@3@$$QEAH@Z
     ??$?0H@FormatArgImpl@str_format_internal@absl@@QEAA@AEBH@Z
-    ??$?0M$00@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAA@$$QEAM@Z
-    ??$?0PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@$00@?$__compressed_pair@PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@23@@__1@std@@QEAA@$$QEAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@@Z
+    ??$?0HU__default_init_tag@__1@std@@@?$__compressed_pair@_KV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAA@$$QEAH$$QEAU__default_init_tag@12@@Z
+    ??$?0HU__default_init_tag@__1@std@@@?$__compressed_pair@_KV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEAA@$$QEAH$$QEAU__default_init_tag@12@@Z
+    ??$?0HU__default_init_tag@__1@std@@@?$__compressed_pair@_KV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEAH$$QEAU__default_init_tag@12@@Z
+    ??$?0MU__default_init_tag@__1@std@@@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAA@$$QEAM$$QEAU__default_init_tag@12@@Z
+    ??$?0PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@U__default_init_tag@12@@?$__compressed_pair@PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@23@@__1@std@@QEAA@$$QEAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@$$QEAU__default_init_tag@12@@Z
     ??$?0PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@X@?$__compressed_pair_elem@PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@$0A@$0A@@__1@std@@QEAA@$$QEAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@@Z
     ??$?0PEAUTransition@cctz@time_internal@absl@@@?$__wrap_iter@PEBUTransition@cctz@time_internal@absl@@@__1@std@@QEAA@AEBV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@12@PEAX@Z
     ??$?0PEAUTransitionType@cctz@time_internal@absl@@@?$__wrap_iter@PEBUTransitionType@cctz@time_internal@absl@@@__1@std@@QEAA@AEBV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@12@PEAX@Z
-    ??$?0PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$00@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAA@$$QEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
     ??$?0PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAA@$$QEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$QEAU?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@12@@Z
+    ??$?0PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAA@$$QEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$QEAU__default_init_tag@12@@Z
     ??$?0PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@X@?$__compressed_pair_elem@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$0A@$0A@@__1@std@@QEAA@$$QEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
-    ??$?0PEAVZoneInfoSource@cctz@time_internal@absl@@$00@?$__compressed_pair@PEAVZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEAPEAVZoneInfoSource@cctz@time_internal@absl@@@Z
+    ??$?0PEAVZoneInfoSource@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEAVZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEAPEAVZoneInfoSource@cctz@time_internal@absl@@$$QEAU__default_init_tag@12@@Z
     ??$?0PEAVZoneInfoSource@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PEAVZoneInfoSource@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@$$QEAPEAVZoneInfoSource@cctz@time_internal@absl@@@Z
     ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@X@?$__compressed_pair_elem@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@$00$00@__1@std@@QEAA@$$QEAU?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@12@@Z
     ??$?0UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@$$V$00@?$CompressedTuple@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@container_internal@absl@@QEAA@$$QEAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@2@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@Z
@@ -438,39 +438,27 @@
     ??$UnhidePtr@X@base_internal@absl@@YAPEAX_K@Z
     ??$__advance@PEBUTransition@cctz@time_internal@absl@@@__1@std@@YAXAEAPEBUTransition@cctz@time_internal@absl@@_JUrandom_access_iterator_tag@01@@Z
     ??$__advance@PEBVFormatArgImpl@str_format_internal@absl@@@__1@std@@YAXAEAPEBVFormatArgImpl@str_format_internal@absl@@_JUrandom_access_iterator_tag@01@@Z
-    ??$__construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV12345@@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV56789@@Z
-    ??$__construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAPEAPEBV56789@@Z
-    ??$__construct@PEAUCordRep@cord_internal@absl@@AEBQEAU123@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@AEBQEAU567@@Z
-    ??$__construct@PEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV12345@@?$allocator_traits@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV56789@@Z
-    ??$__construct@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@PEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
-    ??$__construct@UConversionItem@ParsedFormatBase@str_format_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QEAU5678@@Z
-    ??$__construct@UTransition@cctz@time_internal@absl@@$$V@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@@Z
-    ??$__construct@UTransition@cctz@time_internal@absl@@AEBU1234@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@AEBU5678@@Z
-    ??$__construct@UTransition@cctz@time_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@$$QEAU5678@@Z
-    ??$__construct@UTransitionType@cctz@time_internal@absl@@$$V@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@@Z
-    ??$__construct@UTransitionType@cctz@time_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@$$QEAU5678@@Z
-    ??$__construct@UViableSubstitution@strings_internal@absl@@AEAVstring_view@3@AEBV43@AEA_K@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PEAUViableSubstitution@strings_internal@absl@@AEAVstring_view@7@AEBV87@AEA_K@Z
     ??$__construct_at_end@PEBQEAUCordRep@cord_internal@absl@@@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAXPEBQEAUCordRep@cord_internal@absl@@0_K@Z
     ??$__construct_at_end@PEBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAXPEBVFormatArgImpl@str_format_internal@absl@@0_K@Z
     ??$__construct_at_end@V?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXV?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
     ??$__construct_at_end@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__1@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@0@Z
     ??$__construct_at_end@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__1@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@0@Z
-    ??$__construct_backward_with_exception_guarantees@PEAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@1AEAPEAPEAU456@@Z
-    ??$__construct_backward_with_exception_guarantees@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@1AEAPEAU4567@@Z
-    ??$__construct_backward_with_exception_guarantees@UTransition@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@1AEAPEAU4567@@Z
-    ??$__construct_backward_with_exception_guarantees@UTransitionType@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@1AEAPEAU4567@@Z
-    ??$__construct_backward_with_exception_guarantees@UViableSubstitution@strings_internal@absl@@@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PEAUViableSubstitution@strings_internal@absl@@1AEAPEAU456@@Z
-    ??$__construct_forward_with_exception_guarantees@UTransition@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@1AEAPEAU4567@@Z
-    ??$__construct_forward_with_exception_guarantees@UTransitionType@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@1AEAPEAU4567@@Z
-    ??$__construct_node_hash@AEBUpiecewise_construct_t@__1@std@@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAA?AV?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@12@_KAEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@PEAUCordRep@cord_internal@absl@@X@__1@std@@YAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@01@PEAPEAUCordRep@cord_internal@absl@@1AEAPEAPEAU345@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@X@__1@std@@YAXAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@01@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@1AEAPEAU3456@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@UTransition@cctz@time_internal@absl@@X@__1@std@@YAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@01@PEAUTransition@cctz@time_internal@absl@@1AEAPEAU3456@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@UTransitionType@cctz@time_internal@absl@@X@__1@std@@YAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@01@PEAUTransitionType@cctz@time_internal@absl@@1AEAPEAU3456@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@UViableSubstitution@strings_internal@absl@@X@__1@std@@YAXAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@01@PEAUViableSubstitution@strings_internal@absl@@1AEAPEAU345@@Z
+    ??$__construct_forward_with_exception_guarantees@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@PEAUTransition@cctz@time_internal@absl@@@__1@std@@YAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@01@PEAUTransition@cctz@time_internal@absl@@1AEAPEAU3456@@Z
+    ??$__construct_forward_with_exception_guarantees@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@PEAUTransitionType@cctz@time_internal@absl@@@__1@std@@YAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@01@PEAUTransitionType@cctz@time_internal@absl@@1AEAPEAU3456@@Z
+    ??$__construct_node_hash@AEBUpiecewise_construct_t@__1@std@@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAA?AV?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@12@_KAEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
     ??$__construct_one_at_end@$$V@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXXZ
     ??$__construct_one_at_end@$$V@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXXZ
     ??$__construct_one_at_end@AEAVstring_view@absl@@AEBV12@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@AEAAXAEAVstring_view@absl@@AEBV34@AEA_K@Z
     ??$__construct_one_at_end@AEBQEAUCordRep@cord_internal@absl@@@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAXAEBQEAUCordRep@cord_internal@absl@@@Z
     ??$__construct_one_at_end@AEBUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXAEBUTransition@cctz@time_internal@absl@@@Z
     ??$__construct_one_at_end@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAX$$QEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
-    ??$__construct_range_forward@$$CBVFormatArgImpl@str_format_internal@absl@@V123@V123@V123@@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PEBVFormatArgImpl@str_format_internal@absl@@1AEAPEAV456@@Z
-    ??$__construct_range_forward@QEAUCordRep@cord_internal@absl@@PEAU123@PEAU123@PEAU123@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEBQEAUCordRep@cord_internal@absl@@1AEAPEAPEAU456@@Z
+    ??$__construct_range_forward@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@QEAUCordRep@cord_internal@absl@@PEAU456@PEAU456@PEAU456@X@__1@std@@YAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@01@PEBQEAUCordRep@cord_internal@absl@@1AEAPEAPEAU345@@Z
+    ??$__construct_range_forward@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@$$CBVFormatArgImpl@str_format_internal@absl@@V456@V456@V456@X@__1@std@@YAXAEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@01@PEBVFormatArgImpl@str_format_internal@absl@@1AEAPEAV345@@Z
     ??$__copy@$$CBVFormatArgImpl@str_format_internal@absl@@V123@@__1@std@@YAPEAVFormatArgImpl@str_format_internal@absl@@PEBV234@0PEAV234@@Z
     ??$__cxx_atomic_compare_exchange_weak@PEAUHashtablezInfo@container_internal@absl@@@__1@std@@YA_NPEAU?$__cxx_atomic_base_impl@PEAUHashtablezInfo@container_internal@absl@@@01@PEAPEAUHashtablezInfo@container_internal@absl@@PEAU345@W4memory_order@01@3@Z
     ??$__cxx_atomic_exchange@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@__1@std@@YAP6AXAEBUHashtablezInfo@container_internal@absl@@@ZPEAU?$__cxx_atomic_base_impl@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@01@P6AX0@ZW4memory_order@01@@Z
@@ -480,14 +468,6 @@
     ??$__cxx_atomic_load@W4State@PerThreadSynch@base_internal@absl@@@__1@std@@YA?AW4State@PerThreadSynch@base_internal@absl@@PEBU?$__cxx_atomic_base_impl@W4State@PerThreadSynch@base_internal@absl@@@01@W4memory_order@01@@Z
     ??$__cxx_atomic_store@W4OnDeadlockCycle@absl@@@__1@std@@YAXPEAU?$__cxx_atomic_base_impl@W4OnDeadlockCycle@absl@@@01@W4OnDeadlockCycle@absl@@W4memory_order@01@@Z
     ??$__cxx_atomic_store@W4State@PerThreadSynch@base_internal@absl@@@__1@std@@YAXPEAU?$__cxx_atomic_base_impl@W4State@PerThreadSynch@base_internal@absl@@@01@W4State@PerThreadSynch@base_internal@absl@@W4memory_order@01@@Z
-    ??$__destroy@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
-    ??$__destroy@PEAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@@Z
-    ??$__destroy@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$0A@@12@AEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@PEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
-    ??$__destroy@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
-    ??$__destroy@UTransition@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@@Z
-    ??$__destroy@UTransitionType@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@@Z
-    ??$__destroy@UViableSubstitution@strings_internal@absl@@@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PEAUViableSubstitution@strings_internal@absl@@@Z
-    ??$__destroy@VFormatArgImpl@str_format_internal@absl@@@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PEAVFormatArgImpl@str_format_internal@absl@@@Z
     ??$__distance@PEBUPayload@status_internal@absl@@@__1@std@@YA_JPEBUPayload@status_internal@absl@@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@PEBUTransition@cctz@time_internal@absl@@@__1@std@@YA_JPEBUTransition@cctz@time_internal@absl@@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@PEBVFormatArgImpl@str_format_internal@absl@@@__1@std@@YA_JPEBVFormatArgImpl@str_format_internal@absl@@0Urandom_access_iterator_tag@01@@Z
@@ -495,7 +475,7 @@
     ??$__distance@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@YA_JV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@01@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@YA_JV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@01@0Urandom_access_iterator_tag@01@@Z
     ??$__emplace_back_slow_path@AEAVstring_view@absl@@AEBV12@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@AEAAXAEAVstring_view@absl@@AEBV34@AEA_K@Z
-    ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@_N@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
+    ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@_N@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
     ??$__lower_bound@AEAUByUnixTime@Transition@cctz@time_internal@absl@@PEBU2345@U2345@@__1@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@AEAUByUnixTime@2345@@Z
     ??$__move@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@@__1@std@@YAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV23456@00@Z
     ??$__move@UTransition@cctz@time_internal@absl@@U1234@@__1@std@@YAPEAUTransition@cctz@time_internal@absl@@PEAU2345@00@Z
@@ -506,13 +486,13 @@
     ??$__push_back_slow_path@AEBQEAUCordRep@cord_internal@absl@@@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAXAEBQEAUCordRep@cord_internal@absl@@@Z
     ??$__push_back_slow_path@AEBUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXAEBUTransition@cctz@time_internal@absl@@@Z
     ??$__push_back_slow_path@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAX$$QEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
-    ??$__to_raw_pointer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV23456@@Z
-    ??$__to_raw_pointer@PEAUCordRep@cord_internal@absl@@@__1@std@@YAPEAPEAUCordRep@cord_internal@absl@@PEAPEAU234@@Z
-    ??$__to_raw_pointer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@YAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@PEAU2345@@Z
-    ??$__to_raw_pointer@UTransition@cctz@time_internal@absl@@@__1@std@@YAPEAUTransition@cctz@time_internal@absl@@PEAU2345@@Z
-    ??$__to_raw_pointer@UTransitionType@cctz@time_internal@absl@@@__1@std@@YAPEAUTransitionType@cctz@time_internal@absl@@PEAU2345@@Z
-    ??$__to_raw_pointer@UViableSubstitution@strings_internal@absl@@@__1@std@@YAPEAUViableSubstitution@strings_internal@absl@@PEAU234@@Z
-    ??$__to_raw_pointer@VFormatArgImpl@str_format_internal@absl@@@__1@std@@YAPEAVFormatArgImpl@str_format_internal@absl@@PEAV234@@Z
+    ??$__to_address@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV23456@@Z
+    ??$__to_address@PEAUCordRep@cord_internal@absl@@@__1@std@@YAPEAPEAUCordRep@cord_internal@absl@@PEAPEAU234@@Z
+    ??$__to_address@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@YAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@PEAU2345@@Z
+    ??$__to_address@UTransition@cctz@time_internal@absl@@@__1@std@@YAPEAUTransition@cctz@time_internal@absl@@PEAU2345@@Z
+    ??$__to_address@UTransitionType@cctz@time_internal@absl@@@__1@std@@YAPEAUTransitionType@cctz@time_internal@absl@@PEAU2345@@Z
+    ??$__to_address@UViableSubstitution@strings_internal@absl@@@__1@std@@YAPEAUViableSubstitution@strings_internal@absl@@PEAU234@@Z
+    ??$__to_address@VFormatArgImpl@str_format_internal@absl@@@__1@std@@YAPEAVFormatArgImpl@str_format_internal@absl@@PEAV234@@Z
     ??$__unwrap_iter@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV23456@@Z
     ??$__unwrap_iter@PEAUTransition@cctz@time_internal@absl@@@__1@std@@YAPEAUTransition@cctz@time_internal@absl@@PEAU2345@@Z
     ??$__unwrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@__1@std@@YAPEAUTransitionType@cctz@time_internal@absl@@PEAU2345@@Z
@@ -532,8 +512,8 @@
     ??$addressof@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@YAPEAV?$allocator@PEBUCordRep@cord_internal@absl@@@01@AEAV201@@Z
     ??$addressof@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@__1@std@@YAPEAV?$allocator@UPayload@status_internal@absl@@@01@AEAV201@@Z
     ??$addressof@V?$allocator@USubRange@absl@@@__1@std@@@__1@std@@YAPEAV?$allocator@USubRange@absl@@@01@AEAV201@@Z
-    ??$advance@PEBUTransition@cctz@time_internal@absl@@@__1@std@@YAXAEAPEBUTransition@cctz@time_internal@absl@@_J@Z
-    ??$advance@PEBVFormatArgImpl@str_format_internal@absl@@@__1@std@@YAXAEAPEBVFormatArgImpl@str_format_internal@absl@@_J@Z
+    ??$advance@PEBUTransition@cctz@time_internal@absl@@_J@__1@std@@YAXAEAPEBUTransition@cctz@time_internal@absl@@_J@Z
+    ??$advance@PEBVFormatArgImpl@str_format_internal@absl@@_K@__1@std@@YAXAEAPEBVFormatArgImpl@str_format_internal@absl@@_K@Z
     ??$assign@PEBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QEAAXPEBVFormatArgImpl@str_format_internal@absl@@0@Z
     ??$assign@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$optional_data_base@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@optional_internal@absl@@IEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$bit_cast@_J_K$0A@@absl@@YA_JAEB_K@Z
@@ -542,12 +522,12 @@
     ??$construct@HAEBH@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@SAXAEAV?$allocator@H@__1@std@@PEAHAEBH@Z
     ??$construct@HH@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@SAXAEAV?$allocator@H@__1@std@@PEAH$$QEAH@Z
     ??$construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV12345@@?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV34567@@Z
-    ??$construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV12345@@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV45678@@Z
+    ??$construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV12345@X@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV45678@@Z
     ??$construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@@?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAPEAPEBV34567@@Z
-    ??$construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAPEAPEBV45678@@Z
+    ??$construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@X@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAPEAPEBV45678@@Z
     ??$construct@PEAUCordRep@cord_internal@absl@@AEBQEAU123@@?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@QEAAXPEAPEAUCordRep@cord_internal@absl@@AEBQEAU345@@Z
-    ??$construct@PEAUCordRep@cord_internal@absl@@AEBQEAU123@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@AEBQEAU456@@Z
     ??$construct@PEAUCordRep@cord_internal@absl@@AEBQEAU123@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@PEAPEAUCordRep@cord_internal@1@AEBQEAU561@@Z
+    ??$construct@PEAUCordRep@cord_internal@absl@@AEBQEAU123@X@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@AEBQEAU456@@Z
     ??$construct@PEAUCordRep@cord_internal@absl@@PEAU123@@?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@QEAAXPEAPEAUCordRep@cord_internal@absl@@$$QEAPEAU345@@Z
     ??$construct@PEAUCordRep@cord_internal@absl@@PEAU123@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@PEAPEAUCordRep@cord_internal@1@$$QEAPEAU561@@Z
     ??$construct@PEBUCordRep@cord_internal@absl@@AEBQEBU123@@?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@QEAAXPEAPEBUCordRep@cord_internal@absl@@AEBQEBU345@@Z
@@ -555,11 +535,11 @@
     ??$construct@PEBUCordRep@cord_internal@absl@@PEBU123@@?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@QEAAXPEAPEBUCordRep@cord_internal@absl@@$$QEAPEBU345@@Z
     ??$construct@PEBUCordRep@cord_internal@absl@@PEBU123@@?$allocator_traits@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@PEAPEBUCordRep@cord_internal@1@$$QEAPEBU561@@Z
     ??$construct@PEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV12345@@?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAAXPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV34567@@Z
-    ??$construct@PEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV12345@@?$allocator_traits@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV45678@@Z
+    ??$construct@PEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV12345@X@?$allocator_traits@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV45678@@Z
     ??$construct@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@QEAAXPEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
-    ??$construct@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@SAXAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@PEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
+    ??$construct@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@X@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@SAXAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@PEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
     ??$construct@UConversionItem@ParsedFormatBase@str_format_internal@absl@@U1234@@?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QEAU3456@@Z
-    ??$construct@UConversionItem@ParsedFormatBase@str_format_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QEAU4567@@Z
+    ??$construct@UConversionItem@ParsedFormatBase@str_format_internal@absl@@U1234@X@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QEAU4567@@Z
     ??$construct@UPayload@status_internal@absl@@AEBU123@@?$allocator@UPayload@status_internal@absl@@@__1@std@@QEAAXPEAUPayload@status_internal@absl@@AEBU345@@Z
     ??$construct@UPayload@status_internal@absl@@AEBU123@@?$allocator_traits@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@UPayload@status_internal@absl@@@__1@std@@PEAUPayload@status_internal@1@AEBU561@@Z
     ??$construct@UPayload@status_internal@absl@@U123@@?$allocator@UPayload@status_internal@absl@@@__1@std@@QEAAXPEAUPayload@status_internal@absl@@$$QEAU345@@Z
@@ -567,17 +547,17 @@
     ??$construct@USubRange@absl@@U12@@?$allocator@USubRange@absl@@@__1@std@@QEAAXPEAUSubRange@absl@@$$QEAU34@@Z
     ??$construct@USubRange@absl@@U12@@?$allocator_traits@V?$allocator@USubRange@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@USubRange@absl@@@__1@std@@PEAUSubRange@1@$$QEAU51@@Z
     ??$construct@UTransition@cctz@time_internal@absl@@$$V@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
-    ??$construct@UTransition@cctz@time_internal@absl@@$$V@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@@Z
+    ??$construct@UTransition@cctz@time_internal@absl@@$$VX@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@@Z
     ??$construct@UTransition@cctz@time_internal@absl@@AEBU1234@@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@AEBU3456@@Z
-    ??$construct@UTransition@cctz@time_internal@absl@@AEBU1234@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@AEBU4567@@Z
+    ??$construct@UTransition@cctz@time_internal@absl@@AEBU1234@X@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@AEBU4567@@Z
     ??$construct@UTransition@cctz@time_internal@absl@@U1234@@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@$$QEAU3456@@Z
-    ??$construct@UTransition@cctz@time_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@$$QEAU4567@@Z
+    ??$construct@UTransition@cctz@time_internal@absl@@U1234@X@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@$$QEAU4567@@Z
     ??$construct@UTransitionType@cctz@time_internal@absl@@$$V@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
-    ??$construct@UTransitionType@cctz@time_internal@absl@@$$V@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@@Z
+    ??$construct@UTransitionType@cctz@time_internal@absl@@$$VX@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@@Z
     ??$construct@UTransitionType@cctz@time_internal@absl@@U1234@@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@$$QEAU3456@@Z
-    ??$construct@UTransitionType@cctz@time_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@$$QEAU4567@@Z
+    ??$construct@UTransitionType@cctz@time_internal@absl@@U1234@X@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@$$QEAU4567@@Z
     ??$construct@UViableSubstitution@strings_internal@absl@@AEAVstring_view@3@AEBV43@AEA_K@?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@AEAVstring_view@5@AEBV65@AEA_K@Z
-    ??$construct@UViableSubstitution@strings_internal@absl@@AEAVstring_view@3@AEBV43@AEA_K@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PEAUViableSubstitution@strings_internal@absl@@AEAVstring_view@6@AEBV76@AEA_K@Z
+    ??$construct@UViableSubstitution@strings_internal@absl@@AEAVstring_view@3@AEBV43@AEA_KX@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PEAUViableSubstitution@strings_internal@absl@@AEAVstring_view@6@AEBV76@AEA_K@Z
     ??$construct@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$optional_data_base@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@optional_internal@absl@@IEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$construct_impl@V?$allocator@H@__1@std@@AEAPEAHAEBH@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@CAXHAEAV?$allocator@H@__1@std@@AEAPEAHAEBH@Z
     ??$construct_impl@V?$allocator@H@__1@std@@AEAPEAHH@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@CAXHAEAV?$allocator@H@__1@std@@AEAPEAH$$QEAH@Z
@@ -591,18 +571,18 @@
     ??$copy@PEBVFormatArgImpl@str_format_internal@absl@@PEAV123@@__1@std@@YAPEAVFormatArgImpl@str_format_internal@absl@@PEBV234@0PEAV234@@Z
     ??$countl_zero@_K@absl@@YAH_K@Z
     ??$destroy@H@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@SAXAEAV?$allocator@H@__1@std@@PEAH@Z
-    ??$destroy@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
-    ??$destroy@PEAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@@Z
+    ??$destroy@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@X@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??$destroy@PEAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@PEAPEAUCordRep@cord_internal@1@@Z
+    ??$destroy@PEAUCordRep@cord_internal@absl@@X@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@@Z
     ??$destroy@PEBUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@PEAPEBUCordRep@cord_internal@1@@Z
-    ??$destroy@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@SAXAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@PEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
-    ??$destroy@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+    ??$destroy@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@XX@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@SAXAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@PEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
+    ??$destroy@UConversionItem@ParsedFormatBase@str_format_internal@absl@@X@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ??$destroy@UPayload@status_internal@absl@@@?$allocator_traits@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@UPayload@status_internal@absl@@@__1@std@@PEAUPayload@status_internal@1@@Z
     ??$destroy@USubRange@absl@@@?$allocator_traits@V?$allocator@USubRange@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@USubRange@absl@@@__1@std@@PEAUSubRange@1@@Z
-    ??$destroy@UTransition@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@@Z
-    ??$destroy@UTransitionType@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@@Z
-    ??$destroy@UViableSubstitution@strings_internal@absl@@@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PEAUViableSubstitution@strings_internal@absl@@@Z
-    ??$destroy@VFormatArgImpl@str_format_internal@absl@@@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PEAVFormatArgImpl@str_format_internal@absl@@@Z
+    ??$destroy@UTransition@cctz@time_internal@absl@@X@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@@Z
+    ??$destroy@UTransitionType@cctz@time_internal@absl@@X@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@@Z
+    ??$destroy@UViableSubstitution@strings_internal@absl@@X@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PEAUViableSubstitution@strings_internal@absl@@@Z
+    ??$destroy@VFormatArgImpl@str_format_internal@absl@@X@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PEAVFormatArgImpl@str_format_internal@absl@@@Z
     ??$destroy_impl@V?$allocator@H@__1@std@@H@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@CAXHAEAV?$allocator@H@__1@std@@PEAH@Z
     ??$destroy_impl@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@PEAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@CAXHAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@PEAPEAUCordRep@cord_internal@1@@Z
     ??$destroy_impl@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@PEBUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@absl@@CAXHAEAV?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@PEAPEBUCordRep@cord_internal@1@@Z
@@ -626,7 +606,7 @@
     ??$emplace_back@PEAUCordRep@cord_internal@absl@@@?$InlinedVector@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAAEAPEAUCordRep@cord_internal@1@$$QEAPEAU231@@Z
     ??$emplace_back@UPayload@status_internal@absl@@@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEAAAEAUPayload@status_internal@1@$$QEAU231@@Z
     ??$emplace_back@USubRange@absl@@@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QEAAAEAUSubRange@1@$$QEAU21@@Z
-    ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
+    ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??$forward@$$T@absl@@YA$$QEA$$TAEA$$T@Z
     ??$forward@AEAI@absl@@YAAEAIAEAI@Z
     ??$forward@AEAPEAPEAUCordRep@cord_internal@absl@@@__1@std@@YAAEAPEAPEAUCordRep@cord_internal@absl@@AEAPEAPEAU234@@Z
@@ -738,6 +718,19 @@
     ??$make_pair@AEAPEAUCordRep@cord_internal@absl@@AEAPEAU123@@__1@std@@YA?AU?$pair@PEAUCordRep@cord_internal@absl@@PEAU123@@01@AEAPEAUCordRep@cord_internal@absl@@0@Z
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$V@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@XZ
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@AEAV12@@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@AEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
+    ??$max_size@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@X@?$allocator_traits@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@12@@Z
+    ??$max_size@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@PEAUCordRep@cord_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@PEBUCordRep@cord_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@X@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@@Z
+    ??$max_size@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@UPayload@status_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UPayload@status_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@USubRange@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@USubRange@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@USubRange@absl@@@12@@Z
+    ??$max_size@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@@Z
     ??$min@VDuration@absl@@@__1@std@@YAAEBVDuration@absl@@AEBV23@0@Z
     ??$min@VDuration@absl@@U?$__less@VDuration@absl@@V12@@__1@std@@@__1@std@@YAAEBVDuration@absl@@AEBV23@0U?$__less@VDuration@absl@@V12@@01@@Z
     ??$move@AEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YA$$QEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAPEAPEAPEBV23456@@Z
@@ -829,20 +822,25 @@
     ??0?$__atomic_base@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z$0A@@__1@std@@QEAA@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@Z
     ??0?$__atomic_base@PEAUHashtablezInfo@container_internal@absl@@$0A@@__1@std@@QEAA@PEAUHashtablezInfo@container_internal@absl@@@Z
     ??0?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@U?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@$0A@$0A@@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
+    ??0?$__compressed_pair_elem@U?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@$0A@$0A@@__1@std@@QEAA@U__value_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@$00$00@__1@std@@QEAA@U__value_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
     ??0?$__cxx_atomic_base_impl@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@__1@std@@QEAA@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@Z
     ??0?$__cxx_atomic_base_impl@PEAUHashtablezInfo@container_internal@absl@@@__1@std@@QEAA@PEAUHashtablezInfo@container_internal@absl@@@Z
     ??0?$__cxx_atomic_impl@P6AXAEBUHashtablezInfo@container_internal@absl@@@ZU?$__cxx_atomic_base_impl@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@__1@std@@@__1@std@@QEAA@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@Z
@@ -855,7 +853,7 @@
     ??0?$__hash_map_iterator@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@QEAA@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@@Z
     ??0?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@QEAA@XZ
     ??0?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@QEAA@AEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@_N@Z
-    ??0?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA@XZ
+    ??0?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA@XZ
     ??0?$__policy_invoker@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z@__function@__1@std@@AEAA@P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@23@PEBT__policy_storage@123@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z@Z
     ??0?$__policy_invoker@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z@__function@__1@std@@QEAA@XZ
     ??0?$__policy_invoker@$$A6AXVstring_view@absl@@AEBVCord@2@@Z@__function@__1@std@@AEAA@P6AXPEBT__policy_storage@123@$$QEAVstring_view@absl@@AEBVCord@6@@Z@Z
@@ -867,8 +865,8 @@
     ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@_K0AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
     ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@_K0AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
     ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEAA@_K0AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
-    ??0?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEAA@XZ
-    ??0?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEAA@XZ
+    ??0?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEAA@XZ
+    ??0?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEAA@XZ
     ??0?$__vector_base@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@IEAA@XZ
     ??0?$__vector_base@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@IEAA@XZ
     ??0?$__vector_base@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@IEAA@XZ
@@ -1383,9 +1381,9 @@
     ??R?$__policy_func@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z@__function@__1@std@@QEBA?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@23@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z
     ??R?$__policy_func@$$A6AXAEBUHashtablezInfo@container_internal@absl@@@Z@__function@__1@std@@QEBAXAEBUHashtablezInfo@container_internal@absl@@@Z
     ??R?$__policy_func@$$A6AXVstring_view@absl@@AEBVCord@2@@Z@__function@__1@std@@QEBAX$$QEAVstring_view@absl@@AEBVCord@5@@Z
-    ??R?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEBA_NAEBU?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
-    ??R?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEBA_NAEBU?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
-    ??R?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEBA_KAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
+    ??R?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEBA_NAEBU?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
+    ??R?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEBA_NAEBU?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
+    ??R?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEBA_KAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??R?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEBAXPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??R?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@QEBAXPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
     ??R?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@QEBAXPEAVTimeZoneIf@cctz@time_internal@absl@@@Z
@@ -2453,7 +2451,7 @@
     ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z
     ?__construct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
     ?__construct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
-    ?__deallocate_node@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAXPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@@Z
+    ?__deallocate_node@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAXPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@@Z
     ?__destruct_at_begin@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ?__destruct_at_begin@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@U?$integral_constant@_N$00@23@@Z
     ?__destruct_at_end@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
@@ -2552,8 +2550,8 @@
     ?__get@?$__compressed_pair_elem@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QEAAAEAV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@23@XZ
     ?__get@?$__compressed_pair_elem@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QEBAAEBV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@23@XZ
     ?__get@?$__compressed_pair_elem@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QEAAAEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@XZ
-    ?__get@?$__compressed_pair_elem@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAAAEAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
-    ?__get@?$__compressed_pair_elem@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?__get@?$__compressed_pair_elem@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAAAEAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?__get@?$__compressed_pair_elem@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?__get@?$__compressed_pair_elem@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAAAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?__get@?$__compressed_pair_elem@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@$00$00@__1@std@@QEAAAEAV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@XZ
     ?__get@?$__compressed_pair_elem@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@$00$00@__1@std@@QEAAAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@23@XZ
@@ -2588,15 +2586,9 @@
     ?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AEBA?AV?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ?__make_iter@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAA?AV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@23@PEAUTransition@cctz@time_internal@absl@@@Z
     ?__make_iter@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAA?AV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@23@PEAUTransitionType@cctz@time_internal@absl@@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@CA_KU?$integral_constant@_N$00@23@AEBV?$allocator@PEAUCordRep@cord_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@CA_KU?$integral_constant@_N$00@23@AEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CA_KU?$integral_constant@_N$00@23@AEBV?$allocator@UTransition@cctz@time_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@CA_KU?$integral_constant@_N$00@23@AEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@CA_KU?$integral_constant@_N$00@23@AEBV?$allocator@UViableSubstitution@strings_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@CA_KU?$integral_constant@_N$00@23@AEBV?$allocator@VFormatArgImpl@str_format_internal@absl@@@23@@Z
     ?__move_range@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXPEAUTransition@cctz@time_internal@absl@@00@Z
     ?__move_range@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXPEAUTransitionType@cctz@time_internal@absl@@00@Z
-    ?__node_alloc@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
+    ?__node_alloc@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
     ?__ptr@?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@QEAAPEAU123@XZ
     ?__recommend@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEBA_K_K@Z
     ?__recommend@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AEBA_K_K@Z
@@ -2604,7 +2596,7 @@
     ?__recommend@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEBA_K_K@Z
     ?__recommend@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@AEBA_K_K@Z
     ?__recommend@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AEBA_K_K@Z
-    ?__rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAX_K@Z
+    ?__rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAX_K@Z
     ?__swap_out_circular_buffer@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAXAEAU?$__split_buffer@PEAUCordRep@cord_internal@absl@@AEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@23@@Z
     ?__swap_out_circular_buffer@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAXAEAU?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@23@@Z
     ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAPEAUTransition@cctz@time_internal@absl@@AEAU?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@23@PEAU4567@@Z
@@ -2625,19 +2617,19 @@
     ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Usecond_tag@1234@U51234@@Z
     ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Uyear_tag@1234@U51234@@Z
     ?alloc@Storage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@XZ
-    ?allocate@?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@QEAAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@_KPEBX@Z
-    ?allocate@?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@QEAAPEAPEAUCordRep@cord_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@QEAAPEAPEBUCordRep@cord_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@QEAAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@23@_KPEBX@Z
-    ?allocate@?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@UPayload@status_internal@absl@@@__1@std@@QEAAPEAUPayload@status_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@USubRange@absl@@@__1@std@@QEAAPEAUSubRange@absl@@_KPEBX@Z
-    ?allocate@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QEAAPEAUTransition@cctz@time_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@QEAAPEAVFormatArgImpl@str_format_internal@absl@@_KPEBX@Z
+    ?allocate@?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_K@Z
+    ?allocate@?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@QEAAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@_K@Z
+    ?allocate@?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@QEAAPEAPEAUCordRep@cord_internal@absl@@_K@Z
+    ?allocate@?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@QEAAPEAPEBUCordRep@cord_internal@absl@@_K@Z
+    ?allocate@?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_K@Z
+    ?allocate@?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@QEAAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@23@_K@Z
+    ?allocate@?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@_K@Z
+    ?allocate@?$allocator@UPayload@status_internal@absl@@@__1@std@@QEAAPEAUPayload@status_internal@absl@@_K@Z
+    ?allocate@?$allocator@USubRange@absl@@@__1@std@@QEAAPEAUSubRange@absl@@_K@Z
+    ?allocate@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QEAAPEAUTransition@cctz@time_internal@absl@@_K@Z
+    ?allocate@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@_K@Z
+    ?allocate@?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@_K@Z
+    ?allocate@?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@QEAAPEAVFormatArgImpl@str_format_internal@absl@@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@SAPEAHAEAV?$allocator@H@__1@std@@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@SAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@AEAV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@_K@Z
@@ -2688,7 +2680,7 @@
     ?begin@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEAAPEAUPayload@status_internal@2@XZ
     ?begin@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEBAPEBUPayload@status_internal@2@XZ
     ?begin@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEBAPEBVFormatArgImpl@str_format_internal@2@XZ
-    ?begin@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
+    ?begin@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
     ?begin@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?begin@?$initializer_list@PEAUCordRep@cord_internal@absl@@@std@@QEBAPEBQEAUCordRep@cord_internal@absl@@XZ
     ?begin@?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@QEBAPEBU?$pair@Vstring_view@absl@@V12@@__1@2@XZ
@@ -2702,7 +2694,7 @@
     ?begin@ChunkRange@Cord@absl@@QEBA?AVChunkIterator@23@XZ
     ?begin@Storage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEBAPEAPEAUCordRep@cord_internal@3@XZ
     ?begin@string_view@absl@@QEBAPEBDXZ
-    ?bucket_count@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEBA_KXZ
+    ?bucket_count@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEBA_KXZ
     ?capacity@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ
     ?capacity@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ
     ?capacity@?$__split_buffer@PEAUCordRep@cord_internal@absl@@AEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ
@@ -2725,7 +2717,7 @@
     ?capacity@CordRepRing@cord_internal@absl@@QEBAIXZ
     ?chunk_begin@Cord@absl@@QEBA?AVChunkIterator@12@XZ
     ?chunk_end@Cord@absl@@QEBA?AVChunkIterator@12@XZ
-    ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAXXZ
+    ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAXXZ
     ?clear@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ
     ?clear@?$__split_buffer@PEAUCordRep@cord_internal@absl@@AEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ
     ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ
@@ -2845,7 +2837,7 @@
     ?end@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEBAPEBUPayload@status_internal@2@XZ
     ?end@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEBAPEBVFormatArgImpl@str_format_internal@2@XZ
     ?end@?$__deque_base@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@IEAA?AV?$__deque_iterator@PEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@AEAPEBV12345@PEAPEAPEBV12345@_J$0A@@23@XZ
-    ?end@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
+    ?end@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
     ?end@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?end@?$initializer_list@PEAUCordRep@cord_internal@absl@@@std@@QEBAPEBQEAUCordRep@cord_internal@absl@@XZ
     ?end@?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@QEBAPEBU?$pair@Vstring_view@absl@@V12@@__1@2@XZ
@@ -2886,7 +2878,7 @@
     ?find_last_not_of@string_view@absl@@QEBA_KV12@_K@Z
     ?find_last_of@string_view@absl@@QEBA_KD_K@Z
     ?find_last_of@string_view@absl@@QEBA_KV12@_K@Z
-    ?first@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEAMXZ
+    ?first@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEAMXZ
     ?first@?$__compressed_pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?first@?$__compressed_pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBAAEBQEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?first@?$__compressed_pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
@@ -2931,7 +2923,7 @@
     ?first@?$__compressed_pair@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?first@?$__compressed_pair@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBAAEBQEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?first@?$__compressed_pair@U?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@@__1@std@@QEAAAEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
-    ?first@?$__compressed_pair@_KV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEA_KXZ
+    ?first@?$__compressed_pair@_KV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEA_KXZ
     ?first@?$__compressed_pair@_KV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEAAAEA_KXZ
     ?first@?$__compressed_pair@_KV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEBAAEB_KXZ
     ?first@?$__compressed_pair@_KV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEA_KXZ
@@ -2986,7 +2978,7 @@
     ?has_timeout@KernelTimeout@synchronization_internal@absl@@QEBA_NXZ
     ?has_value@?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@absl@@QEBA_NXZ
     ?has_zero_flag@FormatConversionSpecImpl@str_format_internal@absl@@QEBA_NXZ
-    ?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?head@CordRepRing@cord_internal@absl@@QEBAIXZ
     ?head@Filler@CordRepRing@cord_internal@absl@@QEBAIXZ
     ?hour@?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
@@ -3002,7 +2994,7 @@
     ?is_length@ConvTag@str_format_internal@absl@@QEBA_NXZ
     ?is_tree@InlineData@cord_internal@absl@@QEBA_NXZ
     ?is_tree@InlineRep@Cord@absl@@QEBA_NXZ
-    ?key_eq@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?key_eq@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?length@?$Span@D@absl@@QEBA_KXZ
     ?length@CordRepRingReader@cord_internal@absl@@QEBA_KXZ
     ?length@string_view@absl@@QEBA_KXZ
@@ -3019,7 +3011,7 @@
     ?max@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@SA?AV12345@XZ
     ?max@?$numeric_limits@Vint128@absl@@@__1@std@@SA?AVint128@absl@@XZ
     ?max@?$numeric_limits@Vuint128@absl@@@__1@std@@SA?AVuint128@absl@@XZ
-    ?max_load_factor@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAMXZ
+    ?max_load_factor@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAMXZ
     ?max_size@?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEBA_KXZ
     ?max_size@?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@QEBA_KXZ
     ?max_size@?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@QEBA_KXZ
@@ -3033,12 +3025,6 @@
     ?max_size@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QEBA_KXZ
     ?max_size@?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@QEBA_KXZ
     ?max_size@?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@QEBA_KXZ
-    ?max_size@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@PEAUCordRep@cord_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UTransition@cctz@time_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UViableSubstitution@strings_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@VFormatArgImpl@str_format_internal@absl@@@23@@Z
     ?max_size@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ
     ?max_size@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ
     ?max_size@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ
@@ -3111,7 +3097,7 @@
     ?rbegin@string_view@absl@@QEBA?AV?$reverse_iterator@PEBD@__1@std@@XZ
     ?reduce_size@InlineRep@Cord@absl@@QEAAX_K@Z
     ?reference@?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@absl@@AEAAAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ
-    ?rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAX_K@Z
+    ?rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAX_K@Z
     ?release@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?release@?$unique_ptr@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@@__1@std@@QEAAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?release@?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@__1@std@@QEAAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@23@XZ
@@ -3150,7 +3136,7 @@
     ?safe_strtou32_base@numbers_internal@absl@@YA_NVstring_view@2@PEAIH@Z
     ?safe_strtou64_base@numbers_internal@absl@@YA_NVstring_view@2@PEA_KH@Z
     ?scale_add@impl@detail@cctz@time_internal@absl@@YA_J_J00@Z
-    ?second@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?second@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?second@?$__compressed_pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?second@?$__compressed_pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?second@?$__compressed_pair@PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@23@@__1@std@@QEAAAEAV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@23@XZ
@@ -3181,7 +3167,7 @@
     ?second@?$__compressed_pair@PEAVZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAU?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@23@XZ
     ?second@?$__compressed_pair@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAU?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?second@?$__compressed_pair@U?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@@__1@std@@QEAAAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
-    ?second@?$__compressed_pair@_KV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?second@?$__compressed_pair@_KV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?second@?$__compressed_pair@_KV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEAAAEAV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@XZ
     ?second@?$__compressed_pair@_KV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?second@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
@@ -3214,7 +3200,7 @@
     ?size@?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEBA_KXZ
     ?size@?$__deque_base@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@IEAAAEA_KXZ
     ?size@?$__deque_base@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@IEBAAEB_KXZ
-    ?size@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAAEA_KXZ
+    ?size@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAAEA_KXZ
     ?size@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ
     ?size@?$initializer_list@PEAUCordRep@cord_internal@absl@@@std@@QEBA_KXZ
     ?size@?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@QEBA_KXZ
diff --git a/third_party/abseil-cpp/symbols_arm64_rel.def b/third_party/abseil-cpp/symbols_arm64_rel.def
index 718c8831..e0accc70 100644
--- a/third_party/abseil-cpp/symbols_arm64_rel.def
+++ b/third_party/abseil-cpp/symbols_arm64_rel.def
@@ -1,7 +1,6 @@
 EXPORTS
     ??$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$?4V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAAEAV01@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
-    ??$?BV?$allocator@D@__1@std@@@string_view@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ
     ??$?MUsecond_tag@detail@cctz@time_internal@absl@@U01234@@detail@cctz@time_internal@absl@@YA_NAEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@0@Z
     ??$?RW4LogSeverity@absl@@AEBQEBDHAEAPEBD@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@AEBQEBD$$QEAHAEAPEBD@Z
     ??$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV012@PEAV012@0_K1@Z
@@ -72,17 +71,19 @@
     ??$StrReplaceAll@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@@absl@@YAHAEBV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@2@@Z
     ??$ToChronoDuration@V?$duration@JV?$ratio@$0DM@$00@__1@std@@@chrono@__1@std@@@time_internal@absl@@YA?AV?$duration@JV?$ratio@$0DM@$00@__1@std@@@chrono@__1@std@@VDuration@1@@Z
     ??$ToChronoDuration@V?$duration@JV?$ratio@$0OBA@$00@__1@std@@@chrono@__1@std@@@time_internal@absl@@YA?AV?$duration@JV?$ratio@$0OBA@$00@__1@std@@@chrono@__1@std@@VDuration@1@@Z
+    ??$__construct_node_hash@AEBUpiecewise_construct_t@__1@std@@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAA?AV?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@12@_KAEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
     ??$__emplace_back_slow_path@AEAVstring_view@absl@@AEBV12@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@AEAAXAEAVstring_view@absl@@AEBV34@AEA_K@Z
-    ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@_N@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
+    ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@_N@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
     ??$__push_back_slow_path@AEBUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXAEBUTransition@cctz@time_internal@absl@@@Z
     ??$__upper_bound@AEAUByCivilTime@Transition@cctz@time_internal@absl@@PEBU2345@U2345@@__1@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@AEAUByCivilTime@2345@@Z
     ??$assign@PEBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QEAAXPEBVFormatArgImpl@str_format_internal@absl@@0@Z
     ??$assign@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$optional_data_base@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@optional_internal@absl@@IEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
+    ??$construct@UPayload@status_internal@absl@@AEBU123@@?$allocator@UPayload@status_internal@absl@@@__1@std@@QEAAXPEAUPayload@status_internal@absl@@AEBU345@@Z
     ??$emplace@$$V@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA?AV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@12@V?$__wrap_iter@PEBUTransition@cctz@time_internal@absl@@@12@@Z
     ??$emplace@$$V@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA?AV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@12@V?$__wrap_iter@PEBUTransitionType@cctz@time_internal@absl@@@12@@Z
     ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ
     ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ
-    ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
+    ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@Vstring_view@2@@Z
     ??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@XZ
     ??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@_K@Z
@@ -115,9 +116,7 @@
     ??0Rep@GraphCycles@synchronization_internal@absl@@QEAA@XZ
     ??0SpinLock@base_internal@absl@@QEAA@W4SchedulingMode@12@@Z
     ??0Status@absl@@QEAA@W4StatusCode@1@Vstring_view@1@@Z
-    ??0StatusRep@status_internal@absl@@QEAA@W4StatusCode@2@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@V?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@56@@Z
     ??0Streamable@str_format_internal@absl@@QEAA@AEBVUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
-    ??0TimeZoneInfo@cctz@time_internal@absl@@QEAA@XZ
     ??0TimeZoneLibC@cctz@time_internal@absl@@QEAA@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??0Waiter@synchronization_internal@absl@@QEAA@XZ
     ??0int128@absl@@QEAA@M@Z
@@ -757,12 +756,12 @@
     ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z
     ?__construct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
     ?__construct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
-    ?__deallocate_node@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAXPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@@Z
-    ?__rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAX_K@Z
+    ?__deallocate_node@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAXPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@@Z
+    ?__rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAX_K@Z
     ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAPEAUTransition@cctz@time_internal@absl@@AEAU?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@23@PEAU4567@@Z
     ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAPEAUTransitionType@cctz@time_internal@absl@@AEAU?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@23@PEAU4567@@Z
     ?__vallocate@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
-    ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAXXZ
+    ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAXXZ
     ?code@Status@absl@@QEBA?AW4StatusCode@2@XZ
     ?cord_ring_buffer_enabled@cord_internal@absl@@3U?$atomic@_N@__1@std@@A
     ?day_difference@impl@detail@cctz@time_internal@absl@@YA_J_JCC0CC@Z
@@ -812,7 +811,7 @@
     ?push_front@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXAEBQEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ?push_front@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ?raw_code@Status@absl@@QEBAHXZ
-    ?rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAX_K@Z
+    ?rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAX_K@Z
     ?reserve@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z
     ?reserve@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z
     ?reserve@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z
diff --git a/third_party/abseil-cpp/symbols_x64_dbg.def b/third_party/abseil-cpp/symbols_x64_dbg.def
index b7f50e051..2de719e 100644
--- a/third_party/abseil-cpp/symbols_x64_dbg.def
+++ b/third_party/abseil-cpp/symbols_x64_dbg.def
@@ -2,13 +2,6 @@
     ??$?0$$CBD$0A@@VoidPtr@str_format_internal@absl@@QEAA@PEBD@Z
     ??$?0$$CBU?$atomic@_N@__1@std@@@Condition@absl@@QEAA@P6A_NPEBU?$atomic@_N@__1@std@@@Z0@Z
     ??$?0$$CBVFormatArgImpl@str_format_internal@absl@@$$CBV012@@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEAA@V?$initializer_list@VFormatArgImpl@str_format_internal@absl@@@std@@@Z
-    ??$?0$$T$00@?$__compressed_pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PEAPEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PEAUTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PEAUTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PEAUViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PEAVFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T@Z
     ??$?0$$T@?$Storage@PEAH$00$0A@@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@3@$$QEA$$T@Z
     ??$?0$$T@?$Storage@PEAPEAUCordRep@cord_internal@absl@@$00$0A@@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@3@$$QEA$$T@Z
     ??$?0$$T@?$Storage@PEAPEBUCordRep@cord_internal@absl@@$00$0A@@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@3@$$QEA$$T@Z
@@ -20,6 +13,13 @@
     ??$?0$$TAEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@?$__compressed_pair@PEAUTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$TAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
     ??$?0$$TAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@?$__compressed_pair@PEAUTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$TAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
     ??$?0$$TAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@?$__compressed_pair@PEAUViableSubstitution@strings_internal@absl@@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$TAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T$$QEAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PEAPEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T$$QEAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T$$QEAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PEAUTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T$$QEAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PEAUTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T$$QEAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PEAUViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T$$QEAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PEAVFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEA$$T$$QEAU__default_init_tag@12@@Z
     ??$?0$$TX@?$__compressed_pair_elem@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@$$QEA$$T@Z
     ??$?0$$TX@?$__compressed_pair_elem@PEAPEAUCordRep@cord_internal@absl@@$0A@$0A@@__1@std@@QEAA@$$QEA$$T@Z
     ??$?0$$TX@?$__compressed_pair_elem@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@$0A@@__1@std@@QEAA@$$QEA$$T@Z
@@ -49,15 +49,15 @@
     ??$?0AEAPEAUCordRep@cord_internal@absl@@AEAPEAU012@$0A@@?$pair@PEAUCordRep@cord_internal@absl@@PEAU123@@__1@std@@QEAA@AEAPEAUCordRep@cord_internal@absl@@0@Z
     ??$?0AEAPEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@?$__compressed_pair@PEAUThreadIdentity@base_internal@absl@@P6AXPEAX@Z@__1@std@@QEAA@AEAPEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@Z
     ??$?0AEAPEAUThreadIdentity@base_internal@absl@@X@?$__compressed_pair_elem@PEAUThreadIdentity@base_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAUThreadIdentity@base_internal@absl@@@Z
-    ??$?0AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$00@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
+    ??$?0AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$QEAU__default_init_tag@12@@Z
     ??$?0AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@X@?$__compressed_pair_elem@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
-    ??$?0AEAPEAVTimeZoneIf@cctz@time_internal@absl@@$00@?$__compressed_pair@PEAVTimeZoneIf@cctz@time_internal@absl@@U?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAVTimeZoneIf@cctz@time_internal@absl@@@Z
+    ??$?0AEAPEAVTimeZoneIf@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEAVTimeZoneIf@cctz@time_internal@absl@@U?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAVTimeZoneIf@cctz@time_internal@absl@@$$QEAU__default_init_tag@12@@Z
     ??$?0AEAPEAVTimeZoneIf@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PEAVTimeZoneIf@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAVTimeZoneIf@cctz@time_internal@absl@@@Z
-    ??$?0AEAPEAVTimeZoneInfo@cctz@time_internal@absl@@$00@?$__compressed_pair@PEAVTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAVTimeZoneInfo@cctz@time_internal@absl@@@Z
+    ??$?0AEAPEAVTimeZoneInfo@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEAVTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAVTimeZoneInfo@cctz@time_internal@absl@@$$QEAU__default_init_tag@12@@Z
     ??$?0AEAPEAVTimeZoneInfo@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PEAVTimeZoneInfo@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAVTimeZoneInfo@cctz@time_internal@absl@@@Z
-    ??$?0AEAPEAVZoneInfoSource@cctz@time_internal@absl@@$00@?$__compressed_pair@PEAVZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAVZoneInfoSource@cctz@time_internal@absl@@@Z
+    ??$?0AEAPEAVZoneInfoSource@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEAVZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAVZoneInfoSource@cctz@time_internal@absl@@$$QEAU__default_init_tag@12@@Z
     ??$?0AEAPEAVZoneInfoSource@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PEAVZoneInfoSource@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAVZoneInfoSource@cctz@time_internal@absl@@@Z
-    ??$?0AEAPEBVImpl@time_zone@cctz@time_internal@absl@@$00@?$__compressed_pair@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
+    ??$?0AEAPEBVImpl@time_zone@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAU__default_init_tag@12@@Z
     ??$?0AEAPEBVImpl@time_zone@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PEBVImpl@time_zone@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??$?0AEAV?$allocator@H@__1@std@@$$T$00@?$CompressedTuple@V?$allocator@H@__1@std@@PEAH@container_internal@absl@@QEAA@AEAV?$allocator@H@__1@std@@$$QEA$$T@Z
     ??$?0AEAV?$allocator@H@__1@std@@$$T@?$CompressedTupleImpl@V?$CompressedTuple@V?$allocator@H@__1@std@@PEAH@container_internal@absl@@U?$integer_sequence@_K$0A@$00@3@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@3@AEAV?$allocator@H@__1@std@@$$QEA$$T@Z
@@ -94,20 +94,20 @@
     ??$?0AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$$Z$$V@?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAA@Upiecewise_construct_t@12@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@V?$tuple@$$V@12@@Z
     ??$?0AEBVCord@absl@@$0A@@?$optional@VCord@absl@@@absl@@QEAA@AEBVCord@1@@Z
     ??$?0AEBVCord@absl@@@?$optional_data_dtor_base@VCord@absl@@$0A@@optional_internal@absl@@IEAA@Uin_place_t@2@AEBVCord@2@@Z
-    ??$?0H$00@?$__compressed_pair@_KV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAA@$$QEAH@Z
-    ??$?0H$00@?$__compressed_pair@_KV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEAA@$$QEAH@Z
-    ??$?0H$00@?$__compressed_pair@_KV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEAH@Z
     ??$?0H@?$Storage@_K$00$0A@@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@3@$$QEAH@Z
     ??$?0H@FormatArgImpl@str_format_internal@absl@@QEAA@AEBH@Z
-    ??$?0M$00@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAA@$$QEAM@Z
-    ??$?0PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@$00@?$__compressed_pair@PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@23@@__1@std@@QEAA@$$QEAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@@Z
+    ??$?0HU__default_init_tag@__1@std@@@?$__compressed_pair@_KV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAA@$$QEAH$$QEAU__default_init_tag@12@@Z
+    ??$?0HU__default_init_tag@__1@std@@@?$__compressed_pair@_KV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEAA@$$QEAH$$QEAU__default_init_tag@12@@Z
+    ??$?0HU__default_init_tag@__1@std@@@?$__compressed_pair@_KV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEAH$$QEAU__default_init_tag@12@@Z
+    ??$?0MU__default_init_tag@__1@std@@@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAA@$$QEAM$$QEAU__default_init_tag@12@@Z
+    ??$?0PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@U__default_init_tag@12@@?$__compressed_pair@PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@23@@__1@std@@QEAA@$$QEAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@$$QEAU__default_init_tag@12@@Z
     ??$?0PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@X@?$__compressed_pair_elem@PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@$0A@$0A@@__1@std@@QEAA@$$QEAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@@Z
     ??$?0PEAUTransition@cctz@time_internal@absl@@@?$__wrap_iter@PEBUTransition@cctz@time_internal@absl@@@__1@std@@QEAA@AEBV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@12@PEAX@Z
     ??$?0PEAUTransitionType@cctz@time_internal@absl@@@?$__wrap_iter@PEBUTransitionType@cctz@time_internal@absl@@@__1@std@@QEAA@AEBV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@12@PEAX@Z
-    ??$?0PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$00@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAA@$$QEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
     ??$?0PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAA@$$QEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$QEAU?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@12@@Z
+    ??$?0PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAA@$$QEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$QEAU__default_init_tag@12@@Z
     ??$?0PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@X@?$__compressed_pair_elem@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$0A@$0A@@__1@std@@QEAA@$$QEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
-    ??$?0PEAVZoneInfoSource@cctz@time_internal@absl@@$00@?$__compressed_pair@PEAVZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEAPEAVZoneInfoSource@cctz@time_internal@absl@@@Z
+    ??$?0PEAVZoneInfoSource@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEAVZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@$$QEAPEAVZoneInfoSource@cctz@time_internal@absl@@$$QEAU__default_init_tag@12@@Z
     ??$?0PEAVZoneInfoSource@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PEAVZoneInfoSource@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@$$QEAPEAVZoneInfoSource@cctz@time_internal@absl@@@Z
     ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@X@?$__compressed_pair_elem@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@$00$00@__1@std@@QEAA@$$QEAU?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@12@@Z
     ??$?0UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@$$V$00@?$CompressedTuple@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@container_internal@absl@@QEAA@$$QEAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@2@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@Z
@@ -438,39 +438,27 @@
     ??$UnhidePtr@X@base_internal@absl@@YAPEAX_K@Z
     ??$__advance@PEBUTransition@cctz@time_internal@absl@@@__1@std@@YAXAEAPEBUTransition@cctz@time_internal@absl@@_JUrandom_access_iterator_tag@01@@Z
     ??$__advance@PEBVFormatArgImpl@str_format_internal@absl@@@__1@std@@YAXAEAPEBVFormatArgImpl@str_format_internal@absl@@_JUrandom_access_iterator_tag@01@@Z
-    ??$__construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV12345@@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV56789@@Z
-    ??$__construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAPEAPEBV56789@@Z
-    ??$__construct@PEAUCordRep@cord_internal@absl@@AEBQEAU123@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@AEBQEAU567@@Z
-    ??$__construct@PEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV12345@@?$allocator_traits@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV56789@@Z
-    ??$__construct@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@PEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
-    ??$__construct@UConversionItem@ParsedFormatBase@str_format_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QEAU5678@@Z
-    ??$__construct@UTransition@cctz@time_internal@absl@@$$V@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@@Z
-    ??$__construct@UTransition@cctz@time_internal@absl@@AEBU1234@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@AEBU5678@@Z
-    ??$__construct@UTransition@cctz@time_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@$$QEAU5678@@Z
-    ??$__construct@UTransitionType@cctz@time_internal@absl@@$$V@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@@Z
-    ??$__construct@UTransitionType@cctz@time_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@$$QEAU5678@@Z
-    ??$__construct@UViableSubstitution@strings_internal@absl@@AEAVstring_view@3@AEBV43@AEA_K@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PEAUViableSubstitution@strings_internal@absl@@AEAVstring_view@7@AEBV87@AEA_K@Z
     ??$__construct_at_end@PEBQEAUCordRep@cord_internal@absl@@@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAXPEBQEAUCordRep@cord_internal@absl@@0_K@Z
     ??$__construct_at_end@PEBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAXPEBVFormatArgImpl@str_format_internal@absl@@0_K@Z
     ??$__construct_at_end@V?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXV?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
     ??$__construct_at_end@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__1@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@0@Z
     ??$__construct_at_end@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__1@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@0@Z
-    ??$__construct_backward_with_exception_guarantees@PEAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@1AEAPEAPEAU456@@Z
-    ??$__construct_backward_with_exception_guarantees@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@1AEAPEAU4567@@Z
-    ??$__construct_backward_with_exception_guarantees@UTransition@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@1AEAPEAU4567@@Z
-    ??$__construct_backward_with_exception_guarantees@UTransitionType@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@1AEAPEAU4567@@Z
-    ??$__construct_backward_with_exception_guarantees@UViableSubstitution@strings_internal@absl@@@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PEAUViableSubstitution@strings_internal@absl@@1AEAPEAU456@@Z
-    ??$__construct_forward_with_exception_guarantees@UTransition@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@1AEAPEAU4567@@Z
-    ??$__construct_forward_with_exception_guarantees@UTransitionType@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@1AEAPEAU4567@@Z
-    ??$__construct_node_hash@AEBUpiecewise_construct_t@__1@std@@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAA?AV?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@12@_KAEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@PEAUCordRep@cord_internal@absl@@X@__1@std@@YAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@01@PEAPEAUCordRep@cord_internal@absl@@1AEAPEAPEAU345@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@X@__1@std@@YAXAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@01@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@1AEAPEAU3456@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@UTransition@cctz@time_internal@absl@@X@__1@std@@YAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@01@PEAUTransition@cctz@time_internal@absl@@1AEAPEAU3456@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@UTransitionType@cctz@time_internal@absl@@X@__1@std@@YAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@01@PEAUTransitionType@cctz@time_internal@absl@@1AEAPEAU3456@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@UViableSubstitution@strings_internal@absl@@X@__1@std@@YAXAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@01@PEAUViableSubstitution@strings_internal@absl@@1AEAPEAU345@@Z
+    ??$__construct_forward_with_exception_guarantees@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@PEAUTransition@cctz@time_internal@absl@@@__1@std@@YAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@01@PEAUTransition@cctz@time_internal@absl@@1AEAPEAU3456@@Z
+    ??$__construct_forward_with_exception_guarantees@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@PEAUTransitionType@cctz@time_internal@absl@@@__1@std@@YAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@01@PEAUTransitionType@cctz@time_internal@absl@@1AEAPEAU3456@@Z
+    ??$__construct_node_hash@AEBUpiecewise_construct_t@__1@std@@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAA?AV?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@12@_KAEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
     ??$__construct_one_at_end@$$V@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXXZ
     ??$__construct_one_at_end@$$V@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXXZ
     ??$__construct_one_at_end@AEAVstring_view@absl@@AEBV12@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@AEAAXAEAVstring_view@absl@@AEBV34@AEA_K@Z
     ??$__construct_one_at_end@AEBQEAUCordRep@cord_internal@absl@@@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAXAEBQEAUCordRep@cord_internal@absl@@@Z
     ??$__construct_one_at_end@AEBUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXAEBUTransition@cctz@time_internal@absl@@@Z
     ??$__construct_one_at_end@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAX$$QEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
-    ??$__construct_range_forward@$$CBVFormatArgImpl@str_format_internal@absl@@V123@V123@V123@@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PEBVFormatArgImpl@str_format_internal@absl@@1AEAPEAV456@@Z
-    ??$__construct_range_forward@QEAUCordRep@cord_internal@absl@@PEAU123@PEAU123@PEAU123@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEBQEAUCordRep@cord_internal@absl@@1AEAPEAPEAU456@@Z
+    ??$__construct_range_forward@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@QEAUCordRep@cord_internal@absl@@PEAU456@PEAU456@PEAU456@X@__1@std@@YAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@01@PEBQEAUCordRep@cord_internal@absl@@1AEAPEAPEAU345@@Z
+    ??$__construct_range_forward@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@$$CBVFormatArgImpl@str_format_internal@absl@@V456@V456@V456@X@__1@std@@YAXAEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@01@PEBVFormatArgImpl@str_format_internal@absl@@1AEAPEAV345@@Z
     ??$__copy@$$CBVFormatArgImpl@str_format_internal@absl@@V123@@__1@std@@YAPEAVFormatArgImpl@str_format_internal@absl@@PEBV234@0PEAV234@@Z
     ??$__cxx_atomic_compare_exchange_weak@PEAUHashtablezInfo@container_internal@absl@@@__1@std@@YA_NPEAU?$__cxx_atomic_base_impl@PEAUHashtablezInfo@container_internal@absl@@@01@PEAPEAUHashtablezInfo@container_internal@absl@@PEAU345@W4memory_order@01@3@Z
     ??$__cxx_atomic_exchange@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@__1@std@@YAP6AXAEBUHashtablezInfo@container_internal@absl@@@ZPEAU?$__cxx_atomic_base_impl@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@01@P6AX0@ZW4memory_order@01@@Z
@@ -480,14 +468,6 @@
     ??$__cxx_atomic_load@W4State@PerThreadSynch@base_internal@absl@@@__1@std@@YA?AW4State@PerThreadSynch@base_internal@absl@@PEBU?$__cxx_atomic_base_impl@W4State@PerThreadSynch@base_internal@absl@@@01@W4memory_order@01@@Z
     ??$__cxx_atomic_store@W4OnDeadlockCycle@absl@@@__1@std@@YAXPEAU?$__cxx_atomic_base_impl@W4OnDeadlockCycle@absl@@@01@W4OnDeadlockCycle@absl@@W4memory_order@01@@Z
     ??$__cxx_atomic_store@W4State@PerThreadSynch@base_internal@absl@@@__1@std@@YAXPEAU?$__cxx_atomic_base_impl@W4State@PerThreadSynch@base_internal@absl@@@01@W4State@PerThreadSynch@base_internal@absl@@W4memory_order@01@@Z
-    ??$__destroy@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
-    ??$__destroy@PEAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@@Z
-    ??$__destroy@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$0A@@12@AEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@PEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
-    ??$__destroy@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
-    ??$__destroy@UTransition@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@@Z
-    ??$__destroy@UTransitionType@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@@Z
-    ??$__destroy@UViableSubstitution@strings_internal@absl@@@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PEAUViableSubstitution@strings_internal@absl@@@Z
-    ??$__destroy@VFormatArgImpl@str_format_internal@absl@@@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PEAVFormatArgImpl@str_format_internal@absl@@@Z
     ??$__distance@PEBUPayload@status_internal@absl@@@__1@std@@YA_JPEBUPayload@status_internal@absl@@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@PEBUTransition@cctz@time_internal@absl@@@__1@std@@YA_JPEBUTransition@cctz@time_internal@absl@@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@PEBVFormatArgImpl@str_format_internal@absl@@@__1@std@@YA_JPEBVFormatArgImpl@str_format_internal@absl@@0Urandom_access_iterator_tag@01@@Z
@@ -495,7 +475,7 @@
     ??$__distance@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@YA_JV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@01@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@YA_JV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@01@0Urandom_access_iterator_tag@01@@Z
     ??$__emplace_back_slow_path@AEAVstring_view@absl@@AEBV12@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@AEAAXAEAVstring_view@absl@@AEBV34@AEA_K@Z
-    ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@_N@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
+    ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@_N@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
     ??$__lower_bound@AEAUByUnixTime@Transition@cctz@time_internal@absl@@PEBU2345@U2345@@__1@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@AEAUByUnixTime@2345@@Z
     ??$__move@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@@__1@std@@YAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV23456@00@Z
     ??$__move@UTransition@cctz@time_internal@absl@@U1234@@__1@std@@YAPEAUTransition@cctz@time_internal@absl@@PEAU2345@00@Z
@@ -506,13 +486,13 @@
     ??$__push_back_slow_path@AEBQEAUCordRep@cord_internal@absl@@@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAXAEBQEAUCordRep@cord_internal@absl@@@Z
     ??$__push_back_slow_path@AEBUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXAEBUTransition@cctz@time_internal@absl@@@Z
     ??$__push_back_slow_path@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAX$$QEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
-    ??$__to_raw_pointer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV23456@@Z
-    ??$__to_raw_pointer@PEAUCordRep@cord_internal@absl@@@__1@std@@YAPEAPEAUCordRep@cord_internal@absl@@PEAPEAU234@@Z
-    ??$__to_raw_pointer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@YAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@PEAU2345@@Z
-    ??$__to_raw_pointer@UTransition@cctz@time_internal@absl@@@__1@std@@YAPEAUTransition@cctz@time_internal@absl@@PEAU2345@@Z
-    ??$__to_raw_pointer@UTransitionType@cctz@time_internal@absl@@@__1@std@@YAPEAUTransitionType@cctz@time_internal@absl@@PEAU2345@@Z
-    ??$__to_raw_pointer@UViableSubstitution@strings_internal@absl@@@__1@std@@YAPEAUViableSubstitution@strings_internal@absl@@PEAU234@@Z
-    ??$__to_raw_pointer@VFormatArgImpl@str_format_internal@absl@@@__1@std@@YAPEAVFormatArgImpl@str_format_internal@absl@@PEAV234@@Z
+    ??$__to_address@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV23456@@Z
+    ??$__to_address@PEAUCordRep@cord_internal@absl@@@__1@std@@YAPEAPEAUCordRep@cord_internal@absl@@PEAPEAU234@@Z
+    ??$__to_address@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@YAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@PEAU2345@@Z
+    ??$__to_address@UTransition@cctz@time_internal@absl@@@__1@std@@YAPEAUTransition@cctz@time_internal@absl@@PEAU2345@@Z
+    ??$__to_address@UTransitionType@cctz@time_internal@absl@@@__1@std@@YAPEAUTransitionType@cctz@time_internal@absl@@PEAU2345@@Z
+    ??$__to_address@UViableSubstitution@strings_internal@absl@@@__1@std@@YAPEAUViableSubstitution@strings_internal@absl@@PEAU234@@Z
+    ??$__to_address@VFormatArgImpl@str_format_internal@absl@@@__1@std@@YAPEAVFormatArgImpl@str_format_internal@absl@@PEAV234@@Z
     ??$__unwrap_iter@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV23456@@Z
     ??$__unwrap_iter@PEAUTransition@cctz@time_internal@absl@@@__1@std@@YAPEAUTransition@cctz@time_internal@absl@@PEAU2345@@Z
     ??$__unwrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@__1@std@@YAPEAUTransitionType@cctz@time_internal@absl@@PEAU2345@@Z
@@ -532,8 +512,8 @@
     ??$addressof@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@YAPEAV?$allocator@PEBUCordRep@cord_internal@absl@@@01@AEAV201@@Z
     ??$addressof@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@__1@std@@YAPEAV?$allocator@UPayload@status_internal@absl@@@01@AEAV201@@Z
     ??$addressof@V?$allocator@USubRange@absl@@@__1@std@@@__1@std@@YAPEAV?$allocator@USubRange@absl@@@01@AEAV201@@Z
-    ??$advance@PEBUTransition@cctz@time_internal@absl@@@__1@std@@YAXAEAPEBUTransition@cctz@time_internal@absl@@_J@Z
-    ??$advance@PEBVFormatArgImpl@str_format_internal@absl@@@__1@std@@YAXAEAPEBVFormatArgImpl@str_format_internal@absl@@_J@Z
+    ??$advance@PEBUTransition@cctz@time_internal@absl@@_J@__1@std@@YAXAEAPEBUTransition@cctz@time_internal@absl@@_J@Z
+    ??$advance@PEBVFormatArgImpl@str_format_internal@absl@@_K@__1@std@@YAXAEAPEBVFormatArgImpl@str_format_internal@absl@@_K@Z
     ??$assign@PEBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QEAAXPEBVFormatArgImpl@str_format_internal@absl@@0@Z
     ??$assign@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$optional_data_base@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@optional_internal@absl@@IEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$bit_cast@MI$0A@@absl@@YAMAEBI@Z
@@ -544,12 +524,12 @@
     ??$construct@HAEBH@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@SAXAEAV?$allocator@H@__1@std@@PEAHAEBH@Z
     ??$construct@HH@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@SAXAEAV?$allocator@H@__1@std@@PEAH$$QEAH@Z
     ??$construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV12345@@?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV34567@@Z
-    ??$construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV12345@@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV45678@@Z
+    ??$construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV12345@X@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEAPEBV45678@@Z
     ??$construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@@?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAPEAPEBV34567@@Z
-    ??$construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAPEAPEBV45678@@Z
+    ??$construct@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@X@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAPEAPEBV45678@@Z
     ??$construct@PEAUCordRep@cord_internal@absl@@AEBQEAU123@@?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@QEAAXPEAPEAUCordRep@cord_internal@absl@@AEBQEAU345@@Z
-    ??$construct@PEAUCordRep@cord_internal@absl@@AEBQEAU123@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@AEBQEAU456@@Z
     ??$construct@PEAUCordRep@cord_internal@absl@@AEBQEAU123@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@PEAPEAUCordRep@cord_internal@1@AEBQEAU561@@Z
+    ??$construct@PEAUCordRep@cord_internal@absl@@AEBQEAU123@X@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@AEBQEAU456@@Z
     ??$construct@PEAUCordRep@cord_internal@absl@@PEAU123@@?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@QEAAXPEAPEAUCordRep@cord_internal@absl@@$$QEAPEAU345@@Z
     ??$construct@PEAUCordRep@cord_internal@absl@@PEAU123@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@PEAPEAUCordRep@cord_internal@1@$$QEAPEAU561@@Z
     ??$construct@PEBUCordRep@cord_internal@absl@@AEBQEBU123@@?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@QEAAXPEAPEBUCordRep@cord_internal@absl@@AEBQEBU345@@Z
@@ -557,11 +537,11 @@
     ??$construct@PEBUCordRep@cord_internal@absl@@PEBU123@@?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@QEAAXPEAPEBUCordRep@cord_internal@absl@@$$QEAPEBU345@@Z
     ??$construct@PEBUCordRep@cord_internal@absl@@PEBU123@@?$allocator_traits@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@PEAPEBUCordRep@cord_internal@1@$$QEAPEBU561@@Z
     ??$construct@PEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV12345@@?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAAXPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV34567@@Z
-    ??$construct@PEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV12345@@?$allocator_traits@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV45678@@Z
+    ??$construct@PEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV12345@X@?$allocator_traits@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBQEBV45678@@Z
     ??$construct@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@QEAAXPEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
-    ??$construct@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@SAXAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@PEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
+    ??$construct@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@X@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@SAXAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@PEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
     ??$construct@UConversionItem@ParsedFormatBase@str_format_internal@absl@@U1234@@?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QEAU3456@@Z
-    ??$construct@UConversionItem@ParsedFormatBase@str_format_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QEAU4567@@Z
+    ??$construct@UConversionItem@ParsedFormatBase@str_format_internal@absl@@U1234@X@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QEAU4567@@Z
     ??$construct@UPayload@status_internal@absl@@AEBU123@@?$allocator@UPayload@status_internal@absl@@@__1@std@@QEAAXPEAUPayload@status_internal@absl@@AEBU345@@Z
     ??$construct@UPayload@status_internal@absl@@AEBU123@@?$allocator_traits@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@UPayload@status_internal@absl@@@__1@std@@PEAUPayload@status_internal@1@AEBU561@@Z
     ??$construct@UPayload@status_internal@absl@@U123@@?$allocator@UPayload@status_internal@absl@@@__1@std@@QEAAXPEAUPayload@status_internal@absl@@$$QEAU345@@Z
@@ -569,17 +549,17 @@
     ??$construct@USubRange@absl@@U12@@?$allocator@USubRange@absl@@@__1@std@@QEAAXPEAUSubRange@absl@@$$QEAU34@@Z
     ??$construct@USubRange@absl@@U12@@?$allocator_traits@V?$allocator@USubRange@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@USubRange@absl@@@__1@std@@PEAUSubRange@1@$$QEAU51@@Z
     ??$construct@UTransition@cctz@time_internal@absl@@$$V@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
-    ??$construct@UTransition@cctz@time_internal@absl@@$$V@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@@Z
+    ??$construct@UTransition@cctz@time_internal@absl@@$$VX@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@@Z
     ??$construct@UTransition@cctz@time_internal@absl@@AEBU1234@@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@AEBU3456@@Z
-    ??$construct@UTransition@cctz@time_internal@absl@@AEBU1234@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@AEBU4567@@Z
+    ??$construct@UTransition@cctz@time_internal@absl@@AEBU1234@X@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@AEBU4567@@Z
     ??$construct@UTransition@cctz@time_internal@absl@@U1234@@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@$$QEAU3456@@Z
-    ??$construct@UTransition@cctz@time_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@$$QEAU4567@@Z
+    ??$construct@UTransition@cctz@time_internal@absl@@U1234@X@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@$$QEAU4567@@Z
     ??$construct@UTransitionType@cctz@time_internal@absl@@$$V@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
-    ??$construct@UTransitionType@cctz@time_internal@absl@@$$V@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@@Z
+    ??$construct@UTransitionType@cctz@time_internal@absl@@$$VX@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@@Z
     ??$construct@UTransitionType@cctz@time_internal@absl@@U1234@@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@$$QEAU3456@@Z
-    ??$construct@UTransitionType@cctz@time_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@$$QEAU4567@@Z
+    ??$construct@UTransitionType@cctz@time_internal@absl@@U1234@X@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@$$QEAU4567@@Z
     ??$construct@UViableSubstitution@strings_internal@absl@@AEAVstring_view@3@AEBV43@AEA_K@?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@AEAVstring_view@5@AEBV65@AEA_K@Z
-    ??$construct@UViableSubstitution@strings_internal@absl@@AEAVstring_view@3@AEBV43@AEA_K@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PEAUViableSubstitution@strings_internal@absl@@AEAVstring_view@6@AEBV76@AEA_K@Z
+    ??$construct@UViableSubstitution@strings_internal@absl@@AEAVstring_view@3@AEBV43@AEA_KX@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PEAUViableSubstitution@strings_internal@absl@@AEAVstring_view@6@AEBV76@AEA_K@Z
     ??$construct@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$optional_data_base@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@optional_internal@absl@@IEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$construct_impl@V?$allocator@H@__1@std@@AEAPEAHAEBH@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@CAXHAEAV?$allocator@H@__1@std@@AEAPEAHAEBH@Z
     ??$construct_impl@V?$allocator@H@__1@std@@AEAPEAHH@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@CAXHAEAV?$allocator@H@__1@std@@AEAPEAH$$QEAH@Z
@@ -593,18 +573,18 @@
     ??$copy@PEBVFormatArgImpl@str_format_internal@absl@@PEAV123@@__1@std@@YAPEAVFormatArgImpl@str_format_internal@absl@@PEBV234@0PEAV234@@Z
     ??$countl_zero@_K@absl@@YAH_K@Z
     ??$destroy@H@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@SAXAEAV?$allocator@H@__1@std@@PEAH@Z
-    ??$destroy@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
-    ??$destroy@PEAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@@Z
+    ??$destroy@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@X@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??$destroy@PEAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@PEAPEAUCordRep@cord_internal@1@@Z
+    ??$destroy@PEAUCordRep@cord_internal@absl@@X@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@12@PEAPEAUCordRep@cord_internal@absl@@@Z
     ??$destroy@PEBUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@PEAPEBUCordRep@cord_internal@1@@Z
-    ??$destroy@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@SAXAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@PEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
-    ??$destroy@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+    ??$destroy@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@XX@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@SAXAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@PEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
+    ??$destroy@UConversionItem@ParsedFormatBase@str_format_internal@absl@@X@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ??$destroy@UPayload@status_internal@absl@@@?$allocator_traits@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@UPayload@status_internal@absl@@@__1@std@@PEAUPayload@status_internal@1@@Z
     ??$destroy@USubRange@absl@@@?$allocator_traits@V?$allocator@USubRange@absl@@@__1@std@@@absl@@SAXAEAV?$allocator@USubRange@absl@@@__1@std@@PEAUSubRange@1@@Z
-    ??$destroy@UTransition@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@@Z
-    ??$destroy@UTransitionType@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@@Z
-    ??$destroy@UViableSubstitution@strings_internal@absl@@@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PEAUViableSubstitution@strings_internal@absl@@@Z
-    ??$destroy@VFormatArgImpl@str_format_internal@absl@@@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PEAVFormatArgImpl@str_format_internal@absl@@@Z
+    ??$destroy@UTransition@cctz@time_internal@absl@@X@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PEAUTransition@cctz@time_internal@absl@@@Z
+    ??$destroy@UTransitionType@cctz@time_internal@absl@@X@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PEAUTransitionType@cctz@time_internal@absl@@@Z
+    ??$destroy@UViableSubstitution@strings_internal@absl@@X@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PEAUViableSubstitution@strings_internal@absl@@@Z
+    ??$destroy@VFormatArgImpl@str_format_internal@absl@@X@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PEAVFormatArgImpl@str_format_internal@absl@@@Z
     ??$destroy_impl@V?$allocator@H@__1@std@@H@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@CAXHAEAV?$allocator@H@__1@std@@PEAH@Z
     ??$destroy_impl@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@PEAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@CAXHAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@PEAPEAUCordRep@cord_internal@1@@Z
     ??$destroy_impl@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@PEBUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@absl@@CAXHAEAV?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@PEAPEBUCordRep@cord_internal@1@@Z
@@ -628,7 +608,7 @@
     ??$emplace_back@PEAUCordRep@cord_internal@absl@@@?$InlinedVector@PEAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAAEAPEAUCordRep@cord_internal@1@$$QEAPEAU231@@Z
     ??$emplace_back@UPayload@status_internal@absl@@@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEAAAEAUPayload@status_internal@1@$$QEAU231@@Z
     ??$emplace_back@USubRange@absl@@@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QEAAAEAUSubRange@1@$$QEAU21@@Z
-    ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
+    ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??$forward@$$T@absl@@YA$$QEA$$TAEA$$T@Z
     ??$forward@AEAI@absl@@YAAEAIAEAI@Z
     ??$forward@AEAPEAPEAUCordRep@cord_internal@absl@@@__1@std@@YAAEAPEAPEAUCordRep@cord_internal@absl@@AEAPEAPEAU234@@Z
@@ -740,6 +720,19 @@
     ??$make_pair@AEAPEAUCordRep@cord_internal@absl@@AEAPEAU123@@__1@std@@YA?AU?$pair@PEAUCordRep@cord_internal@absl@@PEAU123@@01@AEAPEAUCordRep@cord_internal@absl@@0@Z
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$V@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@XZ
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@AEAV12@@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@AEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
+    ??$max_size@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@X@?$allocator_traits@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@12@@Z
+    ??$max_size@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@PEAUCordRep@cord_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@PEBUCordRep@cord_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@X@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@@Z
+    ??$max_size@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@UPayload@status_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UPayload@status_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@USubRange@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@USubRange@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@USubRange@absl@@@12@@Z
+    ??$max_size@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@@Z
     ??$min@VDuration@absl@@@__1@std@@YAAEBVDuration@absl@@AEBV23@0@Z
     ??$min@VDuration@absl@@U?$__less@VDuration@absl@@V12@@__1@std@@@__1@std@@YAAEBVDuration@absl@@AEBV23@0U?$__less@VDuration@absl@@V12@@01@@Z
     ??$move@AEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YA$$QEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAPEAPEAPEBV23456@@Z
@@ -831,20 +824,25 @@
     ??0?$__atomic_base@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z$0A@@__1@std@@QEAA@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@Z
     ??0?$__atomic_base@PEAUHashtablezInfo@container_internal@absl@@$0A@@__1@std@@QEAA@PEAUHashtablezInfo@container_internal@absl@@@Z
     ??0?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@U?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@$0A@$0A@@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@XZ
+    ??0?$__compressed_pair_elem@U?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@$0A@$0A@@__1@std@@QEAA@U__value_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@$00$00@__1@std@@QEAA@U__value_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@$00$00@__1@std@@QEAA@U__default_init_tag@12@@Z
     ??0?$__cxx_atomic_base_impl@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@__1@std@@QEAA@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@Z
     ??0?$__cxx_atomic_base_impl@PEAUHashtablezInfo@container_internal@absl@@@__1@std@@QEAA@PEAUHashtablezInfo@container_internal@absl@@@Z
     ??0?$__cxx_atomic_impl@P6AXAEBUHashtablezInfo@container_internal@absl@@@ZU?$__cxx_atomic_base_impl@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@__1@std@@@__1@std@@QEAA@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@Z
@@ -857,7 +855,7 @@
     ??0?$__hash_map_iterator@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@QEAA@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@@Z
     ??0?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@QEAA@XZ
     ??0?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@QEAA@AEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@_N@Z
-    ??0?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA@XZ
+    ??0?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA@XZ
     ??0?$__policy_invoker@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z@__function@__1@std@@AEAA@P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@23@PEBT__policy_storage@123@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z@Z
     ??0?$__policy_invoker@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z@__function@__1@std@@QEAA@XZ
     ??0?$__policy_invoker@$$A6AXVstring_view@absl@@AEBVCord@2@@Z@__function@__1@std@@AEAA@P6AXPEBT__policy_storage@123@$$QEAVstring_view@absl@@AEBVCord@6@@Z@Z
@@ -869,8 +867,8 @@
     ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@_K0AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
     ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@_K0AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
     ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEAA@_K0AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
-    ??0?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEAA@XZ
-    ??0?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEAA@XZ
+    ??0?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEAA@XZ
+    ??0?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEAA@XZ
     ??0?$__vector_base@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@IEAA@XZ
     ??0?$__vector_base@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@IEAA@XZ
     ??0?$__vector_base@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@IEAA@XZ
@@ -1385,9 +1383,9 @@
     ??R?$__policy_func@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z@__function@__1@std@@QEBA?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@23@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z
     ??R?$__policy_func@$$A6AXAEBUHashtablezInfo@container_internal@absl@@@Z@__function@__1@std@@QEBAXAEBUHashtablezInfo@container_internal@absl@@@Z
     ??R?$__policy_func@$$A6AXVstring_view@absl@@AEBVCord@2@@Z@__function@__1@std@@QEBAX$$QEAVstring_view@absl@@AEBVCord@5@@Z
-    ??R?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEBA_NAEBU?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
-    ??R?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEBA_NAEBU?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
-    ??R?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEBA_KAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
+    ??R?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEBA_NAEBU?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
+    ??R?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEBA_NAEBU?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
+    ??R?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QEBA_KAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??R?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEBAXPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??R?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@QEBAXPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
     ??R?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@QEBAXPEAVTimeZoneIf@cctz@time_internal@absl@@@Z
@@ -2451,7 +2449,7 @@
     ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z
     ?__construct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
     ?__construct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
-    ?__deallocate_node@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAXPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@@Z
+    ?__deallocate_node@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAXPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@@Z
     ?__destruct_at_begin@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ?__destruct_at_begin@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@U?$integral_constant@_N$00@23@@Z
     ?__destruct_at_end@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
@@ -2550,8 +2548,8 @@
     ?__get@?$__compressed_pair_elem@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QEAAAEAV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@23@XZ
     ?__get@?$__compressed_pair_elem@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QEBAAEBV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@23@XZ
     ?__get@?$__compressed_pair_elem@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QEAAAEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@XZ
-    ?__get@?$__compressed_pair_elem@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAAAEAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
-    ?__get@?$__compressed_pair_elem@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?__get@?$__compressed_pair_elem@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAAAEAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?__get@?$__compressed_pair_elem@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?__get@?$__compressed_pair_elem@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QEAAAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?__get@?$__compressed_pair_elem@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@$00$00@__1@std@@QEAAAEAV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@XZ
     ?__get@?$__compressed_pair_elem@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@$00$00@__1@std@@QEAAAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@23@XZ
@@ -2586,15 +2584,9 @@
     ?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AEBA?AV?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ?__make_iter@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAA?AV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@23@PEAUTransition@cctz@time_internal@absl@@@Z
     ?__make_iter@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAA?AV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@23@PEAUTransitionType@cctz@time_internal@absl@@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@CA_KU?$integral_constant@_N$00@23@AEBV?$allocator@PEAUCordRep@cord_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@CA_KU?$integral_constant@_N$00@23@AEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CA_KU?$integral_constant@_N$00@23@AEBV?$allocator@UTransition@cctz@time_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@CA_KU?$integral_constant@_N$00@23@AEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@CA_KU?$integral_constant@_N$00@23@AEBV?$allocator@UViableSubstitution@strings_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@CA_KU?$integral_constant@_N$00@23@AEBV?$allocator@VFormatArgImpl@str_format_internal@absl@@@23@@Z
     ?__move_range@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXPEAUTransition@cctz@time_internal@absl@@00@Z
     ?__move_range@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXPEAUTransitionType@cctz@time_internal@absl@@00@Z
-    ?__node_alloc@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
+    ?__node_alloc@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
     ?__ptr@?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@QEAAPEAU123@XZ
     ?__recommend@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEBA_K_K@Z
     ?__recommend@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AEBA_K_K@Z
@@ -2602,7 +2594,7 @@
     ?__recommend@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEBA_K_K@Z
     ?__recommend@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@AEBA_K_K@Z
     ?__recommend@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AEBA_K_K@Z
-    ?__rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAX_K@Z
+    ?__rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAX_K@Z
     ?__swap_out_circular_buffer@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAXAEAU?$__split_buffer@PEAUCordRep@cord_internal@absl@@AEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@23@@Z
     ?__swap_out_circular_buffer@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAXAEAU?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@23@@Z
     ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAPEAUTransition@cctz@time_internal@absl@@AEAU?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@23@PEAU4567@@Z
@@ -2624,19 +2616,19 @@
     ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Usecond_tag@1234@U51234@@Z
     ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Uyear_tag@1234@U51234@@Z
     ?alloc@Storage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEAAAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@XZ
-    ?allocate@?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@QEAAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@_KPEBX@Z
-    ?allocate@?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@QEAAPEAPEAUCordRep@cord_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@QEAAPEAPEBUCordRep@cord_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@QEAAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@23@_KPEBX@Z
-    ?allocate@?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@UPayload@status_internal@absl@@@__1@std@@QEAAPEAUPayload@status_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@USubRange@absl@@@__1@std@@QEAAPEAUSubRange@absl@@_KPEBX@Z
-    ?allocate@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QEAAPEAUTransition@cctz@time_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@_KPEBX@Z
-    ?allocate@?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@QEAAPEAVFormatArgImpl@str_format_internal@absl@@_KPEBX@Z
+    ?allocate@?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_K@Z
+    ?allocate@?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@QEAAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@_K@Z
+    ?allocate@?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@QEAAPEAPEAUCordRep@cord_internal@absl@@_K@Z
+    ?allocate@?$allocator@PEBUCordRep@cord_internal@absl@@@__1@std@@QEAAPEAPEBUCordRep@cord_internal@absl@@_K@Z
+    ?allocate@?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEAAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_K@Z
+    ?allocate@?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@QEAAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@23@_K@Z
+    ?allocate@?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@_K@Z
+    ?allocate@?$allocator@UPayload@status_internal@absl@@@__1@std@@QEAAPEAUPayload@status_internal@absl@@_K@Z
+    ?allocate@?$allocator@USubRange@absl@@@__1@std@@QEAAPEAUSubRange@absl@@_K@Z
+    ?allocate@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QEAAPEAUTransition@cctz@time_internal@absl@@_K@Z
+    ?allocate@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@_K@Z
+    ?allocate@?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@_K@Z
+    ?allocate@?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@QEAAPEAVFormatArgImpl@str_format_internal@absl@@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@SAPEAHAEAV?$allocator@H@__1@std@@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@SAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@AEAV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@_K@Z
@@ -2687,7 +2679,7 @@
     ?begin@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEAAPEAUPayload@status_internal@2@XZ
     ?begin@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEBAPEBUPayload@status_internal@2@XZ
     ?begin@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEBAPEBVFormatArgImpl@str_format_internal@2@XZ
-    ?begin@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
+    ?begin@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
     ?begin@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?begin@?$initializer_list@PEAUCordRep@cord_internal@absl@@@std@@QEBAPEBQEAUCordRep@cord_internal@absl@@XZ
     ?begin@?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@QEBAPEBU?$pair@Vstring_view@absl@@V12@@__1@2@XZ
@@ -2701,7 +2693,7 @@
     ?begin@ChunkRange@Cord@absl@@QEBA?AVChunkIterator@23@XZ
     ?begin@Storage@?$FixedArray@PEAUCordRep@cord_internal@absl@@$0?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QEBAPEAPEAUCordRep@cord_internal@3@XZ
     ?begin@string_view@absl@@QEBAPEBDXZ
-    ?bucket_count@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEBA_KXZ
+    ?bucket_count@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEBA_KXZ
     ?capacity@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ
     ?capacity@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ
     ?capacity@?$__split_buffer@PEAUCordRep@cord_internal@absl@@AEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ
@@ -2724,7 +2716,7 @@
     ?capacity@CordRepRing@cord_internal@absl@@QEBAIXZ
     ?chunk_begin@Cord@absl@@QEBA?AVChunkIterator@12@XZ
     ?chunk_end@Cord@absl@@QEBA?AVChunkIterator@12@XZ
-    ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAXXZ
+    ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAXXZ
     ?clear@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ
     ?clear@?$__split_buffer@PEAUCordRep@cord_internal@absl@@AEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ
     ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ
@@ -2844,7 +2836,7 @@
     ?end@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEBAPEBUPayload@status_internal@2@XZ
     ?end@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEBAPEBVFormatArgImpl@str_format_internal@2@XZ
     ?end@?$__deque_base@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@IEAA?AV?$__deque_iterator@PEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@AEAPEBV12345@PEAPEAPEBV12345@_J$0A@@23@XZ
-    ?end@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
+    ?end@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
     ?end@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?end@?$initializer_list@PEAUCordRep@cord_internal@absl@@@std@@QEBAPEBQEAUCordRep@cord_internal@absl@@XZ
     ?end@?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@QEBAPEBU?$pair@Vstring_view@absl@@V12@@__1@2@XZ
@@ -2885,7 +2877,7 @@
     ?find_last_not_of@string_view@absl@@QEBA_KV12@_K@Z
     ?find_last_of@string_view@absl@@QEBA_KD_K@Z
     ?find_last_of@string_view@absl@@QEBA_KV12@_K@Z
-    ?first@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEAMXZ
+    ?first@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEAMXZ
     ?first@?$__compressed_pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?first@?$__compressed_pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBAAEBQEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?first@?$__compressed_pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
@@ -2930,7 +2922,7 @@
     ?first@?$__compressed_pair@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?first@?$__compressed_pair@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBAAEBQEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?first@?$__compressed_pair@U?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@@__1@std@@QEAAAEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
-    ?first@?$__compressed_pair@_KV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEA_KXZ
+    ?first@?$__compressed_pair@_KV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEA_KXZ
     ?first@?$__compressed_pair@_KV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEAAAEA_KXZ
     ?first@?$__compressed_pair@_KV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEBAAEB_KXZ
     ?first@?$__compressed_pair@_KV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEA_KXZ
@@ -2985,7 +2977,7 @@
     ?has_timeout@KernelTimeout@synchronization_internal@absl@@QEBA_NXZ
     ?has_value@?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@absl@@QEBA_NXZ
     ?has_zero_flag@FormatConversionSpecImpl@str_format_internal@absl@@QEBA_NXZ
-    ?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?head@CordRepRing@cord_internal@absl@@QEBAIXZ
     ?head@Filler@CordRepRing@cord_internal@absl@@QEBAIXZ
     ?hour@?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
@@ -3001,7 +2993,7 @@
     ?is_length@ConvTag@str_format_internal@absl@@QEBA_NXZ
     ?is_tree@InlineData@cord_internal@absl@@QEBA_NXZ
     ?is_tree@InlineRep@Cord@absl@@QEBA_NXZ
-    ?key_eq@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?key_eq@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?length@?$Span@D@absl@@QEBA_KXZ
     ?length@CordRepRingReader@cord_internal@absl@@QEBA_KXZ
     ?length@string_view@absl@@QEBA_KXZ
@@ -3018,7 +3010,7 @@
     ?max@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@SA?AV12345@XZ
     ?max@?$numeric_limits@Vint128@absl@@@__1@std@@SA?AVint128@absl@@XZ
     ?max@?$numeric_limits@Vuint128@absl@@@__1@std@@SA?AVuint128@absl@@XZ
-    ?max_load_factor@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAMXZ
+    ?max_load_factor@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAMXZ
     ?max_size@?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QEBA_KXZ
     ?max_size@?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@QEBA_KXZ
     ?max_size@?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@QEBA_KXZ
@@ -3032,12 +3024,6 @@
     ?max_size@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QEBA_KXZ
     ?max_size@?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@QEBA_KXZ
     ?max_size@?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@QEBA_KXZ
-    ?max_size@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@PEAUCordRep@cord_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UTransition@cctz@time_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@UViableSubstitution@strings_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@VFormatArgImpl@str_format_internal@absl@@@23@@Z
     ?max_size@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ
     ?max_size@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ
     ?max_size@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ
@@ -3110,7 +3096,7 @@
     ?rbegin@string_view@absl@@QEBA?AV?$reverse_iterator@PEBD@__1@std@@XZ
     ?reduce_size@InlineRep@Cord@absl@@QEAAX_K@Z
     ?reference@?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@absl@@AEAAAEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ
-    ?rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAX_K@Z
+    ?rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAX_K@Z
     ?release@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?release@?$unique_ptr@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@@__1@std@@QEAAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?release@?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@__1@std@@QEAAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@23@XZ
@@ -3149,7 +3135,7 @@
     ?safe_strtou32_base@numbers_internal@absl@@YA_NVstring_view@2@PEAIH@Z
     ?safe_strtou64_base@numbers_internal@absl@@YA_NVstring_view@2@PEA_KH@Z
     ?scale_add@impl@detail@cctz@time_internal@absl@@YA_J_J00@Z
-    ?second@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?second@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?second@?$__compressed_pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?second@?$__compressed_pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?second@?$__compressed_pair@PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@23@@__1@std@@QEAAAEAV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@23@XZ
@@ -3180,7 +3166,7 @@
     ?second@?$__compressed_pair@PEAVZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAU?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@23@XZ
     ?second@?$__compressed_pair@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAU?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?second@?$__compressed_pair@U?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@@__1@std@@QEAAAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@XZ
-    ?second@?$__compressed_pair@_KV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?second@?$__compressed_pair@_KV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?second@?$__compressed_pair@_KV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEAAAEAV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@XZ
     ?second@?$__compressed_pair@_KV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?second@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
@@ -3213,7 +3199,7 @@
     ?size@?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QEBA_KXZ
     ?size@?$__deque_base@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@IEAAAEA_KXZ
     ?size@?$__deque_base@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@IEBAAEB_KXZ
-    ?size@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAAEA_KXZ
+    ?size@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAAEA_KXZ
     ?size@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEBA_KXZ
     ?size@?$initializer_list@PEAUCordRep@cord_internal@absl@@@std@@QEBA_KXZ
     ?size@?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@QEBA_KXZ
diff --git a/third_party/abseil-cpp/symbols_x64_rel.def b/third_party/abseil-cpp/symbols_x64_rel.def
index fdd47fe6..325dfef 100644
--- a/third_party/abseil-cpp/symbols_x64_rel.def
+++ b/third_party/abseil-cpp/symbols_x64_rel.def
@@ -1,7 +1,6 @@
 EXPORTS
     ??$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$?4V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAAEAV01@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
-    ??$?BV?$allocator@D@__1@std@@@string_view@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ
     ??$?MUsecond_tag@detail@cctz@time_internal@absl@@U01234@@detail@cctz@time_internal@absl@@YA_NAEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@0@Z
     ??$?RW4LogSeverity@absl@@AEBQEBDHAEAPEBD@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@AEBQEBD$$QEAHAEAPEBD@Z
     ??$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV012@PEAV012@0_K1@Z
@@ -72,18 +71,20 @@
     ??$StrReplaceAll@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@@absl@@YAHAEBV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@2@@Z
     ??$ToChronoDuration@V?$duration@JV?$ratio@$0DM@$00@__1@std@@@chrono@__1@std@@@time_internal@absl@@YA?AV?$duration@JV?$ratio@$0DM@$00@__1@std@@@chrono@__1@std@@VDuration@1@@Z
     ??$ToChronoDuration@V?$duration@JV?$ratio@$0OBA@$00@__1@std@@@chrono@__1@std@@@time_internal@absl@@YA?AV?$duration@JV?$ratio@$0OBA@$00@__1@std@@@chrono@__1@std@@VDuration@1@@Z
+    ??$__construct_node_hash@AEBUpiecewise_construct_t@__1@std@@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAA?AV?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@12@_KAEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
     ??$__emplace_back_slow_path@AEAVstring_view@absl@@AEBV12@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@AEAAXAEAVstring_view@absl@@AEBV34@AEA_K@Z
-    ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@_N@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
+    ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@_N@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
     ??$__push_back_slow_path@AEBUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXAEBUTransition@cctz@time_internal@absl@@@Z
     ??$__push_back_slow_path@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAX$$QEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ??$__upper_bound@AEAUByCivilTime@Transition@cctz@time_internal@absl@@PEBU2345@U2345@@__1@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@AEAUByCivilTime@2345@@Z
     ??$assign@PEBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QEAAXPEBVFormatArgImpl@str_format_internal@absl@@0@Z
     ??$assign@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$optional_data_base@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@optional_internal@absl@@IEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
+    ??$construct@UPayload@status_internal@absl@@AEBU123@@?$allocator@UPayload@status_internal@absl@@@__1@std@@QEAAXPEAUPayload@status_internal@absl@@AEBU345@@Z
     ??$emplace@$$V@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA?AV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@12@V?$__wrap_iter@PEBUTransition@cctz@time_internal@absl@@@12@@Z
     ??$emplace@$$V@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA?AV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@12@V?$__wrap_iter@PEBUTransitionType@cctz@time_internal@absl@@@12@@Z
     ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ
     ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ
-    ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
+    ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@Vstring_view@2@@Z
     ??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@XZ
     ??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@_K@Z
@@ -117,9 +118,7 @@
     ??0Rep@GraphCycles@synchronization_internal@absl@@QEAA@XZ
     ??0SpinLock@base_internal@absl@@QEAA@W4SchedulingMode@12@@Z
     ??0Status@absl@@QEAA@W4StatusCode@1@Vstring_view@1@@Z
-    ??0StatusRep@status_internal@absl@@QEAA@W4StatusCode@2@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@V?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@56@@Z
     ??0Streamable@str_format_internal@absl@@QEAA@AEBVUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
-    ??0TimeZoneInfo@cctz@time_internal@absl@@QEAA@XZ
     ??0TimeZoneLibC@cctz@time_internal@absl@@QEAA@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??0Waiter@synchronization_internal@absl@@QEAA@XZ
     ??0int128@absl@@QEAA@M@Z
@@ -757,13 +756,13 @@
     ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z
     ?__construct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
     ?__construct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
-    ?__deallocate_node@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAXPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@@Z
-    ?__rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAX_K@Z
+    ?__deallocate_node@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAXPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@@Z
+    ?__rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAX_K@Z
     ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAPEAUTransition@cctz@time_internal@absl@@AEAU?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@23@PEAU4567@@Z
     ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAPEAUTransitionType@cctz@time_internal@absl@@AEAU?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@23@PEAU4567@@Z
     ?__vallocate@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
     ?__vallocate@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
-    ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAXXZ
+    ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAXXZ
     ?code@Status@absl@@QEBA?AW4StatusCode@2@XZ
     ?cord_ring_buffer_enabled@cord_internal@absl@@3U?$atomic@_N@__1@std@@A
     ?day_difference@impl@detail@cctz@time_internal@absl@@YA_J_JCC0CC@Z
@@ -811,7 +810,7 @@
     ?push_front@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXAEBQEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ?push_front@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ?raw_code@Status@absl@@QEBAHXZ
-    ?rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAX_K@Z
+    ?rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAX_K@Z
     ?reserve@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z
     ?reserve@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z
     ?reserve@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z
diff --git a/third_party/abseil-cpp/symbols_x64_rel_asan.def b/third_party/abseil-cpp/symbols_x64_rel_asan.def
index a29b5e1..5b1950c 100644
--- a/third_party/abseil-cpp/symbols_x64_rel_asan.def
+++ b/third_party/abseil-cpp/symbols_x64_rel_asan.def
@@ -1,7 +1,6 @@
 EXPORTS
     ??$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$?4V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QEAAAEAV01@$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
-    ??$?BV?$allocator@D@__1@std@@@string_view@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ
     ??$?MUsecond_tag@detail@cctz@time_internal@absl@@U01234@@detail@cctz@time_internal@absl@@YA_NAEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@0@Z
     ??$?RW4LogSeverity@absl@@AEBQEBDHAEAPEBD@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@AEBQEBD$$QEAHAEAPEBD@Z
     ??$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV012@PEAV012@0_K1@Z
@@ -74,21 +73,23 @@
     ??$ToChronoDuration@V?$duration@JV?$ratio@$0OBA@$00@__1@std@@@chrono@__1@std@@@time_internal@absl@@YA?AV?$duration@JV?$ratio@$0OBA@$00@__1@std@@@chrono@__1@std@@VDuration@1@@Z
     ??$__construct_at_end@PEBQEAUCordRep@cord_internal@absl@@@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAXPEBQEAUCordRep@cord_internal@absl@@0_K@Z
     ??$__construct_at_end@PEBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAXPEBVFormatArgImpl@str_format_internal@absl@@0_K@Z
+    ??$__construct_node_hash@AEBUpiecewise_construct_t@__1@std@@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAA?AV?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@12@_KAEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
     ??$__construct_one_at_end@$$V@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXXZ
     ??$__construct_one_at_end@$$V@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXXZ
     ??$__construct_one_at_end@AEAVstring_view@absl@@AEBV12@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@AEAAXAEAVstring_view@absl@@AEBV34@AEA_K@Z
     ??$__construct_one_at_end@AEBQEAUCordRep@cord_internal@absl@@@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAXAEBQEAUCordRep@cord_internal@absl@@@Z
     ??$__construct_one_at_end@AEBUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXAEBUTransition@cctz@time_internal@absl@@@Z
-    ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@_N@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
+    ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@_N@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QEAV?$tuple@$$V@12@@Z
     ??$__push_back_slow_path@AEBQEAUCordRep@cord_internal@absl@@@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAXAEBQEAUCordRep@cord_internal@absl@@@Z
     ??$__upper_bound@AEAUByCivilTime@Transition@cctz@time_internal@absl@@PEBU2345@U2345@@__1@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@AEAUByCivilTime@2345@@Z
     ??$assign@PEBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QEAAXPEBVFormatArgImpl@str_format_internal@absl@@0@Z
     ??$assign@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$optional_data_base@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@optional_internal@absl@@IEAAX$$QEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
+    ??$construct@UPayload@status_internal@absl@@AEBU123@@?$allocator@UPayload@status_internal@absl@@@__1@std@@QEAAXPEAUPayload@status_internal@absl@@AEBU345@@Z
     ??$emplace@$$V@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA?AV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@12@V?$__wrap_iter@PEBUTransition@cctz@time_internal@absl@@@12@@Z
     ??$emplace@$$V@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA?AV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@12@V?$__wrap_iter@PEBUTransitionType@cctz@time_internal@absl@@@12@@Z
     ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ
     ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ
-    ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
+    ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@Vstring_view@2@@Z
     ??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@XZ
     ??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@_K@Z
@@ -122,9 +123,7 @@
     ??0Rep@GraphCycles@synchronization_internal@absl@@QEAA@XZ
     ??0SpinLock@base_internal@absl@@QEAA@W4SchedulingMode@12@@Z
     ??0Status@absl@@QEAA@W4StatusCode@1@Vstring_view@1@@Z
-    ??0StatusRep@status_internal@absl@@QEAA@W4StatusCode@2@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@V?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@56@@Z
     ??0Streamable@str_format_internal@absl@@QEAA@AEBVUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
-    ??0TimeZoneInfo@cctz@time_internal@absl@@QEAA@XZ
     ??0TimeZoneLibC@cctz@time_internal@absl@@QEAA@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??0Waiter@synchronization_internal@absl@@QEAA@XZ
     ??0_ConstructTransaction@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAA@AEAV123@_K@Z
@@ -779,10 +778,10 @@
     ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z
     ?__construct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
     ?__construct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
-    ?__deallocate_node@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAXPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@@Z
+    ?__deallocate_node@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAXPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@23@@Z
     ?__move_range@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXPEAUTransition@cctz@time_internal@absl@@00@Z
     ?__move_range@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXPEAUTransitionType@cctz@time_internal@absl@@00@Z
-    ?__rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAX_K@Z
+    ?__rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AEAAX_K@Z
     ?__swap_out_circular_buffer@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAXAEAU?$__split_buffer@PEAUCordRep@cord_internal@absl@@AEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@23@@Z
     ?__swap_out_circular_buffer@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAXAEAU?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@23@@Z
     ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAPEAUTransition@cctz@time_internal@absl@@AEAU?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@23@PEAU4567@@Z
@@ -793,7 +792,7 @@
     ?__vallocate@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
     ?__vallocate@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
     ?__vdeallocate@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AEAAXXZ
-    ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAXXZ
+    ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAXXZ
     ?clear@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ
     ?clear@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QEAAXXZ
     ?code@Status@absl@@QEBA?AW4StatusCode@2@XZ
@@ -845,7 +844,7 @@
     ?push_front@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXAEBQEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ?push_front@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ?raw_code@Status@absl@@QEBAHXZ
-    ?rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAX_K@Z
+    ?rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAX_K@Z
     ?reserve@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z
     ?reserve@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z
     ?reserve@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QEAAX_K@Z
diff --git a/third_party/abseil-cpp/symbols_x86_dbg.def b/third_party/abseil-cpp/symbols_x86_dbg.def
index b9ba368..b6650fe20 100644
--- a/third_party/abseil-cpp/symbols_x86_dbg.def
+++ b/third_party/abseil-cpp/symbols_x86_dbg.def
@@ -2,13 +2,6 @@
     ??$?0$$CBD$0A@@VoidPtr@str_format_internal@absl@@QAE@PBD@Z
     ??$?0$$CBU?$atomic@_N@__1@std@@@Condition@absl@@QAE@P6A_NPBU?$atomic@_N@__1@std@@@Z0@Z
     ??$?0$$CBVFormatArgImpl@str_format_internal@absl@@$$CBV012@@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QAE@V?$initializer_list@VFormatArgImpl@str_format_internal@absl@@@std@@@Z
-    ??$?0$$T$00@?$__compressed_pair@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PAPAUCordRep@cord_internal@absl@@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PAUTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PAUTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PAUViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$T@Z
-    ??$?0$$T$00@?$__compressed_pair@PAVFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$T@Z
     ??$?0$$T@?$Storage@PAH$00$0A@@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@3@$$QA$$T@Z
     ??$?0$$T@?$Storage@PAPAUCordRep@cord_internal@absl@@$00$0A@@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@3@$$QA$$T@Z
     ??$?0$$T@?$Storage@PAPBUCordRep@cord_internal@absl@@$00$0A@@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@3@$$QA$$T@Z
@@ -20,6 +13,13 @@
     ??$?0$$TAAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@?$__compressed_pair@PAUTransition@cctz@time_internal@absl@@AAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$TAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
     ??$?0$$TAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@?$__compressed_pair@PAUTransitionType@cctz@time_internal@absl@@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$TAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
     ??$?0$$TAAV?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@?$__compressed_pair@PAUViableSubstitution@strings_internal@absl@@AAV?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$TAAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$T$$QAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PAPAUCordRep@cord_internal@absl@@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$T$$QAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$T$$QAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PAUTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$T$$QAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PAUTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$T$$QAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PAUViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$T$$QAU__default_init_tag@12@@Z
+    ??$?0$$TU__default_init_tag@__1@std@@@?$__compressed_pair@PAVFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QAE@$$QA$$T$$QAU__default_init_tag@12@@Z
     ??$?0$$TX@?$__compressed_pair_elem@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QAE@$$QA$$T@Z
     ??$?0$$TX@?$__compressed_pair_elem@PAPAUCordRep@cord_internal@absl@@$0A@$0A@@__1@std@@QAE@$$QA$$T@Z
     ??$?0$$TX@?$__compressed_pair_elem@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@$0A@@__1@std@@QAE@$$QA$$T@Z
@@ -52,15 +52,15 @@
     ??$?0AAPAUCordRep@cord_internal@absl@@AAPAU012@$0A@@?$pair@PAUCordRep@cord_internal@absl@@PAU123@@__1@std@@QAE@AAPAUCordRep@cord_internal@absl@@0@Z
     ??$?0AAPAUThreadIdentity@base_internal@absl@@ABQ6AXPAX@Z@?$__compressed_pair@PAUThreadIdentity@base_internal@absl@@P6AXPAX@Z@__1@std@@QAE@AAPAUThreadIdentity@base_internal@absl@@ABQ6AXPAX@Z@Z
     ??$?0AAPAUThreadIdentity@base_internal@absl@@X@?$__compressed_pair_elem@PAUThreadIdentity@base_internal@absl@@$0A@$0A@@__1@std@@QAE@AAPAUThreadIdentity@base_internal@absl@@@Z
-    ??$?0AAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$00@?$__compressed_pair@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QAE@AAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
+    ??$?0AAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QAE@AAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$QAU__default_init_tag@12@@Z
     ??$?0AAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@X@?$__compressed_pair_elem@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$0A@$0A@@__1@std@@QAE@AAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
-    ??$?0AAPAVTimeZoneIf@cctz@time_internal@absl@@$00@?$__compressed_pair@PAVTimeZoneIf@cctz@time_internal@absl@@U?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@AAPAVTimeZoneIf@cctz@time_internal@absl@@@Z
+    ??$?0AAPAVTimeZoneIf@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PAVTimeZoneIf@cctz@time_internal@absl@@U?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@AAPAVTimeZoneIf@cctz@time_internal@absl@@$$QAU__default_init_tag@12@@Z
     ??$?0AAPAVTimeZoneIf@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PAVTimeZoneIf@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QAE@AAPAVTimeZoneIf@cctz@time_internal@absl@@@Z
-    ??$?0AAPAVTimeZoneInfo@cctz@time_internal@absl@@$00@?$__compressed_pair@PAVTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@AAPAVTimeZoneInfo@cctz@time_internal@absl@@@Z
+    ??$?0AAPAVTimeZoneInfo@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PAVTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@AAPAVTimeZoneInfo@cctz@time_internal@absl@@$$QAU__default_init_tag@12@@Z
     ??$?0AAPAVTimeZoneInfo@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PAVTimeZoneInfo@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QAE@AAPAVTimeZoneInfo@cctz@time_internal@absl@@@Z
-    ??$?0AAPAVZoneInfoSource@cctz@time_internal@absl@@$00@?$__compressed_pair@PAVZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@AAPAVZoneInfoSource@cctz@time_internal@absl@@@Z
+    ??$?0AAPAVZoneInfoSource@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PAVZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@AAPAVZoneInfoSource@cctz@time_internal@absl@@$$QAU__default_init_tag@12@@Z
     ??$?0AAPAVZoneInfoSource@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PAVZoneInfoSource@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QAE@AAPAVZoneInfoSource@cctz@time_internal@absl@@@Z
-    ??$?0AAPBVImpl@time_zone@cctz@time_internal@absl@@$00@?$__compressed_pair@PBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@AAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
+    ??$?0AAPBVImpl@time_zone@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@AAPBVImpl@time_zone@cctz@time_internal@absl@@$$QAU__default_init_tag@12@@Z
     ??$?0AAPBVImpl@time_zone@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PBVImpl@time_zone@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QAE@AAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??$?0AAV?$allocator@H@__1@std@@$$T$00@?$CompressedTuple@V?$allocator@H@__1@std@@PAH@container_internal@absl@@QAE@AAV?$allocator@H@__1@std@@$$QA$$T@Z
     ??$?0AAV?$allocator@H@__1@std@@$$T@?$CompressedTupleImpl@V?$CompressedTuple@V?$allocator@H@__1@std@@PAH@container_internal@absl@@U?$integer_sequence@I$0A@$00@3@$00@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@3@AAV?$allocator@H@__1@std@@$$QA$$T@Z
@@ -94,20 +94,20 @@
     ??$?0ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$$Z$$V@?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QAE@Upiecewise_construct_t@12@V?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@V?$tuple@$$V@12@@Z
     ??$?0ABVCord@absl@@$0A@@?$optional@VCord@absl@@@absl@@QAE@ABVCord@1@@Z
     ??$?0ABVCord@absl@@@?$optional_data_dtor_base@VCord@absl@@$0A@@optional_internal@absl@@IAE@Uin_place_t@2@ABVCord@2@@Z
-    ??$?0H$00@?$__compressed_pair@IV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QAE@$$QAH@Z
-    ??$?0H$00@?$__compressed_pair@IV?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QAE@$$QAH@Z
-    ??$?0H$00@?$__compressed_pair@IV?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@$$QAH@Z
     ??$?0H@?$Storage@I$00$0A@@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@3@$$QAH@Z
     ??$?0H@FormatArgImpl@str_format_internal@absl@@QAE@ABH@Z
-    ??$?0M$00@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QAE@$$QAM@Z
-    ??$?0PAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@$00@?$__compressed_pair@PAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@23@@__1@std@@QAE@$$QAPAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@@Z
+    ??$?0HU__default_init_tag@__1@std@@@?$__compressed_pair@IV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QAE@$$QAH$$QAU__default_init_tag@12@@Z
+    ??$?0HU__default_init_tag@__1@std@@@?$__compressed_pair@IV?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QAE@$$QAH$$QAU__default_init_tag@12@@Z
+    ??$?0HU__default_init_tag@__1@std@@@?$__compressed_pair@IV?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@$$QAH$$QAU__default_init_tag@12@@Z
+    ??$?0MU__default_init_tag@__1@std@@@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QAE@$$QAM$$QAU__default_init_tag@12@@Z
+    ??$?0PAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@U__default_init_tag@12@@?$__compressed_pair@PAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@23@@__1@std@@QAE@$$QAPAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@$$QAU__default_init_tag@12@@Z
     ??$?0PAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@X@?$__compressed_pair_elem@PAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@$0A@$0A@@__1@std@@QAE@$$QAPAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@@Z
     ??$?0PAUTransition@cctz@time_internal@absl@@@?$__wrap_iter@PBUTransition@cctz@time_internal@absl@@@__1@std@@QAE@ABV?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@12@PAX@Z
     ??$?0PAUTransitionType@cctz@time_internal@absl@@@?$__wrap_iter@PBUTransitionType@cctz@time_internal@absl@@@__1@std@@QAE@ABV?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@12@PAX@Z
-    ??$?0PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$00@?$__compressed_pair@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QAE@$$QAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
     ??$?0PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@?$__compressed_pair@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QAE@$$QAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$QAU?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@12@@Z
+    ??$?0PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QAE@$$QAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$QAU__default_init_tag@12@@Z
     ??$?0PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@X@?$__compressed_pair_elem@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$0A@$0A@@__1@std@@QAE@$$QAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
-    ??$?0PAVZoneInfoSource@cctz@time_internal@absl@@$00@?$__compressed_pair@PAVZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@$$QAPAVZoneInfoSource@cctz@time_internal@absl@@@Z
+    ??$?0PAVZoneInfoSource@cctz@time_internal@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PAVZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@$$QAPAVZoneInfoSource@cctz@time_internal@absl@@$$QAU__default_init_tag@12@@Z
     ??$?0PAVZoneInfoSource@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PAVZoneInfoSource@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QAE@$$QAPAVZoneInfoSource@cctz@time_internal@absl@@@Z
     ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@X@?$__compressed_pair_elem@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@$00$00@__1@std@@QAE@$$QAU?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@12@@Z
     ??$?0UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAE@$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@$$V$00@?$CompressedTuple@UStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAE@$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@container_internal@absl@@QAE@$$QAUStringReleaser@?M@???$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@2@QAE@$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@@Z
@@ -436,39 +436,27 @@
     ??$UnhidePtr@X@base_internal@absl@@YAPAXI@Z
     ??$__advance@PBUTransition@cctz@time_internal@absl@@@__1@std@@YAXAAPBUTransition@cctz@time_internal@absl@@HUrandom_access_iterator_tag@01@@Z
     ??$__advance@PBVFormatArgImpl@str_format_internal@absl@@@__1@std@@YAXAAPBVFormatArgImpl@str_format_internal@absl@@HUrandom_access_iterator_tag@01@@Z
-    ??$__construct@PAPBVImpl@time_zone@cctz@time_internal@absl@@ABQAPBV12345@@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@ABQAPBV56789@@Z
-    ??$__construct@PAPBVImpl@time_zone@cctz@time_internal@absl@@PAPBV12345@@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@$$QAPAPBV56789@@Z
-    ??$__construct@PAUCordRep@cord_internal@absl@@ABQAU123@@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@PAUCordRep@cord_internal@absl@@@12@PAPAUCordRep@cord_internal@absl@@ABQAU567@@Z
-    ??$__construct@PBVImpl@time_zone@cctz@time_internal@absl@@ABQBV12345@@?$allocator_traits@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@12@PAPBVImpl@time_zone@cctz@time_internal@absl@@ABQBV56789@@Z
-    ??$__construct@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@ABUpiecewise_construct_t@23@V?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@PAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@ABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QAV?$tuple@$$V@12@@Z
-    ??$__construct@UConversionItem@ParsedFormatBase@str_format_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QAU5678@@Z
-    ??$__construct@UTransition@cctz@time_internal@absl@@$$V@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PAUTransition@cctz@time_internal@absl@@@Z
-    ??$__construct@UTransition@cctz@time_internal@absl@@ABU1234@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PAUTransition@cctz@time_internal@absl@@ABU5678@@Z
-    ??$__construct@UTransition@cctz@time_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PAUTransition@cctz@time_internal@absl@@$$QAU5678@@Z
-    ??$__construct@UTransitionType@cctz@time_internal@absl@@$$V@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PAUTransitionType@cctz@time_internal@absl@@@Z
-    ??$__construct@UTransitionType@cctz@time_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PAUTransitionType@cctz@time_internal@absl@@$$QAU5678@@Z
-    ??$__construct@UViableSubstitution@strings_internal@absl@@AAVstring_view@3@ABV43@AAI@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PAUViableSubstitution@strings_internal@absl@@AAVstring_view@7@ABV87@AAI@Z
     ??$__construct_at_end@PBQAUCordRep@cord_internal@absl@@@?$vector@PAUCordRep@cord_internal@absl@@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AAEXPBQAUCordRep@cord_internal@absl@@0I@Z
     ??$__construct_at_end@PBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AAEXPBVFormatArgImpl@str_format_internal@absl@@0I@Z
     ??$__construct_at_end@V?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXV?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
     ??$__construct_at_end@V?$move_iterator@PAUTransition@cctz@time_internal@absl@@@__1@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@AAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXV?$move_iterator@PAUTransition@cctz@time_internal@absl@@@12@0@Z
     ??$__construct_at_end@V?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@__1@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXV?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@12@0@Z
-    ??$__construct_backward_with_exception_guarantees@PAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@PAUCordRep@cord_internal@absl@@@12@PAPAUCordRep@cord_internal@absl@@1AAPAPAU456@@Z
-    ??$__construct_backward_with_exception_guarantees@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@1AAPAU4567@@Z
-    ??$__construct_backward_with_exception_guarantees@UTransition@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PAUTransition@cctz@time_internal@absl@@1AAPAU4567@@Z
-    ??$__construct_backward_with_exception_guarantees@UTransitionType@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PAUTransitionType@cctz@time_internal@absl@@1AAPAU4567@@Z
-    ??$__construct_backward_with_exception_guarantees@UViableSubstitution@strings_internal@absl@@@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PAUViableSubstitution@strings_internal@absl@@1AAPAU456@@Z
-    ??$__construct_forward_with_exception_guarantees@UTransition@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PAUTransition@cctz@time_internal@absl@@1AAPAU4567@@Z
-    ??$__construct_forward_with_exception_guarantees@UTransitionType@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PAUTransitionType@cctz@time_internal@absl@@1AAPAU4567@@Z
-    ??$__construct_node_hash@ABUpiecewise_construct_t@__1@std@@V?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AAE?AV?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@23@@12@IABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QAV?$tuple@$$V@12@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@PAUCordRep@cord_internal@absl@@X@__1@std@@YAXAAV?$allocator@PAUCordRep@cord_internal@absl@@@01@PAPAUCordRep@cord_internal@absl@@1AAPAPAU345@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@X@__1@std@@YAXAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@01@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@1AAPAU3456@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@UTransition@cctz@time_internal@absl@@X@__1@std@@YAXAAV?$allocator@UTransition@cctz@time_internal@absl@@@01@PAUTransition@cctz@time_internal@absl@@1AAPAU3456@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@UTransitionType@cctz@time_internal@absl@@X@__1@std@@YAXAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@01@PAUTransitionType@cctz@time_internal@absl@@1AAPAU3456@@Z
+    ??$__construct_backward_with_exception_guarantees@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@UViableSubstitution@strings_internal@absl@@X@__1@std@@YAXAAV?$allocator@UViableSubstitution@strings_internal@absl@@@01@PAUViableSubstitution@strings_internal@absl@@1AAPAU345@@Z
+    ??$__construct_forward_with_exception_guarantees@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@PAUTransition@cctz@time_internal@absl@@@__1@std@@YAXAAV?$allocator@UTransition@cctz@time_internal@absl@@@01@PAUTransition@cctz@time_internal@absl@@1AAPAU3456@@Z
+    ??$__construct_forward_with_exception_guarantees@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@PAUTransitionType@cctz@time_internal@absl@@@__1@std@@YAXAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@01@PAUTransitionType@cctz@time_internal@absl@@1AAPAU3456@@Z
+    ??$__construct_node_hash@ABUpiecewise_construct_t@__1@std@@V?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AAE?AV?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@23@@12@IABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QAV?$tuple@$$V@12@@Z
     ??$__construct_one_at_end@$$V@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXXZ
     ??$__construct_one_at_end@$$V@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXXZ
     ??$__construct_one_at_end@AAVstring_view@absl@@ABV12@AAI@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@AAEXAAVstring_view@absl@@ABV34@AAI@Z
     ??$__construct_one_at_end@ABQAUCordRep@cord_internal@absl@@@?$vector@PAUCordRep@cord_internal@absl@@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AAEXABQAUCordRep@cord_internal@absl@@@Z
     ??$__construct_one_at_end@ABUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXABUTransition@cctz@time_internal@absl@@@Z
     ??$__construct_one_at_end@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AAEX$$QAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
-    ??$__construct_range_forward@$$CBVFormatArgImpl@str_format_internal@absl@@V123@V123@V123@@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PBVFormatArgImpl@str_format_internal@absl@@1AAPAV456@@Z
-    ??$__construct_range_forward@QAUCordRep@cord_internal@absl@@PAU123@PAU123@PAU123@@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@PAUCordRep@cord_internal@absl@@@12@PBQAUCordRep@cord_internal@absl@@1AAPAPAU456@@Z
+    ??$__construct_range_forward@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@QAUCordRep@cord_internal@absl@@PAU456@PAU456@PAU456@X@__1@std@@YAXAAV?$allocator@PAUCordRep@cord_internal@absl@@@01@PBQAUCordRep@cord_internal@absl@@1AAPAPAU345@@Z
+    ??$__construct_range_forward@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@$$CBVFormatArgImpl@str_format_internal@absl@@V456@V456@V456@X@__1@std@@YAXAAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@01@PBVFormatArgImpl@str_format_internal@absl@@1AAPAV345@@Z
     ??$__copy@$$CBVFormatArgImpl@str_format_internal@absl@@V123@@__1@std@@YAPAVFormatArgImpl@str_format_internal@absl@@PBV234@0PAV234@@Z
     ??$__cxx_atomic_compare_exchange_weak@PAUHashtablezInfo@container_internal@absl@@@__1@std@@YA_NPAU?$__cxx_atomic_base_impl@PAUHashtablezInfo@container_internal@absl@@@01@PAPAUHashtablezInfo@container_internal@absl@@PAU345@W4memory_order@01@3@Z
     ??$__cxx_atomic_exchange@P6AXABUHashtablezInfo@container_internal@absl@@@Z@__1@std@@YAP6AXABUHashtablezInfo@container_internal@absl@@@ZPAU?$__cxx_atomic_base_impl@P6AXABUHashtablezInfo@container_internal@absl@@@Z@01@P6AX0@ZW4memory_order@01@@Z
@@ -478,14 +466,6 @@
     ??$__cxx_atomic_load@W4State@PerThreadSynch@base_internal@absl@@@__1@std@@YA?AW4State@PerThreadSynch@base_internal@absl@@PBU?$__cxx_atomic_base_impl@W4State@PerThreadSynch@base_internal@absl@@@01@W4memory_order@01@@Z
     ??$__cxx_atomic_store@W4OnDeadlockCycle@absl@@@__1@std@@YAXPAU?$__cxx_atomic_base_impl@W4OnDeadlockCycle@absl@@@01@W4OnDeadlockCycle@absl@@W4memory_order@01@@Z
     ??$__cxx_atomic_store@W4State@PerThreadSynch@base_internal@absl@@@__1@std@@YAXPAU?$__cxx_atomic_base_impl@W4State@PerThreadSynch@base_internal@absl@@@01@W4State@PerThreadSynch@base_internal@absl@@W4memory_order@01@@Z
-    ??$__destroy@PAPBVImpl@time_zone@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
-    ??$__destroy@PAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@PAUCordRep@cord_internal@absl@@@12@PAPAUCordRep@cord_internal@absl@@@Z
-    ??$__destroy@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$0A@@12@AAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@PAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
-    ??$__destroy@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
-    ??$__destroy@UTransition@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PAUTransition@cctz@time_internal@absl@@@Z
-    ??$__destroy@UTransitionType@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PAUTransitionType@cctz@time_internal@absl@@@Z
-    ??$__destroy@UViableSubstitution@strings_internal@absl@@@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PAUViableSubstitution@strings_internal@absl@@@Z
-    ??$__destroy@VFormatArgImpl@str_format_internal@absl@@@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@CAXU?$integral_constant@_N$00@12@AAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PAVFormatArgImpl@str_format_internal@absl@@@Z
     ??$__distance@PBUPayload@status_internal@absl@@@__1@std@@YAHPBUPayload@status_internal@absl@@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@PBUTransition@cctz@time_internal@absl@@@__1@std@@YAHPBUTransition@cctz@time_internal@absl@@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@PBVFormatArgImpl@str_format_internal@absl@@@__1@std@@YAHPBVFormatArgImpl@str_format_internal@absl@@0Urandom_access_iterator_tag@01@@Z
@@ -493,7 +473,7 @@
     ??$__distance@V?$move_iterator@PAUTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@YAHV?$move_iterator@PAUTransition@cctz@time_internal@absl@@@01@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@V?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@YAHV?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@01@0Urandom_access_iterator_tag@01@@Z
     ??$__emplace_back_slow_path@AAVstring_view@absl@@ABV12@AAI@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@AAEXAAVstring_view@absl@@ABV34@AAI@Z
-    ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@ABUpiecewise_construct_t@23@V?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE?AU?$pair@V?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@_N@12@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@ABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QAV?$tuple@$$V@12@@Z
+    ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@ABUpiecewise_construct_t@23@V?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE?AU?$pair@V?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@_N@12@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@ABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QAV?$tuple@$$V@12@@Z
     ??$__lower_bound@AAUByUnixTime@Transition@cctz@time_internal@absl@@PBU2345@U2345@@__1@std@@YAPBUTransition@cctz@time_internal@absl@@PBU2345@0ABU2345@AAUByUnixTime@2345@@Z
     ??$__move@PAPBVImpl@time_zone@cctz@time_internal@absl@@PAPBV12345@@__1@std@@YAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPAPBV23456@00@Z
     ??$__move@UTransition@cctz@time_internal@absl@@U1234@@__1@std@@YAPAUTransition@cctz@time_internal@absl@@PAU2345@00@Z
@@ -504,13 +484,13 @@
     ??$__push_back_slow_path@ABQAUCordRep@cord_internal@absl@@@?$vector@PAUCordRep@cord_internal@absl@@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AAEXABQAUCordRep@cord_internal@absl@@@Z
     ??$__push_back_slow_path@ABUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXABUTransition@cctz@time_internal@absl@@@Z
     ??$__push_back_slow_path@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AAEX$$QAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
-    ??$__to_raw_pointer@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPAPBV23456@@Z
-    ??$__to_raw_pointer@PAUCordRep@cord_internal@absl@@@__1@std@@YAPAPAUCordRep@cord_internal@absl@@PAPAU234@@Z
-    ??$__to_raw_pointer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@YAPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@PAU2345@@Z
-    ??$__to_raw_pointer@UTransition@cctz@time_internal@absl@@@__1@std@@YAPAUTransition@cctz@time_internal@absl@@PAU2345@@Z
-    ??$__to_raw_pointer@UTransitionType@cctz@time_internal@absl@@@__1@std@@YAPAUTransitionType@cctz@time_internal@absl@@PAU2345@@Z
-    ??$__to_raw_pointer@UViableSubstitution@strings_internal@absl@@@__1@std@@YAPAUViableSubstitution@strings_internal@absl@@PAU234@@Z
-    ??$__to_raw_pointer@VFormatArgImpl@str_format_internal@absl@@@__1@std@@YAPAVFormatArgImpl@str_format_internal@absl@@PAV234@@Z
+    ??$__to_address@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPAPBV23456@@Z
+    ??$__to_address@PAUCordRep@cord_internal@absl@@@__1@std@@YAPAPAUCordRep@cord_internal@absl@@PAPAU234@@Z
+    ??$__to_address@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@YAPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@PAU2345@@Z
+    ??$__to_address@UTransition@cctz@time_internal@absl@@@__1@std@@YAPAUTransition@cctz@time_internal@absl@@PAU2345@@Z
+    ??$__to_address@UTransitionType@cctz@time_internal@absl@@@__1@std@@YAPAUTransitionType@cctz@time_internal@absl@@PAU2345@@Z
+    ??$__to_address@UViableSubstitution@strings_internal@absl@@@__1@std@@YAPAUViableSubstitution@strings_internal@absl@@PAU234@@Z
+    ??$__to_address@VFormatArgImpl@str_format_internal@absl@@@__1@std@@YAPAVFormatArgImpl@str_format_internal@absl@@PAV234@@Z
     ??$__unwrap_iter@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPAPBV23456@@Z
     ??$__unwrap_iter@PAUTransition@cctz@time_internal@absl@@@__1@std@@YAPAUTransition@cctz@time_internal@absl@@PAU2345@@Z
     ??$__unwrap_iter@PAUTransitionType@cctz@time_internal@absl@@@__1@std@@YAPAUTransitionType@cctz@time_internal@absl@@PAU2345@@Z
@@ -530,8 +510,8 @@
     ??$addressof@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@YAPAV?$allocator@PBUCordRep@cord_internal@absl@@@01@AAV201@@Z
     ??$addressof@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@__1@std@@YAPAV?$allocator@UPayload@status_internal@absl@@@01@AAV201@@Z
     ??$addressof@V?$allocator@USubRange@absl@@@__1@std@@@__1@std@@YAPAV?$allocator@USubRange@absl@@@01@AAV201@@Z
-    ??$advance@PBUTransition@cctz@time_internal@absl@@@__1@std@@YAXAAPBUTransition@cctz@time_internal@absl@@H@Z
-    ??$advance@PBVFormatArgImpl@str_format_internal@absl@@@__1@std@@YAXAAPBVFormatArgImpl@str_format_internal@absl@@H@Z
+    ??$advance@PBUTransition@cctz@time_internal@absl@@H@__1@std@@YAXAAPBUTransition@cctz@time_internal@absl@@H@Z
+    ??$advance@PBVFormatArgImpl@str_format_internal@absl@@I@__1@std@@YAXAAPBVFormatArgImpl@str_format_internal@absl@@I@Z
     ??$assign@PBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QAEXPBVFormatArgImpl@str_format_internal@absl@@0@Z
     ??$assign@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$optional_data_base@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@optional_internal@absl@@IAEX$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$bit_cast@_J_K$0A@@absl@@YA_JAB_K@Z
@@ -540,12 +520,12 @@
     ??$construct@HABH@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@SAXAAV?$allocator@H@__1@std@@PAHABH@Z
     ??$construct@HH@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@SAXAAV?$allocator@H@__1@std@@PAH$$QAH@Z
     ??$construct@PAPBVImpl@time_zone@cctz@time_internal@absl@@ABQAPBV12345@@?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@ABQAPBV34567@@Z
-    ??$construct@PAPBVImpl@time_zone@cctz@time_internal@absl@@ABQAPBV12345@@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@ABQAPBV45678@@Z
+    ??$construct@PAPBVImpl@time_zone@cctz@time_internal@absl@@ABQAPBV12345@X@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@ABQAPBV45678@@Z
     ??$construct@PAPBVImpl@time_zone@cctz@time_internal@absl@@PAPBV12345@@?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@$$QAPAPBV34567@@Z
-    ??$construct@PAPBVImpl@time_zone@cctz@time_internal@absl@@PAPBV12345@@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@$$QAPAPBV45678@@Z
+    ??$construct@PAPBVImpl@time_zone@cctz@time_internal@absl@@PAPBV12345@X@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@$$QAPAPBV45678@@Z
     ??$construct@PAUCordRep@cord_internal@absl@@ABQAU123@@?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@QAEXPAPAUCordRep@cord_internal@absl@@ABQAU345@@Z
-    ??$construct@PAUCordRep@cord_internal@absl@@ABQAU123@@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@PAUCordRep@cord_internal@absl@@@12@PAPAUCordRep@cord_internal@absl@@ABQAU456@@Z
     ??$construct@PAUCordRep@cord_internal@absl@@ABQAU123@@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAAV?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@PAPAUCordRep@cord_internal@1@ABQAU561@@Z
+    ??$construct@PAUCordRep@cord_internal@absl@@ABQAU123@X@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@PAUCordRep@cord_internal@absl@@@12@PAPAUCordRep@cord_internal@absl@@ABQAU456@@Z
     ??$construct@PAUCordRep@cord_internal@absl@@PAU123@@?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@QAEXPAPAUCordRep@cord_internal@absl@@$$QAPAU345@@Z
     ??$construct@PAUCordRep@cord_internal@absl@@PAU123@@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAAV?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@PAPAUCordRep@cord_internal@1@$$QAPAU561@@Z
     ??$construct@PBUCordRep@cord_internal@absl@@ABQBU123@@?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@QAEXPAPBUCordRep@cord_internal@absl@@ABQBU345@@Z
@@ -553,11 +533,11 @@
     ??$construct@PBUCordRep@cord_internal@absl@@PBU123@@?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@QAEXPAPBUCordRep@cord_internal@absl@@$$QAPBU345@@Z
     ??$construct@PBUCordRep@cord_internal@absl@@PBU123@@?$allocator_traits@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAAV?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@PAPBUCordRep@cord_internal@1@$$QAPBU561@@Z
     ??$construct@PBVImpl@time_zone@cctz@time_internal@absl@@ABQBV12345@@?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QAEXPAPBVImpl@time_zone@cctz@time_internal@absl@@ABQBV34567@@Z
-    ??$construct@PBVImpl@time_zone@cctz@time_internal@absl@@ABQBV12345@@?$allocator_traits@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@12@PAPBVImpl@time_zone@cctz@time_internal@absl@@ABQBV45678@@Z
+    ??$construct@PBVImpl@time_zone@cctz@time_internal@absl@@ABQBV12345@X@?$allocator_traits@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@12@PAPBVImpl@time_zone@cctz@time_internal@absl@@ABQBV45678@@Z
     ??$construct@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@ABUpiecewise_construct_t@23@V?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@QAEXPAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@ABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QAV?$tuple@$$V@12@@Z
-    ??$construct@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@ABUpiecewise_construct_t@23@V?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@SAXAAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@PAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@ABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QAV?$tuple@$$V@12@@Z
+    ??$construct@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@ABUpiecewise_construct_t@23@V?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@X@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@SAXAAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@PAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@ABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QAV?$tuple@$$V@12@@Z
     ??$construct@UConversionItem@ParsedFormatBase@str_format_internal@absl@@U1234@@?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QAU3456@@Z
-    ??$construct@UConversionItem@ParsedFormatBase@str_format_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QAU4567@@Z
+    ??$construct@UConversionItem@ParsedFormatBase@str_format_internal@absl@@U1234@X@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QAU4567@@Z
     ??$construct@UPayload@status_internal@absl@@ABU123@@?$allocator@UPayload@status_internal@absl@@@__1@std@@QAEXPAUPayload@status_internal@absl@@ABU345@@Z
     ??$construct@UPayload@status_internal@absl@@ABU123@@?$allocator_traits@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@SAXAAV?$allocator@UPayload@status_internal@absl@@@__1@std@@PAUPayload@status_internal@1@ABU561@@Z
     ??$construct@UPayload@status_internal@absl@@U123@@?$allocator@UPayload@status_internal@absl@@@__1@std@@QAEXPAUPayload@status_internal@absl@@$$QAU345@@Z
@@ -565,17 +545,17 @@
     ??$construct@USubRange@absl@@U12@@?$allocator@USubRange@absl@@@__1@std@@QAEXPAUSubRange@absl@@$$QAU34@@Z
     ??$construct@USubRange@absl@@U12@@?$allocator_traits@V?$allocator@USubRange@absl@@@__1@std@@@absl@@SAXAAV?$allocator@USubRange@absl@@@__1@std@@PAUSubRange@1@$$QAU51@@Z
     ??$construct@UTransition@cctz@time_internal@absl@@$$V@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
-    ??$construct@UTransition@cctz@time_internal@absl@@$$V@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PAUTransition@cctz@time_internal@absl@@@Z
+    ??$construct@UTransition@cctz@time_internal@absl@@$$VX@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PAUTransition@cctz@time_internal@absl@@@Z
     ??$construct@UTransition@cctz@time_internal@absl@@ABU1234@@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QAEXPAUTransition@cctz@time_internal@absl@@ABU3456@@Z
-    ??$construct@UTransition@cctz@time_internal@absl@@ABU1234@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PAUTransition@cctz@time_internal@absl@@ABU4567@@Z
+    ??$construct@UTransition@cctz@time_internal@absl@@ABU1234@X@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PAUTransition@cctz@time_internal@absl@@ABU4567@@Z
     ??$construct@UTransition@cctz@time_internal@absl@@U1234@@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QAEXPAUTransition@cctz@time_internal@absl@@$$QAU3456@@Z
-    ??$construct@UTransition@cctz@time_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PAUTransition@cctz@time_internal@absl@@$$QAU4567@@Z
+    ??$construct@UTransition@cctz@time_internal@absl@@U1234@X@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PAUTransition@cctz@time_internal@absl@@$$QAU4567@@Z
     ??$construct@UTransitionType@cctz@time_internal@absl@@$$V@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
-    ??$construct@UTransitionType@cctz@time_internal@absl@@$$V@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PAUTransitionType@cctz@time_internal@absl@@@Z
+    ??$construct@UTransitionType@cctz@time_internal@absl@@$$VX@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PAUTransitionType@cctz@time_internal@absl@@@Z
     ??$construct@UTransitionType@cctz@time_internal@absl@@U1234@@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@$$QAU3456@@Z
-    ??$construct@UTransitionType@cctz@time_internal@absl@@U1234@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PAUTransitionType@cctz@time_internal@absl@@$$QAU4567@@Z
+    ??$construct@UTransitionType@cctz@time_internal@absl@@U1234@X@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PAUTransitionType@cctz@time_internal@absl@@$$QAU4567@@Z
     ??$construct@UViableSubstitution@strings_internal@absl@@AAVstring_view@3@ABV43@AAI@?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@QAEXPAUViableSubstitution@strings_internal@absl@@AAVstring_view@5@ABV65@AAI@Z
-    ??$construct@UViableSubstitution@strings_internal@absl@@AAVstring_view@3@ABV43@AAI@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PAUViableSubstitution@strings_internal@absl@@AAVstring_view@6@ABV76@AAI@Z
+    ??$construct@UViableSubstitution@strings_internal@absl@@AAVstring_view@3@ABV43@AAIX@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PAUViableSubstitution@strings_internal@absl@@AAVstring_view@6@ABV76@AAI@Z
     ??$construct@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$optional_data_base@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@optional_internal@absl@@IAEX$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$construct_impl@V?$allocator@H@__1@std@@AAPAHABH@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@CAXHAAV?$allocator@H@__1@std@@AAPAHABH@Z
     ??$construct_impl@V?$allocator@H@__1@std@@AAPAHH@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@CAXHAAV?$allocator@H@__1@std@@AAPAH$$QAH@Z
@@ -589,18 +569,18 @@
     ??$copy@PBVFormatArgImpl@str_format_internal@absl@@PAV123@@__1@std@@YAPAVFormatArgImpl@str_format_internal@absl@@PBV234@0PAV234@@Z
     ??$countl_zero@_K@absl@@YAH_K@Z
     ??$destroy@H@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@SAXAAV?$allocator@H@__1@std@@PAH@Z
-    ??$destroy@PAPBVImpl@time_zone@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
-    ??$destroy@PAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@PAUCordRep@cord_internal@absl@@@12@PAPAUCordRep@cord_internal@absl@@@Z
+    ??$destroy@PAPBVImpl@time_zone@cctz@time_internal@absl@@X@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??$destroy@PAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAAV?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@PAPAUCordRep@cord_internal@1@@Z
+    ??$destroy@PAUCordRep@cord_internal@absl@@X@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@PAUCordRep@cord_internal@absl@@@12@PAPAUCordRep@cord_internal@absl@@@Z
     ??$destroy@PBUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@absl@@SAXAAV?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@PAPBUCordRep@cord_internal@1@@Z
-    ??$destroy@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@SAXAAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@PAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
-    ??$destroy@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+    ??$destroy@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@XX@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@SAXAAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@PAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
+    ??$destroy@UConversionItem@ParsedFormatBase@str_format_internal@absl@@X@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ??$destroy@UPayload@status_internal@absl@@@?$allocator_traits@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@SAXAAV?$allocator@UPayload@status_internal@absl@@@__1@std@@PAUPayload@status_internal@1@@Z
     ??$destroy@USubRange@absl@@@?$allocator_traits@V?$allocator@USubRange@absl@@@__1@std@@@absl@@SAXAAV?$allocator@USubRange@absl@@@__1@std@@PAUSubRange@1@@Z
-    ??$destroy@UTransition@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PAUTransition@cctz@time_internal@absl@@@Z
-    ??$destroy@UTransitionType@cctz@time_internal@absl@@@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PAUTransitionType@cctz@time_internal@absl@@@Z
-    ??$destroy@UViableSubstitution@strings_internal@absl@@@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PAUViableSubstitution@strings_internal@absl@@@Z
-    ??$destroy@VFormatArgImpl@str_format_internal@absl@@@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PAVFormatArgImpl@str_format_internal@absl@@@Z
+    ??$destroy@UTransition@cctz@time_internal@absl@@X@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@PAUTransition@cctz@time_internal@absl@@@Z
+    ??$destroy@UTransitionType@cctz@time_internal@absl@@X@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@PAUTransitionType@cctz@time_internal@absl@@@Z
+    ??$destroy@UViableSubstitution@strings_internal@absl@@X@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@PAUViableSubstitution@strings_internal@absl@@@Z
+    ??$destroy@VFormatArgImpl@str_format_internal@absl@@X@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SAXAAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PAVFormatArgImpl@str_format_internal@absl@@@Z
     ??$destroy_impl@V?$allocator@H@__1@std@@H@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@CAXHAAV?$allocator@H@__1@std@@PAH@Z
     ??$destroy_impl@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@PAUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@CAXHAAV?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@PAPAUCordRep@cord_internal@1@@Z
     ??$destroy_impl@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@PBUCordRep@cord_internal@absl@@@?$allocator_traits@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@absl@@CAXHAAV?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@PAPBUCordRep@cord_internal@1@@Z
@@ -624,7 +604,7 @@
     ??$emplace_back@PAUCordRep@cord_internal@absl@@@?$InlinedVector@PAUCordRep@cord_internal@absl@@$0CP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QAEAAPAUCordRep@cord_internal@1@$$QAPAU231@@Z
     ??$emplace_back@UPayload@status_internal@absl@@@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QAEAAUPayload@status_internal@1@$$QAU231@@Z
     ??$emplace_back@USubRange@absl@@@?$InlinedVector@USubRange@absl@@$0CP@V?$allocator@USubRange@absl@@@__1@std@@@absl@@QAEAAUSubRange@1@$$QAU21@@Z
-    ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE?AV?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
+    ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE?AV?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??$forward@$$T@absl@@YA$$QA$$TAA$$T@Z
     ??$forward@AAI@absl@@YAAAIAAI@Z
     ??$forward@AAPAPAUCordRep@cord_internal@absl@@@__1@std@@YAAAPAPAUCordRep@cord_internal@absl@@AAPAPAU234@@Z
@@ -735,6 +715,19 @@
     ??$make_pair@AAPAUCordRep@cord_internal@absl@@AAPAU123@@__1@std@@YA?AU?$pair@PAUCordRep@cord_internal@absl@@PAU123@@01@AAPAUCordRep@cord_internal@absl@@0@Z
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$V@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@XZ
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@AAV12@@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@AAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
+    ??$max_size@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@X@?$allocator_traits@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@SAIABV?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@12@@Z
+    ??$max_size@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@PAUCordRep@cord_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@PBUCordRep@cord_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@X@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@SAIABV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@@Z
+    ??$max_size@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@UPayload@status_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UPayload@status_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@UPayload@status_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@USubRange@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@USubRange@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@USubRange@absl@@@12@@Z
+    ??$max_size@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+    ??$max_size@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@@Z
     ??$min@VDuration@absl@@@__1@std@@YAABVDuration@absl@@ABV23@0@Z
     ??$min@VDuration@absl@@U?$__less@VDuration@absl@@V12@@__1@std@@@__1@std@@YAABVDuration@absl@@ABV23@0U?$__less@VDuration@absl@@V12@@01@@Z
     ??$move@AAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YA$$QAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@AAPAPAPBV23456@@Z
@@ -826,20 +819,25 @@
     ??0?$__atomic_base@P6AXABUHashtablezInfo@container_internal@absl@@@Z$0A@@__1@std@@QAE@P6AXABUHashtablezInfo@container_internal@absl@@@Z@Z
     ??0?$__atomic_base@PAUHashtablezInfo@container_internal@absl@@$0A@@__1@std@@QAE@PAUHashtablezInfo@container_internal@absl@@@Z
     ??0?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QAE@XZ
-    ??0?$__compressed_pair_elem@U?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@$0A@$0A@@__1@std@@QAE@XZ
-    ??0?$__compressed_pair_elem@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QAE@XZ
-    ??0?$__compressed_pair_elem@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QAE@XZ
-    ??0?$__compressed_pair_elem@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QAE@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@$00$00@__1@std@@QAE@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@$00$00@__1@std@@QAE@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@XZ
-    ??0?$__compressed_pair_elem@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@XZ
+    ??0?$__compressed_pair_elem@U?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@$0A@$0A@@__1@std@@QAE@U__value_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@$00$00@__1@std@@QAE@U__value_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
+    ??0?$__compressed_pair_elem@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@$00$00@__1@std@@QAE@U__default_init_tag@12@@Z
     ??0?$__cxx_atomic_base_impl@P6AXABUHashtablezInfo@container_internal@absl@@@Z@__1@std@@QAE@P6AXABUHashtablezInfo@container_internal@absl@@@Z@Z
     ??0?$__cxx_atomic_base_impl@PAUHashtablezInfo@container_internal@absl@@@__1@std@@QAE@PAUHashtablezInfo@container_internal@absl@@@Z
     ??0?$__cxx_atomic_impl@P6AXABUHashtablezInfo@container_internal@absl@@@ZU?$__cxx_atomic_base_impl@P6AXABUHashtablezInfo@container_internal@absl@@@Z@__1@std@@@__1@std@@QAE@P6AXABUHashtablezInfo@container_internal@absl@@@Z@Z
@@ -852,7 +850,7 @@
     ??0?$__hash_map_iterator@V?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@QAE@V?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@@Z
     ??0?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@QAE@XZ
     ??0?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@QAE@AAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@_N@Z
-    ??0?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE@XZ
+    ??0?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE@XZ
     ??0?$__policy_invoker@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z@__function@__1@std@@AAE@P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@23@PBT__policy_storage@123@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z@Z
     ??0?$__policy_invoker@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z@__function@__1@std@@QAE@XZ
     ??0?$__policy_invoker@$$A6AXVstring_view@absl@@ABVCord@2@@Z@__function@__1@std@@AAE@P6AXPBT__policy_storage@123@$$QAVstring_view@absl@@ABVCord@6@@Z@Z
@@ -864,8 +862,8 @@
     ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@AAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@IIAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
     ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE@IIAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
     ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@AAV?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QAE@IIAAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
-    ??0?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QAE@XZ
-    ??0?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QAE@XZ
+    ??0?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QAE@XZ
+    ??0?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QAE@XZ
     ??0?$__vector_base@PAUCordRep@cord_internal@absl@@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@IAE@XZ
     ??0?$__vector_base@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@IAE@XZ
     ??0?$__vector_base@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@IAE@XZ
@@ -1380,9 +1378,9 @@
     ??R?$__policy_func@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@__1@std@@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z@__function@__1@std@@QBE?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__1@std@@@23@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@23@@Z
     ??R?$__policy_func@$$A6AXABUHashtablezInfo@container_internal@absl@@@Z@__function@__1@std@@QBEXABUHashtablezInfo@container_internal@absl@@@Z
     ??R?$__policy_func@$$A6AXVstring_view@absl@@ABVCord@2@@Z@__function@__1@std@@QBEX$$QAVstring_view@absl@@ABVCord@5@@Z
-    ??R?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QBE_NABU?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
-    ??R?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QBE_NABU?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
-    ??R?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QBEIABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
+    ??R?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QBE_NABU?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
+    ??R?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QBE_NABU?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
+    ??R?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@QBEIABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??R?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QBEXPBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??R?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@QBEXPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
     ??R?$default_delete@VTimeZoneIf@cctz@time_internal@absl@@@__1@std@@QBEXPAVTimeZoneIf@cctz@time_internal@absl@@@Z
@@ -2445,7 +2443,7 @@
     ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXI@Z
     ?__construct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXI@Z
     ?__construct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXI@Z
-    ?__deallocate_node@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AAEXPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@23@@Z
+    ?__deallocate_node@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AAEXPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@23@@Z
     ?__destruct_at_begin@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ?__destruct_at_begin@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@U?$integral_constant@_N$00@23@@Z
     ?__destruct_at_end@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
@@ -2544,8 +2542,8 @@
     ?__get@?$__compressed_pair_elem@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QAEAAV?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@23@XZ
     ?__get@?$__compressed_pair_elem@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QBEABV?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@23@XZ
     ?__get@?$__compressed_pair_elem@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@$00$0A@@__1@std@@QAEAAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@23@XZ
-    ?__get@?$__compressed_pair_elem@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QAEAAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
-    ?__get@?$__compressed_pair_elem@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QAEAAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?__get@?$__compressed_pair_elem@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QAEAAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?__get@?$__compressed_pair_elem@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@$00$00@__1@std@@QAEAAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?__get@?$__compressed_pair_elem@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@$00$00@__1@std@@QAEAAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?__get@?$__compressed_pair_elem@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@$00$00@__1@std@@QAEAAV?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@23@XZ
     ?__get@?$__compressed_pair_elem@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@$00$00@__1@std@@QAEAAV?$allocator@PAUCordRep@cord_internal@absl@@@23@XZ
@@ -2580,15 +2578,9 @@
     ?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@ABE?AV?$__wrap_iter@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ?__make_iter@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAE?AV?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@23@PAUTransition@cctz@time_internal@absl@@@Z
     ?__make_iter@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAE?AV?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@23@PAUTransitionType@cctz@time_internal@absl@@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@CAIU?$integral_constant@_N$00@23@ABV?$allocator@PAUCordRep@cord_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@CAIU?$integral_constant@_N$00@23@ABV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAIU?$integral_constant@_N$00@23@ABV?$allocator@UTransition@cctz@time_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@CAIU?$integral_constant@_N$00@23@ABV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@CAIU?$integral_constant@_N$00@23@ABV?$allocator@UViableSubstitution@strings_internal@absl@@@23@@Z
-    ?__max_size@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@CAIU?$integral_constant@_N$00@23@ABV?$allocator@VFormatArgImpl@str_format_internal@absl@@@23@@Z
     ?__move_range@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXPAUTransition@cctz@time_internal@absl@@00@Z
     ?__move_range@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXPAUTransitionType@cctz@time_internal@absl@@00@Z
-    ?__node_alloc@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEAAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@23@XZ
+    ?__node_alloc@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEAAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@23@XZ
     ?__ptr@?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@QAEPAU123@XZ
     ?__recommend@?$vector@PAUCordRep@cord_internal@absl@@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@ABEII@Z
     ?__recommend@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@ABEII@Z
@@ -2596,7 +2588,7 @@
     ?__recommend@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@ABEII@Z
     ?__recommend@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@ABEII@Z
     ?__recommend@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@ABEII@Z
-    ?__rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AAEXI@Z
+    ?__rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AAEXI@Z
     ?__swap_out_circular_buffer@?$vector@PAUCordRep@cord_internal@absl@@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AAEXAAU?$__split_buffer@PAUCordRep@cord_internal@absl@@AAV?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@23@@Z
     ?__swap_out_circular_buffer@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AAEXAAU?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@AAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@23@@Z
     ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEPAUTransition@cctz@time_internal@absl@@AAU?$__split_buffer@UTransition@cctz@time_internal@absl@@AAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@23@PAU4567@@Z
@@ -2618,19 +2610,19 @@
     ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Usecond_tag@1234@U51234@@Z
     ?align@detail@cctz@time_internal@absl@@YA?AUfields@1234@Uyear_tag@1234@U51234@@Z
     ?alloc@Storage@?$FixedArray@PAUCordRep@cord_internal@absl@@$0PPPPPPPP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QAEAAV?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@XZ
-    ?allocate@?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QAEPAPAPBVImpl@time_zone@cctz@time_internal@absl@@IPBX@Z
-    ?allocate@?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@QAEPAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@23@IPBX@Z
-    ?allocate@?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@QAEPAPAUCordRep@cord_internal@absl@@IPBX@Z
-    ?allocate@?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@QAEPAPBUCordRep@cord_internal@absl@@IPBX@Z
-    ?allocate@?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QAEPAPBVImpl@time_zone@cctz@time_internal@absl@@IPBX@Z
-    ?allocate@?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@QAEPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@23@IPBX@Z
-    ?allocate@?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@IPBX@Z
-    ?allocate@?$allocator@UPayload@status_internal@absl@@@__1@std@@QAEPAUPayload@status_internal@absl@@IPBX@Z
-    ?allocate@?$allocator@USubRange@absl@@@__1@std@@QAEPAUSubRange@absl@@IPBX@Z
-    ?allocate@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QAEPAUTransition@cctz@time_internal@absl@@IPBX@Z
-    ?allocate@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QAEPAUTransitionType@cctz@time_internal@absl@@IPBX@Z
-    ?allocate@?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@QAEPAUViableSubstitution@strings_internal@absl@@IPBX@Z
-    ?allocate@?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@QAEPAVFormatArgImpl@str_format_internal@absl@@IPBX@Z
+    ?allocate@?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QAEPAPAPBVImpl@time_zone@cctz@time_internal@absl@@I@Z
+    ?allocate@?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@QAEPAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@23@I@Z
+    ?allocate@?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@QAEPAPAUCordRep@cord_internal@absl@@I@Z
+    ?allocate@?$allocator@PBUCordRep@cord_internal@absl@@@__1@std@@QAEPAPBUCordRep@cord_internal@absl@@I@Z
+    ?allocate@?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QAEPAPBVImpl@time_zone@cctz@time_internal@absl@@I@Z
+    ?allocate@?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@QAEPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@23@I@Z
+    ?allocate@?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@I@Z
+    ?allocate@?$allocator@UPayload@status_internal@absl@@@__1@std@@QAEPAUPayload@status_internal@absl@@I@Z
+    ?allocate@?$allocator@USubRange@absl@@@__1@std@@QAEPAUSubRange@absl@@I@Z
+    ?allocate@?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@QAEPAUTransition@cctz@time_internal@absl@@I@Z
+    ?allocate@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QAEPAUTransitionType@cctz@time_internal@absl@@I@Z
+    ?allocate@?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@QAEPAUViableSubstitution@strings_internal@absl@@I@Z
+    ?allocate@?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@QAEPAVFormatArgImpl@str_format_internal@absl@@I@Z
     ?allocate@?$allocator_traits@V?$allocator@H@__1@std@@@absl@@SAPAHAAV?$allocator@H@__1@std@@I@Z
     ?allocate@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@I@Z
     ?allocate@?$allocator_traits@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@SAPAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@23@AAV?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@23@I@Z
@@ -2681,7 +2673,7 @@
     ?begin@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QAEPAUPayload@status_internal@2@XZ
     ?begin@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QBEPBUPayload@status_internal@2@XZ
     ?begin@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QBEPBVFormatArgImpl@str_format_internal@2@XZ
-    ?begin@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE?AV?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@23@XZ
+    ?begin@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE?AV?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@23@XZ
     ?begin@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEPAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?begin@?$initializer_list@PAUCordRep@cord_internal@absl@@@std@@QBEPBQAUCordRep@cord_internal@absl@@XZ
     ?begin@?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@QBEPBU?$pair@Vstring_view@absl@@V12@@__1@2@XZ
@@ -2695,7 +2687,7 @@
     ?begin@ChunkRange@Cord@absl@@QBE?AVChunkIterator@23@XZ
     ?begin@Storage@?$FixedArray@PAUCordRep@cord_internal@absl@@$0PPPPPPPP@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@absl@@QBEPAPAUCordRep@cord_internal@3@XZ
     ?begin@string_view@absl@@QBEPBDXZ
-    ?bucket_count@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QBEIXZ
+    ?bucket_count@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QBEIXZ
     ?capacity@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QBEIXZ
     ?capacity@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QBEIXZ
     ?capacity@?$__split_buffer@PAUCordRep@cord_internal@absl@@AAV?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QBEIXZ
@@ -2718,7 +2710,7 @@
     ?capacity@CordRepRing@cord_internal@absl@@QBEIXZ
     ?chunk_begin@Cord@absl@@QBE?AVChunkIterator@12@XZ
     ?chunk_end@Cord@absl@@QBE?AVChunkIterator@12@XZ
-    ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEXXZ
+    ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEXXZ
     ?clear@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXXZ
     ?clear@?$__split_buffer@PAUCordRep@cord_internal@absl@@AAV?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QAEXXZ
     ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@AAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QAEXXZ
@@ -2838,7 +2830,7 @@
     ?end@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QBEPBUPayload@status_internal@2@XZ
     ?end@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QBEPBVFormatArgImpl@str_format_internal@2@XZ
     ?end@?$__deque_base@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@IAE?AV?$__deque_iterator@PBVImpl@time_zone@cctz@time_internal@absl@@PAPBV12345@AAPBV12345@PAPAPBV12345@H$0A@@23@XZ
-    ?end@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE?AV?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@23@XZ
+    ?end@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE?AV?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@23@XZ
     ?end@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEPAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?end@?$initializer_list@PAUCordRep@cord_internal@absl@@@std@@QBEPBQAUCordRep@cord_internal@absl@@XZ
     ?end@?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@QBEPBU?$pair@Vstring_view@absl@@V12@@__1@2@XZ
@@ -2879,12 +2871,12 @@
     ?find_last_not_of@string_view@absl@@QBEIV12@I@Z
     ?find_last_of@string_view@absl@@QBEIDI@Z
     ?find_last_of@string_view@absl@@QBEIV12@I@Z
-    ?first@?$__compressed_pair@IV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QAEAAIXZ
+    ?first@?$__compressed_pair@IV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QAEAAIXZ
     ?first@?$__compressed_pair@IV?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QAEAAIXZ
     ?first@?$__compressed_pair@IV?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QBEABIXZ
     ?first@?$__compressed_pair@IV?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEAAIXZ
     ?first@?$__compressed_pair@IV?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QBEABIXZ
-    ?first@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QAEAAMXZ
+    ?first@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QAEAAMXZ
     ?first@?$__compressed_pair@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEAAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?first@?$__compressed_pair@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QBEABQAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?first@?$__compressed_pair@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEAAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
@@ -2979,7 +2971,7 @@
     ?has_timeout@KernelTimeout@synchronization_internal@absl@@QBE_NXZ
     ?has_value@?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@absl@@QBE_NXZ
     ?has_zero_flag@FormatConversionSpecImpl@str_format_internal@absl@@QBE_NXZ
-    ?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEAAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEAAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?head@CordRepRing@cord_internal@absl@@QBEIXZ
     ?head@Filler@CordRepRing@cord_internal@absl@@QBEIXZ
     ?hour@?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QBEHXZ
@@ -2995,7 +2987,7 @@
     ?is_length@ConvTag@str_format_internal@absl@@QBE_NXZ
     ?is_tree@InlineData@cord_internal@absl@@QBE_NXZ
     ?is_tree@InlineRep@Cord@absl@@QBE_NXZ
-    ?key_eq@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEAAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?key_eq@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEAAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?length@?$Span@D@absl@@QBEIXZ
     ?length@CordRepRingReader@cord_internal@absl@@QBEIXZ
     ?length@string_view@absl@@QBEIXZ
@@ -3012,7 +3004,7 @@
     ?max@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@SA?AV12345@XZ
     ?max@?$numeric_limits@Vint128@absl@@@__1@std@@SA?AVint128@absl@@XZ
     ?max@?$numeric_limits@Vuint128@absl@@@__1@std@@SA?AVuint128@absl@@XZ
-    ?max_load_factor@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEAAMXZ
+    ?max_load_factor@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEAAMXZ
     ?max_size@?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@QBEIXZ
     ?max_size@?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@QBEIXZ
     ?max_size@?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@QBEIXZ
@@ -3026,12 +3018,6 @@
     ?max_size@?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@QBEIXZ
     ?max_size@?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@QBEIXZ
     ?max_size@?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@QBEIXZ
-    ?max_size@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@PAUCordRep@cord_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@UTransition@cctz@time_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@UViableSubstitution@strings_internal@absl@@@23@@Z
-    ?max_size@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@VFormatArgImpl@str_format_internal@absl@@@23@@Z
     ?max_size@?$vector@PAUCordRep@cord_internal@absl@@V?$allocator@PAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@QBEIXZ
     ?max_size@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@QBEIXZ
     ?max_size@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QBEIXZ
@@ -3104,7 +3090,7 @@
     ?rbegin@string_view@absl@@QBE?AV?$reverse_iterator@PBD@__1@std@@XZ
     ?reduce_size@InlineRep@Cord@absl@@QAEXI@Z
     ?reference@?$optional@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@absl@@AAEAAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ
-    ?rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEXI@Z
+    ?rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEXI@Z
     ?release@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEPBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?release@?$unique_ptr@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@@__1@std@@QAEPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
     ?release@?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@23@@__1@std@@QAEPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@23@XZ
@@ -3143,10 +3129,10 @@
     ?safe_strtou32_base@numbers_internal@absl@@YA_NVstring_view@2@PAIH@Z
     ?safe_strtou64_base@numbers_internal@absl@@YA_NVstring_view@2@PA_KH@Z
     ?scale_add@impl@detail@cctz@time_internal@absl@@YA_J_J00@Z
-    ?second@?$__compressed_pair@IV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QAEAAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?second@?$__compressed_pair@IV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QAEAAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?second@?$__compressed_pair@IV?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QAEAAV?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@23@XZ
     ?second@?$__compressed_pair@IV?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEAAV?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
-    ?second@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QAEAAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
+    ?second@?$__compressed_pair@MV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@__1@std@@@__1@std@@QAEAAV?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@XZ
     ?second@?$__compressed_pair@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEAAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?second@?$__compressed_pair@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEAAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?second@?$__compressed_pair@PAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@23@@__1@std@@QAEAAV?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@23@XZ
@@ -3207,7 +3193,7 @@
     ?size@?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@QBEIXZ
     ?size@?$__deque_base@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@IAEAAIXZ
     ?size@?$__deque_base@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@IBEABIXZ
-    ?size@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AAEAAIXZ
+    ?size@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AAEAAIXZ
     ?size@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QBEIXZ
     ?size@?$initializer_list@PAUCordRep@cord_internal@absl@@@std@@QBEIXZ
     ?size@?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@QBEIXZ
diff --git a/third_party/abseil-cpp/symbols_x86_rel.def b/third_party/abseil-cpp/symbols_x86_rel.def
index 0c67af2f..70d53d52 100644
--- a/third_party/abseil-cpp/symbols_x86_rel.def
+++ b/third_party/abseil-cpp/symbols_x86_rel.def
@@ -1,7 +1,6 @@
 EXPORTS
     ??$?0V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAE@$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$?4V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAEAAV01@$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
-    ??$?BV?$allocator@D@__1@std@@@string_view@absl@@QBE?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@XZ
     ??$?MUsecond_tag@detail@cctz@time_internal@absl@@U01234@@detail@cctz@time_internal@absl@@YA_NABV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@0@Z
     ??$?RW4LogSeverity@absl@@ABQBDHAAPBD@?$AtomicHook@P6AXW4LogSeverity@absl@@PBDHABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z@base_internal@absl@@QBEX$$QAW4LogSeverity@2@ABQBD$$QAHAAPBD@Z
     ??$AddRing@$00@CordRepRing@cord_internal@absl@@CAPAV012@PAV012@0II@Z
@@ -70,18 +69,20 @@
     ??$Prepend@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@$0A@@Cord@absl@@QAEX$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??$StrReplaceAll@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@@absl@@YA?AV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@Vstring_view@0@ABV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@3@@Z
     ??$StrReplaceAll@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@@absl@@YAHABV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@__1@std@@@std@@PAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@2@@Z
+    ??$__construct_node_hash@ABUpiecewise_construct_t@__1@std@@V?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AAE?AV?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@23@@12@IABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QAV?$tuple@$$V@12@@Z
     ??$__emplace_back_slow_path@AAVstring_view@absl@@ABV12@AAI@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@AAEXAAVstring_view@absl@@ABV34@AAI@Z
-    ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@ABUpiecewise_construct_t@23@V?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE?AU?$pair@V?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@_N@12@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@ABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QAV?$tuple@$$V@12@@Z
+    ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@ABUpiecewise_construct_t@23@V?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE?AU?$pair@V?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@_N@12@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@ABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@12@$$QAV?$tuple@$$V@12@@Z
     ??$__push_back_slow_path@ABUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXABUTransition@cctz@time_internal@absl@@@Z
     ??$__push_back_slow_path@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__1@std@@@__1@std@@AAEX$$QAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ??$__upper_bound@AAUByCivilTime@Transition@cctz@time_internal@absl@@PBU2345@U2345@@__1@std@@YAPBUTransition@cctz@time_internal@absl@@PBU2345@0ABU2345@AAUByCivilTime@2345@@Z
     ??$assign@PBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@QAEXPBVFormatArgImpl@str_format_internal@absl@@0@Z
     ??$assign@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$optional_data_base@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@optional_internal@absl@@IAEX$$QAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
+    ??$construct@UPayload@status_internal@absl@@ABU123@@?$allocator@UPayload@status_internal@absl@@@__1@std@@QAEXPAUPayload@status_internal@absl@@ABU345@@Z
     ??$emplace@$$V@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE?AV?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@12@V?$__wrap_iter@PBUTransition@cctz@time_internal@absl@@@12@@Z
     ??$emplace@$$V@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAE?AV?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@12@V?$__wrap_iter@PBUTransitionType@cctz@time_internal@absl@@@12@@Z
     ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@AAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXXZ
     ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXXZ
-    ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE?AV?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
+    ??$find@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAE?AV?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??0?$BigUnsigned@$03@strings_internal@absl@@QAE@Vstring_view@2@@Z
     ??0?$BigUnsigned@$03@strings_internal@absl@@QAE@XZ
     ??0?$BigUnsigned@$03@strings_internal@absl@@QAE@_K@Z
@@ -117,7 +118,6 @@
     ??0Status@absl@@QAE@W4StatusCode@1@Vstring_view@1@@Z
     ??0StatusRep@status_internal@absl@@QAE@W4StatusCode@2@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@V?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@56@@Z
     ??0Streamable@str_format_internal@absl@@QAE@ABVUntypedFormatSpecImpl@12@V?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@2@@Z
-    ??0TimeZoneInfo@cctz@time_internal@absl@@QAE@XZ
     ??0TimeZoneLibC@cctz@time_internal@absl@@QAE@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ??0Waiter@synchronization_internal@absl@@QAE@XZ
     ??0int128@absl@@QAE@M@Z
@@ -753,12 +753,12 @@
     ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXI@Z
     ?__construct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXI@Z
     ?__construct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXI@Z
-    ?__deallocate_node@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AAEXPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@23@@Z
-    ?__rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AAEXI@Z
+    ?__deallocate_node@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AAEXPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@23@@Z
+    ?__rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@AAEXI@Z
     ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEPAUTransition@cctz@time_internal@absl@@AAU?$__split_buffer@UTransition@cctz@time_internal@absl@@AAV?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@23@PAU4567@@Z
     ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEPAUTransitionType@cctz@time_internal@absl@@AAU?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@23@PAU4567@@Z
     ?__vallocate@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__1@std@@@__1@std@@AAEXI@Z
-    ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEXXZ
+    ?clear@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEXXZ
     ?code@Status@absl@@QBE?AW4StatusCode@2@XZ
     ?cord_ring_buffer_enabled@cord_internal@absl@@3U?$atomic@_N@__1@std@@A
     ?day_difference@impl@detail@cctz@time_internal@absl@@YA_J_JCC0CC@Z
@@ -805,7 +805,7 @@
     ?push_front@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXABQAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ?push_front@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEX$$QAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ?raw_code@Status@absl@@QBEHXZ
-    ?rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEXI@Z
+    ?rehash@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEXI@Z
     ?reserve@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXI@Z
     ?reserve@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXI@Z
     ?reserve@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__1@std@@@__1@std@@QAEXI@Z
diff --git a/third_party/blink/common/BUILD.gn b/third_party/blink/common/BUILD.gn
index 574cd3b..f01465c 100644
--- a/third_party/blink/common/BUILD.gn
+++ b/third_party/blink/common/BUILD.gn
@@ -96,6 +96,7 @@
     "frame/frame_visual_properties.cc",
     "frame/frame_visual_properties_mojom_traits.cc",
     "frame/from_ad_state.cc",
+    "frame/payment_request_token.cc",
     "frame/transient_allow_fullscreen.cc",
     "frame/user_activation_state.cc",
     "indexeddb/indexed_db_default_mojom_traits.cc",
diff --git a/third_party/blink/common/frame/payment_request_token.cc b/third_party/blink/common/frame/payment_request_token.cc
new file mode 100644
index 0000000..3d3e2b4
--- /dev/null
+++ b/third_party/blink/common/frame/payment_request_token.cc
@@ -0,0 +1,40 @@
+// 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/public/common/frame/payment_request_token.h"
+
+namespace blink {
+
+namespace {
+
+// This represents the time-span of the activate state from the moment a
+// postMessage with the delegated payment token is received.  The receiver
+// |Frame| is able to use the delegated token only once within this time-span.
+//
+// The time-span should be just long enough to allow brief async script calls.
+// The exact value here came from |TransientAllowFullscreen|.
+//
+// TODO(mustaq): Revisit the value after we have a spec for it.
+constexpr base::TimeDelta kActivationLifespan = base::TimeDelta::FromSeconds(1);
+
+}  // namespace
+
+PaymentRequestToken::PaymentRequestToken() = default;
+
+void PaymentRequestToken::Activate() {
+  transient_state_expiry_time_ = base::TimeTicks::Now() + kActivationLifespan;
+}
+
+bool PaymentRequestToken::IsActive() const {
+  return base::TimeTicks::Now() <= transient_state_expiry_time_;
+}
+
+bool PaymentRequestToken::ConsumeIfActive() {
+  if (!IsActive())
+    return false;
+  transient_state_expiry_time_ = base::TimeTicks();
+  return true;
+}
+
+}  // namespace blink
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn
index c72e2dc..e3935bd8 100644
--- a/third_party/blink/public/common/BUILD.gn
+++ b/third_party/blink/public/common/BUILD.gn
@@ -94,6 +94,7 @@
     "frame/frame_policy.h",
     "frame/frame_visual_properties.h",
     "frame/from_ad_state.h",
+    "frame/payment_request_token.h",
     "frame/transient_allow_fullscreen.h",
     "frame/user_activation_state.h",
     "frame/user_activation_update_source.h",
diff --git a/third_party/blink/public/common/frame/payment_request_token.h b/third_party/blink/public/common/frame/payment_request_token.h
new file mode 100644
index 0000000..64295a29
--- /dev/null
+++ b/third_party/blink/public/common/frame/payment_request_token.h
@@ -0,0 +1,42 @@
+// 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 THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_PAYMENT_REQUEST_TOKEN_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_PAYMENT_REQUEST_TOKEN_H_
+
+#include "base/time/time.h"
+#include "third_party/blink/public/common/common_export.h"
+
+namespace blink {
+
+// The |PaymentRequestToken| class represents the state of a delegated payment
+// request capability in a |Frame|.  This constitutes the
+// payment-request-specific part of the general Capability Delegation mechanism
+// where a sender |Frame| calls JS |postMessage| with a feature-specific
+// parameter to trigger a transient delegation of the feature to the receiving
+// |Frame|.
+//
+// Design doc:
+// https://docs.google.com/document/d/1IYN0mVy7yi4Afnm2Y0uda0JH8L2KwLgaBqsMVLMYXtk
+class BLINK_COMMON_EXPORT PaymentRequestToken {
+ public:
+  PaymentRequestToken();
+
+  // Activate the transient state.
+  void Activate();
+
+  // Returns the transient state; |true| if this object was recently activated.
+  bool IsActive() const;
+
+  // Consumes the transient activation state if available, and returns |true| if
+  // successfully consumed.
+  bool ConsumeIfActive();
+
+ private:
+  base::TimeTicks transient_state_expiry_time_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_PAYMENT_REQUEST_TOKEN_H_
diff --git a/third_party/blink/public/mojom/feature_policy/PRESUBMIT.py b/third_party/blink/public/mojom/feature_policy/PRESUBMIT.py
index b7bd9de..c1072acc 100644
--- a/third_party/blink/public/mojom/feature_policy/PRESUBMIT.py
+++ b/third_party/blink/public/mojom/feature_policy/PRESUBMIT.py
@@ -105,7 +105,14 @@
     """
 
     def run_json5_config_checks(input_api, output_api):
-        affected_paths = {f.LocalPath() for f in input_api.AffectedFiles()}
+        # Note:
+        # |input_api.change.AffectedFiles()| returns all affected files in a CL.
+        # |input_api.AffectedFiles()| only returns affected files under current
+        # PRESUBMIT directory.
+        affected_paths = {
+            f.LocalPath()
+            for f in input_api.change.AffectedFiles()
+        }
         if mojom_source_path not in affected_paths and json5_config_path not in affected_paths:
             return []
 
diff --git a/third_party/blink/public/platform/media/webmediaplayer_delegate.h b/third_party/blink/public/platform/media/webmediaplayer_delegate.h
index 09b8a95..19b82f1 100644
--- a/third_party/blink/public/platform/media/webmediaplayer_delegate.h
+++ b/third_party/blink/public/platform/media/webmediaplayer_delegate.h
@@ -98,11 +98,6 @@
   // so that we can do the right thing with media that starts paused.
   virtual void DidPause(int player_id, bool reached_end_of_stream) = 0;
 
-  // Notify that the audio output sink has changed
-  virtual void DidAudioOutputSinkChange(
-      int delegate_id,
-      const std::string& hashed_device_id) = 0;
-
   // Notify that playback is stopped. This will drop wake locks and remove any
   // external controls.
   //
@@ -131,14 +126,6 @@
   // called and returned |true|.
   virtual bool IsStale(int player_id) = 0;
 
-  // Notifies the delegate that the player has entered fullscreen. This does not
-  // differentiate native controls fullscreen and custom controls fullscreen.
-  // |fullscreen_video_status| is used by MediaWebContentsObserver to
-  // trigger automatically Picture-in-Picture for fullscreen videos.
-  virtual void SetIsEffectivelyFullscreen(
-      int player_id,
-      blink::WebFullscreenVideoStatus fullscreen_video_status) = 0;
-
  protected:
   WebMediaPlayerDelegate() = default;
   virtual ~WebMediaPlayerDelegate() = default;
diff --git a/third_party/blink/public/platform/web_media_player.h b/third_party/blink/public/platform/web_media_player.h
index 3bfc9c4..45ba65f 100644
--- a/third_party/blink/public/platform/web_media_player.h
+++ b/third_party/blink/public/platform/web_media_player.h
@@ -203,7 +203,7 @@
   virtual WebTimeRanges Seekable() const = 0;
 
   // Attempts to switch the audio output device.
-  virtual void SetSinkId(const WebString& sing_id,
+  virtual bool SetSinkId(const WebString& sing_id,
                          WebSetSinkIdCompleteCallback) = 0;
 
   // True if the loaded media has a playable video/audio track.
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h
index cbd9a2f..74699ef 100644
--- a/third_party/blink/public/platform/web_runtime_features.h
+++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -89,6 +89,8 @@
   BLINK_PLATFORM_EXPORT static void EnableBlockingFocusWithoutUserActivation(
       bool);
   BLINK_PLATFORM_EXPORT static void EnableCacheInlineScriptCode(bool);
+  BLINK_PLATFORM_EXPORT static void EnableCapabilityDelegationPaymentRequest(
+      bool enable);
   BLINK_PLATFORM_EXPORT static void EnableClickPointerEvent(bool enable);
   BLINK_PLATFORM_EXPORT static void EnableCompositeBGColorAnimation(
       bool enable);
diff --git a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
index 56193fd..191ab552 100644
--- a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
+++ b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
@@ -118,7 +118,7 @@
   void SetPreservesPitch(bool preserves_pitch) override;
   void SetAutoplayInitiated(bool autoplay_initiated) override;
   void OnRequestPictureInPicture() override;
-  void SetSinkId(const WebString& sink_id,
+  bool SetSinkId(const WebString& sink_id,
                  WebSetSinkIdCompleteCallback completion_callback) override;
   void SetPreload(WebMediaPlayer::Preload preload) override;
   WebTimeRanges Buffered() const override;
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni
index da1455f..050e3386 100644
--- a/third_party/blink/renderer/bindings/generated_in_modules.gni
+++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -1204,6 +1204,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_service_worker_update_via_cache.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_error_code.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_error_code.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage_bucket_durability.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage_bucket_durability.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_priority.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_priority.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_track_default_type.cc",
diff --git a/third_party/blink/renderer/build/scripts/templates/policy_helper.cc.tmpl b/third_party/blink/renderer/build/scripts/templates/policy_helper.cc.tmpl
index 9eda0cb..d548acd 100644
--- a/third_party/blink/renderer/build/scripts/templates/policy_helper.cc.tmpl
+++ b/third_party/blink/renderer/build/scripts/templates/policy_helper.cc.tmpl
@@ -49,8 +49,20 @@
   return default_feature_name_map;
 }
 
-const DocumentPolicyFeatureSet& GetAvailableDocumentPolicyFeatures() {
+
+DocumentPolicyFeatureSet& GetAvailableDocumentPolicyFeaturesInternal() {
   DEFINE_STATIC_LOCAL(DocumentPolicyFeatureSet, features, ());
+  return features;
+}
+
+
+void ResetAvailableDocumentPolicyFeaturesForTest() {
+  GetAvailableDocumentPolicyFeaturesInternal().clear();
+}
+
+
+const DocumentPolicyFeatureSet& GetAvailableDocumentPolicyFeatures() {
+  DocumentPolicyFeatureSet& features = GetAvailableDocumentPolicyFeaturesInternal();
   if (features.IsEmpty()) {
     {% for feature in document_policy_features %}
     {% if not feature.depends_on or feature.name in dp_origin_trial_dependency_map %}
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index 4fcf9c8..9d18ec8 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1224,6 +1224,7 @@
     "exported/web_selector_test.cc",
     "exported/web_view_test.cc",
     "feature_policy/document_policy_parser_test.cc",
+    "feature_policy/document_policy_sim_test.cc",
     "feature_policy/feature_policy_devtools_support_test.cc",
     "feature_policy/feature_policy_test.cc",
     "feature_policy/policy_test.cc",
diff --git a/third_party/blink/renderer/core/OWNERS b/third_party/blink/renderer/core/OWNERS
index 7f6fc058..393b9d2 100644
--- a/third_party/blink/renderer/core/OWNERS
+++ b/third_party/blink/renderer/core/OWNERS
@@ -37,6 +37,7 @@
 ikilpatrick@chromium.org
 inferno@chromium.org
 japhet@chromium.org
+jarhar@chromium.org
 jbroman@chromium.org
 jfernandez@igalia.com
 jianli@chromium.org
@@ -50,9 +51,6 @@
 masonfreed@chromium.org
 mkwst@chromium.org
 mstensho@chromium.org
-# nainar reviews changes in core/css,core/style
-# and related code in core/dom and core/layout.
-nainar@chromium.org
 nhiroki@chromium.org
 obrufau@igalia.com
 # pdr reviews many svg and text autosizing patches.
diff --git a/third_party/blink/renderer/core/css/counter_style.cc b/third_party/blink/renderer/core/css/counter_style.cc
index 7464728..71fc781 100644
--- a/third_party/blink/renderer/core/css/counter_style.cc
+++ b/third_party/blink/renderer/core/css/counter_style.cc
@@ -272,67 +272,49 @@
   return list_marker_text::GetText(EListStyleType::kHebrew, value);
 }
 
-String SimpChineseInformalAlgorithm(unsigned value) {
+int AbsoluteValueForLegacyCJKAlgorithms(int value) {
   // @counter-style algorithm works on absolute value, but the legacy
   // implementation works on the original value (and handles negative sign on
-  // its own). Range check before proceeding.
-  if (value > std::numeric_limits<int>::max())
-    return String();
-  return list_marker_text::GetText(EListStyleType::kSimpChineseInformal, value);
+  // its own). Clamp to the signed int range before proceeding.
+  if (UNLIKELY(value == std::numeric_limits<int>::min()))
+    return std::numeric_limits<int>::max();
+  else
+    return std::abs(value);
 }
 
-String SimpChineseFormalAlgorithm(unsigned value) {
-  // @counter-style algorithm works on absolute value, but the legacy
-  // implementation works on the original value (and handles negative sign on
-  // its own). Range check before proceeding.
-  if (value > std::numeric_limits<int>::max())
-    return String();
-  return list_marker_text::GetText(EListStyleType::kSimpChineseFormal, value);
+String SimpChineseInformalAlgorithm(int value) {
+  return list_marker_text::GetText(EListStyleType::kSimpChineseInformal,
+                                   AbsoluteValueForLegacyCJKAlgorithms(value));
 }
 
-String TradChineseInformalAlgorithm(unsigned value) {
-  // @counter-style algorithm works on absolute value, but the legacy
-  // implementation works on the original value (and handles negative sign on
-  // its own). Range check before proceeding.
-  if (value > std::numeric_limits<int>::max())
-    return String();
-  return list_marker_text::GetText(EListStyleType::kTradChineseInformal, value);
+String SimpChineseFormalAlgorithm(int value) {
+  return list_marker_text::GetText(EListStyleType::kSimpChineseFormal,
+                                   AbsoluteValueForLegacyCJKAlgorithms(value));
 }
 
-String TradChineseFormalAlgorithm(unsigned value) {
-  // @counter-style algorithm works on absolute value, but the legacy
-  // implementation works on the original value (and handles negative sign on
-  // its own). Range check before proceeding.
-  if (value > std::numeric_limits<int>::max())
-    return String();
-  return list_marker_text::GetText(EListStyleType::kTradChineseFormal, value);
+String TradChineseInformalAlgorithm(int value) {
+  return list_marker_text::GetText(EListStyleType::kTradChineseInformal,
+                                   AbsoluteValueForLegacyCJKAlgorithms(value));
 }
 
-String KoreanHangulFormalAlgorithm(unsigned value) {
-  // @counter-style algorithm works on absolute value, but the legacy
-  // implementation works on the original value (and handles negative sign on
-  // its own). Range check before proceeding.
-  if (value > std::numeric_limits<int>::max())
-    return String();
-  return list_marker_text::GetText(EListStyleType::kKoreanHangulFormal, value);
+String TradChineseFormalAlgorithm(int value) {
+  return list_marker_text::GetText(EListStyleType::kTradChineseFormal,
+                                   AbsoluteValueForLegacyCJKAlgorithms(value));
 }
 
-String KoreanHanjaInformalAlgorithm(unsigned value) {
-  // @counter-style algorithm works on absolute value, but the legacy
-  // implementation works on the original value (and handles negative sign on
-  // its own). Range check before proceeding.
-  if (value > std::numeric_limits<int>::max())
-    return String();
-  return list_marker_text::GetText(EListStyleType::kKoreanHanjaInformal, value);
+String KoreanHangulFormalAlgorithm(int value) {
+  return list_marker_text::GetText(EListStyleType::kKoreanHangulFormal,
+                                   AbsoluteValueForLegacyCJKAlgorithms(value));
 }
 
-String KoreanHanjaFormalAlgorithm(unsigned value) {
-  // @counter-style algorithm works on absolute value, but the legacy
-  // implementation works on the original value (and handles negative sign on
-  // its own). Range check before proceeding.
-  if (value > std::numeric_limits<int>::max())
-    return String();
-  return list_marker_text::GetText(EListStyleType::kKoreanHanjaFormal, value);
+String KoreanHanjaInformalAlgorithm(int value) {
+  return list_marker_text::GetText(EListStyleType::kKoreanHanjaInformal,
+                                   AbsoluteValueForLegacyCJKAlgorithms(value));
+}
+
+String KoreanHanjaFormalAlgorithm(int value) {
+  return list_marker_text::GetText(EListStyleType::kKoreanHanjaFormal,
+                                   AbsoluteValueForLegacyCJKAlgorithms(value));
 }
 
 String LowerArmenianAlgorithm(unsigned value) {
@@ -639,7 +621,10 @@
   if (!RangeContains(value))
     return String();
 
-  unsigned abs_value = value < 0 ? -value : value;
+  unsigned abs_value =
+      value == std::numeric_limits<int>::min()
+          ? static_cast<unsigned>(std::numeric_limits<int>::max()) + 1u
+          : std::abs(value);
 
   switch (system_) {
     case CounterStyleSystem::kCyclic:
@@ -658,19 +643,19 @@
     case CounterStyleSystem::kHebrew:
       return HebrewAlgorithm(abs_value);
     case CounterStyleSystem::kSimpChineseInformal:
-      return SimpChineseInformalAlgorithm(abs_value);
+      return SimpChineseInformalAlgorithm(value);
     case CounterStyleSystem::kSimpChineseFormal:
-      return SimpChineseFormalAlgorithm(abs_value);
+      return SimpChineseFormalAlgorithm(value);
     case CounterStyleSystem::kTradChineseInformal:
-      return TradChineseInformalAlgorithm(abs_value);
+      return TradChineseInformalAlgorithm(value);
     case CounterStyleSystem::kTradChineseFormal:
-      return TradChineseFormalAlgorithm(abs_value);
+      return TradChineseFormalAlgorithm(value);
     case CounterStyleSystem::kKoreanHangulFormal:
-      return KoreanHangulFormalAlgorithm(abs_value);
+      return KoreanHangulFormalAlgorithm(value);
     case CounterStyleSystem::kKoreanHanjaInformal:
-      return KoreanHanjaInformalAlgorithm(abs_value);
+      return KoreanHanjaInformalAlgorithm(value);
     case CounterStyleSystem::kKoreanHanjaFormal:
-      return KoreanHanjaFormalAlgorithm(abs_value);
+      return KoreanHanjaFormalAlgorithm(value);
     case CounterStyleSystem::kLowerArmenian:
       return LowerArmenianAlgorithm(abs_value);
     case CounterStyleSystem::kUpperArmenian:
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
index cfe11aa1..caf654b4 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -121,10 +121,10 @@
 }
 const CSSValue* AlignmentBaseline::CSSValueFromComputedStyleInternal(
     const ComputedStyle& style,
-    const SVGComputedStyle& svg_style,
+    const SVGComputedStyle&,
     const LayoutObject*,
     bool allow_visited_style) const {
-  return CSSIdentifierValue::Create(svg_style.AlignmentBaseline());
+  return CSSIdentifierValue::Create(style.AlignmentBaseline());
 }
 
 const CSSValue* AnimationDelay::ParseSingleValue(
@@ -1407,10 +1407,10 @@
 
 const CSSValue* BufferedRendering::CSSValueFromComputedStyleInternal(
     const ComputedStyle& style,
-    const SVGComputedStyle& svg_style,
+    const SVGComputedStyle&,
     const LayoutObject*,
     bool allow_visited_style) const {
-  return CSSIdentifierValue::Create(svg_style.BufferedRendering());
+  return CSSIdentifierValue::Create(style.BufferedRendering());
 }
 
 const CSSValue* CaptionSide::CSSValueFromComputedStyleInternal(
@@ -2850,11 +2850,11 @@
 }
 
 const CSSValue* FloodOpacity::CSSValueFromComputedStyleInternal(
-    const ComputedStyle&,
-    const SVGComputedStyle& svg_style,
+    const ComputedStyle& style,
+    const SVGComputedStyle&,
     const LayoutObject*,
     bool allow_visited_style) const {
-  return CSSNumericLiteralValue::Create(svg_style.FloodOpacity(),
+  return CSSNumericLiteralValue::Create(style.FloodOpacity(),
                                         CSSPrimitiveValue::UnitType::kNumber);
 }
 
@@ -4715,18 +4715,18 @@
 
 const CSSValue* Mask::CSSValueFromComputedStyleInternal(
     const ComputedStyle& style,
-    const SVGComputedStyle& svg_style,
+    const SVGComputedStyle&,
     const LayoutObject*,
     bool allow_visited_style) const {
-  return ComputedStyleUtils::ValueForSVGResource(svg_style.MaskerResource());
+  return ComputedStyleUtils::ValueForSVGResource(style.MaskerResource());
 }
 
 const CSSValue* MaskType::CSSValueFromComputedStyleInternal(
     const ComputedStyle& style,
-    const SVGComputedStyle& svg_style,
+    const SVGComputedStyle&,
     const LayoutObject*,
     bool allow_visited_style) const {
-  return CSSIdentifierValue::Create(svg_style.MaskType());
+  return CSSIdentifierValue::Create(style.MaskType());
 }
 
 const CSSValue* MathShift::CSSValueFromComputedStyleInternal(
@@ -6536,11 +6536,11 @@
 }
 
 const CSSValue* StopOpacity::CSSValueFromComputedStyleInternal(
-    const ComputedStyle&,
-    const SVGComputedStyle& svg_style,
+    const ComputedStyle& style,
+    const SVGComputedStyle&,
     const LayoutObject*,
     bool allow_visited_style) const {
-  return CSSNumericLiteralValue::Create(svg_style.StopOpacity(),
+  return CSSNumericLiteralValue::Create(style.StopOpacity(),
                                         CSSPrimitiveValue::UnitType::kNumber);
 }
 
@@ -7534,10 +7534,10 @@
 
 const CSSValue* VectorEffect::CSSValueFromComputedStyleInternal(
     const ComputedStyle& style,
-    const SVGComputedStyle& svg_style,
+    const SVGComputedStyle&,
     const LayoutObject*,
     bool allow_visited_style) const {
-  return CSSIdentifierValue::Create(svg_style.VectorEffect());
+  return CSSIdentifierValue::Create(style.VectorEffect());
 }
 
 const CSSValue* VerticalAlign::ParseSingleValue(
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 6373d384..682af22 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -33,7 +33,7 @@
 // instead of including more headers. If that is infeasible, adjust the limit.
 // For more info, see
 // https://chromium.googlesource.com/chromium/src/+/HEAD/docs/wmax_tokens.md
-#pragma clang max_tokens_here 1001000
+#pragma clang max_tokens_here 1010000
 
 #include <memory>
 #include <utility>
diff --git a/third_party/blink/renderer/core/editing/editing_style.cc b/third_party/blink/renderer/core/editing/editing_style.cc
index cb4fee97..086314f 100644
--- a/third_party/blink/renderer/core/editing/editing_style.cc
+++ b/third_party/blink/renderer/core/editing/editing_style.cc
@@ -153,16 +153,9 @@
   return false;
 }
 
-static CSSComputedStyleDeclaration* EnsureComputedStyle(
-    const Position& position) {
-  Element* elem = AssociatedElementOf(position);
-  if (!elem)
-    return nullptr;
-  return MakeGarbageCollected<CSSComputedStyleDeclaration>(elem);
-}
-
 static MutableCSSPropertyValueSet* GetPropertiesNotIn(
     CSSPropertyValueSet* style_with_redundant_properties,
+    Node*,
     CSSStyleDeclaration* base_style,
     SecureContextMode);
 enum LegacyFontSizeMode {
@@ -470,8 +463,7 @@
       EditingStyleUtilities::BackgroundColorValueInEffect(node));
 }
 
-static CSSValueID TextAlignResolvingStartAndEnd(CSSValueID text_align,
-                                                CSSValueID direction) {
+static CSSValueID NormalizeTextAlign(CSSValueID text_align) {
   switch (text_align) {
     case CSSValueID::kCenter:
     case CSSValueID::kWebkitCenter:
@@ -485,21 +477,71 @@
     case CSSValueID::kWebkitRight:
       return CSSValueID::kRight;
     case CSSValueID::kStart:
-      return direction != CSSValueID::kRtl ? CSSValueID::kLeft
-                                           : CSSValueID::kRight;
     case CSSValueID::kEnd:
-      return direction == CSSValueID::kRtl ? CSSValueID::kRight
-                                           : CSSValueID::kLeft;
+      return text_align;
     default:
       return CSSValueID::kInvalid;
   }
 }
+static CSSValueID TextAlignResolvingStartAndEnd(CSSValueID text_align,
+                                                TextDirection direction) {
+  const CSSValueID normalized = NormalizeTextAlign(text_align);
+  switch (normalized) {
+    case CSSValueID::kStart:
+      return IsLtr(direction) ? CSSValueID::kLeft : CSSValueID::kRight;
+    case CSSValueID::kEnd:
+      return IsLtr(direction) ? CSSValueID::kRight : CSSValueID::kLeft;
+    default:
+      return normalized;
+  }
+}
 
+// Returns true "text-align" property of |style| is redundant when applying
+// |style| inheriting from |base_style| to |node|.
+// Note: direction for "text-align:start" and "text-align:end" are taken
+// from |node|.
 template <typename T>
-static CSSValueID TextAlignResolvingStartAndEnd(T* style) {
-  return TextAlignResolvingStartAndEnd(
-      GetIdentifierValue(style, CSSPropertyID::kTextAlign),
-      GetIdentifierValue(style, CSSPropertyID::kDirection));
+static bool IsRedundantTextAlign(MutableCSSPropertyValueSet* style,
+                                 T* base_style,
+                                 Node* node) {
+  DCHECK(node);
+  const CSSValueID base_text_align = NormalizeTextAlign(
+      GetIdentifierValue(base_style, CSSPropertyID::kTextAlign));
+  if (base_text_align == CSSValueID::kInvalid)
+    return false;
+  const CSSValueID text_align =
+      NormalizeTextAlign(GetIdentifierValue(style, CSSPropertyID::kTextAlign));
+  if (text_align == CSSValueID::kInvalid)
+    return false;
+  if (text_align == base_text_align)
+    return true;
+  if (base_text_align == CSSValueID::kStart ||
+      base_text_align == CSSValueID::kEnd) {
+    // Returns true for "text-align:left" of <p>
+    //   <div style="text-align:start"><p dir="ltr" style="text-align:left">
+    // because meaning of "text-align:start" in <p> is identical to
+    // "text-align:left".
+    //
+    // Returns false for "text-align:left" of <p>
+    //   <div style="text-align:start"><p dir="rtl" style="text-align:left">
+    // because meaning of "text-align:start" in <p> is identical to
+    // "text-align:right".
+    return TextAlignResolvingStartAndEnd(
+               base_text_align, node->EnsureComputedStyle()->Direction()) ==
+           text_align;
+  }
+  if (text_align == CSSValueID::kStart || text_align == CSSValueID::kEnd) {
+    // Returns true for "text-align:start" of <p>
+    //  <div style="text-align:left"><p dir="ltr" style="text-align:start">
+    //  <div style="text-align:right"><p dir="rtl" style="text-align:start">
+    // Returns false for "text-align:start" of <p>
+    //  <div style="text-align:left"><p dir="rtl" style="text-align:start">
+    //  <div style="text-align:right"><p dir="ltr" style="text-align:start">
+    return TextAlignResolvingStartAndEnd(
+               text_align, node->EnsureComputedStyle()->Direction()) ==
+           base_text_align;
+  }
+  return false;
 }
 
 void EditingStyle::Init(Node* node, PropertiesToInclude properties_to_include) {
@@ -507,7 +549,7 @@
     node = TabSpanElement(node)->parentNode();
   else if (IsTabHTMLSpanElement(node))
     node = node->parentNode();
-
+  node_ = node;
   auto* computed_style_at_position =
       MakeGarbageCollected<CSSComputedStyleDeclaration>(node);
   mutable_style_ =
@@ -578,6 +620,10 @@
     mutable_style_->RemoveProperty(CSSPropertyID::kCaretColor);
 }
 
+CSSValueID EditingStyle::GetProperty(CSSPropertyID property_id) const {
+  return GetIdentifierValue(mutable_style_.Get(), property_id);
+}
+
 void EditingStyle::SetProperty(CSSPropertyID property_id,
                                const String& value,
                                bool important,
@@ -833,17 +879,21 @@
     SecureContextMode secure_context_mode) const {
   if (!style || !style->mutable_style_)
     return EditingTriState::kFalse;
+  DCHECK(style->node_);
   return TriStateOfStyle(
       style->mutable_style_->EnsureCSSStyleDeclaration(execution_context),
-      kDoNotIgnoreTextOnlyProperties, secure_context_mode);
+      style->node_, kDoNotIgnoreTextOnlyProperties, secure_context_mode);
 }
 
 EditingTriState EditingStyle::TriStateOfStyle(
     CSSStyleDeclaration* style_to_compare,
+    Node* node,
     ShouldIgnoreTextOnlyProperties should_ignore_text_only_properties,
     SecureContextMode secure_context_mode) const {
+  // editing/execCommand/query-text-alignment.html requires |node|.
+  DCHECK(node);
   MutableCSSPropertyValueSet* difference = GetPropertiesNotIn(
-      mutable_style_.Get(), style_to_compare, secure_context_mode);
+      mutable_style_.Get(), node, style_to_compare, secure_context_mode);
 
   // CSS properties that create a visual difference only when applied to text.
   static const CSSProperty* kTextOnlyProperties[] = {
@@ -911,7 +961,7 @@
         // node.isTextNode() because the node can be an element node. See bug
         // http://crbug.com/584939.
         EditingTriState node_state = TriStateOfStyle(
-            node_style, EditingStyle::kDoNotIgnoreTextOnlyProperties,
+            node_style, &node, EditingStyle::kDoNotIgnoreTextOnlyProperties,
             secure_context_mode);
         if (node_is_start) {
           state = node_state;
@@ -1158,7 +1208,7 @@
 bool EditingStyle::StyleIsPresentInComputedStyleOfNode(Node* node) const {
   return !mutable_style_ ||
          GetPropertiesNotIn(
-             mutable_style_.Get(),
+             mutable_style_.Get(), node,
              MakeGarbageCollected<CSSComputedStyleDeclaration>(node),
              node->GetExecutionContext()->GetSecureContextMode())
              ->IsEmpty();
@@ -1244,8 +1294,9 @@
 
   mutable_style_->RemoveEquivalentProperties(style_at_position);
 
-  if (TextAlignResolvingStartAndEnd(mutable_style_.Get()) ==
-      TextAlignResolvingStartAndEnd(style_at_position))
+  DCHECK(editing_style_at_position->node_);
+  if (IsRedundantTextAlign(mutable_style_.Get(), style_at_position,
+                           editing_style_at_position->node_))
     mutable_style_->RemoveProperty(CSSPropertyID::kTextAlign);
 
   if (GetFontColor(mutable_style_.Get()) == GetFontColor(style_at_position))
@@ -1529,7 +1580,7 @@
                                       StyleResolver::kAllButEmptyCSSRules);
   if (style_from_matched_rules && !style_from_matched_rules->IsEmpty()) {
     mutable_style_ =
-        GetPropertiesNotIn(mutable_style_.Get(),
+        GetPropertiesNotIn(mutable_style_.Get(), element,
                            style_from_matched_rules->EnsureCSSStyleDeclaration(
                                element->GetExecutionContext()),
                            secure_context_mode);
@@ -1548,7 +1599,7 @@
     RemovePropertiesInStyle(computed_style->mutable_style_.Get(),
                             style_from_matched_rules);
     mutable_style_ = GetPropertiesNotIn(
-        mutable_style_.Get(),
+        mutable_style_.Get(), element,
         computed_style->mutable_style_->EnsureCSSStyleDeclaration(
             element->GetExecutionContext()),
         secure_context_mode);
@@ -1560,12 +1611,10 @@
   if (IsStyleSpanOrSpanWithOnlyStyleAttribute(element)) {
     if (!style_from_matched_rules->GetPropertyCSSValue(
             CSSPropertyID::kDisplay) &&
-        GetIdentifierValue(mutable_style_.Get(), CSSPropertyID::kDisplay) ==
-            CSSValueID::kInline)
+        GetProperty(CSSPropertyID::kDisplay) == CSSValueID::kInline)
       mutable_style_->RemoveProperty(CSSPropertyID::kDisplay);
     if (!style_from_matched_rules->GetPropertyCSSValue(CSSPropertyID::kFloat) &&
-        GetIdentifierValue(mutable_style_.Get(), CSSPropertyID::kFloat) ==
-            CSSValueID::kNone)
+        GetProperty(CSSPropertyID::kFloat) == CSSValueID::kNone)
       mutable_style_->RemoveProperty(CSSPropertyID::kFloat);
   }
 }
@@ -1602,6 +1651,7 @@
 
 void EditingStyle::Trace(Visitor* visitor) const {
   visitor->Trace(mutable_style_);
+  visitor->Trace(node_);
 }
 
 static void ReconcileTextDecorationProperties(
@@ -1635,14 +1685,19 @@
       apply_subscript_(false),
       apply_superscript_(false) {
   Document* document = position.GetDocument();
-  if (!style || !style->Style() || !document || !document->GetFrame() ||
-      !AssociatedElementOf(position))
+  if (!style || !style->Style() || !document || !document->GetFrame())
+    return;
+  Element* const element = AssociatedElementOf(position);
+  if (!element)
     return;
 
-  CSSComputedStyleDeclaration* computed_style = EnsureComputedStyle(position);
+  CSSComputedStyleDeclaration* const computed_style =
+      MakeGarbageCollected<CSSComputedStyleDeclaration>(element);
   // FIXME: take care of background-color in effect
+  // Note: editing/undo/redo-selection-modify-crash.html needs to pass
+  // |element| to |GetPropertiesNotIn()| to remove "text-align:left".
   MutableCSSPropertyValueSet* mutable_style = GetPropertiesNotIn(
-      style->Style(), computed_style,
+      style->Style(), element, computed_style,
       document->GetExecutionContext()->GetSecureContextMode());
   DCHECK(mutable_style);
 
@@ -1842,9 +1897,11 @@
 
 MutableCSSPropertyValueSet* GetPropertiesNotIn(
     CSSPropertyValueSet* style_with_redundant_properties,
+    Node* node,
     CSSStyleDeclaration* base_style,
     SecureContextMode secure_context_mode) {
   DCHECK(style_with_redundant_properties);
+  DCHECK(node);
   DCHECK(base_style);
   MutableCSSPropertyValueSet* result =
       style_with_redundant_properties->MutableCopy();
@@ -1874,9 +1931,7 @@
       GetFontColor(result) == GetFontColor(base_style))
     result->RemoveProperty(CSSPropertyID::kColor);
 
-  if (base_style->GetPropertyCSSValueInternal(CSSPropertyID::kTextAlign) &&
-      TextAlignResolvingStartAndEnd(result) ==
-          TextAlignResolvingStartAndEnd(base_style))
+  if (IsRedundantTextAlign(result, base_style, node))
     result->RemoveProperty(CSSPropertyID::kTextAlign);
 
   if (base_style->GetPropertyCSSValueInternal(
diff --git a/third_party/blink/renderer/core/editing/editing_style.h b/third_party/blink/renderer/core/editing/editing_style.h
index 0b9319d..8bebbbf 100644
--- a/third_party/blink/renderer/core/editing/editing_style.h
+++ b/third_party/blink/renderer/core/editing/editing_style.h
@@ -153,6 +153,7 @@
   float FontSizeDelta() const { return font_size_delta_; }
   bool HasFontSizeDelta() const { return font_size_delta_ != kNoFontDelta; }
 
+  CSSValueID GetProperty(CSSPropertyID) const;
   void SetProperty(CSSPropertyID,
                    const String& value,
                    bool important,
@@ -171,6 +172,7 @@
                                           CSSComputedStyleDeclaration*);
   void ExtractFontSizeDelta();
   EditingTriState TriStateOfStyle(CSSStyleDeclaration* style_to_compare,
+                                  Node* node,
                                   ShouldIgnoreTextOnlyProperties,
                                   SecureContextMode) const;
   bool ConflictsWithInlineStyleOfElement(
@@ -180,6 +182,10 @@
   void MergeStyle(const CSSPropertyValueSet*, CSSPropertyOverrideMode);
 
   Member<MutableCSSPropertyValueSet> mutable_style_;
+  // This |EditingStyle| is constructed from |node_|. |node_| is null when
+  // this |EditingStyle| is constructed from |CSSPropertyValueSet*| or
+  // |CSSPropertyID|.
+  Member<Node> node_;
   bool is_monospace_font_ = false;
   float font_size_delta_ = kNoFontDelta;
   bool is_vertical_align_ = false;
diff --git a/third_party/blink/renderer/core/editing/editing_style_test.cc b/third_party/blink/renderer/core/editing/editing_style_test.cc
index fcce278..68b5368 100644
--- a/third_party/blink/renderer/core/editing/editing_style_test.cc
+++ b/third_party/blink/renderer/core/editing/editing_style_test.cc
@@ -35,4 +35,30 @@
       << "Keep unresolved value on merging style";
 }
 
+// http://crbug.com/957952
+TEST_F(EditingStyleTest, RemoveStyleFromRulesAndContext_TextAlignEffective) {
+  // Note: <div>'s "text-align" is "start".
+  // For <p> with "text-align:start", it equivalents to "text-align:right"
+  SetBodyContent("<div><p dir=rtl id=target>");
+  Element& target = *GetElementById("target");
+  EditingStyle& style = *MakeGarbageCollected<EditingStyle>(
+      CSSPropertyID::kTextAlign, "left", SecureContextMode::kInsecureContext);
+  style.RemoveStyleFromRulesAndContext(&target, target.parentNode());
+
+  EXPECT_EQ(CSSValueID::kLeft, style.GetProperty(CSSPropertyID::kTextAlign));
+}
+
+// http://crbug.com/957952
+TEST_F(EditingStyleTest, RemoveStyleFromRulesAndContext_TextAlignRedundant) {
+  // Note: <div>'s "text-align" is "start".
+  // For <p> with "text-align:start", it equivalents to "text-align:right"
+  SetBodyContent("<div><p dir=rtl id=target>");
+  Element& target = *GetElementById("target");
+  EditingStyle& style = *MakeGarbageCollected<EditingStyle>(
+      CSSPropertyID::kTextAlign, "right", SecureContextMode::kInsecureContext);
+  style.RemoveStyleFromRulesAndContext(&target, target.parentNode());
+
+  EXPECT_EQ(CSSValueID::kInvalid, style.GetProperty(CSSPropertyID::kTextAlign));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/editing/ime/cached_text_input_info.cc b/third_party/blink/renderer/core/editing/ime/cached_text_input_info.cc
index ca08115..614d0ca 100644
--- a/third_party/blink/renderer/core/editing/ime/cached_text_input_info.cc
+++ b/third_party/blink/renderer/core/editing/ime/cached_text_input_info.cc
@@ -29,6 +29,7 @@
   text_ = g_empty_string;
   composition_.Clear();
   selection_.Clear();
+  offset_map_.clear();
 }
 
 void CachedTextInputInfo::DidLayoutSubtree(const LayoutObject& layout_object) {
diff --git a/third_party/blink/renderer/core/editing/position.cc b/third_party/blink/renderer/core/editing/position.cc
index d278e52..ccdfb73 100644
--- a/third_party/blink/renderer/core/editing/position.cc
+++ b/third_party/blink/renderer/core/editing/position.cc
@@ -632,6 +632,10 @@
   return PositionInFlatTree(anchor, pos.AnchorType());
 }
 
+PositionInFlatTree ToPositionInFlatTree(const PositionInFlatTree& position) {
+  return position;
+}
+
 Position ToPositionInDOMTree(const Position& position) {
   return position;
 }
diff --git a/third_party/blink/renderer/core/editing/position.h b/third_party/blink/renderer/core/editing/position.h
index e671ec25..f9e1093 100644
--- a/third_party/blink/renderer/core/editing/position.h
+++ b/third_party/blink/renderer/core/editing/position.h
@@ -270,6 +270,7 @@
 }
 
 CORE_EXPORT PositionInFlatTree ToPositionInFlatTree(const Position&);
+CORE_EXPORT PositionInFlatTree ToPositionInFlatTree(const PositionInFlatTree&);
 CORE_EXPORT Position ToPositionInDOMTree(const Position&);
 CORE_EXPORT Position ToPositionInDOMTree(const PositionInFlatTree&);
 
diff --git a/third_party/blink/renderer/core/editing/visible_position.cc b/third_party/blink/renderer/core/editing/visible_position.cc
index 8d5860f..e769f71 100644
--- a/third_party/blink/renderer/core/editing/visible_position.cc
+++ b/third_party/blink/renderer/core/editing/visible_position.cc
@@ -31,6 +31,7 @@
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
+#include "third_party/blink/renderer/core/editing/inline_box_position.h"
 #include "third_party/blink/renderer/core/editing/local_caret_rect.h"
 #include "third_party/blink/renderer/core/editing/ng_flat_tree_shorthands.h"
 #include "third_party/blink/renderer/core/editing/text_affinity.h"
@@ -38,6 +39,8 @@
 #include "third_party/blink/renderer/core/html/html_element.h"
 #include "third_party/blink/renderer/core/html_names.h"
 #include "third_party/blink/renderer/core/layout/layout_object.h"
+#include "third_party/blink/renderer/core/layout/line/inline_box.h"
+#include "third_party/blink/renderer/core/layout/line/root_inline_box.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/geometry/float_quad.h"
@@ -71,6 +74,37 @@
 }
 
 template <typename Strategy>
+static inline bool InDifferentLinesOfSameInlineFormattingContext(
+    const PositionWithAffinityTemplate<Strategy>& position1,
+    const PositionWithAffinityTemplate<Strategy>& position2) {
+  DCHECK(position1.IsNotNull());
+  DCHECK(position2.IsNotNull());
+  // Optimization for common cases.
+  if (position1 == position2)
+    return false;
+  // InSameLine may DCHECK that the anchors have a layout object.
+  if (!position1.AnchorNode()->GetLayoutObject() ||
+      !position2.AnchorNode()->GetLayoutObject())
+    return false;
+  // Return false if the positions are in the same line.
+  if (InSameLine(position1, position2))
+    return false;
+  // Return whether the positions are in the same inline formatting context.
+  if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+    const LayoutBlockFlow* block1 =
+        NGInlineFormattingContextOf(position1.GetPosition());
+    return block1 &&
+           block1 == NGInlineFormattingContextOf(position2.GetPosition());
+  }
+  const InlineBox* inline_box1 = ComputeInlineBoxPosition(position1).inline_box;
+  if (!inline_box1)
+    return false;
+  const InlineBox* inline_box2 = ComputeInlineBoxPosition(position2).inline_box;
+  return inline_box2 &&
+         inline_box1->Root().LineBoxes() == inline_box2->Root().LineBoxes();
+}
+
+template <typename Strategy>
 VisiblePositionTemplate<Strategy> VisiblePositionTemplate<Strategy>::Create(
     const PositionWithAffinityTemplate<Strategy>& position_with_affinity) {
   if (position_with_affinity.IsNull())
@@ -88,8 +122,31 @@
     return VisiblePositionTemplate<Strategy>();
   const PositionWithAffinityTemplate<Strategy> downstream_position(
       deep_position);
-  if (position_with_affinity.Affinity() == TextAffinity::kDownstream)
+  if (position_with_affinity.Affinity() == TextAffinity::kDownstream) {
+    // Fast path for common cases.
+    if (position_with_affinity == downstream_position)
+      return VisiblePositionTemplate<Strategy>(downstream_position);
+
+    // If the canonical position went into a previous line of the same inline
+    // formatting context, use the start of the current line instead.
+    const PositionInFlatTree& flat_deep_position =
+        ToPositionInFlatTree(deep_position);
+    const PositionInFlatTree& flat_position =
+        ToPositionInFlatTree(position_with_affinity.GetPosition());
+    if (flat_deep_position.IsNotNull() && flat_position.IsNotNull() &&
+        flat_deep_position < flat_position &&
+        InDifferentLinesOfSameInlineFormattingContext(position_with_affinity,
+                                                      downstream_position)) {
+      const PositionWithAffinityTemplate<Strategy>& start_of_line =
+          StartOfLine(position_with_affinity);
+      if (start_of_line.IsNull())
+        return VisiblePositionTemplate<Strategy>();
+      return VisiblePositionTemplate<Strategy>(start_of_line);
+    }
+
+    // Otherwise use the canonical position.
     return VisiblePositionTemplate<Strategy>(downstream_position);
+  }
 
   if (RuntimeEnabledFeatures::BidiCaretAffinityEnabled() &&
       NGInlineFormattingContextOf(deep_position)) {
diff --git a/third_party/blink/renderer/core/editing/visible_position_test.cc b/third_party/blink/renderer/core/editing/visible_position_test.cc
index 6b89c01e..54ba2fa 100644
--- a/third_party/blink/renderer/core/editing/visible_position_test.cc
+++ b/third_party/blink/renderer/core/editing/visible_position_test.cc
@@ -198,6 +198,41 @@
   EXPECT_FALSE(visible_position2.IsValid());
 }
 
+TEST_F(VisiblePositionTest, NormalizationAroundLineBreak) {
+  LoadAhem();
+  InsertStyleElement(
+      "div {"
+      "width: 5.5ch;"
+      "font: 10px/10px Ahem;"
+      "word-wrap: break-word;"
+      "}");
+  SetBodyContent(
+      "<div>line1line2</div>"
+      "<div>line1<br>line2</div>"
+      "<div>line1<wbr>line2</div>"
+      "<div>line1<span></span>line2</div>"
+      "<div>line1<span></span><span></span>line2</div>");
+
+  StaticElementList* tests = GetDocument().QuerySelectorAll("div");
+  for (unsigned i = 0; i < tests->length(); ++i) {
+    Element* test = tests->item(i);
+    Node* node1 = test->firstChild();
+    Node* node2 = test->lastChild();
+    PositionWithAffinity line1_end(Position(node1, 5), TextAffinity::kUpstream);
+    PositionWithAffinity line2_start(Position(node2, node1 == node2 ? 5 : 0),
+                                     TextAffinity::kDownstream);
+    PositionWithAffinity line1_end_normalized =
+        CreateVisiblePosition(line1_end).ToPositionWithAffinity();
+    PositionWithAffinity line2_start_normalized =
+        CreateVisiblePosition(line2_start).ToPositionWithAffinity();
+
+    EXPECT_FALSE(InSameLine(line1_end, line2_start));
+    EXPECT_FALSE(InSameLine(line1_end_normalized, line2_start_normalized));
+    EXPECT_TRUE(InSameLine(line1_end, line1_end_normalized));
+    EXPECT_TRUE(InSameLine(line2_start, line2_start_normalized));
+  }
+}
+
 #endif
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/editing/visible_units.cc b/third_party/blink/renderer/core/editing/visible_units.cc
index 9426fe7..9341b58 100644
--- a/third_party/blink/renderer/core/editing/visible_units.cc
+++ b/third_party/blink/renderer/core/editing/visible_units.cc
@@ -77,7 +77,32 @@
 }
 
 template <typename PositionType>
-static PositionType SnapFallbackTemplate(const PositionType& position) {
+static PositionType CanonicalPosition(const PositionType& position) {
+  // Sometimes updating selection positions can be extremely expensive and
+  // occur frequently.  Often calling preventDefault on mousedown events can
+  // avoid doing unnecessary text selection work.  http://crbug.com/472258.
+  TRACE_EVENT0("input", "VisibleUnits::canonicalPosition");
+
+  // FIXME (9535):  Canonicalizing to the leftmost candidate means that if
+  // we're at a line wrap, we will ask layoutObjects to paint downstream
+  // carets for other layoutObjects. To fix this, we need to either a) add
+  // code to all paintCarets to pass the responsibility off to the appropriate
+  // layoutObject for VisiblePosition's like these, or b) canonicalize to the
+  // rightmost candidate unless the affinity is upstream.
+  if (position.IsNull())
+    return PositionType();
+
+  DCHECK(position.GetDocument());
+  DCHECK(!position.GetDocument()->NeedsLayoutTreeUpdate());
+
+  const PositionType& backward_candidate = MostBackwardCaretPosition(position);
+  if (IsVisuallyEquivalentCandidate(backward_candidate))
+    return backward_candidate;
+
+  const PositionType& forward_candidate = MostForwardCaretPosition(position);
+  if (IsVisuallyEquivalentCandidate(forward_candidate))
+    return forward_candidate;
+
   // When neither upstream or downstream gets us to a candidate
   // (upstream/downstream won't leave blocks or enter new ones), we search
   // forward and backward until we find one.
@@ -130,93 +155,12 @@
   return next;
 }
 
-template <typename Strategy>
-static PositionWithAffinityTemplate<Strategy> SnapBackwardTemplate(
-    const PositionTemplate<Strategy>& position) {
-  // Sometimes updating selection positions can be extremely expensive and
-  // occur frequently.  Often calling preventDefault on mousedown events can
-  // avoid doing unnecessary text selection work.  http://crbug.com/472258.
-  TRACE_EVENT0("input", "VisibleUnits::SnapBackward");
-
-  if (position.IsNull())
-    return PositionWithAffinityTemplate<Strategy>();
-
-  DCHECK(position.GetDocument());
-  DCHECK(!position.GetDocument()->NeedsLayoutTreeUpdate());
-
-  const PositionTemplate<Strategy>& candidate1 =
-      MostBackwardCaretPosition(position);
-  if (IsVisuallyEquivalentCandidate(candidate1)) {
-    return PositionWithAffinityTemplate<Strategy>(candidate1,
-                                                  TextAffinity::kUpstream);
-  }
-
-  const PositionTemplate<Strategy>& candidate2 =
-      MostForwardCaretPosition(position);
-  if (IsVisuallyEquivalentCandidate(candidate2)) {
-    return PositionWithAffinityTemplate<Strategy>(candidate2,
-                                                  TextAffinity::kDownstream);
-  }
-
-  return PositionWithAffinityTemplate<Strategy>(SnapFallbackTemplate(position),
-                                                TextAffinity::kDownstream);
-}
-
-PositionWithAffinity SnapBackward(const Position& position) {
-  return SnapBackwardTemplate(position);
-}
-
-PositionInFlatTreeWithAffinity SnapBackward(
-    const PositionInFlatTree& position) {
-  return SnapBackwardTemplate(position);
-}
-
-template <typename Strategy>
-static PositionWithAffinityTemplate<Strategy> SnapForwardTemplate(
-    const PositionTemplate<Strategy>& position) {
-  // Sometimes updating selection positions can be extremely expensive and
-  // occur frequently.  Often calling preventDefault on mousedown events can
-  // avoid doing unnecessary text selection work.  http://crbug.com/472258.
-  TRACE_EVENT0("input", "VisibleUnits::SnapForward");
-
-  if (position.IsNull())
-    return PositionWithAffinityTemplate<Strategy>();
-
-  DCHECK(position.GetDocument());
-  DCHECK(!position.GetDocument()->NeedsLayoutTreeUpdate());
-
-  const PositionTemplate<Strategy>& candidate1 =
-      MostForwardCaretPosition(position);
-  if (IsVisuallyEquivalentCandidate(candidate1)) {
-    return PositionWithAffinityTemplate<Strategy>(candidate1,
-                                                  TextAffinity::kDownstream);
-  }
-
-  const PositionTemplate<Strategy>& candidate2 =
-      MostBackwardCaretPosition(position);
-  if (IsVisuallyEquivalentCandidate(candidate2)) {
-    return PositionWithAffinityTemplate<Strategy>(candidate2,
-                                                  TextAffinity::kDownstream);
-  }
-
-  return PositionWithAffinityTemplate<Strategy>(SnapFallbackTemplate(position),
-                                                TextAffinity::kDownstream);
-}
-
-PositionWithAffinity SnapForward(const Position& position) {
-  return SnapForwardTemplate(position);
-}
-
-PositionInFlatTreeWithAffinity SnapForward(const PositionInFlatTree& position) {
-  return SnapForwardTemplate(position);
-}
-
 Position CanonicalPositionOf(const Position& position) {
-  return SnapBackward(position).GetPosition();
+  return CanonicalPosition(position);
 }
 
 PositionInFlatTree CanonicalPositionOf(const PositionInFlatTree& position) {
-  return SnapBackward(position).GetPosition();
+  return CanonicalPosition(position);
 }
 
 template <typename Strategy>
diff --git a/third_party/blink/renderer/core/editing/visible_units.h b/third_party/blink/renderer/core/editing/visible_units.h
index 969c4a2..7a142bb 100644
--- a/third_party/blink/renderer/core/editing/visible_units.h
+++ b/third_party/blink/renderer/core/editing/visible_units.h
@@ -92,12 +92,6 @@
 // If true, adjacent candidates are visually distinct.
 CORE_EXPORT bool EndsOfNodeAreVisuallyDistinctPositions(const Node*);
 
-CORE_EXPORT PositionWithAffinity SnapBackward(const Position&);
-CORE_EXPORT PositionInFlatTreeWithAffinity
-SnapBackward(const PositionInFlatTree&);
-CORE_EXPORT PositionWithAffinity SnapForward(const Position&);
-CORE_EXPORT PositionInFlatTreeWithAffinity
-SnapForward(const PositionInFlatTree&);
 CORE_EXPORT Position CanonicalPositionOf(const Position&);
 CORE_EXPORT PositionInFlatTree CanonicalPositionOf(const PositionInFlatTree&);
 
diff --git a/third_party/blink/renderer/core/editing/visible_units_test.cc b/third_party/blink/renderer/core/editing/visible_units_test.cc
index 756c813b..a837b012 100644
--- a/third_party/blink/renderer/core/editing/visible_units_test.cc
+++ b/third_party/blink/renderer/core/editing/visible_units_test.cc
@@ -114,66 +114,25 @@
 
   EXPECT_EQ(Position(),
             CanonicalPositionOf(Position(GetDocument().documentElement(), 0)));
-  EXPECT_EQ(
-      Position(),
-      SnapBackward(Position(GetDocument().documentElement(), 0)).GetPosition());
-  EXPECT_EQ(
-      Position(),
-      SnapForward(Position(GetDocument().documentElement(), 0)).GetPosition());
 
   EXPECT_EQ(Position(one->firstChild(), 0),
             CanonicalPositionOf(Position(one, 0)));
-  EXPECT_EQ(Position(one->firstChild(), 0),
-            SnapBackward(Position(one, 0)).GetPosition());
-  EXPECT_EQ(Position(one->firstChild(), 0),
-            SnapForward(Position(one, 0)).GetPosition());
-
   EXPECT_EQ(Position(one->firstChild(), 1),
             CanonicalPositionOf(Position(one, 1)));
-  EXPECT_EQ(Position(one->firstChild(), 1),
-            SnapBackward(Position(one, 1)).GetPosition());
-  EXPECT_EQ(Position(one->firstChild(), 1),
-            SnapForward(Position(one, 1)).GetPosition());
 
   EXPECT_EQ(Position(one->firstChild(), 0),
             CanonicalPositionOf(Position(one->firstChild(), 0)));
-  EXPECT_EQ(Position(one->firstChild(), 0),
-            SnapBackward(Position(one->firstChild(), 0)).GetPosition());
-  EXPECT_EQ(Position(one->firstChild(), 0),
-            SnapForward(Position(one->firstChild(), 0)).GetPosition());
-
   EXPECT_EQ(Position(one->firstChild(), 1),
             CanonicalPositionOf(Position(one->firstChild(), 1)));
-  EXPECT_EQ(Position(one->firstChild(), 1),
-            SnapBackward(Position(one->firstChild(), 1)).GetPosition());
-  EXPECT_EQ(Position(one->firstChild(), 1),
-            SnapForward(Position(one->firstChild(), 1)).GetPosition());
 
   EXPECT_EQ(Position(html, 0), CanonicalPositionOf(Position(html, 0)));
-  EXPECT_EQ(Position(html, 0), SnapBackward(Position(html, 0)).GetPosition());
-  EXPECT_EQ(Position(html, 0), SnapForward(Position(html, 0)).GetPosition());
-
   EXPECT_EQ(Position(html, 1), CanonicalPositionOf(Position(html, 1)));
-  EXPECT_EQ(Position(html, 1), SnapBackward(Position(html, 1)).GetPosition());
-  EXPECT_EQ(Position(html, 1), SnapForward(Position(html, 1)).GetPosition());
-
   EXPECT_EQ(Position(html, 2), CanonicalPositionOf(Position(html, 2)));
-  EXPECT_EQ(Position(html, 2), SnapBackward(Position(html, 2)).GetPosition());
-  EXPECT_EQ(Position(html, 2), SnapForward(Position(html, 2)).GetPosition());
 
   EXPECT_EQ(Position(two->firstChild(), 0),
             CanonicalPositionOf(Position(two, 0)));
-  EXPECT_EQ(Position(two->firstChild(), 0),
-            SnapBackward(Position(two, 0)).GetPosition());
-  EXPECT_EQ(Position(two->firstChild(), 0),
-            SnapForward(Position(two, 0)).GetPosition());
-
   EXPECT_EQ(Position(two->firstChild(), 2),
             CanonicalPositionOf(Position(two, 1)));
-  EXPECT_EQ(Position(two->firstChild(), 2),
-            SnapBackward(Position(two, 1)).GetPosition());
-  EXPECT_EQ(Position(two->firstChild(), 2),
-            SnapForward(Position(two, 1)).GetPosition());
 }
 
 // For http://crbug.com/695317
@@ -181,20 +140,13 @@
   SetBodyContent("<input>123");
   Element* const input = GetDocument().QuerySelector("input");
 
-  Position position =
-      Position::FirstPositionInNode(*GetDocument().documentElement());
-  EXPECT_EQ(Position::BeforeNode(*input), CanonicalPositionOf(position));
-  EXPECT_EQ(Position::BeforeNode(*input), SnapBackward(position).GetPosition());
-  EXPECT_EQ(Position::BeforeNode(*input), SnapForward(position).GetPosition());
+  EXPECT_EQ(Position::BeforeNode(*input),
+            CanonicalPositionOf(Position::FirstPositionInNode(
+                *GetDocument().documentElement())));
 
-  PositionInFlatTree pos_in_flat_tree =
-      PositionInFlatTree::FirstPositionInNode(*GetDocument().documentElement());
   EXPECT_EQ(PositionInFlatTree::BeforeNode(*input),
-            CanonicalPositionOf(pos_in_flat_tree));
-  EXPECT_EQ(PositionInFlatTree::BeforeNode(*input),
-            SnapBackward(pos_in_flat_tree).GetPosition());
-  EXPECT_EQ(PositionInFlatTree::BeforeNode(*input),
-            SnapForward(pos_in_flat_tree).GetPosition());
+            CanonicalPositionOf(PositionInFlatTree::FirstPositionInNode(
+                *GetDocument().documentElement())));
 }
 
 TEST_F(VisibleUnitsTest, characterBefore) {
@@ -829,12 +781,8 @@
 
   Node* paragraph = GetDocument().QuerySelector("p");
   Node* text = paragraph->firstChild();
-  EXPECT_EQ(Position(text, 2),
-            CanonicalPositionOf(Position::BeforeNode(*paragraph)));
-  EXPECT_EQ(Position(text, 2),
-            SnapBackward(Position::BeforeNode(*paragraph)).GetPosition());
-  EXPECT_EQ(Position(text, 2),
-            SnapForward(Position::BeforeNode(*paragraph)).GetPosition());
+  Position start = CanonicalPositionOf(Position::BeforeNode(*paragraph));
+  EXPECT_EQ(Position(text, 2), start);
 }
 
 TEST_F(VisibleUnitsTest, MostForwardCaretPositionWithInvisibleFirstLetter) {
diff --git a/third_party/blink/renderer/core/feature_policy/document_policy_sim_test.cc b/third_party/blink/renderer/core/feature_policy/document_policy_sim_test.cc
new file mode 100644
index 0000000..636509b
--- /dev/null
+++ b/third_party/blink/renderer/core/feature_policy/document_policy_sim_test.cc
@@ -0,0 +1,457 @@
+// 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 "base/test/scoped_feature_list.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/feature_policy/policy_disposition.mojom-blink.h"
+#include "third_party/blink/renderer/core/feature_policy/policy_helper.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
+#include "third_party/blink/renderer/platform/testing/histogram_tester.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
+
+namespace blink {
+
+class DocumentPolicySimTest : public SimTest {
+ public:
+  DocumentPolicySimTest()
+      : scoped_document_policy_(true),
+        scoped_document_policy_negotiation_(true) {
+    ResetAvailableDocumentPolicyFeaturesForTest();
+  }
+
+ private:
+  ScopedDocumentPolicyForTest scoped_document_policy_;
+  ScopedDocumentPolicyNegotiationForTest scoped_document_policy_negotiation_;
+};
+
+// When runtime feature DocumentPolicy is not enabled, specifying
+// Document-Policy, Require-Document-Policy and policy attribute
+// should have no effect, i.e.
+// document load should not be blocked even if the required policy and incoming
+// policy are incompatible and calling
+// |Document::IsFeatureEnabled(DocumentPolicyFeature...)| should always return
+// true.
+TEST_F(DocumentPolicySimTest, DocumentPolicyNoEffectWhenFlagNotSet) {
+  ScopedDocumentPolicyForTest sdp(false);
+  ScopedDocumentPolicyNegotiationForTest sdpn(false);
+  ResetAvailableDocumentPolicyFeaturesForTest();
+
+  SimRequest::Params main_params;
+  main_params.response_http_headers = {
+      {"Require-Document-Policy", "lossless-images-max-bpp=1.0"}};
+
+  SimRequest::Params iframe_params;
+  iframe_params.response_http_headers = {
+      {"Document-Policy", "lossless-images-max-bpp=1.1"}};
+
+  SimRequest main_resource("https://example.com", "text/html", main_params);
+  SimRequest iframe_resource("https://example.com/foo.html", "text/html",
+                             iframe_params);
+
+  LoadURL("https://example.com");
+  main_resource.Complete(R"(
+    <iframe
+      src="https://example.com/foo.html"
+      policy="lossless-images-max-bpp=1.0">
+    </iframe>
+  )");
+
+  iframe_resource.Finish();
+  auto* child_frame = To<WebLocalFrameImpl>(MainFrame().FirstChild());
+  auto* child_window = child_frame->GetFrame()->DomWindow();
+  auto& console_messages = static_cast<frame_test_helpers::TestWebFrameClient*>(
+                               child_frame->Client())
+                               ->ConsoleMessages();
+
+  // Should not receive a console error message caused by document policy
+  // violation blocking document load.
+  EXPECT_TRUE(console_messages.IsEmpty());
+
+  EXPECT_EQ(child_window->Url(), KURL("https://example.com/foo.html"));
+
+  EXPECT_FALSE(child_window->document()->IsUseCounted(
+      mojom::WebFeature::kDocumentPolicyCausedPageUnload));
+
+  // lossless-images-max-bpp should be set to inf in main document, i.e. allow
+  // all values.
+  EXPECT_TRUE(Window().IsFeatureEnabled(
+      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
+      PolicyValue::CreateDecDouble(2.0)));
+  EXPECT_TRUE(Window().IsFeatureEnabled(
+      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
+      PolicyValue::CreateDecDouble(1.0)));
+
+  // lossless-images-max-bpp should be set to inf in child document, i.e. allow
+  // all values.
+  EXPECT_TRUE(child_window->IsFeatureEnabled(
+      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
+      PolicyValue::CreateDecDouble(2.0)));
+  EXPECT_TRUE(child_window->IsFeatureEnabled(
+      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
+      PolicyValue::CreateDecDouble(1.0)));
+}
+
+// When runtime feature DocumentPolicyNegotiation is not enabled, specifying
+// Require-Document-Policy HTTP header and policy attribute on iframe should
+// have no effect, i.e. document load should not be blocked even if the required
+// policy and incoming policy are incompatible. Document-Policy header should
+// function as normal.
+TEST_F(DocumentPolicySimTest, DocumentPolicyNegotiationNoEffectWhenFlagNotSet) {
+  ScopedDocumentPolicyNegotiationForTest sdpn(false);
+  ResetAvailableDocumentPolicyFeaturesForTest();
+
+  SimRequest::Params main_params;
+  main_params.response_http_headers = {
+      {"Require-Document-Policy", "lossless-images-max-bpp=1.0"}};
+
+  SimRequest::Params iframe_params;
+  iframe_params.response_http_headers = {
+      {"Document-Policy", "lossless-images-max-bpp=1.1"}};
+
+  SimRequest main_resource("https://example.com", "text/html", main_params);
+  SimRequest iframe_resource("https://example.com/foo.html", "text/html",
+                             iframe_params);
+
+  LoadURL("https://example.com");
+  main_resource.Complete(R"(
+    <iframe
+      src="https://example.com/foo.html"
+      policy="lossless-images-max-bpp=1.0">
+    </iframe>
+  )");
+
+  iframe_resource.Finish();
+  auto* child_frame = To<WebLocalFrameImpl>(MainFrame().FirstChild());
+  auto* child_window = child_frame->GetFrame()->DomWindow();
+  auto& console_messages = static_cast<frame_test_helpers::TestWebFrameClient*>(
+                               child_frame->Client())
+                               ->ConsoleMessages();
+
+  // Should not receive a console error message caused by document policy
+  // violation blocking document load.
+  EXPECT_TRUE(console_messages.IsEmpty());
+
+  EXPECT_EQ(child_window->Url(), KURL("https://example.com/foo.html"));
+
+  EXPECT_FALSE(child_window->document()->IsUseCounted(
+      mojom::WebFeature::kDocumentPolicyCausedPageUnload));
+
+  // lossless-images-max-bpp should be set to inf in main document, i.e. allow
+  // all values.
+  EXPECT_TRUE(Window().IsFeatureEnabled(
+      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
+      PolicyValue::CreateDecDouble(2.0)));
+  EXPECT_TRUE(Window().IsFeatureEnabled(
+      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
+      PolicyValue::CreateDecDouble(1.0)));
+
+  // lossless-images-max-bpp should be set to 1.1 in child document.
+  EXPECT_FALSE(child_window->IsFeatureEnabled(
+      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
+      PolicyValue::CreateDecDouble(2.0)));
+  EXPECT_TRUE(child_window->IsFeatureEnabled(
+      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
+      PolicyValue::CreateDecDouble(1.0)));
+}
+
+TEST_F(DocumentPolicySimTest, ReportDocumentPolicyHeaderParsingError) {
+  SimRequest::Params params;
+  params.response_http_headers = {{"Document-Policy", "bad-feature-name"}};
+  SimRequest main_resource("https://example.com", "text/html", params);
+  LoadURL("https://example.com");
+  main_resource.Finish();
+
+  EXPECT_EQ(ConsoleMessages().size(), 1u);
+  EXPECT_TRUE(
+      ConsoleMessages().front().StartsWith("Document-Policy HTTP header:"));
+}
+
+TEST_F(DocumentPolicySimTest, ReportRequireDocumentPolicyHeaderParsingError) {
+  SimRequest::Params params;
+  params.response_http_headers = {
+      {"Require-Document-Policy", "bad-feature-name"}};
+  SimRequest main_resource("https://example.com", "text/html", params);
+  LoadURL("https://example.com");
+  main_resource.Finish();
+
+  EXPECT_EQ(ConsoleMessages().size(), 1u);
+  EXPECT_TRUE(ConsoleMessages().front().StartsWith(
+      "Require-Document-Policy HTTP header:"));
+}
+
+TEST_F(DocumentPolicySimTest, ReportErrorWhenDocumentPolicyIncompatible) {
+  SimRequest::Params params;
+  params.response_http_headers = {
+      {"Document-Policy", "lossless-images-max-bpp=1.1"}};
+
+  SimRequest main_resource("https://example.com", "text/html");
+  SimRequest iframe_resource("https://example.com/foo.html", "text/html",
+                             params);
+
+  LoadURL("https://example.com");
+  main_resource.Complete(R"(
+    <iframe
+      src="https://example.com/foo.html"
+      policy="lossless-images-max-bpp=1.0">
+    </iframe>
+  )");
+
+  // When blocked by document policy, the document should be filled in with an
+  // empty response, with Finish called on |navigation_body_loader| already.
+  // If Finish was not called on the loader, because the document was not
+  // blocked, this test will fail by crashing here.
+  iframe_resource.Finish(true /* body_loader_finished */);
+
+  auto* child_frame = To<WebLocalFrameImpl>(MainFrame().FirstChild());
+  auto* child_document = child_frame->GetFrame()->GetDocument();
+
+  // Should console log a error message.
+  auto& console_messages = static_cast<frame_test_helpers::TestWebFrameClient*>(
+                               child_frame->Client())
+                               ->ConsoleMessages();
+
+  ASSERT_EQ(console_messages.size(), 1u);
+  EXPECT_TRUE(console_messages.front().Contains("document policy"));
+
+  // Should replace the document's origin with an opaque origin.
+  EXPECT_EQ(child_document->Url(), SecurityOrigin::UrlWithUniqueOpaqueOrigin());
+
+  EXPECT_TRUE(child_document->IsUseCounted(
+      mojom::WebFeature::kDocumentPolicyCausedPageUnload));
+}
+
+// HTTP header Require-Document-Policy should only take effect on subtree of
+// current document, but not on current document.
+TEST_F(DocumentPolicySimTest,
+       RequireDocumentPolicyHeaderShouldNotAffectCurrentDocument) {
+  SimRequest::Params params;
+  params.response_http_headers = {
+      {"Require-Document-Policy", "lossless-images-max-bpp=1.0"},
+      {"Document-Policy", "lossless-images-max-bpp=1.1"}};
+
+  SimRequest main_resource("https://example.com", "text/html", params);
+  LoadURL("https://example.com");
+  // If document is blocked by document policy because of incompatible document
+  // policy, this test will fail by crashing here.
+  main_resource.Finish();
+}
+
+TEST_F(DocumentPolicySimTest, DocumentPolicyHeaderHistogramTest) {
+  HistogramTester histogram_tester;
+
+  SimRequest::Params params;
+  params.response_http_headers = {
+      {"Document-Policy",
+       "font-display-late-swap, lossless-images-max-bpp=1.1"}};
+
+  SimRequest main_resource("https://example.com", "text/html", params);
+  LoadURL("https://example.com");
+  main_resource.Finish();
+
+  histogram_tester.ExpectTotalCount("Blink.UseCounter.DocumentPolicy.Header",
+                                    2);
+  histogram_tester.ExpectBucketCount("Blink.UseCounter.DocumentPolicy.Header",
+                                     1 /* kFontDisplay */, 1);
+  histogram_tester.ExpectBucketCount("Blink.UseCounter.DocumentPolicy.Header",
+                                     2 /* kUnoptimizedLosslessImages */, 1);
+}
+
+TEST_F(DocumentPolicySimTest, DocumentPolicyPolicyAttributeHistogramTest) {
+  HistogramTester histogram_tester;
+
+  SimRequest main_resource("https://example.com", "text/html");
+  LoadURL("https://example.com");
+
+  // Same feature should only be reported once in a document despite its
+  // occurrence.
+  main_resource.Complete(R"(
+    <iframe policy="font-display-late-swap"></iframe>
+    <iframe policy="font-display-late-swap=?0"></iframe>
+    <iframe
+      policy="font-display-late-swap, lossless-images-max-bpp=1.1">
+    </iframe>
+  )");
+
+  histogram_tester.ExpectTotalCount(
+      "Blink.UseCounter.DocumentPolicy.PolicyAttribute", 2);
+  histogram_tester.ExpectBucketCount(
+      "Blink.UseCounter.DocumentPolicy.PolicyAttribute", 1 /* kFontDisplay */,
+      1);
+  histogram_tester.ExpectBucketCount(
+      "Blink.UseCounter.DocumentPolicy.PolicyAttribute",
+      2 /* kUnoptimizedLosslessImages */, 1);
+}
+
+TEST_F(DocumentPolicySimTest, DocumentPolicyEnforcedReportHistogramTest) {
+  HistogramTester histogram_tester;
+
+  SimRequest main_resource("https://example.com", "text/html");
+  LoadURL("https://example.com");
+  main_resource.Finish();
+
+  Window().ReportDocumentPolicyViolation(
+      mojom::blink::DocumentPolicyFeature::kFontDisplay,
+      mojom::blink::PolicyDisposition::kEnforce,
+      "first font display violation");
+
+  histogram_tester.ExpectTotalCount("Blink.UseCounter.DocumentPolicy.Enforced",
+                                    1);
+  histogram_tester.ExpectBucketCount("Blink.UseCounter.DocumentPolicy.Enforced",
+                                     1 /* kFontDisplay */, 1);
+
+  // Multiple reports should be recorded multiple times.
+  Window().ReportDocumentPolicyViolation(
+      mojom::blink::DocumentPolicyFeature::kFontDisplay,
+      mojom::blink::PolicyDisposition::kEnforce,
+      "second font display violation");
+
+  histogram_tester.ExpectTotalCount("Blink.UseCounter.DocumentPolicy.Enforced",
+                                    2);
+  histogram_tester.ExpectBucketCount("Blink.UseCounter.DocumentPolicy.Enforced",
+                                     1 /* kFontDisplay */, 2);
+}
+
+TEST_F(DocumentPolicySimTest, DocumentPolicyReportOnlyReportHistogramTest) {
+  HistogramTester histogram_tester;
+
+  SimRequest::Params params;
+  params.response_http_headers = {
+      {"Document-Policy-Report-Only", "font-display-late-swap"}};
+  SimRequest main_resource("https://example.com", "text/html", params);
+
+  LoadURL("https://example.com");
+  main_resource.Finish();
+
+  Window().ReportDocumentPolicyViolation(
+      mojom::blink::DocumentPolicyFeature::kFontDisplay,
+      mojom::blink::PolicyDisposition::kReport, "first font display violation");
+
+  histogram_tester.ExpectTotalCount(
+      "Blink.UseCounter.DocumentPolicy.ReportOnly", 1);
+  histogram_tester.ExpectBucketCount(
+      "Blink.UseCounter.DocumentPolicy.ReportOnly", 1 /* kFontDisplay */, 1);
+
+  // Multiple reports should be recorded multiple times.
+  Window().ReportDocumentPolicyViolation(
+      mojom::blink::DocumentPolicyFeature::kFontDisplay,
+      mojom::blink::PolicyDisposition::kReport,
+      "second font display violation");
+
+  histogram_tester.ExpectTotalCount(
+      "Blink.UseCounter.DocumentPolicy.ReportOnly", 2);
+  histogram_tester.ExpectBucketCount(
+      "Blink.UseCounter.DocumentPolicy.ReportOnly", 1 /* kFontDisplay */, 2);
+}
+
+class DocumentPolicyHeaderUseCounterTest
+    : public DocumentPolicySimTest,
+      public testing::WithParamInterface<std::tuple<bool, bool, bool>> {};
+
+TEST_P(DocumentPolicyHeaderUseCounterTest, ShouldObserveUseCounterUpdate) {
+  bool has_document_policy_header, has_report_only_header, has_require_header;
+  std::tie(has_document_policy_header, has_report_only_header,
+           has_require_header) = GetParam();
+
+  SimRequest::Params params;
+  if (has_document_policy_header) {
+    params.response_http_headers.insert("Document-Policy",
+                                        "lossless-images-max-bpp=1.0");
+  }
+  if (has_report_only_header) {
+    params.response_http_headers.insert("Document-Policy-Report-Only",
+                                        "lossless-images-max-bpp=1.0");
+  }
+  if (has_require_header) {
+    params.response_http_headers.insert("Require-Document-Policy",
+                                        "lossless-images-max-bpp=1.0");
+  }
+  SimRequest main_resource("https://example.com", "text/html", params);
+  LoadURL("https://example.com");
+  main_resource.Complete();
+
+  EXPECT_EQ(
+      GetDocument().IsUseCounted(mojom::WebFeature::kDocumentPolicyHeader),
+      has_document_policy_header);
+  EXPECT_EQ(GetDocument().IsUseCounted(
+                mojom::WebFeature::kDocumentPolicyReportOnlyHeader),
+            has_report_only_header);
+  EXPECT_EQ(GetDocument().IsUseCounted(
+                mojom::WebFeature::kRequireDocumentPolicyHeader),
+            has_require_header);
+}
+
+INSTANTIATE_TEST_SUITE_P(DocumentPolicyHeaderValues,
+                         DocumentPolicyHeaderUseCounterTest,
+                         ::testing::Combine(::testing::Bool(),
+                                            ::testing::Bool(),
+                                            ::testing::Bool()));
+
+TEST_F(DocumentPolicySimTest,
+       DocumentPolicyIframePolicyAttributeUseCounterTest) {
+  SimRequest main_resource("https://example.com", "text/html");
+  SimRequest::Params iframe_params;
+  iframe_params.response_http_headers = {
+      {"Document-Policy", "lossless-images-max-bpp=1.0"}};
+  SimRequest iframe_resource("https://example.com/foo.html", "text/html",
+                             iframe_params);
+  LoadURL("https://example.com");
+  main_resource.Complete(R"(
+    <iframe
+      src="https://example.com/foo.html"
+      policy="lossless-images-max-bpp=1.0"
+    ></iframe>
+  )");
+  iframe_resource.Finish();
+
+  EXPECT_TRUE(GetDocument().IsUseCounted(
+      mojom::WebFeature::kDocumentPolicyIframePolicyAttribute));
+  EXPECT_FALSE(
+      GetDocument().IsUseCounted(mojom::WebFeature::kRequiredDocumentPolicy));
+
+  auto* child_frame = To<WebLocalFrameImpl>(MainFrame().FirstChild());
+  auto* child_document = child_frame->GetFrame()->GetDocument();
+
+  EXPECT_FALSE(child_document->IsUseCounted(
+      mojom::WebFeature::kDocumentPolicyIframePolicyAttribute));
+  EXPECT_TRUE(
+      child_document->IsUseCounted(mojom::WebFeature::kRequiredDocumentPolicy));
+}
+
+TEST_F(DocumentPolicySimTest, RequiredDocumentPolicyUseCounterTest) {
+  SimRequest::Params main_frame_params;
+  main_frame_params.response_http_headers = {
+      {"Require-Document-Policy", "lossless-images-max-bpp=1.0"}};
+  SimRequest main_resource("https://example.com", "text/html",
+                           main_frame_params);
+
+  SimRequest::Params iframe_params;
+  iframe_params.response_http_headers = {
+      {"Document-Policy", "lossless-images-max-bpp=1.0"}};
+  SimRequest iframe_resource("https://example.com/foo.html", "text/html",
+                             iframe_params);
+
+  LoadURL("https://example.com");
+  main_resource.Complete(R"(
+    <iframe src="https://example.com/foo.html"></iframe>
+  )");
+  iframe_resource.Finish();
+
+  EXPECT_FALSE(GetDocument().IsUseCounted(
+      mojom::WebFeature::kDocumentPolicyIframePolicyAttribute));
+  EXPECT_FALSE(
+      GetDocument().IsUseCounted(mojom::WebFeature::kRequiredDocumentPolicy));
+
+  auto* child_frame = To<WebLocalFrameImpl>(MainFrame().FirstChild());
+  auto* child_document = child_frame->GetFrame()->GetDocument();
+
+  EXPECT_FALSE(child_document->IsUseCounted(
+      mojom::WebFeature::kDocumentPolicyIframePolicyAttribute));
+  EXPECT_TRUE(
+      child_document->IsUseCounted(mojom::WebFeature::kRequiredDocumentPolicy));
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/feature_policy/policy_helper.h b/third_party/blink/renderer/core/feature_policy/policy_helper.h
index a0292f4..7bd6408 100644
--- a/third_party/blink/renderer/core/feature_policy/policy_helper.h
+++ b/third_party/blink/renderer/core/feature_policy/policy_helper.h
@@ -10,6 +10,7 @@
 #include "third_party/blink/public/mojom/feature_policy/document_policy_feature.mojom-blink.h"
 #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink-forward.h"
+#include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -79,6 +80,9 @@
 // policy object.
 const DocumentPolicyFeatureSet& GetAvailableDocumentPolicyFeatures();
 
+// Refresh the set content based on current RuntimeFeatures environment.
+CORE_EXPORT void ResetAvailableDocumentPolicyFeaturesForTest();
+
 // Returns true if this FeaturePolicyFeature is currently disabled by an origin
 // trial (it is origin trial controlled, and the origin trial is not enabled).
 // The first String param should be a name of FeaturePolicyFeature.
diff --git a/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc b/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc
index f718f51a..bfc683591 100644
--- a/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc
+++ b/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc
@@ -463,9 +463,10 @@
 
     Element* element = GetDocument().getElementById("test");
     ASSERT_NE(nullptr, element);
-    const SVGComputedStyle& svg_style = element->ComputedStyleRef().SvgStyle();
-    EXPECT_EQ(0xff008000, svg_style.StopColor().GetColor());
-    EXPECT_EQ(.5f, svg_style.StopOpacity());
+    const ComputedStyle& style = element->ComputedStyleRef();
+    EXPECT_EQ(0xff008000,
+              style.VisitedDependentColor(GetCSSPropertyStopColor()));
+    EXPECT_EQ(.5f, style.StopOpacity());
   };
 
   EXPECT_TRUE(GetDocument().HaveRenderBlockingResourcesLoaded());
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index eaaabab..3051ca0 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -850,6 +850,14 @@
   return transient_allow_fullscreen_.IsActive();
 }
 
+bool LocalFrame::IsPaymentRequestTokenActive() const {
+  return payment_request_token_.IsActive();
+}
+
+bool LocalFrame::ConsumePaymentRequestToken() {
+  return payment_request_token_.ConsumeIfActive();
+}
+
 void LocalFrame::SetOptimizationGuideHints(
     mojom::blink::BlinkOptimizationGuideHintsPtr hints) {
   DCHECK(hints);
@@ -3344,6 +3352,12 @@
         message.user_activation->has_been_active,
         message.user_activation->was_active);
   }
+
+  if (RuntimeEnabledFeatures::CapabilityDelegationPaymentRequestEnabled() &&
+      message.delegate_payment_request) {
+    payment_request_token_.Activate();
+  }
+
   message_event->initMessageEvent(
       "message", false, false, std::move(message.message), source_origin,
       "" /*lastEventId*/, window, ports, user_activation,
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h
index 2f9dfd7d..23b9035 100644
--- a/third_party/blink/renderer/core/frame/local_frame.h
+++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -38,6 +38,7 @@
 #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/unique_receiver_set.h"
+#include "third_party/blink/public/common/frame/payment_request_token.h"
 #include "third_party/blink/public/common/frame/transient_allow_fullscreen.h"
 #include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h"
 #include "third_party/blink/public/mojom/frame/back_forward_cache_controller.mojom-blink.h"
@@ -736,6 +737,12 @@
   // Return true if the frame has a transient affordance to enter fullscreen.
   bool IsTransientAllowFullscreenActive() const;
 
+  // Returns the state of the |PaymentRequestToken| in the current |Frame|.
+  bool IsPaymentRequestTokenActive() const;
+
+  // Consumes the |PaymentRequestToken| of the current |Frame| if it was active.
+  bool ConsumePaymentRequestToken();
+
   void SetOptimizationGuideHints(
       mojom::blink::BlinkOptimizationGuideHintsPtr hints);
   mojom::blink::BlinkOptimizationGuideHints* GetOptimizationGuideHints() {
@@ -1008,6 +1015,8 @@
   // Manages a transient affordance for this frame to enter fullscreen.
   TransientAllowFullscreen transient_allow_fullscreen_;
 
+  PaymentRequestToken payment_request_token_;
+
   std::unique_ptr<PolicyContainer> policy_container_;
 
   bool is_window_controls_overlay_visible_ = false;
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc
index fa2a333a..edb7197a 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.cc
+++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -1465,6 +1465,12 @@
          !GetWebMediaPlayer()->PausedWhenHidden();
 }
 
+void HTMLMediaElement::DidAudioOutputSinkChanged(
+    const String& hashed_device_id) {
+  for (auto& observer : media_player_observer_remote_set_)
+    observer->OnAudioOutputSinkChanged(hashed_device_id);
+}
+
 void HTMLMediaElement::AddMediaPlayerObserverForTesting(
     mojo::PendingRemote<media::mojom::blink::MediaPlayerObserver> observer) {
   AddMediaPlayerObserver(std::move(observer));
@@ -4399,38 +4405,26 @@
 }
 
 void HTMLMediaElement::DidPlayerStartPlaying() {
-  for (auto& observer : media_player_observer_remote_set_) {
-    if (!observer.is_bound())
-      continue;
+  for (auto& observer : media_player_observer_remote_set_)
     observer->OnMediaPlaying();
-  }
 }
 
 void HTMLMediaElement::DidPlayerPaused(bool stream_ended) {
-  for (auto& observer : media_player_observer_remote_set_) {
-    if (!observer.is_bound())
-      continue;
+  for (auto& observer : media_player_observer_remote_set_)
     observer->OnMediaPaused(stream_ended);
-  }
 }
 
 void HTMLMediaElement::DidPlayerMutedStatusChange(bool muted) {
-  for (auto& observer : media_player_observer_remote_set_) {
-    if (!observer.is_bound())
-      continue;
+  for (auto& observer : media_player_observer_remote_set_)
     observer->OnMutedStatusChanged(muted);
-  }
 }
 
 void HTMLMediaElement::DidMediaMetadataChange(
     bool has_audio,
     bool has_video,
     media::MediaContentType media_content_type) {
-  for (auto& observer : media_player_observer_remote_set_) {
-    if (!observer.is_bound())
-      continue;
+  for (auto& observer : media_player_observer_remote_set_)
     observer->OnMediaMetadataChanged(has_audio, has_video, media_content_type);
-  }
 }
 
 void HTMLMediaElement::DidPlayerMediaPositionStateChange(
@@ -4438,8 +4432,6 @@
     base::TimeDelta duration,
     base::TimeDelta position) {
   for (auto& observer : media_player_observer_remote_set_) {
-    if (!observer.is_bound())
-      continue;
     observer->OnMediaPositionStateChanged(
         media_session::mojom::blink::MediaPosition::New(
             playback_rate, duration, position, base::TimeTicks::Now()));
@@ -4447,27 +4439,18 @@
 }
 
 void HTMLMediaElement::DidDisableAudioOutputSinkChanges() {
-  for (auto& observer : media_player_observer_remote_set_) {
-    if (!observer.is_bound())
-      continue;
+  for (auto& observer : media_player_observer_remote_set_)
     observer->OnAudioOutputSinkChangingDisabled();
-  }
 }
 
 void HTMLMediaElement::DidPlayerSizeChange(const gfx::Size& size) {
-  for (auto& observer : media_player_observer_remote_set_) {
-    if (!observer.is_bound())
-      continue;
+  for (auto& observer : media_player_observer_remote_set_)
     observer->OnMediaSizeChanged(size);
-  }
 }
 
 void HTMLMediaElement::DidBufferUnderflow() {
-  for (auto& observer : media_player_observer_remote_set_) {
-    if (!observer.is_bound())
-      continue;
+  for (auto& observer : media_player_observer_remote_set_)
     observer->OnBufferUnderflow();
-  }
 }
 
 void HTMLMediaElement::DidSeek() {
@@ -4476,11 +4459,8 @@
       (base::TimeTicks::Now() - last_seek_update_time_ >=
        base::TimeDelta::FromSeconds(1))) {
     last_seek_update_time_ = base::TimeTicks::Now();
-    for (auto& observer : media_player_observer_remote_set_) {
-      if (!observer.is_bound())
-        continue;
+    for (auto& observer : media_player_observer_remote_set_)
       observer->OnSeek();
-    }
   }
 }
 
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.h b/third_party/blink/renderer/core/html/media/html_media_element.h
index 85124f7a..66b4f59 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.h
+++ b/third_party/blink/renderer/core/html/media/html_media_element.h
@@ -352,6 +352,8 @@
   // becomes visible again.
   bool PausedWhenVisible() const;
 
+  void DidAudioOutputSinkChanged(const String& hashed_device_id);
+
   void SetCcLayerForTesting(cc::Layer* layer) { SetCcLayer(layer); }
 
   // Required by tests set mock receivers to check that messages are delivered.
diff --git a/third_party/blink/renderer/core/html/media/html_media_element_test.cc b/third_party/blink/renderer/core/html/media/html_media_element_test.cc
index 1f2ee646..08e4ae42 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element_test.cc
+++ b/third_party/blink/renderer/core/html/media/html_media_element_test.cc
@@ -145,6 +145,9 @@
   void OnMediaPositionStateChanged(
       ::media_session::mojom::blink::MediaPositionPtr) override {}
 
+  void OnMediaEffectivelyFullscreenChanged(
+      blink::WebFullscreenVideoStatus status) override {}
+
   void OnMediaSizeChanged(const gfx::Size& size) override {
     received_media_size_ = size;
     run_loop_->Quit();
@@ -152,6 +155,8 @@
 
   void OnPictureInPictureAvailabilityChanged(bool available) override {}
 
+  void OnAudioOutputSinkChanged(const WTF::String& hashed_device_id) override {}
+
   void OnAudioOutputSinkChangingDisabled() override {}
 
   void OnBufferUnderflow() override {
diff --git a/third_party/blink/renderer/core/html/media/html_video_element.cc b/third_party/blink/renderer/core/html/media/html_video_element.cc
index 6ccd30d..3b34fe1 100644
--- a/third_party/blink/renderer/core/html/media/html_video_element.cc
+++ b/third_party/blink/renderer/core/html/media/html_video_element.cc
@@ -266,11 +266,8 @@
   if (!web_media_player_)
     return;
 
-  for (auto& observer : GetMediaPlayerObserverRemoteSet()) {
-    if (!observer.is_bound())
-      continue;
+  for (auto& observer : GetMediaPlayerObserverRemoteSet())
     observer->OnPictureInPictureAvailabilityChanged(SupportsPictureInPicture());
-  }
 }
 
 // TODO(zqzhang): this callback could be used to hide native controls instead of
@@ -736,6 +733,9 @@
   is_effectively_fullscreen_ =
       status != blink::WebFullscreenVideoStatus::kNotEffectivelyFullscreen;
   if (GetWebMediaPlayer()) {
+    for (auto& observer : GetMediaPlayerObserverRemoteSet())
+      observer->OnMediaEffectivelyFullscreenChanged(status);
+
     GetWebMediaPlayer()->SetIsEffectivelyFullscreen(status);
     GetWebMediaPlayer()->OnDisplayTypeChanged(GetDisplayType());
   }
diff --git a/third_party/blink/renderer/core/input/mouse_event_manager.cc b/third_party/blink/renderer/core/input/mouse_event_manager.cc
index 3856924..48dbe7f 100644
--- a/third_party/blink/renderer/core/input/mouse_event_manager.cc
+++ b/third_party/blink/renderer/core/input/mouse_event_manager.cc
@@ -714,6 +714,12 @@
   if (single_click)
     FocusDocumentView();
 
+  // |SelectionController| calls |PositionForPoint()| which requires
+  // |kPrePaintClean|. |FocusDocumentView| above is the last possible
+  // modifications before we call |SelectionController|.
+  if (LocalFrameView* frame_view = frame_->View())
+    frame_view->UpdateLifecycleToPrePaintClean(DocumentUpdateReason::kInput);
+
   Node* inner_node = event.InnerNode();
 
   mouse_press_node_ = inner_node;
@@ -854,6 +860,11 @@
       return WebInputEventResult::kNotHandled;
   }
 
+  // |SelectionController| calls |PositionForPoint()| which requires
+  // |kPrePaintClean|.
+  if (LocalFrameView* frame_view = frame_->View())
+    frame_view->UpdateLifecycleToPrePaintClean(DocumentUpdateReason::kInput);
+
   mouse_down_may_start_drag_ = false;
 
   frame_->GetEventHandler().GetSelectionController().HandleMouseDraggedEvent(
diff --git a/third_party/blink/renderer/core/layout/hit_test_result.cc b/third_party/blink/renderer/core/layout/hit_test_result.cc
index 73a8a75..821f016e 100644
--- a/third_party/blink/renderer/core/layout/hit_test_result.cc
+++ b/third_party/blink/renderer/core/layout/hit_test_result.cc
@@ -164,6 +164,9 @@
   const Node* node = inner_possibly_pseudo_node_;
   if (!node)
     return PositionWithAffinity();
+  // |LayoutObject::PositionForPoint()| requires |kPrePaintClean|.
+  DCHECK_GE(node->GetDocument().Lifecycle().GetState(),
+            DocumentLifecycle::kPrePaintClean);
   LayoutObject* layout_object = node->GetLayoutObject();
   if (!layout_object)
     return PositionWithAffinity();
@@ -193,6 +196,9 @@
     node = InnerNodeOrImageMapImage();
   if (!node)
     return PositionWithAffinity();
+  // |LayoutObject::PositionForPoint()| requires |kPrePaintClean|.
+  DCHECK_GE(node->GetDocument().Lifecycle().GetState(),
+            DocumentLifecycle::kPrePaintClean);
   LayoutObject* layout_object = node->GetLayoutObject();
   if (!layout_object)
     return PositionWithAffinity();
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index 9fa4fdee..3502fb3 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -472,7 +472,8 @@
         !after_child->IsBeforeContent()) {
       table = after_child;
     } else {
-      table = LayoutObjectFactory::CreateAnonymousTableWithParent(*this);
+      table = LayoutObjectFactory::CreateAnonymousTableWithParent(
+          *this, !new_child->IsLayoutNGObject());
       children->InsertChildNode(this, table, before_child);
     }
     table->AddChild(new_child);
@@ -4309,7 +4310,7 @@
   NOT_DESTROYED();
   if (IsSVGChild()) {
     // The boundaries affect mask clip.
-    if (StyleRef().SvgStyle().HasMasker())
+    if (StyleRef().MaskerResource())
       SetNeedsPaintPropertyUpdate();
     if (StyleRef().HasClipPath())
       InvalidateClipPathCache();
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index 5dc07fe..78f0d538 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -150,7 +150,7 @@
 // exclude certain functions like ~SVGImage() from this rule. This is allowed
 // when a Persistent is guaranteeing to keep the LayoutObject alive for that GC
 // cycle.
-class AllowDestroyingLayoutObjectInFinalizerScope {
+class CORE_EXPORT AllowDestroyingLayoutObjectInFinalizerScope {
   STACK_ALLOCATED();
 
  public:
diff --git a/third_party/blink/renderer/core/layout/layout_object_factory.cc b/third_party/blink/renderer/core/layout/layout_object_factory.cc
index d67ea5ad..8648656 100644
--- a/third_party/blink/renderer/core/layout/layout_object_factory.cc
+++ b/third_party/blink/renderer/core/layout/layout_object_factory.cc
@@ -351,13 +351,15 @@
 }
 
 LayoutBox* LayoutObjectFactory::CreateAnonymousTableWithParent(
-    const LayoutObject& parent) {
+    const LayoutObject& parent,
+    bool child_forces_legacy) {
   scoped_refptr<ComputedStyle> new_style =
       ComputedStyle::CreateAnonymousStyleWithDisplay(
           parent.StyleRef(),
           parent.IsLayoutInline() ? EDisplay::kInlineTable : EDisplay::kTable);
-  LegacyLayout legacy =
-      parent.ForceLegacyLayout() ? LegacyLayout::kForce : LegacyLayout::kAuto;
+  LegacyLayout legacy = parent.ForceLegacyLayout() || child_forces_legacy
+                            ? LegacyLayout::kForce
+                            : LegacyLayout::kAuto;
 
   LayoutBlock* new_table =
       CreateTable(parent.GetDocument(), *new_style, legacy);
diff --git a/third_party/blink/renderer/core/layout/layout_object_factory.h b/third_party/blink/renderer/core/layout/layout_object_factory.h
index a1ed82d5..dfd5a5d8 100644
--- a/third_party/blink/renderer/core/layout/layout_object_factory.h
+++ b/third_party/blink/renderer/core/layout/layout_object_factory.h
@@ -104,7 +104,11 @@
 
   // Anonoymous creation methods
 
-  static LayoutBox* CreateAnonymousTableWithParent(const LayoutObject& parent);
+  // |child_forces_legacy| true if creating parents boxes for legacy child.
+  // Table must match child's type.
+  static LayoutBox* CreateAnonymousTableWithParent(
+      const LayoutObject& parent,
+      bool child_forces_legacy = false);
 
   static LayoutBox* CreateAnonymousTableSectionWithParent(
       const LayoutObject& parent);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc
index af19cf8..a7bb7d0 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc
@@ -313,9 +313,14 @@
   const base::Optional<unsigned> maybe_offset =
       mapping->GetTextContentOffset(position);
   if (!maybe_offset.has_value()) {
-    // TODO(xiaochengh): Investigate if we reach here.
-    NOTREACHED();
-    return NGCaretPosition();
+    // We can reach here with empty text nodes.
+    if (auto* data = DynamicTo<Text>(position.AnchorNode())) {
+      DCHECK_EQ(data->length(), 0u);
+    } else {
+      // TODO(xiaochengh): Investigate if we reach here.
+      NOTREACHED();
+      return NGCaretPosition();
+    }
   }
 
   const LayoutText* const layout_text =
@@ -324,7 +329,7 @@
                 *position.AnchorNode(), position.OffsetInContainerNode()))
           : nullptr;
 
-  const unsigned offset = *maybe_offset;
+  const unsigned offset = maybe_offset.value_or(0);
   const TextAffinity affinity = position_with_affinity.Affinity();
   // For upstream position, we use offset before ZWS to distinguish downstream
   // and upstream position when line breaking before ZWS.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
index 878a9f5e..832c5579 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
@@ -2285,10 +2285,8 @@
   }
 
   // Use the style at the beginning of the line if no items are available.
-  if (break_token_) {
-    DCHECK(break_token_->Style());
+  if (break_token_ && break_token_->Style())
     return *break_token_->Style();
-  }
   return line_info->LineStyle();
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc
index 1435b43..2bb3a983 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc
@@ -259,6 +259,12 @@
   std::swap(oof_positioned_fragmentainer_descendants_, *descendants);
 }
 
+void NGContainerFragmentBuilder::ClearOutOfFlowFragmentainerDescendants() {
+  if (!HasOutOfFlowFragmentainerDescendants())
+    return;
+  oof_positioned_fragmentainer_descendants_.clear();
+}
+
 void NGContainerFragmentBuilder::
     MoveOutOfFlowDescendantCandidatesToDescendants() {
   DCHECK(oof_positioned_descendants_.IsEmpty());
diff --git a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h
index 823d6fa..8405632 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h
@@ -145,6 +145,8 @@
   void SwapMulticolsWithPendingOOFs(
       MulticolCollection* multicols_with_pending_oofs);
 
+  void ClearOutOfFlowFragmentainerDescendants();
+
   bool HasOutOfFlowPositionedCandidates() const {
     return !oof_positioned_candidates_.IsEmpty();
   }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
index c87efc2..087687c 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
@@ -753,4 +753,30 @@
   return space_builder.ToConstraintSpace();
 }
 
+NGBoxFragmentBuilder CreateContainerBuilderForMulticol(
+    const NGBlockNode& multicol,
+    const NGConstraintSpace& space,
+    const NGFragmentGeometry& fragment_geometry) {
+  const ComputedStyle* style = &multicol.Style();
+  NGBoxFragmentBuilder multicol_container_builder(multicol, style, &space,
+                                                  style->GetWritingDirection());
+  multicol_container_builder.SetIsNewFormattingContext(true);
+  multicol_container_builder.SetInitialFragmentGeometry(fragment_geometry);
+  multicol_container_builder.SetIsBlockFragmentationContextRoot();
+
+  return multicol_container_builder;
+}
+
+NGConstraintSpace CreateConstraintSpaceForMulticol(
+    const NGBlockNode& multicol) {
+  WritingDirectionMode writing_direction_mode =
+      multicol.Style().GetWritingDirection();
+  NGConstraintSpaceBuilder space_builder(
+      writing_direction_mode.GetWritingMode(), writing_direction_mode,
+      /* is_new_fc */ true);
+
+  // TODO(almaher): Do we need to set available size, % res size, etc?
+  return space_builder.ToConstraintSpace();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h
index b85b17a..f653e846 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h
@@ -266,6 +266,13 @@
     bool allow_discard_start_margin,
     bool balance_columns);
 
+// Calculate the container builder and constraint space for a multicol.
+NGBoxFragmentBuilder CreateContainerBuilderForMulticol(
+    const NGBlockNode& multicol,
+    const NGConstraintSpace& space,
+    const NGFragmentGeometry& fragment_geometry);
+NGConstraintSpace CreateConstraintSpaceForMulticol(const NGBlockNode& multicol);
+
 // Return the adjusted child margin to be applied at the end of a fragment.
 // Margins should collapse with the fragmentainer boundary. |bfc_block_offset|
 // is the BFC offset where the margin should be applied (i.e. after the
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
index 8c03202..00c0789 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -643,21 +643,42 @@
 // TODO(almaher): Look into moving this to NGColumnLayoutAlgorithm instead.
 void NGOutOfFlowLayoutPart::LayoutOOFsInMulticol(const NGBlockNode& multicol) {
   Vector<NGLogicalOutOfFlowPositionedNode> oof_nodes_to_layout;
+  Vector<NGLink*> mutable_multicol_children;
+
+  NGConstraintSpace multicol_constraint_space =
+      CreateConstraintSpaceForMulticol(multicol);
+  NGFragmentGeometry fragment_geometry =
+      CalculateInitialFragmentGeometry(multicol_constraint_space, multicol);
+  NGBoxFragmentBuilder multicol_container_builder =
+      CreateContainerBuilderForMulticol(multicol, multicol_constraint_space,
+                                        fragment_geometry);
 
   // Accumulate all of the pending OOF positioned nodes that are stored inside
   // |multicol|.
   for (auto& multicol_fragment : multicol.GetLayoutBox()->PhysicalFragments()) {
     const NGPhysicalBoxFragment* multicol_box_fragment =
         To<NGPhysicalBoxFragment>(&multicol_fragment);
-    if (!multicol_box_fragment
-             ->HasOutOfFlowPositionedFragmentainerDescendants())
-      continue;
 
     WritingDirectionMode writing_direction =
         multicol_box_fragment->Style().GetWritingDirection();
     const WritingModeConverter converter(writing_direction,
                                          multicol_box_fragment->Size());
 
+    // Collect the children of the multicol fragments.
+    for (auto& child :
+         multicol_box_fragment->GetMutableChildrenForOutOfFlow().Children()) {
+      const auto* fragment = To<NGPhysicalContainerFragment>(child.get());
+      LogicalOffset offset =
+          converter.ToLogical(child.Offset(), fragment->Size());
+
+      multicol_container_builder.AddChild(*fragment, offset);
+      mutable_multicol_children.emplace_back(&child);
+    }
+
+    if (!multicol_box_fragment
+             ->HasOutOfFlowPositionedFragmentainerDescendants())
+      continue;
+
     // Convert the OOF fragmentainer descendants to the logical coordinate space
     // and store the resulting nodes inside |oof_nodes_to_layout|.
     for (const auto& descendant :
@@ -688,14 +709,21 @@
   }
   DCHECK(!oof_nodes_to_layout.IsEmpty());
 
-  // TODO(almaher): This lays out the OOF nodes in the outer fragmentation
-  // context. We want to lay these out inside the column children of |multicol|
-  // instead.
-  LayoutFragmentainerDescendants(&oof_nodes_to_layout);
+  // Clear out any OOF fragmentainer descendants that had been re-propagated
+  // when setting up |multicol_container_builder|.
+  // TODO(almaher): Avoid adding the descendants again to begin with.
+  multicol_container_builder.ClearOutOfFlowFragmentainerDescendants();
+
+  // Layout the OOF positioned elements inside the inner multicol.
+  NGOutOfFlowLayoutPart(multicol, multicol_constraint_space,
+                        &multicol_container_builder)
+      .LayoutFragmentainerDescendants(&oof_nodes_to_layout,
+                                      &mutable_multicol_children);
 }
 
 void NGOutOfFlowLayoutPart::LayoutFragmentainerDescendants(
-    Vector<NGLogicalOutOfFlowPositionedNode>* descendants) {
+    Vector<NGLogicalOutOfFlowPositionedNode>* descendants,
+    Vector<NGLink*>* mutable_multicol_children) {
   original_column_block_size_ =
       ShrinkLogicalSize(container_builder_->InitialBorderBoxSize(),
                         container_builder_->BorderScrollbarPadding())
@@ -705,6 +733,8 @@
     for (auto& descendant : *descendants) {
       scoped_refptr<const NGLayoutResult> result =
           LayoutFragmentainerDescendant(descendant);
+      // TODO(almaher): Handle nested OOFs and inner multicols with pending OOFs
+      // in the case of nested fragmentation.
       container_builder_->PropagateOOFPositionedInfo(
           result->PhysicalFragment(), result->OutOfFlowPositionedOffset());
     }
@@ -723,7 +753,7 @@
     wtf_size_t index = descendant_result.key - 1;
     const Vector<scoped_refptr<const NGLayoutResult>>& results =
         descendant_result.value;
-    AddOOFResultsToFragmentainer(results, index);
+    AddOOFResultsToFragmentainer(results, index, mutable_multicol_children);
   }
 }
 
@@ -1143,7 +1173,8 @@
 
 void NGOutOfFlowLayoutPart::AddOOFResultsToFragmentainer(
     const Vector<scoped_refptr<const NGLayoutResult>>& results,
-    wtf_size_t index) {
+    wtf_size_t index,
+    Vector<NGLink*>* mutable_multicol_children) {
   wtf_size_t num_children = container_builder_->Children().size();
   bool is_new_fragment = index >= num_children;
 
@@ -1227,12 +1258,27 @@
     }
     scoped_refptr<const NGLayoutResult> new_result = algorithm.Layout();
     node.AddColumnResult(new_result);
+    // TODO(almaher): Handle "new" columns for nested fragmentation.
     container_builder_->AddChild(new_result->PhysicalFragment(), offset);
   } else {
     scoped_refptr<const NGLayoutResult> new_result = algorithm.Layout();
     node.ReplaceColumnResult(new_result, fragment);
-    container_builder_->ReplaceChild(index, new_result->PhysicalFragment(),
-                                     fragmentainer.offset);
+    const NGPhysicalContainerFragment* new_fragment =
+        &new_result->PhysicalFragment();
+
+    if (mutable_multicol_children) {
+      // We are in a nested fragmentation context. Replace the column entry
+      // directly in the existing multicol fragment.
+      NGLink* link = (*mutable_multicol_children)[index];
+      link->fragment->Release();
+      new (&link->fragment)
+          scoped_refptr<const NGPhysicalFragment>(std::move(new_fragment));
+    } else {
+      // We are not in a nested context, so replace the column entry in the
+      // builder itself.
+      container_builder_->ReplaceChild(index, *new_fragment,
+                                       fragmentainer.offset);
+    }
   }
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
index 357634b..c7fb651 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
@@ -26,6 +26,7 @@
 class NGBoxFragmentBuilder;
 class NGLayoutResult;
 class NGPhysicalContainerFragment;
+struct NGLink;
 struct NGLogicalOutOfFlowPositionedNode;
 
 // Helper class for positioning of out-of-flow blocks.
@@ -104,8 +105,12 @@
 
   void LayoutOOFsInMulticol(const NGBlockNode& multicol);
 
+  // Layout the OOF nodes that are descendants of a fragmentation context root.
+  // |mutable_multicol_children| holds the children of an inner multicol if
+  // we are laying out OOF elements inside a nested fragmentation context.
   void LayoutFragmentainerDescendants(
-      Vector<NGLogicalOutOfFlowPositionedNode>* descendants);
+      Vector<NGLogicalOutOfFlowPositionedNode>* descendants,
+      Vector<NGLink*>* mutable_multicol_children = nullptr);
 
   scoped_refptr<const NGLayoutResult> LayoutFragmentainerDescendant(
       const NGLogicalOutOfFlowPositionedNode&);
@@ -133,7 +138,8 @@
       bool should_use_fixed_block_size);
   void AddOOFResultsToFragmentainer(
       const Vector<scoped_refptr<const NGLayoutResult>>& results,
-      wtf_size_t index);
+      wtf_size_t index,
+      Vector<NGLink*>* mutable_multicol_children = nullptr);
   const NGConstraintSpace& GetFragmentainerConstraintSpace(wtf_size_t index);
   void AddOOFResultToFragmentainerResults(
       const scoped_refptr<const NGLayoutResult> result,
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc
index 2b31d23f..0a06b7d5 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc
@@ -1305,7 +1305,52 @@
 }
 
 // Fragmented OOF element inside a nested multi-column.
-TEST_F(NGOutOfFlowLayoutPartTest, AbsposNestedFragmentation) {
+TEST_F(NGOutOfFlowLayoutPartTest, SimpleAbsposNestedFragmentation) {
+  SetBodyInnerHTML(
+      R"HTML(
+      <style>
+        .multicol {
+          columns:2; column-fill:auto; column-gap:0px;
+        }
+        .rel {
+          position: relative; width:55px; height:80px;
+        }
+        .abs {
+          position:absolute; top:0px; width:5px; height:80px;
+        }
+      </style>
+      <div id="container">
+        <div class="multicol" id="outer" style="height:100px;">
+          <div style="height:40px; width:40px;"></div>
+          <div class="multicol" id="inner">
+            <div class="rel">
+              <div class="abs"></div>
+            </div>
+          </div>
+        </div>
+      </div>
+      )HTML");
+  String dump = DumpFragmentTree(GetElementById("container"));
+
+  String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+  offset:unplaced size:1000x100
+    offset:0,0 size:1000x100
+      offset:0,0 size:500x100
+        offset:0,0 size:40x40
+        offset:0,40 size:500x60
+          offset:0,0 size:250x60
+            offset:0,0 size:55x60
+            offset:0,0 size:5x60
+          offset:250,0 size:250x60
+            offset:0,0 size:55x20
+            offset:0,0 size:5x20
+)DUMP";
+  EXPECT_EQ(expectation, dump);
+}
+
+// Fragmented OOF element inside a nested multi-column.
+// TODO(almaher): Re-enable once the crash is fixed.
+TEST_F(NGOutOfFlowLayoutPartTest, DISABLED_AbsposNestedFragmentation) {
   SetBodyInnerHTML(
       R"HTML(
       <style>
@@ -1394,10 +1439,9 @@
       )HTML");
   String dump = DumpFragmentTree(GetElementById("container"));
 
-  // TODO(almaher): The abspos element should be placed in the inner multicol
-  // rather than the outer multicol. The static offset is also incorrectly
-  // computed due to the fact that the containing block offset is now relative
-  // to the inner multicol rather than the outer.
+  // TODO(almaher): The static position should be 250px down instead of 50px.
+  // It looks like the block size of the first two inner columns are not
+  // taken into account when determining the static position.
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:1000x100
     offset:0,0 size:1000x100
@@ -1406,16 +1450,16 @@
           offset:0,0 size:250x100
             offset:0,0 size:55x100
               offset:0,0 size:25x100
+            offset:0,50 size:5x50
           offset:250,0 size:250x100
             offset:0,0 size:55x100
               offset:0,0 size:25x100
-        offset:0,50 size:5x50
+            offset:0,0 size:5x20
       offset:500,0 size:500x100
         offset:0,0 size:500x100
           offset:0,0 size:250x100
             offset:0,0 size:55x50
               offset:0,0 size:25x50
-        offset:0,0 size:5x20
 )DUMP";
   EXPECT_EQ(expectation, dump);
 }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h
index ddf2b82..921533e 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h
@@ -147,6 +147,29 @@
             oof_positioned_descendants_->size()};
   }
 
+  // This exposes a mutable part of the fragment for |NGOutOfFlowLayoutPart|.
+  class MutableChildrenForOutOfFlow final {
+    STACK_ALLOCATED();
+
+   protected:
+    friend class NGOutOfFlowLayoutPart;
+    base::span<NGLink> Children() const {
+      return base::make_span(buffer_, num_children_);
+    }
+
+   private:
+    friend class NGPhysicalContainerFragment;
+    MutableChildrenForOutOfFlow(const NGLink* buffer, wtf_size_t num_children)
+        : buffer_(const_cast<NGLink*>(buffer)), num_children_(num_children) {}
+
+    NGLink* buffer_;
+    wtf_size_t num_children_;
+  };
+
+  MutableChildrenForOutOfFlow GetMutableChildrenForOutOfFlow() const {
+    return MutableChildrenForOutOfFlow(buffer_, num_children_);
+  }
+
  protected:
   // block_or_line_writing_mode is used for converting the child offsets.
   NGPhysicalContainerFragment(NGContainerFragmentBuilder*,
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc
index aa42ec3..98b84d70 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc
@@ -1122,7 +1122,7 @@
       group_index = 0;
 
     LayoutUnit remaining_deficit = excess_block_size;
-    NGTableTypes::Section* last_section;
+    NGTableTypes::Section* last_section = nullptr;
     for (NGTableTypes::Section& section : *sections) {
       if (group_index == 2 && !is_group_2(section))
         continue;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.cc
index 084a0a1a..b1a37a9a 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.cc
@@ -61,19 +61,18 @@
   if (!old_style)
     return;
   auto& element = To<SVGFilterPrimitiveStandardAttributes>(*GetNode());
-  const SVGComputedStyle& new_style = StyleRef().SvgStyle();
+  const ComputedStyle& style = StyleRef();
   if (IsA<SVGFEFloodElement>(element) || IsA<SVGFEDropShadowElement>(element)) {
     CheckForColorChange(element, svg_names::kFloodColorAttr, diff,
-                        old_style->SvgStyle().FloodColor(),
-                        new_style.FloodColor());
-    if (new_style.FloodOpacity() != old_style->SvgStyle().FloodOpacity())
+                        old_style->FloodColor(), style.FloodColor());
+    if (style.FloodOpacity() != old_style->FloodOpacity())
       element.PrimitiveAttributeChanged(svg_names::kFloodOpacityAttr);
   } else if (IsA<SVGFEDiffuseLightingElement>(element) ||
              IsA<SVGFESpecularLightingElement>(element)) {
     CheckForColorChange(element, svg_names::kLightingColorAttr, diff,
-                        old_style->SvgStyle().LightingColor(),
-                        new_style.LightingColor());
+                        old_style->LightingColor(), style.LightingColor());
   }
+  const SVGComputedStyle& new_style = style.SvgStyle();
   if (new_style.ColorInterpolationFilters() !=
       old_style->SvgStyle().ColorInterpolationFilters()) {
     element.PrimitiveAttributeChanged(
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc
index 04839616..7be59302 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc
@@ -104,7 +104,7 @@
       resources.push_back(reference_operation->Resource());
   }
   const SVGComputedStyle& svg_style = style.SvgStyle();
-  if (auto* masker = svg_style.MaskerResource())
+  if (auto* masker = style.MaskerResource())
     resources.push_back(masker->Resource());
   if (auto* marker = svg_style.MarkerStartResource())
     resources.push_back(marker->Resource());
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_shape.h b/third_party/blink/renderer/core/layout/svg/layout_svg_shape.h
index 4ee4c921..57839b1f6 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_shape.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_shape.h
@@ -95,7 +95,7 @@
 
   bool HasNonScalingStroke() const {
     NOT_DESTROYED();
-    return StyleRef().SvgStyle().VectorEffect() == VE_NON_SCALING_STROKE;
+    return StyleRef().VectorEffect() == VE_NON_SCALING_STROKE;
   }
   const Path& NonScalingStrokePath() const {
     NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc
index a758ecb..6970a9e3 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc
@@ -167,7 +167,7 @@
 }
 
 void LayoutSVGText::UpdateTransformAffectsVectorEffect() {
-  if (StyleRef().SvgStyle().VectorEffect() == VE_NON_SCALING_STROKE) {
+  if (StyleRef().VectorEffect() == VE_NON_SCALING_STROKE) {
     SetTransformAffectsVectorEffect(true);
     return;
   }
@@ -176,8 +176,7 @@
   for (LayoutObject* descendant = FirstChild(); descendant;
        descendant = descendant->NextInPreOrder(this)) {
     if (descendant->IsSVGInline() &&
-        descendant->StyleRef().SvgStyle().VectorEffect() ==
-            VE_NON_SCALING_STROKE) {
+        descendant->StyleRef().VectorEffect() == VE_NON_SCALING_STROKE) {
       SetTransformAffectsVectorEffect(true);
       break;
     }
diff --git a/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc b/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
index 2e776ee5..a91cc9fc5 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
@@ -269,9 +269,8 @@
   if (LayoutSVGResourceClipper* clipper =
           GetSVGResourceAsType(*client, style.ClipPath()))
     visual_rect.Intersect(clipper->ResourceBoundingBox(object_bounding_box));
-  const SVGComputedStyle& svg_style = style.SvgStyle();
   if (auto* masker = GetSVGResourceAsType<LayoutSVGResourceMasker>(
-          *client, svg_style.MaskerResource()))
+          *client, style.MaskerResource()))
     visual_rect.Intersect(masker->ResourceBoundingBox(object_bounding_box, 1));
 }
 
@@ -370,7 +369,7 @@
 bool SVGLayoutSupport::WillIsolateBlendingDescendantsForStyle(
     const ComputedStyle& style) {
   return style.HasGroupingProperty(style.BoxReflect()) ||
-         style.SvgStyle().HasMasker();
+         style.MaskerResource();
 }
 
 bool SVGLayoutSupport::WillIsolateBlendingDescendantsForObject(
@@ -383,7 +382,7 @@
 }
 
 bool SVGLayoutSupport::IsIsolationRequired(const LayoutObject* object) {
-  if (object->StyleRef().SvgStyle().HasMasker())
+  if (object->StyleRef().MaskerResource())
     return true;
   return WillIsolateBlendingDescendantsForObject(object) &&
          object->HasNonIsolatedBlendingDescendants();
diff --git a/third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.cc b/third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.cc
index 0168039..26e0bf8 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.cc
@@ -745,10 +745,10 @@
   if (!client)
     return;
   if (auto* masker = GetSVGResourceAsType<LayoutSVGResourceMasker>(
-          *client, style.SvgStyle().MaskerResource())) {
+          *client, style.MaskerResource())) {
     WriteSVGResourceReferencePrefix(ts, "masker", masker,
-                                    style.SvgStyle().MaskerResource()->Url(),
-                                    tree_scope, indent);
+                                    style.MaskerResource()->Url(), tree_scope,
+                                    indent);
     ts << " " << masker->ResourceBoundingBox(reference_box, 1) << "\n";
   }
   if (const ClipPathOperation* clip_path = style.ClipPath()) {
diff --git a/third_party/blink/renderer/core/layout/svg/svg_resources.cc b/third_party/blink/renderer/core/layout/svg/svg_resources.cc
index 984e7e3e..feb1e540 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_resources.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_resources.cc
@@ -82,7 +82,7 @@
     layout_object->SetNeedsPaintPropertyUpdate();
     client.MarkFilterDataDirty();
   }
-  if (StyleSVGResource* masker_resource = style.SvgStyle().MaskerResource())
+  if (StyleSVGResource* masker_resource = style.MaskerResource())
     masker_resource->AddClient(element.EnsureSVGResourceClient());
   if (had_client)
     ClearClipPathFilterMask(element, old_style);
@@ -102,7 +102,7 @@
     style->Filter().RemoveClient(*client);
     client->InvalidateFilterData();
   }
-  if (StyleSVGResource* masker_resource = style->SvgStyle().MaskerResource())
+  if (StyleSVGResource* masker_resource = style->MaskerResource())
     masker_resource->RemoveClient(*client);
 }
 
@@ -269,7 +269,7 @@
     layout_object->InvalidateClipPathCache();
   }
 
-  if (ContainsResource(svg_style.MaskerResource(), resource)) {
+  if (ContainsResource(style.MaskerResource(), resource)) {
     // TODO(fs): "Downgrade" to non-subtree?
     layout_object->SetSubtreeShouldDoFullPaintInvalidation();
     layout_object->SetNeedsPaintPropertyUpdate();
@@ -385,7 +385,7 @@
     object_.SetShouldDoFullPaintInvalidation();
     object_.InvalidateClipPathCache();
   }
-  if (style.SvgStyle().HasMasker()) {
+  if (style.MaskerResource()) {
     object_.SetShouldDoFullPaintInvalidation();
     object_.SetNeedsPaintPropertyUpdate();
   }
diff --git a/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine_baseline.cc b/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine_baseline.cc
index c7824b10..edf089d 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine_baseline.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine_baseline.cc
@@ -118,8 +118,7 @@
   LineLayoutItem text_line_layout_parent = text_line_layout.Parent();
   DCHECK(text_line_layout_parent);
 
-  EAlignmentBaseline baseline =
-      text_line_layout.StyleRef().SvgStyle().AlignmentBaseline();
+  EAlignmentBaseline baseline = text_line_layout.StyleRef().AlignmentBaseline();
   if (baseline == AB_AUTO || baseline == AB_BASELINE) {
     baseline = DominantBaselineToAlignmentBaseline(is_vertical_text,
                                                    text_line_layout_parent);
diff --git a/third_party/blink/renderer/core/loader/document_loader_test.cc b/third_party/blink/renderer/core/loader/document_loader_test.cc
index 0cdc9a8..17ad6ed 100644
--- a/third_party/blink/renderer/core/loader/document_loader_test.cc
+++ b/third_party/blink/renderer/core/loader/document_loader_test.cc
@@ -10,8 +10,6 @@
 #include "base/test/scoped_feature_list.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-shared.h"
-#include "third_party/blink/public/mojom/feature_policy/policy_disposition.mojom-blink.h"
 #include "third_party/blink/public/mojom/frame/frame_owner_element_type.mojom-blink.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_url_loader_client.h"
@@ -262,452 +260,6 @@
   EXPECT_TRUE(child_window->IsFeatureEnabled(
       blink::mojom::blink::FeaturePolicyFeature::kPayment));
 }
-// When runtime feature DocumentPolicy is not enabled, specifying
-// Document-Policy, Require-Document-Policy and policy attribute
-// should have no effect, i.e.
-// document load should not be blocked even if the required policy and incoming
-// policy are incompatible and calling
-// |Document::IsFeatureEnabled(DocumentPolicyFeature...)| should always return
-// true.
-// TODO(crbug.com/1168960): Convert the test into a browsertest so that
-// the initialization of static |GetAvailableDocumentPolicyFeatures| set
-// is not affecting subsequent tests.
-TEST_F(DocumentLoaderSimTest, DISABLED_DocumentPolicyNoEffectWhenFlagNotSet) {
-  blink::ScopedDocumentPolicyForTest sdp(false);
-  blink::ScopedDocumentPolicyNegotiationForTest sdpn(false);
-
-  SimRequest::Params main_params;
-  main_params.response_http_headers = {
-      {"Require-Document-Policy", "lossless-images-max-bpp=1.0"}};
-
-  SimRequest::Params iframe_params;
-  iframe_params.response_http_headers = {
-      {"Document-Policy", "lossless-images-max-bpp=1.1"}};
-
-  SimRequest main_resource("https://example.com", "text/html", main_params);
-  SimRequest iframe_resource("https://example.com/foo.html", "text/html",
-                             iframe_params);
-
-  LoadURL("https://example.com");
-  main_resource.Complete(R"(
-    <iframe
-      src="https://example.com/foo.html"
-      policy="lossless-images-max-bpp=1.0">
-    </iframe>
-  )");
-
-  iframe_resource.Finish();
-  auto* child_frame = To<WebLocalFrameImpl>(MainFrame().FirstChild());
-  auto* child_window = child_frame->GetFrame()->DomWindow();
-  auto& console_messages = static_cast<frame_test_helpers::TestWebFrameClient*>(
-                               child_frame->Client())
-                               ->ConsoleMessages();
-
-  // Should not receive a console error message caused by document policy
-  // violation blocking document load.
-  EXPECT_TRUE(console_messages.IsEmpty());
-
-  EXPECT_EQ(child_window->Url(), KURL("https://example.com/foo.html"));
-
-  EXPECT_FALSE(child_window->document()->IsUseCounted(
-      mojom::WebFeature::kDocumentPolicyCausedPageUnload));
-
-  // lossless-images-max-bpp should be set to inf in main document, i.e. allow
-  // all values.
-  EXPECT_TRUE(Window().IsFeatureEnabled(
-      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
-      PolicyValue::CreateDecDouble(2.0)));
-  EXPECT_TRUE(Window().IsFeatureEnabled(
-      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
-      PolicyValue::CreateDecDouble(1.0)));
-
-  // lossless-images-max-bpp should be set to inf in child document, i.e. allow
-  // all values.
-  EXPECT_TRUE(child_window->IsFeatureEnabled(
-      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
-      PolicyValue::CreateDecDouble(2.0)));
-  EXPECT_TRUE(child_window->IsFeatureEnabled(
-      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
-      PolicyValue::CreateDecDouble(1.0)));
-}
-
-// When runtime feature DocumentPolicyNegotiation is not enabled, specifying
-// Require-Document-Policy HTTP header and policy attribute on iframe should
-// have no effect, i.e. document load should not be blocked even if the required
-// policy and incoming policy are incompatible. Document-Policy header should
-// function as normal.
-TEST_F(DocumentLoaderSimTest, DocumentPolicyNegotiationNoEffectWhenFlagNotSet) {
-  blink::ScopedDocumentPolicyForTest sdp(true);
-  blink::ScopedDocumentPolicyNegotiationForTest sdpn(false);
-
-  SimRequest::Params main_params;
-  main_params.response_http_headers = {
-      {"Require-Document-Policy", "lossless-images-max-bpp=1.0"}};
-
-  SimRequest::Params iframe_params;
-  iframe_params.response_http_headers = {
-      {"Document-Policy", "lossless-images-max-bpp=1.1"}};
-
-  SimRequest main_resource("https://example.com", "text/html", main_params);
-  SimRequest iframe_resource("https://example.com/foo.html", "text/html",
-                             iframe_params);
-
-  LoadURL("https://example.com");
-  main_resource.Complete(R"(
-    <iframe
-      src="https://example.com/foo.html"
-      policy="lossless-images-max-bpp=1.0">
-    </iframe>
-  )");
-
-  iframe_resource.Finish();
-  auto* child_frame = To<WebLocalFrameImpl>(MainFrame().FirstChild());
-  auto* child_window = child_frame->GetFrame()->DomWindow();
-  auto& console_messages = static_cast<frame_test_helpers::TestWebFrameClient*>(
-                               child_frame->Client())
-                               ->ConsoleMessages();
-
-  // Should not receive a console error message caused by document policy
-  // violation blocking document load.
-  EXPECT_TRUE(console_messages.IsEmpty());
-
-  EXPECT_EQ(child_window->Url(), KURL("https://example.com/foo.html"));
-
-  EXPECT_FALSE(child_window->document()->IsUseCounted(
-      mojom::WebFeature::kDocumentPolicyCausedPageUnload));
-
-  // lossless-images-max-bpp should be set to inf in main document, i.e. allow
-  // all values.
-  EXPECT_TRUE(Window().IsFeatureEnabled(
-      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
-      PolicyValue::CreateDecDouble(2.0)));
-  EXPECT_TRUE(Window().IsFeatureEnabled(
-      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
-      PolicyValue::CreateDecDouble(1.0)));
-
-  // lossless-images-max-bpp should be set to 1.1 in child document.
-  EXPECT_FALSE(child_window->IsFeatureEnabled(
-      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
-      PolicyValue::CreateDecDouble(2.0)));
-  EXPECT_TRUE(child_window->IsFeatureEnabled(
-      mojom::blink::DocumentPolicyFeature::kLosslessImagesMaxBpp,
-      PolicyValue::CreateDecDouble(1.0)));
-}
-
-TEST_F(DocumentLoaderSimTest, ReportDocumentPolicyHeaderParsingError) {
-  blink::ScopedDocumentPolicyForTest sdp(true);
-  SimRequest::Params params;
-  params.response_http_headers = {{"Document-Policy", "bad-feature-name"}};
-  SimRequest main_resource("https://example.com", "text/html", params);
-  LoadURL("https://example.com");
-  main_resource.Finish();
-
-  EXPECT_EQ(ConsoleMessages().size(), 1u);
-  EXPECT_TRUE(
-      ConsoleMessages().front().StartsWith("Document-Policy HTTP header:"));
-}
-
-TEST_F(DocumentLoaderSimTest, ReportRequireDocumentPolicyHeaderParsingError) {
-  blink::ScopedDocumentPolicyForTest sdp(true);
-  SimRequest::Params params;
-  params.response_http_headers = {
-      {"Require-Document-Policy", "bad-feature-name"}};
-  SimRequest main_resource("https://example.com", "text/html", params);
-  LoadURL("https://example.com");
-  main_resource.Finish();
-
-  EXPECT_EQ(ConsoleMessages().size(), 1u);
-  EXPECT_TRUE(ConsoleMessages().front().StartsWith(
-      "Require-Document-Policy HTTP header:"));
-}
-
-TEST_F(DocumentLoaderSimTest, ReportErrorWhenDocumentPolicyIncompatible) {
-  blink::ScopedDocumentPolicyForTest sdp(true);
-  blink::ScopedDocumentPolicyNegotiationForTest sdpn(true);
-  SimRequest::Params params;
-  params.response_http_headers = {
-      {"Document-Policy", "lossless-images-max-bpp=1.1"}};
-
-  SimRequest main_resource("https://example.com", "text/html");
-  SimRequest iframe_resource("https://example.com/foo.html", "text/html",
-                             params);
-
-  LoadURL("https://example.com");
-  main_resource.Complete(R"(
-    <iframe
-      src="https://example.com/foo.html"
-      policy="lossless-images-max-bpp=1.0">
-    </iframe>
-  )");
-
-  // When blocked by document policy, the document should be filled in with an
-  // empty response, with Finish called on |navigation_body_loader| already.
-  // If Finish was not called on the loader, because the document was not
-  // blocked, this test will fail by crashing here.
-  iframe_resource.Finish(true /* body_loader_finished */);
-
-  auto* child_frame = To<WebLocalFrameImpl>(MainFrame().FirstChild());
-  auto* child_document = child_frame->GetFrame()->GetDocument();
-
-  // Should console log a error message.
-  auto& console_messages = static_cast<frame_test_helpers::TestWebFrameClient*>(
-                               child_frame->Client())
-                               ->ConsoleMessages();
-
-  ASSERT_EQ(console_messages.size(), 1u);
-  EXPECT_TRUE(console_messages.front().Contains("document policy"));
-
-  // Should replace the document's origin with an opaque origin.
-  EXPECT_EQ(child_document->Url(), SecurityOrigin::UrlWithUniqueOpaqueOrigin());
-
-  EXPECT_TRUE(child_document->IsUseCounted(
-      mojom::WebFeature::kDocumentPolicyCausedPageUnload));
-}
-
-// HTTP header Require-Document-Policy should only take effect on subtree of
-// current document, but not on current document.
-TEST_F(DocumentLoaderSimTest,
-       RequireDocumentPolicyHeaderShouldNotAffectCurrentDocument) {
-  blink::ScopedDocumentPolicyForTest sdp(true);
-  blink::ScopedDocumentPolicyNegotiationForTest sdpn(true);
-  SimRequest::Params params;
-  params.response_http_headers = {
-      {"Require-Document-Policy", "lossless-images-max-bpp=1.0"},
-      {"Document-Policy", "lossless-images-max-bpp=1.1"}};
-
-  SimRequest main_resource("https://example.com", "text/html", params);
-  LoadURL("https://example.com");
-  // If document is blocked by document policy because of incompatible document
-  // policy, this test will fail by crashing here.
-  main_resource.Finish();
-}
-
-TEST_F(DocumentLoaderSimTest, DocumentPolicyHeaderHistogramTest) {
-  blink::ScopedDocumentPolicyForTest sdp(true);
-  HistogramTester histogram_tester;
-
-  SimRequest::Params params;
-  params.response_http_headers = {
-      {"Document-Policy",
-       "font-display-late-swap, lossless-images-max-bpp=1.1"}};
-
-  SimRequest main_resource("https://example.com", "text/html", params);
-  LoadURL("https://example.com");
-  main_resource.Finish();
-
-  histogram_tester.ExpectTotalCount("Blink.UseCounter.DocumentPolicy.Header",
-                                    2);
-  histogram_tester.ExpectBucketCount("Blink.UseCounter.DocumentPolicy.Header",
-                                     1 /* kFontDisplay */, 1);
-  histogram_tester.ExpectBucketCount("Blink.UseCounter.DocumentPolicy.Header",
-                                     2 /* kUnoptimizedLosslessImages */, 1);
-}
-
-TEST_F(DocumentLoaderSimTest, DocumentPolicyPolicyAttributeHistogramTest) {
-  blink::ScopedDocumentPolicyForTest sdp(true);
-  blink::ScopedDocumentPolicyNegotiationForTest sdpn(true);
-  HistogramTester histogram_tester;
-
-  SimRequest main_resource("https://example.com", "text/html");
-  LoadURL("https://example.com");
-
-  // Same feature should only be reported once in a document despite its
-  // occurrence.
-  main_resource.Complete(R"(
-    <iframe policy="font-display-late-swap"></iframe>
-    <iframe policy="font-display-late-swap=?0"></iframe>
-    <iframe
-      policy="font-display-late-swap, lossless-images-max-bpp=1.1">
-    </iframe>
-  )");
-
-  histogram_tester.ExpectTotalCount(
-      "Blink.UseCounter.DocumentPolicy.PolicyAttribute", 2);
-  histogram_tester.ExpectBucketCount(
-      "Blink.UseCounter.DocumentPolicy.PolicyAttribute", 1 /* kFontDisplay */,
-      1);
-  histogram_tester.ExpectBucketCount(
-      "Blink.UseCounter.DocumentPolicy.PolicyAttribute",
-      2 /* kUnoptimizedLosslessImages */, 1);
-}
-
-TEST_F(DocumentLoaderSimTest, DocumentPolicyEnforcedReportHistogramTest) {
-  blink::ScopedDocumentPolicyForTest sdp(true);
-  HistogramTester histogram_tester;
-
-  SimRequest main_resource("https://example.com", "text/html");
-  LoadURL("https://example.com");
-  main_resource.Finish();
-
-  Window().ReportDocumentPolicyViolation(
-      mojom::blink::DocumentPolicyFeature::kFontDisplay,
-      mojom::blink::PolicyDisposition::kEnforce,
-      "first font display violation");
-
-  histogram_tester.ExpectTotalCount("Blink.UseCounter.DocumentPolicy.Enforced",
-                                    1);
-  histogram_tester.ExpectBucketCount("Blink.UseCounter.DocumentPolicy.Enforced",
-                                     1 /* kFontDisplay */, 1);
-
-  // Multiple reports should be recorded multiple times.
-  Window().ReportDocumentPolicyViolation(
-      mojom::blink::DocumentPolicyFeature::kFontDisplay,
-      mojom::blink::PolicyDisposition::kEnforce,
-      "second font display violation");
-
-  histogram_tester.ExpectTotalCount("Blink.UseCounter.DocumentPolicy.Enforced",
-                                    2);
-  histogram_tester.ExpectBucketCount("Blink.UseCounter.DocumentPolicy.Enforced",
-                                     1 /* kFontDisplay */, 2);
-}
-
-TEST_F(DocumentLoaderSimTest, DocumentPolicyReportOnlyReportHistogramTest) {
-  blink::ScopedDocumentPolicyForTest sdp(true);
-  HistogramTester histogram_tester;
-
-  SimRequest::Params params;
-  params.response_http_headers = {
-      {"Document-Policy-Report-Only", "font-display-late-swap"}};
-  SimRequest main_resource("https://example.com", "text/html", params);
-
-  LoadURL("https://example.com");
-  main_resource.Finish();
-
-  Window().ReportDocumentPolicyViolation(
-      mojom::blink::DocumentPolicyFeature::kFontDisplay,
-      mojom::blink::PolicyDisposition::kReport, "first font display violation");
-
-  histogram_tester.ExpectTotalCount(
-      "Blink.UseCounter.DocumentPolicy.ReportOnly", 1);
-  histogram_tester.ExpectBucketCount(
-      "Blink.UseCounter.DocumentPolicy.ReportOnly", 1 /* kFontDisplay */, 1);
-
-  // Multiple reports should be recorded multiple times.
-  Window().ReportDocumentPolicyViolation(
-      mojom::blink::DocumentPolicyFeature::kFontDisplay,
-      mojom::blink::PolicyDisposition::kReport,
-      "second font display violation");
-
-  histogram_tester.ExpectTotalCount(
-      "Blink.UseCounter.DocumentPolicy.ReportOnly", 2);
-  histogram_tester.ExpectBucketCount(
-      "Blink.UseCounter.DocumentPolicy.ReportOnly", 1 /* kFontDisplay */, 2);
-}
-
-class DocumentPolicyHeaderUseCounterTest
-    : public DocumentLoaderSimTest,
-      public testing::WithParamInterface<std::tuple<bool, bool, bool>> {};
-
-TEST_P(DocumentPolicyHeaderUseCounterTest, ShouldObserveUseCounterUpdate) {
-  blink::ScopedDocumentPolicyForTest sdp(true);
-  blink::ScopedDocumentPolicyNegotiationForTest sdpn(true);
-
-  bool has_document_policy_header, has_report_only_header, has_require_header;
-  std::tie(has_document_policy_header, has_report_only_header,
-           has_require_header) = GetParam();
-
-  SimRequest::Params params;
-  if (has_document_policy_header) {
-    params.response_http_headers.insert("Document-Policy",
-                                        "lossless-images-max-bpp=1.0");
-  }
-  if (has_report_only_header) {
-    params.response_http_headers.insert("Document-Policy-Report-Only",
-                                        "lossless-images-max-bpp=1.0");
-  }
-  if (has_require_header) {
-    params.response_http_headers.insert("Require-Document-Policy",
-                                        "lossless-images-max-bpp=1.0");
-  }
-  SimRequest main_resource("https://example.com", "text/html", params);
-  LoadURL("https://example.com");
-  main_resource.Complete();
-
-  EXPECT_EQ(
-      GetDocument().IsUseCounted(mojom::WebFeature::kDocumentPolicyHeader),
-      has_document_policy_header);
-  EXPECT_EQ(GetDocument().IsUseCounted(
-                mojom::WebFeature::kDocumentPolicyReportOnlyHeader),
-            has_report_only_header);
-  EXPECT_EQ(GetDocument().IsUseCounted(
-                mojom::WebFeature::kRequireDocumentPolicyHeader),
-            has_require_header);
-}
-
-INSTANTIATE_TEST_SUITE_P(DocumentPolicyHeaderValues,
-                         DocumentPolicyHeaderUseCounterTest,
-                         ::testing::Combine(::testing::Bool(),
-                                            ::testing::Bool(),
-                                            ::testing::Bool()));
-
-TEST_F(DocumentLoaderSimTest,
-       DocumentPolicyIframePolicyAttributeUseCounterTest) {
-  blink::ScopedDocumentPolicyForTest sdp(true);
-  blink::ScopedDocumentPolicyNegotiationForTest sdpn(true);
-  SimRequest main_resource("https://example.com", "text/html");
-  SimRequest::Params iframe_params;
-  iframe_params.response_http_headers = {
-      {"Document-Policy", "lossless-images-max-bpp=1.0"}};
-  SimRequest iframe_resource("https://example.com/foo.html", "text/html",
-                             iframe_params);
-  LoadURL("https://example.com");
-  main_resource.Complete(R"(
-    <iframe
-      src="https://example.com/foo.html"
-      policy="lossless-images-max-bpp=1.0"
-    ></iframe>
-  )");
-  iframe_resource.Finish();
-
-  EXPECT_TRUE(GetDocument().IsUseCounted(
-      mojom::WebFeature::kDocumentPolicyIframePolicyAttribute));
-  EXPECT_FALSE(
-      GetDocument().IsUseCounted(mojom::WebFeature::kRequiredDocumentPolicy));
-
-  auto* child_frame = To<WebLocalFrameImpl>(MainFrame().FirstChild());
-  auto* child_document = child_frame->GetFrame()->GetDocument();
-
-  EXPECT_FALSE(child_document->IsUseCounted(
-      mojom::WebFeature::kDocumentPolicyIframePolicyAttribute));
-  EXPECT_TRUE(
-      child_document->IsUseCounted(mojom::WebFeature::kRequiredDocumentPolicy));
-}
-
-TEST_F(DocumentLoaderSimTest, RequiredDocumentPolicyUseCounterTest) {
-  blink::ScopedDocumentPolicyForTest sdp(true);
-  blink::ScopedDocumentPolicyNegotiationForTest sdpn(true);
-
-  SimRequest::Params main_frame_params;
-  main_frame_params.response_http_headers = {
-      {"Require-Document-Policy", "lossless-images-max-bpp=1.0"}};
-  SimRequest main_resource("https://example.com", "text/html",
-                           main_frame_params);
-
-  SimRequest::Params iframe_params;
-  iframe_params.response_http_headers = {
-      {"Document-Policy", "lossless-images-max-bpp=1.0"}};
-  SimRequest iframe_resource("https://example.com/foo.html", "text/html",
-                             iframe_params);
-
-  LoadURL("https://example.com");
-  main_resource.Complete(R"(
-    <iframe src="https://example.com/foo.html"></iframe>
-  )");
-  iframe_resource.Finish();
-
-  EXPECT_FALSE(GetDocument().IsUseCounted(
-      mojom::WebFeature::kDocumentPolicyIframePolicyAttribute));
-  EXPECT_FALSE(
-      GetDocument().IsUseCounted(mojom::WebFeature::kRequiredDocumentPolicy));
-
-  auto* child_frame = To<WebLocalFrameImpl>(MainFrame().FirstChild());
-  auto* child_document = child_frame->GetFrame()->GetDocument();
-
-  EXPECT_FALSE(child_document->IsUseCounted(
-      mojom::WebFeature::kDocumentPolicyIframePolicyAttribute));
-  EXPECT_TRUE(
-      child_document->IsUseCounted(mojom::WebFeature::kRequiredDocumentPolicy));
-}
 
 TEST_F(DocumentLoaderTest, CommitsDeferredOnSameOriginNavigation) {
   const KURL& requestor_url =
diff --git a/third_party/blink/renderer/core/paint/css_mask_painter.cc b/third_party/blink/renderer/core/paint/css_mask_painter.cc
index eb0af92..3cf51b9 100644
--- a/third_party/blink/renderer/core/paint/css_mask_painter.cc
+++ b/third_party/blink/renderer/core/paint/css_mask_painter.cc
@@ -21,7 +21,7 @@
   if (object.IsSVG()) {
     if (SVGResourceClient* client = SVGResources::GetClient(object)) {
       auto* masker = GetSVGResourceAsType<LayoutSVGResourceMasker>(
-          *client, style.SvgStyle().MaskerResource());
+          *client, style.MaskerResource());
       if (masker) {
         const FloatRect reference_box =
             SVGResources::ReferenceBoxForEffects(object);
@@ -65,10 +65,10 @@
   if (!client)
     return kColorFilterNone;
   auto* masker = GetSVGResourceAsType<LayoutSVGResourceMasker>(
-      *client, object.StyleRef().SvgStyle().MaskerResource());
+      *client, object.StyleRef().MaskerResource());
   if (!masker)
     return kColorFilterNone;
-  return masker->StyleRef().SvgStyle().MaskType() == MT_LUMINANCE
+  return masker->StyleRef().MaskType() == MT_LUMINANCE
              ? kColorFilterLuminanceToAlpha
              : kColorFilterNone;
 }
diff --git a/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc b/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc
index 44b9852..67587b83 100644
--- a/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc
+++ b/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc
@@ -75,6 +75,18 @@
   return base::nullopt;
 }
 
+bool ShouldTile(const NinePieceImageGrid::NinePieceDrawInfo& draw_info) {
+  // Corner pieces shouldn't be tiled.
+  if (draw_info.is_corner_piece)
+    return false;
+  // If we're supposed to stretch in both dimensions, we can skip tiling
+  // calculations.
+  if (draw_info.tile_rule.horizontal == kStretchImageRule &&
+      draw_info.tile_rule.vertical == kStretchImageRule)
+    return false;
+  return true;
+}
+
 void PaintPieces(GraphicsContext& context,
                  const PhysicalRect& border_image_rect,
                  const ComputedStyle& style,
@@ -105,49 +117,42 @@
   for (NinePiece piece = kMinPiece; piece < kMaxPiece; ++piece) {
     NinePieceImageGrid::NinePieceDrawInfo draw_info =
         grid.GetNinePieceDrawInfo(piece);
+    if (!draw_info.is_drawable)
+      continue;
 
-    if (draw_info.is_drawable) {
-      if (draw_info.is_corner_piece) {
-        // Since there is no way for the developer to specify decode behavior,
-        // use kSync by default.
-        context.DrawImage(image, Image::kSyncDecode, draw_info.destination,
-                          &draw_info.source, style.HasFilterInducingProperty());
-      } else if (draw_info.tile_rule.horizontal == kStretchImageRule &&
-                 draw_info.tile_rule.vertical == kStretchImageRule) {
-        // Just do a scale.
-        // Since there is no way for the developer to specify decode behavior,
-        // use kSync by default.
-        context.DrawImage(image, Image::kSyncDecode, draw_info.destination,
-                          &draw_info.source, style.HasFilterInducingProperty());
-      } else {
-        // TODO(cavalcantii): see crbug.com/662513.
-        base::Optional<TileParameters> h_tile = ComputeTileParameters(
-            draw_info.tile_rule.horizontal, draw_info.destination.X(),
-            draw_info.destination.Width(), draw_info.source.X(),
-            draw_info.source.Width(), draw_info.tile_scale.Width());
-        base::Optional<TileParameters> v_tile = ComputeTileParameters(
-            draw_info.tile_rule.vertical, draw_info.destination.Y(),
-            draw_info.destination.Height(), draw_info.source.Y(),
-            draw_info.source.Height(), draw_info.tile_scale.Height());
-        if (!h_tile || !v_tile)
-          continue;
-
-        FloatSize tile_scale_factor(h_tile->scale_factor, v_tile->scale_factor);
-        FloatPoint tile_phase(draw_info.destination.X() - h_tile->phase,
-                              draw_info.destination.Y() - v_tile->phase);
-        FloatSize tile_spacing(h_tile->spacing, v_tile->spacing);
-
-        // TODO(cavalcantii): see crbug.com/662507.
-        base::Optional<ScopedInterpolationQuality>
-            interpolation_quality_override;
-        if (draw_info.tile_rule.horizontal == kRoundImageRule ||
-            draw_info.tile_rule.vertical == kRoundImageRule)
-          interpolation_quality_override.emplace(context, kInterpolationMedium);
-
-        context.DrawImageTiled(image, draw_info.destination, draw_info.source,
-                               tile_scale_factor, tile_phase, tile_spacing);
-      }
+    if (!ShouldTile(draw_info)) {
+      // Since there is no way for the developer to specify decode behavior,
+      // use kSync by default.
+      context.DrawImage(image, Image::kSyncDecode, draw_info.destination,
+                        &draw_info.source, style.HasFilterInducingProperty());
+      continue;
     }
+
+    // TODO(cavalcantii): see crbug.com/662513.
+    base::Optional<TileParameters> h_tile = ComputeTileParameters(
+        draw_info.tile_rule.horizontal, draw_info.destination.X(),
+        draw_info.destination.Width(), draw_info.source.X(),
+        draw_info.source.Width(), draw_info.tile_scale.Width());
+    base::Optional<TileParameters> v_tile = ComputeTileParameters(
+        draw_info.tile_rule.vertical, draw_info.destination.Y(),
+        draw_info.destination.Height(), draw_info.source.Y(),
+        draw_info.source.Height(), draw_info.tile_scale.Height());
+    if (!h_tile || !v_tile)
+      continue;
+
+    FloatSize tile_scale_factor(h_tile->scale_factor, v_tile->scale_factor);
+    FloatPoint tile_phase(draw_info.destination.X() - h_tile->phase,
+                          draw_info.destination.Y() - v_tile->phase);
+    FloatSize tile_spacing(h_tile->spacing, v_tile->spacing);
+
+    // TODO(cavalcantii): see crbug.com/662507.
+    base::Optional<ScopedInterpolationQuality> interpolation_quality_override;
+    if (draw_info.tile_rule.horizontal == kRoundImageRule ||
+        draw_info.tile_rule.vertical == kRoundImageRule)
+      interpolation_quality_override.emplace(context, kInterpolationMedium);
+
+    context.DrawImageTiled(image, draw_info.destination, draw_info.source,
+                           tile_scale_factor, tile_phase, tile_spacing);
   }
 }
 
diff --git a/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc b/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc
index 6f48ca6..171b634 100644
--- a/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc
+++ b/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc
@@ -109,7 +109,7 @@
   if (!client)
     return;
   if (GetSVGResourceAsType<LayoutSVGResourceMasker>(
-          *client, object_.StyleRef().SvgStyle().MaskerResource()))
+          *client, object_.StyleRef().MaskerResource()))
     should_paint_mask_ = true;
 }
 
diff --git a/third_party/blink/renderer/core/paint/svg_inline_text_box_painter.cc b/third_party/blink/renderer/core/paint/svg_inline_text_box_painter.cc
index f79b5d2..cc25334e 100644
--- a/third_party/blink/renderer/core/paint/svg_inline_text_box_painter.cc
+++ b/third_party/blink/renderer/core/paint/svg_inline_text_box_painter.cc
@@ -366,7 +366,7 @@
             break;
           stroke_flags.setAntiAlias(true);
           float stroke_scale_factor =
-              svg_decoration_style.VectorEffect() == VE_NON_SCALING_STROKE
+              decoration_style.VectorEffect() == VE_NON_SCALING_STROKE
                   ? 1 / scaling_factor
                   : 1;
           StrokeData stroke_data;
@@ -429,9 +429,7 @@
   if (resource_mode == kApplyToStrokeMode) {
     // The stroke geometry needs be generated based on the scaled font.
     float stroke_scale_factor =
-        style.SvgStyle().VectorEffect() != VE_NON_SCALING_STROKE
-            ? scaling_factor
-            : 1;
+        style.VectorEffect() != VE_NON_SCALING_STROKE ? scaling_factor : 1;
     StrokeData stroke_data;
     SVGLayoutSupport::ApplyStrokeStyleToStrokeData(
         stroke_data, style, ParentInlineLayoutObject(), stroke_scale_factor);
diff --git a/third_party/blink/renderer/core/paint/svg_mask_painter.cc b/third_party/blink/renderer/core/paint/svg_mask_painter.cc
index d049d3e..fb46328c 100644
--- a/third_party/blink/renderer/core/paint/svg_mask_painter.cc
+++ b/third_party/blink/renderer/core/paint/svg_mask_painter.cc
@@ -42,9 +42,9 @@
                            EnclosingIntRect(visual_rect));
 
   SVGResourceClient* client = SVGResources::GetClient(layout_object);
-  const SVGComputedStyle& svg_style = layout_object.StyleRef().SvgStyle();
+  const ComputedStyle& style = layout_object.StyleRef();
   auto* masker = GetSVGResourceAsType<LayoutSVGResourceMasker>(
-      *client, svg_style.MaskerResource());
+      *client, style.MaskerResource());
   DCHECK(masker);
   SECURITY_DCHECK(!masker->NeedsLayout());
   masker->ClearInvalidationMask();
@@ -57,7 +57,7 @@
     content_transformation.ScaleNonUniform(reference_box.Width(),
                                            reference_box.Height());
   } else if (layout_object.IsSVGForeignObject()) {
-    content_transformation.Scale(layout_object.StyleRef().EffectiveZoom());
+    content_transformation.Scale(style.EffectiveZoom());
   }
 
   sk_sp<const PaintRecord> record =
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h
index 011c5ff..73a6470 100644
--- a/third_party/blink/renderer/core/style/computed_style.h
+++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -1101,6 +1101,13 @@
   const SVGComputedStyle& SvgStyle() const { return *svg_style_.Get(); }
   SVGComputedStyle& AccessSVGStyle() { return *svg_style_.Access(); }
 
+  EAlignmentBaseline AlignmentBaseline() const {
+    return SvgStyle().AlignmentBaseline();
+  }
+  EBufferedRendering BufferedRendering() const {
+    return SvgStyle().BufferedRendering();
+  }
+
   // baseline-shift
   EBaselineShift BaselineShift() const { return SvgStyle().BaselineShift(); }
   const Length& BaselineShiftValue() const {
@@ -1152,9 +1159,11 @@
   void SetStopColor(const StyleColor& c) { AccessSVGStyle().SetStopColor(c); }
 
   // flood-color
+  const StyleColor& FloodColor() const { return SvgStyle().FloodColor(); }
   void SetFloodColor(const StyleColor& c) { AccessSVGStyle().SetFloodColor(c); }
 
   // lighting-color
+  const StyleColor& LightingColor() const { return SvgStyle().LightingColor(); }
   void SetLightingColor(const StyleColor& c) {
     AccessSVGStyle().SetLightingColor(c);
   }
@@ -1163,6 +1172,11 @@
   float FloodOpacity() const { return SvgStyle().FloodOpacity(); }
   void SetFloodOpacity(float f) { AccessSVGStyle().SetFloodOpacity(f); }
 
+  EMaskType MaskType() const { return SvgStyle().MaskType(); }
+  StyleSVGResource* MaskerResource() const {
+    return SvgStyle().MaskerResource();
+  }
+
   // stop-opacity
   float StopOpacity() const { return SvgStyle().StopOpacity(); }
   void SetStopOpacity(float f) { AccessSVGStyle().SetStopOpacity(f); }
@@ -1195,6 +1209,8 @@
     AccessSVGStyle().SetStrokeWidth(w);
   }
 
+  EVectorEffect VectorEffect() const { return SvgStyle().VectorEffect(); }
+
   // Comparison operators
   // FIXME: Replace callers of operator== wth a named method instead, e.g.
   // inheritedEquals().
@@ -2455,7 +2471,7 @@
   // Return true if this style has properties ('filter', 'clip-path' and 'mask')
   // that applies an effect to SVG elements.
   bool HasSVGEffect() const {
-    return HasFilter() || HasClipPath() || SvgStyle().HasMasker();
+    return HasFilter() || HasClipPath() || MaskerResource();
   }
 
   // Paint utility functions.
@@ -2916,8 +2932,6 @@
   StyleColor DecorationColorIncludingFallback(bool visited_link) const;
 
   const StyleColor& StopColor() const { return SvgStyle().StopColor(); }
-  const StyleColor& FloodColor() const { return SvgStyle().FloodColor(); }
-  const StyleColor& LightingColor() const { return SvgStyle().LightingColor(); }
 
   // Appearance accessors are private to make sure callers use
   // EffectiveAppearance in almost all cases.
diff --git a/third_party/blink/renderer/core/style/svg_computed_style.h b/third_party/blink/renderer/core/style/svg_computed_style.h
index 2e6c549..a70adb7e7 100644
--- a/third_party/blink/renderer/core/style/svg_computed_style.h
+++ b/third_party/blink/renderer/core/style/svg_computed_style.h
@@ -367,7 +367,6 @@
   }
 
   // convenience
-  bool HasMasker() const { return MaskerResource(); }
   bool HasMarkers() const {
     return MarkerStartResource() || MarkerMidResource() || MarkerEndResource();
   }
diff --git a/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc b/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc
index 4386c126..7def4c5 100644
--- a/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc
@@ -181,7 +181,7 @@
   // TaintsOrigin() is only called after a successful call to Build()
   // (see above), so we should have a ComputedStyle here.
   DCHECK(style);
-  return style->SvgStyle().LightingColor().IsCurrentColor();
+  return style->LightingColor().IsCurrentColor();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc b/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc
index b20e547f..f7419497 100644
--- a/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc
@@ -21,7 +21,6 @@
 
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
 #include "third_party/blink/renderer/core/style/computed_style.h"
-#include "third_party/blink/renderer/core/style/svg_computed_style.h"
 #include "third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h"
 #include "third_party/blink/renderer/core/svg/svg_animated_number.h"
 #include "third_party/blink/renderer/core/svg/svg_animated_number_optional_number.h"
@@ -82,7 +81,7 @@
     return true;
   }
   if (attr_name == svg_names::kFloodOpacityAttr) {
-    drop_shadow->SetShadowOpacity(style.SvgStyle().FloodOpacity());
+    drop_shadow->SetShadowOpacity(style.FloodOpacity());
     return true;
   }
   return SVGFilterPrimitiveStandardAttributes::SetFilterEffectAttribute(
@@ -110,7 +109,7 @@
     return nullptr;
 
   Color color = style->VisitedDependentColor(GetCSSPropertyFloodColor());
-  float opacity = style->SvgStyle().FloodOpacity();
+  float opacity = style->FloodOpacity();
 
   FilterEffect* input1 = filter_builder->GetEffectById(
       AtomicString(in1_->CurrentValue()->Value()));
@@ -131,7 +130,7 @@
   // TaintsOrigin() is only called after a successful call to Build()
   // (see above), so we should have a ComputedStyle here.
   DCHECK(style);
-  return style->SvgStyle().FloodColor().IsCurrentColor();
+  return style->FloodColor().IsCurrentColor();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc b/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc
index 37fc529..bb15c833 100644
--- a/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc
@@ -22,7 +22,6 @@
 
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
 #include "third_party/blink/renderer/core/style/computed_style.h"
-#include "third_party/blink/renderer/core/style/svg_computed_style.h"
 #include "third_party/blink/renderer/core/svg_names.h"
 #include "third_party/blink/renderer/platform/graphics/filters/fe_flood.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
@@ -43,7 +42,7 @@
         style.VisitedDependentColor(GetCSSPropertyFloodColor()));
   }
   if (attr_name == svg_names::kFloodOpacityAttr)
-    return flood->SetFloodOpacity(style.SvgStyle().FloodOpacity());
+    return flood->SetFloodOpacity(style.FloodOpacity());
 
   return SVGFilterPrimitiveStandardAttributes::SetFilterEffectAttribute(
       effect, attr_name);
@@ -55,7 +54,7 @@
     return nullptr;
 
   Color color = style->VisitedDependentColor(GetCSSPropertyFloodColor());
-  float opacity = style->SvgStyle().FloodOpacity();
+  float opacity = style->FloodOpacity();
 
   return MakeGarbageCollected<FEFlood>(filter, color, opacity);
 }
@@ -65,7 +64,7 @@
   // TaintsOrigin() is only called after a successful call to Build()
   // (see above), so we should have a ComputedStyle here.
   DCHECK(style);
-  return style->SvgStyle().FloodColor().IsCurrentColor();
+  return style->FloodColor().IsCurrentColor();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc b/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc
index 52bb6526..8f542156 100644
--- a/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc
@@ -194,7 +194,7 @@
   // TaintsOrigin() is only called after a successful call to Build()
   // (see above), so we should have a ComputedStyle here.
   DCHECK(style);
-  return style->SvgStyle().LightingColor().IsCurrentColor();
+  return style->LightingColor().IsCurrentColor();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_stop_element.cc b/third_party/blink/renderer/core/svg/svg_stop_element.cc
index 98ed837..4c6f6f6a 100644
--- a/third_party/blink/renderer/core/svg/svg_stop_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_stop_element.cc
@@ -85,7 +85,7 @@
     return Color::kBlack;
 
   Color base_color = style->VisitedDependentColor(GetCSSPropertyStopColor());
-  return base_color.CombineWithAlpha(style->SvgStyle().StopOpacity());
+  return base_color.CombineWithAlpha(style->StopOpacity());
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc b/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc
index 521eac5f0..ab92435 100644
--- a/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc
+++ b/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc
@@ -100,8 +100,10 @@
       WTF::Bind(&SetSinkIdResolver::OnSetSinkIdComplete, WrapPersistent(this));
   WebMediaPlayer* web_media_player = element_->GetWebMediaPlayer();
   if (web_media_player) {
-    web_media_player->SetSinkId(sink_id_,
-                                std::move(set_sink_id_completion_callback));
+    if (web_media_player->SetSinkId(
+            sink_id_, std::move(set_sink_id_completion_callback))) {
+      element_->DidAudioOutputSinkChanged(sink_id_);
+    }
     return;
   }
 
@@ -197,13 +199,15 @@
 void HTMLMediaElementAudioOutputDevice::SetSinkId(const String& sink_id) {
   // No need to call WebFrameClient::CheckIfAudioSinkExistsAndIsAuthorized as
   // this call is not coming from content and should already be allowed.
-  WebMediaPlayer* web_media_player = GetSupplementable()->GetWebMediaPlayer();
+  HTMLMediaElement* html_media_element = GetSupplementable();
+  WebMediaPlayer* web_media_player = html_media_element->GetWebMediaPlayer();
   if (!web_media_player)
     return;
 
   sink_id_ = sink_id;
 
-  web_media_player->SetSinkId(sink_id_, base::DoNothing());
+  if (web_media_player->SetSinkId(sink_id_, base::DoNothing()))
+    html_media_element->DidAudioOutputSinkChanged(sink_id_);
 }
 
 void HTMLMediaElementAudioOutputDevice::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/buckets/storage_bucket_manager.cc b/third_party/blink/renderer/modules/buckets/storage_bucket_manager.cc
index 60a0c91..a5b3e771 100644
--- a/third_party/blink/renderer/modules/buckets/storage_bucket_manager.cc
+++ b/third_party/blink/renderer/modules/buckets/storage_bucket_manager.cc
@@ -21,7 +21,9 @@
     const StorageBucketOptions* options) {
   auto policies = mojom::blink::BucketPolicies::New();
   policies->persisted = options->persisted();
-  policies->title = options->hasTitleNonNull() ? options->titleNonNull() : "";
+  policies->title = (options->hasTitle() && !options->title().IsEmpty())
+                        ? options->title()
+                        : "";
   policies->quota = options->hasQuotaNonNull()
                         ? options->quotaNonNull()
                         : mojom::blink::kNoQuotaPolicyValue;
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc
index 4abd434..3af77edc 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc
@@ -23,6 +23,7 @@
 }
 
 CanvasFormattedText::~CanvasFormattedText() {
+  AllowDestroyingLayoutObjectInFinalizerScope scope;
   if (block_)
     block_->Destroy();
 }
diff --git a/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc b/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
index 855bd45..def304a 100644
--- a/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
+++ b/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
@@ -916,7 +916,7 @@
   }
 
   if (options->hasPublicKey() || options->hasConditionalPublicKey()) {
-    PublicKeyCredentialRequestOptions* public_key_options;
+    const PublicKeyCredentialRequestOptions* public_key_options;
     bool is_conditional_ui_request;
     if (options->hasPublicKey()) {
       public_key_options = options->publicKey();
diff --git a/third_party/blink/renderer/modules/file_system_access/global_file_system_access.cc b/third_party/blink/renderer/modules/file_system_access/global_file_system_access.cc
index 8681d83..45c55b4 100644
--- a/third_party/blink/renderer/modules/file_system_access/global_file_system_access.cc
+++ b/third_party/blink/renderer/modules/file_system_access/global_file_system_access.cc
@@ -291,16 +291,16 @@
   auto well_known_starting_directory =
       mojom::blink::WellKnownDirectory::kDefault;
   mojo::PendingRemote<blink::mojom::blink::FileSystemAccessTransferToken> token;
-  if (options->hasStartInNonNull()) {
-    if (options->startIn().IsWellKnownDirectory()) {
+  if (options->hasStartIn()) {
+    auto& start_in = options->startIn();
+    if (start_in.IsWellKnownDirectory()) {
       well_known_starting_directory = ConvertWellKnownDirectory(
-          options->startIn().GetAsWellKnownDirectory(), exception_state);
+          start_in.GetAsWellKnownDirectory(), exception_state);
       if (exception_state.HadException())
         return ScriptPromise();
     }
-
-    if (options->startIn().IsFileSystemHandle()) {
-      token = options->startIn().GetAsFileSystemHandle()->Transfer();
+    if (start_in.IsFileSystemHandle()) {
+      token = start_in.GetAsFileSystemHandle()->Transfer();
     }
   }
 
@@ -341,16 +341,16 @@
   auto well_known_starting_directory =
       mojom::blink::WellKnownDirectory::kDefault;
   mojo::PendingRemote<blink::mojom::blink::FileSystemAccessTransferToken> token;
-  if (options->hasStartInNonNull()) {
-    if (options->startIn().IsWellKnownDirectory()) {
+  if (options->hasStartIn()) {
+    auto& start_in = options->startIn();
+    if (start_in.IsWellKnownDirectory()) {
       well_known_starting_directory = ConvertWellKnownDirectory(
-          options->startIn().GetAsWellKnownDirectory(), exception_state);
+          start_in.GetAsWellKnownDirectory(), exception_state);
       if (exception_state.HadException())
         return ScriptPromise();
     }
-
-    if (options->startIn().IsFileSystemHandle()) {
-      token = options->startIn().GetAsFileSystemHandle()->Transfer();
+    if (start_in.IsFileSystemHandle()) {
+      token = start_in.GetAsFileSystemHandle()->Transfer();
     }
   }
 
@@ -381,16 +381,16 @@
   auto well_known_starting_directory =
       mojom::blink::WellKnownDirectory::kDefault;
   mojo::PendingRemote<blink::mojom::blink::FileSystemAccessTransferToken> token;
-  if (options->hasStartInNonNull()) {
-    if (options->startIn().IsWellKnownDirectory()) {
+  if (options->hasStartIn()) {
+    auto& start_in = options->startIn();
+    if (start_in.IsWellKnownDirectory()) {
       well_known_starting_directory = ConvertWellKnownDirectory(
-          options->startIn().GetAsWellKnownDirectory(), exception_state);
+          start_in.GetAsWellKnownDirectory(), exception_state);
       if (exception_state.HadException())
         return ScriptPromise();
     }
-
-    if (options->startIn().IsFileSystemHandle()) {
-      token = options->startIn().GetAsFileSystemHandle()->Transfer();
+    if (start_in.IsFileSystemHandle()) {
+      token = start_in.GetAsFileSystemHandle()->Transfer();
     }
   }
 
diff --git a/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc b/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc
index d38b297..1dbba71 100644
--- a/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc
+++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc
@@ -188,9 +188,9 @@
   void SetHasAudio(media::mojom::AudioCodec audio_codec) override {}
   void SetHasVideo(media::mojom::VideoCodec video_codec) override {}
   void SetVideoPipelineInfo(
-      media::mojom::blink::PipelineDecoderInfoPtr info) override {}
+      media::mojom::blink::VideoDecoderInfoPtr info) override {}
   void SetAudioPipelineInfo(
-      media::mojom::blink::PipelineDecoderInfoPtr info) override {}
+      media::mojom::blink::AudioDecoderInfoPtr info) override {}
 
  private:
   mojo::Receiver<media::mojom::blink::MediaMetricsProvider> receiver_{this};
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
index e5db035..f8f63a5 100644
--- a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
+++ b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
@@ -57,8 +57,10 @@
   void OnRequestPictureInPicture() override {}
   WebTimeRanges Buffered() const override { return WebTimeRanges(); }
   WebTimeRanges Seekable() const override { return WebTimeRanges(); }
-  void SetSinkId(const WebString& sinkId,
-                 WebSetSinkIdCompleteCallback) override {}
+  bool SetSinkId(const WebString& sinkId,
+                 WebSetSinkIdCompleteCallback) override {
+    return false;
+  }
   bool HasVideo() const override { return true; }
   bool HasAudio() const override { return false; }
   gfx::Size NaturalSize() const override { return size_; }
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
index 46b9d505..4120914 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
@@ -822,27 +822,28 @@
   DCHECK(bridge_->GetSurfaceId().is_valid());
 }
 
-void WebMediaPlayerMS::SetSinkId(
+bool WebMediaPlayerMS::SetSinkId(
     const WebString& sink_id,
     WebSetSinkIdCompleteCallback completion_callback) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   SendLogMessage(
       String::Format("%s({sink_id=%s})", __func__, sink_id.Utf8().c_str()));
+
+  media::OutputDeviceStatusCB callback =
+      ConvertToOutputDeviceStatusCB(std::move(completion_callback));
+
   if (!audio_renderer_) {
     SendLogMessage(String::Format(
         "%s => (WARNING: failed to instantiate audio renderer)", __func__));
-  }
-  media::OutputDeviceStatusCB callback =
-      ConvertToOutputDeviceStatusCB(std::move(completion_callback));
-  if (audio_renderer_) {
-    auto sink_id_utf8 = sink_id.Utf8();
-    audio_renderer_->SwitchOutputDevice(sink_id_utf8, std::move(callback));
-    delegate_->DidAudioOutputSinkChange(delegate_id_, sink_id_utf8);
-  } else {
     std::move(callback).Run(media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL);
     SendLogMessage(String::Format(
         "%s => (ERROR: OUTPUT_DEVICE_STATUS_ERROR_INTERNAL)", __func__));
+    return false;
   }
+
+  auto sink_id_utf8 = sink_id.Utf8();
+  audio_renderer_->SwitchOutputDevice(sink_id_utf8, std::move(callback));
+  return true;
 }
 
 void WebMediaPlayerMS::SetPreload(WebMediaPlayer::Preload preload) {
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc
index 980d5e5..2ad2897 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc
@@ -144,12 +144,6 @@
     return false;
   }
 
-  void SetIsEffectivelyFullscreen(
-      int delegate_id,
-      WebFullscreenVideoStatus fullscreen_video_status) override {
-    EXPECT_EQ(delegate_id_, delegate_id);
-  }
-
   bool IsFrameHidden() override { return is_hidden_; }
   bool IsFrameClosed() override { return false; }
 
@@ -157,11 +151,6 @@
 
   int delegate_id() { return delegate_id_; }
 
-  void DidAudioOutputSinkChange(int delegate_id,
-                                const std::string& hashed_device_id) override {
-    EXPECT_EQ(delegate_id_, delegate_id);
-  }
-
  private:
   int delegate_id_ = 1234;
   Observer* observer_ = nullptr;
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc
index e439b8b..ef20425 100644
--- a/third_party/blink/renderer/modules/payments/payment_request.cc
+++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -809,16 +809,21 @@
   }
 
   LocalFrame* local_frame = DomWindow()->GetFrame();
-  bool is_user_gesture = LocalFrame::HasTransientUserActivation(local_frame);
-  if (!is_user_gesture) {
+
+  bool payment_request_allowed =
+      LocalFrame::HasTransientUserActivation(local_frame);
+  if (!payment_request_allowed) {
     UseCounter::Count(GetExecutionContext(),
                       WebFeature::kPaymentRequestShowWithoutGesture);
   }
-  if (RuntimeEnabledFeatures::PaymentRequestShowConsumesUserActivationEnabled(
+
+  if (RuntimeEnabledFeatures::CapabilityDelegationPaymentRequestEnabled(
           GetExecutionContext())) {
-    if (!is_user_gesture) {
+    payment_request_allowed |= local_frame->IsPaymentRequestTokenActive();
+    if (!payment_request_allowed) {
       String message =
-          "PaymentRequest.show() requires transient user activation";
+          "PaymentRequest.show() requires either transient user activation or "
+          "delegated payment request capability";
       GetExecutionContext()->AddConsoleMessage(
           MakeGarbageCollected<ConsoleMessage>(
               mojom::blink::ConsoleMessageSource::kJavaScript,
@@ -828,15 +833,15 @@
       return ScriptPromise();
     }
     LocalFrame::ConsumeTransientUserActivation(local_frame);
-  }
+    local_frame->ConsumePaymentRequestToken();
 
-  // TODO(crbug.com/825270): Pretend that a user gesture is provided to allow
-  // origins that are part of the Secure Payment Confirmation Origin Trial to
-  // use skip-the-sheet flow as a hack for secure modal window
-  // (crbug.com/1122028). Remove this after user gesture delegation ships.
-  if (RuntimeEnabledFeatures::SecurePaymentConfirmationEnabled(
-          GetExecutionContext())) {
-    is_user_gesture = true;
+  } else if (RuntimeEnabledFeatures::SecurePaymentConfirmationEnabled(
+                 GetExecutionContext())) {
+    // TODO(crbug.com/825270): Pretend that a user gesture is provided to allow
+    // origins that are part of the Secure Payment Confirmation Origin Trial to
+    // use skip-the-sheet flow as a hack for secure modal window
+    // (crbug.com/1122028). Remove this after user gesture delegation ships.
+    payment_request_allowed = true;
   }
 
   // TODO(crbug.com/779126): add support for handling payment requests in
@@ -852,7 +857,7 @@
   UseCounter::Count(GetExecutionContext(), WebFeature::kPaymentRequestShow);
 
   is_waiting_for_show_promise_to_resolve_ = !details_promise.IsEmpty();
-  payment_provider_->Show(is_user_gesture,
+  payment_provider_->Show(payment_request_allowed,
                           is_waiting_for_show_promise_to_resolve_);
   if (is_waiting_for_show_promise_to_resolve_) {
     // If the website does not calculate the final shopping cart contents within
diff --git a/third_party/blink/renderer/modules/payments/payment_request_test.cc b/third_party/blink/renderer/modules/payments/payment_request_test.cc
index 580ed77e..c4ffa02 100644
--- a/third_party/blink/renderer/modules/payments/payment_request_test.cc
+++ b/third_party/blink/renderer/modules/payments/payment_request_test.cc
@@ -304,8 +304,7 @@
 }
 
 TEST(PaymentRequestTest, CannotShowWithoutUserActivation) {
-  RuntimeEnabledFeatures::SetPaymentRequestShowConsumesUserActivationEnabled(
-      true);
+  RuntimeEnabledFeatures::SetCapabilityDelegationPaymentRequestEnabled(true);
   PaymentRequestV8TestingScope scope;
   MockFunctionScope funcs(scope.GetScriptState());
   PaymentRequest* request = PaymentRequest::Create(
@@ -318,8 +317,7 @@
 }
 
 TEST(PaymentRequestTest, ShowConsumesUserActivation) {
-  RuntimeEnabledFeatures::SetPaymentRequestShowConsumesUserActivationEnabled(
-      true);
+  RuntimeEnabledFeatures::SetCapabilityDelegationPaymentRequestEnabled(true);
   PaymentRequestV8TestingScope scope;
   MockFunctionScope funcs(scope.GetScriptState());
   PaymentRequest* request = PaymentRequest::Create(
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc
index e5574d4..db68cc5bf 100644
--- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc
+++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc
@@ -5,6 +5,7 @@
 #include "sanitizer.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/v8_node_filter.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_parse_from_string_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_document_fragment_or_document.h"
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_trusted_html_or_document_fragment_or_document.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_sanitizer_config.h"
@@ -23,7 +24,6 @@
 #include "third_party/blink/renderer/core/trustedtypes/trusted_html.h"
 #include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
 #include "third_party/blink/renderer/core/xml/dom_parser.h"
-#include "third_party/blink/renderer/core/xml/parse_from_string_options.h"
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_node.cc b/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
index bd0580f..9156511 100644
--- a/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
@@ -110,6 +110,14 @@
 }
 
 void ScriptProcessorHandler::Process(uint32_t frames_to_process) {
+  // The main thread might be accessing the shared buffers. If so, silience
+  // the output and return.
+  MutexTryLocker try_locker(process_event_lock_);
+  if (!try_locker.Locked()) {
+    Output(0).Bus()->Zero();
+    return;
+  }
+
   // Discussion about inputs and outputs:
   // As in other AudioNodes, ScriptProcessorNode uses an AudioBus for its input
   // and output (see inputBus and outputBus below).  Additionally, there is a
@@ -181,47 +189,26 @@
   buffer_read_write_index_ =
       (buffer_read_write_index_ + frames_to_process) % BufferSize();
 
-  // m_bufferReadWriteIndex will wrap back around to 0 when the current input
-  // and output buffers are full.
-  // When this happens, fire an event and swap buffers.
+  // Fire an event and swap buffers when |buffer_read_write_index_| wraps back
+  // around to 0. It means the current input and output buffers are full.
   if (!buffer_read_write_index_) {
-    // Avoid building up requests on the main thread to fire process events when
-    // they're not being handled.  This could be a problem if the main thread is
-    // very busy doing other things and is being held up handling previous
-    // requests.  The audio thread can't block on this lock, so we call
-    // tryLock() instead.
-    MutexTryLocker try_locker(process_event_lock_);
-    if (!try_locker.Locked()) {
-      // We're late in handling the previous request. The main thread must be
-      // very busy.  The best we can do is clear out the buffer ourself here.
-      shared_output_buffer->Zero();
+    if (Context()->HasRealtimeConstraint()) {
+      // For a realtime context, fire an event and do not wait.
+      PostCrossThreadTask(
+          *task_runner_, FROM_HERE,
+          CrossThreadBindOnce(&ScriptProcessorHandler::FireProcessEvent,
+                              AsWeakPtr(), double_buffer_index_));
     } else {
-      // With the realtime context, execute the script code asynchronously
-      // and do not wait.
-      if (Context()->HasRealtimeConstraint()) {
-        // Fire the event on the main thread with the appropriate buffer
-        // index.
-        PostCrossThreadTask(
-            *task_runner_, FROM_HERE,
-            CrossThreadBindOnce(&ScriptProcessorHandler::FireProcessEvent,
-                                AsWeakPtr(), double_buffer_index_));
-      } else {
-        // If this node is in the offline audio context, use the
-        // waitable event to synchronize to the offline rendering thread.
-        std::unique_ptr<base::WaitableEvent> waitable_event =
-            std::make_unique<base::WaitableEvent>();
-
-        PostCrossThreadTask(
-            *task_runner_, FROM_HERE,
-            CrossThreadBindOnce(
-                &ScriptProcessorHandler::FireProcessEventForOfflineAudioContext,
-                AsWeakPtr(), double_buffer_index_,
-                CrossThreadUnretained(waitable_event.get())));
-
-        // Okay to block the offline audio rendering thread since it is
-        // not the actual audio device thread.
-        waitable_event->Wait();
-      }
+      // For an offline context, wait until the script execution is finished.
+      std::unique_ptr<base::WaitableEvent> waitable_event =
+          std::make_unique<base::WaitableEvent>();
+      PostCrossThreadTask(
+          *task_runner_, FROM_HERE,
+          CrossThreadBindOnce(
+              &ScriptProcessorHandler::FireProcessEventForOfflineAudioContext,
+              AsWeakPtr(), double_buffer_index_,
+              CrossThreadUnretained(waitable_event.get())));
+      waitable_event->Wait();
     }
 
     SwapBuffers();
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc b/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc
index b3a153f3..45cc35c8 100644
--- a/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder.cc
@@ -82,7 +82,7 @@
   media_log->SetProperty<media::MediaLogProperty::kFrameTitle>(
       std::string("AudioDecoder(WebCodecs)"));
   media_log->SetProperty<media::MediaLogProperty::kAudioDecoderName>(
-      decoder.GetDisplayName());
+      decoder.GetDecoderType());
   media_log->SetProperty<media::MediaLogProperty::kIsPlatformAudioDecoder>(
       decoder.IsPlatformDecoder());
   media_log->SetProperty<media::MediaLogProperty::kAudioTracks>(
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.cc b/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.cc
index ee9ace13..f35cf14 100644
--- a/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.cc
+++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.cc
@@ -199,6 +199,7 @@
     if (decoder_) {
       status = media::OkStatus();
       decoder_details = DecoderDetails({decoder_->GetDisplayName(),
+                                        decoder_->GetDecoderType(),
                                         decoder_->IsPlatformDecoder(),
                                         decoder_->NeedsBitstreamConversion()});
     }
@@ -283,6 +284,11 @@
                           : AudioDecoderBroker::kDefaultDisplayName;
 }
 
+media::AudioDecoderType AudioDecoderBroker::GetDecoderType() const {
+  return decoder_details_ ? decoder_details_->decoder_id
+                          : media::AudioDecoderType::kBroker;
+}
+
 bool AudioDecoderBroker::IsPlatformDecoder() const {
   return decoder_details_ ? decoder_details_->is_platform_decoder : false;
 }
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.h b/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.h
index 6c811fd..cafb1ac 100644
--- a/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.h
+++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker.h
@@ -41,6 +41,7 @@
  public:
   struct DecoderDetails {
     std::string display_name;
+    media::AudioDecoderType decoder_id;
     bool is_platform_decoder;
     bool needs_bitstream_conversion;
   };
@@ -80,6 +81,7 @@
 
   // AudioDecoder implementation.
   std::string GetDisplayName() const override;
+  media::AudioDecoderType GetDecoderType() const override;
   bool IsPlatformDecoder() const override;
   void Initialize(const media::AudioDecoderConfig& config,
                   media::CdmContext* cdm_context,
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker_test.cc b/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker_test.cc
index 3a7869c..15b07906 100644
--- a/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker_test.cc
+++ b/third_party/blink/renderer/modules/webcodecs/audio_decoder_broker_test.cc
@@ -331,7 +331,7 @@
       media::EmptyExtraData(), media::EncryptionScheme::kUnencrypted));
   EXPECT_EQ(GetDisplayName(), "MojoAudioDecoder");
 
-  // Using vorbis buffer here because its easy and the  fake decoder generates
+  // Using vorbis buffer here because its easy and the fake decoder generates
   // output regardless of the input details.
   DecodeBuffer(media::ReadTestDataFile("vorbis-packet-0"));
   DecodeBuffer(media::DecoderBuffer::CreateEOSBuffer());
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder.cc b/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
index 12c9f7e..77bdd59 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
@@ -229,7 +229,7 @@
   media_log->SetProperty<media::MediaLogProperty::kFrameTitle>(
       std::string("VideoDecoder(WebCodecs)"));
   media_log->SetProperty<media::MediaLogProperty::kVideoDecoderName>(
-      decoder.GetDisplayName());
+      decoder.GetDecoderType());
   media_log->SetProperty<media::MediaLogProperty::kIsPlatformVideoDecoder>(
       decoder.IsPlatformDecoder());
   media_log->SetProperty<media::MediaLogProperty::kVideoTracks>(
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc b/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc
index f913738..0420ce0 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc
@@ -225,10 +225,10 @@
     base::Optional<DecoderDetails> decoder_details;
     if (decoder_) {
       status = media::OkStatus();
-      decoder_details = DecoderDetails({decoder_->GetDisplayName(),
-                                        decoder_->IsPlatformDecoder(),
-                                        decoder_->NeedsBitstreamConversion(),
-                                        decoder_->GetMaxDecodeRequests()});
+      decoder_details = DecoderDetails(
+          {decoder_->GetDisplayName(), decoder_->GetDecoderType(),
+           decoder_->IsPlatformDecoder(), decoder_->NeedsBitstreamConversion(),
+           decoder_->GetMaxDecodeRequests()});
     }
 
     // Fire |init_cb|.
@@ -315,6 +315,11 @@
   media_task_runner_->DeleteSoon(FROM_HERE, std::move(media_tasks_));
 }
 
+media::VideoDecoderType VideoDecoderBroker::GetDecoderType() const {
+  return decoder_details_ ? decoder_details_->decoder_id
+                          : media::VideoDecoderType::kBroker;
+}
+
 std::string VideoDecoderBroker::GetDisplayName() const {
   return decoder_details_ ? decoder_details_->display_name
                           : VideoDecoderBroker::kDefaultDisplayName;
diff --git a/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h b/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h
index 9cc7863e..e48f7f100 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h
+++ b/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h
@@ -45,6 +45,7 @@
  public:
   struct DecoderDetails {
     std::string display_name;
+    media::VideoDecoderType decoder_id;
     bool is_platform_decoder;
     bool needs_bitstream_conversion;
     int max_decode_requests;
@@ -88,6 +89,7 @@
   VideoDecoderBroker& operator=(const VideoDecoderBroker&) = delete;
 
   // VideoDecoder implementation.
+  media::VideoDecoderType GetDecoderType() const override;
   std::string GetDisplayName() const override;
   bool IsPlatformDecoder() const override;
   void Initialize(const media::VideoDecoderConfig& config,
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
index 0343693..e053356 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -282,8 +282,8 @@
   // TODO(https://crbug.com/1139089) : Add encoder properties.
   media::MediaLog* log = logger_->log();
 
-  log->SetProperty<media::MediaLogProperty::kVideoDecoderName>(encoder_name);
-  log->SetProperty<media::MediaLogProperty::kIsPlatformVideoDecoder>(
+  log->SetProperty<media::MediaLogProperty::kVideoEncoderName>(encoder_name);
+  log->SetProperty<media::MediaLogProperty::kIsPlatformVideoEncoder>(
       is_hw_accelerated);
 }
 
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
index 0fdb8c5..5b4e02e4 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
@@ -471,9 +471,10 @@
                                   const WGPUOrigin3D& origin,
                                   const WGPUExtent3D& copy_size,
                                   const WGPUTextureCopyView& destination) {
-  scoped_refptr<WebGPUMailboxTexture> mailbox_texture = base::AdoptRef(
-      new WebGPUMailboxTexture(GetDawnControlClient(), device_->GetHandle(),
-                               image, WGPUTextureUsage_CopySrc));
+  scoped_refptr<WebGPUMailboxTexture> mailbox_texture =
+      WebGPUMailboxTexture::FromStaticBitmapImage(
+          GetDawnControlClient(), device_->GetHandle(),
+          WGPUTextureUsage_CopySrc, image);
 
   WGPUTexture src_texture = mailbox_texture->GetTexture();
   DCHECK(src_texture != nullptr);
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_texture.cc b/third_party/blink/renderer/modules/webgpu/gpu_texture.cc
index 3254dd5..2ab5110 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_texture.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_texture.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/webgpu/gpu_texture.h"
 
+#include "gpu/command_buffer/client/webgpu_interface.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_descriptor.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_view_descriptor.h"
 #include "third_party/blink/renderer/core/html/media/html_video_element.h"
@@ -14,7 +15,6 @@
 #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.h"
-#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
 
 namespace blink {
 
@@ -125,6 +125,8 @@
 
   // Create a CanvasResourceProvider for producing WebGPU-compatible shared
   // images.
+  // TODO(crbug.com/1174809): This should recycle resources instead of creating
+  // a new shared image every time.
   std::unique_ptr<CanvasResourceProvider> resource_provider =
       CanvasResourceProvider::CreateWebGPUImageProvider(
           IntSize(video->videoWidth(), video->videoHeight()),
@@ -152,19 +154,11 @@
   DCHECK(canvas_resource->IsValid());
   DCHECK(canvas_resource->IsAccelerated());
 
-  scoped_refptr<StaticBitmapImage> image = canvas_resource->Bitmap();
-
-  // Set origin to be clean. This was checked above.
-  image->SetOriginClean(true);
-
-  DCHECK(image->IsTextureBacked());
-  SkImageInfo image_info = image->PaintImageForCurrentFrame().GetSkImageInfo();
-
   // Extract the format. This is only used to validate copyImageBitmapToTexture
   // right now. We may want to reflect it from this function or validate it
   // against some input parameters.
   WGPUTextureFormat format;
-  switch (image_info.colorType()) {
+  switch (canvas_resource->CreateSkImageInfo().colorType()) {
     case SkColorType::kRGBA_8888_SkColorType:
       format = WGPUTextureFormat_RGBA8Unorm;
       break;
@@ -193,9 +187,10 @@
       return nullptr;
   }
 
-  scoped_refptr<WebGPUMailboxTexture> mailbox_texture = base::AdoptRef(
-      new WebGPUMailboxTexture(device->GetDawnControlClient(),
-                               device->GetHandle(), image.get(), usage));
+  scoped_refptr<WebGPUMailboxTexture> mailbox_texture =
+      WebGPUMailboxTexture::FromCanvasResource(device->GetDawnControlClient(),
+                                               device->GetHandle(), usage,
+                                               std::move(canvas_resource));
   DCHECK(mailbox_texture->GetTexture() != nullptr);
 
   return MakeGarbageCollected<GPUTexture>(device, format,
diff --git a/third_party/blink/renderer/modules/websockets/BUILD.gn b/third_party/blink/renderer/modules/websockets/BUILD.gn
index 78e57912..c806a79 100644
--- a/third_party/blink/renderer/modules/websockets/BUILD.gn
+++ b/third_party/blink/renderer/modules/websockets/BUILD.gn
@@ -26,4 +26,6 @@
     "websocket_stream.cc",
     "websocket_stream.h",
   ]
+
+  deps = [ "//services/network/public/mojom:websocket_mojom" ]
 }
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
index ddb5e89112..c241f313 100644
--- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc
+++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -50,6 +50,10 @@
   RuntimeEnabledFeatures::SetBrowserVerifiedUserActivationMouseEnabled(enable);
 }
 
+void WebRuntimeFeatures::EnableCapabilityDelegationPaymentRequest(bool enable) {
+  RuntimeEnabledFeatures::SetCapabilityDelegationPaymentRequestEnabled(enable);
+}
+
 void WebRuntimeFeatures::EnableClickPointerEvent(bool enable) {
   RuntimeEnabledFeatures::SetClickPointerEventEnabled(enable);
 }
diff --git a/third_party/blink/renderer/platform/fonts/font.cc b/third_party/blink/renderer/platform/fonts/font.cc
index 4996daf..e30fba0 100644
--- a/third_party/blink/renderer/platform/fonts/font.cc
+++ b/third_party/blink/renderer/platform/fonts/font.cc
@@ -96,7 +96,8 @@
 // should clear the entry from FontFallbackMap.
 // Note that we must not persist a FontFallbackList reference outside Font.
 void Font::ReleaseFontFallbackListRef() const {
-  if (!font_fallback_list_ || !font_fallback_list_->IsValid()) {
+  if (!font_fallback_list_ || !font_fallback_list_->IsValid() ||
+      !font_fallback_list_->HasFontFallbackMap()) {
     font_fallback_list_.reset();
     return;
   }
@@ -106,12 +107,13 @@
   CHECK(!list_ref.HasOneRef());
   font_fallback_list_.reset();
   if (list_ref.HasOneRef())
-    GetFontFallbackMap(list_ref.GetFontSelector()).Remove(font_description_);
+    list_ref.GetFontFallbackMap().Remove(font_description_);
 }
 
 void Font::RevalidateFontFallbackList() const {
+  DCHECK(font_fallback_list_);
   font_fallback_list_ =
-      GetFontFallbackMap(GetFontSelector()).Get(font_description_);
+      font_fallback_list_->GetFontFallbackMap().Get(font_description_);
 }
 
 FontFallbackList* Font::EnsureFontFallbackList() const {
diff --git a/third_party/blink/renderer/platform/fonts/font_fallback_list.cc b/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
index f312347..a759bfd 100644
--- a/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
+++ b/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
@@ -33,15 +33,16 @@
 #include "third_party/blink/renderer/platform/fonts/font_cache.h"
 #include "third_party/blink/renderer/platform/fonts/font_cache_key.h"
 #include "third_party/blink/renderer/platform/fonts/font_description.h"
+#include "third_party/blink/renderer/platform/fonts/font_fallback_map.h"
 #include "third_party/blink/renderer/platform/fonts/font_family.h"
 #include "third_party/blink/renderer/platform/fonts/segmented_font_data.h"
 #include "third_party/blink/renderer/platform/wtf/text/character_names.h"
 
 namespace blink {
 
-FontFallbackList::FontFallbackList(FontSelector* font_selector)
+FontFallbackList::FontFallbackList(FontFallbackMap& font_fallback_map)
     : cached_primary_simple_font_data_(nullptr),
-      font_selector_(font_selector),
+      font_fallback_map_(font_fallback_map),
       family_index_(0),
       generation_(FontCache::GetFontCache()->Generation()),
       has_loading_fallback_(false),
@@ -51,6 +52,17 @@
       can_shape_word_by_word_computed_(false),
       is_invalid_(false) {}
 
+FontFallbackList::~FontFallbackList() {
+  ReleaseFontData();
+}
+
+FontSelector* FontFallbackList::GetFontSelector() const {
+  // FontFallbackList objects are managed in FontFallbackMap, and should not be
+  // used after FontFallbackMap is destroyed.
+  DCHECK(font_fallback_map_);
+  return font_fallback_map_->GetFontSelector();
+}
+
 void FontFallbackList::ReleaseFontData() {
   unsigned num_fonts = font_list_.size();
   for (unsigned i = 0; i < num_fonts; ++i) {
@@ -141,36 +153,37 @@
     family_index_++;
     if (curr_family->Family().length()) {
       scoped_refptr<FontData> result;
-      if (font_selector_)
-        result = font_selector_->GetFontData(font_description,
-                                             curr_family->Family());
+      if (GetFontSelector()) {
+        result = GetFontSelector()->GetFontData(font_description,
+                                                curr_family->Family());
+      }
 
       if (!result) {
         result = FontCache::GetFontCache()->GetFontData(font_description,
                                                         curr_family->Family());
-        if (font_selector_) {
-          font_selector_->ReportFontLookupByUniqueOrFamilyName(
+        if (GetFontSelector()) {
+          GetFontSelector()->ReportFontLookupByUniqueOrFamilyName(
               curr_family->Family(), font_description,
               DynamicTo<SimpleFontData>(result.get()));
         }
       }
       if (result) {
-        if (font_selector_) {
-          font_selector_->ReportSuccessfulFontFamilyMatch(
+        if (GetFontSelector()) {
+          GetFontSelector()->ReportSuccessfulFontFamilyMatch(
               curr_family->Family());
         }
         return result;
       }
 
-      if (font_selector_)
-        font_selector_->ReportFailedFontFamilyMatch(curr_family->Family());
+      if (GetFontSelector())
+        GetFontSelector()->ReportFailedFontFamilyMatch(curr_family->Family());
     }
   }
   family_index_ = kCAllFamiliesScanned;
 
-  if (font_selector_) {
+  if (GetFontSelector()) {
     // Try the user's preferred standard font.
-    if (scoped_refptr<FontData> data = font_selector_->GetFontData(
+    if (scoped_refptr<FontData> data = GetFontSelector()->GetFontData(
             font_description, font_family_names::kWebkitStandard))
       return data;
   }
@@ -178,9 +191,9 @@
   // Still no result. Hand back our last resort fallback font.
   auto last_resort =
       FontCache::GetFontCache()->GetLastResortFallbackFont(font_description);
-  if (font_selector_) {
-    font_selector_->ReportLastResortFallbackFontLookup(font_description,
-                                                       last_resort.get());
+  if (GetFontSelector()) {
+    GetFontSelector()->ReportLastResortFallbackFontLookup(font_description,
+                                                          last_resort.get());
   }
   return last_resort;
 }
@@ -194,9 +207,10 @@
       FontFaceCreationParams params(
           AdjustFamilyNameToAvoidUnsupportedFonts(current_family->Family()));
       scoped_refptr<FontData> result;
-      if (font_selector_)
-        result = font_selector_->GetFontData(font_description,
-                                             current_family->Family());
+      if (GetFontSelector()) {
+        result = GetFontSelector()->GetFontData(font_description,
+                                                current_family->Family());
+      }
       if (!result) {
         if (FontPlatformData* platform_data =
                 FontCache::GetFontCache()->GetFontPlatformData(font_description,
diff --git a/third_party/blink/renderer/platform/fonts/font_fallback_list.h b/third_party/blink/renderer/platform/fonts/font_fallback_list.h
index 52e794b0..684d089 100644
--- a/third_party/blink/renderer/platform/fonts/font_fallback_list.h
+++ b/third_party/blink/renderer/platform/fonts/font_fallback_list.h
@@ -36,6 +36,7 @@
 namespace blink {
 
 class FontDescription;
+class FontFallbackMap;
 
 const int kCAllFamiliesScanned = -1;
 
@@ -46,11 +47,12 @@
   USING_FAST_MALLOC(FontFallbackList);
 
  public:
-  static scoped_refptr<FontFallbackList> Create(FontSelector* font_selector) {
-    return base::AdoptRef(new FontFallbackList(font_selector));
+  static scoped_refptr<FontFallbackList> Create(
+      FontFallbackMap& font_fallback_map) {
+    return base::AdoptRef(new FontFallbackList(font_fallback_map));
   }
 
-  ~FontFallbackList() { ReleaseFontData(); }
+  ~FontFallbackList();
 
   // Returns whether the cached data is valid. We can use a FontFallbackList
   // only when it's valid.
@@ -65,7 +67,12 @@
 
   bool ShouldSkipDrawing() const;
 
-  FontSelector* GetFontSelector() const { return font_selector_.Get(); }
+  // Returns false only after the WeakPersistent to FontFallbackMap is turned to
+  // nullptr due to GC.
+  bool HasFontFallbackMap() const { return font_fallback_map_; }
+  FontFallbackMap& GetFontFallbackMap() const { return *font_fallback_map_; }
+
+  FontSelector* GetFontSelector() const;
   uint16_t Generation() const { return generation_; }
 
   ShapeCache* GetShapeCache(const FontDescription& font_description) {
@@ -103,7 +110,7 @@
   bool HasAdvanceOverride() const { return has_advance_override_; }
 
  private:
-  explicit FontFallbackList(FontSelector* font_selector);
+  explicit FontFallbackList(FontFallbackMap& font_fallback_map);
 
   scoped_refptr<FontData> GetFontData(const FontDescription&);
 
@@ -116,7 +123,7 @@
 
   Vector<scoped_refptr<FontData>, 1> font_list_;
   const SimpleFontData* cached_primary_simple_font_data_;
-  const Persistent<FontSelector> font_selector_;
+  const WeakPersistent<FontFallbackMap> font_fallback_map_;
   int family_index_;
   uint16_t generation_;
   bool has_loading_fallback_ : 1;
diff --git a/third_party/blink/renderer/platform/fonts/font_fallback_map.cc b/third_party/blink/renderer/platform/fonts/font_fallback_map.cc
index 518f246..624a815 100644
--- a/third_party/blink/renderer/platform/fonts/font_fallback_map.cc
+++ b/third_party/blink/renderer/platform/fonts/font_fallback_map.cc
@@ -26,7 +26,7 @@
     return iter->value;
   }
   auto add_result = fallback_list_for_description_.insert(
-      font_description, FontFallbackList::Create(font_selector_));
+      font_description, FontFallbackList::Create(*this));
   return add_result.stored_value->value;
 }
 
diff --git a/third_party/blink/renderer/platform/fonts/font_fallback_map.h b/third_party/blink/renderer/platform/fonts/font_fallback_map.h
index e2186f7e..135f1124 100644
--- a/third_party/blink/renderer/platform/fonts/font_fallback_map.h
+++ b/third_party/blink/renderer/platform/fonts/font_fallback_map.h
@@ -25,6 +25,8 @@
 
   ~FontFallbackMap() override;
 
+  FontSelector* GetFontSelector() const { return font_selector_; }
+
   scoped_refptr<FontFallbackList> Get(const FontDescription& font_description);
   void Remove(const FontDescription& font_description);
 
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc
index 9dc4bc9..16df6620 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc
@@ -406,9 +406,9 @@
                                WGPUTextureUsage_CopySrc, _))
       .WillOnce(testing::SaveArg<5>(&mailbox_bytes));
 
-  scoped_refptr<WebGPUMailboxTexture> mailbox_texture = base::AdoptRef(
-      new WebGPUMailboxTexture(dawn_control_client_, fake_device_, bitmap.get(),
-                               WGPUTextureUsage_CopySrc));
+  scoped_refptr<WebGPUMailboxTexture> mailbox_texture =
+      WebGPUMailboxTexture::FromStaticBitmapImage(
+          dawn_control_client_, fake_device_, WGPUTextureUsage_CopySrc, bitmap);
 
   gpu::Mailbox mailbox = gpu::Mailbox::FromVolatile(
       *reinterpret_cast<const volatile gpu::Mailbox*>(mailbox_bytes));
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.cc
index 13ec602..915f3403 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.cc
@@ -5,22 +5,62 @@
 #include "third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.h"
 
 #include "gpu/command_buffer/client/webgpu_interface.h"
+#include "third_party/blink/renderer/platform/graphics/canvas_resource.h"
 #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
 
 namespace blink {
 
+// static
+scoped_refptr<WebGPUMailboxTexture> WebGPUMailboxTexture::FromStaticBitmapImage(
+    scoped_refptr<DawnControlClientHolder> dawn_control_client,
+    WGPUDevice device,
+    WGPUTextureUsage usage,
+    scoped_refptr<StaticBitmapImage> image) {
+  DCHECK(image->IsTextureBacked());
+  auto finished_access_callback =
+      WTF::Bind(&StaticBitmapImage::UpdateSyncToken, WTF::RetainedRef(image));
+
+  return base::AdoptRef(new WebGPUMailboxTexture(
+      std::move(dawn_control_client), device, usage,
+      image->GetMailboxHolder().mailbox, image->GetMailboxHolder().sync_token,
+      std::move(finished_access_callback)));
+}
+
+// static
+scoped_refptr<WebGPUMailboxTexture> WebGPUMailboxTexture::FromCanvasResource(
+    scoped_refptr<DawnControlClientHolder> dawn_control_client,
+    WGPUDevice device,
+    WGPUTextureUsage usage,
+    scoped_refptr<CanvasResource> canvas_resource) {
+  auto finished_access_callback = WTF::Bind(&CanvasResource::WaitSyncToken,
+                                            WTF::RetainedRef(canvas_resource));
+
+  const gpu::Mailbox& mailbox =
+      canvas_resource->GetOrCreateGpuMailbox(kUnverifiedSyncToken);
+  gpu::SyncToken sync_token = canvas_resource->GetSyncToken();
+  return base::AdoptRef(new WebGPUMailboxTexture(
+      std::move(dawn_control_client), device, usage, mailbox, sync_token,
+      std::move(finished_access_callback)));
+}
+
 WebGPUMailboxTexture::WebGPUMailboxTexture(
     scoped_refptr<DawnControlClientHolder> dawn_control_client,
     WGPUDevice device,
-    StaticBitmapImage* image,
-    WGPUTextureUsage usage)
-    : dawn_control_client_(std::move(dawn_control_client)), device_(device) {
+    WGPUTextureUsage usage,
+    const gpu::Mailbox& mailbox,
+    const gpu::SyncToken& sync_token,
+    base::OnceCallback<void(const gpu::SyncToken&)> destroy_callback)
+    : dawn_control_client_(std::move(dawn_control_client)),
+      device_(device),
+      destroy_callback_(std::move(destroy_callback)) {
   dawn_control_client_->GetProcs().deviceReference(device_);
 
-  mailbox_ = image->GetMailboxHolder().mailbox;
+  gpu::webgpu::WebGPUInterface* webgpu = dawn_control_client_->GetInterface();
+
+  // Wait on any work using the image.
+  webgpu->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
 
   // Produce and inject image to WebGPU texture
-  gpu::webgpu::WebGPUInterface* webgpu = dawn_control_client_->GetInterface();
   gpu::webgpu::ReservedTexture reservation = webgpu->ReserveTexture(device_);
   DCHECK(reservation.texture);
 
@@ -32,7 +72,7 @@
   // representation.
   webgpu->AssociateMailbox(reservation.deviceId, reservation.deviceGeneration,
                            wire_texture_id_, wire_texture_generation_, usage,
-                           reinterpret_cast<GLbyte*>(&mailbox_));
+                           reinterpret_cast<const GLbyte*>(&mailbox));
 }
 
 WebGPUMailboxTexture::~WebGPUMailboxTexture() {
@@ -40,7 +80,12 @@
 
   gpu::webgpu::WebGPUInterface* webgpu = dawn_control_client_->GetInterface();
   webgpu->DissociateMailbox(wire_texture_id_, wire_texture_generation_);
-  mailbox_.SetZero();
+
+  if (destroy_callback_) {
+    gpu::SyncToken finished_access_token;
+    webgpu->GenUnverifiedSyncTokenCHROMIUM(finished_access_token.GetData());
+    std::move(destroy_callback_).Run(finished_access_token);
+  }
 
   dawn_control_client_->GetProcs().deviceRelease(device_);
 }
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.h b/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.h
index 6875816..73d181c 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.h
+++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.h
@@ -8,23 +8,32 @@
 #include <dawn/webgpu.h>
 
 #include "gpu/command_buffer/common/mailbox.h"
+#include "gpu/command_buffer/common/sync_token.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
 
 namespace blink {
 
+class CanvasResource;
 class DawnControlClientHolder;
 class StaticBitmapImage;
 
 class PLATFORM_EXPORT WebGPUMailboxTexture
     : public RefCounted<WebGPUMailboxTexture> {
  public:
-  WebGPUMailboxTexture(
+  static scoped_refptr<WebGPUMailboxTexture> FromStaticBitmapImage(
       scoped_refptr<DawnControlClientHolder> dawn_control_client,
       WGPUDevice device,
-      StaticBitmapImage* image,
-      WGPUTextureUsage usage);
+      WGPUTextureUsage usage,
+      scoped_refptr<StaticBitmapImage> image);
+
+  static scoped_refptr<WebGPUMailboxTexture> FromCanvasResource(
+      scoped_refptr<DawnControlClientHolder> dawn_control_client,
+      WGPUDevice device,
+      WGPUTextureUsage usage,
+      scoped_refptr<CanvasResource> canvas_resource);
+
   ~WebGPUMailboxTexture();
 
   WGPUTexture GetTexture() { return texture_; }
@@ -33,9 +42,17 @@
   WGPUDevice GetDeviceForTest() { return device_; }
 
  private:
+  WebGPUMailboxTexture(
+      scoped_refptr<DawnControlClientHolder> dawn_control_client,
+      WGPUDevice device,
+      WGPUTextureUsage usage,
+      const gpu::Mailbox& mailbox,
+      const gpu::SyncToken& sync_token,
+      base::OnceCallback<void(const gpu::SyncToken&)> destroy_callback);
+
   scoped_refptr<DawnControlClientHolder> dawn_control_client_;
-  gpu::Mailbox mailbox_;
   WGPUDevice device_;
+  base::OnceCallback<void(const gpu::SyncToken&)> destroy_callback_;
   WGPUTexture texture_;
   uint32_t wire_texture_id_ = 0;
   uint32_t wire_texture_generation_ = 0;
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc
index dedd99a..991dd8f1 100644
--- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc
+++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc
@@ -50,6 +50,9 @@
 class MockVideoDecoder : public media::VideoDecoder {
  public:
   std::string GetDisplayName() const override { return "MockVideoDecoder"; }
+  media::VideoDecoderType GetDecoderType() const override {
+    return media::VideoDecoderType::kUnknown;
+  }
   void Initialize(const media::VideoDecoderConfig& config,
                   bool low_delay,
                   media::CdmContext* cdm_context,
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter_test.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter_test.cc
index 01f48b0a..df6a8c6 100644
--- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter_test.cc
+++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_stream_adapter_test.cc
@@ -53,6 +53,9 @@
 class MockVideoDecoder : public media::VideoDecoder {
  public:
   std::string GetDisplayName() const override { return "MockVideoDecoder"; }
+  media::VideoDecoderType GetDecoderType() const override {
+    return media::VideoDecoderType::kUnknown;
+  }
   void Initialize(const media::VideoDecoderConfig& config,
                   bool low_delay,
                   media::CdmContext* cdm_context,
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index ab53d26..4c091de7 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1556,10 +1556,6 @@
       name: "PaymentRequestMerchantValidationEvent",
       status: "experimental",
     },
-    // Enables the correct behavior for show(): crbug.com/825270
-    {
-      name: "PaymentRequestShowConsumesUserActivation",
-    },
     {
       name: "PaymentRetry",
       status: "stable",
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
index 1ac5f4fd..56b3c6d 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -14,6 +14,9 @@
 #include "base/task/sequence_manager/lazy_now.h"
 #include "base/time/time.h"
 #include "base/trace_event/blame_context.h"
+#include "components/power_scheduler/power_mode.h"
+#include "components/power_scheduler/power_mode_arbiter.h"
+#include "components/power_scheduler/power_mode_voter.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h"
 #include "third_party/blink/public/platform/blame_context.h"
@@ -190,7 +193,10 @@
       waiting_for_meaningful_paint_(true,
                                     "FrameScheduler.WaitingForMeaningfulPaint",
                                     &tracing_controller_,
-                                    YesNoStateToString) {
+                                    YesNoStateToString),
+      loading_power_mode_voter_(
+          power_scheduler::PowerModeArbiter::GetInstance()->NewVoter(
+              "PowerModeVoter.Loading")) {
   frame_task_queue_controller_.reset(
       new FrameTaskQueueController(main_thread_scheduler_, this, this));
 }
@@ -611,9 +617,14 @@
   bool is_same_document = navigation_type == NavigationType::kSameDocument;
 
   if (!is_same_document) {
+    loading_power_mode_voter_->VoteFor(power_scheduler::PowerMode::kLoading);
+    loading_power_mode_voter_->ResetVoteAfterTimeout(
+        power_scheduler::PowerModeVoter::kLoadingTimeout);
+
     waiting_for_contentful_paint_ = true;
     waiting_for_meaningful_paint_ = true;
   }
+
   if (is_main_frame && !is_same_document) {
     task_time_ = base::TimeDelta();
     // Ignore result here, based on the assumption that
@@ -941,6 +952,8 @@
     // update.
     main_thread_scheduler_->OnMainFrameLoad(*this);
   }
+
+  loading_power_mode_voter_->VoteFor(power_scheduler::PowerMode::kIdle);
 }
 
 bool FrameSchedulerImpl::IsWaitingForContentfulPaint() const {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
index 7bb5a41..6d7cb41 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
@@ -18,6 +18,7 @@
 #include "base/single_thread_task_runner.h"
 #include "base/task/sequence_manager/task_queue.h"
 #include "base/trace_event/trace_event.h"
+#include "components/power_scheduler/power_mode_voter.h"
 #include "net/base/request_priority.h"
 #include "services/metrics/public/cpp/ukm_source_id.h"
 #include "third_party/blink/public/platform/task_type.h"
@@ -372,6 +373,8 @@
   TraceableState<bool, TracingCategoryName::kInfo>
       waiting_for_meaningful_paint_;
 
+  std::unique_ptr<power_scheduler::PowerModeVoter> loading_power_mode_voter_;
+
   // TODO(altimin): Remove after we have have 1:1 relationship between frames
   // and documents.
   base::WeakPtrFactory<FrameSchedulerImpl> document_bound_weak_factory_{this};
diff --git a/third_party/blink/renderer/platform/testing/empty_web_media_player.h b/third_party/blink/renderer/platform/testing/empty_web_media_player.h
index eca5bf03..bbc0aa4 100644
--- a/third_party/blink/renderer/platform/testing/empty_web_media_player.h
+++ b/third_party/blink/renderer/platform/testing/empty_web_media_player.h
@@ -40,8 +40,10 @@
   }
   WebTimeRanges Buffered() const override;
   WebTimeRanges Seekable() const override;
-  void SetSinkId(const WebString& sink_id,
-                 WebSetSinkIdCompleteCallback) override {}
+  bool SetSinkId(const WebString& sink_id,
+                 WebSetSinkIdCompleteCallback) override {
+    return false;
+  }
   bool HasVideo() const override { return false; }
   bool HasAudio() const override { return false; }
   gfx::Size NaturalSize() const override;
diff --git a/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc b/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc
index 01719e59..d00ca96 100644
--- a/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc
+++ b/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc
@@ -437,7 +437,7 @@
   auto* ri = scoped_context.RasterInterface();
   auto* gr_context = raster_context_provider->GrContext();
 
-  if (!ri || !gr_context) {
+  if (!ri) {
     return nullptr;
   }
 
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
index 5ae5b8b..ff23e48 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
+++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -713,6 +713,8 @@
 
 crbug.com/1074752 editing/selection/selection-color.html [ Failure ]
 
+crbug.com/1002937 external/wpt/editing/run/caret-navigation-around-line-break.html [ Failure ]
+
 crbug.com/1074752 external/wpt/css/css-pseudo/active-selection-051.html [ Failure ]
 crbug.com/1074752 external/wpt/css/css-pseudo/active-selection-052.html [ Failure ]
 crbug.com/1074752 external/wpt/css/css-pseudo/active-selection-053.html [ Failure ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index d7405bb6..4edad4b 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -2241,7 +2241,6 @@
 crbug.com/626703 external/wpt/uievents/order-of-events/focus-events/focus-contained-manual.html [ Skip ]
 crbug.com/626703 external/wpt/uievents/order-of-events/mouse-events/click-on-html-manual.html [ Skip ]
 crbug.com/626703 external/wpt/uievents/order-of-events/mouse-events/click-on-div-manual.html [ Skip ]
-crbug.com/626703 external/wpt/touch-events/multi-touch-interfaces-manual.html [ Skip ]
 crbug.com/626703 external/wpt/pointerevents/pointerevent_multiple_primary_pointers_boundary_events-manual.html [ Skip ]
 crbug.com/626703 external/wpt/uievents/order-of-events/mouse-events/click-order-manual.html [ Skip ]
 crbug.com/626703 external/wpt/uievents/order-of-events/mouse-events/mousemove-between-manual.html [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 30d58ad3..f5d56ad 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -380,6 +380,8 @@
 
 crbug.com/1042783 external/wpt/css/css-backgrounds/background-size/background-size-near-zero-png.html [ Failure ]
 crbug.com/1042783 external/wpt/css/css-backgrounds/background-size/background-size-near-zero-svg.html [ Failure ]
+crbug.com/935057 external/wpt/css/css-backgrounds/background-size-043.html [ Failure ]
+crbug.com/935057 external/wpt/css/css-backgrounds/background-size-044.html [ Failure ]
 
 # Fails, at a minimum, due to lack of support for CSS mask property in html elements
 crbug.com/432153 external/wpt/svg/painting/reftests/display-none-mask.html [ Skip ]
@@ -760,7 +762,6 @@
 crbug.com/1066577 external/wpt/css/css-lists/li-value-reversed-004.html [ Failure ]
 
 # [css-counter-styles-3]
-crbug.com/687225 fast/css/content-counter-large-negative-cjk.html [ Failure ]
 # Image symbols are not implemented yet
 crbug.com/687225 external/wpt/css/css-counter-styles/counter-style-prefix-suffix-syntax.html [ Failure ]
 crbug.com/687225 external/wpt/css/css-counter-styles/counter-style-symbols-syntax.html [ Failure ]
@@ -1220,6 +1221,12 @@
 crbug.com/995106 external/wpt/css/css-lists/inline-list-with-table-child.html [ Failure ]
 crbug.com/1012289 external/wpt/css/css-lists/list-style-type-string-005b.html [ Failure ]
 
+# css-pseudo
+crbug.com/1163437 external/wpt/css/css-pseudo/grammar-spelling-errors-001.html [ Failure ]
+crbug.com/1163437 external/wpt/css/css-pseudo/grammar-spelling-errors-002.html [ Failure ]
+crbug.com/1147859 external/wpt/css/css-pseudo/highlight-painting-001.html [ Failure ]
+crbug.com/1147859 external/wpt/css/css-pseudo/highlight-painting-002.html [ Failure ]
+crbug.com/1147859 external/wpt/css/css-pseudo/highlight-painting-003.html [ Failure ]
 crbug.com/995106 external/wpt/css/css-pseudo/first-letter-exclude-inline-marker.html [ Failure ]
 crbug.com/995106 external/wpt/css/css-pseudo/first-letter-exclude-inline-child-marker.html [ Failure ]
 crbug.com/1172333 external/wpt/css/css-pseudo/first-letter-digraph.html [ Failure ]
@@ -1242,6 +1249,22 @@
 crbug.com/1068610 external/wpt/css/css-color/predefined-006.html [ Failure ]
 crbug.com/1068610 external/wpt/css/css-color/predefined-009.html [ Failure ]
 crbug.com/1068610 external/wpt/css/css-color/predefined-010.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/a98rgb-001.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/a98rgb-002.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/a98rgb-003.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/a98rgb-004.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/lab-008.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/lch-008.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/prophoto-rgb-001.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/prophoto-rgb-002.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/prophoto-rgb-003.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/prophoto-rgb-004.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/prophoto-rgb-005.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/rec2020-001.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/rec2020-002.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/rec2020-003.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/rec2020-004.html [ Failure ]
+crbug.com/1068610 external/wpt/css/css-color/rec2020-005.html [ Failure ]
 
 # @supports
 crbug.com/1158554 external/wpt/css/css-conditional/css-supports-040.xht [ Failure ]
@@ -1412,8 +1435,6 @@
 
 crbug.com/860211 [ Mac ] external/wpt/editing/run/delete.html [ Failure ]
 
-crbug.com/1002937 external/wpt/editing/run/caret-navigation-around-line-break.html [ Failure ]
-
 crbug.com/821455 editing/pasteboard/drag-files-to-editable-element.html [ Failure ]
 
 crbug.com/1170052 external/wpt/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-audio-is-silence.https.html [ Pass Timeout ]
@@ -2538,45 +2559,7 @@
 crbug.com/626703 external/wpt/css/css-images/object-fit-none-svg-001e.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-images/object-fit-none-svg-003i.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-images/object-fit-fill-svg-002e.html [ Failure ]
-crbug.com/626703 virtual/composite-bgcolor-animation/external/wpt/css/css-backgrounds/background-size-043.html [ Failure ]
 crbug.com/626703 [ Mac10.13 ] external/wpt/webxr/xrSession_requestReferenceSpace_features.https.html [ Timeout ]
-crbug.com/626703 external/wpt/css/css-pseudo/grammar-spelling-errors-001.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-backgrounds/background-size-043.html [ Failure ]
-crbug.com/626703 virtual/composite-bgcolor-animation/external/wpt/css/css-backgrounds/background-size-044.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-backgrounds/background-size-044.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-pseudo/grammar-spelling-errors-002.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/rec2020-004.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/a98rgb-004.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/a98rgb-004.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/prophoto-rgb-003.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/rec2020-003.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/prophoto-rgb-001.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/lch-008.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/rec2020-005.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/prophoto-rgb-002.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/lab-008.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/a98rgb-001.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/prophoto-rgb-005.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/rec2020-001.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/rec2020-001.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/a98rgb-003.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/a98rgb-003.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/lab-008.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/rec2020-005.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/prophoto-rgb-003.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/rec2020-002.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/prophoto-rgb-004.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/lch-008.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/prophoto-rgb-004.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/a98rgb-001.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/rec2020-003.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/a98rgb-002.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/prophoto-rgb-002.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-color/rec2020-004.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/rec2020-002.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/prophoto-rgb-005.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/prophoto-rgb-001.html [ Failure ]
-crbug.com/626703 virtual/system-color-compute/external/wpt/css/css-color/a98rgb-002.html [ Failure ]
 crbug.com/626703 [ Mac10.15 ] external/wpt/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-screenx-screeny.html [ Timeout ]
 crbug.com/626703 [ Linux ] virtual/threaded/external/wpt/css/css-animations/nested-scale-animations.html [ Failure ]
 crbug.com/1014091 external/wpt/shadow-dom/focus/focus-pseudo-on-shadow-host-1.html [ Failure ]
@@ -3081,7 +3064,6 @@
 crbug.com/626703 external/wpt/html/browsers/history/joint-session-history/joint-session-history-remove-iframe.html [ Timeout ]
 crbug.com/626703 external/wpt/css/css-fonts/font-variant-descriptor-01.html [ Failure ]
 crbug.com/626703 [ Win7 ] external/wpt/css/css-fonts/variations/font-opentype-collections.html [ Timeout ]
-crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping.html [ Failure ]
 crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/disclosure-styles.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-fonts/font-variant-05.xht [ Failure ]
 crbug.com/626703 external/wpt/css/css-fonts/font-variant-06.xht [ Failure ]
@@ -5649,11 +5631,6 @@
 # Sheriff 2021-01-13
 crbug.com/1164459 [ Mac10.15 ] external/wpt/preload/download-resources.html [ Pass Failure ]
 
-# CSS spelling and grammar features (issue 1163437)
-crbug.com/1147859 external/wpt/css/css-pseudo/highlight-painting-001.html [ Failure ]
-crbug.com/1147859 external/wpt/css/css-pseudo/highlight-painting-002.html [ Failure ]
-crbug.com/1147859 external/wpt/css/css-pseudo/highlight-painting-003.html [ Failure ]
-
 # Sheriff 2021-01-15
 crbug.com/1167222 http/tests/websocket/multiple-connections-throttled.html [ Pass Failure ]
 crbug.com/1167309 fast/canvas/canvas-createImageBitmap-drawImage.html [ Pass Failure ]
@@ -5697,5 +5674,11 @@
 crbug.com/1060837 external/wpt/html/cross-origin-embedder-policy/reporting-to-owner.https.html [ Timeout ]
 crbug.com/1060837 virtual/plz-dedicated-worker/external/wpt/html/cross-origin-embedder-policy/reporting-to-owner.https.html [ Pass ]
 
+# flaky test
+crbug.com/1173956 http/tests/xsl/xslt-transform-with-javascript-disabled.html [ Failure Pass ]
+
 # Failing on Webkit Linux Leak
 crbug.com/1174806 external/wpt/css/selectors/focus-visible-006.html [ Pass Failure ]
+
+# Timing out on Fuchsia
+crbug.com/1171283 [ Fuchsia ] virtual/threaded/synthetic_gestures/synthetic-pinch-zoom-gesture-touchscreen-zoom-out-slow.html [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/editing/input/cached-text-input-memory-leak.html b/third_party/blink/web_tests/editing/input/cached-text-input-memory-leak.html
new file mode 100644
index 0000000..4f5498bd
--- /dev/null
+++ b/third_party/blink/web_tests/editing/input/cached-text-input-memory-leak.html
@@ -0,0 +1,35 @@
+<html>
+<head>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../../resources/testdriver.js"></script>
+<script src="../../resources/testdriver-vendor.js"></script>
+<title>This tests the memory leak issue in CachedTextInputInfo</title>
+</head>
+<body>
+<div class="App" id="app"></div>
+<span id="app1">
+    How to repro:<br/>
+    1. Click on this page before the "Watch me leak!" text disappears.<br/>
+    2. Once the text disappears, without clicking anywhere else, take a heap snapshot.<br/>
+</span>
+<script>
+promise_test(async () => {
+  document.addEventListener("selectionchange", e => {
+      var app = document.getElementById("app");
+      var header = document.getElementById("header");
+      app.removeChild(header);
+  });
+  var app = document.getElementById("app");
+  var header = document.createElement("h1");
+  header.id = "header";
+  header.innerHTML = "Watch me leak!";
+  app.appendChild(header);
+  var app1 = document.getElementById("app1");
+  await test_driver.click(app1);
+  assert_equals(document.activeElement, document.body, 'activeElement');
+  assert_equals(app.firstChild, null, 'child');
+}, 'Removing an element after clicking textnodes shouldn\'t cause memory leaks');
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/editing/inserting/insert_html_text_align_start.html b/third_party/blink/web_tests/editing/inserting/insert_html_text_align_start.html
new file mode 100644
index 0000000..771b6f3
--- /dev/null
+++ b/third_party/blink/web_tests/editing/inserting/insert_html_text_align_start.html
@@ -0,0 +1,93 @@
+<!doctype html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../assert_selection.js"></script>
+<script>
+// <div dir="ltr">
+selection_test(
+    '<div contenteditable dir="ltr">|</div>',
+    'insertHTML <p dir="ltr" style="text-align:left"></p>',
+    '<div contenteditable dir="ltr">|<p dir="ltr"></p></div>',
+    'ltr:start ltr:left, text-align of <p> is redundant');
+selection_test(
+    '<div contenteditable dir="ltr">|</div>',
+    'insertHTML <p dir="ltr" style="text-align:right"></p>',
+    '<div contenteditable dir="ltr">|<p dir="ltr" style="text-align:right"></p></div>',
+    'ltr:start ltr:right');
+selection_test(
+    '<div contenteditable dir="ltr">|</div>',
+    'insertHTML <p dir="rtl" style="text-align:left"></p>',
+    '<div contenteditable dir="ltr">|<p dir="rtl" style="text-align:left"></p></div>',
+    'ltr:start rtl:left');
+selection_test(
+    '<div contenteditable dir="ltr">|</div>',
+    'insertHTML <p dir="rtl" style="text-align:right"></p>',
+    '<div contenteditable dir="ltr">|<p dir="rtl"></p></div>',
+    'ltr:start rtl:right');
+
+// <div dir="rtl">
+selection_test(
+    '<div contenteditable dir="rtl">|</div>',
+    'insertHTML <p dir="ltr" style="text-align:left"></p>',
+    '<div contenteditable dir="rtl">|<p dir="ltr"></p></div>',
+    'rtl:start ltr:left, text-align of <p> is redundant');
+selection_test(
+    '<div contenteditable dir="rtl">|</div>',
+    'insertHTML <p dir="ltr" style="text-align:right"></p>',
+    '<div contenteditable dir="rtl">|<p dir="ltr" style="text-align:right"></p></div>',
+    'rtl:start ltr:right');
+selection_test(
+    '<div contenteditable dir="rtl">|</div>',
+    'insertHTML <p dir="rtl" style="text-align:left"></p>',
+    '<div contenteditable dir="rtl">|<p dir="rtl" style="text-align:left"></p></div>',
+    'rtl:start rtl:left');
+selection_test(
+    '<div contenteditable dir="rtl">|</div>',
+    'insertHTML <p dir="rtl" style="text-align:right"></p>',
+    '<div contenteditable dir="rtl">|<p dir="rtl"></p></div>',
+    'rtl:start rtl:right');
+
+// <div dir="ltr>", <p style="text-align:start">
+selection_test(
+    '<div contenteditable dir="ltr" style="text-align:left">|</div>',
+    'insertHTML <p dir="ltr" style="text-align:start"></p>',
+    '<div contenteditable dir="ltr" style="text-align:left">|<p dir="ltr"></p></div>',
+    'ltr:left ltr:start, text-align of <p> is redundant');
+selection_test(
+    '<div contenteditable dir="ltr" style="text-align:left">|</div>',
+    'insertHTML <p dir="rtl" style="text-align:start"></p>',
+    '<div contenteditable dir="ltr" style="text-align:left">|<p dir="rtl" style="text-align:start"></p></div>',
+    'ltr:left rtl:start');
+selection_test(
+    '<div contenteditable dir="ltr" style="text-align:right">|</div>',
+    'insertHTML <p dir="ltr" style="text-align:start"></p>',
+    '<div contenteditable dir="ltr" style="text-align:right">|<p dir="ltr" style="text-align:start"></p></div>',
+    'ltr:right ltr:start');
+selection_test(
+    '<div contenteditable dir="ltr" style="text-align:right">|</div>',
+    'insertHTML <p dir="rtl" style="text-align:start"></p>',
+    '<div contenteditable dir="ltr" style="text-align:right">|<p dir="rtl"></p></div>',
+    'ltr:right rtl:start, text-align of <p> is redundant');
+
+// <div dir="rtl>", <p style="text-align:start">
+selection_test(
+    '<div contenteditable dir="rtl" style="text-align:left">|</div>',
+    'insertHTML <p dir="ltr" style="text-align:start"></p>',
+    '<div contenteditable dir="rtl" style="text-align:left">|<p dir="ltr"></p></div>',
+    'rtl:left ltr:start, text-align of <p> is redundant');
+selection_test(
+    '<div contenteditable dir="rtl" style="text-align:left">|</div>',
+    'insertHTML <p dir="rtl" style="text-align:start"></p>',
+    '<div contenteditable dir="rtl" style="text-align:left">|<p dir="rtl" style="text-align:start"></p></div>',
+    'rtl:left rtl:start');
+selection_test(
+    '<div contenteditable dir="rtl" style="text-align:right">|</div>',
+    'insertHTML <p dir="ltr" style="text-align:start"></p>',
+    '<div contenteditable dir="rtl" style="text-align:right">|<p dir="ltr" style="text-align:start"></p></div>',
+    'rtl:right ltr:start');
+selection_test(
+    '<div contenteditable dir="rtl" style="text-align:right">|</div>',
+    'insertHTML <p dir="rtl" style="text-align:start"></p>',
+    '<div contenteditable dir="rtl" style="text-align:right">|<p dir="rtl"></p></div>',
+    'rtl:right rtl:start, text-align of <p> is redundant');
+</script>
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 c8263ed..a37e933 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
@@ -182286,6 +182286,12 @@
       []
      ]
     },
+    "plugin-types": {
+     "plugin-types-ignored.html.sub.headers": [
+      "5508935fff4bf3c2d15f0de35a0efb43da595910",
+      []
+     ]
+    },
     "prefetch-src": {
      "prefetch-header-allowed.html.headers": [
       "2b1d42a8d16c04cf339366b05262c27516e4196c",
@@ -224296,7 +224302,7 @@
       []
      ],
      "justifyleft_2001-last-expected.txt": [
-      "d23a057b64b156408f3a66ff90a02a10308ae265",
+      "248e4286b4235bb9f1e0a4fdedacb132a9548fc2",
       []
      ],
      "justifyright_1-1000-expected.txt": [
@@ -251340,7 +251346,7 @@
       []
      ],
      "webxr-test.js": [
-      "2846adda6ab414a8593a4c83dc4dbe082adcb62b",
+      "e3b21fb720af82c479d8b1547a5c420eceeb004d",
       []
      ],
      "webxr-test.js.headers": [
@@ -263142,11 +263148,11 @@
       []
      ],
      "webxr_math_utils.js": [
-      "bb55fb72978690427aac38b84d1eac24e838d0eb",
+      "54a61c185469c1c4472a72f5816e6fe05562af83",
       []
      ],
      "webxr_test_asserts.js": [
-      "38f1364ce03ce96890cda97dcc226b8e472dd332",
+      "a82f7aaf90aabb8a49b9f10aa0d50ba795d798fe",
       []
      ],
      "webxr_test_constants.js": [
@@ -285519,6 +285525,15 @@
       ]
      ]
     },
+    "plugin-types": {
+     "plugin-types-ignored.html": [
+      "cf27cdfc54b31aa12c0f5718a85ab6e956e70093",
+      [
+       null,
+       {}
+      ]
+     ]
+    },
     "prefetch-src": {
      "prefetch-allowed.html": [
       "95177c13064b024b362b1b6ba9528f878024ee36",
@@ -344477,6 +344492,15 @@
       ]
      ]
     },
+    "redirects": {
+     "data.window.js": [
+      "eeb41966b447cd58b7f124176a07664e91d2d3c6",
+      [
+       "fetch/redirects/data.window.html",
+       {}
+      ]
+     ]
+    },
     "security": {
      "dangling-markup-mitigation-data-url.tentative.sub.html": [
       "f27735daa1dd650726525d72a48b91d58d62535b",
@@ -446891,14 +446915,14 @@
       ]
      ],
      "ar_hittest_subscription_inputSources.https.html": [
-      "dcd1d717883367fc8f01f49864621be913fb3850",
+      "ca92d390fc6c913410b10fd2c656f544ac1e5317",
       [
        null,
        {}
       ]
      ],
      "ar_hittest_subscription_refSpaces.https.html": [
-      "465e16110394600c6ffaefdd23cb58958411bd02",
+      "a30e71949c9d6af6c81f1095b90c27a899b0b3f3",
       [
        null,
        {}
@@ -446919,7 +446943,7 @@
       ]
      ],
      "ar_hittest_subscription_transientInputSources.https.html": [
-      "04df13240668c2513ccb01975259919cc95438e9",
+      "9e0347963c64fb1d481d23f6d8b6249274dcd7f7",
       [
        null,
        {}
@@ -447232,7 +447256,7 @@
      ]
     ],
     "xrRigidTransform_inverse.https.html": [
-     "cd5b34583b3a152879ad6d559a3c3098357630b8",
+     "d4fdc15396d25223ab07d473a0039434b4c58761",
      [
       null,
       {}
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/plugin-types/plugin-types-ignored.html b/third_party/blink/web_tests/external/wpt/content-security-policy/plugin-types/plugin-types-ignored.html
new file mode 100644
index 0000000..cf27cdfc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/content-security-policy/plugin-types/plugin-types-ignored.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+</head>
+
+<body>
+  <!-- Test that the old CSP directive 'plugin-types' has no effect anymore -->
+  <object type="application/pdf"></object>
+  <!-- we rely on the report because we can't rely on the onload event for
+         "allowed" tests as it is not fired for object and embed -->
+   <script async defer src='../support/checkReport.sub.js?reportExists=false'></script>
+</body>
+
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/plugin-types/plugin-types-ignored.html.sub.headers b/third_party/blink/web_tests/external/wpt/content-security-policy/plugin-types/plugin-types-ignored.html.sub.headers
new file mode 100644
index 0000000..5508935f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/content-security-policy/plugin-types/plugin-types-ignored.html.sub.headers
@@ -0,0 +1,6 @@
+Expires: Mon, 26 Jul 1997 05:00:00 GMT
+Cache-Control: no-store, no-cache, must-revalidate
+Cache-Control: post-check=0, pre-check=0, false
+Pragma: no-cache
+Set-Cookie: plugin-types-ignored={{$id:uuid()}}; Path=/content-security-policy/plugin-types/
+Content-Security-Policy: plugin-types application/x-shockwave-flash; report-uri ../support/report.py?op=put&reportID={{$id}}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/no-room-for-line-in-first-fragmentainer-crash.html b/third_party/blink/web_tests/external/wpt/css/css-break/no-room-for-line-in-first-fragmentainer-crash.html
new file mode 100644
index 0000000..bc7b9aaa
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/no-room-for-line-in-first-fragmentainer-crash.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1175666">
+<div style="width:500px; columns:3; column-fill:auto; height:100px; line-height:100px;">
+  <div style="padding-top:50px;">
+    <canvas style="float:left; width:200px; height:100px;"></canvas>
+    <span style="display:inline-block; width:100px; height:10px;"></span>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/crashtests/dialog-table-crash.html b/third_party/blink/web_tests/external/wpt/css/css-tables/crashtests/dialog-table-crash.html
new file mode 100644
index 0000000..decc3eb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-tables/crashtests/dialog-table-crash.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<link rel="help" href="https://crbug.com/1175425">
+
+<div id="container" style="border-collapse:collapse;">
+  <div id="insertBefore"></div>
+  <div style="display:table-row-group;"></div>
+  <div id="victim" style="border:solid; display:table-row-group;">
+    <div style="display:table-cell;"></div>
+  </div>
+</div>
+
+<script>
+  document.body.offsetTop;
+  container.insertBefore(insertBefore, victim)
+</script>
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/crashtests/uninitialized_read_crash.html b/third_party/blink/web_tests/external/wpt/css/css-tables/crashtests/uninitialized_read_crash.html
new file mode 100644
index 0000000..5aa3b22
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-tables/crashtests/uninitialized_read_crash.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<link rel="help" href="https://crbug.com/1172819">
+
+<table style="height:69080px;width:100px;background: blue;border-spacing:2px;">
+
+<thead style="height:400%">
+  <tr style="height:18px"></tr>
+</thead>
+<tbody>
+  <tr style="height: 2712px"></tr>
+</tbody>
+<tbody>
+  <tr style="height: 1694px"></tr>
+</tbody>
+<tbody>
+  <tr style="height: 6436px"></tr>
+</tbody>
+</table>
diff --git a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping-ref.html b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping-ref.html
index 3924851..744aa328 100644
--- a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping-ref.html
@@ -17,24 +17,8 @@
 </style>
 <ul class="triangle"><li></ul>
 <ul class="triangle"><li></ul>
-<ul class="triangle"><li></ul>
-<ul class="hiragana"><li></ul>
-<ul class="katakana"><li></ul>
-<ul class="hiragana-iroha"><li></ul>
-<ul class="katakana-iroha"><li></ul>
-<ul class="hiragana"><li></ul>
-<ul class="katakana"><li></ul>
-<ul class="hiragana-iroha"><li></ul>
-<ul class="katakana-iroha"><li></ul>
 
 <ol><li></ol>
-<ol class="triangle"><li></ol>
-<ol class="triangle"><li></ol>
-<ol class="triangle"><li></ol>
-<ol class="hiragana"><li></ol>
-<ol class="katakana"><li></ol>
-<ol class="hiragana-iroha"><li></ol>
-<ol class="katakana-iroha"><li></ol>
 <ol class="hiragana"><li></ol>
 <ol class="katakana"><li></ol>
 <ol class="hiragana-iroha"><li></ol>
@@ -43,7 +27,6 @@
 <ul>
   <li class="triangle">
   <li class="triangle">
-  <li class="triangle">
   <li class="hiragana">
   <li class="katakana">
   <li class="hiragana-iroha">
diff --git a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping.html b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping.html
index 1e3fcfc..6c53b42 100644
--- a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping.html
+++ b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping.html
@@ -34,33 +34,16 @@
   }
 </style>
 <ul type="circle"><li></ul>
-<ul type="round"><li></ul>
 <ul type="square"><li></ul>
-<ul type="i"><li></ul>
-<ul type="I"><li></ul>
-<ul type="a"><li></ul>
-<ul type="A"><li></ul>
-<ul type="lower-roman"><li></ul>
-<ul type="upper-roman"><li></ul>
-<ul type="lower-alpha"><li></ul>
-<ul type="upper-alpha"><li></ul>
 
 <ol><li></ol>
-<ol type="circle"><li></ol>
-<ol type="round"><li></ol>
-<ol type="square"><li></ol>
 <ol type="i"><li></ol>
 <ol type="I"><li></ol>
 <ol type="a"><li></ol>
 <ol type="A"><li></ol>
-<ol type="lower-roman"><li></ol>
-<ol type="upper-roman"><li></ol>
-<ol type="lower-alpha"><li></ol>
-<ol type="upper-alpha"><li></ol>
 
 <ul>
   <li type="circle">
-  <li type="round">
   <li type="square">
   <li type="i">
   <li type="I">
diff --git a/third_party/blink/web_tests/external/wpt/editing/run/justifyleft_2001-last-expected.txt b/third_party/blink/web_tests/external/wpt/editing/run/justifyleft_2001-last-expected.txt
index d23a057b6..248e4286b 100644
--- a/third_party/blink/web_tests/external/wpt/editing/run/justifyleft_2001-last-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/editing/run/justifyleft_2001-last-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 447 tests; 366 PASS, 81 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 447 tests; 372 PASS, 75 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:left>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra" queryCommandIndeterm("defaultparagraphseparator") before
 PASS [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:left>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra" queryCommandState("defaultparagraphseparator") before
 FAIL [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:left>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra" queryCommandValue("defaultparagraphseparator") before assert_equals: Wrong result returned expected "p" but got "div"
@@ -241,7 +241,7 @@
 PASS [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra": execCommand("defaultparagraphseparator", false, "div") return value
 PASS [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra": execCommand("justifyleft", false, "") return value
 PASS [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" checks for modifications to non-editable content
-FAIL [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "foo<p>extra</p>" but got "<div style=\"text-align:end\">foo</div><p>extra</p>"
+FAIL [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "foo<p>extra</p>" but got "<div style=\"text-align:left\">foo</div><p>extra</p>"
 PASS [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("stylewithcss") before
 PASS [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("stylewithcss") before
 PASS [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("stylewithcss") before
@@ -255,8 +255,8 @@
 PASS [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("defaultparagraphseparator") after
 PASS [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("defaultparagraphseparator") after
 PASS [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyleft") before
-FAIL [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") before assert_equals: Wrong result returned expected false but got true
-FAIL [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") before assert_equals: Wrong result returned expected "right" but got "true"
+PASS [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") before
+FAIL [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") before assert_equals: Wrong result returned expected "right" but got "false"
 PASS [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyleft") after
 PASS [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") after
 FAIL [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") after assert_equals: Wrong result returned expected "left" but got "true"
@@ -264,7 +264,7 @@
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra": execCommand("defaultparagraphseparator", false, "div") return value
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra": execCommand("justifyleft", false, "") return value
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" checks for modifications to non-editable content
-FAIL [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "foo<p>extra</p>" but got "<div style=\"text-align:end\">foo</div><p>extra</p>"
+FAIL [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "foo<p>extra</p>" but got "<div style=\"text-align:left\">foo</div><p>extra</p>"
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("stylewithcss") before
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("stylewithcss") before
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("stylewithcss") before
@@ -278,8 +278,8 @@
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("defaultparagraphseparator") after
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("defaultparagraphseparator") after
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyleft") before
-FAIL [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") before assert_equals: Wrong result returned expected false but got true
-FAIL [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") before assert_equals: Wrong result returned expected "right" but got "true"
+PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") before
+FAIL [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") before assert_equals: Wrong result returned expected "right" but got "false"
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyleft") after
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") after
 FAIL [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") after assert_equals: Wrong result returned expected "left" but got "true"
@@ -287,7 +287,7 @@
 PASS [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra": execCommand("defaultparagraphseparator", false, "p") return value
 PASS [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra": execCommand("justifyleft", false, "") return value
 PASS [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" checks for modifications to non-editable content
-FAIL [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "foo<p>extra</p>" but got "<div style=\"text-align:end\">foo</div><p>extra</p>"
+FAIL [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "foo<p>extra</p>" but got "<div style=\"text-align:left\">foo</div><p>extra</p>"
 PASS [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("stylewithcss") before
 PASS [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("stylewithcss") before
 PASS [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("stylewithcss") before
@@ -301,8 +301,8 @@
 PASS [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("defaultparagraphseparator") after
 PASS [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("defaultparagraphseparator") after
 PASS [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyleft") before
-FAIL [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") before assert_equals: Wrong result returned expected false but got true
-FAIL [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") before assert_equals: Wrong result returned expected "right" but got "true"
+PASS [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") before
+FAIL [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") before assert_equals: Wrong result returned expected "right" but got "false"
 PASS [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyleft") after
 PASS [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") after
 FAIL [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") after assert_equals: Wrong result returned expected "left" but got "true"
@@ -310,7 +310,7 @@
 PASS [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra": execCommand("defaultparagraphseparator", false, "p") return value
 PASS [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra": execCommand("justifyleft", false, "") return value
 PASS [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" checks for modifications to non-editable content
-FAIL [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "foo<p>extra</p>" but got "<div style=\"text-align:end\">foo</div><p>extra</p>"
+FAIL [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "foo<p>extra</p>" but got "<div style=\"text-align:left\">foo</div><p>extra</p>"
 PASS [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("stylewithcss") before
 PASS [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("stylewithcss") before
 PASS [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("stylewithcss") before
@@ -324,8 +324,8 @@
 PASS [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("defaultparagraphseparator") after
 PASS [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("defaultparagraphseparator") after
 PASS [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyleft") before
-FAIL [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") before assert_equals: Wrong result returned expected false but got true
-FAIL [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") before assert_equals: Wrong result returned expected "right" but got "true"
+PASS [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") before
+FAIL [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") before assert_equals: Wrong result returned expected "right" but got "false"
 PASS [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyleft") after
 PASS [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") after
 FAIL [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") after assert_equals: Wrong result returned expected "left" but got "true"
@@ -364,7 +364,7 @@
 PASS [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra": execCommand("defaultparagraphseparator", false, "div") return value
 PASS [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra": execCommand("justifyleft", false, "") return value
 PASS [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" checks for modifications to non-editable content
-FAIL [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div style=\"text-align:left\"><div dir=\"rtl\">foo</div></div><p>extra</p>" but got "<div dir=\"rtl\" style=\"text-align:left\">foo</div><p>extra</p>"
+FAIL [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div style=\"text-align:left\"><div dir=\"rtl\">foo</div></div><p>extra</p>" but got "<div dir=\"rtl\" style=\"text-align:end\">foo</div><p>extra</p>"
 PASS [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("defaultparagraphseparator") before
 PASS [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("defaultparagraphseparator") before
 PASS [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("defaultparagraphseparator") before
@@ -372,15 +372,15 @@
 PASS [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("defaultparagraphseparator") after
 PASS [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("defaultparagraphseparator") after
 PASS [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyleft") before
-FAIL [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") before assert_equals: Wrong result returned expected true but got false
-FAIL [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") before assert_equals: Wrong result returned expected "left" but got "false"
+PASS [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") before
+FAIL [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") before assert_equals: Wrong result returned expected "left" but got "true"
 PASS [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyleft") after
 PASS [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") after
 FAIL [["defaultparagraphseparator","div"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") after assert_equals: Wrong result returned expected "left" but got "true"
 PASS [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra": execCommand("defaultparagraphseparator", false, "p") return value
 PASS [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra": execCommand("justifyleft", false, "") return value
 PASS [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" checks for modifications to non-editable content
-FAIL [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div style=\"text-align:left\"><div dir=\"rtl\">foo</div></div><p>extra</p>" but got "<div dir=\"rtl\" style=\"text-align:left\">foo</div><p>extra</p>"
+FAIL [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div style=\"text-align:left\"><div dir=\"rtl\">foo</div></div><p>extra</p>" but got "<div dir=\"rtl\" style=\"text-align:end\">foo</div><p>extra</p>"
 PASS [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("defaultparagraphseparator") before
 PASS [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("defaultparagraphseparator") before
 PASS [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("defaultparagraphseparator") before
@@ -388,8 +388,8 @@
 PASS [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("defaultparagraphseparator") after
 PASS [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("defaultparagraphseparator") after
 PASS [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyleft") before
-FAIL [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") before assert_equals: Wrong result returned expected true but got false
-FAIL [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") before assert_equals: Wrong result returned expected "left" but got "false"
+PASS [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") before
+FAIL [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") before assert_equals: Wrong result returned expected "left" but got "true"
 PASS [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyleft") after
 PASS [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyleft") after
 FAIL [["defaultparagraphseparator","p"],["justifyleft",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyleft") after assert_equals: Wrong result returned expected "left" but got "true"
diff --git a/third_party/blink/web_tests/external/wpt/fetch/redirects/data.window.js b/third_party/blink/web_tests/external/wpt/fetch/redirects/data.window.js
new file mode 100644
index 0000000..eeb41966
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fetch/redirects/data.window.js
@@ -0,0 +1,25 @@
+// See ../api/redirect/redirect-to-dataurl.any.js for fetch() tests
+
+async_test(t => {
+  const img = document.createElement("img");
+  img.onload = t.unreached_func();
+  img.onerror = t.step_func_done();
+  img.src = "../api/resources/redirect.py?location=data:image/png%3Bbase64,iVBORw0KGgoAAAANSUhEUgAAAIUAAABqCAIAAAAdqgU8AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAF6SURBVHhe7dNBDQAADIPA%2Bje92eBxSQUQSLedlQzo0TLQonFWPVoGWjT%2BoUfLQIvGP/RoGWjR%2BIceLQMtGv/Qo2WgReMferQMtGj8Q4%2BWgRaNf%2BjRMtCi8Q89WgZaNP6hR8tAi8Y/9GgZaNH4hx4tAy0a/9CjZaBF4x96tAy0aPxDj5aBFo1/6NEy0KLxDz1aBlo0/qFHy0CLxj/0aBlo0fiHHi0DLRr/0KNloEXjH3q0DLRo/EOPloEWjX/o0TLQovEPPVoGWjT%2BoUfLQIvGP/RoGWjR%2BIceLQMtGv/Qo2WgReMferQMtGj8Q4%2BWgRaNf%2BjRMtCi8Q89WgZaNP6hR8tAi8Y/9GgZaNH4hx4tAy0a/9CjZaBF4x96tAy0aPxDj5aBFo1/6NEy0KLxDz1aBlo0/qFHy0CLxj/0aBlo0fiHHi0DLRr/0KNloEXjH3q0DLRo/EOPloEWjX/o0TLQovEPPVoGWjT%2BoUfLQIvGP/RoGWjR%2BIceJQMPIOzeGc0PIDEAAAAASUVORK5CYII";
+}, "<img> fetch that redirects to data: URL");
+
+globalThis.globalTest = null;
+async_test(t => {
+  globalThis.globalTest = t;
+  const script = document.createElement("script");
+  script.src = "../api/resources/redirect.py?location=data:text/javascript,(globalThis.globalTest.unreached_func())()";
+  script.onerror = t.step_func_done();
+  document.body.append(script);
+}, "<script> fetch that redirects to data: URL");
+
+async_test(t => {
+  const client = new XMLHttpRequest();
+  client.open("GET", "../api/resources/redirect.py?location=data:,");
+  client.send();
+  client.onload = t.unreached_func();
+  client.onerror = t.step_func_done();
+}, "XMLHttpRequest fetch that redirects to data: URL");
diff --git a/third_party/blink/web_tests/external/wpt/touch-events/multi-touch-interfaces-manual.html b/third_party/blink/web_tests/external/wpt/touch-events/multi-touch-interfaces-manual.html
deleted file mode 100644
index e9f1b91..0000000
--- a/third_party/blink/web_tests/external/wpt/touch-events/multi-touch-interfaces-manual.html
+++ /dev/null
@@ -1,274 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-     Test cases for Touch Events v1 Recommendation
-     http://www.w3.org/TR/touch-events/
-
-     These tests are based on Mozilla-Nokia-Google's single-touch
-     tests and to some extent Olli Pettay's multi-touch tests.
-
-     The primary purpose of the tests in this document is checking that the
-     various interfaces of the Touch Events APIs are correctly implemented.
-     Other interactions are covered in other test files.
-
-     This document references Test Assertions (abbrev TA below) written by Cathy Chan
-     http://www.w3.org/2010/webevents/wiki/TestAssertions
--->
-
-<head>
-<title>Touch Events Multi-Touch Interface Tests</title>
-<meta name="viewport" content="width=device-width">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-    setup({explicit_done: true});
-
-    // Check a Touch object's atttributes for existence and correct type
-    // TA: 1.1.2, 1.1.3
-    function check_Touch_object (t) {
-        test(function() {
-           assert_equals(Object.prototype.toString.call(t), "[object Touch]", "touch is of type Touch");
-        }, "touch point is a Touch object");
-        [
-          ["long", "identifier"],
-          ["EventTarget", "target"],
-          ["long", "screenX"],
-          ["long", "screenY"],
-          ["long", "clientX"],
-          ["long", "clientY"],
-          ["long", "pageX"],
-          ["long", "pageY"],
-        ].forEach(function(attr) {
-            var type = attr[0];
-            var name = attr[1];
-
-            // existence check
-            test(function() {
-                assert_true(name in t, name + " attribute in Touch object");
-            }, "Touch." + name + " attribute exists");
-
-            // type check
-            switch(type) {
-            case "long":
-                test(function() {
-                    assert_equals(typeof t[name], "number", name + " attribute of type long");
-                }, "Touch." + name + " attribute is of type number (long)");
-                break;
-            case "EventTarget":
-                // An event target is some type of Element
-                test(function() {
-                    assert_true(t[name] instanceof Element, "EventTarget must be an Element.");
-                }, "Touch." + name + " attribute is of type Element");
-                break;
-            default:
-                break;
-            }
-       });
-    }
-
-    // Check a TouchList object's attributes and methods for existence and proper type
-    // Also make sure all of the members of the list are Touch objects
-    // TA: 1.2.1, 1.2.2, 1.2.5, 1.2.6
-    function check_TouchList_object (tl) {
-        test(function() {
-           assert_equals(Object.prototype.toString.call(tl), "[object TouchList]", "touch list is of type TouchList");
-        }, "touch list is a TouchList object");
-        [
-          ["unsigned long", "length"],
-          ["function", "item"],
-        ].forEach(function(attr) {
-            var type = attr[0];
-            var name = attr[1];
-
-            // existence check
-            test(function() {
-                assert_true(name in tl, name + " attribute in TouchList");
-            }, "TouchList." + name + " attribute exists");
-
-            // type check
-            switch(type) {
-            case "unsigned long":
-                test(function() {
-                    assert_equals(typeof tl[name], "number", name + " attribute of type long");
-                }, "TouchList." + name + " attribute is of type number (unsigned long)");
-                break;
-            case "function":
-                test(function() {
-                    assert_equals(typeof tl[name], "function", name + " attribute of type function");
-                }, "TouchList." + name + " attribute is of type function");
-                break;
-            default:
-                break;
-            }
-       });
-       // Each member of tl should be a proper Touch object
-       for (var i=0; i < tl.length; i++) {
-           check_Touch_object(tl.item(i));
-       }
-    }
-
-    // Check a TouchEvent event's attributes for existence and proper type
-    // Also check that each of the event's TouchList objects are valid
-    // TA: 1.{3,4,5}.1.1, 1.{3,4,5}.1.2
-    function check_TouchEvent(ev) {
-        test(function() {
-           assert_true(ev instanceof TouchEvent, "event is a TouchEvent event");
-        }, ev.type + " event is a TouchEvent event");
-        [
-          ["TouchList", "touches"],
-          ["TouchList", "targetTouches"],
-          ["TouchList", "changedTouches"],
-          ["boolean", "altKey"],
-          ["boolean", "metaKey"],
-          ["boolean", "ctrlKey"],
-          ["boolean", "shiftKey"],
-        ].forEach(function(attr) {
-            var type = attr[0];
-            var name = attr[1];
-
-            // existence check
-            test(function() {
-                assert_true(name in ev, name + " attribute in " + ev.type + " event");
-            }, ev.type + "." + name + " attribute exists");
-
-            // type check
-            switch(type) {
-            case "boolean":
-                test(function() {
-                    assert_equals(typeof ev[name], "boolean", name + " attribute of type boolean");
-                }, ev.type + "." + name + " attribute is of type boolean");
-                break;
-            case "TouchList":
-                test(function() {
-                    assert_equals(Object.prototype.toString.call(ev[name]), "[object TouchList]", name + " attribute of type TouchList");
-                }, ev.type + "." + name + " attribute is of type TouchList");
-                // Now check the validity of the TouchList
-                check_TouchList_object(ev[name]);
-                break;
-            default:
-                break;
-            }
-        });
-    }
-
-    function is_touch_over_element(touch, element) {
-        var bounds = element.getBoundingClientRect();
-        return touch.pageX >= bounds.left && touch.pageX <= bounds.right &&
-               touch.pageY >= bounds.top && touch.pageY <= bounds.bottom;
-    }
-
-    function check_touch_clientXY(touch) {
-        assert_equals(touch.clientX, touch.pageX - window.pageXOffset, "touch.clientX is touch.pageX - window.pageXOffset.");
-        assert_equals(touch.clientY, touch.pageY - window.pageYOffset, "touch.clientY is touch.pageY - window.pageYOffset.");
-    }
-
-    function run() {
-        var target0 = document.getElementById("target0");
-        var target1 = document.getElementById("target1");
-
-        var test_touchstart = async_test("touchstart event received");
-        var test_touchmove = async_test("touchmove event received");
-        var test_touchend = async_test("touchend event received");
-        var test_mousedown = async_test("Interaction with mouse events");
-
-        var touchstart_received = 0;
-        var touchmove_received = false;
-        var touchend_received = false;
-        var invalid_touchmove_received = false;
-
-        on_event(target0, "touchstart", function onTouchStart(ev) {
-            ev.preventDefault();
-
-            if(!touchstart_received) {
-                // Check event ordering TA: 1.6.2
-                test_touchstart.step(function() {
-                    assert_false(touchmove_received, "touchstart precedes touchmove");
-                    assert_false(touchend_received, "touchstart precedes touchend");
-                });
-                test_touchstart.done();
-                test_mousedown.done(); // If we got here, then the mouse event test is not needed.
-            }
-
-            if(++touchstart_received <= 2)
-                check_TouchEvent(ev);
-        });
-
-        on_event(target0, "touchmove", function onTouchMove(ev) {
-            ev.preventDefault();
-
-            if (touchmove_received)
-              return;
-            touchmove_received = true;
-
-            test_touchmove.step(function() {
-                assert_true(touchstart_received>0, "touchmove follows touchstart");
-                assert_false(touchend_received, "touchmove precedes touchend");
-            });
-            test_touchmove.done();
-
-            check_TouchEvent(ev);
-        });
-
-        on_event(target1, "touchmove", function onTouchMove(ev) {
-            invalid_touchmove_received = true;
-        });
-
-        on_event(window, "touchend", function onTouchEnd(ev) {
-            touchend_received = true;
-
-            test_touchend.step(function() {
-                assert_true(touchstart_received>0, "touchend follows touchstart");
-                assert_true(touchmove_received, "touchend follows touchmove");
-                assert_false(invalid_touchmove_received, "touchmove dispatched to correct target");
-            });
-            test_touchend.done();
-
-            check_TouchEvent(ev);
-            done();
-        });
-
-        on_event(target0, "mousedown", function onMouseDown(ev) {
-            test_mousedown.step(function() {
-                assert_true(touchstart_received,
-                    "The touchstart event must be dispatched before any mouse " +
-                    "events. (If this fails, it might mean that the user agent does " +
-                    "not implement W3C touch events at all.)"
-                );
-            });
-            test_mousedown.done();
-
-            if (!touchstart_received) {
-                // Abort the tests.  If touch events are not supported, then most of
-                // the other event handlers will never be called, and the test will
-                // time out with misleading results.
-                done();
-            }
-        });
-    }
-</script>
-<style>
-    div {
-        margin: 0em;
-        padding: 2em;
-    }
-    #target0 {
-        background: yellow;
-        border: 1px solid orange;
-    }
-    #target1 {
-        background: lightblue;
-        border: 1px solid blue;
-    }
-</style>
-</head>
-<body onload="run()">
-    <h1>Touch Events: multi-touch interface tests</h1>
-    <div id="target0">
-        Touch this box with one finger, then another one...
-    </div>
-    <div id="target1">
-        ...then drag to this box and lift your fingers.
-    </div>
-    <div id="log"></div>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/external/wpt/touch-events/multi-touch-interfaces.html b/third_party/blink/web_tests/external/wpt/touch-events/multi-touch-interfaces.html
new file mode 100644
index 0000000..fae8844
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/touch-events/multi-touch-interfaces.html
@@ -0,0 +1,293 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+     Test cases for Touch Events v1 Recommendation
+     http://www.w3.org/TR/touch-events/
+
+     These tests are based on Mozilla-Nokia-Google's single-touch
+     tests and to some extent Olli Pettay's multi-touch tests.
+
+     The primary purpose of the tests in this document is checking that the
+     various interfaces of the Touch Events APIs are correctly implemented.
+     Other interactions are covered in other test files.
+
+     This document references Test Assertions (abbrev TA below) written by Cathy Chan
+     http://www.w3.org/2010/webevents/wiki/TestAssertions
+-->
+
+<head>
+<title>Touch Events Multi-Touch Interface Tests</title>
+<meta name="viewport" content="width=device-width">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script>
+    setup({explicit_done: true});
+
+    // Check a Touch object's atttributes for existence and correct type
+    // TA: 1.1.2, 1.1.3
+    function check_Touch_object (t, element) {
+        test(function() {
+           assert_equals(Object.prototype.toString.call(t), "[object Touch]", "touch is of type Touch");
+        }, element + "'s touch point is a Touch object");
+        [
+          ["long", "identifier"],
+          ["EventTarget", "target"],
+          ["long", "screenX"],
+          ["long", "screenY"],
+          ["long", "clientX"],
+          ["long", "clientY"],
+          ["long", "pageX"],
+          ["long", "pageY"],
+        ].forEach(function(attr) {
+            var type = attr[0];
+            var name = attr[1];
+
+            // existence check
+            test(function() {
+                assert_true(name in t, name + " attribute in Touch object");
+            }, element + ".Touch." + name + " attribute exists");
+
+            // type check
+            switch(type) {
+            case "long":
+                test(function() {
+                    assert_equals(typeof t[name], "number", name + " attribute of type long");
+                }, element + ".Touch." + name + " attribute is of type number (long)");
+                break;
+            case "EventTarget":
+                // An event target is some type of Element
+                test(function() {
+                    assert_true(t[name] instanceof Element, "EventTarget must be an Element.");
+                }, element + ".Touch." + name + " attribute is of type Element");
+                break;
+            default:
+                break;
+            }
+       });
+    }
+
+    // Check a TouchList object's attributes and methods for existence and proper type
+    // Also make sure all of the members of the list are Touch objects
+    // TA: 1.2.1, 1.2.2, 1.2.5, 1.2.6
+    function check_TouchList_object (tl, element) {
+        test(function() {
+           assert_equals(Object.prototype.toString.call(tl), "[object TouchList]", "touch list is of type TouchList");
+        }, element + "'s touch list is a TouchList object");
+        [
+          ["unsigned long", "length"],
+          ["function", "item"],
+        ].forEach(function(attr) {
+            var type = attr[0];
+            var name = attr[1];
+
+            // existence check
+            test(function() {
+                assert_true(name in tl, name + " attribute in TouchList");
+            }, element + ".TouchList." + name + " attribute exists");
+
+            // type check
+            switch(type) {
+            case "unsigned long":
+                test(function() {
+                    assert_equals(typeof tl[name], "number", name + " attribute of type long");
+                }, element + ".TouchList." + name + " attribute is of type number (unsigned long)");
+                break;
+            case "function":
+                test(function() {
+                    assert_equals(typeof tl[name], "function", name + " attribute of type function");
+                }, element + ".TouchList." + name + " attribute is of type function");
+                break;
+            default:
+                break;
+            }
+       });
+       // Each member of tl should be a proper Touch object
+       for (var i=0; i < tl.length; i++) {
+           check_Touch_object(tl.item(i), element + "[" + i + "]");
+       }
+    }
+
+    // Check a TouchEvent event's attributes for existence and proper type
+    // Also check that each of the event's TouchList objects are valid
+    // TA: 1.{3,4,5}.1.1, 1.{3,4,5}.1.2
+    function check_TouchEvent(ev, touchstart_count) {
+        test(function() {
+           assert_true(ev instanceof TouchEvent, "event is a TouchEvent event");
+        }, ev.type + touchstart_count + " event is a TouchEvent event");
+        [
+          ["TouchList", "touches"],
+          ["TouchList", "targetTouches"],
+          ["TouchList", "changedTouches"],
+          ["boolean", "altKey"],
+          ["boolean", "metaKey"],
+          ["boolean", "ctrlKey"],
+          ["boolean", "shiftKey"],
+        ].forEach(function(attr) {
+            var type = attr[0];
+            var name = attr[1];
+
+            // existence check
+            test(function() {
+                assert_true(name in ev, name + " attribute in " + ev.type + " event");
+            }, ev.type + touchstart_count + "." + name + " attribute exists");
+
+            // type check
+            switch(type) {
+            case "boolean":
+                test(function() {
+                    assert_equals(typeof ev[name], "boolean", name + " attribute of type boolean");
+                }, ev.type + touchstart_count + "." + name + " attribute is of type boolean");
+                break;
+            case "TouchList":
+                test(function() {
+                    assert_equals(Object.prototype.toString.call(ev[name]), "[object TouchList]", name + " attribute of type TouchList");
+                }, ev.type + touchstart_count + "." + name + " attribute is of type TouchList");
+                // Now check the validity of the TouchList
+                check_TouchList_object(ev[name], ev.type + touchstart_count + "." + name);
+                break;
+            default:
+                break;
+            }
+        });
+    }
+
+    function is_touch_over_element(touch, element) {
+        var bounds = element.getBoundingClientRect();
+        return touch.pageX >= bounds.left && touch.pageX <= bounds.right &&
+               touch.pageY >= bounds.top && touch.pageY <= bounds.bottom;
+    }
+
+    function check_touch_clientXY(touch) {
+        assert_equals(touch.clientX, touch.pageX - window.pageXOffset, "touch.clientX is touch.pageX - window.pageXOffset.");
+        assert_equals(touch.clientY, touch.pageY - window.pageYOffset, "touch.clientY is touch.pageY - window.pageYOffset.");
+    }
+
+    function run() {
+        var target0 = document.getElementById("target0");
+        var target1 = document.getElementById("target1");
+
+        var test_touchstart = async_test("touchstart event received");
+        var test_touchmove = async_test("touchmove event received");
+        var test_touchend = async_test("touchend event received");
+        var test_mousedown = async_test("Interaction with mouse events");
+
+        var touchstart_received = 0;
+        var touchmove_received = false;
+        var touchend_received = false;
+        var invalid_touchmove_received = false;
+        var actions_promise;
+
+        on_event(target0, "touchstart", function onTouchStart(ev) {
+            ev.preventDefault();
+
+            if(!touchstart_received) {
+                // Check event ordering TA: 1.6.2
+                test_touchstart.step(function() {
+                    assert_false(touchmove_received, "touchstart precedes touchmove");
+                    assert_false(touchend_received, "touchstart precedes touchend");
+                });
+                test_touchstart.done();
+                test_mousedown.done(); // If we got here, then the mouse event test is not needed.
+            }
+
+            if(++touchstart_received <= 2)
+                check_TouchEvent(ev, touchstart_received);
+        });
+
+        on_event(target0, "touchmove", function onTouchMove(ev) {
+            ev.preventDefault();
+
+            if (touchmove_received)
+              return;
+            touchmove_received = true;
+
+            test_touchmove.step(function() {
+                assert_true(touchstart_received>0, "touchmove follows touchstart");
+                assert_false(touchend_received, "touchmove precedes touchend");
+            });
+            test_touchmove.done();
+
+            check_TouchEvent(ev);
+        });
+
+        on_event(target1, "touchmove", function onTouchMove(ev) {
+            invalid_touchmove_received = true;
+        });
+
+        on_event(window, "touchend", function onTouchEnd(ev) {
+            touchend_received = true;
+
+            test_touchend.step(function() {
+                assert_true(touchstart_received>0, "touchend follows touchstart");
+                assert_true(touchmove_received, "touchend follows touchmove");
+                assert_false(invalid_touchmove_received, "touchmove dispatched to correct target");
+            });
+            test_touchend.done();
+
+            check_TouchEvent(ev);
+            done();
+        });
+
+        on_event(target0, "mousedown", function onMouseDown(ev) {
+            test_mousedown.step(function() {
+                assert_true(touchstart_received,
+                    "The touchstart event must be dispatched before any mouse " +
+                    "events. (If this fails, it might mean that the user agent does " +
+                    "not implement W3C touch events at all.)"
+                );
+            });
+            test_mousedown.done();
+
+            if (!touchstart_received) {
+                // Abort the tests.  If touch events are not supported, then most of
+                // the other event handlers will never be called, and the test will
+                // time out with misleading results.
+                done();
+            }
+        });
+
+        actions_promise = new test_driver.Actions()
+          .addPointer("touchPointer1", "touch")
+          .addPointer("touchPointer2", "touch")
+          .pointerMove(0, 0, {origin: target0, sourceName: "touchPointer1"})
+          .pointerMove(3, 0, {origin: target0, sourceName: "touchPointer2"})
+          .pointerDown({sourceName: "touchPointer1"})
+          .pointerDown({sourceName: "touchPointer2"})
+          .pointerMove(0, 10, {origin: target0, sourceName: "touchPointer1"})
+          .pointerMove(3, 10, {origin: target0, sourceName: "touchPointer2"})
+          .pointerMove(0, 0, {origin: target1, sourceName: "touchPointer1"})
+          .pointerMove(3, 0, {origin: target1, sourceName: "touchPointer2"})
+          .pointerUp({sourceName: "touchPointer1"})
+          .pointerUp({sourceName: "touchPointer2"})
+          .send();
+    }
+</script>
+<style>
+    div {
+        margin: 0em;
+        padding: 2em;
+    }
+    #target0 {
+        background: yellow;
+        border: 1px solid orange;
+    }
+    #target1 {
+        background: lightblue;
+        border: 1px solid blue;
+    }
+</style>
+</head>
+<body onload="run()">
+    <h1>Touch Events: multi-touch interface tests</h1>
+    <div id="target0">
+        Touch this box with one finger, then another one...
+    </div>
+    <div id="target1">
+        ...then drag to this box and lift your fingers.
+    </div>
+    <div id="log"></div>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-capture-video.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-capture-video.https.html
index ed12e68..b6c0222 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-capture-video.https.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-capture-video.https.html
@@ -64,8 +64,8 @@
   // Uses Helper.js GetVideoSignal to query |destVideo| pixel value at a certain position.
   const pixelValue = getVideoSignal(destVideo);
 
-  // Expected value computed by test runs.
-  assert_approx_equals(pixelValue, 50, 2);
+  // Anything non-black means that capture works.
+  assert_not_equals(pixelValue, 0);
   }, "Capturing a video element and sending it via PeerConnection");
 </script>
 </body>
diff --git a/third_party/blink/web_tests/external/wpt_automation/css/selectors/focus-visible-012-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/css/selectors/focus-visible-012-manual-automation.js
deleted file mode 100644
index e34d916d..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/css/selectors/focus-visible-012-manual-automation.js
+++ /dev/null
@@ -1,48 +0,0 @@
-function keyDown(key, modifiers) {
-  return new Promise(function(resolve, reject) {
-    if (window.eventSender) {
-    eventSender.keyDown(key, modifiers);
-    resolve();
-    } else {
-    reject();
-    }
-  });
-}
-
-const boundaryOffset = 2;
-
-function mouseClickInTarget(targetSelector) {
-  var targetDocument = document;
-  var frameLeft = 0;
-  var frameTop = 0;
-  var button = 0;
-
-  return new Promise(function(resolve, reject) {
-    if (window.chrome && chrome.gpuBenchmarking) {
-    var target = targetDocument.querySelector(targetSelector);
-    var targetRect = target.getBoundingClientRect();
-    var xPosition = frameLeft + targetRect.left + boundaryOffset;
-    var yPosition = frameTop + targetRect.top + boundaryOffset;
-    chrome.gpuBenchmarking.pointerActionSequence(
-        [{
-            source: 'mouse',
-            actions: [
-            {name: 'pointerMove', x: xPosition, y: yPosition},
-            {name: 'pointerDown', x: xPosition, y: yPosition, button: button},
-            {name: 'pointerUp', button: button}
-            ]
-        }],
-        resolve);
-    } else {
-    reject();
-    }
-  });
-}
-
-function inject_input() {
-  return mouseClickInTarget("#el").then(() => {
-    return keyDown("y", ["ctrlKey"]);
-  });
-};
-
-inject_input();
\ No newline at end of file
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/delete-across-editable-content-boundaries-2-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/delete-across-editable-content-boundaries-2-expected.txt
index be3109b..9919137 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/delete-across-editable-content-boundaries-2-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/delete-across-editable-content-boundaries-2-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-FAIL This tests to see that selected non-editable nodes that are not in both the start and end editable root are preserved during a deletion.  You should see "foo" and "qux" on both sides of the editable piece. <radr://problem/5026848> resources/testharness.js:2044:25)
+FAIL This tests to see that selected non-editable nodes that are not in both the start and end editable root are preserved during a deletion.  You should see "foo" and "qux" on both sides of the editable piece. <radr://problem/5026848> resources/testharness.js:2092:25)
 	 expected <div contenteditable><table contenteditable="false"><tbody><tr><td>foo</td><td contenteditable>bar |</td><td>qux</td></tr></tbody></table>Editable <span>content</span></div>,
 	 but got  <div contenteditable><table contenteditable="false"><tbody><tr><td>foo</td><td contenteditable>bar |</td><td>qux</td></tr></tbody></table>Editable <span>content</span></div>,
 	 sameupto <div contenteditable><table contenteditable="false"><tbody><tr><td>foo</td><td contenteditable>bar
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/delete_selection_contains_table_row-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/delete_selection_contains_table_row-expected.txt
index ab4feac..a68cb4a 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/delete_selection_contains_table_row-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/delete_selection_contains_table_row-expected.txt
@@ -1,6 +1,6 @@
 This is a testharness.js-based test.
 PASS Empties the second row which should be removed
-FAIL Empties the second row which should NOT be removed because contains the selection resources/testharness.js:2044:25)
+FAIL Empties the second row which should NOT be removed because contains the selection resources/testharness.js:2092:25)
 	 expected <div contenteditable><table><tbody><tr><td>1</td><td>2</td><td>3</td></tr><tr><td>|<br></td><td></td><td><br></td></tr><tr><td>7</td><td>8</td><td>9</td></tr></tbody></table></div>,
 	 but got  <div contenteditable><table><tbody><tr><td>1</td><td>2</td><td>3</td></tr><tr><td>|<br></td><td></td><td></td></tr><tr><td>7</td><td>8</td><td>9</td></tr></tbody></table></div>,
 	 sameupto <div contenteditable><table><tbody><tr><td>1</td><td>2</td><td>3</td></tr><tr><td>|<br></td><td></td><td><
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/delete_to_empty_row-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/delete_to_empty_row-expected.txt
index fd52357..3e5e2ff 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/delete_to_empty_row-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/delete_to_empty_row-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-FAIL assertSelection(inputText, tester, expectedText, options) resources/testharness.js:2044:25)
+FAIL assertSelection(inputText, tester, expectedText, options) resources/testharness.js:2092:25)
 	 expected <div contenteditable><table><tbody><tr><td>|<br></td><td></td><td><br></td></tr><tr><td>21</td><td>22</td><td>33</td></tr><tr><td><br></td><td><br></td><td><br></td></tr></tbody></table></div>,
 	 but got  <div contenteditable><table><tbody><tr><td>|<br></td><td></td><td></td></tr><tr><td>21</td><td>22</td><td>33</td></tr><tr><td><br></td><td><br></td><td><br></td></tr></tbody></table></div>,
 	 sameupto <div contenteditable><table><tbody><tr><td>|<br></td><td></td><td><
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/replace_text_in_node_preserving_markers_crash-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/replace_text_in_node_preserving_markers_crash-expected.txt
index 8635bf1..db36cfa 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/replace_text_in_node_preserving_markers_crash-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/deleting/replace_text_in_node_preserving_markers_crash-expected.txt
@@ -1,17 +1,17 @@
 This is a testharness.js-based test.
-FAIL assertSelection(inputText, tester, expectedText, options) resources/testharness.js:2044:25)
+FAIL assertSelection(inputText, tester, expectedText, options) resources/testharness.js:2092:25)
 	 expected <div contenteditable style="width: 3px;">abcd ef| hijkl</div>,
 	 but got  <div contenteditable style="width: 3px;">abcd ef|hijkl</div>,
 	 sameupto <div contenteditable style="width: 3px;">abcd ef|
-FAIL assertSelection(inputText, tester, expectedText, options) 1 resources/testharness.js:2044:25)
+FAIL assertSelection(inputText, tester, expectedText, options) 1 resources/testharness.js:2092:25)
 	 expected <div contenteditable style="width: 3px;">abcd e| hijkl</div>,
 	 but got  <div contenteditable style="width: 3px;">abcd e|hijkl</div>,
 	 sameupto <div contenteditable style="width: 3px;">abcd e|
-FAIL assertSelection(inputText, tester, expectedText, options) 2 resources/testharness.js:2044:25)
+FAIL assertSelection(inputText, tester, expectedText, options) 2 resources/testharness.js:2092:25)
 	 expected <div contenteditable style="width: 3px;">abcd | hijkl</div>,
 	 but got  <div contenteditable style="width: 3px;">abcd |hijkl</div>,
 	 sameupto <div contenteditable style="width: 3px;">abcd
-FAIL assertSelection(inputText, tester, expectedText, options) 3 resources/testharness.js:2044:25)
+FAIL assertSelection(inputText, tester, expectedText, options) 3 resources/testharness.js:2092:25)
 	 expected <div contenteditable style="width: 3px;">abcd| hijkl</div>,
 	 but got  <div contenteditable style="width: 3px;">abcd|hijkl</div>,
 	 sameupto <div contenteditable style="width: 3px;">abcd|
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/caret_at_soft_line_break-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/caret_at_soft_line_break-expected.txt
index 7088f53..0974bc7 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/caret_at_soft_line_break-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/caret_at_soft_line_break-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-FAIL assertSelection(inputText, tester, expectedText, options) resources/testharness.js:2044:25)
+FAIL assertSelection(inputText, tester, expectedText, options) resources/testharness.js:2092:25)
 	 expected <div contenteditable style="width:250px;">Try to create a caret after this lin<span id="clickme">e|</span> <span></span>thisshouldbeonthesecondline</div>,
 	 but got  <div contenteditable style="width:250px;">Try to create a caret after this lin<span id="clickme">e</span> |<span></span>thisshouldbeonthesecondline</div>,
 	 sameupto <div contenteditable style="width:250px;">Try to create a caret after this lin<span id="clickme">e
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/click-before-and-after-table-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/click-before-and-after-table-expected.txt
index b76b5da..35b4ff28 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/click-before-and-after-table-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/click-before-and-after-table-expected.txt
@@ -1,6 +1,6 @@
 This is a testharness.js-based test.
 PASS Click the after table
-FAIL Click inside of right side border of the table resources/testharness.js:2044:25)
+FAIL Click inside of right side border of the table resources/testharness.js:2092:25)
 	 expected <div contenteditable><table id="target" style="margin: 25px; border:20px solid #ccc; padding: 10px;"><tbody><tr><td>ABC</td><td>XYZ|</td></tr></tbody></table></div>,
 	 but got  <div contenteditable><table id="target" style="margin: 25px; border:20px solid #ccc; padding: 10px;"><tbody><tr><td>ABC|</td><td>XYZ</td></tr></tbody></table></div>,
 	 sameupto <div contenteditable><table id="target" style="margin: 25px; border:20px solid #ccc; padding: 10px;"><tbody><tr><td>ABC
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/extend/extend_selection_17_ltr_forward_lineboundary-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/extend/extend_selection_17_ltr_forward_lineboundary-expected.txt
index ff8bb7a..cb23379 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/extend/extend_selection_17_ltr_forward_lineboundary-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/extend/extend_selection_17_ltr_forward_lineboundary-expected.txt
@@ -1,57 +1,57 @@
 This is a testharness.js-based test.
-FAIL 17-0 ltr forward lineboundary resources/testharness.js:2044:25)
+FAIL 17-0 ltr forward lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">^‫car| דהו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">^‫car דהו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">^‫car
-FAIL 17-1 ltr forward lineboundary resources/testharness.js:2044:25)
+FAIL 17-1 ltr forward lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫^car| דהו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫^car דהו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫^car
-FAIL 17-2 ltr forward lineboundary resources/testharness.js:2044:25)
+FAIL 17-2 ltr forward lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫c^ar| דהו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫c^ar דהו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫c^ar
-FAIL 17-3 ltr forward lineboundary resources/testharness.js:2044:25)
+FAIL 17-3 ltr forward lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫ca^r| דהו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫ca^r דהו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫ca^r
-FAIL 17-4 ltr forward lineboundary resources/testharness.js:2044:25)
+FAIL 17-4 ltr forward lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דהו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car^ דהו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-5 ltr forward lineboundary resources/testharness.js:2044:25)
+FAIL 17-5 ltr forward lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| ^דהו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car ^דהו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-6 ltr forward lineboundary resources/testharness.js:2044:25)
+FAIL 17-6 ltr forward lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| ד^הו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car ד^הו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-7 ltr forward lineboundary resources/testharness.js:2044:25)
+FAIL 17-7 ltr forward lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דה^ו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car דה^ו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-8 ltr forward lineboundary resources/testharness.js:2044:25)
+FAIL 17-8 ltr forward lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דהו^ אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car דהו^ אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-9 ltr forward lineboundary resources/testharness.js:2044:25)
+FAIL 17-9 ltr forward lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דהו ^אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car דהו ^אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-10 ltr forward lineboundary resources/testharness.js:2044:25)
+FAIL 17-10 ltr forward lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דהו א^בג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car דהו א^בג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-11 ltr forward lineboundary resources/testharness.js:2044:25)
+FAIL 17-11 ltr forward lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דהו אב^ג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car דהו אב^ג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-12 ltr forward lineboundary resources/testharness.js:2044:25)
+FAIL 17-12 ltr forward lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דהו אבג^.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car דהו אבג^.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-13 ltr forward lineboundary resources/testharness.js:2044:25)
+FAIL 17-13 ltr forward lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דהו אבג.^‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car דהו אבג.^‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/extend/extend_selection_17_ltr_right_lineboundary-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/extend/extend_selection_17_ltr_right_lineboundary-expected.txt
index bfe51a3..bcc6c04 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/extend/extend_selection_17_ltr_right_lineboundary-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/extend/extend_selection_17_ltr_right_lineboundary-expected.txt
@@ -1,57 +1,57 @@
 This is a testharness.js-based test.
-FAIL 17-0 ltr right lineboundary resources/testharness.js:2044:25)
+FAIL 17-0 ltr right lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">^‫car| דהו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">^‫car דהו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">^‫car
-FAIL 17-1 ltr right lineboundary resources/testharness.js:2044:25)
+FAIL 17-1 ltr right lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫^car| דהו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫^car דהו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫^car
-FAIL 17-2 ltr right lineboundary resources/testharness.js:2044:25)
+FAIL 17-2 ltr right lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫c^ar| דהו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫c^ar דהו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫c^ar
-FAIL 17-3 ltr right lineboundary resources/testharness.js:2044:25)
+FAIL 17-3 ltr right lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫ca^r| דהו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫ca^r דהו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫ca^r
-FAIL 17-4 ltr right lineboundary resources/testharness.js:2044:25)
+FAIL 17-4 ltr right lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דהו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car^ דהו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-5 ltr right lineboundary resources/testharness.js:2044:25)
+FAIL 17-5 ltr right lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| ^דהו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car ^דהו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-6 ltr right lineboundary resources/testharness.js:2044:25)
+FAIL 17-6 ltr right lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| ד^הו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car ד^הו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-7 ltr right lineboundary resources/testharness.js:2044:25)
+FAIL 17-7 ltr right lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דה^ו אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car דה^ו אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-8 ltr right lineboundary resources/testharness.js:2044:25)
+FAIL 17-8 ltr right lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דהו^ אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car דהו^ אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-9 ltr right lineboundary resources/testharness.js:2044:25)
+FAIL 17-9 ltr right lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דהו ^אבג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car דהו ^אבג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-10 ltr right lineboundary resources/testharness.js:2044:25)
+FAIL 17-10 ltr right lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דהו א^בג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car דהו א^בג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-11 ltr right lineboundary resources/testharness.js:2044:25)
+FAIL 17-11 ltr right lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דהו אב^ג.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car דהו אב^ג.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-12 ltr right lineboundary resources/testharness.js:2044:25)
+FAIL 17-12 ltr right lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דהו אבג^.‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car דהו אבג^.‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
-FAIL 17-13 ltr right lineboundary resources/testharness.js:2044:25)
+FAIL 17-13 ltr right lineboundary resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="ltr">‫car| דהו אבג.^‬</div>,
 	 but got  <div contenteditable dir="ltr">‫car דהו אבג.^‬|</div>,
 	 sameupto <div contenteditable dir="ltr">‫car
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/home-end-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/home-end-expected.txt
index 8a88e1b..652fc06d 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/home-end-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/home-end-expected.txt
@@ -119,12 +119,12 @@
 PASS 15-RTL backward
 PASS 15-RTL right
 PASS 15-RTL left
-FAIL 16-LTR forward resources/testharness.js:2044:25)
+FAIL 16-LTR forward resources/testharness.js:2092:25)
 	 expected <div contenteditable style="direction:ltr">‫xyz| דהו אבג.‬</div>,
 	 but got  <div contenteditable style="direction:ltr">‫xyz דהו אבג.‬|</div>,
 	 sameupto <div contenteditable style="direction:ltr">‫xyz
 PASS 16-LTR backward
-FAIL 16-LTR right resources/testharness.js:2044:25)
+FAIL 16-LTR right resources/testharness.js:2092:25)
 	 expected <div contenteditable style="direction:ltr">‫xyz| דהו אבג.‬</div>,
 	 but got  <div contenteditable style="direction:ltr">‫xyz דהו אבג.‬|</div>,
 	 sameupto <div contenteditable style="direction:ltr">‫xyz
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/modify-up-on-rtl-wrapping-text-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/modify-up-on-rtl-wrapping-text-expected.txt
index 4079d585..9d5101a 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/modify-up-on-rtl-wrapping-text-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/editing/selection/modify-up-on-rtl-wrapping-text-expected.txt
@@ -1,14 +1,14 @@
 This is a testharness.js-based test.
-FAIL 2 lines resources/testharness.js:2044:25)
+FAIL 2 lines resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="rtl" style="font-family: monospace; width: 2ch"><bdo dir="rtl">A| BC</bdo></div>,
 	 but got  <div contenteditable dir="rtl" style="font-family: monospace; width: 2ch"><bdo dir="rtl">A |BC</bdo></div>,
 	 sameupto <div contenteditable dir="rtl" style="font-family: monospace; width: 2ch"><bdo dir="rtl">A
-FAIL 3 lines-1 resources/testharness.js:2044:25)
+FAIL 3 lines-1 resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="rtl" style="font-family: monospace; width: 2ch"><bdo dir="rtl">A BC| DE</bdo></div>,
 	 but got  <div contenteditable dir="rtl" style="font-family: monospace; width: 2ch"><bdo dir="rtl">A BC |DE</bdo></div>,
 	 sameupto <div contenteditable dir="rtl" style="font-family: monospace; width: 2ch"><bdo dir="rtl">A BC
 PASS 3 lines-2
-FAIL 5 lines-1 resources/testharness.js:2044:25)
+FAIL 5 lines-1 resources/testharness.js:2092:25)
 	 expected <div contenteditable dir="rtl" style="font-family: monospace; width: 2ch"><bdo dir="rtl">A BC DE FG| HI</bdo></div>,
 	 but got  <div contenteditable dir="rtl" style="font-family: monospace; width: 2ch"><bdo dir="rtl">A BC DE FG |HI</bdo></div>,
 	 sameupto <div contenteditable dir="rtl" style="font-family: monospace; width: 2ch"><bdo dir="rtl">A BC DE FG
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-copy-truncated-text.js b/third_party/blink/web_tests/http/tests/devtools/console/console-copy-truncated-text.js
index 7c70e21..7c14731 100644
--- a/third_party/blink/web_tests/http/tests/devtools/console/console-copy-truncated-text.js
+++ b/third_party/blink/web_tests/http/tests/devtools/console/console-copy-truncated-text.js
@@ -196,7 +196,7 @@
     async function onSearch() {
       var matches = consoleView.element
         .childTextNodes()
-        .filter(node => node.parentElement.classList.contains('highlighted-search-result'))
+        .filter(node => node.parentElement && node.parentElement.classList.contains('highlighted-search-result'))
         .map(node => node.parentElement);
       TestRunner.addResult('Highlighted ' + matches.length + ' matches');
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/unit/remote-object-from-local-expected.txt b/third_party/blink/web_tests/http/tests/devtools/unit/remote-object-from-local-expected.txt
deleted file mode 100644
index 6a9a140..0000000
--- a/third_party/blink/web_tests/http/tests/devtools/unit/remote-object-from-local-expected.txt
+++ /dev/null
@@ -1,171 +0,0 @@
-Tests construction of RemoteObjects from local values.
-
-Expression: "1n"
-type: bigint
-subtype: undefined
-value: 1
-description: 1
-hasChildren: false
-preview: undefined
-unserializableValue: 1n
-arrayLength: 0
-
-ToCallArgument:
-value: undefined
-unserializableValue: 1n
-
-Expression: "42"
-type: number
-subtype: undefined
-value: 42
-description: 42
-hasChildren: false
-preview: undefined
-unserializableValue: undefined
-arrayLength: 0
-
-ToCallArgument:
-value: 42
-unserializableValue: undefined
-
-Expression: "'foo string'"
-type: string
-subtype: undefined
-value: foo string
-description: foo string
-hasChildren: false
-preview: undefined
-unserializableValue: undefined
-arrayLength: 0
-
-ToCallArgument:
-value: foo string
-unserializableValue: undefined
-
-Expression: "NaN"
-type: number
-subtype: undefined
-value: NaN
-description: NaN
-hasChildren: false
-preview: undefined
-unserializableValue: NaN
-arrayLength: 0
-
-ToCallArgument:
-value: undefined
-unserializableValue: NaN
-
-Expression: "Infinity"
-type: number
-subtype: undefined
-value: Infinity
-description: Infinity
-hasChildren: false
-preview: undefined
-unserializableValue: Infinity
-arrayLength: 0
-
-ToCallArgument:
-value: undefined
-unserializableValue: Infinity
-
-Expression: "-Infinity"
-type: number
-subtype: undefined
-value: -Infinity
-description: -Infinity
-hasChildren: false
-preview: undefined
-unserializableValue: -Infinity
-arrayLength: 0
-
-ToCallArgument:
-value: undefined
-unserializableValue: -Infinity
-
-Expression: "-0"
-type: number
-subtype: undefined
-value: 0
-description: 0
-hasChildren: false
-preview: undefined
-unserializableValue: -0
-arrayLength: 0
-
-ToCallArgument:
-value: undefined
-unserializableValue: -0
-
-Expression: "[1n, 2, NaN, -0, null, undefined]"
-type: object
-subtype: array
-value: 1,2,NaN,0,,
-description: [1, 2, NaN, 0, null, undefined]
-hasChildren: true
-preview: undefined
-unserializableValue: undefined
-arrayLength: 6
-
-ToCallArgument:
-value: 1,2,NaN,0,,
-unserializableValue: undefined
-
-Expression: "({ foo: 'bar' })"
-type: object
-subtype: undefined
-value: [object Object]
-description: {foo: "bar"}
-hasChildren: true
-preview: undefined
-unserializableValue: undefined
-arrayLength: 0
-
-ToCallArgument:
-value: [object Object]
-unserializableValue: undefined
-
-Expression: "(function(){ return arguments; })(1,2,3,4)"
-type: object
-subtype: undefined
-value: [object Arguments]
-description: {0: 1, 1: 2, 2: 3, 3: 4}
-hasChildren: true
-preview: undefined
-unserializableValue: undefined
-arrayLength: 0
-
-ToCallArgument:
-value: [object Arguments]
-unserializableValue: undefined
-
-Expression: "(function func() {})"
-type: function
-subtype: undefined
-value: function func() {}
-description: function func() {}
-hasChildren: false
-preview: undefined
-unserializableValue: undefined
-arrayLength: 0
-
-ToCallArgument:
-value: function func() {}
-unserializableValue: undefined
-
-Expression: "new Error('errr')"
-type: object
-subtype: undefined
-value: Error: errr
-description: {}
-hasChildren: false
-preview: undefined
-unserializableValue: undefined
-arrayLength: 0
-
-ToCallArgument:
-value: Error: errr
-unserializableValue: undefined
-
-
diff --git a/third_party/blink/web_tests/http/tests/devtools/unit/remote-object-from-local.js b/third_party/blink/web_tests/http/tests/devtools/unit/remote-object-from-local.js
deleted file mode 100644
index 955643e..0000000
--- a/third_party/blink/web_tests/http/tests/devtools/unit/remote-object-from-local.js
+++ /dev/null
@@ -1,41 +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.
-
-(async function() {
-  TestRunner.addResult(`Tests construction of RemoteObjects from local values.\n`);
-  await TestRunner.loadModule('sdk');
-
-  var expressions = [
-    '1n', '42', '\'foo string\'', 'NaN', 'Infinity', '-Infinity', '-0', '[1n, 2, NaN, -0, null, undefined]',
-    '({ foo: \'bar\' })', '(function(){ return arguments; })(1,2,3,4)', '(function func() {})', 'new Error(\'errr\')'
-  ];
-
-  for (const expression of expressions) {
-    const remoteObject = SDK.RemoteObject.fromLocalObject(eval(expression));
-    TestRunner.addResult(`Expression: "${expression}"`);
-    dumpRemoteObject(remoteObject);
-    TestRunner.addResult(``);
-    dumpCallArgument(SDK.RemoteObject.toCallArgument(remoteObject));
-    TestRunner.addResult(``);
-  }
-
-  TestRunner.completeTest();
-
-  // BigInts fail in JSON.stringify(), so manually log properties.
-  function dumpRemoteObject(object) {
-    const properties = ['type', 'subtype', 'value', 'description', 'hasChildren', 'preview'];
-    const methods = ['unserializableValue', 'arrayLength'];
-    for (const prop of properties)
-      TestRunner.addResult(`${prop}: ${object[prop]}`);
-    for (const method of methods)
-      TestRunner.addResult(`${method}: ${object[method]()}`);
-  }
-
-  function dumpCallArgument(object) {
-    TestRunner.addResult(`ToCallArgument:`);
-    const properties = ['value', 'unserializableValue'];
-    for (const prop of properties)
-      TestRunner.addResult(`${prop}: ${object[prop]}`);
-  }
-})();
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/editing/run/justifyright_4001-last-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/editing/run/justifyright_4001-last-expected.txt
index 07170e18..387366c3 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/editing/run/justifyright_4001-last-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/editing/run/justifyright_4001-last-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 757 tests; 607 PASS, 150 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 757 tests; 609 PASS, 148 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]] "<p>[foo]<p align=right>bar<p>extra" queryCommandIndeterm("justifyright") before
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]] "<p>[foo]<p align=right>bar<p>extra" queryCommandState("justifyright") before
 FAIL [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]] "<p>[foo]<p align=right>bar<p>extra" queryCommandValue("justifyright") before assert_equals: Wrong result returned expected "left" but got "false"
@@ -526,10 +526,10 @@
 FAIL [["justifyright",""]] "<div style=text-align:start>[foo]</div><p>extra" queryCommandValue("justifyright") after assert_equals: Wrong result returned expected "right" but got "true"
 PASS [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra": execCommand("justifyright", false, "") return value
 PASS [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" checks for modifications to non-editable content
-PASS [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" compare innerHTML
+FAIL [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div style=\"text-align:right\">foo</div><p>extra</p>" but got "<div style=\"text-align:end\">foo</div><p>extra</p>"
 PASS [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyright") before
-FAIL [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") before assert_equals: Wrong result returned expected true but got false
-FAIL [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") before assert_equals: Wrong result returned expected "right" but got "false"
+PASS [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") before
+FAIL [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") before assert_equals: Wrong result returned expected "right" but got "true"
 PASS [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyright") after
 PASS [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") after
 FAIL [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") after assert_equals: Wrong result returned expected "right" but got "true"
@@ -568,7 +568,7 @@
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra": execCommand("stylewithcss", false, "true") return value
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra": execCommand("justifyright", false, "") return value
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" checks for modifications to non-editable content
-FAIL [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div dir=\"rtl\">foo</div><p>extra</p>" but got "<div dir=\"rtl\" style=\"text-align:end\">foo</div><p>extra</p>"
+FAIL [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div dir=\"rtl\">foo</div><p>extra</p>" but got "<div dir=\"rtl\" style=\"text-align:right\">foo</div><p>extra</p>"
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("stylewithcss") before
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("stylewithcss") before
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("stylewithcss") before
@@ -576,15 +576,15 @@
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("stylewithcss") after
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("stylewithcss") after
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyright") before
-FAIL [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") before assert_equals: Wrong result returned expected false but got true
-FAIL [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") before assert_equals: Wrong result returned expected "left" but got "true"
+PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") before
+FAIL [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") before assert_equals: Wrong result returned expected "left" but got "false"
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyright") after
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") after
 FAIL [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") after assert_equals: Wrong result returned expected "right" but got "true"
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra": execCommand("stylewithcss", false, "false") return value
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra": execCommand("justifyright", false, "") return value
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" checks for modifications to non-editable content
-FAIL [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div dir=\"rtl\">foo</div><p>extra</p>" but got "<div dir=\"rtl\" style=\"text-align:end\">foo</div><p>extra</p>"
+FAIL [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div dir=\"rtl\">foo</div><p>extra</p>" but got "<div dir=\"rtl\" style=\"text-align:right\">foo</div><p>extra</p>"
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("stylewithcss") before
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("stylewithcss") before
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("stylewithcss") before
@@ -592,8 +592,8 @@
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("stylewithcss") after
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("stylewithcss") after
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyright") before
-FAIL [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") before assert_equals: Wrong result returned expected false but got true
-FAIL [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") before assert_equals: Wrong result returned expected "left" but got "true"
+PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") before
+FAIL [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") before assert_equals: Wrong result returned expected "left" but got "false"
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyright") after
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") after
 FAIL [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") after assert_equals: Wrong result returned expected "right" but got "true"
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/editing/run/justifyright_4001-last-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/editing/run/justifyright_4001-last-expected.txt
index 0f927b2..a44c45ab 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/editing/run/justifyright_4001-last-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/editing/run/justifyright_4001-last-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 757 tests; 619 PASS, 138 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 757 tests; 621 PASS, 136 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]] "<p>[foo]<p align=right>bar<p>extra" queryCommandIndeterm("justifyright") before
 PASS [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]] "<p>[foo]<p align=right>bar<p>extra" queryCommandState("justifyright") before
 FAIL [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]] "<p>[foo]<p align=right>bar<p>extra" queryCommandValue("justifyright") before assert_equals: Wrong result returned expected "left" but got "false"
@@ -526,10 +526,10 @@
 FAIL [["justifyright",""]] "<div style=text-align:start>[foo]</div><p>extra" queryCommandValue("justifyright") after assert_equals: Wrong result returned expected "right" but got "true"
 PASS [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra": execCommand("justifyright", false, "") return value
 PASS [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" checks for modifications to non-editable content
-PASS [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" compare innerHTML
+FAIL [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div style=\"text-align:right\">foo</div><p>extra</p>" but got "<div style=\"text-align:end\">foo</div><p>extra</p>"
 PASS [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyright") before
-FAIL [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") before assert_equals: Wrong result returned expected true but got false
-FAIL [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") before assert_equals: Wrong result returned expected "right" but got "false"
+PASS [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") before
+FAIL [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") before assert_equals: Wrong result returned expected "right" but got "true"
 PASS [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyright") after
 PASS [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") after
 FAIL [["justifyright",""]] "<div style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") after assert_equals: Wrong result returned expected "right" but got "true"
@@ -568,7 +568,7 @@
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra": execCommand("stylewithcss", false, "true") return value
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra": execCommand("justifyright", false, "") return value
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" checks for modifications to non-editable content
-FAIL [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div dir=\"rtl\">foo</div><p>extra</p>" but got "<div dir=\"rtl\" style=\"text-align:end\">foo</div><p>extra</p>"
+FAIL [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div dir=\"rtl\">foo</div><p>extra</p>" but got "<div dir=\"rtl\" style=\"text-align:right\">foo</div><p>extra</p>"
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("stylewithcss") before
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("stylewithcss") before
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("stylewithcss") before
@@ -576,15 +576,15 @@
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("stylewithcss") after
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("stylewithcss") after
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyright") before
-FAIL [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") before assert_equals: Wrong result returned expected false but got true
-FAIL [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") before assert_equals: Wrong result returned expected "left" but got "true"
+PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") before
+FAIL [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") before assert_equals: Wrong result returned expected "left" but got "false"
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyright") after
 PASS [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") after
 FAIL [["stylewithcss","true"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") after assert_equals: Wrong result returned expected "right" but got "true"
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra": execCommand("stylewithcss", false, "false") return value
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra": execCommand("justifyright", false, "") return value
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" checks for modifications to non-editable content
-FAIL [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div dir=\"rtl\">foo</div><p>extra</p>" but got "<div dir=\"rtl\" style=\"text-align:end\">foo</div><p>extra</p>"
+FAIL [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div dir=\"rtl\">foo</div><p>extra</p>" but got "<div dir=\"rtl\" style=\"text-align:right\">foo</div><p>extra</p>"
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("stylewithcss") before
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("stylewithcss") before
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("stylewithcss") before
@@ -592,8 +592,8 @@
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("stylewithcss") after
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("stylewithcss") after
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyright") before
-FAIL [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") before assert_equals: Wrong result returned expected false but got true
-FAIL [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") before assert_equals: Wrong result returned expected "left" but got "true"
+PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") before
+FAIL [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") before assert_equals: Wrong result returned expected "left" but got "false"
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandIndeterm("justifyright") after
 PASS [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandState("justifyright") after
 FAIL [["stylewithcss","false"],["justifyright",""]] "<div dir=rtl style=text-align:end>[foo]</div><p>extra" queryCommandValue("justifyright") after assert_equals: Wrong result returned expected "right" but got "true"
diff --git a/third_party/closure_compiler/README.chromium b/third_party/closure_compiler/README.chromium
index eb84396..4b49b71 100644
--- a/third_party/closure_compiler/README.chromium
+++ b/third_party/closure_compiler/README.chromium
@@ -1,8 +1,8 @@
 Name: Closure compiler
 Short Name: closure-compiler
 URL: http://github.com/google/closure-compiler
-Version: 20201006.0.0
-Date: 2020/10/12 10:13
+Version: 20210202.0.0
+Date: 2021/02/08 10:12
 License: Apache 2.0
 License File: LICENSE
 Security Critical: no
diff --git a/third_party/closure_compiler/closure_args.gni b/third_party/closure_compiler/closure_args.gni
index 4c5e280..04b9946c 100644
--- a/third_party/closure_compiler/closure_args.gni
+++ b/third_party/closure_compiler/closure_args.gni
@@ -26,6 +26,7 @@
 # Additional closure args for performing full checks.
 default_closure_args = strict_error_checking_closure_args + [
                          "compilation_level=SIMPLE_OPTIMIZATIONS",
+                         "generate_exports=false",
 
                          "extra_annotation_name=attribute",
                          "extra_annotation_name=demo",
@@ -51,10 +52,6 @@
   "module_resolution=BROWSER_WITH_TRANSFORMED_PREFIXES",
   "browser_resolver_prefix_replacements=\"chrome://resources/=./\"",
   "browser_resolver_prefix_replacements=\"//resources/=./\"",
-
-  # Turn off primarily because cr.define() should not be used in any JS Modules
-  # based code, and secondarily because of b/133333578.
-  "chrome_pass=false",
 ]
 
 mojom_js_args = [
@@ -90,7 +87,6 @@
                   # the path once the CrOS chroot no longer uses symlinks when
                   # building chrome.
                   "hide_warnings_for=third_party/polymer/v3_0/components-chromium/",
-                  "polymer_pass=false",
 
                   # Note: "2" is counter-intuitively the correct value to use for Polymer 3.
                   "polymer_version=2",
diff --git a/third_party/closure_compiler/compile_js.gni b/third_party/closure_compiler/compile_js.gni
index 8a1d466..760ccd7 100644
--- a/third_party/closure_compiler/compile_js.gni
+++ b/third_party/closure_compiler/compile_js.gni
@@ -218,20 +218,28 @@
       args += [ "--checks-only" ]
     }
 
-    if (!defined(is_polymer3)) {
-      is_polymer3 = false
-    }
-
     # |minifying_closure_args| from
     # //third_party/closure_compiler/closure_args.gni
     if (!defined(closure_flags)) {
       closure_flags = default_closure_args
     }
+
+    # Only one of |is_polymer3|, |uses_js_modules| and |uses_legacy_modules|
+    # should be true at any given time.
+    is_polymer3 = defined(is_polymer3) && is_polymer3
+    uses_legacy_modules = defined(uses_legacy_modules) && uses_legacy_modules
+    uses_js_modules = defined(uses_js_modules) && uses_js_modules
+
     if (is_polymer3) {
+      assert(!uses_js_modules && !uses_legacy_modules)
       closure_flags += polymer3_args
-    } else if (defined(uses_js_modules) && uses_js_modules) {
+    }
+    if (uses_js_modules) {
+      assert(!uses_legacy_modules && !is_polymer3)
       closure_flags += js_modules_args
-    } else if (defined(uses_legacy_modules) && uses_legacy_modules) {
+    }
+    if (uses_legacy_modules) {
+      assert(!uses_js_modules && !is_polymer3)
       closure_flags += legacy_modules_args
     }
 
diff --git a/third_party/closure_compiler/compiler/compiler.jar b/third_party/closure_compiler/compiler/compiler.jar
index 1e249b4..5d03db5 100644
--- a/third_party/closure_compiler/compiler/compiler.jar
+++ b/third_party/closure_compiler/compiler/compiler.jar
Binary files differ
diff --git a/third_party/closure_compiler/externs/pending.js b/third_party/closure_compiler/externs/pending.js
index bfda31c..b304a275 100644
--- a/third_party/closure_compiler/externs/pending.js
+++ b/third_party/closure_compiler/externs/pending.js
@@ -9,34 +9,6 @@
  */
 
 /**
- * TODO(dstockwell): Remove this once it is added to Closure Compiler itself.
- * @see https://drafts.fxtf.org/geometry/#DOMMatrix
- */
-class DOMMatrix {
-  /**
-   * @param {number} x
-   * @param {number} y
-   */
-  translateSelf(x, y) {}
-  /**
-   * @param {number} x
-   * @param {number} y
-   * @param {number} z
-   */
-  rotateSelf(x, y, z) {}
-  /**
-   * @param {number} x
-   * @param {number} y
-   */
-  scaleSelf(x, y) {}
-  /**
-   * @param {{x: number, y: number}} point
-   * @return {{x: number, y: number}}
-   */
-  transformPoint(point) {}
-}
-
-/**
  * TODO(katie): Remove this once length is added to the Closure
  * chrome_extensions.js.
  * An event from the TTS engine to communicate the status of an utterance.
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index 926f316..9604bb2 100644
--- a/third_party/freetype/README.chromium
+++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@
 Name: FreeType
 URL: http://www.freetype.org/
-Version: VER-2-10-4-145-g947e47528
-Revision: 947e47528345ab821b4d0fc7d3f0472fa236045e
+Version: VER-2-10-4-151-g2c4055960
+Revision: 2c40559609c102a934c1f0c5ee7ccb790fc887dc
 CPEPrefix: cpe:/a:freetype:freetype:2.10.4
 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
          JPEG Group) licenses"
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_1.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_1.a.sha1
index ee5e0aa..0235e87a 100644
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_1.a.sha1
+++ b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_1.a.sha1
@@ -1 +1 @@
-e3a8233332ab7f448613c5d3c6c78e5e698505e5
\ No newline at end of file
+2e6b1f0a93fe933d32821dab7def7f455d72b9c2
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_Cr.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_Cr.a.sha1
index 6ee4f74..a2c91e3 100644
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_Cr.a.sha1
+++ b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_Cr.a.sha1
@@ -1 +1 @@
-dceee76743308d071abb90cf0157b3a9620badfa
\ No newline at end of file
+b5ced156750e1c714781961f276103005e42e2e6
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_ndk1.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_ndk1.a.sha1
index d4ad04c4..132abcc 100644
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_ndk1.a.sha1
+++ b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_ndk1.a.sha1
@@ -1 +1 @@
-3dde388b26d3659b4f99d84c9a358fc78f37f5b8
\ No newline at end of file
+1e3451acb5715926b640319e16aedc9553f3637b
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm_1.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm_1.a.sha1
index 58d381d..c2edca27 100644
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm_1.a.sha1
+++ b/third_party/gvr-android-sdk/libgvr_shim_static_arm_1.a.sha1
@@ -1 +1 @@
-8d19ef4983bbfe1b9b679f418dee80678a7d7652
\ No newline at end of file
+072456a40003979858f2c307cb3de60d1136cd4d
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm_Cr.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm_Cr.a.sha1
index 0c8b7e64..a9f94a6 100644
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm_Cr.a.sha1
+++ b/third_party/gvr-android-sdk/libgvr_shim_static_arm_Cr.a.sha1
@@ -1 +1 @@
-ee194b9c00e14ae07fb0e39add6522a6637b742f
\ No newline at end of file
+1d298d06f9943a85a0a46a4453b41fcbf6bb351b
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm_ndk1.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm_ndk1.a.sha1
index 0b49459..92a0c11 100644
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm_ndk1.a.sha1
+++ b/third_party/gvr-android-sdk/libgvr_shim_static_arm_ndk1.a.sha1
@@ -1 +1 @@
-136cb96d7936fe9ad491046fd7c0ddf541ad2765
\ No newline at end of file
+2616c1b7efb574068394fe72bde930d937485eba
\ No newline at end of file
diff --git a/tools/android/modularization/owners/getowners.py b/tools/android/modularization/owners/getowners.py
index 9184b4dc..461bcc4 100755
--- a/tools/android/modularization/owners/getowners.py
+++ b/tools/android/modularization/owners/getowners.py
@@ -4,7 +4,7 @@
 # found in the LICENSE file.
 r'''Get chromium OWNERS information for android directories.
 
-   tools/android/modularization/getowners.py -- \
+   tools/android/modularization/owners/getowners.py -- \
    --git-dir ~/chromium/src \
    -o ~/owners.json
 '''
@@ -21,6 +21,7 @@
 from typing import Dict, List, Optional, Tuple
 
 import owners_data
+import owners_dir_metadata
 import owners_exporter
 import owners_git
 import owners_input
@@ -42,10 +43,9 @@
       '--limit-to-dir',
       help='Limit to a single directory. Used to restrict a smaller scope for '
       'debugging.')
-  # TODO(crbug.com/1135347): --dirmd-dir is currently unused, but will be used
-  # to parse DIR_METADATA files.
   arg_parser.add_argument(
       '--dirmd-path',
+      default='dirmd',
       help="Path to dirmd. If not specified, assume it's in PATH.")
   arguments = arg_parser.parse_args()
 
@@ -58,9 +58,13 @@
   paths_to_search = owners_input.get_android_folders(chromium_root,
                                                      arguments.limit_to_dir)
 
+  all_dir_metadata = owners_dir_metadata.read_raw_dir_metadata(
+      chromium_root, arguments.dirmd_path)
+
   with multiprocessing.Pool() as p:
-    data = p.map(functools.partial(_process_requested_path, chromium_root),
-                 paths_to_search)
+    data = p.map(
+        functools.partial(_process_requested_path, chromium_root,
+                          all_dir_metadata), paths_to_search)
 
   owners_exporter.to_json_file(data, arguments.output)
   print(f'Exported to {arguments.output}')
@@ -69,14 +73,18 @@
 
 
 def _process_requested_path(
-    chromium_root: str, requested_path: owners_data.RequestedPath
+    chromium_root: str, all_dir_metadata: Dict,
+    requested_path: owners_data.RequestedPath
 ) -> Tuple[owners_data.RequestedPath, owners_data.PathData]:
   '''Gets the necessary information from the git repository.'''
 
   owners_file = _find_owners_file(chromium_root, requested_path.path)
   owners = _build_owners_info(chromium_root, owners_file)
   git_data = _fetch_git_data(chromium_root, requested_path)
-  path_data = owners_data.PathData(owners, git_data)
+  dir_metadata = owners_dir_metadata.build_dir_metadata(chromium_root,
+                                                        all_dir_metadata,
+                                                        requested_path)
+  path_data = owners_data.PathData(owners, git_data, dir_metadata)
   return (requested_path, path_data)
 
 
@@ -184,12 +192,6 @@
         continue
       elif line.startswith('file://'):
         owners.file_inherited = line[len('file://'):].strip()
-      elif line.startswith('# COMPONENT:'):
-        owners.component = line[len('# COMPONENT:'):].strip()
-      elif line.startswith('# TEAM:'):
-        owners.team = line[len('# TEAM:'):].strip()
-      elif line.startswith('# OS:'):
-        owners.os = line[len('# OS:'):].strip()
       elif line.startswith('#'):
         continue
       elif line.startswith('per-file'):
@@ -221,13 +223,7 @@
       return
     if not owners.owners and parent_owners.owners:
       owners.owners.extend(parent_owners.owners)
-    if not owners.component and parent_owners.component:
-      owners.component = parent_owners.component
-    if not owners.team and parent_owners.team:
-      owners.team = parent_owners.team
-    if not owners.os and parent_owners.os:
-      owners.os = parent_owners.os
-    if owners.owners and owners.component and owners.team and owners.os:
+    if owners.owners:
       return
     visited.add(parent_owners.owners_file)
 
diff --git a/tools/android/modularization/owners/owners_data.py b/tools/android/modularization/owners/owners_data.py
index 788095c..8a6f3b60 100644
--- a/tools/android/modularization/owners/owners_data.py
+++ b/tools/android/modularization/owners/owners_data.py
@@ -9,14 +9,22 @@
 
 
 @dataclasses.dataclass
+class DirMetadata:
+  '''A synthetic representation of a DIR_METADATA file.'''
+  component: Optional[str] = None
+  team: Optional[str] = None
+  os: Optional[str] = None
+
+  def copy(self):
+    return dataclasses.replace(self)
+
+
+@dataclasses.dataclass
 class Owners:
   '''A synthetic representation of an OWNERS file.'''
   owners_file: str  # Path to OWNERS file
   file_inherited: Optional[str] = None  # Referenced OWNERS file
   owners: List[str] = dataclasses.field(default_factory=list)  # owners' emails
-  component: Optional[str] = None
-  team: Optional[str] = None
-  os: Optional[str] = None
 
 
 @dataclasses.dataclass
@@ -58,3 +66,4 @@
   '''Path to be searched for.'''
   owner: Owners
   git_data: GitData
+  dir_metadata: DirMetadata
diff --git a/tools/android/modularization/owners/owners_dir_metadata.py b/tools/android/modularization/owners/owners_dir_metadata.py
new file mode 100644
index 0000000..3af6ad1
--- /dev/null
+++ b/tools/android/modularization/owners/owners_dir_metadata.py
@@ -0,0 +1,68 @@
+# Lint as: python3
+# 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 json
+import os
+import pathlib
+import sys
+from typing import Dict
+
+import owners_data
+
+_SRC_PATH = os.path.abspath(
+    os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))
+
+sys.path.append(
+    os.path.join(_SRC_PATH, 'tools', 'android', 'dependency_analysis'))
+import subprocess_utils
+
+
+def read_raw_dir_metadata(chromium_root: str, dirmd_path: str) -> Dict:
+  '''Runs all DIR_METADATA files with dirmd and returns a dict of raw data.'''
+  raw_str: str = subprocess_utils.run_command(
+      [dirmd_path, 'export', '--root', chromium_root])
+  raw_dict: Dict = json.loads(raw_str)
+  return raw_dict['dirs']
+
+
+def build_dir_metadata(chromium_root: str, all_dir_metadata: Dict,
+                       requested_path: owners_data.RequestedPath
+                       ) -> owners_data.DirMetadata:
+  '''Creates a synthetic representation of an DIR_METADATA file.'''
+  return _build_dir_metadata_recursive(chromium_root, all_dir_metadata,
+                                       pathlib.Path(requested_path.path))
+
+
+# Memoized synthetic dir_metadatas
+synthetic_dir_metadatas: Dict[pathlib.Path, owners_data.DirMetadata] = {}
+
+
+def _build_dir_metadata_recursive(chromium_root: str, all_dir_metadata: Dict,
+                                  path: pathlib.Path
+                                  ) -> owners_data.DirMetadata:
+  # Use memoized value
+  if path in synthetic_dir_metadatas:
+    return synthetic_dir_metadatas[path]
+
+  # Clone parent synthetic dir_metadata as base
+  if len(path.parts) > 1:
+    parent_dir_metadata = _build_dir_metadata_recursive(chromium_root,
+                                                        all_dir_metadata,
+                                                        path.parent)
+    dir_metadata = parent_dir_metadata.copy()
+  else:
+    dir_metadata = owners_data.DirMetadata()
+
+  # Add data from all_dir_metadata, if there is a DIR_METADATA in the directory
+  # Be careful to keep values inherited from the parent dir.
+  raw_dict = all_dir_metadata.get(str(path), {})
+  monorail = raw_dict.get('monorail', {})
+  dir_metadata.component = monorail.get('component', dir_metadata.component)
+  dir_metadata.team = raw_dict.get('teamEmail', dir_metadata.team)
+  dir_metadata.os = raw_dict.get('os', dir_metadata.os)
+
+  # Memoize and return
+  synthetic_dir_metadatas[path] = dir_metadata
+  return dir_metadata
diff --git a/tools/android/modularization/owners/owners_exporter.py b/tools/android/modularization/owners/owners_exporter.py
index 3f1eeb8..80b96ad 100644
--- a/tools/android/modularization/owners/owners_exporter.py
+++ b/tools/android/modularization/owners/owners_exporter.py
@@ -33,6 +33,7 @@
     return r
 
   owners = path_data.owner
+  dir_metadata = path_data.dir_metadata
   git_data = path_data.git_data
 
   return {
@@ -40,9 +41,9 @@
       'feature': requested_path.feature,
       'owners_file': owners.owners_file,
       'owners_email': ', '.join(owners.owners),
-      'team': owners.team if owners.team else '',
-      'component': owners.component if owners.component else '',
-      'os': owners.os if owners.os else '',
+      'team': dir_metadata.team if dir_metadata.team else '',
+      'component': dir_metadata.component if dir_metadata.component else '',
+      'os': dir_metadata.os if dir_metadata.os else '',
       'lines_of_code': str(git_data.lines_of_code),
       'number_of_files': str(git_data.number_of_files),
       'latest_cl_date': git_data.latest_cl_date,
diff --git a/tools/cfi/ignores.txt b/tools/cfi/ignores.txt
index e0fe3a6..63160e2 100644
--- a/tools/cfi/ignores.txt
+++ b/tools/cfi/ignores.txt
@@ -41,6 +41,9 @@
 # Vulkan memory allocator
 src:*third_party/vulkan_memory_allocator/src/vk_mem_alloc.h
 
+# https://llvm.org/pr48993
+fun:*shared_ptr_emplace*__get_elem*
+
 #############################################################################
 # Base class's constructor accesses a derived class.
 
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
index 2f99c18..22d0b00 100644
--- a/tools/gritsettings/resource_ids.spec
+++ b/tools/gritsettings/resource_ids.spec
@@ -251,6 +251,10 @@
     "META": {"sizes": {"includes": [10],}},
     "includes": [2050],
   },
+  "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/chromeos/network_ui/network_ui_resources.grd": {
+    "META": {"sizes": {"includes": [10]}},
+    "includes": [2065],
+  },
   "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/gaia_auth_host/resources.grd": {
     "META": {"sizes": {"includes": [10],}},
     "includes": [2080],
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 71679c0..f2216f4 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -556,6 +556,7 @@
       'android-builder-perf': 'official_goma_minimal_symbols_android',
       'chromeos-amd64-generic-lacros-builder-perf': 'chromeos_amd64-generic_lacros_official',
       'linux-builder-perf': 'official_goma_linux_perf',
+      'linux-builder-perf-rel': 'official_goma_linux_perf',
       'mac-builder-perf': 'official_goma_mac_perf',
       'mac-arm-builder-perf': 'official_goma_mac_arm_perf',
       'win32-builder-perf': 'official_goma_x86_perf',
@@ -1512,7 +1513,7 @@
     ],
 
     'angle_specific_release_trybot_ios': [
-      'angle_specific_tests', 'release_trybot', 'ios', 'ios_simulator', 'ios_cpu_x64', 'xctest',
+      'angle_specific_tests', 'release_trybot', 'ios', 'ios_simulator', 'ios_cpu_x64', 'xctest', 'ios_disable_xcode_project_generation',
     ],
 
     'angle_specific_release_trybot_x86': [
@@ -1759,11 +1760,11 @@
     ],
 
     'clang_code_coverage_ios_xctest': [
-      'use_clang_coverage', 'debug_static_bot', 'x64', 'ios', 'xctest',
+      'use_clang_coverage', 'debug_static_bot', 'x64', 'ios', 'xctest', 'ios_disable_xcode_project_generation',
     ],
 
     'ios_simulator_code_coverage_partial_instrumentation_xctest': [
-      'use_clang_coverage', 'debug_static_bot', 'x64', 'ios', 'ios_simulator', 'partial_code_coverage_instrumentation', 'xctest',
+      'use_clang_coverage', 'debug_static_bot', 'x64', 'ios', 'ios_simulator', 'partial_code_coverage_instrumentation', 'xctest', 'ios_disable_xcode_project_generation',
     ],
 
     'clang_tot_asan_lsan_static_release': [
@@ -2189,40 +2190,40 @@
     'ios_error': [ 'error'],
 
     'ios_clang_tot_xctest': [
-      'clang_tot', 'ios', 'ios_simulator', 'ios_cpu_x64', 'ios_disable_code_signing', 'release', 'static', 'xctest',
+      'clang_tot', 'ios', 'ios_simulator', 'ios_cpu_x64', 'ios_disable_code_signing', 'release', 'static', 'xctest', 'ios_disable_xcode_project_generation',
     ],
 
     'ios_clang_device_tot_xctest': [
-      'clang_tot', 'ios', 'ios_device', 'ios_cpu_arm64', 'release', 'ios_chromium_cert', 'xctest',
+      'clang_tot', 'ios', 'ios_device', 'ios_cpu_arm64', 'release', 'ios_chromium_cert', 'xctest', 'ios_disable_xcode_project_generation',
     ],
 
     'ios_cronet_xctest': [
-      'cronet_ios', 'debug_static_bot', 'ios_deployment_target_10_0', 'ios', 'ios_simulator', 'ios_cpu_x64_x86', 'xctest',
+      'cronet_ios', 'debug_static_bot', 'ios_deployment_target_10_0', 'ios', 'ios_simulator', 'ios_cpu_x64_x86', 'xctest', 'ios_disable_xcode_project_generation',
     ],
 
     'ios_device_release_compile_only': [
-        'compile_only', 'ios', 'ios_device', 'ios_cpu_arm64', 'ios_google_cert', 'ios_disable_code_signing', 'release_bot'
+        'compile_only', 'ios', 'ios_device', 'ios_cpu_arm64', 'ios_google_cert', 'ios_disable_code_signing', 'release_bot', 'ios_disable_xcode_project_generation',
     ],
 
     # doesn't have symbol_level=0
     'ios_device_release_static_bot_xctest': [
-        'ios', 'ios_device', 'ios_cpu_arm64', 'ios_disable_code_signing', 'release_bot', 'xctest',
+        'ios', 'ios_device', 'ios_cpu_arm64', 'ios_disable_code_signing', 'release_bot', 'xctest', 'ios_disable_xcode_project_generation',
     ],
 
     'ios_simulator_debug_static_bot_xctest': [
-        'debug_static_bot', 'ios', 'ios_simulator', 'ios_cpu_x64', 'xctest',
+        'debug_static_bot', 'ios', 'ios_simulator', 'ios_cpu_x64', 'xctest', 'ios_disable_xcode_project_generation',
     ],
 
     'ios_simulator_debug_static_bot_invert_fieldtrials_xctest': [
-        'debug_static_bot', 'ios', 'ios_simulator', 'ios_cpu_x64', 'invert_fieldtrials', 'xctest',
+        'debug_static_bot', 'ios', 'ios_simulator', 'ios_cpu_x64', 'invert_fieldtrials', 'xctest', 'ios_disable_xcode_project_generation',
     ],
 
     'ios_simulator_debug_static_bot_multi_window_xctest': [
-        'debug_static_bot', 'ios_enable_multi_window', 'ios', 'ios_simulator', 'ios_cpu_x64', 'xctest',
+        'debug_static_bot', 'ios_enable_multi_window', 'ios', 'ios_simulator', 'ios_cpu_x64', 'xctest', 'ios_disable_xcode_project_generation',
     ],
 
     'ios_simulator_release_static_asan_bot_xctest': [
-        'ios', 'ios_simulator', 'ios_cpu_x64', 'release_bot', 'asan', 'xctest',
+        'ios', 'ios_simulator', 'ios_cpu_x64', 'release_bot', 'asan', 'xctest', 'ios_disable_xcode_project_generation',
     ],
 
     'lacros_on_linux_release_bot': [
@@ -3087,6 +3088,11 @@
       'gn_args': 'ios_enable_multi_window=true'
     },
 
+    'ios_disable_xcode_project_generation': {
+      # defaults to true under build/config/ios/rules.gni
+      'gn_args': 'ios_set_attributes_for_xcode_project_generation=false',
+    },
+
     'mbi_mode_per_render_process_host': {
       'gn_args': 'mbi_mode=\"per_render_process_host\"',
     },
diff --git a/tools/mb/mb_config_expectations/chromium.angle.json b/tools/mb/mb_config_expectations/chromium.angle.json
index e796400c9..402c2e3 100644
--- a/tools/mb/mb_config_expectations/chromium.angle.json
+++ b/tools/mb/mb_config_expectations/chromium.angle.json
@@ -96,6 +96,7 @@
       "build_angle_trace_perf_tests": true,
       "dcheck_always_on": true,
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": false,
       "symbol_level": 1,
diff --git a/tools/mb/mb_config_expectations/chromium.clang.json b/tools/mb/mb_config_expectations/chromium.clang.json
index 1a0392c..c7818fd3 100644
--- a/tools/mb/mb_config_expectations/chromium.clang.json
+++ b/tools/mb/mb_config_expectations/chromium.clang.json
@@ -413,6 +413,7 @@
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
       "ios_enable_code_signing": false,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_clang": true,
       "is_component_build": false,
       "is_debug": false,
@@ -426,6 +427,7 @@
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
       "ios_code_signing_identity_description": "iPhone Developer",
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_clang": true,
       "is_debug": false,
       "llvm_force_head_revision": true,
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json
index 640541f5..b782e27 100644
--- a/tools/mb/mb_config_expectations/chromium.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -360,6 +360,7 @@
   "ios-asan": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_asan": true,
       "is_component_build": false,
       "is_debug": false,
@@ -372,6 +373,7 @@
   "ios-simulator-code-coverage": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -384,6 +386,7 @@
   "ios-simulator-cr-recipe": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -406,6 +409,7 @@
       "enable_websockets": false,
       "include_transport_security_state_preload_list": false,
       "ios_deployment_target": "10.0",
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_cronet_build": true,
       "is_debug": true,
@@ -423,6 +427,7 @@
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
       "ios_enable_multi_window": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -435,6 +440,7 @@
   "ios-webkit-tot": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -447,6 +453,7 @@
   "ios13-beta-simulator": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -460,6 +467,7 @@
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
       "ios_enable_code_signing": false,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": false,
       "target_cpu": "arm64",
@@ -471,6 +479,7 @@
   "ios13-sdk-simulator": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -483,6 +492,7 @@
   "ios14-beta-simulator": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -495,6 +505,7 @@
   "ios14-sdk-simulator": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
diff --git a/tools/mb/mb_config_expectations/chromium.goma.fyi.json b/tools/mb/mb_config_expectations/chromium.goma.fyi.json
index 31df3bb..9361b635 100644
--- a/tools/mb/mb_config_expectations/chromium.goma.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.goma.fyi.json
@@ -115,6 +115,7 @@
     "gn_args": {
       "ios_code_signing_identity_description": "Apple Development",
       "ios_enable_code_signing": false,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": false,
       "symbol_level": 0,
@@ -128,6 +129,7 @@
     "gn_args": {
       "ios_code_signing_identity_description": "Apple Development",
       "ios_enable_code_signing": false,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": false,
       "symbol_level": 0,
diff --git a/tools/mb/mb_config_expectations/chromium.goma.json b/tools/mb/mb_config_expectations/chromium.goma.json
index d9b484f8..a033691 100644
--- a/tools/mb/mb_config_expectations/chromium.goma.json
+++ b/tools/mb/mb_config_expectations/chromium.goma.json
@@ -153,6 +153,7 @@
     "gn_args": {
       "ios_code_signing_identity_description": "Apple Development",
       "ios_enable_code_signing": false,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": false,
       "symbol_level": 0,
diff --git a/tools/mb/mb_config_expectations/chromium.mac.json b/tools/mb/mb_config_expectations/chromium.mac.json
index e22df37..c7193ab 100644
--- a/tools/mb/mb_config_expectations/chromium.mac.json
+++ b/tools/mb/mb_config_expectations/chromium.mac.json
@@ -24,6 +24,7 @@
     "gn_args": {
       "ios_code_signing_identity_description": "Apple Development",
       "ios_enable_code_signing": false,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": false,
       "symbol_level": 0,
@@ -36,6 +37,7 @@
   "ios-simulator": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -48,6 +50,7 @@
   "ios-simulator-full-configs": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -60,6 +63,7 @@
   "ios-simulator-noncq": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
diff --git a/tools/mb/mb_config_expectations/chromium.perf.json b/tools/mb/mb_config_expectations/chromium.perf.json
index 75496fd..5cc14f66 100644
--- a/tools/mb/mb_config_expectations/chromium.perf.json
+++ b/tools/mb/mb_config_expectations/chromium.perf.json
@@ -87,6 +87,15 @@
       "use_goma": true
     }
   },
+  "linux-builder-perf-rel": {
+    "gn_args": {
+      "is_chrome_branded": true,
+      "is_official_build": true,
+      "symbol_level": 1,
+      "use_gnome_keyring": false,
+      "use_goma": true
+    }
+  },
   "mac-arm-builder-perf": {
     "gn_args": {
       "enable_keystone_registration_framework": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.angle.json b/tools/mb/mb_config_expectations/tryserver.chromium.angle.json
index d855b9d..814acf89 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.angle.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.angle.json
@@ -113,6 +113,7 @@
       "build_angle_trace_perf_tests": true,
       "dcheck_always_on": true,
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": false,
       "symbol_level": 1,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.mac.json b/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
index bfaacd1..bfef7290 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
@@ -225,6 +225,7 @@
     "gn_args": {
       "ios_code_signing_identity_description": "Apple Development",
       "ios_enable_code_signing": false,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": false,
       "symbol_level": 0,
@@ -238,6 +239,7 @@
     "gn_args": {
       "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt",
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -251,6 +253,7 @@
   "ios-simulator-cr-recipe": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -273,6 +276,7 @@
       "enable_websockets": false,
       "include_transport_security_state_preload_list": false,
       "ios_deployment_target": "10.0",
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_cronet_build": true,
       "is_debug": true,
@@ -290,6 +294,7 @@
     "gn_args": {
       "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt",
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -304,6 +309,7 @@
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
       "invert_fieldtrials": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -317,6 +323,7 @@
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
       "ios_enable_multi_window": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -329,6 +336,7 @@
   "ios-simulator-noncq": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -341,6 +349,7 @@
   "ios13-beta-simulator": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -353,6 +362,7 @@
   "ios13-sdk-simulator": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -365,6 +375,7 @@
   "ios14-beta-simulator": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
@@ -377,6 +388,7 @@
   "ios14-sdk-simulator": {
     "gn_args": {
       "enable_run_ios_unittests_with_xctest": true,
+      "ios_set_attributes_for_xcode_project_generation": false,
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 559c1f88..e95ad38 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -8322,6 +8322,11 @@
   <int value="1" label="Is malware"/>
 </enum>
 
+<enum name="BooleanIsMimeTypeApk">
+  <int value="0" label="Not apk"/>
+  <int value="1" label="Apk"/>
+</enum>
+
 <enum name="BooleanIsMobileOptimized">
   <int value="0" label="Not mobile optimized web page"/>
   <int value="1" label="Mobile optimized web page"/>
@@ -26999,14 +27004,20 @@
   <int value="25" label="INVALID_PATH_FOR_BITMAP_IMAGE"/>
   <int value="26" label="ERROR_RE_ENCODING_THEME_IMAGE"/>
   <int value="27" label="ERROR_SAVING_THEME_IMAGE"/>
-  <int value="28" label="COULD_NOT_READ_CATALOG_DATA_FROM_DISK"/>
-  <int value="29" label="INVALID_CATALOG_DATA"/>
-  <int value="30" label="INVALID_PATH_FOR_CATALOG"/>
-  <int value="31" label="ERROR_SERIALIZING_CATALOG"/>
-  <int value="32" label="ERROR_SAVING_CATALOG"/>
-  <int value="33" label="CRX_HASH_VERIFICATION_FAILED"/>
-  <int value="34" label="CRX_FILE_IS_DELTA_UPDATE"/>
-  <int value="35" label="CRX_EXPECTED_HASH_INVALID"/>
+  <int value="28" label="DEPRECATED_ABORTED_DUE_TO_SHUTDOWN"/>
+  <int value="29" label="COULD_NOT_READ_CATALOG_DATA_FROM_DISK"/>
+  <int value="30" label="INVALID_CATALOG_DATA"/>
+  <int value="31" label="INVALID_PATH_FOR_CATALOG"/>
+  <int value="32" label="ERROR_SERIALIZING_CATALOG"/>
+  <int value="33" label="ERROR_SAVING_CATALOG"/>
+  <int value="34" label="CRX_HASH_VERIFICATION_FAILED"/>
+  <int value="35" label="UNZIP_FAILED"/>
+  <int value="36" label="DIRECTORY_MOVE_FAILED"/>
+  <int value="37" label="CRX_FILE_IS_DELTA_UPDATE"/>
+  <int value="38" label="CRX_EXPECTED_HASH_INVALID"/>
+  <int value="39" label="DEPRECATED_ERROR_PARSING_DNR_RULESET"/>
+  <int value="40" label="ERROR_INDEXING_DNR_RULESET"/>
+  <int value="41" label="CRX_REQUIRED_PROOF_MISSING"/>
 </enum>
 
 <enum name="ExtensionUpdateCheckDataKey">
@@ -35650,16 +35661,16 @@
   <int value="0" label="Success"/>
   <int value="1" label="kInvalidClientId"/>
   <int value="2" label="kEmptyScopes"/>
-  <int value="3" label="kOAuth2InvalidScopes"/>
-  <int value="4" label="kGaiaFlowAuthFailure"/>
+  <int value="3" label="kOAuth2InvalidScopes (deprecated 02/2021)"/>
+  <int value="4" label="kGaiaFlowAuthFailure (deprecated 02/2021)"/>
   <int value="5" label="kMintTokenAuthFailure"/>
   <int value="6" label="kGetAccessTokenAuthFailure"/>
-  <int value="7" label="kOAuth2Failure"/>
+  <int value="7" label="kOAuth2Failure (deprecated 02/2021)"/>
   <int value="8" label="kNoGrant"/>
   <int value="9" label="kInteractionRequired"/>
   <int value="10" label="kInteractionAlreadyRunning"/>
-  <int value="11" label="kOAuth2AccessDenied"/>
-  <int value="12" label="kGaiaFlowRejected"/>
+  <int value="11" label="kOAuth2AccessDenied (deprecated 02/2021)"/>
+  <int value="12" label="kGaiaFlowRejected (deprecated 02/2021)"/>
   <int value="13" label="kRemoteConsentFlowRejected"/>
   <int value="14" label="kUserNotSignedIn"/>
   <int value="15" label="kNotAllowlistedInPublicSession"/>
@@ -35668,9 +35679,9 @@
   <int value="18" label="kUserNonPrimary"/>
   <int value="19" label="kRemoteConsentUserNonPrimary"/>
   <int value="20" label="kBrowserSigninNotAllowed"/>
-  <int value="21" label="kInvalidRedirect"/>
+  <int value="21" label="kInvalidRedirect (deprecated 02/2021)"/>
   <int value="22" label="kOffTheRecord"/>
-  <int value="23" label="kPageLoadFailure"/>
+  <int value="23" label="kPageLoadFailure (deprecated 02/2021)"/>
   <int value="24" label="kRemoteConsentPageLoadFailure"/>
   <int value="25" label="kSetAccountsInCookieFailure"/>
   <int value="26" label="kInvalidConsentResult"/>
@@ -54955,13 +54966,13 @@
 
 <enum name="OAuth2MintTokenApiCallResult">
   <int value="0" label="Mint token success"/>
-  <int value="1" label="Issue advice success"/>
+  <int value="1" label="Issue advice success (deprecated 02/2021)"/>
   <int value="2" label="Remote consent success"/>
   <int value="3" label="Api call failure"/>
   <int value="4" label="Parse JSON failure"/>
   <int value="5" label="&quot;issueAdvice&quot; key not found"/>
   <int value="6" label="Parse mint token failure"/>
-  <int value="7" label="Parse issue advice failure"/>
+  <int value="7" label="Parse issue advice failure (deprecated 02/2021)"/>
   <int value="8" label="Remote consent fallback (deprecated 06/2020)"/>
   <int value="9" label="Parse remote consent failure"/>
   <int value="10" label="Mint token success with fallback scopes"/>
@@ -59198,6 +59209,12 @@
   <int value="9" label="SetLocalAnswerResolved"/>
 </enum>
 
+<enum name="PeerConnectionBundlePolicy">
+  <int value="0" label="balanced"/>
+  <int value="1" label="max-bundle"/>
+  <int value="2" label="max-compat"/>
+</enum>
+
 <enum name="PeerConnectionBundleUsage">
   <int value="0" label="There are no m-lines"/>
   <int value="1" label="No BUNDLE, datachannel-only"/>
@@ -67427,6 +67444,14 @@
   <int value="8" label="SKIPPED_VERSION_CHECK_EQUAL"/>
 </enum>
 
+<enum name="SBMetricsCollectorEventType">
+  <int value="0" label="USER_STATE_DISABLED"/>
+  <int value="1" label="USER_STATE_ENABLED"/>
+  <int value="2" label="DATABASE_INTERSTITIAL_BYPASS"/>
+  <int value="3" label="CSD_INTERSITITAL_BYPASS"/>
+  <int value="4" label="REAL_TIME_INTERSTITIAL_BYPASS"/>
+</enum>
+
 <enum name="SBPhishingClassifierEvent">
   <int value="0" label="Phishing detection was requested to start"/>
   <int value="1" label="Page text was captured"/>
@@ -68795,6 +68820,17 @@
   <int value="19" label="Clear data on site details page"/>
 </enum>
 
+<enum name="SettingsPrivacySandboxEnabled">
+  <int value="0" label="PS enabled, allow all cookies"/>
+  <int value="1" label="PS enabled, block 3P cookies"/>
+  <int value="2" label="PS enabled, block all cookies"/>
+  <int value="3" label="PS disabled, allow all cookies"/>
+  <int value="4" label="PS disabled, block 3P cookies"/>
+  <int value="5" label="PS disabled, block all cookies"/>
+  <int value="6" label="PS disabled, policy block 3P cookies"/>
+  <int value="7" label="PS disabled, policy block all cookies"/>
+</enum>
+
 <enum name="SettingsResetPromptConfigError">
   <int value="1" label="Config Ok"/>
   <int value="2" label="Missing domain_hashes param"/>
@@ -72574,11 +72610,15 @@
 </enum>
 
 <enum name="StructuredMetricsInternalError">
-  <int value="0" label="Missing key"/>
+  <int value="0" label="Missing key (deprecated)"/>
   <int value="1" label="Wrong key length"/>
   <int value="2" label="Missing last rotation"/>
   <int value="3" label="Missing rotation period"/>
   <int value="4" label="Failed uint conversion"/>
+  <int value="5" label="Failed key read error"/>
+  <int value="6" label="Failed key parse error"/>
+  <int value="7" label="Failed key write error"/>
+  <int value="8" label="Failed key serialization"/>
 </enum>
 
 <enum name="StructuredMetricsKeyValidationState">
diff --git a/tools/metrics/histograms/histograms_xml/ash/histograms.xml b/tools/metrics/histograms/histograms_xml/ash/histograms.xml
index 7913fb1..16dfa409 100644
--- a/tools/metrics/histograms/histograms_xml/ash/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/ash/histograms.xml
@@ -1213,10 +1213,13 @@
   </summary>
 </histogram>
 
-<histogram name="Ash.LoginAnimation.Duration" units="ms"
+<histogram base="true" name="Ash.LoginAnimation.Duration" units="ms"
     expires_after="2021-12-10">
   <owner>oshima@chromium.org</owner>
   <owner>chromeos-wmp@google.com</owner>
+<!-- Name completed by histogram_suffixes
+     name="TabletOrClamshellMode" -->
+
   <summary>
     The duration of how long it took to finish all animations applied during the
     login process, from the time the first animation is added, to the time the
@@ -1224,19 +1227,26 @@
   </summary>
 </histogram>
 
-<histogram name="Ash.LoginAnimation.Jank" units="%" expires_after="2021-12-10">
+<histogram base="true" name="Ash.LoginAnimation.Jank" units="%"
+    expires_after="2021-12-10">
   <owner>oshima@chromium.org</owner>
   <owner>chromeos-wmp@google.com</owner>
+<!-- Name completed by histogram_suffixes
+     name="TabletOrClamshellMode" -->
+
   <summary>
     Jank metrics of all animations applied during the login process. This
     represents how often the frame update rate changed during animation.
   </summary>
 </histogram>
 
-<histogram name="Ash.LoginAnimation.Smoothness" units="%"
+<histogram base="true" name="Ash.LoginAnimation.Smoothness" units="%"
     expires_after="2021-12-10">
   <owner>oshima@chromium.org</owner>
   <owner>chromeos-wmp@google.com</owner>
+<!-- Name completed by histogram_suffixes
+     name="TabletOrClamshellMode" -->
+
   <summary>
     Relative smoothness of all animations applied during the login process. 100%
     represents the ideal smoothness for 60 frames per second.
@@ -2200,19 +2210,26 @@
   </summary>
 </histogram>
 
-<histogram name="Ash.UnlockAnimation.Jank" units="%" expires_after="2021-12-10">
+<histogram base="true" name="Ash.UnlockAnimation.Jank" units="%"
+    expires_after="2021-12-10">
   <owner>oshima@chromium.org</owner>
   <owner>chromeos-wmp@google.com</owner>
+<!-- Name completed by histogram_suffixes
+     name="TabletOrClamshellMode" -->
+
   <summary>
     Jank metrics of all animations applied during the unlock process. This
     represents how often the frame update rate changed during animation.
   </summary>
 </histogram>
 
-<histogram name="Ash.UnlockAnimation.Smoothness" units="%"
+<histogram base="true" name="Ash.UnlockAnimation.Smoothness" units="%"
     expires_after="2021-12-10">
   <owner>oshima@chromium.org</owner>
   <owner>chromeos-wmp@google.com</owner>
+<!-- Name completed by histogram_suffixes
+     name="TabletOrClamshellMode" -->
+
   <summary>
     Relative smoothness of all animations applied during the unlock process.
     100% represents the ideal smoothness for 60 frames per second.
diff --git a/tools/metrics/histograms/histograms_xml/blink/histograms.xml b/tools/metrics/histograms/histograms_xml/blink/histograms.xml
index aff5075..ef7309a5 100644
--- a/tools/metrics/histograms/histograms_xml/blink/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/blink/histograms.xml
@@ -227,7 +227,7 @@
 </histogram>
 
 <histogram name="Blink.Canvas.RasterDuration" units="microseconds"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>aaronhk@chromium.org</owner>
   <owner>fserb@chromium.org</owner>
   <summary>
@@ -2734,7 +2734,7 @@
 </histogram>
 
 <histogram name="BlinkGC.TimeForIncrementalMarking" units="ms"
-    expires_after="M92">
+    expires_after="2021-08-08">
   <owner>mlippautz@chromium.org</owner>
   <owner>oilpan-reviews@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/browser/histograms.xml b/tools/metrics/histograms/histograms_xml/browser/histograms.xml
index f1cef713..de8c740 100644
--- a/tools/metrics/histograms/histograms_xml/browser/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/browser/histograms.xml
@@ -810,7 +810,7 @@
 </histogram>
 
 <histogram name="BrowserSwitcher.LaunchTime" units="ms"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>nicolaso@chromium.org</owner>
   <owner>pastarmovj@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/crypt/histograms.xml b/tools/metrics/histograms/histograms_xml/crypt/histograms.xml
index 9fd801062..626966ff1 100644
--- a/tools/metrics/histograms/histograms_xml/crypt/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/crypt/histograms.xml
@@ -65,7 +65,7 @@
 </histogram>
 
 <histogram name="CryptAuth.DeviceSync.Result" enum="BooleanSuccess"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>hansberry@chromium.org</owner>
   <owner>better-together-dev@google.com</owner>
   <summary>Indicates success of performing a DeviceSync.</summary>
@@ -719,7 +719,7 @@
 </histogram>
 
 <histogram name="CryptAuth.Enrollment.Result" enum="BooleanSuccess"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>nohle@chromium.org</owner>
   <owner>better-together-dev@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/custom_tabs/histograms.xml b/tools/metrics/histograms/histograms_xml/custom_tabs/histograms.xml
index f49cf20..990af8e 100644
--- a/tools/metrics/histograms/histograms_xml/custom_tabs/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/custom_tabs/histograms.xml
@@ -101,7 +101,7 @@
 </histogram>
 
 <histogram name="CustomTabs.DetachedResourceRequest.FinalStatus"
-    enum="NetErrorCodes" expires_after="M92">
+    enum="NetErrorCodes" expires_after="2021-08-08">
   <owner>lizeb@chromium.org</owner>
   <owner>cct-team@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/extensions/histograms.xml b/tools/metrics/histograms/histograms_xml/extensions/histograms.xml
index bab8ce5..b949a206 100644
--- a/tools/metrics/histograms/histograms_xml/extensions/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/extensions/histograms.xml
@@ -1465,6 +1465,10 @@
 
 <histogram name="Extensions.ForceInstalledFailureSandboxUnpackFailureReason"
     enum="ExtensionUnpackFailureReason" expires_after="2021-08-01">
+  <obsolete>
+    Deprecated as of 02/2021 in favour of
+    `Extensions.ForceInstalledFailureSandboxUnpackFailureReason2`.
+  </obsolete>
   <owner>burunduk@chromium.org</owner>
   <owner>swapnilgupta@google.com</owner>
   <owner>managed-devices@google.com</owner>
@@ -1476,6 +1480,22 @@
   </summary>
 </histogram>
 
+<histogram name="Extensions.ForceInstalledFailureSandboxUnpackFailureReason2"
+    enum="ExtensionUnpackFailureReason" expires_after="2021-08-01">
+  <owner>burunduk@chromium.org</owner>
+  <owner>swapnilgupta@google.com</owner>
+  <owner>managed-devices@google.com</owner>
+  <summary>
+    The reason why enterprise policy forced extensions had failed to unpack.
+    Recorded for each forced extension that failed to install after 5 minutes
+    with Extensions.ForceInstalledFailureReason3 equal to
+    CRX_INSTALL_ERROR_SANDBOXED_UNPACKER_FAILURE.
+
+    Replaced Extensions.ForceInstalledFailureSandboxUnpackFailureReason because
+    the enum values were not in sync with the C++ enums.
+  </summary>
+</histogram>
+
 <histogram name="Extensions.ForceInstalledFailureSessionType"
     enum="SessionType" expires_after="2021-08-01">
   <owner>burunduk@chromium.org</owner>
@@ -1795,7 +1815,7 @@
 </histogram>
 
 <histogram name="Extensions.Functions.FailedTime" enum="ExtensionFunctions"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -1806,7 +1826,7 @@
 </histogram>
 
 <histogram name="Extensions.Functions.FailedTotalExecutionTime" units="ms"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -1847,7 +1867,7 @@
 </histogram>
 
 <histogram name="Extensions.Functions.SucceededTime" enum="ExtensionFunctions"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -1858,7 +1878,7 @@
 </histogram>
 
 <histogram name="Extensions.Functions.SucceededTotalExecutionTime" units="ms"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -1871,7 +1891,7 @@
 </histogram>
 
 <histogram name="Extensions.Functions.SynchronousExecutionTime" units="ms"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -3098,6 +3118,10 @@
 
 <histogram name="Extensions.SandboxUnpackFailureReason"
     enum="ExtensionUnpackFailureReason" expires_after="never">
+  <obsolete>
+    Deprecated as of 02/2021 in favour of
+    `Extensions.SandboxUnpackFailureReason2`.
+  </obsolete>
 <!-- expires-never: Monitors core extension installation flows. -->
 
   <owner>rdevlin.cronin@chromium.org</owner>
@@ -3107,6 +3131,20 @@
   </summary>
 </histogram>
 
+<histogram name="Extensions.SandboxUnpackFailureReason2"
+    enum="ExtensionUnpackFailureReason" expires_after="never">
+<!-- expires-never: Monitors core extension installation flows. -->
+
+  <owner>rdevlin.cronin@chromium.org</owner>
+  <owner>extensions-core@chromium.org</owner>
+  <summary>
+    The reason an extension failed to unpack, recorded when a failure occurs.
+
+    Replaced Extensions.SandboxUnpackFailureReason because the enum values were
+    not in sync with the C++ enums.
+  </summary>
+</histogram>
+
 <histogram name="Extensions.SandboxUnpackHashCheck" enum="BooleanValidHashSum"
     expires_after="M85">
   <owner>achuith@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
index 5540024..fa724b5 100644
--- a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
@@ -18878,8 +18878,13 @@
   <affected-histogram name="Apps.StateTransition.Drag.PresentationTime"/>
   <affected-histogram
       name="Apps.StateTransition.Drag.PresentationTime.MaxLatency"/>
+  <affected-histogram name="Ash.LoginAnimation.Duration"/>
+  <affected-histogram name="Ash.LoginAnimation.Jank"/>
+  <affected-histogram name="Ash.LoginAnimation.Smoothness"/>
   <affected-histogram name="Ash.Overview.AnimationSmoothness.Close"/>
   <affected-histogram name="Ash.Overview.WindowDrag.PresentationTime"/>
+  <affected-histogram name="Ash.UnlockAnimation.Jank"/>
+  <affected-histogram name="Ash.UnlockAnimation.Smoothness"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="TabSwitchingType" separator=".">
diff --git a/tools/metrics/histograms/histograms_xml/history/histograms.xml b/tools/metrics/histograms/histograms_xml/history/histograms.xml
index de143b14..8f75e4f 100644
--- a/tools/metrics/histograms/histograms_xml/history/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/history/histograms.xml
@@ -410,7 +410,7 @@
 </histogram>
 
 <histogram name="History.DomainCount1Day" units="domains"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>mpearson@chromium.org</owner>
   <owner>mjzhang@chromium.org</owner>
   <owner>chrome-analysis-team@google.com</owner>
@@ -435,7 +435,7 @@
 </histogram>
 
 <histogram name="History.DomainCount28Day" units="domains"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>mpearson@chromium.org</owner>
   <owner>mjzhang@chromium.org</owner>
   <owner>chrome-analysis-team@google.com</owner>
@@ -461,7 +461,7 @@
 </histogram>
 
 <histogram name="History.DomainCount7Day" units="domains"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>mpearson@chromium.org</owner>
   <owner>mjzhang@chromium.org</owner>
   <owner>chrome-analysis-team@google.com</owner>
diff --git a/tools/metrics/histograms/histograms_xml/media/histograms.xml b/tools/metrics/histograms/histograms_xml/media/histograms.xml
index 9130d71..1403f90 100644
--- a/tools/metrics/histograms/histograms_xml/media/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/media/histograms.xml
@@ -41,7 +41,7 @@
 </histogram>
 
 <histogram name="Media.Android.MediaPlayerSuccess" enum="MediaPlayerExitStatus"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>tguilbert@chromium.org</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>Android: Whether MediaPlayer exited without errors.</summary>
@@ -218,7 +218,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Capture.LowLatencyCallbackError"
-    enum="BooleanError" expires_after="2021-06-06">
+    enum="BooleanError" expires_after="2021-08-08">
   <owner>guidou@chromium.org</owner>
   <owner>olka@chromium.org</owner>
   <summary>
@@ -427,7 +427,7 @@
 </histogram>
 
 <histogram name="Media.Audio.OutputDeviceAuthorizationTime" units="ms"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>armax@chromium.org</owner>
   <owner>guidou@chromium.org</owner>
   <owner>olka@chromium.org</owner>
@@ -541,7 +541,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Render.GetSourceDataTime.WebRTC"
-    units="microseconds" expires_after="2021-06-06">
+    units="microseconds" expires_after="2021-08-08">
   <owner>guidou@chromium.org</owner>
   <owner>armax@chromium.org</owner>
   <summary>
@@ -558,7 +558,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Render.GetSourceDataTimeMax.WebRTC"
-    units="microseconds" expires_after="2021-06-06">
+    units="microseconds" expires_after="2021-08-08">
   <owner>guidou@chromium.org</owner>
   <owner>armax@chromium.org</owner>
   <summary>
@@ -623,7 +623,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Render.OutputDeviceAuthorizationTimedOut"
-    enum="BooleanTimedOut" expires_after="2021-06-06">
+    enum="BooleanTimedOut" expires_after="2021-08-08">
   <owner>guidou@chromium.org</owner>
   <owner>olka@chromium.org</owner>
   <summary>
@@ -633,7 +633,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Render.OutputDeviceStatus"
-    enum="OutputDeviceStatus" expires_after="2021-06-06">
+    enum="OutputDeviceStatus" expires_after="2021-08-08">
   <owner>armax@chromium.org</owner>
   <owner>dalecurtis@chromium.org</owner>
   <owner>guidou@chromium.org</owner>
@@ -655,7 +655,7 @@
 
 <histogram
     name="Media.Audio.Render.SinkCache.GetOutputDeviceInfoCacheUtilization"
-    enum="GetOutputDeviceInfoCacheHit" expires_after="2021-06-06">
+    enum="GetOutputDeviceInfoCacheHit" expires_after="2021-08-08">
   <owner>guidou@chromium.org</owner>
   <owner>olka@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/multi_device/histograms.xml b/tools/metrics/histograms/histograms_xml/multi_device/histograms.xml
index c7e09198..9eb1aa0 100644
--- a/tools/metrics/histograms/histograms_xml/multi_device/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/multi_device/histograms.xml
@@ -22,7 +22,7 @@
 <histograms>
 
 <histogram name="MultiDevice.BetterTogetherSuite.MultiDeviceFeatureState"
-    enum="MultiDevice_FeatureState" expires_after="2021-06-06">
+    enum="MultiDevice_FeatureState" expires_after="2021-08-08">
   <owner>vecore@google.com</owner>
   <owner>better-together-dev@google.com</owner>
   <summary>
@@ -33,7 +33,7 @@
 </histogram>
 
 <histogram name="MultiDevice.DeviceSyncService.FindEligibleDevices.Result"
-    enum="BooleanSuccess" expires_after="2021-06-06">
+    enum="BooleanSuccess" expires_after="2021-08-08">
   <owner>vecore@google.com</owner>
   <owner>better-together-dev@google.com</owner>
   <summary>Result of trying to find eligible devices.</summary>
@@ -177,7 +177,7 @@
 
 <histogram
     name="MultiDevice.SecureChannel.BLE.Performance.StartScanToAuthenticationDuration.Background"
-    units="ms" expires_after="2021-06-06">
+    units="ms" expires_after="2021-08-08">
   <owner>vecore@google.com</owner>
   <owner>better-together-dev@google.com</owner>
   <summary>
@@ -210,7 +210,7 @@
 
 <histogram
     name="MultiDevice.SecureChannel.BLE.Performance.StartScanToReceiveAdvertisementDuration.Background"
-    units="ms" expires_after="2021-06-06">
+    units="ms" expires_after="2021-08-08">
   <owner>vecore@google.com</owner>
   <owner>better-together-dev@google.com</owner>
   <summary>
@@ -375,7 +375,7 @@
 </histogram>
 
 <histogram name="MultiDevice.Setup.HostStatus"
-    enum="MultiDevice_Setup_HostStatus" expires_after="2021-06-06">
+    enum="MultiDevice_Setup_HostStatus" expires_after="2021-08-08">
   <owner>vecore@google.com</owner>
   <owner>better-together-dev@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/net/histograms.xml b/tools/metrics/histograms/histograms_xml/net/histograms.xml
index fe4150c..b366b0e6 100644
--- a/tools/metrics/histograms/histograms_xml/net/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/net/histograms.xml
@@ -1092,7 +1092,7 @@
 </histogram>
 
 <histogram name="Net.DNS.ProbeSequence.NetworkChange.Success.AttemptTime"
-    units="ms" expires_after="2021-04-04">
+    units="ms" expires_after="2021-08-08">
   <owner>ericorth@chromium.org</owner>
   <owner>doh-core@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/oobe/histograms.xml b/tools/metrics/histograms/histograms_xml/oobe/histograms.xml
index 0f74465..fc857fdb 100644
--- a/tools/metrics/histograms/histograms_xml/oobe/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/oobe/histograms.xml
@@ -32,7 +32,7 @@
 </histogram>
 
 <histogram name="OOBE.BootToSignInCompleted" units="ms"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>alemate@chromium.org</owner>
   <owner>rsorokin@chromium.org</owner>
   <owner>cros-oac@google.com</owner>
diff --git a/tools/metrics/histograms/histograms_xml/optimization/histograms.xml b/tools/metrics/histograms/histograms_xml/optimization/histograms.xml
index cf5570b..0f280a6 100644
--- a/tools/metrics/histograms/histograms_xml/optimization/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/optimization/histograms.xml
@@ -452,7 +452,7 @@
 </histogram>
 
 <histogram name="OptimizationGuide.ProcessHintsResult"
-    enum="OptimizationGuideProcessHintsResult" expires_after="2021-06-06">
+    enum="OptimizationGuideProcessHintsResult" expires_after="2021-08-08">
   <owner>mcrouse@chromium.org</owner>
   <owner>sophiechang@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml
index ca43f1a..1b9a6dc 100644
--- a/tools/metrics/histograms/histograms_xml/others/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -12736,7 +12736,7 @@
 </histogram>
 
 <histogram name="ReadingList.WindowDisplayedDuration" units="ms"
-    expires_after="M92">
+    expires_after="2021-08-08">
   <owner>corising@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <summary>
@@ -14221,7 +14221,7 @@
 </histogram>
 
 <histogram name="SignedExchange.LoadResult2" enum="SignedExchangeLoadResult"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>ksakamoto@chromium.org</owner>
   <owner>kinuko@chromium.org</owner>
   <owner>horo@chromium.org</owner>
@@ -17781,7 +17781,7 @@
 </histogram>
 
 <histogram name="WebApp.Preinstalled.DisabledCount" units="apps"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>alancutter@chromium.org</owner>
   <owner>desktop-pwas-team@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/page/histograms.xml b/tools/metrics/histograms/histograms_xml/page/histograms.xml
index a2d2295..ce522962 100644
--- a/tools/metrics/histograms/histograms_xml/page/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/page/histograms.xml
@@ -1610,7 +1610,7 @@
 </histogram>
 
 <histogram name="PageLoad.Internal.ErrorCode" enum="InternalErrorLoadEvent"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>csharrison@chromium.org</owner>
   <owner>bmcquade@chromium.org</owner>
   <summary>
@@ -1829,7 +1829,7 @@
 </histogram>
 
 <histogram name="PageLoad.LayoutInstability.CumulativeShiftScore"
-    units="scorex10" expires_after="2021-06-06">
+    units="scorex10" expires_after="2021-08-08">
   <owner>bmcquade@chromium.org</owner>
   <owner>skobes@chromium.org</owner>
   <summary>
@@ -2106,7 +2106,7 @@
 </histogram>
 
 <histogram name="PageLoad.PaintTiming.NavigationToLargestContentfulPaint"
-    units="ms" expires_after="2021-06-06">
+    units="ms" expires_after="2021-08-08">
   <owner>maxlg@chromium.org</owner>
   <owner>speed-metrics-dev@chromium.org</owner>
   <owner>chrome-analysis-team@google.com</owner>
@@ -2297,7 +2297,7 @@
 </histogram>
 
 <histogram name="PageSerialization.MhtmlGeneration.FinalSaveStatus"
-    enum="MhtmlGenerationFinalSaveStatus" expires_after="2021-06-06">
+    enum="MhtmlGenerationFinalSaveStatus" expires_after="2021-08-08">
   <owner>sclittle@chromium.org</owner>
   <owner>offline-dev@chromium.org</owner>
   <summary>Final status of the MHTML save operation for a page.</summary>
diff --git a/tools/metrics/histograms/histograms_xml/password/histograms.xml b/tools/metrics/histograms/histograms_xml/password/histograms.xml
index 9fff123..d3966b0 100644
--- a/tools/metrics/histograms/histograms_xml/password/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/password/histograms.xml
@@ -711,7 +711,7 @@
 </histogram>
 
 <histogram name="PasswordManager.AutomaticChange.AcceptanceWithoutAutoButton"
-    enum="PasswordCheckResolutionAction" expires_after="M92">
+    enum="PasswordCheckResolutionAction" expires_after="2021-08-08">
   <owner>kolos@chromium.org</owner>
   <owner>battre@chromium.org</owner>
   <summary>
@@ -1313,7 +1313,7 @@
 </histogram>
 
 <histogram name="PasswordManager.IsSyncPasswordHashSaved"
-    enum="IsSyncPasswordHashSaved" expires_after="2021-06-06">
+    enum="IsSyncPasswordHashSaved" expires_after="2021-08-08">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -1634,7 +1634,7 @@
 </histogram>
 
 <histogram name="PasswordManager.NewlySavedPasswordIsGenerated"
-    enum="BooleanNewlySavedPasswordIsGenerated" expires_after="2021-06-06">
+    enum="BooleanNewlySavedPasswordIsGenerated" expires_after="2021-08-08">
   <owner>nepper@chromium.org</owner>
   <owner>battre@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
@@ -1794,6 +1794,9 @@
 
 <histogram name="PasswordManager.PasswordSavedWithManualFallback"
     enum="BooleanPasswordSavedWithFallback" expires_after="2020-05-24">
+  <obsolete>
+    Obsolete since M90.
+  </obsolete>
   <owner>kolos@chromium.org</owner>
   <summary>
     Measures whether users save passwords with automatic prompt or manual
@@ -2246,6 +2249,9 @@
 
 <histogram name="PasswordManager.UsernameCorrectionFound"
     enum="BooleanUsernameCorrectionVote" expires_after="M85">
+  <obsolete>
+    Obsolete since M86.
+  </obsolete>
   <owner>kolos@chromium.org</owner>
   <summary>
     Chrome saves locally all fields a user typed on a sign-up form. If Chrome
@@ -2257,7 +2263,8 @@
 </histogram>
 
 <histogram name="PasswordManager.UsernameDetectionMethod"
-    enum="UsernameDetectionMethod" expires_after="M85">
+    enum="UsernameDetectionMethod" expires_after="M93">
+  <owner>jdoerrie@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
   <summary>
     Measures what method was used for username field detection in the renderer
@@ -2494,7 +2501,7 @@
 </histogram>
 
 <histogram base="true" name="PasswordProtection.RequestOutcome"
-    enum="PasswordProtectionRequestOutcome" expires_after="2021-06-06">
+    enum="PasswordProtectionRequestOutcome" expires_after="2021-08-08">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -2527,7 +2534,7 @@
 </histogram>
 
 <histogram name="PasswordProtection.Verdict" enum="PasswordProtectionVerdict"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/permissions/histograms.xml b/tools/metrics/histograms/histograms_xml/permissions/histograms.xml
index 1dcaaa2..513215c5 100644
--- a/tools/metrics/histograms/histograms_xml/permissions/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/permissions/histograms.xml
@@ -34,7 +34,7 @@
 </histogram>
 
 <histogram name="Permissions.Action.WithDisposition" enum="PermissionAction"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>andypaicu@chromium.org</owner>
   <owner>engedy@chromium.org</owner>
   <owner>hkamila@chromium.org</owner>
@@ -192,7 +192,7 @@
 </histogram>
 
 <histogram name="Permissions.CrowdDeny.PreloadData.VersionAtAbuseCheckTime"
-    units="date" expires_after="2021-06-06">
+    units="date" expires_after="2021-08-08">
   <owner>elklm@chromium.org</owner>
   <owner>src/components/permissions/PERMISSIONS_OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/profile/histograms.xml b/tools/metrics/histograms/histograms_xml/profile/histograms.xml
index b148b3d8..1350583 100644
--- a/tools/metrics/histograms/histograms_xml/profile/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/profile/histograms.xml
@@ -568,6 +568,21 @@
   </summary>
 </histogram>
 
+<histogram name="Profile.SyncCustomizationBubbleDelay" units="ms"
+    expires_after="M93">
+  <owner>jkrcal@chromium.org</owner>
+  <owner>chrome-signin-team@google.com</owner>
+  <summary>
+    The histogram gets recorded for every signed-in profile creation flow where
+    the user enables sync right in the flow. In this case, Chrome needs to check
+    theme sync before showing a profile customization bubble. The recorded value
+    is the delay between the moment sync consent is given and the moment Chrome
+    decides whether to show the customization bubble (if the consent is given in
+    the profile creation flow, the start of the measured interval is actually
+    when a new browser window opens after the consent is given).
+  </summary>
+</histogram>
+
 <histogram name="Profile.SyncCustomize" enum="ProfileSyncCustomize"
     expires_after="M92">
   <owner>msalama@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/renderer4/histograms.xml b/tools/metrics/histograms/histograms_xml/renderer4/histograms.xml
index 2e162cf0..59a2585 100644
--- a/tools/metrics/histograms/histograms_xml/renderer4/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/renderer4/histograms.xml
@@ -133,7 +133,7 @@
 </histogram>
 
 <histogram base="true" name="Renderer4.ImageDecodeTaskDurationUs"
-    units="microseconds" expires_after="2021-06-08">
+    units="microseconds" expires_after="2021-08-08">
 <!-- Name completed by histogram_suffixes name="DecodedImageType" -->
 
 <!-- Name completed by histogram_suffixes name="OutOfRaster" -->
diff --git a/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml b/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml
index 4779869..e8899f8d 100644
--- a/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml
@@ -57,6 +57,16 @@
   </summary>
 </histogram>
 
+<histogram name="SafeBrowsing.AndroidTelemetry.ApkDownload.IsMimeTypeApk"
+    enum="BooleanIsMimeTypeApk" expires_after="2022-02-05">
+  <owner>xinghuilu@chromium.org</owner>
+  <owner>chrome-safebrowsing-alerts@google.com</owner>
+  <summary>
+    Records whether the mime type of the download is apk. Logged each time an
+    apk download report is sent on Android.
+  </summary>
+</histogram>
+
 <histogram name="SafeBrowsing.AndroidTelemetry.ApkDownload.Outcome"
     enum="ApkDownloadTelemetryOutcome" expires_after="2021-07-01">
   <owner>xinghuilu@chromium.org</owner>
@@ -659,6 +669,16 @@
   </summary>
 </histogram>
 
+<histogram name="SafeBrowsing.EsbDisabled.LastBypassEventType"
+    enum="SBMetricsCollectorEventType" expires_after="2022-02-05">
+  <owner>xinghuilu@chromium.org</owner>
+  <owner>chrome-safebrowsing-alerts@google.com</owner>
+  <summary>
+    Records the last bypass event type before a user disables Enhanced Safe
+    Browsing. Logged each time a user disables Enhanced Safe Browsing.
+  </summary>
+</histogram>
+
 <histogram name="SafeBrowsing.FileTypeUpdate.DynamicUpdateResult"
     enum="SBFileTypeUpdateResult" expires_after="2021-06-13">
   <owner>drubery@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/sb_client/histograms.xml b/tools/metrics/histograms/histograms_xml/sb_client/histograms.xml
index 317b325..7211130 100644
--- a/tools/metrics/histograms/histograms_xml/sb_client/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/sb_client/histograms.xml
@@ -471,7 +471,7 @@
 </histogram>
 
 <histogram name="SBClientPhishing.PhishingDetectorResult"
-    enum="ClientSidePhishingResult" expires_after="2021-06-06">
+    enum="ClientSidePhishingResult" expires_after="2021-08-08">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>The result enum received from the renderer-side classifier</summary>
diff --git a/tools/metrics/histograms/histograms_xml/service/histograms.xml b/tools/metrics/histograms/histograms_xml/service/histograms.xml
index b533e27..1939c79 100644
--- a/tools/metrics/histograms/histograms_xml/service/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/service/histograms.xml
@@ -1021,7 +1021,7 @@
 </histogram>
 
 <histogram name="ServiceWorker.StartWorker.Status"
-    enum="ServiceWorkerStatusCode" expires_after="2021-06-06">
+    enum="ServiceWorkerStatusCode" expires_after="2021-08-08">
   <owner>falken@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
   <summary>
@@ -1043,7 +1043,7 @@
 </histogram>
 
 <histogram name="ServiceWorker.StartWorker.Time" units="ms"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>falken@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/settings/histograms.xml b/tools/metrics/histograms/histograms_xml/settings/histograms.xml
index e48b202..6ca0f9c 100644
--- a/tools/metrics/histograms/histograms_xml/settings/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/settings/histograms.xml
@@ -161,6 +161,18 @@
   </summary>
 </histogram>
 
+<histogram name="Settings.PrivacySandbox.Enabled"
+    enum="SettingsPrivacySandboxEnabled" expires_after="M95">
+  <owner>harrisonseean@chromium.org</owner>
+  <owner>msramek@chromium.org</owner>
+  <owner>chrome-friendly-settings@google.com</owner>
+  <summary>
+    Whether or not privacy sandbox apis are enabled, including the current state
+    of cookie settings, and if it is disabled by policy. Recorded on profile
+    startup.
+  </summary>
+</histogram>
+
 <histogram name="Settings.SafetyCheck.ChromeCleanerResult"
     enum="SafetyCheckChromeCleanerStatus" expires_after="M92">
   <owner>rainhard@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/startup/histograms.xml b/tools/metrics/histograms/histograms_xml/startup/histograms.xml
index 9223b5a..5b8314f 100644
--- a/tools/metrics/histograms/histograms_xml/startup/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/startup/histograms.xml
@@ -151,7 +151,7 @@
 </histogram>
 
 <histogram name="Startup.Android.GURLEnsureMainDexInitialized" units="ms"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>mthiesse@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
   <summary>
@@ -648,7 +648,7 @@
 </histogram>
 
 <histogram name="Startup.Temperature" enum="StartupTemperature"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
 <!-- expires-after: Diagnosis metric for changes in StartupTemperature suffix.
      Shouldn't truly expire but kColdStartHardFaultCountThreshold should be
      surveyed yearly. -->
diff --git a/tools/metrics/histograms/histograms_xml/subresource/histograms.xml b/tools/metrics/histograms/histograms_xml/subresource/histograms.xml
index ea4bd236..a76e0c98 100644
--- a/tools/metrics/histograms/histograms_xml/subresource/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/subresource/histograms.xml
@@ -311,7 +311,7 @@
 </histogram>
 
 <histogram name="SubresourceFilter.IndexRuleset.Verify.Status"
-    enum="SubresourceFilterVerifyStatus" expires_after="2021-06-06">
+    enum="SubresourceFilterVerifyStatus" expires_after="2021-08-08">
   <owner>alexmt@chromium.org</owner>
   <owner>chrome-ads-histograms@google.com</owner>
   <summary>
@@ -579,7 +579,7 @@
 </histogram>
 
 <histogram name="SubresourceFilter.SafeBrowsing.TotalCheckTime" units="ms"
-    expires_after="M92">
+    expires_after="2021-08-08">
   <owner>alexmt@chromium.org</owner>
   <owner>chrome-ads-histograms@google.com</owner>
   <summary>
@@ -703,7 +703,7 @@
 </histogram>
 
 <histogram name="SubresourceRedirect.DidCompress.BytesSaved" units="bytes"
-    expires_after="M92">
+    expires_after="2021-08-08">
   <owner>robertogden@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
@@ -713,7 +713,7 @@
 </histogram>
 
 <histogram name="SubresourceRedirect.DidCompress.CompressionPercent" units="%"
-    expires_after="M92">
+    expires_after="2021-08-08">
   <owner>robertogden@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/sync/histograms.xml b/tools/metrics/histograms/histograms_xml/sync/histograms.xml
index bc954e0..b4da8e5b9 100644
--- a/tools/metrics/histograms/histograms_xml/sync/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/sync/histograms.xml
@@ -801,7 +801,7 @@
 </histogram>
 
 <histogram name="Sync.PostedClientToServerMessage"
-    enum="SyncClientToServerMessageContents" expires_after="2021-06-06">
+    enum="SyncClientToServerMessageContents" expires_after="2021-08-08">
   <owner>mastiz@chromium.org</owner>
   <summary>
     Number of network requests issued by sync to the sync server, grouped by
@@ -810,7 +810,7 @@
 </histogram>
 
 <histogram name="Sync.PostedClientToServerMessageError" enum="SyncErrorType"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
 <!-- TODO(crbug.com/1004302): Deprecate once
 Sync.PostedClientToServerMessageError2 has reached Stable (so the two histograms
 can be compared for the same population). -->
diff --git a/tools/metrics/histograms/histograms_xml/tab/histograms.xml b/tools/metrics/histograms/histograms_xml/tab/histograms.xml
index 2ab39b0f..faa38c3 100644
--- a/tools/metrics/histograms/histograms_xml/tab/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/tab/histograms.xml
@@ -271,7 +271,7 @@
 </histogram>
 
 <histogram name="Tab.Preview.TimeToFirstUsableFrameAfterStartCapture"
-    units="ms" expires_after="M92">
+    units="ms" expires_after="2021-08-08">
   <owner>dfried@chromium.org</owner>
   <owner>collinbaker@chromium.org</owner>
   <summary>
@@ -281,7 +281,7 @@
 </histogram>
 
 <histogram name="Tab.Preview.TimeToNotifyObserversAfterCaptureReceived"
-    units="microseconds" expires_after="M92">
+    units="microseconds" expires_after="2021-08-08">
   <owner>dfried@chromium.org</owner>
   <owner>collinbaker@chromium.org</owner>
   <summary>
@@ -295,7 +295,7 @@
 </histogram>
 
 <histogram name="Tab.Preview.TimeToStoreAfterFrameReceived"
-    units="microseconds" expires_after="M92">
+    units="microseconds" expires_after="2021-08-08">
   <owner>dfried@chromium.org</owner>
   <owner>collinbaker@chromium.org</owner>
   <summary>
@@ -307,7 +307,7 @@
 </histogram>
 
 <histogram name="Tab.Preview.TimeToStoreAfterTabSwitch" units="ms"
-    expires_after="M92">
+    expires_after="2021-08-08">
   <owner>dfried@chromium.org</owner>
   <owner>collinbaker@chromium.org</owner>
   <summary>
@@ -1413,7 +1413,7 @@
 </histogram>
 
 <histogram name="Tabs.PersistedTabData.Deserialize.Critical"
-    enum="BooleanSuccess" expires_after="2021-03-25">
+    enum="BooleanSuccess" expires_after="2022-02-07">
   <owner>yusufo@chromium.org</owner>
   <owner>nyquist@chromium.org</owner>
   <owner>dtrainor@chromium.org</owner>
@@ -1426,7 +1426,7 @@
 </histogram>
 
 <histogram name="Tabs.PersistedTabData.Serialize.Critical"
-    enum="BooleanSuccess" expires_after="2021-03-25">
+    enum="BooleanSuccess" expires_after="2022-02-07">
   <owner>yusufo@chromium.org</owner>
   <owner>nyquist@chromium.org</owner>
   <owner>dtrainor@chromium.org</owner>
@@ -1439,7 +1439,7 @@
 </histogram>
 
 <histogram name="Tabs.PersistedTabData.Storage.Delete.File"
-    enum="BooleanSuccess" expires_after="2021-03-25">
+    enum="BooleanSuccess" expires_after="2022-02-07">
   <owner>yusufo@chromium.org</owner>
   <owner>nyquist@chromium.org</owner>
   <owner>dtrainor@chromium.org</owner>
@@ -1452,7 +1452,7 @@
 </histogram>
 
 <histogram name="Tabs.PersistedTabData.Storage.Exists.File"
-    enum="BooleanSuccess" expires_after="2021-03-25">
+    enum="BooleanSuccess" expires_after="2022-02-07">
   <owner>yusufo@chromium.org</owner>
   <owner>nyquist@chromium.org</owner>
   <owner>dtrainor@chromium.org</owner>
@@ -1491,7 +1491,7 @@
 </histogram>
 
 <histogram name="Tabs.PersistedTabData.Storage.Save.File" enum="BooleanSuccess"
-    expires_after="2021-03-25">
+    expires_after="2022-02-07">
   <owner>yusufo@chromium.org</owner>
   <owner>nyquist@chromium.org</owner>
   <owner>dtrainor@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/translate/histograms.xml b/tools/metrics/histograms/histograms_xml/translate/histograms.xml
index 753d907..85877894 100644
--- a/tools/metrics/histograms/histograms_xml/translate/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/translate/histograms.xml
@@ -42,7 +42,7 @@
 </histogram>
 
 <histogram name="Translate.BubbleUiEvent" enum="TranslateBubbleUiEvent"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>groby@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>Tracks UI events related to the translate bubble.</summary>
@@ -92,7 +92,7 @@
 </histogram>
 
 <histogram name="Translate.CompactInfobar.Event" enum="TranslateCompactUIEvent"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>anthonyvd@chromium.org</owner>
   <owner>chrome-language@google.com</owner>
   <summary>Various user actions performed in the translate infobar.</summary>
@@ -293,7 +293,7 @@
 </histogram>
 
 <histogram name="Translate.InitiationStatus.v2"
-    enum="TranslateInitiationStatus" expires_after="2021-06-06">
+    enum="TranslateInitiationStatus" expires_after="2021-08-08">
   <owner>kenjibaheux@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -764,7 +764,7 @@
 </histogram>
 
 <histogram name="Translate.ShowErrorUI" enum="TranslateError"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>kenjibaheux@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -789,7 +789,7 @@
 </histogram>
 
 <histogram name="Translate.SourceLanguage" enum="CLD3LanguageCode"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>yyushkina@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -844,7 +844,7 @@
 </histogram>
 
 <histogram name="Translate.Translate" enum="BooleanTranslate"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>kenjibaheux@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/v8/histograms.xml b/tools/metrics/histograms/histograms_xml/v8/histograms.xml
index aa821aa2..d0df313a 100644
--- a/tools/metrics/histograms/histograms_xml/v8/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/v8/histograms.xml
@@ -137,7 +137,7 @@
 </histogram>
 
 <histogram name="V8.CompileScript.CacheBehaviour" enum="V8CacheBehaviour"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>leszeks@chromium.org</owner>
   <owner>v8-runtime@google.com</owner>
   <summary>
@@ -148,7 +148,7 @@
 </histogram>
 
 <histogram name="V8.CompileScriptMicroSeconds" units="microseconds"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>leszeks@chromium.org</owner>
   <owner>v8-runtime@google.com</owner>
   <summary>
@@ -292,7 +292,7 @@
 </histogram>
 
 <histogram name="V8.CompileScriptMicroSeconds.ProduceCache"
-    units="microseconds" expires_after="2021-06-06">
+    units="microseconds" expires_after="2021-08-08">
   <owner>leszeks@chromium.org</owner>
   <owner>v8-runtime@google.com</owner>
   <summary>
@@ -308,7 +308,7 @@
 </histogram>
 
 <histogram name="V8.CompileScriptMicroSeconds.StreamingFinalization"
-    units="microseconds" expires_after="2021-06-06">
+    units="microseconds" expires_after="2021-08-08">
   <owner>leszeks@chromium.org</owner>
   <owner>v8-runtime@google.com</owner>
   <summary>
@@ -650,7 +650,7 @@
   <summary>Reason a mark-compact garbage collection was started in V8.</summary>
 </histogram>
 
-<histogram name="V8.GCMarkingSum" units="ms" expires_after="2021-06-06">
+<histogram name="V8.GCMarkingSum" units="ms" expires_after="2021-08-08">
   <owner>mlippautz@chromium.org</owner>
   <owner>v8-memory-sheriffs@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/web_apk/histograms.xml b/tools/metrics/histograms/histograms_xml/web_apk/histograms.xml
index 8e36d16..704604e3 100644
--- a/tools/metrics/histograms/histograms_xml/web_apk/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/web_apk/histograms.xml
@@ -276,7 +276,7 @@
 </histogram>
 
 <histogram name="WebApk.Update.GooglePlayUpdateResult"
-    enum="WebApkGooglePlayInstallResult" expires_after="2021-06-06">
+    enum="WebApkGooglePlayInstallResult" expires_after="2021-08-08">
   <owner>hartmanng@chromium.org</owner>
   <owner>
     src/chrome/android/java/src/org/chromium/chrome/browser/webapps/OWNERS
diff --git a/tools/metrics/histograms/histograms_xml/web_core/histograms.xml b/tools/metrics/histograms/histograms_xml/web_core/histograms.xml
index 55bbebf..8512a002 100644
--- a/tools/metrics/histograms/histograms_xml/web_core/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/web_core/histograms.xml
@@ -30,7 +30,7 @@
 </variants>
 
 <histogram name="WebCore.DistillabilityUs" units="microseconds"
-    expires_after="2021-06-06">
+    expires_after="2021-08-08">
   <owner>wychen@chromium.org</owner>
   <owner>gilmanmh@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml b/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml
index 7581665..dc9cebb 100644
--- a/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml
@@ -1187,6 +1187,17 @@
   </summary>
 </histogram>
 
+<histogram name="WebRTC.PeerConnection.BundlePolicy"
+    enum="PeerConnectionBundlePolicy" expires_after="2022-01-01">
+  <owner>hta@chromium.org</owner>
+  <owner>webrtc-dev@chromium.org</owner>
+  <summary>
+    Determines whether BUNDLE is configured. Recorded during DTLS connection
+    establishment which usually happens only once per connection. Values are
+    specified in https://w3c.github.io/webrtc-pc/#dom-rtcbundlepolicy
+  </summary>
+</histogram>
+
 <histogram name="WebRTC.PeerConnection.BundleUsage"
     enum="PeerConnectionBundleUsage" expires_after="2022-01-01">
   <owner>hta@chromium.org</owner>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 21690cd4..9d9aa77 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -7584,8 +7584,9 @@
   </metric>
   <metric name="AudioDecoderName">
     <summary>
-      Enumeration of audio decoder names, zero if none or unknown (Cast, HLS,
-      etc). See WatchTimeRecorder::AudioDecoderName enum for expected values.
+      Enumeration of audio decoder implementations, zero if none or unknown
+      (Cast, HLS, etc). See AudioDecoderType (media/base/decoder.h) for expected
+      values.
     </summary>
   </metric>
   <metric name="AudioEncryptionScheme">
@@ -7697,8 +7698,9 @@
   </metric>
   <metric name="VideoDecoderName">
     <summary>
-      Enumeration of video decoder names, zero if none or unknown (Cast, HLS,
-      etc). See WatchTimeRecorder::VideoDecoderName enum for expected values.
+      Enumeration of video decoder implementations, zero if none or unknown
+      (Cast, HLS, etc). See VideoDecoderType (media/base/decoder.h) for expected
+      values.
     </summary>
   </metric>
   <metric name="VideoEncryptionScheme">
@@ -12067,6 +12069,11 @@
       of the interval: 3900 mAh; - Battery charge at the end of the interval:
       3700 mAh; - Discharge proportion: (3900-3700) / 4000 = 0.05 - Reported
       value: 500.
+
+      There's a few special values: -1 if the device is on AC power during the
+      entirety of the interval, -2 if the device gets plugged or unplugged
+      during the interval, -3 if the battery metrics can't be retrieved or -4 if
+      the system has no battery.
     </summary>
   </metric>
   <metric name="CPUTimeMs">
diff --git a/tools/perf/core/bot_platforms.py b/tools/perf/core/bot_platforms.py
index 2f6d9d5..80bce935 100644
--- a/tools/perf/core/bot_platforms.py
+++ b/tools/perf/core/bot_platforms.py
@@ -287,6 +287,10 @@
                           flags=['--xvfb'],
                           estimated_runtime=estimated_runtime)
 
+_CHROME_HEALTH_BENCHMARK_CONFIGS_DESKTOP = PerfSuite([
+    _GetBenchmarkConfig('system_health.common_desktop')
+])
+
 
 _LINUX_BENCHMARK_CONFIGS = PerfSuite(OFFICIAL_BENCHMARK_CONFIGS).Remove([
     'blink_perf.display_locking',
@@ -464,6 +468,13 @@
     26,
     'linux',
     executables=_LINUX_EXECUTABLE_CONFIGS)
+LINUX_REL = PerfPlatform(
+    'linux-perf-rel',
+    'Ubuntu-14.04, 8 core, NVIDIA Quadro P400',
+    _CHROME_HEALTH_BENCHMARK_CONFIGS_DESKTOP,
+    2,
+    'linux',
+    executables=_LINUX_EXECUTABLE_CONFIGS)
 
 # Mac
 MAC_HIGH_END = PerfPlatform(
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py
index 91f87419..0f6866a 100755
--- a/tools/perf/core/perf_data_generator.py
+++ b/tools/perf/core/perf_data_generator.py
@@ -445,6 +445,9 @@
     'linux-builder-perf': {
         'additional_compile_targets': ['chromedriver', 'chromium_builder_perf'],
     },
+    'linux-builder-perf-rel': {
+        'additional_compile_targets': ['chromedriver', 'chromium_builder_perf'],
+    },
     'mac-builder-perf': {
         'additional_compile_targets': ['chromedriver', 'chromium_builder_perf'],
     },
@@ -661,8 +664,8 @@
             # that we can be informed if this
             # version ever changes or becomes inconsistent. It is important
             # that bots are homogeneous. See crbug.com/988045 for history.
-            'os': 'Windows-10-16299.309',
-            'gpu': '8086:5912-23.20.16.4877',
+            'os': 'Windows-10-18363.476',
+            'gpu': '8086:5912-27.20.100.8681',
             'synthetic_product_name': 'OptiPlex 7050 (Dell Inc.)'
         },
     },
@@ -777,6 +780,24 @@
             'synthetic_product_name': 'PowerEdge R230 (Dell Inc.)'
         },
     },
+    'linux-perf-rel': {
+        'tests': [
+            {
+                'isolate': 'performance_test_suite',
+                'extra_args': [
+                    '--assert-gpu-compositing',
+                ],
+            },
+        ],
+        'platform':
+        'linux',
+        'dimension': {
+            'gpu': '10de:1cb3-440.100',
+            'os': 'Ubuntu-18.04',
+            'pool': 'chrome.tests.perf',
+            'synthetic_product_name': 'PowerEdge R230 (Dell Inc.)'
+        },
+    },
     'mac-10_13_laptop_high_end-perf': {
         'tests': [
             {
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 5fc9753..edc8e4d 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -1,16 +1,16 @@
 {
     "trace_processor_shell": {
         "win": {
-            "hash": "92b847ade5811efcc2b33af2fad902128192b418",
-            "remote_path": "perfetto_binaries/trace_processor_shell/win/c29e801b3fb47a5b682f2d0f417579a55688d1e7/trace_processor_shell.exe"
+            "hash": "05f898ec237791c9d9d6d1901e9cef62888eb944",
+            "remote_path": "perfetto_binaries/trace_processor_shell/win/6a605833d9b393d20d9fee45830dd3997599c2be/trace_processor_shell.exe"
         },
         "mac": {
             "hash": "0802cb84e7fbfe4e104048c5973c6e38e7b62aec",
-            "remote_path": "perfetto_binaries/trace_processor_shell/mac/c29e801b3fb47a5b682f2d0f417579a55688d1e7/trace_processor_shell"
+            "remote_path": "perfetto_binaries/trace_processor_shell/mac/b05d9d92a00eb13527779d8f4fb3324ee1a2a2ee/trace_processor_shell"
         },
         "linux": {
             "hash": "139c8527bd8b2f7b3a9c90f28f6b292cf1cba69e",
-            "remote_path": "perfetto_binaries/trace_processor_shell/linux/b05d9d92a00eb13527779d8f4fb3324ee1a2a2ee/trace_processor_shell"
+            "remote_path": "perfetto_binaries/trace_processor_shell/linux/b3db3ded2c90769dd8c19ec0fb2018691fa9decb/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/perf/core/shard_maps/linux-perf-rel_map.json b/tools/perf/core/shard_maps/linux-perf-rel_map.json
new file mode 100644
index 0000000..95a8010e
--- /dev/null
+++ b/tools/perf/core/shard_maps/linux-perf-rel_map.json
@@ -0,0 +1,56 @@
+{
+    "0": {
+        "benchmarks": {
+            "system_health.common_desktop": {
+                "end": 22,
+                "abridged": false
+            }
+        },
+        "executables": {
+            "base_perftests": {
+                "path": "base_perftests",
+                "arguments": [
+                    "--test-launcher-jobs=1",
+                    "--test-launcher-retry-limit=0"
+                ]
+            },
+            "load_library_perf_tests": {
+                "path": "load_library_perf_tests"
+            },
+            "performance_browser_tests": {
+                "path": "browser_tests",
+                "arguments": [
+                    "--full-performance-run",
+                    "--test-launcher-jobs=1",
+                    "--test-launcher-retry-limit=0",
+                    "--ui-test-action-timeout=60000",
+                    "--ui-test-action-max-timeout=60000",
+                    "--test-launcher-timeout=60000",
+                    "--gtest_filter=*/TabCapturePerformanceTest.*:*/CastV2PerformanceTest.*"
+                ]
+            }
+        }
+    },
+    "1": {
+        "benchmarks": {
+            "system_health.common_desktop": {
+                "begin": 22,
+                "abridged": false
+            }
+        },
+        "executables": {
+            "tracing_perftests": {
+                "path": "tracing_perftests"
+            }
+        }
+    },
+    "extra_infos": {
+        "num_stories": 84,
+        "predicted_min_shard_time": 585.0,
+        "predicted_min_shard_index": 1,
+        "predicted_max_shard_time": 588.0,
+        "predicted_max_shard_index": 0,
+        "shard #0": 588.0,
+        "shard #1": 585.0
+    }
+}
\ No newline at end of file
diff --git a/tools/perf/core/shard_maps/timing_data/linux-perf-rel_timing.json b/tools/perf/core/shard_maps/timing_data/linux-perf-rel_timing.json
new file mode 100644
index 0000000..d547a7a
--- /dev/null
+++ b/tools/perf/core/shard_maps/timing_data/linux-perf-rel_timing.json
@@ -0,0 +1,18 @@
+[
+    {
+        "duration": "3.0",
+        "name": "load_library_perf_tests/_gtest_"
+    },
+    {
+        "duration": "5.0",
+        "name": "tracing_perftests/_gtest_"
+    },
+    {
+        "duration": "165.0",
+        "name": "performance_browser_tests/_gtest_"
+    },
+    {
+        "duration": "200.0",
+        "name": "base_perftests/_gtest_"
+    }
+]
\ No newline at end of file
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index 13ac89f..69d8c2b 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -162,7 +162,6 @@
  <item id="icon_catcher_get_large_icon" added_in_milestone="62" hash_code="44494884" type="0" content_hash_code="98262037" os_list="linux,windows" file_path="components/ntp_tiles/icon_cacher_impl.cc"/>
  <item id="image_annotation" added_in_milestone="73" hash_code="107881858" type="0" content_hash_code="76229990" os_list="linux,windows" file_path="services/image_annotation/annotator.cc"/>
  <item id="indexed_db_internals_handler" added_in_milestone="62" hash_code="131180348" type="0" content_hash_code="59026406" os_list="linux,windows" file_path="content/browser/indexed_db/indexed_db_internals_ui.cc"/>
- <item id="interest_feed_send" added_in_milestone="67" hash_code="76717919" type="0" content_hash_code="6240898" os_list="linux,windows" file_path="components/feed/core/feed_networking_host.cc"/>
  <item id="interest_feedv2_image_send" added_in_milestone="86" hash_code="92245202" type="0" content_hash_code="107508312" os_list="linux,windows" file_path="components/feed/core/v2/image_fetcher.cc"/>
  <item id="interest_feedv2_send" added_in_milestone="83" hash_code="85742023" type="0" content_hash_code="49706671" os_list="linux,windows" file_path="components/feed/core/v2/feed_network_impl.cc"/>
  <item id="intranet_redirect_detector" added_in_milestone="62" hash_code="21785164" type="0" content_hash_code="62025595" os_list="linux,windows" file_path="chrome/browser/intranet_redirect_detector.cc"/>
diff --git a/ui/accessibility/ax_tree_serializer.h b/ui/accessibility/ax_tree_serializer.h
index ddbbdcdc..1790e3b 100644
--- a/ui/accessibility/ax_tree_serializer.h
+++ b/ui/accessibility/ax_tree_serializer.h
@@ -8,6 +8,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <ctime>
 #include <ostream>
 #include <unordered_map>
 #include <unordered_set>
diff --git a/ui/file_manager/file_manager/foreground/elements/BUILD.gn b/ui/file_manager/file_manager/foreground/elements/BUILD.gn
index a578f69..acd4f7f 100644
--- a/ui/file_manager/file_manager/foreground/elements/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/elements/BUILD.gn
@@ -517,6 +517,7 @@
 
   closure_flags =
       strict_error_checking_closure_args + [
+        "generate_exports=false",
         "js_module_root=./gen/ui",
         "js_module_root=../../ui",
         "browser_resolver_prefix_replacements=\"chrome://test/=./\"",
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn
index 5bc69f6..d7770e0 100644
--- a/ui/file_manager/file_manager/foreground/js/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -2095,6 +2095,7 @@
 
   closure_flags =
       strict_error_checking_closure_args + [
+        "generate_exports=false",
         "js_module_root=./gen/ui",
         "js_module_root=../../ui",
         "jscomp_off=duplicate",
diff --git a/ui/file_manager/file_manager/foreground/js/drive_dialog_controller.js b/ui/file_manager/file_manager/foreground/js/drive_dialog_controller.js
index b711a1e..83a2ac9 100644
--- a/ui/file_manager/file_manager/foreground/js/drive_dialog_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/drive_dialog_controller.js
@@ -23,6 +23,10 @@
 
     /** @private {boolean} */
     this.open_ = false;
+
+    // Listen to mount events in order to hide the dialog when Drive shuts down.
+    chrome.fileManagerPrivate.onMountCompleted.addListener(
+        this.onMountCompleted_.bind(this));
   }
 
   /**
@@ -63,4 +67,13 @@
     this.dialog_.show(
         message, () => this.onResult_(true), () => this.onResult_(false));
   }
+
+  onMountCompleted_(event) {
+    if (event.eventType ===
+            chrome.fileManagerPrivate.MountCompletedEventType.UNMOUNT &&
+        event.volumeMetadata.volumeType ===
+            chrome.fileManagerPrivate.VolumeType.DRIVE) {
+      this.dialog_.hide();
+    }
+  }
 }
diff --git a/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn b/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn
index caeb450..2d3d6ac 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn
@@ -1165,6 +1165,7 @@
 
   closure_flags =
       strict_error_checking_closure_args + [
+        "generate_exports=false",
         "js_module_root=./gen/ui",
         "js_module_root=../../ui",
         "jscomp_off=duplicate",
diff --git a/ui/file_manager/integration_tests/file_manager/drive_specific.js b/ui/file_manager/integration_tests/file_manager/drive_specific.js
index 1c4d8a59..b6e3dadf 100644
--- a/ui/file_manager/integration_tests/file_manager/drive_specific.js
+++ b/ui/file_manager/integration_tests/file_manager/drive_specific.js
@@ -949,3 +949,20 @@
   // Check: the last dialog result should be 1 (accept).
   await waitForLastDriveDialogResult('1');
 };
+
+/**
+ * Tests that the Enable Docs Offline dialog disappears when Drive is unmounted.
+ */
+testcase.driveEnableDocsOfflineDialogDisappearsOnUnmount = async () => {
+  // Open Files app on Downloads.
+  const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS);
+
+  // Open the Enable Docs Offline dialog.
+  await openAndWaitForEnableDocsOfflineDialog(appId);
+
+  // Unmount Drive.
+  await sendTestMessage({name: 'unmountDrive'});
+
+  // Check: the Enable Docs Offline dialog should disappear.
+  await remoteCall.waitForElementLost(appId, '.cr-dialog-container.shown');
+};
diff --git a/ui/file_manager/video_player/js/BUILD.gn b/ui/file_manager/video_player/js/BUILD.gn
index c2ad2f7..ad25c71 100644
--- a/ui/file_manager/video_player/js/BUILD.gn
+++ b/ui/file_manager/video_player/js/BUILD.gn
@@ -181,6 +181,7 @@
 
   closure_flags =
       strict_error_checking_closure_args + [
+        "generate_exports=false",
         "js_module_root=./gen/ui",
         "js_module_root=../../ui",
         "browser_resolver_prefix_replacements=\"chrome://test/=./\"",
diff --git a/ui/login/display_manager.js b/ui/login/display_manager.js
index f9631c6..1f5c1605 100644
--- a/ui/login/display_manager.js
+++ b/ui/login/display_manager.js
@@ -271,6 +271,9 @@
     },
 
     setOrientation: function(isHorizontal) {
+      // Below code is also used to set the dialog orientation for in-session
+      // multidevice setup flow and assistant onboarding flow. Please make sure
+      // code changes are applied to all places.
       if (isHorizontal) {
         document.documentElement.setAttribute('orientation', 'horizontal');
       } else {
@@ -279,6 +282,9 @@
     },
 
     setDialogSize: function(width, height) {
+      // Below code is also used to set the dialog size for in-session
+      // multidevice setup flow and assistant onboarding flow. Please make sure
+      // code changes are applied to all places.
       document.documentElement.style.setProperty(
         '--oobe-oobe-dialog-height-base', height + 'px');
       document.documentElement.style.setProperty(
diff --git a/ui/login/oobe.css b/ui/login/oobe.css
index c0f4452..c8ef82e 100644
--- a/ui/login/oobe.css
+++ b/ui/login/oobe.css
@@ -125,89 +125,6 @@
   outline: none;
 }
 
-/* Follow same focus coloring as in widgets.css */
-/* Do not apply this style to restricted button state. */
-button.custom-appearance:not(.button-restricted):not(.button-fancy):not(
-    [is="gaia-icon-button"]) {
-  border: 2px solid transparent;
-  /* Don't grey out disabled buttons. */
-  color: buttontext !important;
-  transition: border-color 200ms;
-}
-
-/* ':focus' used three times to increase specificity. */
-button.custom-appearance:focus:focus:focus {
-  border-color: rgba(66, 133, 244, 0.6); /* #4285f4 */
-}
-
-button:not(.custom-appearance) {
-  min-width: 72px !important;
-}
-
-button.button-fancy {
-  min-width: 72px !important;
-}
-
-button.button-blue {
-  background-image: linear-gradient(rgb(93, 154, 255),
-                                    rgb(93, 154, 255) 38%,
-                                    rgb(88, 145, 240));
-  border: 1px solid rgba(45, 102, 195, 1);
-  border-radius: 2px;
-  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.15), inset 0 1px 2px
-              rgba(255, 255, 255, 0.4);
-  color: #fff;
-  font-size: 14px;
-  margin: 0 1px 0 0;
-  min-height: 2em;
-  min-width: 4em;
-  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5);
-}
-
-
-button.button-blue:hover {
-  background-image: linear-gradient(rgb(101, 158, 253),
-                                    rgb(101, 158, 253) 38%,
-                                    rgb(96, 151, 241));
-  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25), inset 0 1px 2px
-              rgba(255, 255, 255, 0.4);
-}
-
-button.button-blue:active {
-  background-image: linear-gradient(rgb(96, 149, 237),
-                                    rgb(96, 149, 237) 38%,
-                                    rgb(96, 149, 237));
-  border: 1px solid rgba(38, 84, 160, 1);
-  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
-}
-
-button.button-red {
-  background-image: linear-gradient(rgb(221, 75, 57),
-                                    rgb(221, 75, 57) 38%,
-                                    rgb(197, 66, 49));
-  border: 1px solid rgba(167, 57, 44, 1);
-  border-radius: 2px;
-  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.15), inset 0 1px 2px
-      rgba(255, 255, 255, 0.4);
-  color: #fff;
-  margin: 0 1px 0 0;
-  min-height: 2em;
-  min-width: 4em;
-  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.15);
-}
-
-button.button-red:hover {
-  background-image: linear-gradient(rgb(231, 78, 59),
-                                    rgb(231, 78, 59) 38%,
-                                    rgb(209, 70, 52));
-  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25), inset 0 1px 2px
-      rgba(255, 255, 255, 0.4);
-}
-
-button.button-red:active {
-  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
-}
-
 .label,
 .flexible-label {
   display: block;
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/button_bar.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/button_bar.html
index 69ee219..cd25990 100644
--- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/button_bar.html
+++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/button_bar.html
@@ -27,7 +27,7 @@
         }
       }
     </style>
-    <div id="shadow" hidden></div>
+    <div id="shadow" hidden$="[[!shouldShowShadow]]"></div>
     <div id="button-container">
       <div id="backward"
           on-click="onBackwardButtonClicked_"
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/button_bar.js b/ui/webui/resources/cr_components/chromeos/multidevice_setup/button_bar.js
index d3176fc..45d50cd 100644
--- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/button_bar.js
+++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/button_bar.js
@@ -32,8 +32,7 @@
     shouldShowShadow: {
       type: Boolean,
       value: false,
-      observer: 'onShouldShowShadowChange_',
-    }
+    },
   },
 
   /** @private */
@@ -50,9 +49,4 @@
   onBackwardButtonClicked_() {
     this.fire('backward-navigation-requested');
   },
-
-  /** @private */
-  onShouldShowShadowChange_() {
-    this.$.shadow.hidden = !!this.shouldShowShadow;
-  },
 });
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.html
index 7e1ee2c..3070216 100644
--- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.html
+++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.html
@@ -30,15 +30,22 @@
         flex-direction: column;
         font-size: 13px;
         height: 100%;
-        line-height: 16px;
         margin: auto;
-        max-width: var(--multidevice-setup-width, var(--default-ui-width));
-        padding: 32px;
       }
 
       iron-pages {
+        height: 100%;
         overflow: var(--iron-pages-overflow, visible);
-        padding: 0 32px;
+      }
+
+      button-bar {
+        padding: 24px;
+      }
+
+      @media screen and (orientation: portrait) {
+        :host-context(html[screen=oobe]) button-bar {
+          align-items: center;
+        }
       }
 
       @media screen and (max-width: 767px) {
@@ -48,7 +55,6 @@
           /* Add height of buttons plus padding on top and bottom of buttons. */
           margin-bottom: calc(var(--narrow-button-bar-height) +
                               calc(2 * var(--narrow-button-bar-spacing)));
-          padding: 32px 32px 0 32px;
         }
 
         iron-pages {
@@ -95,7 +101,6 @@
             delegate="[[delegate]]">
         </start-setup-page>
       </iron-pages>
-      <div class="flex"></div>
       <button-bar forward-button-hidden="[[!forwardButtonTextId]]"
           backward-button-hidden="[[!backwardButtonTextId]]"
           cancel-button-hidden="[[!cancelButtonTextId]]"
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/password_page.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/password_page.html
index ac75f0e..3fd567d 100644
--- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/password_page.html
+++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/password_page.html
@@ -10,6 +10,12 @@
 <dom-module id="password-page">
   <template>
     <style include="multidevice-setup-shared">
+      #content-container {
+        display: flex;
+        flex: 1;
+        flex-direction: column;
+      }
+
       #user-info-container  {
         align-items: center;
         color: var(--paper-grey-600);
@@ -28,6 +34,12 @@
         margin-top: 64px;
         width: 100%;
       }
+
+      @media screen and (orientation: landscape) {
+        #user-info-container {
+          padding-top: 72px;
+        }
+      }
     </style>
     <ui-page header-text="[[i18nDynamic(locale, 'passwordPageHeader')]]"
         icon-name="google-g">
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/setup_succeeded_page.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/setup_succeeded_page.html
index 37f85df..2105228 100644
--- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/setup_succeeded_page.html
+++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/setup_succeeded_page.html
@@ -10,7 +10,9 @@
   <template>
     <style include="multidevice-setup-shared">
       #page-icon-container {
+        align-items: center;
         display: flex;
+        flex: 1;
         justify-content: center;
       }
 
@@ -19,7 +21,6 @@
                               url(setup_succeeded_icon_1x.png) 1x,
                               url(setup_succeeded_icon_2x.png) 2x);
         height: 156px;
-        margin-top: 64px;
         width: 416px;
       }
     </style>
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/start_setup_page.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/start_setup_page.html
index f3b5939a..153297c 100644
--- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/start_setup_page.html
+++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/start_setup_page.html
@@ -15,7 +15,7 @@
     <style include="multidevice-setup-shared">
       #selector-and-details-container {
         display: flex;
-        margin-top: 20px;
+        flex-direction: column;
         min-height: 246px;
       }
 
@@ -49,14 +49,13 @@
         color: var(--paper-grey-600);
         display: flex;
         flex-direction: column;
+        margin-top: 18px;
       }
 
       #feature-details-container {
-        border-inline-start: 1px solid rgb(218, 220, 224);
         display: flex;
         flex-direction: column;
         justify-content: center;
-        padding-inline-start: 24px;
       }
 
       #feature-details-container-header {
@@ -67,7 +66,7 @@
         align-items: center;
         box-sizing: border-box;
         display: flex;
-        padding: 10px 0;
+        min-height: 36px;
       }
 
       .feature-detail iron-icon {
@@ -89,22 +88,14 @@
         display: inline-block;
       }
 
-      /* On devices with small screens, use a single-column layout. */
-      @media screen and (max-width: 767px) {
-        #selector-and-details-container {
-          display: flex;
-          flex-direction: column;
-          margin-top: 32px;
-        }
+      #additional-content-container {
+        display: flex;
+        flex-direction: column;
+      }
 
-        #feature-details-container {
-          border-inline-start: none;
-          margin-top: 32px;
-          padding-inline-start: inherit;
-        }
-
-        .feature-detail {
-          min-height: 45px;
+      @media screen and (orientation: landscape) {
+        #additional-content-container {
+          justify-content: center;
         }
       }
     </style>
@@ -114,36 +105,8 @@
       <span slot="message" id="multidevice-summary-message" inner-h-t-m-l=
           "[[i18nAdvancedDynamic_(locale, 'startSetupPageMessage')]]">
       </span>
-      <div slot="additional-content">
+      <div id="additional-content-container" slot="additional-content">
         <div id="selector-and-details-container">
-          <div id="deviceSelectionContainer" class="flex">
-            [[getDeviceSelectionHeader_(devices)]]
-            <div id="singleDeviceName"
-                hidden$="[[!doesDeviceListHaveOneElement_(devices)]]">
-              [[getFirstDeviceNameInList_(devices)]]
-            </div>
-            <div hidden$="[[!doesDeviceListHaveMultipleElements_(devices)]]">
-              <select id="deviceDropdown"
-                  class="md-select"
-                  on-change="onDeviceDropdownSelectionChanged_">
-                <template is="dom-repeat" items="[[devices]]">
-                  <option
-                      class$="[[getDeviceOptionClass_(item.connectivityStatus)]]"
-                      value$="[[getInstanceIdOrLegacyDeviceId_(item)]]">
-                    [[getDeviceNameWithConnectivityStatus_(item)]]
-                  </option>
-                </template>
-              </select>
-            </div>
-            <div class="flex"></div>
-            <div id="page-icon-container">
-              <div id="page-icon"></div>
-            </div>
-            <div class="flex"></div>
-            <div id="footnote">
-              [[i18nAdvancedDynamic_(locale, 'startSetupPageFootnote')]]
-            </div>
-          </div>
           <div id="feature-details-container" class="flex">
             <div id="feature-details-container-header">
               [[i18nDynamic(locale, 'startSetupPageFeatureListHeader')]]
@@ -187,6 +150,34 @@
               </span>
             </div>
           </div>
+          <div id="deviceSelectionContainer" class="flex">
+            [[getDeviceSelectionHeader_(devices)]]
+            <div id="singleDeviceName"
+                hidden$="[[!doesDeviceListHaveOneElement_(devices)]]">
+              [[getFirstDeviceNameInList_(devices)]]
+            </div>
+            <div hidden$="[[!doesDeviceListHaveMultipleElements_(devices)]]">
+              <select id="deviceDropdown"
+                  class="md-select"
+                  on-change="onDeviceDropdownSelectionChanged_">
+                <template is="dom-repeat" items="[[devices]]">
+                  <option
+                      class$="[[getDeviceOptionClass_(item.connectivityStatus)]]"
+                      value$="[[getInstanceIdOrLegacyDeviceId_(item)]]">
+                    [[getDeviceNameWithConnectivityStatus_(item)]]
+                  </option>
+                </template>
+              </select>
+            </div>
+            <div class="flex"></div>
+            <div id="page-icon-container">
+              <div id="page-icon"></div>
+            </div>
+            <div class="flex"></div>
+            <div id="footnote">
+              [[i18nAdvancedDynamic_(locale, 'startSetupPageFootnote')]]
+            </div>
+          </div>
         </div>
       </div>
     </ui-page>
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/ui_page.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/ui_page.html
index 5d4d3be6..3d7087a 100644
--- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/ui_page.html
+++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/ui_page.html
@@ -14,28 +14,141 @@
 
       h1 {
         color: var(--google-grey-900);
-        font-family: 'Google Sans';
+        font-family: 'Google Sans', Roboto, sans-serif;
         font-size: 28px;
-        font-weight: normal;
-        line-height: 28px;
+        font-weight: 400;
         margin: 0;
-        padding-top: 36px;
-      }
-
-      #message-container {
-        box-sizing: border-box;
-        min-height: 32px;
-        padding-top: 16px;
+        padding-top: 40px;
+        text-align: var(--multidevice-setup-text-alignment);
       }
     </style>
-    <iron-icon icon="[[computeIconIdentifier_(iconName)]]"></iron-icon>
-    <h1>[[headerText]]</h1>
-    <div id="message-container">
-      <slot name="message"></slot>
-    </div>
-    <div id="additional-content-container">
-      <slot name="additional-content"></slot>
-    </div>
+    <template is="dom-if" if="[[newLayoutEnabled]]">
+      <!--
+        Below code is duplicated in oobe-adaptive-dialog. Please make sure
+        code changed are applied to both places.
+      -->
+      <style>
+        :host {
+          --multidevice-setup-dialog-height: var(--oobe-oobe-dialog-height-base);
+          --multidevice-setup-dialog-width: var(--oobe-oobe-dialog-width-base);
+          --multidevice-setup-dialog-content-padding: 40px;
+        }
+
+        :host-context([orientation=horizontal]) {
+          --multidevice-setup-dialog-content-direction: row;
+          --multidevice-setup-dialog-item-alignment: unset;
+          --multidevice-setup-text-alignment: start;
+          --multidevice-setup-dialog-content-width: calc(
+              var(--multidevice-setup-dialog-width) -
+              4 * var(--multidevice-setup-dialog-content-padding) -
+              var(--multidevice-setup-dialog-header-width));
+          /* Header takes 40% of the width remaining after applying padding */
+          --multidevice-setup-dialog-header-width: clamp(302px,
+              calc(0.4 * (var(--multidevice-setup-dialog-width) -
+              4 * var(--multidevice-setup-dialog-content-padding))) , 346px);
+        }
+
+        :host-context([orientation=vertical]) {
+          --multidevice-setup-dialog-content-direction: column;
+          --multidevice-setup-dialog-item-alignment: center;
+          --multidevice-setup-text-alignment: center;
+          --multidevice-setup-dialog-content-width: calc(
+              var(--multidevice-setup-dialog-width) -
+              2 * var(--multidevice-setup-dialog-content-padding));
+          /* Header takes 40% of the width remaining after applying padding */
+          --multidevice-setup-dialog-header-width: clamp(302px,
+              calc(0.4 * (var(--multidevice-setup-dialog-width) -
+              2 * var(--multidevice-setup-dialog-content-padding))) , 346px);
+        }
+
+        #message-container {
+          color: var(--google-grey-700);
+          line-height: 18px;
+          min-height: 32px;
+          overflow-wrap: break-word;
+          padding-top: 16px;
+          text-align: var(--multidevice-setup-text-alignment);
+        }
+
+        #main-container {
+          align-items: var(--multidevice-setup-dialog-item-alignment);
+          display: flex;
+          flex-direction: var(--multidevice-setup-dialog-content-direction);
+          height: 100%;
+        }
+
+        #header-container {
+          align-items: var(--multidevice-setup-dialog-item-alignment);
+          display: flex;
+          flex-direction: column;
+          padding-bottom: 0;
+          padding-inline-end: var(--multidevice-setup-dialog-content-padding);
+          padding-inline-start: var(--multidevice-setup-dialog-content-padding);
+          padding-top: calc(var(--multidevice-setup-dialog-content-padding)
+            + 2 * min(40px, max(24px, calc(var(--multidevice-setup-dialog-height)
+            * 0.025))));
+          width: var(--multidevice-setup-dialog-header-width);
+        }
+
+        :host-context([screen=oobe]) #header-container {
+          padding-top: calc(var(--multidevice-setup-dialog-content-padding)
+            + 2 * min(40px, max(24px, calc(var(--multidevice-setup-dialog-height)
+            * 0.025))) + 32px);
+        }
+
+        #additional-content-container {
+          border: transparent;
+          display: flex;
+          flex: 1;
+          margin-top: 40px;
+          overflow-y: auto;
+          padding-bottom: 0;
+          padding-inline-end: var(--multidevice-setup-dialog-content-padding);
+          padding-inline-start: var(--multidevice-setup-dialog-content-padding);
+          padding-top: 0;
+          width: var(--multidevice-setup-dialog-content-width);
+        }
+      </style>
+      <div id="main-container">
+        <div id="header-container">
+          <iron-icon icon="[[computeIconIdentifier_(iconName)]]"></iron-icon>
+          <h1>[[headerText]]</h1>
+          <div id="message-container">
+            <slot name="message"></slot>
+          </div>
+        </div>
+        <div id="additional-content-container">
+          <slot name="additional-content"></slot>
+        </div>
+      </div>
+    </template>
+    <template is="dom-if" if="[[!newLayoutEnabled]]">
+      <style>
+        #main-container {
+          padding: 32px 64px;
+        }
+
+        #message-container {
+          line-height: 18px;
+          min-height: 32px;
+          padding-top: 16px;
+        }
+
+        #additional-content-container {
+          margin-top: 24px;
+        }
+      </style>
+      <div id="main-container">
+        <iron-icon icon="[[computeIconIdentifier_(iconName)]]"></iron-icon>
+        <h1>[[headerText]]</h1>
+        <div id="message-container">
+          <slot name="message"></slot>
+        </div>
+        <div id="additional-content-container">
+          <slot name="additional-content"></slot>
+        </div>
+      </div>
+    </template>
   </template>
   <script src="ui_page.js"></script>
 </dom-module>
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/ui_page.js b/ui/webui/resources/cr_components/chromeos/multidevice_setup/ui_page.js
index 27d1ff30..7cf19d5 100644
--- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/ui_page.js
+++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/ui_page.js
@@ -22,6 +22,19 @@
      * @type {string}
      */
     iconName: String,
+
+    /**
+     * Whether new OOBE layout is enabled.
+     *
+     * @type {string}
+     */
+    newLayoutEnabled: {
+      type: Boolean,
+      value() {
+        return loadTimeData.valueExists('newLayoutEnabled') &&
+            loadTimeData.getBoolean('newLayoutEnabled');
+      }
+    },
   },
 
   /**
diff --git a/ui/webui/resources/cr_components/chromeos/network/BUILD.gn b/ui/webui/resources/cr_components/chromeos/network/BUILD.gn
index 29d3ea88..9c2a32a 100644
--- a/ui/webui/resources/cr_components/chromeos/network/BUILD.gn
+++ b/ui/webui/resources/cr_components/chromeos/network/BUILD.gn
@@ -448,6 +448,7 @@
   deps = [
     ":network_list_item.m",
     ":network_list_types.m",
+    ":onc_mojo.m",
     "//third_party/polymer/v3_0/components-chromium/iron-list:iron-list",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_elements:cr_scrollable_behavior.m",
@@ -459,8 +460,10 @@
 js_library("network_list_item.m") {
   sources = [ "$root_gen_dir/ui/webui/resources/cr_components/chromeos/network/network_list_item.m.js" ]
   deps = [
+    ":cr_policy_network_behavior_mojo.m",
     ":mojo_interface_provider.m",
     ":network_list_types.m",
+    ":onc_mojo.m",
     "//third_party/polymer/v3_0/components-chromium/paper-spinner:paper-spinner-lite",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/js/cr/ui:focus_row_behavior.m",
@@ -470,6 +473,7 @@
 
 js_library("network_list_types.m") {
   sources = [ "$root_gen_dir/ui/webui/resources/cr_components/chromeos/network/network_list_types.m.js" ]
+  deps = [ ":onc_mojo.m" ]
   extra_deps = [ ":modulize" ]
 }
 
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_list.html b/ui/webui/resources/cr_components/chromeos/network/network_list.html
index 902d268..17c8ff3 100644
--- a/ui/webui/resources/cr_components/chromeos/network/network_list.html
+++ b/ui/webui/resources/cr_components/chromeos/network/network_list.html
@@ -2,6 +2,7 @@
 
 <link rel="import" href="network_list_item.html">
 <link rel="import" href="network_list_types.html">
+<link rel="import" href="onc_mojo.html">
 <link rel="import" href="../../../cr_elements/cr_scrollable_behavior.html">
 <link rel="import" href="../../../cr_elements/shared_style_css.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_list_item.html b/ui/webui/resources/cr_components/chromeos/network/network_list_item.html
index a1bfbb7d..c409860 100644
--- a/ui/webui/resources/cr_components/chromeos/network/network_list_item.html
+++ b/ui/webui/resources/cr_components/chromeos/network/network_list_item.html
@@ -2,6 +2,8 @@
 
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html">
+<link rel="import" href="chrome://resources/html/load_time_data.html">
+<link rel="import" href="chrome://resources/html/assert.html">
 <link rel="import" href="../../../cr_elements/cr_icon_button/cr_icon_button.html">
 <link rel="import" href="../../../cr_elements/icons.html">
 <link rel="import" href="../../../cr_elements/policy/cr_policy_indicator.html">
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_list_types.js b/ui/webui/resources/cr_components/chromeos/network/network_list_types.js
index a873ff6..82e39513 100644
--- a/ui/webui/resources/cr_components/chromeos/network/network_list_types.js
+++ b/ui/webui/resources/cr_components/chromeos/network/network_list_types.js
@@ -2,6 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// clang-format off
+// #import {OncMojo} from './onc_mojo.m.js';
+// clang-format on
+
 /**
  * @fileoverview
  * This file contains typedefs properties for NetworkList, shared by
diff --git a/weblayer/browser/DEPS b/weblayer/browser/DEPS
index fcbdb46e..1cce9a3 100644
--- a/weblayer/browser/DEPS
+++ b/weblayer/browser/DEPS
@@ -21,6 +21,7 @@
   "+components/download/content/public",
   "+components/download/public/common",
   "+components/embedder_support",
+  "+components/error_page/common",
   "+components/error_page/content/browser",
   "+components/favicon_base",
   "+components/favicon",
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/NavigationTest.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/NavigationTest.java
index 0ce303d..8fcbf6a 100644
--- a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/NavigationTest.java
+++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/NavigationTest.java
@@ -575,21 +575,21 @@
     @Test
     @SmallTest
     public void testLoadError() throws Exception {
-        String url = mActivityTestRule.getTestDataURL("non_existent.html");
+        String url = mActivityTestRule.getTestDataURL("non_empty404.html");
 
         InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl("about:blank");
         setNavigationCallback(activity);
 
-        int curFailedCount = mCallback.onFailedCallback.getCallCount();
+        int curCompletedCount = mCallback.onCompletedCallback.getCallCount();
 
         // navigateAndWait() expects a success code, so it won't work here.
         runOnUiThreadBlocking(
                 () -> { activity.getTab().getNavigationController().navigate(Uri.parse(url)); });
 
-        mCallback.onFailedCallback.assertCalledWith(
-                curFailedCount, url, LoadError.HTTP_CLIENT_ERROR);
-        assertEquals(mCallback.onFailedCallback.getHttpStatusCode(), 404);
-        assertEquals(mCallback.onFailedCallback.getNavigationState(), NavigationState.FAILED);
+        mCallback.onCompletedCallback.assertCalledWith(
+                curCompletedCount, url, LoadError.HTTP_CLIENT_ERROR);
+        assertEquals(mCallback.onCompletedCallback.getHttpStatusCode(), 404);
+        assertEquals(mCallback.onCompletedCallback.getNavigationState(), NavigationState.COMPLETE);
     }
 
     @MinWebLayerVersion(89)
diff --git a/weblayer/browser/content_browser_client_impl.cc b/weblayer/browser/content_browser_client_impl.cc
index fba8aa1..6496b35 100644
--- a/weblayer/browser/content_browser_client_impl.cc
+++ b/weblayer/browser/content_browser_client_impl.cc
@@ -22,6 +22,8 @@
 #include "components/captive_portal/core/buildflags.h"
 #include "components/embedder_support/switches.h"
 #include "components/embedder_support/user_agent_utils.h"
+#include "components/error_page/common/error.h"
+#include "components/error_page/common/localized_error.h"
 #include "components/error_page/content/browser/net_error_auto_reloader.h"
 #include "components/network_time/network_time_tracker.h"
 #include "components/no_state_prefetch/browser/no_state_prefetch_manager.h"
@@ -1026,7 +1028,9 @@
 }
 
 bool ContentBrowserClientImpl::HasErrorPage(int http_status_code) {
-  return http_status_code >= 400;
+  // Use an internal error page, if we have one for the status code.
+  return error_page::LocalizedError::HasStrings(
+      error_page::Error::kHttpErrorDomain, http_status_code);
 }
 
 }  // namespace weblayer
diff --git a/weblayer/browser/content_view_render_view.cc b/weblayer/browser/content_view_render_view.cc
index b61a0c7b..0b1005e6 100644
--- a/weblayer/browser/content_view_render_view.cc
+++ b/weblayer/browser/content_view_render_view.cc
@@ -110,7 +110,6 @@
 
 void ContentViewRenderView::SurfaceCreated(JNIEnv* env) {
   InitCompositor();
-  current_surface_format_ = 0;
 }
 
 void ContentViewRenderView::SurfaceDestroyed(JNIEnv* env,
@@ -118,17 +117,14 @@
   if (cache_back_buffer)
     compositor_->CacheBackBufferForCurrentSurface();
   compositor_->SetSurface(nullptr, false);
-  current_surface_format_ = 0;
 }
 
 void ContentViewRenderView::SurfaceChanged(
     JNIEnv* env,
     jboolean can_be_used_with_surface_control,
-    jint format,
     jint width,
     jint height,
     const JavaParamRef<jobject>& surface) {
-  current_surface_format_ = format;
   compositor_->SetSurface(surface, can_be_used_with_surface_control);
   compositor_->SetWindowBounds(gfx::Size(width, height));
 }
diff --git a/weblayer/browser/content_view_render_view.h b/weblayer/browser/content_view_render_view.h
index 0cf93c0..a18e5e0 100644
--- a/weblayer/browser/content_view_render_view.h
+++ b/weblayer/browser/content_view_render_view.h
@@ -55,7 +55,6 @@
   void SurfaceDestroyed(JNIEnv* env, jboolean cache_back_buffer);
   void SurfaceChanged(JNIEnv* env,
                       jboolean can_be_used_with_surface_control,
-                      jint format,
                       jint width,
                       jint height,
                       const base::android::JavaParamRef<jobject>& surface);
@@ -84,8 +83,6 @@
   scoped_refptr<cc::Layer> root_container_layer_;
   scoped_refptr<cc::Layer> web_contents_layer_;
 
-  int current_surface_format_ = 0;
-
   base::RepeatingClosure height_changed_listener_;
   int height_ = 0;
 
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ContactsPickerAdapter.java b/weblayer/browser/java/org/chromium/weblayer_private/ContactsPickerAdapter.java
index bb79433..025b819 100644
--- a/weblayer/browser/java/org/chromium/weblayer_private/ContactsPickerAdapter.java
+++ b/weblayer/browser/java/org/chromium/weblayer_private/ContactsPickerAdapter.java
@@ -72,9 +72,10 @@
         try {
             name = identityCallback.getFullName();
             ValueCallback<Bitmap> onAvatarLoaded = (Bitmap returnedAvatar) -> {
-                if (weakThis.get() == null) return;
+                ContactsPickerAdapter strongThis = weakThis.get();
+                if (strongThis == null) return;
 
-                weakThis.get().updateOwnerInfoWithIcon(returnedAvatar);
+                strongThis.updateOwnerInfoWithIcon(returnedAvatar);
             };
             identityCallback.getAvatar(getIconRawPixelSize(), ObjectWrapper.wrap(onAvatarLoaded));
         } catch (RemoteException e) {
@@ -103,8 +104,13 @@
     }
 
     private void updateOwnerInfoWithIcon(Bitmap icon) {
-        mAvatar = icon;
-        if (mSelfContactSynthesized && mAvatar != null) {
+        if (icon == null) return;
+
+        mAvatar = icon.copy(icon.getConfig(), true);
+        mAvatar.setDensity(
+                mWindowAndroid.getContext().get().getResources().getConfiguration().densityDpi);
+
+        if (mSelfContactSynthesized) {
             getAllContacts().get(0).setSelfIcon(createAvatarDrawable());
             update();
         }
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java b/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java
index 12e0017a..29f0895 100644
--- a/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java
+++ b/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java
@@ -107,8 +107,8 @@
     // Common interface to listen to surface related events.
     private interface SurfaceEventListener {
         void surfaceCreated();
-        void surfaceChanged(Surface surface, boolean canBeUsedWithSurfaceControl, int format,
-                int width, int height);
+        void surfaceChanged(
+                Surface surface, boolean canBeUsedWithSurfaceControl, int width, int height);
         // |cacheBackBuffer| will delay destroying the EGLSurface until after the next swap.
         void surfaceDestroyed(boolean cacheBackBuffer);
         void surfaceRedrawNeededAsync(Runnable drawingFinished);
@@ -165,12 +165,12 @@
         }
 
         @Override
-        public void surfaceChanged(Surface surface, boolean canBeUsedWithSurfaceControl, int format,
-                int width, int height) {
+        public void surfaceChanged(
+                Surface surface, boolean canBeUsedWithSurfaceControl, int width, int height) {
             assert mNativeContentViewRenderView != 0;
             assert mSurfaceData == ContentViewRenderView.this.mCurrent;
             ContentViewRenderViewJni.get().surfaceChanged(mNativeContentViewRenderView,
-                    canBeUsedWithSurfaceControl, format, width, height, surface);
+                    canBeUsedWithSurfaceControl, width, height, surface);
             mCompositorHasSurface = surface != null;
             maybeUpdatePhysicalBackingSize(width, height);
         }
@@ -481,12 +481,12 @@
         }
 
         @Override
-        public void surfaceChanged(Surface surface, boolean canBeUsedWithSurfaceControl, int format,
-                int width, int height) {
+        public void surfaceChanged(
+                Surface surface, boolean canBeUsedWithSurfaceControl, int width, int height) {
             if (mMarkedForDestroy) return;
             // Selection magnifier does not work with surface control enabled.
-            mListener.surfaceChanged(surface, canBeUsedWithSurfaceControl && mAllowSurfaceControl,
-                    format, width, height);
+            mListener.surfaceChanged(
+                    surface, canBeUsedWithSurfaceControl && mAllowSurfaceControl, width, height);
             mNumSurfaceViewSwapsUntilVisible = 2;
         }
 
@@ -551,7 +551,7 @@
 
         @Override
         public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-            mListener.surfaceChanged(holder.getSurface(), true, format, width, height);
+            mListener.surfaceChanged(holder.getSurface(), true, width, height);
         }
 
         @Override
@@ -602,7 +602,7 @@
                 mCurrentSurfaceTexture = surfaceTexture;
                 mCurrentSurface = new Surface(mCurrentSurfaceTexture);
             }
-            mListener.surfaceChanged(mCurrentSurface, false, PixelFormat.OPAQUE, width, height);
+            mListener.surfaceChanged(mCurrentSurface, false, width, height);
         }
 
         @Override
@@ -949,7 +949,7 @@
         void surfaceCreated(long nativeContentViewRenderView);
         void surfaceDestroyed(long nativeContentViewRenderView, boolean cacheBackBuffer);
         void surfaceChanged(long nativeContentViewRenderView, boolean canBeUsedWithSurfaceControl,
-                int format, int width, int height, Surface surface);
+                int width, int height, Surface surface);
         void setNeedsRedraw(long nativeContentViewRenderView);
         void evictCachedSurface(long nativeContentViewRenderView);
         ResourceManager getResourceManager(long nativeContentViewRenderView);
diff --git a/weblayer/browser/navigation_browsertest.cc b/weblayer/browser/navigation_browsertest.cc
index b755e90..808c5e9 100644
--- a/weblayer/browser/navigation_browsertest.cc
+++ b/weblayer/browser/navigation_browsertest.cc
@@ -116,12 +116,29 @@
   EXPECT_EQ(observer.navigation_state(), NavigationState::kComplete);
 }
 
+// Http client error when the server returns a non-empty response.
 IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, HttpClientError) {
   EXPECT_TRUE(embedded_test_server()->Start());
 
   OneShotNavigationObserver observer(shell());
   GetNavigationController()->Navigate(
-      embedded_test_server()->GetURL("/non_existent.html"));
+      embedded_test_server()->GetURL("/non_empty404.html"));
+
+  observer.WaitForNavigation();
+  EXPECT_TRUE(observer.completed());
+  EXPECT_FALSE(observer.is_error_page());
+  EXPECT_EQ(observer.load_error(), Navigation::kHttpClientError);
+  EXPECT_EQ(observer.http_status_code(), 404);
+  EXPECT_EQ(observer.navigation_state(), NavigationState::kComplete);
+}
+
+// Http client error when the server returns an empty response.
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, HttpClientErrorEmptyResponse) {
+  EXPECT_TRUE(embedded_test_server()->Start());
+
+  OneShotNavigationObserver observer(shell());
+  GetNavigationController()->Navigate(
+      embedded_test_server()->GetURL("/empty404.html"));
 
   observer.WaitForNavigation();
   EXPECT_FALSE(observer.completed());
diff --git a/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java b/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java
index 53dafa9..3298d8a9 100644
--- a/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java
+++ b/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java
@@ -569,8 +569,11 @@
                 // Simulate a delayed load.
                 final Handler handler = new Handler(Looper.getMainLooper());
                 handler.postDelayed(() -> {
-                    avatarLoadedCallback.onReceiveValue(BitmapFactory.decodeResource(
-                            getApplicationContext().getResources(), R.drawable.avatar_sunglasses));
+                    Bitmap bitmap = BitmapFactory.decodeResource(
+                            getApplicationContext().getResources(), R.drawable.avatar_sunglasses);
+                    // Curveball: set an arbitrary density.
+                    bitmap.setDensity(120);
+                    avatarLoadedCallback.onReceiveValue(bitmap);
                 }, 3000);
             }
         });
diff --git a/weblayer/shell/browser/shell_views.cc b/weblayer/shell/browser/shell_views.cc
index 41d08b1..d71da0e 100644
--- a/weblayer/shell/browser/shell_views.cc
+++ b/weblayer/shell/browser/shell_views.cc
@@ -27,6 +27,8 @@
 #include "ui/views/controls/webview/webview.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/layout/grid_layout.h"
+#include "ui/views/metadata/metadata_header_macros.h"
+#include "ui/views/metadata/metadata_impl_macros.h"
 #include "ui/views/test/desktop_test_views_delegate.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/desktop_aura/desktop_screen.h"
@@ -51,6 +53,8 @@
 class ShellWindowDelegateView : public views::WidgetDelegateView,
                                 public views::TextfieldController {
  public:
+  METADATA_HEADER(ShellWindowDelegateView);
+
   enum UIControl { BACK_BUTTON, FORWARD_BUTTON, STOP_BUTTON };
 
   explicit ShellWindowDelegateView(Shell* shell) : shell_(shell) {
@@ -58,7 +62,10 @@
     InitShellWindow();
   }
 
-  ~ShellWindowDelegateView() override {}
+  ShellWindowDelegateView(const ShellWindowDelegateView&) = delete;
+  ShellWindowDelegateView& operator=(const ShellWindowDelegateView&) = delete;
+
+  ~ShellWindowDelegateView() override = default;
 
   // Update the state of UI controls
   void SetAddressBarURL(const GURL& url) {
@@ -281,10 +288,11 @@
   // Contents view contains the WebBrowser view
   View* contents_view_ = nullptr;
   views::WebView* web_view_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(ShellWindowDelegateView);
 };
 
+BEGIN_METADATA(ShellWindowDelegateView, views::WidgetDelegateView)
+END_METADATA
+
 }  // namespace
 
 #if defined(USE_AURA)
diff --git a/weblayer/test/data/non_empty404.html b/weblayer/test/data/non_empty404.html
new file mode 100644
index 0000000..ebf944d
--- /dev/null
+++ b/weblayer/test/data/non_empty404.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+404 with some body.
+</body>
+</html>
\ No newline at end of file
diff --git a/weblayer/test/data/non_empty404.html.mock-http-headers b/weblayer/test/data/non_empty404.html.mock-http-headers
new file mode 100644
index 0000000..0590363
--- /dev/null
+++ b/weblayer/test/data/non_empty404.html.mock-http-headers
@@ -0,0 +1,2 @@
+HTTP/1.0 404 Not Found
+Content-type: text/html