diff --git a/DEPS b/DEPS
index f00970c..d444ba0 100644
--- a/DEPS
+++ b/DEPS
@@ -234,15 +234,15 @@
   # 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': '0ed19771c38ceda8fabb2ffcb0a6b687fcf65302',
+  'skia_revision': '660cc2a38f6f15e71b9cb0bb54014dbf87118150',
   # 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': '10ed64a372e70c27ab0dd770ccf3ca3b93e3eda1',
+  'v8_revision': '1e81daa096a86e2da18f6a94a769751c7a1ee4aa',
   # 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': '739c414f77c83a0772f6b0e67b7a09f91b35b100',
+  'angle_revision': '17261f3bffe2475cab26117719afc62c9fb794e3',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -309,7 +309,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': 'f7a1e3a4947323b1dda0cf6d2f1909922a3e9766',
+  'devtools_frontend_revision': '67872d6878d653f8c310cfecde9a5f080db20021',
   # 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.
@@ -349,7 +349,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '6e83e6284eb6a83e3ffce3e1d7d78cfee3130833',
+  'dawn_revision': 'ba276a4f554cbe11702f8def449991c527fc2da6',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -708,7 +708,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/linux-amd64',
-          'version': 'tjDUZnRDfRwNyESHBJLS2WJSuJJKpq74mSbfBTq5YWgC',
+          'version': 'idSG1kF8MNunTVuRba0XNB9pBkoIEESFYfMwG6vCzY4C',
         },
       ],
       'dep_type': 'cipd',
@@ -719,7 +719,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/mac-amd64',
-          'version': 'e21q_i0io864UpRIXAkBKPDHVbkHSDUrDm7QfX0oeosC',
+          'version': 'vAGO-FUCV6mp667Lz9xPlA-m6Qg9r-2727wVxRwyv6wC',
         },
       ],
       'dep_type': 'cipd',
@@ -730,7 +730,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/windows-amd64',
-          'version': '_mv2OMpjccweT-C9WjlRVvg3G6Wl8DKlaXteORrc2ccC',
+          'version': 'T1trgreQia99KgYSLmE5CEnoL0JqxLmRJDyQy0FGDAsC',
         },
       ],
       'dep_type': 'cipd',
@@ -791,7 +791,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'fLKT6t1QfUqOQR_DsCtVlubXz-ud0Hwfsmzy21I9rToC',
+          'version': 'yAYkpiAexFiePTwSGcIK0Fh0Q7AjB3YFFda0UfCrl9QC',
       },
     ],
     'condition': 'checkout_android',
@@ -1393,7 +1393,7 @@
   },
 
   'src/third_party/openh264/src':
-    Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '3dd5b80bc4f172dd82925bb259cb7c82348409c5',
+    Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'b52786888ddce9d6bc06b7825ba9bffc65924e0c',
 
   'src/third_party/openscreen/src':
     Var('chromium_git') + '/openscreen' + '@' + 'f1c6841fc07df323c0dd90fa1be000152a7cd99a',
@@ -1413,7 +1413,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'b9dad73621357b1698837d1abb64c020c5547172',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '9e18a83edc73bc998ed8aa2ee481b57c8fc5f5f5',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1634,7 +1634,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'f6f0c1129dffbd7f2c862ea6f7543f3cba582b4c',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'c56645c0cd1ea3cb718935789b786b7ee9c35659',
+    Var('webrtc_git') + '/src.git' + '@' + '90cc4fe0e9e78b4b7f631f495d63422816bf2763',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1692,7 +1692,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@ae53e3e15f319f49946af9137bae7048528dd7bc',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@e77d11f497177826d9ac64a1267e8d2449b8836d',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/ash/capture_mode/capture_mode_unittests.cc b/ash/capture_mode/capture_mode_unittests.cc
index 1466f6e..667d9b5 100644
--- a/ash/capture_mode/capture_mode_unittests.cc
+++ b/ash/capture_mode/capture_mode_unittests.cc
@@ -2920,6 +2920,12 @@
   // The window should have a valid capture ID.
   EXPECT_TRUE(window->subtree_capture_id().is_valid());
 
+  // Generate a couple of mouse moves, so that the second one gets throttled
+  // using the `VideoRecordingWatcher::cursor_events_throttle_timer_`. This is
+  // needed for a regression testing of https://crbug.com/1273609.
+  event_generator->MoveMouseBy(20, 30);
+  event_generator->MoveMouseBy(-10, -20);
+
   // Closing the window being recorded should end video recording.
   base::HistogramTester histogram_tester;
   window.reset();
diff --git a/ash/capture_mode/video_recording_watcher.cc b/ash/capture_mode/video_recording_watcher.cc
index 3342fef..51738c6 100644
--- a/ash/capture_mode/video_recording_watcher.cc
+++ b/ash/capture_mode/video_recording_watcher.cc
@@ -208,6 +208,7 @@
   if (recording_source_ == CaptureModeSource::kRegion)
     partial_region_bounds_ = controller_->user_capture_region();
 
+  display::Screen::GetScreen()->AddObserver(this);
   window_being_recorded_->AddObserver(this);
   TabletModeController::Get()->AddObserver(this);
 
@@ -237,6 +238,8 @@
 
 void VideoRecordingWatcher::ToggleRecordingOverlayEnabled() {
   DCHECK(is_in_projector_mode_);
+  DCHECK(!is_shutting_down_);
+  DCHECK(recording_overlay_controller_);
 
   recording_overlay_controller_->Toggle();
 }
@@ -245,6 +248,12 @@
   is_shutting_down_ = true;
   DCHECK(window_being_recorded_);
 
+  cursor_events_throttle_timer_.Stop();
+  cursor_capture_overlay_remote_.reset();
+  root_observer_.reset();
+  recording_overlay_controller_.reset();
+  dimmers_.clear();
+
   if (is_in_projector_mode_)
     ProjectorControllerImpl::Get()->OnRecordingEnded();
 
@@ -262,6 +271,7 @@
   // |window_being_recorded_| is not capturable.
   auto to_be_removed_request = std::move(non_root_window_capture_request_);
   window_being_recorded_->RemoveObserver(this);
+  display::Screen::GetScreen()->RemoveObserver(this);
 }
 
 void VideoRecordingWatcher::OnWindowParentChanged(aura::Window* window,
diff --git a/ash/capture_mode/video_recording_watcher.h b/ash/capture_mode/video_recording_watcher.h
index 0710752..b88fdf39 100644
--- a/ash/capture_mode/video_recording_watcher.h
+++ b/ash/capture_mode/video_recording_watcher.h
@@ -276,9 +276,6 @@
   // make it capturable by the |FrameSinkVideoCapturer|.
   aura::ScopedWindowCaptureRequest non_root_window_capture_request_;
 
-  // Register for DisplayObserver callbacks.
-  display::ScopedDisplayObserver display_observer_{this};
-
   // True if the shutting down process has been triggered.
   bool is_shutting_down_ = false;
 };
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera/preview.js b/ash/webui/camera_app_ui/resources/js/views/camera/preview.js
index 310c96f6..7b01243 100644
--- a/ash/webui/camera_app_ui/resources/js/views/camera/preview.js
+++ b/ash/webui/camera_app_ui/resources/js/views/camera/preview.js
@@ -643,6 +643,7 @@
           AndroidStatisticsFaceDetectMode
               .ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) {
         dom.get('#preview-num-faces', HTMLDivElement).style.display = 'none';
+        this.faceOverlay_.clear();
         return;
       }
       assert(rects.length % 4 === 0);
diff --git a/ash/webui/shimless_rma/DEPS b/ash/webui/shimless_rma/DEPS
index 0dcb482..cdebd9908 100644
--- a/ash/webui/shimless_rma/DEPS
+++ b/ash/webui/shimless_rma/DEPS
@@ -1,6 +1,7 @@
 include_rules = [
   "+ash/grit/ash_shimless_rma_resources.h",
   "+chromeos/dbus",
+  "+chromeos/dbus/power",
   "+chromeos/dbus/rmad",
   "+chromeos/dbus/update_engine",
   "+chromeos/dbus/util",
diff --git a/ash/webui/shimless_rma/backend/BUILD.gn b/ash/webui/shimless_rma/backend/BUILD.gn
index 81e4e7b..dfd5a5dc 100644
--- a/ash/webui/shimless_rma/backend/BUILD.gn
+++ b/ash/webui/shimless_rma/backend/BUILD.gn
@@ -19,6 +19,7 @@
     "//ash/public/cpp:cpp",
     "//ash/webui/shimless_rma/mojom",
     "//chromeos/dbus",
+    "//chromeos/dbus/power",
     "//chromeos/dbus/rmad",
     "//chromeos/dbus/rmad:rmad_proto",
     "//chromeos/dbus/update_engine",
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service.cc b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
index 57c1acf3a..a250e9ac 100644
--- a/ash/webui/shimless_rma/backend/shimless_rma_service.cc
+++ b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
@@ -5,7 +5,9 @@
 #include "ash/webui/shimless_rma/backend/shimless_rma_service.h"
 
 #include <memory>
+#include <string>
 #include <utility>
+#include <vector>
 
 #include "ash/public/cpp/network_config_service.h"
 #include "ash/webui/shimless_rma/backend/shimless_rma_delegate.h"
@@ -14,6 +16,7 @@
 #include "ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.h"
 #include "base/bind.h"
 #include "base/logging.h"
+#include "chromeos/dbus/power/power_manager_client.h"
 #include "chromeos/dbus/rmad/rmad.pb.h"
 #include "chromeos/dbus/rmad/rmad_client.h"
 #include "chromeos/dbus/util/version_loader.h"
@@ -75,7 +78,6 @@
   qr_code->data.assign(qr_data->data.begin(), qr_data->data.end());
   return qr_code;
 }
-
 }  // namespace
 
 ShimlessRmaService::ShimlessRmaService(
@@ -112,9 +114,33 @@
 }
 
 void ShimlessRmaService::AbortRma(AbortRmaCallback callback) {
-  chromeos::RmadClient::Get()->AbortRma(
-      base::BindOnce(&ShimlessRmaService::OnAbortRmaResponse,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+  chromeos::RmadClient::Get()->AbortRma(base::BindOnce(
+      &ShimlessRmaService::OnAbortRmaResponse, weak_ptr_factory_.GetWeakPtr(),
+      std::move(callback), /*reboot=*/false));
+}
+
+// TODO(gavindodd): Work out how to catch the restart in tests and add unit test
+void ShimlessRmaService::CriticalErrorExitToLogin(
+    CriticalErrorExitToLoginCallback callback) {
+  if (!critical_error_occurred_) {
+    std::move(callback).Run(rmad::RMAD_ERROR_REQUEST_INVALID);
+    return;
+  }
+  chromeos::RmadClient::Get()->AbortRma(base::BindOnce(
+      &ShimlessRmaService::OnAbortRmaResponse, weak_ptr_factory_.GetWeakPtr(),
+      std::move(callback), /*reboot=*/false));
+}
+
+// TODO(gavindodd): Work out how to catch the reboot in tests and add unit test
+void ShimlessRmaService::CriticalErrorReboot(
+    CriticalErrorRebootCallback callback) {
+  if (!critical_error_occurred_) {
+    std::move(callback).Run(rmad::RMAD_ERROR_REQUEST_INVALID);
+    return;
+  }
+  chromeos::RmadClient::Get()->AbortRma(base::BindOnce(
+      &ShimlessRmaService::OnAbortRmaResponse, weak_ptr_factory_.GetWeakPtr(),
+      std::move(callback), /*reboot=*/true));
 }
 
 void ShimlessRmaService::BeginFinalization(BeginFinalizationCallback callback) {
@@ -959,8 +985,7 @@
     absl::optional<rmad::GetStateReply> response) {
   if (!response) {
     LOG(ERROR) << "Failed to call rmadClient";
-    // TODO(gavindodd): This needs better handling. Maybe display an error and
-    // force a chrome update?
+    critical_error_occurred_ = true;
     std::move(callback).Run(mojom::State::kUnknown, false, false,
                             rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID);
     return;
@@ -974,6 +999,9 @@
   mojo_state_ = RmadStateToMojo(state_proto_.state_case());
   if (response->error() != rmad::RMAD_ERROR_OK) {
     LOG(ERROR) << "rmadClient returned error " << response->error();
+    if (response->error() == rmad::RMAD_ERROR_RMA_NOT_REQUIRED) {
+      critical_error_occurred_ = true;
+    }
     std::move(callback).Run(RmadStateToMojo(state_proto_.state_case()),
                             can_abort_, can_go_back_, response->error());
     return;
@@ -985,13 +1013,31 @@
 
 void ShimlessRmaService::OnAbortRmaResponse(
     AbortRmaCallback callback,
+    bool reboot,
     absl::optional<rmad::AbortRmaReply> response) {
   if (!response) {
     LOG(ERROR) << "Failed to call rmad::AbortRma";
     std::move(callback).Run(rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID);
-    return;
+  } else {
+    std::move(callback).Run(response->error());
   }
-  std::move(callback).Run(response->error());
+  // Only reboot or exit to login if abort was successful or a critical error
+  // has occurred.
+  if (critical_error_occurred_ || response->error() == rmad::RMAD_ERROR_OK) {
+    if (reboot) {
+      VLOG(1) << "Rebooting...";
+      chromeos::PowerManagerClient::Get()->RequestRestart(
+          power_manager::REQUEST_RESTART_FOR_USER,
+          critical_error_occurred_
+              ? "Rebooting after user cancelled RMA due to critical error."
+              : "Rebooting after user cancelled RMA.");
+    } else {
+      VLOG(1) << "Restarting Chrome to bypass RMA after cancel request.";
+      // TODO(gavindodd): Append ::ash::switches::kNoShimlessRma when autolaunch
+      // is implemented.
+      shimless_rma_delegate_->RestartChrome();
+    }
+  }
 }
 
 void ShimlessRmaService::OnNetworkListResponse(
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service.h b/ash/webui/shimless_rma/backend/shimless_rma_service.h
index f94c8698..d5b013e 100644
--- a/ash/webui/shimless_rma/backend/shimless_rma_service.h
+++ b/ash/webui/shimless_rma/backend/shimless_rma_service.h
@@ -129,6 +129,10 @@
   void EndRmaAndShutdown(EndRmaAndShutdownCallback callback) override;
   void EndRmaAndCutoffBattery(EndRmaAndCutoffBatteryCallback callback) override;
 
+  void CriticalErrorExitToLogin(
+      CriticalErrorExitToLoginCallback callback) override;
+  void CriticalErrorReboot(CriticalErrorRebootCallback callback) override;
+
   void ObserveError(
       ::mojo::PendingRemote<mojom::ErrorObserver> observer) override;
   void ObserveOsUpdateProgress(
@@ -176,6 +180,7 @@
   void OnGetStateResponse(Callback callback,
                           absl::optional<rmad::GetStateReply> response);
   void OnAbortRmaResponse(AbortRmaCallback callback,
+                          bool reboot,
                           absl::optional<rmad::AbortRmaReply> response);
   void OnGetLog(GetLogCallback callback, absl::optional<std::string> log);
   void OnNetworkListResponse(
@@ -231,6 +236,11 @@
   // Provides browser functionality from //chrome to the Shimless RMA UI.
   std::unique_ptr<ShimlessRmaDelegate> shimless_rma_delegate_;
 
+  // When a critical error occurs this is set to true and never clears.
+  // It is used to allow abort requests to reboot or exit to login, even if the
+  // request fails.
+  bool critical_error_occurred_ = false;
+
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<ShimlessRmaService> weak_ptr_factory_{this};
diff --git a/ash/webui/shimless_rma/mojom/shimless_rma.mojom b/ash/webui/shimless_rma/mojom/shimless_rma.mojom
index 412910c..3be9062 100644
--- a/ash/webui/shimless_rma/mojom/shimless_rma.mojom
+++ b/ash/webui/shimless_rma/mojom/shimless_rma.mojom
@@ -676,6 +676,17 @@
           RmadErrorCode error);
 
   ///////////////////////////////////////
+  // Critical error handling
+  // These methods will fail if backend is not in critical error state.
+  // Currently the only critical error is when error is kRmaNotRequired
+  // (state is kUnknown).
+  //
+  // Attempt to cancel RMA and restart Chrome without checking RMA.
+  CriticalErrorExitToLogin() => (RmadErrorCode error);
+  // Attempt to cancel RMA and reboot the device.
+  CriticalErrorReboot() => (RmadErrorCode error);
+
+  ///////////////////////////////////////
   // Observers
   //
   // Registers an observer for any out of band error that occurs, such as a
diff --git a/ash/webui/shimless_rma/resources/fake_shimless_rma_service.js b/ash/webui/shimless_rma/resources/fake_shimless_rma_service.js
index a31dada..0b68b86 100644
--- a/ash/webui/shimless_rma/resources/fake_shimless_rma_service.js
+++ b/ash/webui/shimless_rma/resources/fake_shimless_rma_service.js
@@ -698,6 +698,23 @@
   }
 
   /**
+   * @return {!Promise<!{error: !RmadErrorCode}>}
+   */
+  criticalErrorExitToLogin() {
+    return this.methods_.resolveMethodWithDelay(
+        'criticalErrorExitToLogin', this.resolveMethodDelayMs_);
+  }
+
+  /**
+   * @return {!Promise<!{error: !RmadErrorCode}>}
+   */
+  criticalErrorReboot() {
+    return this.methods_.resolveMethodWithDelay(
+        'criticalErrorReboot', this.resolveMethodDelayMs_);
+  }
+
+
+  /**
    * Implements ShimlessRmaServiceInterface.ObserveError.
    * @param {!ErrorObserverRemote} remote
    */
@@ -1171,6 +1188,10 @@
     this.methods_.register('endRmaAndReboot');
     this.methods_.register('endRmaAndShutdown');
     this.methods_.register('endRmaAndCutoffBattery');
+
+    // Critical error handling
+    this.methods_.register('criticalErrorExitToLogin');
+    this.methods_.register('criticalErrorReboot');
   }
 
   /**
diff --git a/base/native_library_fuchsia.cc b/base/native_library_fuchsia.cc
index 616bc67..d08dc221 100644
--- a/base/native_library_fuchsia.cc
+++ b/base/native_library_fuchsia.cc
@@ -50,7 +50,7 @@
 
   // Use fdio_open_fd (a Fuchsia-specific API) here so we can pass the
   // appropriate FS rights flags to request executability.
-  // TODO(1018538): Teach base::File about FLAG_EXECUTE on Fuchsia, and then
+  // TODO(1018538): Teach base::File about FLAG_WIN_EXECUTE on Fuchsia, and then
   // use it here instead of using fdio_open_fd() directly.
   base::ScopedFD fd;
   zx_status_t status = fdio_open_fd(
diff --git a/base/threading/scoped_blocking_call.h b/base/threading/scoped_blocking_call.h
index b9c78aeaf..91c0e3f 100644
--- a/base/threading/scoped_blocking_call.h
+++ b/base/threading/scoped_blocking_call.h
@@ -10,6 +10,7 @@
 #include "base/location.h"
 #include "base/strings/string_piece.h"
 #include "base/threading/scoped_blocking_call_internal.h"
+#include "base/types/strong_alias.h"
 
 namespace base {
 
@@ -116,14 +117,21 @@
 using IOJankReportingCallback =
     RepeatingCallback<void(int janky_intervals_per_minute,
                            int total_janks_per_minute)>;
+using OnlyObservedThreadsForTest =
+    StrongAlias<class OnlyObservedThreadsTag, bool>;
 // Enables IO jank monitoring and reporting for this process. Should be called
 // at most once per process and only if
 // base::TimeTicks::IsConsistentAcrossProcesses() (the algorithm is unsafe
 // otherwise). |reporting_callback| will be invoked each time a monitoring
-// window completes, see internal::~IOJankMonitoringWindow() for details (must
-// be thread-safe).
-void BASE_EXPORT
-EnableIOJankMonitoringForProcess(IOJankReportingCallback reporting_callback);
+// window completes, see internal::~IOJankMonitoringWindow() for details
+// (must be thread-safe). |only_observed_threads| can be set to true to have
+// the IOJank implementation ignore ScopedBlockingCalls on threads without a
+// BlockingObserver in tests that need to deterministically observe
+// ScopedBlockingCall side-effects.
+void BASE_EXPORT EnableIOJankMonitoringForProcess(
+    IOJankReportingCallback reporting_callback,
+    OnlyObservedThreadsForTest only_observed_threads =
+        OnlyObservedThreadsForTest(false));
 
 }  // namespace base
 
diff --git a/base/threading/scoped_blocking_call_internal.cc b/base/threading/scoped_blocking_call_internal.cc
index 82b5bda2..cc02ab5 100644
--- a/base/threading/scoped_blocking_call_internal.cc
+++ b/base/threading/scoped_blocking_call_internal.cc
@@ -38,6 +38,10 @@
 LazyInstance<ThreadLocalPointer<UncheckedScopedBlockingCall>>::Leaky
     tls_last_scoped_blocking_call = LAZY_INSTANCE_INITIALIZER;
 
+// Set to true by scoped_blocking_call_unittest to ensure unrelated threads
+// entering ScopedBlockingCalls don't affect test outcomes.
+bool g_only_monitor_observed_threads = false;
+
 bool IsBackgroundPriorityWorker() {
   return GetTaskPriorityForCurrentThread() == TaskPriority::BEST_EFFORT &&
          CanUseBackgroundPriorityForWorkerThread();
@@ -99,6 +103,7 @@
 
 // static
 void IOJankMonitoringWindow::CancelMonitoringForTesting() {
+  g_only_monitor_observed_threads = false;
   AutoLock lock(current_jank_window_lock());
   current_jank_window_storage() = nullptr;
   reporting_callback_storage() = NullCallback();
@@ -310,7 +315,8 @@
   // threads. Cancels() any pending monitored call when a WILL_BLOCK or
   // ScopedBlockingCallWithBaseSyncPrimitives nests into a
   // ScopedBlockingCall(MAY_BLOCK).
-  if (!IsBackgroundPriorityWorker()) {
+  if (!IsBackgroundPriorityWorker() &&
+      (!g_only_monitor_observed_threads || blocking_observer_)) {
     const bool is_monitored_type =
         blocking_call_type == BlockingCallType::kRegular && !is_will_block_;
     if (is_monitored_type && !previous_scoped_blocking_call_) {
@@ -352,7 +358,8 @@
 }  // namespace internal
 
 void EnableIOJankMonitoringForProcess(
-    IOJankReportingCallback reporting_callback) {
+    IOJankReportingCallback reporting_callback,
+    OnlyObservedThreadsForTest only_observed_threads) {
   {
     AutoLock lock(internal::IOJankMonitoringWindow::current_jank_window_lock());
 
@@ -362,6 +369,15 @@
         std::move(reporting_callback);
   }
 
+  if (only_observed_threads) {
+    internal::g_only_monitor_observed_threads = true;
+  } else {
+    // Do not set it to `false` when it already is as that causes data races in
+    // browser tests (which EnableIOJankMonitoringForProcess after ThreadPool is
+    // already running).
+    DCHECK(!internal::g_only_monitor_observed_threads);
+  }
+
   // Make sure monitoring starts now rather than randomly at the next
   // ScopedMonitoredCall construction.
   internal::IOJankMonitoringWindow::MonitorNextJankWindowIfNecessary(
diff --git a/base/threading/scoped_blocking_call_internal.h b/base/threading/scoped_blocking_call_internal.h
index 3f053b6..fda362bf 100644
--- a/base/threading/scoped_blocking_call_internal.h
+++ b/base/threading/scoped_blocking_call_internal.h
@@ -6,12 +6,14 @@
 #define BASE_THREADING_SCOPED_BLOCKING_CALL_INTERNAL_H_
 
 #include "base/base_export.h"
+#include "base/callback_forward.h"
 #include "base/debug/activity_tracker.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
 #include "base/time/time.h"
+#include "base/types/strong_alias.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
@@ -19,7 +21,10 @@
 // Forward-declare types from scoped_blocking_call.h to break cyclic dependency.
 enum class BlockingType;
 using IOJankReportingCallback = RepeatingCallback<void(int, int)>;
-void BASE_EXPORT EnableIOJankMonitoringForProcess(IOJankReportingCallback);
+using OnlyObservedThreadsForTest =
+    StrongAlias<class OnlyObservedThreadsTag, bool>;
+void BASE_EXPORT EnableIOJankMonitoringForProcess(IOJankReportingCallback,
+                                                  OnlyObservedThreadsForTest);
 
 // Implementation details of types in scoped_blocking_call.h and classes for a
 // few key //base types to observe and react to blocking calls.
@@ -101,7 +106,9 @@
 
  private:
   friend class base::RefCountedThreadSafe<IOJankMonitoringWindow>;
-  friend void base::EnableIOJankMonitoringForProcess(IOJankReportingCallback);
+  friend void base::EnableIOJankMonitoringForProcess(
+      IOJankReportingCallback,
+      OnlyObservedThreadsForTest);
 
   // No-op if reporting_callback_storage() is null (i.e. unless
   // EnableIOJankMonitoringForProcess() was called).
diff --git a/base/threading/scoped_blocking_call_unittest.cc b/base/threading/scoped_blocking_call_unittest.cc
index 605fa86..c3f59fa 100644
--- a/base/threading/scoped_blocking_call_unittest.cc
+++ b/base/threading/scoped_blocking_call_unittest.cc
@@ -24,6 +24,7 @@
 #include "build/build_config.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using testing::ElementsAre;
 
@@ -170,7 +171,7 @@
   explicit ScopedBlockingCallIOJankMonitoringTest(
       test::TaskEnvironment::TimeSource time_source =
           test::TaskEnvironment::TimeSource::MOCK_TIME)
-      : task_environment_(time_source) {}
+      : task_environment_(absl::in_place, time_source) {}
 
   void SetUp() override {
     // Note 1: While EnableIOJankMonitoringForProcess() is documented as being
@@ -181,15 +182,26 @@
     // spite of EnableIOJankMonitoringForProcess()'s requirement as
     // TimeSource::MOCK_TIME avoids usage of the system clock and avoids the
     // issue.
-    EnableIOJankMonitoringForProcess(BindLambdaForTesting(
-        [&](int janky_intervals_per_minute, int total_janks_per_minute) {
-          reports_.push_back(
-              {janky_intervals_per_minute, total_janks_per_minute});
-        }));
+    // OnlyObservedThreadsForTest(true) to prevent flakes which are believed to
+    // be caused by ScopedBlockingCall interference in the same process but
+    // outside this test's managed threads: crbug.com/1071166.
+    EnableIOJankMonitoringForProcess(
+        BindLambdaForTesting([&](int janky_intervals_per_minute,
+                                 int total_janks_per_minute) {
+          reports_.emplace_back(
+              janky_intervals_per_minute, total_janks_per_minute);
+        }),
+        OnlyObservedThreadsForTest(true));
+
+    internal::SetBlockingObserverForCurrentThread(&main_thread_observer);
   }
 
   void TearDown() override {
+    // Reclaim worker threads before CancelMonitoringForTesting() to avoid a
+    // data race (crbug.com/1071166#c16).
+    task_environment_.reset();
     internal::IOJankMonitoringWindow::CancelMonitoringForTesting();
+    internal::ClearBlockingObserverForCurrentThread();
   }
 
  protected:
@@ -214,7 +226,12 @@
   // TaskEnvironment+MOCK_TIME advances the test in lock steps.
   std::vector<std::pair<int, int>> reports_;
 
-  test::TaskEnvironment task_environment_;
+  absl::optional<test::TaskEnvironment> task_environment_;
+
+  // The main thread needs to register a BlockingObserver per
+  // OnlyObservedThreadsForTest(true) but doesn't otherwise care about
+  // observing.
+  testing::NiceMock<MockBlockingObserver> main_thread_observer;
 };
 
 }  // namespace
@@ -224,14 +241,14 @@
       internal::IOJankMonitoringWindow::kIOJankInterval * 7;
   {
     ScopedBlockingCall blocked_for_7s(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(kJankTiming);
+    task_environment_->FastForwardBy(kJankTiming);
   }
 
   // No janks reported before the monitoring window completes.
   EXPECT_THAT(reports_, ElementsAre());
 
   // Advance precisely to the end of this window.
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow - kJankTiming);
 
   EXPECT_THAT(reports_, ElementsAre(std::make_pair(7, 7)));
@@ -243,14 +260,14 @@
   {
     ScopedBlockingCall blocked_for_7s(FROM_HERE, BlockingType::MAY_BLOCK);
     ScopedBlockingCall nested(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(kJankTiming);
+    task_environment_->FastForwardBy(kJankTiming);
   }
 
   // No janks reported before the monitoring window completes.
   EXPECT_THAT(reports_, ElementsAre());
 
   // Jump to the next window.
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   EXPECT_THAT(reports_, ElementsAre(std::make_pair(7, 7)));
@@ -264,16 +281,16 @@
   for (int i = 0; i < 3; ++i) {
     {
       ScopedBlockingCall blocked_for_7s(FROM_HERE, BlockingType::MAY_BLOCK);
-      task_environment_.FastForwardBy(kJankTiming);
+      task_environment_->FastForwardBy(kJankTiming);
     }
-    task_environment_.FastForwardBy(kIdleTiming);
+    task_environment_->FastForwardBy(kIdleTiming);
   }
 
   // No janks reported before the monitoring window completes.
   EXPECT_THAT(reports_, ElementsAre());
 
   // Complete the current window.
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow -
       (kJankTiming + kIdleTiming) * 3);
 
@@ -287,11 +304,11 @@
 
   {
     ScopedBlockingCall blocked_for_3windows(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(kJankTiming);
+    task_environment_->FastForwardBy(kJankTiming);
   }
 
   // Fast-forward by another window with no active blocking calls.
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   // 3 windows janky for their full breadth and 1 window janky for 5 seconds.
@@ -306,13 +323,13 @@
   // No janks reported before the monitoring window completes.
   EXPECT_THAT(reports_, ElementsAre());
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   EXPECT_THAT(reports_, ElementsAre(std::make_pair(0, 0)));
 
   // No blocking call in next window also reports zero.
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
   EXPECT_THAT(reports_,
               ElementsAre(std::make_pair(0, 0), std::make_pair(0, 0)));
@@ -321,20 +338,20 @@
 // Start the jank mid-interval; that interval should be counted but the last
 // incomplete interval won't count.
 TEST_F(ScopedBlockingCallIOJankMonitoringTest, Jank7sMidInterval) {
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kIOJankInterval / 3);
 
   constexpr auto kJankTiming =
       internal::IOJankMonitoringWindow::kIOJankInterval * 7;
   {
     ScopedBlockingCall blocked_for_7s(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(kJankTiming);
+    task_environment_->FastForwardBy(kJankTiming);
   }
 
   // No janks reported before the monitoring window completes.
   EXPECT_THAT(reports_, ElementsAre());
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   EXPECT_THAT(reports_, ElementsAre(std::make_pair(7, 7)));
@@ -343,20 +360,20 @@
 // Start the jank mid-interval; that interval should be counted but the second
 // one won't count.
 TEST_F(ScopedBlockingCallIOJankMonitoringTest, Jank1sMidInterval) {
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kIOJankInterval / 3);
 
   constexpr auto kJankTiming =
       internal::IOJankMonitoringWindow::kIOJankInterval;
   {
     ScopedBlockingCall blocked_for_1s(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(kJankTiming);
+    task_environment_->FastForwardBy(kJankTiming);
   }
 
   // No janks reported before the monitoring window completes.
   EXPECT_THAT(reports_, ElementsAre());
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   EXPECT_THAT(reports_, ElementsAre(std::make_pair(1, 1)));
@@ -364,20 +381,20 @@
 
 // Jank that lasts for 1.3 intervals should be rounded down to 1.
 TEST_F(ScopedBlockingCallIOJankMonitoringTest, JankRoundDown) {
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kIOJankInterval * 0.9);
 
   constexpr auto kJankTiming =
       internal::IOJankMonitoringWindow::kIOJankInterval * 1.3;
   {
     ScopedBlockingCall blocked_for_1s(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(kJankTiming);
+    task_environment_->FastForwardBy(kJankTiming);
   }
 
   // No janks reported before the monitoring window completes.
   EXPECT_THAT(reports_, ElementsAre());
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   EXPECT_THAT(reports_, ElementsAre(std::make_pair(1, 1)));
@@ -385,20 +402,20 @@
 
 // Jank that lasts for 1.7 intervals should be rounded up to 2.
 TEST_F(ScopedBlockingCallIOJankMonitoringTest, JankRoundUp) {
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kIOJankInterval * 0.5);
 
   constexpr auto kJankTiming =
       internal::IOJankMonitoringWindow::kIOJankInterval * 1.7;
   {
     ScopedBlockingCall blocked_for_1s(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(kJankTiming);
+    task_environment_->FastForwardBy(kJankTiming);
   }
 
   // No janks reported before the monitoring window completes.
   EXPECT_THAT(reports_, ElementsAre());
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   EXPECT_THAT(reports_, ElementsAre(std::make_pair(2, 2)));
@@ -407,19 +424,19 @@
 // Start mid-interval and perform an operation that overlaps into the next one
 // but is under the jank timing.
 TEST_F(ScopedBlockingCallIOJankMonitoringTest, NoJankMidInterval) {
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kIOJankInterval / 3);
 
   {
     ScopedBlockingCall non_janky(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(
+    task_environment_->FastForwardBy(
         internal::IOJankMonitoringWindow::kIOJankInterval - Milliseconds(1));
   }
 
   // No janks reported before the monitoring window completes.
   EXPECT_THAT(reports_, ElementsAre());
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   EXPECT_THAT(reports_, ElementsAre(std::make_pair(0, 0)));
@@ -454,14 +471,14 @@
   }
 
   all_threads_blocked.Wait();
-  task_environment_.AdvanceClock(kJankTiming);
+  task_environment_->AdvanceClock(kJankTiming);
   resume_all_threads.Signal();
-  task_environment_.RunUntilIdle();
+  task_environment_->RunUntilIdle();
 
   // No janks reported before the monitoring window completes.
   EXPECT_THAT(reports_, ElementsAre());
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   // Still only 7 janky internals, but more overall janks.
@@ -498,35 +515,35 @@
   base::ThreadPool::PostTask(FROM_HERE, {MayBlock()},
                              BindOnce(blocking_task, 0));
   next_task_is_blocked.Wait();
-  task_environment_.AdvanceClock(
+  task_environment_->AdvanceClock(
       internal::IOJankMonitoringWindow::kIOJankInterval);
 
   // [1-2]s
   base::ThreadPool::PostTask(FROM_HERE, {MayBlock()},
                              BindOnce(blocking_task, 1));
   next_task_is_blocked.Wait();
-  task_environment_.AdvanceClock(
+  task_environment_->AdvanceClock(
       internal::IOJankMonitoringWindow::kIOJankInterval);
 
   // [2-3]s
   base::ThreadPool::PostTask(FROM_HERE, {MayBlock()},
                              BindOnce(blocking_task, 2));
   next_task_is_blocked.Wait();
-  task_environment_.AdvanceClock(
+  task_environment_->AdvanceClock(
       internal::IOJankMonitoringWindow::kIOJankInterval);
 
   // [3-6]s
   for (int i = 0; i < kNumJankyTasks; ++i) {
     resume_thread[i].Signal();
     exited_blocking_scope[i].Wait();
-    task_environment_.AdvanceClock(
+    task_environment_->AdvanceClock(
         internal::IOJankMonitoringWindow::kIOJankInterval);
   }
 
   // No janks reported before the monitoring window completes.
   EXPECT_THAT(reports_, ElementsAre());
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   // 9s of total janks spread across 5 intervals.
@@ -537,15 +554,7 @@
 // First one starting at 10 seconds (can't start later than that or we'll trip
 // the kTimeDiscrepancyTimeout per TaskEnvironment's inability to RunUntilIdle()
 // with pending blocked tasks).
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
-// https://crbug.com/1071166
-#define MAYBE_MultiThreadedOverlappedWindows \
-  DISABLED_MultiThreadedOverlappedWindows
-#else
-#define MAYBE_MultiThreadedOverlappedWindows MultiThreadedOverlappedWindows
-#endif
-TEST_F(ScopedBlockingCallIOJankMonitoringTest,
-       MAYBE_MultiThreadedOverlappedWindows) {
+TEST_F(ScopedBlockingCallIOJankMonitoringTest, MultiThreadedOverlappedWindows) {
   constexpr int kNumJankyTasks = 3;
   static_assert(
       kNumJankyTasks <= test::TaskEnvironment::kNumForegroundThreadPoolThreads,
@@ -572,7 +581,7 @@
   // [0-10s] (minus 1 ms to avoid reaching the timeout; this also tests the
   // logic that intervals are rounded down to the starting interval (e.g.
   // interval 9/60 in this case)).
-  task_environment_.AdvanceClock(
+  task_environment_->AdvanceClock(
       internal::IOJankMonitoringWindow::kTimeDiscrepancyTimeout -
       Milliseconds(1));
 
@@ -580,34 +589,34 @@
   base::ThreadPool::PostTask(FROM_HERE, {MayBlock()},
                              BindOnce(blocking_task, 0));
   next_task_is_blocked.Wait();
-  task_environment_.AdvanceClock(
+  task_environment_->AdvanceClock(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   // [70-130]s
   base::ThreadPool::PostTask(FROM_HERE, {MayBlock()},
                              BindOnce(blocking_task, 1));
   next_task_is_blocked.Wait();
-  task_environment_.AdvanceClock(
+  task_environment_->AdvanceClock(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   // [130-190]s
   base::ThreadPool::PostTask(FROM_HERE, {MayBlock()},
                              BindOnce(blocking_task, 2));
   next_task_is_blocked.Wait();
-  task_environment_.AdvanceClock(
+  task_environment_->AdvanceClock(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   // [190-370]s
   for (int i = 0; i < kNumJankyTasks; ++i) {
     resume_thread[i].Signal();
     exited_blocking_scope[i].Wait();
-    task_environment_.AdvanceClock(
+    task_environment_->AdvanceClock(
         internal::IOJankMonitoringWindow::kMonitoringWindow);
   }
 
   // Already past the last window (relevant events end at 360s); flush the
   // pending ripe delayed task that will complete the last window.
-  task_environment_.RunUntilIdle();
+  task_environment_->RunUntilIdle();
 
   // 540s(180s*3) of total janks spread across 300 intervals in 6 windows.
   // Distributed as such (zoomed out to 6 intervals per window):
@@ -629,25 +638,25 @@
       internal::IOJankMonitoringWindow::kIOJankInterval * 7;
   {
     ScopedBlockingCall blocked_for_7s(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(kJankTiming);
+    task_environment_->FastForwardBy(kJankTiming);
   }
 
   // Jump just beyond the kTimeDiscrepancyTimeout for the next window.
-  task_environment_.AdvanceClock(
+  task_environment_->AdvanceClock(
       internal::IOJankMonitoringWindow::kMonitoringWindow +
       internal::IOJankMonitoringWindow::kTimeDiscrepancyTimeout - kJankTiming);
-  task_environment_.RunUntilIdle();
+  task_environment_->RunUntilIdle();
 
   // Window was canceled and previous jank was not reported.
   EXPECT_THAT(reports_, ElementsAre());
 
   // The second window should be independent and need a full kMonitoringWindow
   // to elapse before reporting.
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow - Seconds(1));
   EXPECT_THAT(reports_, ElementsAre());
 
-  task_environment_.FastForwardBy(Seconds(1));
+  task_environment_->FastForwardBy(Seconds(1));
   EXPECT_THAT(reports_, ElementsAre(std::make_pair(0, 0)));
 }
 
@@ -657,11 +666,11 @@
                                              BlockingType::MAY_BLOCK);
 
     // Fast-forward 2 full windows and almost to the end of the 3rd.
-    task_environment_.FastForwardBy(
+    task_environment_->FastForwardBy(
         internal::IOJankMonitoringWindow::kMonitoringWindow * 3 - Seconds(1));
 
     // Simulate a "sleep" over the timeout threshold.
-    task_environment_.AdvanceClock(
+    task_environment_->AdvanceClock(
         Seconds(1) + internal::IOJankMonitoringWindow::kTimeDiscrepancyTimeout);
   }
 
@@ -672,13 +681,13 @@
 
   // The 4th window has a new |start_time| so completing the "remaining delta"
   // doesn't cause a report from the cancelled 3rd window.
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow - Seconds(1));
   EXPECT_THAT(reports_,
               ElementsAre(std::make_pair(60, 60), std::make_pair(60, 60)));
 
   // Completing the whole 4th window generates a report.
-  task_environment_.FastForwardBy(Seconds(1));
+  task_environment_->FastForwardBy(Seconds(1));
   EXPECT_THAT(reports_,
               ElementsAre(std::make_pair(60, 60), std::make_pair(60, 60),
                           std::make_pair(0, 0)));
@@ -705,13 +714,13 @@
       }));
 
   task_running.Wait();
-  task_environment_.AdvanceClock(kJankTiming);
+  task_environment_->AdvanceClock(kJankTiming);
   resume_task.Signal();
 
   // No janks reported before the monitoring window completes.
   EXPECT_THAT(reports_, ElementsAre());
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   if (internal::CanUseBackgroundPriorityForWorkerThread())
@@ -751,13 +760,13 @@
       }));
 
   tasks_running.Wait();
-  task_environment_.AdvanceClock(kJankTiming);
+  task_environment_->AdvanceClock(kJankTiming);
   resume_tasks.Signal();
 
   // No janks reported before the monitoring window completes.
   EXPECT_THAT(reports_, ElementsAre());
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   if (internal::CanUseBackgroundPriorityForWorkerThread())
@@ -771,10 +780,10 @@
       internal::IOJankMonitoringWindow::kIOJankInterval * 7;
   {
     ScopedBlockingCall blocked_for_7s(FROM_HERE, BlockingType::WILL_BLOCK);
-    task_environment_.FastForwardBy(kBlockedTiming);
+    task_environment_->FastForwardBy(kBlockedTiming);
   }
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   EXPECT_THAT(reports_, ElementsAre(std::make_pair(0, 0)));
@@ -786,12 +795,12 @@
       internal::IOJankMonitoringWindow::kIOJankInterval * 7;
   {
     ScopedBlockingCall blocked_for_14s(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(kBlockedTiming);
+    task_environment_->FastForwardBy(kBlockedTiming);
     ScopedBlockingCall will_block_for_7s(FROM_HERE, BlockingType::WILL_BLOCK);
-    task_environment_.FastForwardBy(kBlockedTiming);
+    task_environment_->FastForwardBy(kBlockedTiming);
   }
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   EXPECT_THAT(reports_, ElementsAre(std::make_pair(0, 0)));
@@ -802,12 +811,12 @@
       internal::IOJankMonitoringWindow::kIOJankInterval * 7;
   {
     ScopedBlockingCall blocked_for_14s(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(kBlockedTiming);
+    task_environment_->FastForwardBy(kBlockedTiming);
     ScopedBlockingCall may_block_for_7s(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(kBlockedTiming);
+    task_environment_->FastForwardBy(kBlockedTiming);
   }
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   EXPECT_THAT(reports_, ElementsAre(std::make_pair(14, 14)));
@@ -822,10 +831,10 @@
     // like Slow Reports and HangWatcher).
     internal::ScopedBlockingCallWithBaseSyncPrimitives
         base_sync_primitives_for_7s(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(kBlockedTiming);
+    task_environment_->FastForwardBy(kBlockedTiming);
   }
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   EXPECT_THAT(reports_, ElementsAre(std::make_pair(0, 0)));
@@ -837,13 +846,13 @@
       internal::IOJankMonitoringWindow::kIOJankInterval * 7;
   {
     ScopedBlockingCall blocked_for_14s(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(kBlockedTiming);
+    task_environment_->FastForwardBy(kBlockedTiming);
     internal::ScopedBlockingCallWithBaseSyncPrimitives
         base_sync_primitives_for_7s(FROM_HERE, BlockingType::MAY_BLOCK);
-    task_environment_.FastForwardBy(kBlockedTiming);
+    task_environment_->FastForwardBy(kBlockedTiming);
   }
 
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow);
 
   EXPECT_THAT(reports_, ElementsAre(std::make_pair(0, 0)));
@@ -865,7 +874,7 @@
                 "");
 
   // Start this test near an IOJankMonitoringWindow boundary.
-  task_environment_.FastForwardBy(
+  task_environment_->FastForwardBy(
       internal::IOJankMonitoringWindow::kMonitoringWindow - kDeltaFromBoundary);
 
   const int kNumRacingThreads =
@@ -887,7 +896,7 @@
   }
   all_threads_blocked.Wait();
   unblock_worker_threads.Signal();
-  task_environment_.RunUntilIdle();
+  task_environment_->RunUntilIdle();
 
   all_threads_blocked.Reset();
   on_thread_blocked = BarrierClosure(
@@ -910,7 +919,7 @@
   // the boundary is crossed before it sampled its assigned
   // IOJankMonitoringWindow, getting a window which doesn't overlap with the
   // sampled Now() identifying the ScopedBlockingCall's entry point.
-  task_environment_.AdvanceClock(kDeltaFromBoundary);
+  task_environment_->AdvanceClock(kDeltaFromBoundary);
   {
     // We have to use AdvanceClock() above as a FastForwardBy() would stall on
     // the blocked workers. This means the delayed task causing the first
@@ -920,13 +929,13 @@
   }
 
   all_threads_blocked.Wait();
-  task_environment_.AdvanceClock(kBlockedTiming);
+  task_environment_->AdvanceClock(kBlockedTiming);
   // If a worker thread holds a "begin" timestamp in the past versus its
   // assigned IOJankMonitoringWindow, completing the janky ScopedBlockingCall
   // will result in an OOB-index into
   // |IOJankMonitoringWindow::intervals_jank_count_|.
   unblock_worker_threads.Signal();
-  task_environment_.RunUntilIdle();
+  task_environment_->RunUntilIdle();
 
   // Force a report immediately.
   internal::IOJankMonitoringWindow::CancelMonitoringForTesting();
diff --git a/build/android/OWNERS b/build/android/OWNERS
index 0b64bda0..d334c39 100644
--- a/build/android/OWNERS
+++ b/build/android/OWNERS
@@ -1,7 +1,7 @@
+agrieve@chromium.org
 bjoyce@chromium.org
 jbudorick@chromium.org
 mheikal@chromium.org
 pasko@chromium.org
-skyostil@chromium.org
 tiborg@chromium.org
 wnwen@chromium.org
diff --git a/build/android/adb_command_line.py b/build/android/adb_command_line.py
index ae6a9e33a..3fd16db 100755
--- a/build/android/adb_command_line.py
+++ b/build/android/adb_command_line.py
@@ -27,7 +27,7 @@
     raise device_errors.CommandFailedError(
         'WebView only respects flags on a userdebug or eng device, yours '
         'is a user build.', device)
-  elif device.IsUserBuild():
+  if device.IsUserBuild():
     logging.warning(
         'Your device (%s) is a user build; Chrome may or may not pick up '
         'your commandline flags. Check your '
diff --git a/build/android/adb_logcat_monitor.py b/build/android/adb_logcat_monitor.py
index 6230db4d..95091282 100755
--- a/build/android/adb_logcat_monitor.py
+++ b/build/android/adb_logcat_monitor.py
@@ -33,12 +33,10 @@
 
 class TimeoutException(Exception):
   """Exception used to signal a timeout."""
-  pass
 
 
 class SigtermError(Exception):
   """Exception used to catch a sigterm."""
-  pass
 
 
 def StartLogcatIfNecessary(device_id, adb_cmd, base_dir):
@@ -48,12 +46,11 @@
     if process.poll() is None:
       # Logcat process is still happily running
       return
-    else:
-      logging.info('Logcat for device %s has died', device_id)
-      error_filter = re.compile('- waiting for device -')
-      for line in process.stderr:
-        if not error_filter.match(line):
-          logging.error(device_id + ':   ' + line)
+    logging.info('Logcat for device %s has died', device_id)
+    error_filter = re.compile('- waiting for device -')
+    for line in process.stderr:
+      if not error_filter.match(line):
+        logging.error(device_id + ':   ' + line)
 
   logging.info('Starting logcat %d for device %s', logcat_num,
                device_id)
@@ -153,6 +150,8 @@
 if __name__ == '__main__':
   if 2 <= len(sys.argv) <= 3:
     print('adb_logcat_monitor: Initializing')
-    sys.exit(main(*sys.argv[1:3]))
+    if len(sys.argv) == 2:
+      sys.exit(main(sys.argv[1]))
+  sys.exit(main(sys.argv[1], sys.argv[2]))
 
   print('Usage: %s <base_dir> [<adb_binary_path>]' % sys.argv[0])
diff --git a/build/android/apk_operations.py b/build/android/apk_operations.py
index 192d20b..d4e6c04 100755
--- a/build/android/apk_operations.py
+++ b/build/android/apk_operations.py
@@ -647,7 +647,7 @@
     # Give preference to PID reported by "ps" over those found from
     # _start_pattern. There can be multiple "Start proc" messages from prior
     # runs of the app.
-    self._found_initial_pid = self._primary_pid != None
+    self._found_initial_pid = self._primary_pid is not None
     # Retrieve any additional patterns that are relevant for the User.
     self._user_defined_highlight = None
     user_regex = os.environ.get('CHROMIUM_LOGCAT_HIGHLIGHT')
@@ -673,10 +673,10 @@
   def _GetPidStyle(self, pid, dim=False):
     if pid == self._primary_pid:
       return colorama.Fore.WHITE
-    elif pid in self._my_pids:
+    if pid in self._my_pids:
       # TODO(wnwen): Use one separate persistent color per process, pop LRU
       return colorama.Fore.YELLOW
-    elif dim:
+    if dim:
       return colorama.Style.DIM
     return ''
 
@@ -685,7 +685,7 @@
     if dim:
       return ''
     style = colorama.Fore.BLACK
-    if priority == 'E' or priority == 'F':
+    if priority in ('E', 'F'):
       style += colorama.Back.RED
     elif priority == 'W':
       style += colorama.Back.YELLOW
@@ -1068,7 +1068,7 @@
   def RegisterBundleGenerationInfo(self, bundle_generation_info):
     self.bundle_generation_info = bundle_generation_info
 
-  def _RegisterExtraArgs(self, subp):
+  def _RegisterExtraArgs(self, group):
     pass
 
   def RegisterArgs(self, parser):
diff --git a/build/android/asan_symbolize.py b/build/android/asan_symbolize.py
index 60b00d00..899171c 100755
--- a/build/android/asan_symbolize.py
+++ b/build/android/asan_symbolize.py
@@ -100,7 +100,7 @@
 
   for library, items in libraries.items():
     libname = _TranslateLibPath(library, asan_libs)
-    lib_relative_addrs = set([i.rel_address for i in items])
+    lib_relative_addrs = set(i.rel_address for i in items)
     # pylint: disable=no-member
     info_dict = symbol.SymbolInformationForSet(libname,
                                                lib_relative_addrs,
diff --git a/build/android/convert_dex_profile.py b/build/android/convert_dex_profile.py
index 1b110946..d4bbe96 100755
--- a/build/android/convert_dex_profile.py
+++ b/build/android/convert_dex_profile.py
@@ -159,10 +159,10 @@
         logging.warning('ambigous methods in dex %s at lines %s in class "%s"',
             found_methods, hint_lines, self.name)
       return found_methods
-    else:
-      logging.warning('No method named "%s" in class "%s" is '
-                      'mapped to lines %s', method_name, self.name, hint_lines)
-      return None
+    logging.warning(
+        'No method named "%s" in class "%s" is '
+        'mapped to lines %s', method_name, self.name, hint_lines)
+    return None
 
 
 class Profile(object):
diff --git a/build/android/diff_resource_sizes.py b/build/android/diff_resource_sizes.py
index 0bd2c47..e43110c7 100755
--- a/build/android/diff_resource_sizes.py
+++ b/build/android/diff_resource_sizes.py
@@ -194,6 +194,7 @@
         logging.critical('Dumping diff histograms to %s', histogram_path)
         with open(histogram_path, 'w') as json_file:
           json_file.write(histogram_result.stdout)
+  return 0
 
 
 if __name__ == '__main__':
diff --git a/build/android/dump_apk_resource_strings.py b/build/android/dump_apk_resource_strings.py
index 559547b..25f91de9 100755
--- a/build/android/dump_apk_resource_strings.py
+++ b/build/android/dump_apk_resource_strings.py
@@ -532,7 +532,7 @@
 
   res_map = ResourceStringMap()
   current_locale = None
-  current_resource_id = None
+  current_resource_id = -1  # represents undefined.
   current_resource_name = None
   need_value = False
   while True:
diff --git a/build/android/emma_coverage_stats.py b/build/android/emma_coverage_stats.py
index 9ea8baa..ec88717 100755
--- a/build/android/emma_coverage_stats.py
+++ b/build/android/emma_coverage_stats.py
@@ -399,9 +399,8 @@
     """
     if os.path.splitext(file_path)[1] == '.java' and os.path.exists(file_path):
       return True
-    else:
-      logging.info('Skipping file %s, cannot compute code coverage.', file_path)
-      return False
+    logging.info('Skipping file %s, cannot compute code coverage.', file_path)
+    return False
 
   @staticmethod
   def GetPackageNameFromFile(file_path):
@@ -421,8 +420,7 @@
         package = package_match.group(_EmmaCoverageStats.RE_PACKAGE_MATCH_GROUP)
         file_name = os.path.basename(file_path)
         return '%s.%s' % (package, file_name)
-      else:
-        return None
+      return None
 
 
 def GenerateCoverageReport(line_coverage_file, out_file_path, coverage_dir):
diff --git a/build/android/gradle/generate_gradle.py b/build/android/gradle/generate_gradle.py
index 8a5c0ab..e8b425b 100755
--- a/build/android/gradle/generate_gradle.py
+++ b/build/android/gradle/generate_gradle.py
@@ -301,12 +301,14 @@
     for library targets."""
     resource_packages = entry.Javac().get('resource_packages')
     if not resource_packages:
-      logging.debug('Target ' + entry.GnTarget() + ' includes resources from '
-          'unknown package. Unable to process with gradle.')
+      logging.debug(
+          'Target %s includes resources from unknown package. '
+          'Unable to process with gradle.', entry.GnTarget())
       return _DEFAULT_ANDROID_MANIFEST_PATH
-    elif len(resource_packages) > 1:
-      logging.debug('Target ' + entry.GnTarget() + ' includes resources from '
-          'multiple packages. Unable to process with gradle.')
+    if len(resource_packages) > 1:
+      logging.debug(
+          'Target %s includes resources from multiple packages. '
+          'Unable to process with gradle.', entry.GnTarget())
       return _DEFAULT_ANDROID_MANIFEST_PATH
 
     variables = {'package': resource_packages[0]}
@@ -543,7 +545,7 @@
     gradle_treat_as_prebuilt = deps_info.get('gradle_treat_as_prebuilt', False)
     if is_prebuilt or gradle_treat_as_prebuilt:
       return None
-    elif deps_info['requires_android']:
+    if deps_info['requires_android']:
       target_type = 'android_library'
     else:
       target_type = 'java_library'
diff --git a/build/android/gradle/gn_to_cmake.py b/build/android/gradle/gn_to_cmake.py
index 7289825..e20a3bc 100755
--- a/build/android/gradle/gn_to_cmake.py
+++ b/build/android/gradle/gn_to_cmake.py
@@ -48,8 +48,8 @@
   def Escape(c):
     if c in string.ascii_letters or c in string.digits or c in '_.+-':
       return c
-    else:
-      return '__'
+    return '__'
+
   return ''.join([Escape(c) for c in a])
 
 
@@ -65,9 +65,11 @@
 def SetVariableList(out, variable_name, values):
   """Sets a CMake variable to a list."""
   if not values:
-    return SetVariable(out, variable_name, "")
+    SetVariable(out, variable_name, "")
+    return
   if len(values) == 1:
-    return SetVariable(out, variable_name, values[0])
+    SetVariable(out, variable_name, values[0])
+    return
   out.write('list(APPEND "')
   out.write(CMakeStringEscape(variable_name))
   out.write('"\n  "')
@@ -196,8 +198,7 @@
   def GetAbsolutePath(self, path):
     if path.startswith("//"):
       return self.root_path + "/" + path[2:]
-    else:
-      return path
+    return path
 
   def GetObjectSourceDependencies(self, gn_target_name, object_dependencies):
     """All OBJECT libraries whose sources have not been absorbed."""
@@ -675,7 +676,7 @@
 def main():
   if len(sys.argv) != 2:
     print('Usage: ' + sys.argv[0] + ' <json_file_name>')
-    exit(1)
+    sys.exit(1)
 
   json_path = sys.argv[1]
   project = None
diff --git a/build/android/gyp/assert_static_initializers.py b/build/android/gyp/assert_static_initializers.py
index 330b272..8d5c0e9f 100755
--- a/build/android/gyp/assert_static_initializers.py
+++ b/build/android/gyp/assert_static_initializers.py
@@ -71,7 +71,7 @@
       raise Exception(
           'Expected no initializers for %s, yet some were found' % so_path)
     return 0
-  elif not match:
+  if not match:
     raise Exception('Did not find section: .init_array in {}:\n{}'.format(
         so_path, stdout))
   size_str = re.split(r'\W+', match.group(0))[5]
diff --git a/build/android/gyp/java_cpp_enum.py b/build/android/gyp/java_cpp_enum.py
index 08a381a9..11bde52 100755
--- a/build/android/gyp/java_cpp_enum.py
+++ b/build/android/gyp/java_cpp_enum.py
@@ -305,7 +305,7 @@
                       '. Use () for multi-line directives. E.g.\n' +
                       '// GENERATED_JAVA_ENUM_PACKAGE: (\n' +
                       '//   foo.package)')
-    elif generator_directive:
+    if generator_directive:
       directive_name = generator_directive.groups()[0]
       directive_value = generator_directive.groups()[1]
       self._generator_directives.Update(directive_name, directive_value)
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py
index 5c2bceb..01bbaa8 100755
--- a/build/android/gyp/write_build_config.py
+++ b/build/android/gyp/write_build_config.py
@@ -2114,6 +2114,7 @@
   if options.depfile:
     build_utils.WriteDepfile(options.depfile, options.build_config,
                              sorted(set(all_inputs)))
+  return 0
 
 
 if __name__ == '__main__':
diff --git a/build/android/gyp/write_native_libraries_java.py b/build/android/gyp/write_native_libraries_java.py
index 322b8b2..3200145d 100755
--- a/build/android/gyp/write_native_libraries_java.py
+++ b/build/android/gyp/write_native_libraries_java.py
@@ -100,7 +100,7 @@
   def bool_str(value):
     if value:
       return ' = true'
-    elif options.final:
+    if options.final:
       return ' = false'
     return ''
 
diff --git a/build/android/provision_devices.py b/build/android/provision_devices.py
index ecce837..aabb7ade 100755
--- a/build/android/provision_devices.py
+++ b/build/android/provision_devices.py
@@ -398,10 +398,9 @@
     if tdelta <= 1:
       logging.info('Date/time successfully set on %s', device)
       return True
-    else:
-      logging.error('Date mismatch. Device: %s Correct: %s',
-                    device_time.isoformat(), correct_time.isoformat())
-      return False
+    logging.error('Date mismatch. Device: %s Correct: %s',
+                  device_time.isoformat(), correct_time.isoformat())
+    return False
 
   # Sometimes the date is not set correctly on the devices. Retry on failure.
   if device.IsUserBuild():
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index b9127d7..c5ac8d6 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -823,8 +823,7 @@
 
   if command == 'python':
     return _RunPythonTests(args)
-  else:
-    raise Exception('Unknown test type.')
+  raise Exception('Unknown test type.')
 
 
 def _SinkTestResult(test_result, test_file_name, result_sink_client):
diff --git a/build/config/chromeos/rules.gni b/build/config/chromeos/rules.gni
index 09f9701..f0731b6f 100644
--- a/build/config/chromeos/rules.gni
+++ b/build/config/chromeos/rules.gni
@@ -224,7 +224,6 @@
 
   generate_wrapper(target_name) {
     executable = "//build/chromeos/test_runner.py"
-    use_vpython3 = true
     wrapper_script = generated_script
     executable_args = []
 
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index cdb9a62..e1666c5 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -550,6 +550,13 @@
         ldflags += [ "-Wl,-mllvm,-instcombine-lower-dbg-declare=0" ]
       }
     }
+
+    # TODO(crbug.com/1235145): Investigate why/if this should be needed.
+    if (is_win) {
+      cflags += [ "/clang:-ffp-contract=off" ]
+    } else {
+      cflags += [ "-ffp-contract=off" ]
+    }
   }
 
   # C11/C++11 compiler flags setup.
@@ -1704,7 +1711,7 @@
     "-A",
     "bare_trait_objects",
     "-A",
-    "non_fmt_panic",
+    "non_fmt_panics",
     "-A",
     "redundant_semicolons",
     "-A",
diff --git a/build/config/fuchsia/generate_runner_scripts.gni b/build/config/fuchsia/generate_runner_scripts.gni
index 2e327d6..51a9de3 100644
--- a/build/config/fuchsia/generate_runner_scripts.gni
+++ b/build/config/fuchsia/generate_runner_scripts.gni
@@ -87,7 +87,6 @@
                                ])
 
     wrapper_script = _generated_script_path
-    use_vpython3 = true
 
     deps = [ invoker.package ]
 
diff --git a/build/config/fuchsia/sizes.gni b/build/config/fuchsia/sizes.gni
index eb4c5038..20a5bf8 100644
--- a/build/config/fuchsia/sizes.gni
+++ b/build/config/fuchsia/sizes.gni
@@ -14,7 +14,6 @@
     testonly = true
     executable = "//build/fuchsia/binary_sizes.py"
     wrapper_script = "$root_out_dir/bin/run_${target_name}"
-    use_vpython3 = true
 
     assert(target_cpu == "arm64" || target_cpu == "x64",
            "target_cpu must be arm64 or x64")
diff --git a/build/util/generate_wrapper.gni b/build/util/generate_wrapper.gni
index 3406013..d63720b 100644
--- a/build/util/generate_wrapper.gni
+++ b/build/util/generate_wrapper.gni
@@ -20,8 +20,8 @@
 #     build product. Paths can be relative to the containing gn file
 #     or source-absolute.
 #   executable_args: List of arguments to write into the wrapper.
-#   use_vpython3: If true, invoke the generated wrapper with vpython3 instead
-#     of vpython.
+#   use_vpython3: If false, invoke the generated wrapper with vpython instead
+#     of vpython3.
 #
 # Example wrapping a checked-in script:
 #   generate_wrapper("sample_wrapper") {
diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc
index 07dbe4b..f6bb7778 100644
--- a/cc/trees/proxy_impl.cc
+++ b/cc/trees/proxy_impl.cc
@@ -62,10 +62,14 @@
   const raw_ptr<CompletionEvent> event_;
 };
 
-ProxyImpl::ProxyImpl(base::WeakPtr<ProxyMain> proxy_main_weak_ptr,
-                     LayerTreeHost* layer_tree_host,
-                     TaskRunnerProvider* task_runner_provider)
-    : layer_tree_host_id_(layer_tree_host->GetId()),
+ProxyImpl::ProxyImpl(
+    base::WeakPtr<ProxyMain> proxy_main_weak_ptr,
+    LayerTreeHost* layer_tree_host,
+    int id,
+    const LayerTreeSettings* settings,
+    RenderingStatsInstrumentation* rendering_stats_instrumentation,
+    TaskRunnerProvider* task_runner_provider)
+    : layer_tree_host_id_(id),
       next_frame_is_newly_committed_frame_(false),
       inside_draw_(false),
       task_runner_provider_(task_runner_provider),
@@ -80,17 +84,16 @@
   DCHECK(IsMainThreadBlocked());
 
   host_impl_ = layer_tree_host->CreateLayerTreeHostImpl(this);
-  const LayerTreeSettings& settings = layer_tree_host->GetSettings();
-  send_compositor_frame_ack_ = settings.send_compositor_frame_ack;
+  send_compositor_frame_ack_ = settings->send_compositor_frame_ack;
   last_raster_priority_ = SAME_PRIORITY_FOR_BOTH_TREES;
 
-  SchedulerSettings scheduler_settings(settings.ToSchedulerSettings());
+  SchedulerSettings scheduler_settings(settings->ToSchedulerSettings());
 
   std::unique_ptr<CompositorTimingHistory> compositor_timing_history(
       new CompositorTimingHistory(
           scheduler_settings.using_synchronous_renderer_compositor,
           CompositorTimingHistory::RENDERER_UMA,
-          layer_tree_host->rendering_stats_instrumentation()));
+          rendering_stats_instrumentation));
   scheduler_ = std::make_unique<Scheduler>(
       this, scheduler_settings, layer_tree_host_id_,
       task_runner_provider_->ImplThreadTaskRunner(),
diff --git a/cc/trees/proxy_impl.h b/cc/trees/proxy_impl.h
index e3f0a20..52017b9 100644
--- a/cc/trees/proxy_impl.h
+++ b/cc/trees/proxy_impl.h
@@ -6,6 +6,7 @@
 #define CC_TREES_PROXY_IMPL_H_
 
 #include <memory>
+#include <utility>
 #include <vector>
 
 #include "base/memory/raw_ptr.h"
@@ -37,6 +38,9 @@
  public:
   ProxyImpl(base::WeakPtr<ProxyMain> proxy_main_weak_ptr,
             LayerTreeHost* layer_tree_host,
+            int id,
+            const LayerTreeSettings* settings,
+            RenderingStatsInstrumentation* rendering_stats_instrumentation,
             TaskRunnerProvider* task_runner_provider);
   ProxyImpl(const ProxyImpl&) = delete;
   ~ProxyImpl() override;
diff --git a/cc/trees/proxy_main.cc b/cc/trees/proxy_main.cc
index 57192ea..e639566 100644
--- a/cc/trees/proxy_main.cc
+++ b/cc/trees/proxy_main.cc
@@ -53,11 +53,16 @@
   DCHECK(!started_);
 }
 
-void ProxyMain::InitializeOnImplThread(CompletionEvent* completion_event) {
+void ProxyMain::InitializeOnImplThread(
+    CompletionEvent* completion_event,
+    int id,
+    const LayerTreeSettings* settings,
+    RenderingStatsInstrumentation* rendering_stats_instrumentation) {
   DCHECK(task_runner_provider_->IsImplThread());
   DCHECK(!proxy_impl_);
   proxy_impl_ = std::make_unique<ProxyImpl>(
-      weak_factory_.GetWeakPtr(), layer_tree_host_, task_runner_provider_);
+      weak_factory_.GetWeakPtr(), layer_tree_host_, id, settings,
+      rendering_stats_instrumentation, task_runner_provider_);
   completion_event->Signal();
 }
 
@@ -567,8 +572,12 @@
     DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
     CompletionEvent completion;
     ImplThreadTaskRunner()->PostTask(
-        FROM_HERE, base::BindOnce(&ProxyMain::InitializeOnImplThread,
-                                  base::Unretained(this), &completion));
+        FROM_HERE,
+        base::BindOnce(&ProxyMain::InitializeOnImplThread,
+                       base::Unretained(this), &completion,
+                       layer_tree_host_->GetId(),
+                       &layer_tree_host_->GetSettings(),
+                       layer_tree_host_->rendering_stats_instrumentation()));
     completion.Wait();
   }
 
diff --git a/cc/trees/proxy_main.h b/cc/trees/proxy_main.h
index 26be7ad..cbcd3a8 100644
--- a/cc/trees/proxy_main.h
+++ b/cc/trees/proxy_main.h
@@ -123,7 +123,11 @@
   bool IsImplThread() const;
   base::SingleThreadTaskRunner* ImplThreadTaskRunner();
 
-  void InitializeOnImplThread(CompletionEvent* completion_event);
+  void InitializeOnImplThread(
+      CompletionEvent* completion_event,
+      int id,
+      const LayerTreeSettings* settings,
+      RenderingStatsInstrumentation* rendering_stats_instrumentation);
   void DestroyProxyImplOnImplThread(CompletionEvent* completion_event);
 
   raw_ptr<LayerTreeHost> layer_tree_host_;
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index 3dd6126..da3b164b 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -1370,7 +1370,10 @@
   }
 
   if (is_chromeos_lacros) {
-    public_deps += [ "//chromeos/lacros" ]
+    public_deps += [
+      "//chromeos/lacros",
+      "//chromeos/lacros/dbus",
+    ]
   }
 
   if (is_chromeos_ash) {
diff --git a/chrome/VERSION b/chrome/VERSION
index a64adcc..4634856 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=98
 MINOR=0
-BUILD=4739
+BUILD=4740
 PATCH=0
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn
index ff9b86f..1ec0f190 100644
--- a/chrome/app/BUILD.gn
+++ b/chrome/app/BUILD.gn
@@ -225,6 +225,7 @@
     deps += [
       "//chromeos/crosapi/mojom",
       "//chromeos/lacros",
+      "//chromeos/lacros/dbus",
     ]
   }
 
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index 93511e9..87727e3f 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -186,7 +186,7 @@
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "chrome/common/chrome_paths_lacros.h"
 #include "chromeos/crosapi/mojom/crosapi.mojom.h"  // nogncheck
-#include "chromeos/lacros/lacros_dbus_helper.h"
+#include "chromeos/lacros/dbus/lacros_dbus_helper.h"
 #include "chromeos/lacros/lacros_service.h"
 #include "media/base/media_switches.h"
 #endif
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 8419b3e..b1577af 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2019,6 +2019,7 @@
     "//chrome/browser/ui/webui/read_later/side_panel:mojo_bindings",
     "//chrome/browser/ui/webui/realbox:mojo_bindings",
     "//chrome/browser/ui/webui/reset_password:mojo_bindings",
+    "//chrome/browser/ui/webui/segmentation_internals:mojo_bindings",
     "//chrome/browser/ui/webui/tab_search:mojo_bindings",
     "//chrome/browser/ui/webui/usb_internals:mojo_bindings",
     "//chrome/browser/updates/announcement_notification",
@@ -5222,6 +5223,7 @@
       "//chromeos/crosapi/mojom",
       "//chromeos/dbus/dlp:dlp",
       "//chromeos/lacros",
+      "//chromeos/lacros/dbus",
       "//chromeos/ui/frame",
       "//ui/platform_window",
     ]
diff --git a/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc b/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc
index e4d1807..b2c49df 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc
@@ -108,6 +108,16 @@
 
   publisher_host_ = std::make_unique<PublisherHost>(this);
 
+  if (crosapi::browser_util::IsLacrosEnabled() &&
+      chromeos::ProfileHelper::IsPrimaryProfile(profile_) &&
+      web_app::IsWebAppsCrosapiEnabled()) {
+    auto* browser_manager = crosapi::BrowserManager::Get();
+    // In unit tests, it is possible that the browser manager is not created.
+    if (browser_manager) {
+      keep_alive_ = browser_manager->KeepAlive(
+          crosapi::BrowserManager::Feature::kAppService);
+    }
+  }
   if (!profile_->AsTestingProfile()) {
     app_platform_metrics_service_ =
         std::make_unique<AppPlatformMetricsService>(profile_);
diff --git a/chrome/browser/apps/app_service/app_service_proxy_chromeos.h b/chrome/browser/apps/app_service/app_service_proxy_chromeos.h
index b433be3..b5d61e8 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_chromeos.h
+++ b/chrome/browser/apps/app_service/app_service_proxy_chromeos.h
@@ -16,6 +16,7 @@
 #include "chrome/browser/apps/app_service/app_service_proxy_base.h"
 #include "chrome/browser/apps/app_service/paused_apps.h"
 #include "chrome/browser/apps/app_service/publisher_host.h"
+#include "chrome/browser/ash/crosapi/browser_manager.h"
 #include "components/services/app_service/public/cpp/app_registry_cache.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
 #include "components/services/app_service/public/cpp/instance_registry.h"
@@ -216,6 +217,10 @@
   std::unique_ptr<apps::AppPlatformMetricsService>
       app_platform_metrics_service_;
 
+  // App service require the Lacros Browser to keep alive for web apps.
+  // TODO(crbug.com/1174246): Support Lacros not keeping alive.
+  std::unique_ptr<crosapi::BrowserManager::ScopedKeepAlive> keep_alive_;
+
   base::WeakPtrFactory<AppServiceProxyChromeOs> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_base.cc b/chrome/browser/apps/app_service/publishers/extension_apps_base.cc
index eaf22f5..7e6f961ab 100644
--- a/chrome/browser/apps/app_service/publishers/extension_apps_base.cc
+++ b/chrome/browser/apps/app_service/publishers/extension_apps_base.cc
@@ -24,7 +24,6 @@
 #include "chrome/browser/apps/app_service/publishers/extension_apps_enable_flow.h"
 #include "chrome/browser/apps/app_service/publishers/extension_apps_util.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_uninstall_dialog.h"
 #include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/extensions/launch_util.h"
 #include "chrome/browser/prefs/incognito_mode_prefs.h"
@@ -578,19 +577,8 @@
       ->UninstallExtension(
           app_id, GetExtensionUninstallReason(uninstall_source), &error);
 
-  if (!report_abuse) {
-    UMA_HISTOGRAM_ENUMERATION(
-        "Extensions.UninstallDialogAction",
-        extensions::ExtensionUninstallDialog::CLOSE_ACTION_UNINSTALL,
-        extensions::ExtensionUninstallDialog::CLOSE_ACTION_LAST);
+  if (!report_abuse)
     return;
-  }
-
-  UMA_HISTOGRAM_ENUMERATION(
-      "Extensions.UninstallDialogAction",
-      extensions::ExtensionUninstallDialog::
-          CLOSE_ACTION_UNINSTALL_AND_CHECKBOX_CHECKED,
-      extensions::ExtensionUninstallDialog::CLOSE_ACTION_LAST);
 
   // If the extension specifies a custom uninstall page via
   // chrome.runtime.setUninstallURL, then at uninstallation its uninstall
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
index 74018eba..42b25cc 100644
--- a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
+++ b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
@@ -134,11 +134,6 @@
         "Webapp.UninstallDialogAction",
         extensions::ExtensionUninstallDialog::CLOSE_ACTION_CANCELED,
         extensions::ExtensionUninstallDialog::CLOSE_ACTION_LAST);
-  } else {
-    UMA_HISTOGRAM_ENUMERATION(
-        "Extensions.UninstallDialogAction",
-        extensions::ExtensionUninstallDialog::CLOSE_ACTION_CANCELED,
-        extensions::ExtensionUninstallDialog::CLOSE_ACTION_LAST);
   }
 }
 
diff --git a/chrome/browser/ash/account_manager/account_apps_availability.cc b/chrome/browser/ash/account_manager/account_apps_availability.cc
index 01394690..c372eda 100644
--- a/chrome/browser/ash/account_manager/account_apps_availability.cc
+++ b/chrome/browser/ash/account_manager/account_apps_availability.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ash/account_manager/account_apps_availability.h"
 
 #include "ash/constants/ash_features.h"
+#include "base/containers/flat_set.h"
 #include "base/feature_list.h"
 
 namespace ash {
@@ -19,4 +20,33 @@
          base::FeatureList::IsEnabled(chromeos::features::kLacrosSupport);
 }
 
+void AccountAppsAvailability::AddObserver(Observer* observer) {
+  observer_list_.AddObserver(observer);
+}
+
+void AccountAppsAvailability::RemoveObserver(Observer* observer) {
+  observer_list_.RemoveObserver(observer);
+}
+
+void AccountAppsAvailability::SetIsAccountAvailableInArc(
+    const account_manager::Account& account,
+    bool is_available) {
+  NOTIMPLEMENTED();
+}
+
+void AccountAppsAvailability::GetAccountsAvailableInArc(
+    base::OnceCallback<void(const base::flat_set<account_manager::Account>&)>
+        callback) {
+  NOTIMPLEMENTED();
+}
+
+void AccountAppsAvailability::OnRefreshTokenUpdatedForAccount(
+    const CoreAccountInfo& account_info) {}
+
+void AccountAppsAvailability::OnAccountUpserted(
+    const account_manager::Account& account) {}
+
+void AccountAppsAvailability::OnAccountRemoved(
+    const account_manager::Account& account) {}
+
 }  // namespace ash
diff --git a/chrome/browser/ash/account_manager/account_apps_availability.h b/chrome/browser/ash/account_manager/account_apps_availability.h
index ae76e11..36546d79 100644
--- a/chrome/browser/ash/account_manager/account_apps_availability.h
+++ b/chrome/browser/ash/account_manager/account_apps_availability.h
@@ -5,7 +5,12 @@
 #ifndef CHROME_BROWSER_ASH_ACCOUNT_MANAGER_ACCOUNT_APPS_AVAILABILITY_H_
 #define CHROME_BROWSER_ASH_ACCOUNT_MANAGER_ACCOUNT_APPS_AVAILABILITY_H_
 
+#include "base/containers/flat_set.h"
+#include "base/observer_list.h"
+#include "components/account_manager_core/account.h"
+#include "components/account_manager_core/account_manager_facade.h"
 #include "components/keyed_service/core/keyed_service.h"
+#include "components/signin/public/identity_manager/identity_manager.h"
 
 namespace ash {
 
@@ -16,8 +21,33 @@
 // There should be only one instance of this class, which is attached to the
 // only regular Ash profile. The class should exist only if Account Manager
 // exists (if `ash::IsAccountManagerAvailable(profile)` is `true`).
-class AccountAppsAvailability : public KeyedService {
+class AccountAppsAvailability
+    : public KeyedService,
+      public account_manager::AccountManagerFacade::Observer,
+      public signin::IdentityManager::Observer {
  public:
+  class Observer : public base::CheckedObserver {
+   public:
+    Observer() = default;
+    Observer(const Observer&) = delete;
+    Observer& operator=(const Observer&) = delete;
+    ~Observer() override = default;
+
+    // Called when the account should become available in ARC
+    // (`SetIsAccountAvailableInArc` is called with `true`). Also called when
+    // the token of an account that is already available in ARC is updated. At
+    // the time of this call the `account`'s token is already updated /
+    // available in `IdentityManager`.
+    virtual void OnAccountAvailableInArc(
+        const account_manager::Account& account) {}
+
+    // Called when the account becomes unavailable in ARC
+    // (`SetIsAccountAvailableInArc` is called with `false`).
+    // Also called when the account is removed from Account Manager.
+    virtual void OnAccountUnavailableInArc(
+        const account_manager::Account& account) {}
+  };
+
   AccountAppsAvailability();
   ~AccountAppsAvailability() override;
 
@@ -27,8 +57,34 @@
   // Returns `true` if `kArcAccountRestrictions` and `kLacrosSupport` are
   // enabled.
   static bool IsArcAccountRestrictionsEnabled();
-};
 
+  // Registers an observer.
+  void AddObserver(Observer* observer);
+  // Unregisters an observer that was registered using AddObserver.
+  void RemoveObserver(Observer* observer);
+
+  // Set whether the specified account should be available in ARC. Only Gaia
+  // accounts are supported.
+  void SetIsAccountAvailableInArc(const account_manager::Account& account,
+                                  bool is_available);
+
+  // Calls the `callback` with the set of accounts that should be
+  // available in ARC.
+  void GetAccountsAvailableInArc(
+      base::OnceCallback<void(const base::flat_set<account_manager::Account>&)>
+          callback);
+
+ private:
+  // `IdentityManager::Observer`:
+  void OnRefreshTokenUpdatedForAccount(
+      const CoreAccountInfo& account_info) override;
+
+  // `AccountManagerFacade::Observer`:
+  void OnAccountUpserted(const account_manager::Account& account) override;
+  void OnAccountRemoved(const account_manager::Account& account) override;
+
+  base::ObserverList<Observer> observer_list_;
+};
 }  // namespace ash
 
 #endif  // CHROME_BROWSER_ASH_ACCOUNT_MANAGER_ACCOUNT_APPS_AVAILABILITY_H_
diff --git a/chrome/browser/ash/crosapi/browser_manager.h b/chrome/browser/ash/crosapi/browser_manager.h
index c6b4da3..9cf56d4 100644
--- a/chrome/browser/ash/crosapi/browser_manager.h
+++ b/chrome/browser/ash/crosapi/browser_manager.h
@@ -35,6 +35,7 @@
 }  // namespace component_updater
 
 namespace apps {
+class AppServiceProxyChromeOs;
 class StandaloneBrowserExtensionApps;
 }  // namespace apps
 
@@ -246,6 +247,15 @@
  private:
   FRIEND_TEST_ALL_PREFIXES(BrowserManagerTest, LacrosKeepAlive);
   friend class apps::StandaloneBrowserExtensionApps;
+  // App service require the lacros-chrome to keep alive for web apps to:
+  // 1. Have lacros-chrome running before user open the browser so we can
+  //    have web apps info showing on the app list, shelf, etc..
+  // 2. Able to interact with web apps (e.g. uninstall) at any time.
+  // 3. Have notifications.
+  // TODO(crbug.com/1174246): This is a short term solution to integrate
+  // web apps in Lacros. Need to decouple the App Platform systems from
+  // needing lacros-chrome running all the time.
+  friend class apps::AppServiceProxyChromeOs;
 
   // Returns true if the binary is ready to launch or already launched.
   bool IsReady() const;
diff --git a/chrome/browser/ash/input_method/autocorrect_manager.cc b/chrome/browser/ash/input_method/autocorrect_manager.cc
index 6aacb60..ca4eab41 100644
--- a/chrome/browser/ash/input_method/autocorrect_manager.cc
+++ b/chrome/browser/ash/input_method/autocorrect_manager.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/ash/input_method/autocorrect_manager.h"
 
+#include "ash/constants/ash_features.h"
+#include "base/feature_list.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
@@ -199,6 +201,12 @@
 }
 
 void AutocorrectManager::OnFocus(int context_id) {
+  if (base::FeatureList::IsEnabled(ash::features::kImeRuleConfig)) {
+    GetTextFieldContextualInfo(
+        base::BindOnce(&AutocorrectManager::OnTextFieldContextualInfoChanged,
+                       base::Unretained(this)));
+  }
+
   if (key_presses_until_underline_hide_ > 0) {
     // TODO(b/149796494): move this to onblur()
     LogAssistiveAutocorrectAction(
@@ -268,5 +276,15 @@
   LogAssistiveAutocorrectDelay(base::TimeTicks::Now() - autocorrect_time_);
 }
 
+void AutocorrectManager::OnTextFieldContextualInfoChanged(
+    const TextFieldContextualInfo& info) {
+  // TODO(b/207587725): Check whether auto correct is allowed by rules.
+  disabled_by_rule_ = false;
+}
+
+bool AutocorrectManager::DisabledByRule() {
+  return disabled_by_rule_;
+}
+
 }  // namespace input_method
 }  // namespace ash
diff --git a/chrome/browser/ash/input_method/autocorrect_manager.h b/chrome/browser/ash/input_method/autocorrect_manager.h
index f465fc34..6a395b6 100644
--- a/chrome/browser/ash/input_method/autocorrect_manager.h
+++ b/chrome/browser/ash/input_method/autocorrect_manager.h
@@ -11,6 +11,7 @@
 #include "chrome/browser/ash/input_method/diacritics_insensitive_string_comparator.h"
 #include "chrome/browser/ash/input_method/input_method_engine_base.h"
 #include "chrome/browser/ash/input_method/suggestion_handler_interface.h"
+#include "chrome/browser/ash/input_method/text_field_contextual_info_fetcher.h"
 
 namespace ash {
 namespace input_method {
@@ -67,9 +68,14 @@
 
   void UndoAutocorrect();
 
+  // Whether auto correction is disabled by some rule.
+  bool DisabledByRule();
+
  private:
   void LogAssistiveAutocorrectAction(AutocorrectActions action);
 
+  void OnTextFieldContextualInfoChanged(const TextFieldContextualInfo& info);
+
   SuggestionHandlerInterface* suggestion_handler_;
   int context_id_ = 0;
   int key_presses_until_underline_hide_ = 0;
@@ -81,6 +87,8 @@
   DiacriticsInsensitiveStringComparator
       diacritics_insensitive_string_comparator_;
   bool in_diacritical_autocorrect_session_ = false;
+
+  bool disabled_by_rule_ = false;
 };
 
 }  // namespace input_method
diff --git a/chrome/browser/ash/input_method/input_host_helper.cc b/chrome/browser/ash/input_method/input_host_helper.cc
deleted file mode 100644
index 3a134980..0000000
--- a/chrome/browser/ash/input_method/input_host_helper.cc
+++ /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.
-
-#include "chrome/browser/ash/input_method/input_host_helper.h"
-
-#include "ash/public/cpp/window_properties.h"
-#include "ash/wm/window_util.h"
-#include "ui/aura/window.h"
-
-namespace ash {
-namespace input_method {
-
-void PopulateInputHost(InputAssociatedHost* host) {
-  aura::Window* window = ash::window_util::GetActiveWindow();
-  if (window) {
-    // TODO(crbug/163645900): Get app_type via aura::client::kAppType.
-    const std::string* key = window->GetProperty(ash::kAppIDKey);
-    if (key) {
-      host->app_key = *key;
-    }
-  }
-}
-
-}  // namespace input_method
-}  // namespace ash
diff --git a/chrome/browser/ash/input_method/input_host_helper.h b/chrome/browser/ash/input_method/input_host_helper.h
deleted file mode 100644
index f82060d..0000000
--- a/chrome/browser/ash/input_method/input_host_helper.h
+++ /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.
-
-#ifndef CHROME_BROWSER_ASH_INPUT_METHOD_INPUT_HOST_HELPER_H_
-#define CHROME_BROWSER_ASH_INPUT_METHOD_INPUT_HOST_HELPER_H_
-
-#include <string>
-
-#include "ash/constants/app_types.h"
-
-namespace ash {
-namespace input_method {
-
-struct InputAssociatedHost {
-  // Type of app associated with this text field.
-  ash::AppType app_type;
-  // Key of app associated with this text field.
-  std::string app_key;
-};
-
-void PopulateInputHost(InputAssociatedHost* host);
-
-}  // namespace input_method
-}  // namespace ash
-
-#endif  // CHROME_BROWSER_ASH_INPUT_METHOD_INPUT_HOST_HELPER_H_
diff --git a/chrome/browser/ash/input_method/native_input_method_engine.cc b/chrome/browser/ash/input_method/native_input_method_engine.cc
index 68c90e6a..fd492ae7 100644
--- a/chrome/browser/ash/input_method/native_input_method_engine.cc
+++ b/chrome/browser/ash/input_method/native_input_method_engine.cc
@@ -742,6 +742,13 @@
         std::move(callback).Run(false);
         return;
       }
+
+      // Hot switches to turn on/off certain IME features.
+      if (IsFstEngine(engine_id) && autocorrect_manager_->DisabledByRule()) {
+        std::move(callback).Run(false);
+        return;
+      }
+
       if (filtered) {
         // TODO(b/174612548): Transform the corresponding KEY_RELEASED event to
         // use the composed character as well.
diff --git a/chrome/browser/ash/input_method/text_field_contextual_info_fetcher.cc b/chrome/browser/ash/input_method/text_field_contextual_info_fetcher.cc
new file mode 100644
index 0000000..dfe424d
--- /dev/null
+++ b/chrome/browser/ash/input_method/text_field_contextual_info_fetcher.cc
@@ -0,0 +1,99 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/input_method/text_field_contextual_info_fetcher.h"
+
+#include "ash/constants/app_types.h"
+#include "ash/public/cpp/window_properties.h"
+#include "ash/wm/window_util.h"
+#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/window.h"
+
+namespace ash {
+namespace input_method {
+
+namespace {
+
+void TextFieldContextualInfoWithUrl(TextFieldContextualInfoCallback cb,
+                                    TextFieldContextualInfo& info,
+                                    const absl::optional<GURL>& url) {
+  if (url.has_value()) {
+    info.tab_url = url.value().host();
+  }
+  std::move(cb).Run(std::move(info));
+}
+
+}  // namespace
+
+TextFieldContextualInfo::TextFieldContextualInfo() = default;
+
+TextFieldContextualInfo::TextFieldContextualInfo(ash::AppType type)
+    : app_type(type) {}
+
+TextFieldContextualInfo::~TextFieldContextualInfo() = default;
+
+void GetTextFieldAppTypeAndKey(TextFieldContextualInfo& info) {
+  aura::Window* window = ash::window_util::GetActiveWindow();
+  if (!window) {
+    info.app_type = ash::AppType::NON_APP;
+    return;
+  }
+
+  info.app_type =
+      static_cast<ash::AppType>(window->GetProperty(aura::client::kAppType));
+
+  const std::string* key = window->GetProperty(ash::kAppIDKey);
+  if (key) {
+    info.app_key = *key;
+  }
+}
+
+void GetTextFieldContextualInfo(TextFieldContextualInfoCallback cb) {
+  TextFieldContextualInfo info;
+  GetTextFieldAppTypeAndKey(info);
+
+  if (info.app_type == ash::AppType::LACROS) {
+    GetUrlForTextFieldOnLacros(base::BindOnce(
+        TextFieldContextualInfoWithUrl, std::move(cb), base::OwnedRef(info)));
+    return;
+  }
+
+  TextFieldContextualInfoWithUrl(std::move(cb), info,
+                                 info.app_type == ash::AppType::BROWSER
+                                     ? GetUrlForTextFieldOnAshChrome()
+                                     : absl::nullopt);
+}
+
+absl::optional<GURL> GetUrlForTextFieldOnAshChrome() {
+  Browser* browser = chrome::FindLastActive();
+  // Ash chrome will return true for browser->window()->IsActive() if the
+  // user is currently typing in an ash browser tab. IsActive() will return
+  // false if the user is currently typing a lacros browser tab.
+  if (browser && browser->window() && browser->window()->IsActive() &&
+      browser->tab_strip_model() &&
+      browser->tab_strip_model()->GetActiveWebContents()) {
+    return browser->tab_strip_model()
+        ->GetActiveWebContents()
+        ->GetLastCommittedURL();
+  }
+
+  return absl::nullopt;
+}
+
+void GetUrlForTextFieldOnLacros(TextFieldTabUrlCallback cb) {
+  crosapi::BrowserManager* browser_manager = crosapi::BrowserManager::Get();
+  // browser_manager will exist whenever there is a lacros browser running.
+  // GetActiveTabUrlSupported() will only return true if the current lacros
+  // browser is being used by the user.
+  if (browser_manager && browser_manager->IsRunning() &&
+      browser_manager->GetActiveTabUrlSupported()) {
+    browser_manager->GetActiveTabUrl(std::move(cb));
+    return;
+  }
+
+  std::move(cb).Run(absl::nullopt);
+}
+
+}  // namespace input_method
+}  // namespace ash
diff --git a/chrome/browser/ash/input_method/text_field_contextual_info_fetcher.h b/chrome/browser/ash/input_method/text_field_contextual_info_fetcher.h
new file mode 100644
index 0000000..897b246d
--- /dev/null
+++ b/chrome/browser/ash/input_method/text_field_contextual_info_fetcher.h
@@ -0,0 +1,56 @@
+// 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_ASH_INPUT_METHOD_TEXT_FIELD_CONTEXTUAL_INFO_FETCHER_H_
+#define CHROME_BROWSER_ASH_INPUT_METHOD_TEXT_FIELD_CONTEXTUAL_INFO_FETCHER_H_
+
+#include <string>
+
+#include "ash/constants/app_types.h"
+#include "base/callback.h"
+#include "chrome/browser/ash/crosapi/browser_manager.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "url/gurl.h"
+
+namespace ash {
+namespace input_method {
+
+struct TextFieldContextualInfo {
+  TextFieldContextualInfo();
+  explicit TextFieldContextualInfo(ash::AppType t);
+  ~TextFieldContextualInfo();
+
+  // Type of app associated with the text field.
+  ash::AppType app_type;
+  // Optional, key of the app associated with this text field.
+  std::string app_key;
+  // Optional, tab's url where this text field is.
+  std::string tab_url;
+};
+
+// Get the type and key of the current active app where the text filed is
+// hosted. This is a lightweight and synced call.
+void GetTextFieldAppTypeAndKey(TextFieldContextualInfo& info);
+
+using TextFieldContextualInfoCallback =
+    base::OnceCallback<void(const TextFieldContextualInfo& info)>;
+// Get the contextual info of the current text filed.
+// Its sub queries may go over IPCs.
+void GetTextFieldContextualInfo(TextFieldContextualInfoCallback cb);
+
+// Get the current tab url if the text field is hosted by a tab.
+absl::optional<GURL> GetUrlForTextFieldOnAshChrome();
+
+using TextFieldTabUrlCallback =
+    base::OnceCallback<void(const absl::optional<GURL>& url)>;
+// Get the current tab url if the text field is hosted by a tab from Lacros.
+// This query requires a further call over IPC.
+void GetUrlForTextFieldOnLacros(TextFieldTabUrlCallback cb);
+
+}  // namespace input_method
+}  // namespace ash
+
+#endif  // CHROME_BROWSER_ASH_INPUT_METHOD_TEXT_FIELD_CONTEXTUAL_INFO_FETCHER_H_
diff --git a/chrome/browser/ash/login/screens/consolidated_consent_screen.cc b/chrome/browser/ash/login/screens/consolidated_consent_screen.cc
index ba185f25..6cd4534 100644
--- a/chrome/browser/ash/login/screens/consolidated_consent_screen.cc
+++ b/chrome/browser/ash/login/screens/consolidated_consent_screen.cc
@@ -57,10 +57,15 @@
 }
 
 std::string GetCrosEulaOnlineUrl() {
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kOobeEulaUrlForTests)) {
+    return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+        switches::kOobeEulaUrlForTests);
+  }
+
   return base::StringPrintf(chrome::kCrosEulaOnlineURLPath,
                             g_browser_process->GetApplicationLocale().c_str());
 }
-
 }  // namespace
 
 std::string ConsolidatedConsentScreen::GetResultString(Result result) {
diff --git a/chrome/browser/ash/login/screens/consolidated_consent_screen.h b/chrome/browser/ash/login/screens/consolidated_consent_screen.h
index e66f85ae..d817b47 100644
--- a/chrome/browser/ash/login/screens/consolidated_consent_screen.h
+++ b/chrome/browser/ash/login/screens/consolidated_consent_screen.h
@@ -61,6 +61,10 @@
   // associated View if this class is destroyed before that.
   void OnViewDestroyed(ConsolidatedConsentScreenView* view);
 
+  void set_exit_callback_for_testing(const ScreenExitCallback& exit_callback) {
+    exit_callback_ = exit_callback;
+  }
+
   const ScreenExitCallback& get_exit_callback_for_testing() {
     return exit_callback_;
   }
diff --git a/chrome/browser/ash/login/screens/consolidated_consent_screen_browsertest.cc b/chrome/browser/ash/login/screens/consolidated_consent_screen_browsertest.cc
new file mode 100644
index 0000000..7c1787de
--- /dev/null
+++ b/chrome/browser/ash/login/screens/consolidated_consent_screen_browsertest.cc
@@ -0,0 +1,193 @@
+// 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/ash/login/screens/consolidated_consent_screen.h"
+
+#include "ash/constants/ash_features.h"
+#include "ash/constants/ash_switches.h"
+#include "chrome/browser/ash/login/oobe_screen.h"
+#include "chrome/browser/ash/login/test/fake_eula_mixin.h"
+#include "chrome/browser/ash/login/test/js_checker.h"
+#include "chrome/browser/ash/login/test/login_manager_mixin.h"
+#include "chrome/browser/ash/login/test/oobe_base_test.h"
+#include "chrome/browser/ash/login/test/oobe_screen_waiter.h"
+#include "chrome/browser/ash/login/test/webview_content_extractor.h"
+#include "chrome/browser/ash/login/ui/login_display_host.h"
+#include "chrome/browser/ash/login/ui/webui_login_view.h"
+#include "chrome/browser/ash/login/wizard_controller.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/ui/browser.h"
+#include "content/public/test/browser_test.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace ash {
+namespace {
+
+using ::testing::_;
+
+constexpr char kConsolidatedConsentId[] = "consolidated-consent";
+
+// Loaded Dialog
+const test::UIPath kLoadedDialog = {kConsolidatedConsentId, "loadedDialog"};
+const test::UIPath kGoogleEulaLinkArcDisabled = {kConsolidatedConsentId,
+                                                 "googleEulaLinkArcDisabled"};
+const test::UIPath kCrosEulaLinkArcDisabled = {kConsolidatedConsentId,
+                                               "crosEulaLinkArcDisabled"};
+const test::UIPath kUsageStats = {kConsolidatedConsentId, "usageStats"};
+const test::UIPath kUsageStatsToggle = {kConsolidatedConsentId, "usageOptin"};
+const test::UIPath kUsageLearnMoreLink = {kConsolidatedConsentId,
+                                          "usageLearnMore"};
+const test::UIPath kUsageLearnMorePopUp = {kConsolidatedConsentId,
+                                           "usageLearnMorePopUp"};
+const test::UIPath kUsageLearnMorePopUpClose = {
+    kConsolidatedConsentId, "usageLearnMorePopUp", "closeButton"};
+const test::UIPath kBackup = {kConsolidatedConsentId, "backup"};
+const test::UIPath kLocation = {kConsolidatedConsentId, "location"};
+const test::UIPath kFooter = {kConsolidatedConsentId, "footer"};
+const test::UIPath kAcceptButton = {kConsolidatedConsentId, "acceptButton"};
+
+// Google EUlA Dialog
+const test::UIPath kGoogleEulaDialog = {kConsolidatedConsentId,
+                                        "googleEulaDialog"};
+const test::UIPath kGoogleEulaWebview = {kConsolidatedConsentId,
+                                         "googleEulaWebview"};
+const test::UIPath kGoogleEulaOkButton = {kConsolidatedConsentId,
+                                          "googleEulaOkButton"};
+
+// CROS EULA Dialog
+const test::UIPath kCrosEulaDialog = {kConsolidatedConsentId, "crosEulaDialog"};
+const test::UIPath kCrosEulaWebview = {kConsolidatedConsentId,
+                                       "crosEulaWebview"};
+const test::UIPath kCrosEulaOkButton = {kConsolidatedConsentId,
+                                        "crosEulaOkButton"};
+
+// Regular user flow with ARC not enabled
+class ConsolidatedConsentScreenTest : public OobeBaseTest {
+ public:
+  ConsolidatedConsentScreenTest() {
+    feature_list_.InitAndEnableFeature(features::kOobeConsolidatedConsent);
+  }
+
+  void SetUpOnMainThread() override {
+    LoginDisplayHost::default_host()->GetWizardContext()->is_branded_build =
+        true;
+
+    // Override the screen exit callback with our own method.
+    ConsolidatedConsentScreen* screen =
+        WizardController::default_controller()
+            ->GetScreen<ConsolidatedConsentScreen>();
+
+    original_callback_ = screen->get_exit_callback_for_testing();
+    screen->set_exit_callback_for_testing(
+        base::BindRepeating(&ConsolidatedConsentScreenTest::HandleScreenExit,
+                            base::Unretained(this)));
+
+    OobeBaseTest::SetUpOnMainThread();
+  }
+
+  void LoginAsRegularUser() { login_manager_mixin_.LoginAsNewRegularUser(); }
+
+  void WaitForScreenExit() {
+    if (screen_exited_)
+      return;
+    base::RunLoop run_loop;
+    screen_exit_callback_ = run_loop.QuitClosure();
+    run_loop.Run();
+  }
+
+  absl::optional<ConsolidatedConsentScreen::Result> screen_result_;
+
+ protected:
+  void HandleScreenExit(ConsolidatedConsentScreen::Result result) {
+    ASSERT_FALSE(screen_exited_);
+    screen_exited_ = true;
+    screen_result_ = result;
+    original_callback_.Run(result);
+    if (screen_exit_callback_)
+      std::move(screen_exit_callback_).Run();
+  }
+
+  bool screen_exited_ = false;
+  base::RepeatingClosure screen_exit_callback_;
+  ConsolidatedConsentScreen::ScreenExitCallback original_callback_;
+
+  base::test::ScopedFeatureList feature_list_;
+  LoginManagerMixin login_manager_mixin_{&mixin_host_};
+  FakeEulaMixin fake_eula_{&mixin_host_, embedded_test_server()};
+};
+
+// For regular users with ARC disabled, only usage stats opt-in is visible
+// and the toggle is enabled.
+IN_PROC_BROWSER_TEST_F(ConsolidatedConsentScreenTest, OptinsVisiblity) {
+  LoginAsRegularUser();
+  OobeScreenWaiter(ConsolidatedConsentScreenView::kScreenId).Wait();
+  test::OobeJS().CreateVisibilityWaiter(true, kLoadedDialog)->Wait();
+
+  test::OobeJS().ExpectVisiblePath(kUsageStats);
+  test::OobeJS().ExpectEnabledPath(kUsageStatsToggle);
+  test::OobeJS().ExpectHiddenPath(kBackup);
+  test::OobeJS().ExpectHiddenPath(kLocation);
+  test::OobeJS().ExpectHiddenPath(kFooter);
+}
+
+IN_PROC_BROWSER_TEST_F(ConsolidatedConsentScreenTest, GoogleEula) {
+  LoginAsRegularUser();
+  OobeScreenWaiter(ConsolidatedConsentScreenView::kScreenId).Wait();
+  test::OobeJS().CreateVisibilityWaiter(true, kLoadedDialog)->Wait();
+  test::OobeJS().ClickOnPath(kGoogleEulaLinkArcDisabled);
+  test::OobeJS().CreateVisibilityWaiter(true, kGoogleEulaDialog)->Wait();
+  const std::string webview_contents =
+      test::GetWebViewContents(kGoogleEulaWebview);
+  EXPECT_TRUE(webview_contents.find(FakeEulaMixin::kFakeOnlineEula) !=
+              std::string::npos);
+  test::OobeJS().ClickOnPath(kGoogleEulaOkButton);
+  test::OobeJS().CreateVisibilityWaiter(true, kLoadedDialog)->Wait();
+}
+
+IN_PROC_BROWSER_TEST_F(ConsolidatedConsentScreenTest, CrosEula) {
+  LoginAsRegularUser();
+  OobeScreenWaiter(ConsolidatedConsentScreenView::kScreenId).Wait();
+  test::OobeJS().CreateVisibilityWaiter(true, kLoadedDialog)->Wait();
+
+  test::OobeJS().ClickOnPath(kCrosEulaLinkArcDisabled);
+  test::OobeJS().CreateVisibilityWaiter(true, kCrosEulaDialog)->Wait();
+
+  const std::string webview_contents =
+      test::GetWebViewContents(kCrosEulaWebview);
+  EXPECT_TRUE(webview_contents.find(FakeEulaMixin::kFakeOnlineEula) !=
+              std::string::npos);
+
+  test::OobeJS().ClickOnPath(kCrosEulaOkButton);
+  test::OobeJS().CreateVisibilityWaiter(true, kLoadedDialog)->Wait();
+}
+
+IN_PROC_BROWSER_TEST_F(ConsolidatedConsentScreenTest, Accept) {
+  LoginAsRegularUser();
+  OobeScreenWaiter(ConsolidatedConsentScreenView::kScreenId).Wait();
+  test::OobeJS().CreateVisibilityWaiter(true, kLoadedDialog)->Wait();
+
+  test::OobeJS().ClickOnPath(kCrosEulaOkButton);
+  test::OobeJS().CreateVisibilityWaiter(true, kAcceptButton)->Wait();
+
+  test::OobeJS().ClickOnPath(kAcceptButton);
+  WaitForScreenExit();
+  EXPECT_EQ(screen_result_.value(),
+            ConsolidatedConsentScreen::Result::ACCEPTED);
+}
+
+IN_PROC_BROWSER_TEST_F(ConsolidatedConsentScreenTest, LearnMore) {
+  LoginAsRegularUser();
+  OobeScreenWaiter(ConsolidatedConsentScreenView::kScreenId).Wait();
+  test::OobeJS().CreateVisibilityWaiter(true, kLoadedDialog)->Wait();
+
+  test::OobeJS().ClickOnPath(kUsageLearnMoreLink);
+  test::OobeJS().ExpectAttributeEQ("open", kUsageLearnMorePopUp, true);
+  test::OobeJS().ClickOnPath(kUsageLearnMorePopUpClose);
+  test::OobeJS().ExpectAttributeEQ("open", kUsageLearnMorePopUp, false);
+}
+
+}  // namespace
+}  // namespace ash
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc
index 36425549..b205cbd 100644
--- a/chrome/browser/chrome_browser_interface_binders.cc
+++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -40,6 +40,7 @@
 #include "chrome/browser/ui/webui/media/media_history_ui.h"
 #include "chrome/browser/ui/webui/omnibox/omnibox.mojom.h"
 #include "chrome/browser/ui/webui/omnibox/omnibox_ui.h"
+#include "chrome/browser/ui/webui/segmentation_internals/segmentation_internals_ui.h"
 #include "chrome/browser/ui/webui/usb_internals/usb_internals.mojom.h"
 #include "chrome/browser/ui/webui/usb_internals/usb_internals_ui.h"
 #include "chrome/common/chrome_features.h"
@@ -694,6 +695,10 @@
   RegisterWebUIControllerInterfaceBinder<federated_learning::mojom::PageHandler,
                                          FlocInternalsUI>(map);
 
+  RegisterWebUIControllerInterfaceBinder<
+      segmentation_internals::mojom::PageHandlerFactory,
+      SegmentationInternalsUI>(map);
+
 #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
     BUILDFLAG(IS_CHROMEOS_ASH)
   RegisterWebUIControllerInterfaceBinder<
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 5682a3e..c51f614 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -875,7 +875,6 @@
 
 int ChromeBrowserMainParts::PreCreateThreadsImpl() {
   TRACE_EVENT0("startup", "ChromeBrowserMainParts::PreCreateThreadsImpl");
-  run_message_loop_ = false;
 
   if (browser_process_->GetApplicationLocale().empty()) {
     ShowMissingLocaleMessageBox();
@@ -918,11 +917,6 @@
   }
 
 #if !defined(OS_ANDROID)
-  // Create the RunLoop for MainMessageLoopRun() to use, and pass a copy of
-  // its QuitClosure to the BrowserProcessImpl to call when it is time to exit.
-  DCHECK(!GetMainRunLoopInstance());
-  GetMainRunLoopInstance() = std::make_unique<base::RunLoop>();
-
   // These members must be initialized before returning from this function.
   // Android doesn't use StartupBrowserCreator.
   browser_creator_ = std::make_unique<StartupBrowserCreator>();
@@ -1730,42 +1724,42 @@
       parameters_.autorelease_pool->Recycle();
 #endif  // defined(OS_MAC)
 
-    // Transfer ownership of the browser's lifetime to the BrowserProcess.
+    // Create the RunLoop for MainMessageLoopRun() to use and transfer
+    // ownership of the browser's lifetime to the BrowserProcess.
+    DCHECK(!GetMainRunLoopInstance());
+    GetMainRunLoopInstance() = std::make_unique<base::RunLoop>();
     browser_process_->SetQuitClosure(
         GetMainRunLoopInstance()->QuitWhenIdleClosure());
-    DCHECK(!run_message_loop_);
-    run_message_loop_ = true;
   }
   browser_creator_.reset();
 #endif  // !defined(OS_ANDROID)
 
   PostBrowserStart();
 
-  // The ui_task can be injected by tests to replace the main message loop.
-  // In that case we Run() it here, and set a flag to avoid running the main
-  // message loop later, as the test will do so as needed from the |ui_task|.
-  if (parameters_.ui_task) {
-    std::move(parameters_.ui_task).Run();
-    run_message_loop_ = false;
-  }
-
 #if BUILDFLAG(ENABLE_DOWNGRADE_PROCESSING)
   // Clean up old user data directory, snapshots and disk cache directory.
   downgrade_manager_.DeleteMovedUserDataSoon(user_data_dir_);
 #endif
 
-#if defined(OS_ANDROID)
-  // We never run the C++ main loop on Android, since the UI thread message
-  // loop is controlled by the OS, so this is as close as we can get to
-  // the start of the main loop.
-  if (result_code_ <= 0) {
+  // This should be invoked as close as possible to the start of the browser's
+  // main loop, but before the end of PreMainMessageLoopRun in order for
+  // browser tests (which InterceptMainMessageLoopRun rather than
+  // MainMessageLoopRun) to be able to see its side-effect.
+  if (result_code_ <= 0)
     RecordBrowserStartupTime();
-  }
-#endif  // defined(OS_ANDROID)
 
   return result_code_;
 }
 
+#if !defined(OS_ANDROID)
+bool ChromeBrowserMainParts::ShouldInterceptMainMessageLoopRun() {
+  // Some early return paths in PreMainMessageLoopRunImpl intentionally prevent
+  // the main run loop from being created. Use this as a signal to indicate that
+  // the main message loop shouldn't be run.
+  return !!GetMainRunLoopInstance();
+}
+#endif
+
 void ChromeBrowserMainParts::WillRunMainMessageLoop(
     std::unique_ptr<base::RunLoop>& run_loop) {
 #if defined(OS_ANDROID)
@@ -1773,19 +1767,8 @@
   // Android specific MessageLoop
   NOTREACHED();
 #else
-  if (!run_message_loop_) {
-    run_loop.reset();
-    return;
-  }
-
-  // These should be invoked as close to the start of the browser's
-  // UI thread message loop as possible to get a stable measurement
-  // across versions.
-  RecordBrowserStartupTime();
-
   DCHECK(base::CurrentUIThread::IsSet());
 
-  DCHECK(GetMainRunLoopInstance());
   run_loop = std::move(GetMainRunLoopInstance());
 
   // Trace the entry and exit of this main message loop. We don't use the
diff --git a/chrome/browser/chrome_browser_main.h b/chrome/browser/chrome_browser_main.h
index dc81a05d..d28d8ae 100644
--- a/chrome/browser/chrome_browser_main.h
+++ b/chrome/browser/chrome_browser_main.h
@@ -75,6 +75,9 @@
   int PreCreateThreads() override;
   void PostCreateThreads() override;
   int PreMainMessageLoopRun() override;
+#if !defined(OS_ANDROID)
+  bool ShouldInterceptMainMessageLoopRun() override;
+#endif
   void WillRunMainMessageLoop(
       std::unique_ptr<base::RunLoop>& run_loop) override;
   void OnFirstIdle() override;
@@ -201,7 +204,6 @@
 #endif
 
   raw_ptr<Profile> profile_ = nullptr;
-  bool run_message_loop_ = true;
 
   base::FilePath user_data_dir_;
 
diff --git a/chrome/browser/chrome_browser_main_parts_lacros.cc b/chrome/browser/chrome_browser_main_parts_lacros.cc
index 8b5c6cb..67d0ef2 100644
--- a/chrome/browser/chrome_browser_main_parts_lacros.cc
+++ b/chrome/browser/chrome_browser_main_parts_lacros.cc
@@ -9,7 +9,7 @@
 #include "chrome/browser/lacros/metrics_reporting_observer.h"
 #include "chrome/browser/lacros/prefs_ash_observer.h"
 #include "chrome/common/chrome_switches.h"
-#include "chromeos/lacros/lacros_dbus_helper.h"
+#include "chromeos/lacros/dbus/lacros_dbus_helper.h"
 #include "chromeos/lacros/lacros_service.h"
 #include "content/public/browser/tts_platform.h"
 #include "content/public/common/result_codes.h"
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index cd38d40..0a40e34 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1642,8 +1642,6 @@
     "../ash/input_method/ime_rules_config.h",
     "../ash/input_method/ime_service_connector.cc",
     "../ash/input_method/ime_service_connector.h",
-    "../ash/input_method/input_host_helper.cc",
-    "../ash/input_method/input_host_helper.h",
     "../ash/input_method/input_method_configuration.cc",
     "../ash/input_method/input_method_configuration.h",
     "../ash/input_method/input_method_delegate_impl.cc",
@@ -1674,6 +1672,8 @@
     "../ash/input_method/suggestions_service_client.cc",
     "../ash/input_method/suggestions_service_client.h",
     "../ash/input_method/suggestions_source.h",
+    "../ash/input_method/text_field_contextual_info_fetcher.cc",
+    "../ash/input_method/text_field_contextual_info_fetcher.h",
     "../ash/input_method/text_utils.cc",
     "../ash/input_method/text_utils.h",
     "../ash/input_method/ui/assistive_accessibility_view.cc",
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h
index a8b59bb..c9d4260 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h
@@ -140,7 +140,7 @@
 
   // Returns a list of files inodes disallowed to be transferred to
   // |destination|.
-  virtual std::vector<uint64_t> GetDisallowedTransfers(
+  virtual std::vector<uint64_t> GetDisallowedFileTransfers(
       const std::vector<FileMetadata>& transferred_files,
       const GURL& destination) const = 0;
 };
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
index f008ae6..fc11ddd3 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
@@ -401,7 +401,7 @@
       policy_prefs::kDlpClipboardCheckSizeLimit);
 }
 
-std::vector<uint64_t> DlpRulesManagerImpl::GetDisallowedTransfers(
+std::vector<uint64_t> DlpRulesManagerImpl::GetDisallowedFileTransfers(
     const std::vector<FileMetadata>& transferred_files,
     const GURL& destination) const {
   // TODO(crbug.com/1273793): Change to handle VMs, external drive, ...etc.
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h
index ee7e648..ee641dc 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h
@@ -53,7 +53,7 @@
                                   Restriction restriction,
                                   Level level) const override;
   size_t GetClipboardCheckSizeLimitInBytes() const override;
-  std::vector<uint64_t> GetDisallowedTransfers(
+  std::vector<uint64_t> GetDisallowedFileTransfers(
       const std::vector<FileMetadata>& transferred_files,
       const GURL& destination) const override;
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
index 50fadcdc..9cced26 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
@@ -848,7 +848,7 @@
                 DlpRulesManager::Restriction::kScreenShare));
 }
 
-TEST_F(DlpRulesManagerImplTest, GetDisallowedTransfers) {
+TEST_F(DlpRulesManagerImplTest, GetDisallowedFileTransfers) {
   base::Value rules(base::Value::Type::LIST);
 
   base::Value src_urls_1(base::Value::Type::LIST);
@@ -881,7 +881,7 @@
 
   std::vector<uint64_t> expected_output = {inode_1, inode_2};
 
-  EXPECT_EQ(expected_output, dlp_rules_manager_.GetDisallowedTransfers(
+  EXPECT_EQ(expected_output, dlp_rules_manager_.GetDisallowedFileTransfers(
                                  transferred_files, GURL(kExampleUrl)));
 }
 
diff --git a/chrome/browser/chromeos/policy/dlp/mock_dlp_rules_manager.h b/chrome/browser/chromeos/policy/dlp/mock_dlp_rules_manager.h
index a51599d7..1f23357 100644
--- a/chrome/browser/chromeos/policy/dlp/mock_dlp_rules_manager.h
+++ b/chrome/browser/chromeos/policy/dlp/mock_dlp_rules_manager.h
@@ -49,7 +49,7 @@
   MOCK_CONST_METHOD0(GetClipboardCheckSizeLimitInBytes, size_t());
 
   MOCK_CONST_METHOD2(
-      GetDisallowedTransfers,
+      GetDisallowedFileTransfers,
       std::vector<uint64_t>(const std::vector<FileMetadata>& files_entries,
                             const GURL& destination));
 };
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc
index eeb76dd..2af1824 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc
@@ -654,8 +654,7 @@
     ProtocolHandler handler = ProtocolHandler::CreateProtocolHandler(*p);
     if (!RegisterProtocolHandler(handler, source))
       continue;
-    bool is_default = false;
-    if ((*p)->GetBoolean("default", &is_default) && is_default) {
+    if ((*p)->FindBoolKey("default").value_or(false)) {
       SetDefault(handler);
     }
   }
diff --git a/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc b/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc
index 5d91d3b..771400e 100644
--- a/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc
+++ b/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -13,6 +13,7 @@
 #include "base/test/values_test_util.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/values.h"
+#include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/devtools/protocol/devtools_protocol_test_support.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_util.h"
@@ -191,6 +192,21 @@
                     Not(Contains("keydown"))));
 }
 
+IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest,
+                       NoInputEventsSentToBrowserWhenDisallowed) {
+  may_send_input_event_to_browser_ = false;
+  Attach();
+
+  base::DictionaryValue params;
+  params.SetStringKey("type", "rawKeyDown");
+  params.SetStringKey("key", "F12");
+  params.SetIntKey("windowsVirtualKeyCode", 123);
+  params.SetIntKey("nativeVirtualKeyCode", 123);
+  SendCommandSync("Input.dispatchKeyEvent", std::move(params));
+
+  EXPECT_EQ(nullptr, DevToolsWindow::FindDevToolsWindow(agent_host_.get()));
+}
+
 class DevToolsProtocolTest_AppId : public DevToolsProtocolTest {
  public:
   DevToolsProtocolTest_AppId() {
diff --git a/chrome/browser/devtools/protocol/devtools_protocol_test_support.cc b/chrome/browser/devtools/protocol/devtools_protocol_test_support.cc
index 5f536a1..2c9b449 100644
--- a/chrome/browser/devtools/protocol/devtools_protocol_test_support.cc
+++ b/chrome/browser/devtools/protocol/devtools_protocol_test_support.cc
@@ -146,3 +146,7 @@
 bool DevToolsProtocolTestBase::AllowUnsafeOperations() {
   return allow_unsafe_operations_;
 }
+
+bool DevToolsProtocolTestBase::MaySendInputEventsToBrowser() {
+  return may_send_input_event_to_browser_;
+}
diff --git a/chrome/browser/devtools/protocol/devtools_protocol_test_support.h b/chrome/browser/devtools/protocol/devtools_protocol_test_support.h
index 4eef724..3cfba04 100644
--- a/chrome/browser/devtools/protocol/devtools_protocol_test_support.h
+++ b/chrome/browser/devtools/protocol/devtools_protocol_test_support.h
@@ -67,6 +67,7 @@
   // DevToolsAgentHostClient interface
   void AgentHostClosed(content::DevToolsAgentHost* agent_host) override;
   bool AllowUnsafeOperations() override;
+  bool MaySendInputEventsToBrowser() override;
 
   scoped_refptr<content::DevToolsAgentHost> agent_host_;
   int last_sent_id_ = 0;
@@ -80,6 +81,7 @@
   NotificationMatcher waiting_for_notification_matcher_;
   base::Value waiting_for_notification_params_;
   bool allow_unsafe_operations_ = true;
+  bool may_send_input_event_to_browser_ = true;
 };
 
 #endif  // CHROME_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_TEST_SUPPORT_H_
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc b/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc
index fef26944..42754c5 100644
--- a/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc
+++ b/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc
@@ -13,9 +13,9 @@
 #include "base/feature_list.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/ash/input_method/assistive_window_properties.h"
-#include "chrome/browser/ash/input_method/input_host_helper.h"
 #include "chrome/browser/ash/input_method/input_method_engine.h"
 #include "chrome/browser/ash/input_method/native_input_method_engine.h"
+#include "chrome/browser/ash/input_method/text_field_contextual_info_fetcher.h"
 #include "chrome/browser/ash/login/lock/screen_locker.h"
 #include "chrome/browser/ash/login/session/user_session_manager.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
@@ -282,9 +282,9 @@
 
       // Populate app key for private OnFocus.
       // TODO(b/163645900): Add app type later.
-      ash::input_method::InputAssociatedHost host;
-      ash::input_method::PopulateInputHost(&host);
-      input_context.app_key = std::make_unique<std::string>(host.app_key);
+      ash::input_method::TextFieldContextualInfo info;
+      ash::input_method::GetTextFieldAppTypeAndKey(info);
+      input_context.app_key = std::make_unique<std::string>(info.app_key);
 
       auto args(input_method_private::OnFocus::Create(input_context));
 
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index cb0577f..3af18ca9 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -464,7 +464,6 @@
 void ExtensionService::Init() {
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   TRACE_EVENT0("browser,startup", "ExtensionService::Init");
-  SCOPED_UMA_HISTOGRAM_TIMER("Extensions.ExtensionServiceInitTime");
 
   DCHECK(!system_->is_ready());  // Can't redo init.
   DCHECK_EQ(registry_->enabled_extensions().size(), 0u);
@@ -1394,9 +1393,6 @@
 void ExtensionService::SetReadyAndNotifyListeners() {
   TRACE_EVENT0("browser,startup",
                "ExtensionService::SetReadyAndNotifyListeners");
-  SCOPED_UMA_HISTOGRAM_TIMER(
-      "Extensions.ExtensionServiceNotifyReadyListenersTime");
-
   ready_->Signal();
 }
 
diff --git a/chrome/browser/extensions/extension_uninstall_dialog.cc b/chrome/browser/extensions/extension_uninstall_dialog.cc
index e702051..c91d7171 100644
--- a/chrome/browser/extensions/extension_uninstall_dialog.cc
+++ b/chrome/browser/extensions/extension_uninstall_dialog.cc
@@ -224,12 +224,7 @@
   // closed.
   registry_observation_.Reset();
 
-  // We don't want to artificially weight any of the options, so only record if
-  // a checkbox was shown.
-  if (show_report_abuse_checkbox_) {
-    UMA_HISTOGRAM_ENUMERATION("Extensions.UninstallDialogAction", action,
-                              CLOSE_ACTION_LAST);
-  } else if (show_remove_data_checkbox_) {
+  if (show_remove_data_checkbox_) {
     // TODO(crbug.com/1065748): Delete Webapp recording in extensions dialog.
     UMA_HISTOGRAM_ENUMERATION("Webapp.UninstallDialogAction", action,
                               CLOSE_ACTION_LAST);
diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc
index bc8ef85..0192928 100644
--- a/chrome/browser/extensions/tab_helper.cc
+++ b/chrome/browser/extensions/tab_helper.cc
@@ -432,9 +432,11 @@
   // We should wait for RenderFrameCreated() to happen, to avoid sending this
   // message twice.
   if (render_frame_host->IsRenderFrameCreated()) {
+    SessionID id = sessions::SessionTabHelper::IdForTab(web_contents());
+    CHECK(id.is_valid());
     ExtensionWebContentsObserver::GetForWebContents(web_contents())
         ->GetLocalFrame(render_frame_host)
-        ->SetTabId(sessions::SessionTabHelper::IdForTab(web_contents()).id());
+        ->SetTabId(id.id());
   }
 }
 
diff --git a/chrome/browser/first_run/first_run_internal_posix_browsertest.cc b/chrome/browser/first_run/first_run_internal_posix_browsertest.cc
index 04bb2535..224b881 100644
--- a/chrome/browser/first_run/first_run_internal_posix_browsertest.cc
+++ b/chrome/browser/first_run/first_run_internal_posix_browsertest.cc
@@ -105,8 +105,8 @@
 // run dialog. Ensure browser startup safely handles a signal while the modal
 // RunLoop is running.
 IN_PROC_BROWSER_TEST_F(FirstRunInternalPosixTest, HandleSigint) {
-  // Never reached. PreMainMessageLoopRunImpl() should return before this task
-  // is run.
+  // Never reached. The above SIGINT should prevent the main message loop
+  // (and the browser test hooking it) from running.
   ADD_FAILURE() << "Should never be called";
 }
 
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index deeecbf..2cccd4a 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -2004,9 +2004,9 @@
     "expiry_milestone": 100
   },
   {
-    "name": "enable-fre-ui-module-ios",
-    "owners": [ "tinazwang", "gambard" ],
-    "expiry_milestone": 99
+    "name": "enable-fre-ui-module-ios-with-options",
+    "owners": [ "gambard", "veronguyen", "vincb" ],
+    "expiry_milestone": 100
   },
   {
     "name": "enable-future-v8-vm-features",
diff --git a/chrome/browser/media/webrtc/region_capture_browsertest.cc b/chrome/browser/media/webrtc/region_capture_browsertest.cc
new file mode 100644
index 0000000..b0ab161f
--- /dev/null
+++ b/chrome/browser/media/webrtc/region_capture_browsertest.cc
@@ -0,0 +1,379 @@
+// 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 <memory>
+#include <string>
+#include <vector>
+
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/guid.h"
+#include "base/path_service.h"
+#include "base/strings/strcat.h"
+#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
+#include "build/buildflag.h"
+#include "build/chromeos_buildflags.h"
+#include "chrome/browser/media/webrtc/webrtc_browsertest_base.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_tabstrip.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/permissions/permission_request_manager.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_base.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/prerender_test_util.h"
+#include "testing/gmock/include/gmock/gmock-matchers.h"
+
+// TODO(crbug.com/1215089): Enable this test suite on Lacros.
+#if !BUILDFLAG(IS_CHROMEOS_LACROS)
+
+namespace {
+
+using content::WebContents;
+
+// TODO(crbug.com/1247761): Add tests that verify excessive calls to
+// produceCropId() yield the empty string.
+MATCHER(IsEmptyCropId, "") {
+  static_assert(std::is_same<decltype(arg), const std::string&>::value, "");
+  return arg == "empty-crop-id";  // See region_capture_main.html for rationale.
+}
+
+MATCHER(IsValidCropId, "") {
+  static_assert(std::is_same<decltype(arg), const std::string&>::value, "");
+  return base::GUID::ParseLowercase(arg).is_valid();
+}
+
+const char kMainPageTitle[] = "Region Capture Test - Page 1 (Main)";
+const char kOtherPageTitle[] = "Region Capture Test - Page 2 (Main)";
+
+enum {
+  kMainPageTopLevelDocument,
+  kMainPageEmbeddedDocument,
+  kOtherPageTopLevelDocument,
+  kOtherPageEmbeddedDocument,
+  kServerCount  // Must be last.
+};
+
+enum {
+  kMainTab,
+  kOtherTab,
+  kTabCount  // Must be last.
+};
+
+enum class Frame {
+  kTopLevelDocument,
+  kEmbeddedFrame,
+};
+
+// Conveniently pack together all relevant information about a tab and
+// conveniently expose test controls on it.
+struct TabInfo {
+  void StartEmbeddingFrame(const GURL& url) {
+    std::string script_result;
+    EXPECT_TRUE(content::ExecuteScriptAndExtractString(
+        web_contents->GetMainFrame(),
+        base::StringPrintf("startEmbeddingFrame('%s');", url.spec().c_str()),
+        &script_result));
+    EXPECT_EQ(script_result, "embedding-done");
+  }
+
+  void StartCapture() {
+    // Bring the tab into focus. This avoids getDisplayMedia rejection.
+    browser->tab_strip_model()->ActivateTabAt(tab_strip_index);
+
+    std::string script_result;
+    EXPECT_TRUE(content::ExecuteScriptAndExtractString(
+        web_contents->GetMainFrame(), "startCapture();", &script_result));
+    EXPECT_EQ(script_result, "capture-success");
+  }
+
+  void StartCaptureFromEmbeddedFrame() {
+    std::string script_result;
+    EXPECT_TRUE(content::ExecuteScriptAndExtractString(
+        web_contents->GetMainFrame(), "startCaptureFromEmbeddedFrame();",
+        &script_result));
+    EXPECT_EQ(script_result, "embedded-capture-success");
+  }
+
+  std::string ProduceCropId(Frame frame) {
+    const char* const frame_js =
+        (frame == Frame::kTopLevelDocument) ? "top" : "embedded";
+    std::string script_result = "error-not-modified";
+    EXPECT_TRUE(content::ExecuteScriptAndExtractString(
+        web_contents->GetMainFrame(),
+        base::StrCat({"produceCropId(\"", frame_js, "\");"}), &script_result));
+    return script_result;
+  }
+
+  std::string CropTo(const std::string& crop_id) {
+    std::string script_result = "error-not-modified";
+    EXPECT_TRUE(content::ExecuteScriptAndExtractString(
+        web_contents->GetMainFrame(),
+        base::StrCat({"cropTo(\"", crop_id, "\");"}), &script_result));
+    return script_result;
+  }
+
+  Browser* browser;
+  WebContents* web_contents;
+  int tab_strip_index;
+};
+
+}  // namespace
+
+// Essentially depends on InProcessBrowserTest, but WebRtcTestBase provides
+// detection of JS errors.
+class RegionCaptureBrowserTest : public WebRtcTestBase {
+ public:
+  void SetUpInProcessBrowserTestFixture() override {
+    WebRtcTestBase::SetUpInProcessBrowserTestFixture();
+
+    DetectErrorsInJavaScript();
+
+    base::FilePath test_dir;
+    ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
+
+    for (int i = 0; i < kServerCount; ++i) {
+      servers_.emplace_back(std::make_unique<net::EmbeddedTestServer>());
+      servers_[i]->ServeFilesFromDirectory(test_dir);
+      ASSERT_TRUE(servers_[i]->Start());
+    }
+  }
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    command_line->AppendSwitch(
+        switches::kEnableExperimentalWebPlatformFeatures);
+    command_line_ = command_line;
+  }
+
+  void TearDownOnMainThread() override {
+    for (auto& server : servers_) {
+      if (server) {
+        ASSERT_TRUE(server->ShutdownAndWaitUntilComplete());
+      }
+    }
+
+    WebRtcTestBase::TearDownOnMainThread();
+  }
+
+  // Same as WebRtcTestBase::OpenTestPageInNewTab, but does not assume
+  // a single embedded server is used for all pages, and also embeds
+  // a cross-origin iframe.
+  void SetUpPage(const std::string& top_level_document_document,
+                 net::EmbeddedTestServer* top_level_document_server,
+                 const std::string& embedded_iframe_document,
+                 net::EmbeddedTestServer* embedded_iframe_server,
+                 TabInfo* tab_info) const {
+    chrome::AddTabAt(browser(), GURL(url::kAboutBlankURL), -1, true);
+    EXPECT_TRUE(ui_test_utils::NavigateToURL(
+        browser(),
+        top_level_document_server->GetURL(top_level_document_document)));
+
+    WebContents* const web_contents =
+        browser()->tab_strip_model()->GetActiveWebContents();
+    // web_contents_vector_.push_back(web_contents);
+    permissions::PermissionRequestManager::FromWebContents(web_contents)
+        ->set_auto_response_for_test(
+            permissions::PermissionRequestManager::ACCEPT_ALL);
+
+    *tab_info = {browser(), web_contents,
+                 browser()->tab_strip_model()->active_index()};
+    tab_info->StartEmbeddingFrame(
+        embedded_iframe_server->GetURL(embedded_iframe_document));
+  }
+
+  // Set up all (necessary) tabs, loads iframes, and start capturing the
+  // relevant tab.
+  void SetUpTest(Frame capturing_entity, bool self_capture) {
+    // Main page (for self-capture).
+    SetUpPage("/webrtc/region_capture_main.html",
+              servers_[kMainPageTopLevelDocument].get(),
+              "/webrtc/region_capture_embedded.html",
+              servers_[kMainPageEmbeddedDocument].get(), &tabs_[kMainTab]);
+
+    if (!self_capture) {
+      // Other page (for other-tab-capture).
+      SetUpPage("/webrtc/region_capture_other_main.html",
+                servers_[kOtherPageTopLevelDocument].get(),
+                "/webrtc/region_capture_other_embedded.html",
+                servers_[kOtherPageEmbeddedDocument].get(), &tabs_[kOtherTab]);
+    }
+
+    DCHECK(command_line_);
+    command_line_->AppendSwitchASCII(
+        switches::kAutoSelectTabCaptureSourceByTitle,
+        self_capture ? kMainPageTitle : kOtherPageTitle);
+
+    if (capturing_entity == Frame::kTopLevelDocument) {
+      tabs_[kMainTab].StartCapture();
+    } else {
+      DCHECK_EQ(capturing_entity, Frame::kEmbeddedFrame);
+      tabs_[kMainTab].StartCaptureFromEmbeddedFrame();
+    }
+  }
+
+  // Manipulation after SetUpCommandLine, but before capture starts,
+  // allows tests to set which tab to capture.
+  base::CommandLine* command_line_ = nullptr;
+
+  // Holds the tabs manipulated by this test.
+  TabInfo tabs_[kTabCount];
+
+  // Each page is served from a distinct origin, thereby proving that cropping
+  // works irrespective of whether iframes are in/out-of-process.
+  std::vector<std::unique_ptr<net::EmbeddedTestServer>> servers_;
+};
+
+IN_PROC_BROWSER_TEST_F(RegionCaptureBrowserTest,
+                       ProduceCropIdReturnsValidIdInMainPage) {
+  SetUpTest(Frame::kTopLevelDocument, /*self_capture=*/true);
+  EXPECT_THAT(tabs_[kMainTab].ProduceCropId(Frame::kTopLevelDocument),
+              IsValidCropId());
+}
+
+IN_PROC_BROWSER_TEST_F(RegionCaptureBrowserTest,
+                       ProduceCropIdReturnsValidIdInCrossOriginIframe) {
+  SetUpTest(Frame::kTopLevelDocument, /*self_capture=*/true);
+  EXPECT_THAT(tabs_[kMainTab].ProduceCropId(Frame::kEmbeddedFrame),
+              IsValidCropId());
+}
+
+IN_PROC_BROWSER_TEST_F(RegionCaptureBrowserTest,
+                       ProduceCropIdReturnsSameIdIfSameElement) {
+  SetUpTest(Frame::kTopLevelDocument, /*self_capture=*/true);
+  EXPECT_EQ(tabs_[kMainTab].ProduceCropId(Frame::kTopLevelDocument),
+            tabs_[kMainTab].ProduceCropId(Frame::kTopLevelDocument));
+}
+
+IN_PROC_BROWSER_TEST_F(RegionCaptureBrowserTest,
+                       CropToAllowedIfTopLevelCropsToElementInTopLevel) {
+  SetUpTest(Frame::kTopLevelDocument, /*self_capture=*/true);
+  TabInfo& tab = tabs_[kMainTab];
+
+  const std::string crop_id = tab.ProduceCropId(Frame::kTopLevelDocument);
+  ASSERT_THAT(crop_id, IsValidCropId());
+  EXPECT_EQ(tab.CropTo(crop_id), "top-level-crop-success");
+}
+
+IN_PROC_BROWSER_TEST_F(RegionCaptureBrowserTest,
+                       CropToAllowedIfTopLevelCropsToElementInEmbedded) {
+  SetUpTest(Frame::kTopLevelDocument, /*self_capture=*/true);
+  TabInfo& tab = tabs_[kMainTab];
+
+  const std::string crop_id = tab.ProduceCropId(Frame::kEmbeddedFrame);
+  ASSERT_THAT(crop_id, IsValidCropId());
+  EXPECT_EQ(tab.CropTo(crop_id), "top-level-crop-success");
+}
+
+IN_PROC_BROWSER_TEST_F(RegionCaptureBrowserTest,
+                       CropToAllowedIfEmbeddedFrameCropsToElementInTopLevel) {
+  SetUpTest(Frame::kEmbeddedFrame, /*self_capture=*/true);
+  TabInfo& tab = tabs_[kMainTab];
+
+  const std::string crop_id = tab.ProduceCropId(Frame::kTopLevelDocument);
+  ASSERT_THAT(crop_id, IsValidCropId());
+  EXPECT_EQ(tab.CropTo(crop_id), "embedded-crop-success");
+}
+
+IN_PROC_BROWSER_TEST_F(RegionCaptureBrowserTest,
+                       CropToAllowedIfEmbeddedFrameCropsToElementInEmbedded) {
+  SetUpTest(Frame::kEmbeddedFrame, /*self_capture=*/true);
+  TabInfo& tab = tabs_[kMainTab];
+
+  const std::string crop_id = tab.ProduceCropId(Frame::kEmbeddedFrame);
+  ASSERT_THAT(crop_id, IsValidCropId());
+  EXPECT_EQ(tab.CropTo(crop_id), "embedded-crop-success");
+}
+
+IN_PROC_BROWSER_TEST_F(RegionCaptureBrowserTest, CropToAllowedToUncrop) {
+  SetUpTest(Frame::kTopLevelDocument, /*self_capture=*/true);
+  TabInfo& tab = tabs_[kMainTab];
+
+  const std::string crop_id = tab.ProduceCropId(Frame::kTopLevelDocument);
+  ASSERT_THAT(crop_id, IsValidCropId());
+  ASSERT_EQ(tab.CropTo(crop_id), "top-level-crop-success");
+
+  EXPECT_EQ(tab.CropTo(""), "top-level-crop-success");
+}
+
+IN_PROC_BROWSER_TEST_F(RegionCaptureBrowserTest, CropToRejectedIfUnknown) {
+  SetUpTest(Frame::kTopLevelDocument, /*self_capture=*/true);
+  TabInfo& tab = tabs_[kMainTab];
+
+  const std::string crop_id = tab.ProduceCropId(Frame::kTopLevelDocument);
+  ASSERT_THAT(crop_id, IsValidCropId());
+
+  DCHECK(!crop_id.empty());  // Test sanity.
+  const std::string::value_type wrong_char = (crop_id[0] == 'a' ? 'b' : 'a');
+  const std::string wrong_crop_id = wrong_char + crop_id.substr(1);
+  EXPECT_EQ(tab.CropTo(wrong_crop_id), "top-level-crop-error");
+}
+
+IN_PROC_BROWSER_TEST_F(RegionCaptureBrowserTest, CropToRejectedIfInvalid) {
+  SetUpTest(Frame::kTopLevelDocument, /*self_capture=*/true);
+  TabInfo& tab = tabs_[kMainTab];
+
+  const std::string crop_id = tab.ProduceCropId(Frame::kTopLevelDocument);
+  ASSERT_THAT(crop_id, IsValidCropId());
+
+  EXPECT_EQ(tab.CropTo("invalid-crop-id"), "top-level-crop-error");
+}
+
+IN_PROC_BROWSER_TEST_F(RegionCaptureBrowserTest,
+                       CropToRejectedIfProduceCropIdWasNeverCalled) {
+  SetUpTest(Frame::kTopLevelDocument, /*self_capture=*/true);
+  TabInfo& tab = tabs_[kMainTab];
+
+  const std::string crop_id = tab.ProduceCropId(Frame::kTopLevelDocument);
+  ASSERT_THAT(crop_id, IsValidCropId());
+
+  const std::string kValidCropId = "01234567-0123-0123-0123-0123456789ab";
+  ASSERT_THAT(kValidCropId, IsValidCropId());  // Test is sane.
+
+  EXPECT_EQ(tab.CropTo(kValidCropId), "top-level-crop-error");
+}
+
+IN_PROC_BROWSER_TEST_F(
+    RegionCaptureBrowserTest,
+    CropToForUncroppingRejectedIfProduceCropIdWasCalledButTrackUncropped) {
+  SetUpTest(Frame::kTopLevelDocument, /*self_capture=*/true);
+  TabInfo& tab = tabs_[kMainTab];
+
+  const std::string crop_id = tab.ProduceCropId(Frame::kTopLevelDocument);
+  ASSERT_THAT(crop_id, IsValidCropId());
+  // CropTo(crop_id) with a non-empty |crop_id| is intentionally not called.
+  // Instead, the test immediately calls CropTo("") on a still-uncropped track,
+  // attempting to stop cropping when no cropping was ever specified.
+  EXPECT_EQ(tab.CropTo(""), "top-level-crop-success");
+}
+
+IN_PROC_BROWSER_TEST_F(RegionCaptureBrowserTest,
+                       CropToRejectedIfElementInAnotherTabTopLevel) {
+  SetUpTest(Frame::kTopLevelDocument, /*self_capture=*/false);
+
+  const std::string crop_id =
+      tabs_[kOtherTab].ProduceCropId(Frame::kTopLevelDocument);
+  ASSERT_THAT(crop_id, IsValidCropId());
+
+  EXPECT_EQ(tabs_[kMainTab].CropTo(crop_id), "top-level-crop-error");
+}
+
+IN_PROC_BROWSER_TEST_F(RegionCaptureBrowserTest,
+                       CropToRejectedIfElementInAnotherTabEmbeddedFrame) {
+  SetUpTest(Frame::kTopLevelDocument, /*self_capture=*/false);
+
+  const std::string crop_id =
+      tabs_[kOtherTab].ProduceCropId(Frame::kEmbeddedFrame);
+  ASSERT_THAT(crop_id, IsValidCropId());
+
+  EXPECT_EQ(tabs_[kMainTab].CropTo(crop_id), "top-level-crop-error");
+}
+
+#endif  //  !BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/metrics/startup_metrics_browsertest.cc b/chrome/browser/metrics/startup_metrics_browsertest.cc
index 847aa3a..1aa65ea 100644
--- a/chrome/browser/metrics/startup_metrics_browsertest.cc
+++ b/chrome/browser/metrics/startup_metrics_browsertest.cc
@@ -39,10 +39,6 @@
 
 // Verify that startup histograms are logged on browser startup.
 IN_PROC_BROWSER_TEST_F(StartupMetricsTest, ReportsValues) {
-  // This is usually done from ChromeBrowserMainParts::MainMessageLoopRun().
-  startup_metric_utils::RecordBrowserMainMessageLoopStart(
-      base::TimeTicks::Now(), false /* is_first_run */);
-
   // Wait for all histograms to be recorded. The test will hit a RunLoop timeout
   // if a histogram is not recorded.
   for (auto* const histogram : kStartupMetrics) {
diff --git a/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc b/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc
index 961afb0..0dde01f 100644
--- a/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc
+++ b/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h"
 #include "chrome/browser/optimization_guide/prediction/prediction_manager.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
 #include "components/leveldb_proto/public/proto_database_provider.h"
 #include "components/optimization_guide/core/command_line_top_host_provider.h"
 #include "components/optimization_guide/core/hints_processing_util.h"
@@ -110,7 +111,21 @@
                                 ->GetDefaultStoragePartition()
                                 ->GetProtoDatabaseProvider();
   base::FilePath profile_path = profile->GetOriginalProfile()->GetPath();
-
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
+  // Do not use the primary profile on ChromeOS since it basically is an
+  // ephemeral profile anyway and we cannot provide hints or models to it
+  // anyway. Additionally, sign in profiles do not go through the standard
+  // profile initialization flow, so a lot of things that are required are not
+  // available when the browser context for the signin profile is created.
+  if (profile->IsGuestSession()) {
+    Profile* primary_profile = ProfileManager::GetPrimaryUserProfile();
+    if (primary_profile) {
+      proto_db_provider = primary_profile->GetDefaultStoragePartition()
+                              ->GetProtoDatabaseProvider();
+      profile_path = primary_profile->GetPath();
+    }
+  }
+#endif
   // We have different behavior if |this| is created for an incognito profile.
   // For incognito profiles, we act in "read-only" mode of the original
   // profile's store and do not fetch any new hints or models.
diff --git a/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc b/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc
index 50e37cf..419861e 100644
--- a/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc
+++ b/chrome/browser/optimization_guide/prediction/prediction_manager_browsertest.cc
@@ -814,4 +814,61 @@
   CreateBrowser(profile);
 }
 
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+// CreateGuestBrowser() is not supported for Android or ChromeOS out of the box.
+IN_PROC_BROWSER_TEST_F(PredictionManagerModelDownloadingBrowserTest,
+                       GuestProfileReceivesModel) {
+  SetResponseType(
+      PredictionModelsFetcherRemoteResponseType::kSuccessfulWithValidModelFile);
+
+  {
+    base::HistogramTester histogram_tester;
+    // Register in the primary profile and ensure the model returns.
+    RegisterModelFileObserverWithKeyedService(browser()->profile());
+
+    std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>();
+    model_file_observer()->set_model_file_received_callback(base::BindOnce(
+        [](base::RunLoop* run_loop,
+           proto::OptimizationTarget optimization_target,
+           const ModelInfo& model_info) {
+          EXPECT_EQ(optimization_target,
+                    proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD);
+          run_loop->Quit();
+        },
+        run_loop.get()));
+    run_loop->Run();
+    histogram_tester.ExpectUniqueSample(
+        "OptimizationGuide.PredictionModelDownloadManager.DownloadStatus",
+        PredictionModelDownloadStatus::kSuccess, 1);
+  }
+
+  {
+    base::HistogramTester histogram_tester;
+    // Now hook everything up in the guest profile and we should still get the
+    // model back. We should have seen only 1 model fetch/download occur.
+    Browser* guest_browser = CreateGuestBrowser();
+    std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>();
+    ModelFileObserver model_file_observer;
+    model_file_observer.set_model_file_received_callback(base::BindOnce(
+        [](base::RunLoop* run_loop,
+           proto::OptimizationTarget optimization_target,
+           const ModelInfo& model_info) {
+          EXPECT_EQ(optimization_target,
+                    proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD);
+          run_loop->Quit();
+        },
+        run_loop.get()));
+    OptimizationGuideKeyedServiceFactory::GetForProfile(
+        guest_browser->profile())
+        ->AddObserverForOptimizationTargetModel(
+            proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD,
+            /*model_metadata=*/absl::nullopt, &model_file_observer);
+
+    run_loop->Run();
+    histogram_tester.ExpectTotalCount(
+        "OptimizationGuide.PredictionModelDownloadManager.DownloadStatus", 0);
+  }
+}
+#endif
+
 }  // namespace optimization_guide
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordStoreAndroidBackend.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordStoreAndroidBackend.java
index de0d5ec..3ce30b3 100644
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordStoreAndroidBackend.java
+++ b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordStoreAndroidBackend.java
@@ -37,10 +37,8 @@
      * @param loginsReply Callback that is called on success with serialized {@link
      *         org.chromium.components.sync.protocol.ListPasswordsResult} data.
      * @param failureCallback A callback that is called on failure for any reason. May return sync.
-     * TODO(crbug.com/1229655): Remove default keyword after downstream implementation.
      */
-    default void getAutofillableLogins(
-            Callback<byte[]> loginsReply, Callback<Exception> failureCallback){};
+    void getAutofillableLogins(Callback<byte[]> loginsReply, Callback<Exception> failureCallback);
 
     /**
      * Triggers an async list call to retrieve logins with matching signon realm.
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordStoreAndroidBackendBridgeImpl.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordStoreAndroidBackendBridgeImpl.java
index 2d7c7d3..29487ffd 100644
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordStoreAndroidBackendBridgeImpl.java
+++ b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordStoreAndroidBackendBridgeImpl.java
@@ -58,6 +58,15 @@
     }
 
     @CalledByNative
+    void getAutofillableLogins(@JobId int jobId) {
+        mBackend.getAutofillableLogins(passwords -> {
+            if (mNativeBackendBridge == 0) return;
+            PasswordStoreAndroidBackendBridgeImplJni.get().onCompleteWithLogins(
+                    mNativeBackendBridge, jobId, passwords);
+        }, exception -> handleAndroidBackendException(jobId, exception));
+    }
+
+    @CalledByNative
     void addLogin(@JobId int jobId, byte[] pwdWithLocalData) {
         mBackend.addLogin(pwdWithLocalData, () -> {
             if (mNativeBackendBridge == 0) return;
diff --git a/chrome/browser/password_manager/android/junit/src/org/chromium/chrome/browser/password_manager/PasswordStoreAndroidBackendBridgeTest.java b/chrome/browser/password_manager/android/junit/src/org/chromium/chrome/browser/password_manager/PasswordStoreAndroidBackendBridgeTest.java
index 721b6b3a..e1aa6148 100644
--- a/chrome/browser/password_manager/android/junit/src/org/chromium/chrome/browser/password_manager/PasswordStoreAndroidBackendBridgeTest.java
+++ b/chrome/browser/password_manager/android/junit/src/org/chromium/chrome/browser/password_manager/PasswordStoreAndroidBackendBridgeTest.java
@@ -140,6 +140,40 @@
     }
 
     @Test
+    public void testGetAutofillableLoginsCallsBridgeOnSuccess() {
+        final int kTestTaskId = 1337;
+
+        // Ensure the backend is called with a valid success callback.
+        mBackendBridge.getAutofillableLogins(kTestTaskId);
+        ArgumentCaptor<Callback<byte[]>> successCallback = ArgumentCaptor.forClass(Callback.class);
+        verify(mBackendMock).getAutofillableLogins(successCallback.capture(), any());
+        assertNotNull(successCallback.getValue());
+
+        byte[] kExpectedList = sTestLogins.build().toByteArray();
+        successCallback.getValue().onResult(kExpectedList);
+        verify(mBridgeJniMock)
+                .onCompleteWithLogins(sDummyNativePointer, kTestTaskId, kExpectedList);
+    }
+
+    @Test
+    public void testGetAutofillableLoginsCallsBridgeOnFailure() {
+        final int kTestTaskId = 42069;
+
+        // Ensure the backend is called with a valid failure callback.
+        mBackendBridge.getAutofillableLogins(kTestTaskId);
+        ArgumentCaptor<Callback<Exception>> failureCallback =
+                ArgumentCaptor.forClass(Callback.class);
+        verify(mBackendMock).getAutofillableLogins(any(), failureCallback.capture());
+        assertNotNull(failureCallback.getValue());
+
+        Exception kExpectedException = new Exception("Sample failure");
+        failureCallback.getValue().onResult(kExpectedException);
+        verify(mBridgeJniMock)
+                .onError(
+                        sDummyNativePointer, kTestTaskId, AndroidBackendErrorType.UNCATEGORIZED, 0);
+    }
+
+    @Test
     public void testAddLoginCallsBridgeOnSuccess() {
         final int kTestTaskId = 1337;
 
diff --git a/chrome/browser/password_manager/android/password_store_android_backend.cc b/chrome/browser/password_manager/android/password_store_android_backend.cc
index 4c20254..4040cc1 100644
--- a/chrome/browser/password_manager/android/password_store_android_backend.cc
+++ b/chrome/browser/password_manager/android/password_store_android_backend.cc
@@ -216,8 +216,11 @@
 }
 
 void PasswordStoreAndroidBackend::GetAutofillableLoginsAsync(
-    LoginsReply callback) {
-  // TODO(https://crbug.com/1229654): Implement.
+    LoginsOrErrorReply callback) {
+  JobId job_id = bridge_->GetAutofillableLogins();
+  QueueNewJob(job_id, JobReturnHandler(std::move(callback),
+                                       JobReturnHandler::MetricInfix(
+                                           "GetAutofillableLoginsAsync")));
 }
 
 void PasswordStoreAndroidBackend::FillMatchingLoginsAsync(
diff --git a/chrome/browser/password_manager/android/password_store_android_backend.h b/chrome/browser/password_manager/android/password_store_android_backend.h
index 2dc9a46..856b6b1 100644
--- a/chrome/browser/password_manager/android/password_store_android_backend.h
+++ b/chrome/browser/password_manager/android/password_store_android_backend.h
@@ -138,7 +138,7 @@
                    base::OnceCallback<void(bool)> completion) override;
   void Shutdown(base::OnceClosure shutdown_completed) override;
   void GetAllLoginsAsync(LoginsOrErrorReply callback) override;
-  void GetAutofillableLoginsAsync(LoginsReply callback) override;
+  void GetAutofillableLoginsAsync(LoginsOrErrorReply callback) override;
   void FillMatchingLoginsAsync(
       LoginsReply callback,
       bool include_psl,
diff --git a/chrome/browser/password_manager/android/password_store_android_backend_bridge.h b/chrome/browser/password_manager/android/password_store_android_backend_bridge.h
index d2fd74b..ffce8e9 100644
--- a/chrome/browser/password_manager/android/password_store_android_backend_bridge.h
+++ b/chrome/browser/password_manager/android/password_store_android_backend_bridge.h
@@ -62,6 +62,11 @@
   // job with the returned JobId succeeds.
   virtual JobId GetAllLogins() WARN_UNUSED_RESULT = 0;
 
+  // Triggers an asynchronous request to retrieve all autofillable
+  // (non-blocklisted) passwords. The registered `Consumer` is notified with
+  // `OnCompleteWithLogins` when the job with the returned JobId succeeds.
+  virtual JobId GetAutofillableLogins() WARN_UNUSED_RESULT = 0;
+
   // Triggers an asynchronous request to add |form| to store. The
   // registered `Consumer` is notified with `OnLoginsChanged` when the
   // job with the returned JobId succeeds.
diff --git a/chrome/browser/password_manager/android/password_store_android_backend_bridge_impl.cc b/chrome/browser/password_manager/android/password_store_android_backend_bridge_impl.cc
index f8e4d79d..fb39a1a 100644
--- a/chrome/browser/password_manager/android/password_store_android_backend_bridge_impl.cc
+++ b/chrome/browser/password_manager/android/password_store_android_backend_bridge_impl.cc
@@ -124,6 +124,13 @@
   return job_id;
 }
 
+JobId PasswordStoreAndroidBackendBridgeImpl::GetAutofillableLogins() {
+  JobId job_id = GetNextJobId();
+  Java_PasswordStoreAndroidBackendBridgeImpl_getAutofillableLogins(
+      base::android::AttachCurrentThread(), java_object_, job_id.value());
+  return job_id;
+}
+
 JobId PasswordStoreAndroidBackendBridgeImpl::AddLogin(
     const password_manager::PasswordForm& form) {
   JobId job_id = GetNextJobId();
diff --git a/chrome/browser/password_manager/android/password_store_android_backend_bridge_impl.h b/chrome/browser/password_manager/android/password_store_android_backend_bridge_impl.h
index e919707..95dd10f 100644
--- a/chrome/browser/password_manager/android/password_store_android_backend_bridge_impl.h
+++ b/chrome/browser/password_manager/android/password_store_android_backend_bridge_impl.h
@@ -61,6 +61,7 @@
   // Implements PasswordStoreAndroidBackendBridge interface.
   void SetConsumer(base::WeakPtr<Consumer> consumer) override;
   JobId GetAllLogins() override WARN_UNUSED_RESULT;
+  JobId GetAutofillableLogins() override WARN_UNUSED_RESULT;
   JobId AddLogin(const password_manager::PasswordForm& form) override
       WARN_UNUSED_RESULT;
   JobId UpdateLogin(const password_manager::PasswordForm& form) override
diff --git a/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc b/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc
index d5307642..08bd7b5 100644
--- a/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc
+++ b/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc
@@ -78,6 +78,7 @@
  public:
   MOCK_METHOD(void, SetConsumer, (base::WeakPtr<Consumer>), (override));
   MOCK_METHOD(JobId, GetAllLogins, (), (override));
+  MOCK_METHOD(JobId, GetAutofillableLogins, (), (override));
   MOCK_METHOD(JobId, AddLogin, (const PasswordForm&), (override));
   MOCK_METHOD(JobId, UpdateLogin, (const PasswordForm&), (override));
   MOCK_METHOD(JobId, RemoveLogin, (const PasswordForm&), (override));
@@ -140,6 +141,21 @@
   RunUntilIdle();
 }
 
+TEST_F(PasswordStoreAndroidBackendTest, CallsBridgeForAutofillableLogins) {
+  backend().InitBackend(PasswordStoreAndroidBackend::RemoteChangesReceived(),
+                        base::RepeatingClosure(), base::DoNothing());
+  const JobId kJobId{1337};
+  base::MockCallback<LoginsOrErrorReply> mock_reply;
+  EXPECT_CALL(*bridge(), GetAutofillableLogins).WillOnce(Return(kJobId));
+  backend().GetAutofillableLoginsAsync(mock_reply.Get());
+
+  std::vector<std::unique_ptr<PasswordForm>> expected_logins =
+      CreateTestLogins();
+  EXPECT_CALL(mock_reply, Run(LoginsResultsOrErrorAre(&expected_logins)));
+  consumer().OnCompleteWithLogins(kJobId, UnwrapForms(CreateTestLogins()));
+  RunUntilIdle();
+}
+
 TEST_F(PasswordStoreAndroidBackendTest, CallsBridgeForRemoveLogin) {
   backend().InitBackend(PasswordStoreAndroidBackend::RemoteChangesReceived(),
                         base::RepeatingClosure(), base::DoNothing());
diff --git a/chrome/browser/payments/chrome_payment_request_delegate.cc b/chrome/browser/payments/chrome_payment_request_delegate.cc
index 25e02dcb..3811ec96 100644
--- a/chrome/browser/payments/chrome_payment_request_delegate.cc
+++ b/chrome/browser/payments/chrome_payment_request_delegate.cc
@@ -41,6 +41,7 @@
 #include "content/public/browser/web_contents.h"
 #include "services/metrics/public/cpp/ukm_recorder.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
 #include "third_party/libaddressinput/chromium/chrome_metadata_source.h"
 #include "third_party/libaddressinput/chromium/chrome_storage_impl.h"
 
@@ -64,6 +65,12 @@
   return autofill::ValidationRulesStorageFactory::CreateStorage();
 }
 
+bool FrameSupportsPayments(content::RenderFrameHost* rfh) {
+  return rfh && rfh->IsActive() &&
+         rfh->IsFeatureEnabled(
+             blink::mojom::PermissionsPolicyFeature::kPayment);
+}
+
 }  // namespace
 
 ChromePaymentRequestDelegate::ChromePaymentRequestDelegate(
@@ -151,9 +158,10 @@
 
 const GURL& ChromePaymentRequestDelegate::GetLastCommittedURL() const {
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_);
-  return rfh && rfh->IsActive() ? content::WebContents::FromRenderFrameHost(rfh)
-                                      ->GetLastCommittedURL()
-                                : GURL::EmptyGURL();
+  return FrameSupportsPayments(rfh)
+             ? content::WebContents::FromRenderFrameHost(rfh)
+                   ->GetLastCommittedURL()
+             : GURL::EmptyGURL();
 }
 
 void ChromePaymentRequestDelegate::DoFullCardRequest(
@@ -161,7 +169,7 @@
     base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate>
         result_delegate) {
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_);
-  if (!rfh || !rfh->IsActive() || !shown_dialog_)
+  if (!FrameSupportsPayments(rfh) || !shown_dialog_)
     return;
   content::WebContents* web_contents =
       content::WebContents::FromRenderFrameHost(rfh);
@@ -213,7 +221,7 @@
 
 bool ChromePaymentRequestDelegate::IsBrowserWindowActive() const {
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_);
-  if (!rfh || !rfh->IsActive())
+  if (FrameSupportsPayments(rfh))
     return false;
 
   Browser* browser = chrome::FindBrowserWithWebContents(
@@ -225,7 +233,7 @@
     const std::u16string& merchant_name,
     base::OnceClosure response_callback) {
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_);
-  if (!rfh || !rfh->IsActive())
+  if (!FrameSupportsPayments(rfh))
     return;
   content::WebContents* web_contents =
       content::WebContents::FromRenderFrameHost(rfh);
@@ -244,7 +252,7 @@
   // displays the top-level origin in its UI before the user can click on the
   // [Verify] button to invoke this authenticator.
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_);
-  return rfh && rfh->IsActive()
+  return FrameSupportsPayments(rfh)
              ? std::make_unique<content::InternalAuthenticatorImpl>(rfh)
              : nullptr;
 }
@@ -281,7 +289,7 @@
 std::string
 ChromePaymentRequestDelegate::GetInvalidSslCertificateErrorMessage() {
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_);
-  return rfh && rfh->IsActive()
+  return FrameSupportsPayments(rfh)
              ? SslValidityChecker::GetInvalidSslCertificateErrorMessage(
                    content::WebContents::FromRenderFrameHost(rfh))
              : "";
@@ -294,7 +302,7 @@
 std::string ChromePaymentRequestDelegate::GetTwaPackageName() const {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_);
-  if (!rfh || !rfh->IsActive())
+  if (!FrameSupportsPayments(rfh))
     return "";
 
   auto* web_contents = content::WebContents::FromRenderFrameHost(rfh);
diff --git a/chrome/browser/profiles/profile_manager_browsertest.cc b/chrome/browser/profiles/profile_manager_browsertest.cc
index d3839646..6f7a16a 100644
--- a/chrome/browser/profiles/profile_manager_browsertest.cc
+++ b/chrome/browser/profiles/profile_manager_browsertest.cc
@@ -693,6 +693,10 @@
   EXPECT_EQ(1U, browser_list->size());
   EXPECT_EQ(initial_profile_count, storage.GetNumberOfProfiles());
 
+// The following check is flaky on Windows.
+// TODO(https://crbug.com/1191455): re-enable this check when the profile
+// directory deletion works more reliably on Windows.
+#if !defined(OS_WIN)
   if (base::FeatureList::IsEnabled(features::kDestroyProfileOnBrowserClose)) {
     // Check that NukeProfileFromDisk() works correctly.
     base::ScopedAllowBlockingForTesting allow_blocking;
@@ -711,6 +715,7 @@
     run_loop.Run();
     EXPECT_FALSE(base::PathExists(path_profile2));
   }
+#endif  // !defined(OS_WIN)
 }
 
 // The test makes sense on those platforms where the keychain exists.
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn
index cf761c9..2a525b3a 100644
--- a/chrome/browser/resources/BUILD.gn
+++ b/chrome/browser/resources/BUILD.gn
@@ -18,7 +18,7 @@
 assert(!is_ios, "Chromium/iOS shouldn't use anything in //chrome")
 
 group("resources") {
-  public_deps = []
+  public_deps = [ "segmentation_internals:resources" ]
 
   if (!is_android) {
     public_deps += [
diff --git a/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.html b/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.html
index 9e6b159b..75bb5ea 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.html
+++ b/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.html
@@ -212,7 +212,7 @@
         </div>
 
         <!-- Usage stats toggle row -->
-        <div class="layout horizontal center oobe-optin-row">
+        <div id="usageStats" class="layout horizontal center oobe-optin-row">
           <div class="oobe-optin-content flex">
             <span id="usageTitle" class="oobe-optin-title">
               [[i18nDynamic(locale, 'consolidatedConsentUsageOptInTitle')]]
@@ -232,7 +232,7 @@
         </div>
 
         <!-- Backup toggle row -->
-        <div class="layout horizontal center oobe-optin-row"
+        <div id="backup" class="layout horizontal center oobe-optin-row"
             hidden="[[isArcOptInsHidden_(isArcEnabled_, isDemo_)]]">
           <div class="oobe-optin-content flex">
             <span id="backupTitle" class="oobe-optin-title">
@@ -259,7 +259,7 @@
         </div>
 
         <!-- Location services toggle row -->
-        <div class="layout horizontal center oobe-optin-row"
+        <div id="location" class="layout horizontal center oobe-optin-row"
             hidden="[[isArcOptInsHidden_(isArcEnabled_, isDemo_)]]">
           <div class="oobe-optin-content flex">
             <span id="locationTitle" class="oobe-optin-title">
diff --git a/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.js b/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.js
index f3f6cb2..5c28eca 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.js
+++ b/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.js
@@ -123,7 +123,7 @@
      * The hostname of the url where the terms of service will be fetched.
      * Overwritten by tests to load terms of service from local test server.
      */
-    this.termsOfServiceHostName_ = 'https://play.google.com';
+    this.arcTosHostName_ = 'https://play.google.com';
 
     // Online URLs
     this.googleEulaUrl_ = '';
@@ -168,6 +168,12 @@
       resetAllowed: true,
     });
     this.updateLocalizedContent();
+
+    if (loadTimeData.valueExists(
+            'consolidatedConsentArcTosHostNameForTesting')) {
+      this.setArcTosHostNameForTesting_(loadTimeData.getString(
+          'consolidatedConsentArcTosHostNameForTesting'));
+    }
   }
 
   onBeforeShow(data) {
@@ -181,7 +187,7 @@
 
     this.googleEulaUrl_ = data['googleEulaUrl'];
     this.crosEulaUrl_ = data['crosEulaUrl'];
-    this.arcTosUrl_ = this.termsOfServiceHostName_ + '/about/play-terms.html';
+    this.arcTosUrl_ = this.arcTosHostName_ + '/about/play-terms.html';
 
     this.maybeLoadWebviews_(
         this.isEnterpriseManagedAccount_, this.isArcEnabled_);
@@ -237,14 +243,14 @@
 
     webview.addContentScripts([{
       name: 'preProcess',
-      matches: [this.getTermsOfServiceHostNameForMatchPattern_() + '/*'],
+      matches: [this.getArcTosHostNameForMatchPattern_() + '/*'],
       js: {code: scriptSetParameters},
       run_at: 'document_start'
     }]);
 
     webview.addContentScripts([{
       name: 'postProcess',
-      matches: [this.getTermsOfServiceHostNameForMatchPattern_() + '/*'],
+      matches: [this.getArcTosHostNameForMatchPattern_() + '/*'],
       css: {files: ['playstore.css']},
       js: {files: ['playstore.js']},
       run_at: 'document_end'
@@ -319,8 +325,8 @@
    * @return {string}
    * @private
    */
-  getTermsOfServiceHostNameForMatchPattern_() {
-    return this.termsOfServiceHostName_.replace(/:[0-9]+/, '');
+  getArcTosHostNameForMatchPattern_() {
+    return this.arcTosHostName_.replace(/:[0-9]+/, '');
   }
 
   /**
@@ -495,7 +501,6 @@
     return this.i18n('consolidatedConsentHeader');
   }
 
-
   getUsageText_(locale, isChildAccount, isArcEnabled, isDemo) {
     if (this.isArcOptInsHidden_(isArcEnabled, isDemo)) {
       return this.i18n('consolidatedConsentUsageOptInArcDisabled');
@@ -645,6 +650,27 @@
   onBack_() {
     this.userActed('back');
   }
+
+  /**
+   * Sets Play Store hostname url used to fetch terms of service for testing.
+   * @param {string} hostname hostname used to fetch terms of service.
+   * @suppress {missingProperties} as WebView type has no addContentScripts
+   */
+  setArcTosHostNameForTesting_(hostname) {
+    this.arcTosHostName_ = hostname;
+
+    // Enable loading content script 'playstore.js' when fetching ToS from
+    // the test server.
+    var termsView = this.$.arcTosWebview;
+    termsView.removeContentScripts(['postProcess']);
+    termsView.addContentScripts([{
+      name: 'postProcess',
+      matches: [this.getArcTosHostNameForMatchPattern_() + '/*'],
+      css: {files: ['playstore.css']},
+      js: {files: ['playstore.js']},
+      run_at: 'document_end'
+    }]);
+  }
 }
 
 customElements.define(ConsolidatedConsent.is, ConsolidatedConsent);
diff --git a/chrome/browser/resources/segmentation_internals/BUILD.gn b/chrome/browser/resources/segmentation_internals/BUILD.gn
new file mode 100644
index 0000000..b60e7d0e
--- /dev/null
+++ b/chrome/browser/resources/segmentation_internals/BUILD.gn
@@ -0,0 +1,75 @@
+# 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/common/features.gni")
+import("//tools/grit/grit_rule.gni")
+import("//tools/polymer/html_to_js.gni")
+import("//tools/typescript/ts_library.gni")
+import("//ui/webui/resources/tools/generate_grd.gni")
+
+tsc_folder = "tsc"
+
+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/resources.grd"
+  deps = [ ":build_grd" ]
+
+  outputs = [
+    "grit/segmentation_internals_resources.h",
+    "grit/segmentation_internals_resources_map.cc",
+    "grit/segmentation_internals_resources_map.h",
+    "segmentation_internals_resources.pak",
+  ]
+  output_dir = "$root_gen_dir/chrome"
+}
+
+generate_grd("build_grd") {
+  grd_prefix = "segmentation_internals"
+  out_grd = "$target_gen_dir/resources.grd"
+  deps = [ ":build_ts" ]
+  manifest_files = [ "$target_gen_dir/tsconfig.manifest" ]
+  input_files = [ "segmentation_internals.html" ]
+  input_files_base_dir = rebase_path(".", "//")
+}
+
+html_to_js("web_components") {
+  js_files = [ "segmentation_internals.ts" ]
+}
+
+copy("copy_proxy") {
+  sources = [ "segmentation_internals_browser_proxy.ts" ]
+  outputs = [ "$target_gen_dir/{{source_file_part}}" ]
+}
+
+copy("copy_mojo") {
+  deps = [
+    "//chrome/browser/ui/webui/segmentation_internals:mojo_bindings_webui_js",
+  ]
+  mojom_folder = "$root_gen_dir/mojom-webui/chrome/browser/ui/webui/segmentation_internals/"
+  sources = [ "$mojom_folder/segmentation_internals.mojom-webui.js" ]
+  outputs = [ "$target_gen_dir/{{source_file_part}}" ]
+}
+
+ts_library("build_ts") {
+  root_dir = "$target_gen_dir"
+  out_dir = "$target_gen_dir/$tsc_folder"
+  tsconfig_base = "tsconfig_base.json"
+  in_files = [
+    "segmentation_internals.ts",
+    "segmentation_internals_browser_proxy.ts",
+    "segmentation_internals.mojom-webui.js",
+  ]
+  deps = [
+    "//ui/webui/resources:library",
+    "//ui/webui/resources/js/browser_command:build_ts",
+  ]
+  extra_deps = [
+    ":copy_mojo",
+    ":copy_proxy",
+    ":web_components",
+  ]
+}
diff --git a/chrome/browser/resources/segmentation_internals/OWNERS b/chrome/browser/resources/segmentation_internals/OWNERS
new file mode 100644
index 0000000..b3f32429
--- /dev/null
+++ b/chrome/browser/resources/segmentation_internals/OWNERS
@@ -0,0 +1 @@
+file://components/segmentation_platform/OWNERS
\ No newline at end of file
diff --git a/chrome/browser/resources/segmentation_internals/segmentation_internals.html b/chrome/browser/resources/segmentation_internals/segmentation_internals.html
new file mode 100644
index 0000000..09db8ab2
--- /dev/null
+++ b/chrome/browser/resources/segmentation_internals/segmentation_internals.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html lang="en" dir="ltr">
+  <head>
+    <meta charset="utf-8">
+    <title>Segmentation Internals</title>
+    <meta name="viewport" content="width=device-width">
+    <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
+  </head>
+  <body>
+    <h1>Segmentation Internals</h1>
+    <h4>Get segment</h4>
+    <div>
+      <Label for="segment-key">Segment key:</Label>
+      <input type="text" id="segment-key">
+      <button id="get-segment">Get segment result</button>
+    </div>
+    <h4>Segment result</h4>
+    <div>
+      Is ready: <span id="is-ready"></span>
+    </div>
+    <div>
+      Optimization target: <span id="optimization-target"></span>
+      </div>
+    <script type="module" src="segmentation_internals.js"></script>
+  </body>
+</html>
diff --git a/chrome/browser/resources/segmentation_internals/segmentation_internals.ts b/chrome/browser/resources/segmentation_internals/segmentation_internals.ts
new file mode 100644
index 0000000..688ef83c
--- /dev/null
+++ b/chrome/browser/resources/segmentation_internals/segmentation_internals.ts
@@ -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.
+
+import {$} from 'chrome://resources/js/util.m.js';
+
+import {SegmentationInternalsBrowserProxy} from './segmentation_internals_browser_proxy.js';
+
+function getProxy(): SegmentationInternalsBrowserProxy {
+  return SegmentationInternalsBrowserProxy.getInstance();
+}
+
+function initialize() {
+  $('get-segment').onclick = async function() {
+    const {result} = await getProxy().getSegment(
+        ($('segment-key') as HTMLInputElement).value);
+    $('is-ready').textContent = String(result.isReady);
+    $('optimization-target').textContent = String(result.optimizationTarget);
+  };
+}
+
+document.addEventListener('DOMContentLoaded', initialize);
diff --git a/chrome/browser/resources/segmentation_internals/segmentation_internals_browser_proxy.ts b/chrome/browser/resources/segmentation_internals/segmentation_internals_browser_proxy.ts
new file mode 100644
index 0000000..0511df3
--- /dev/null
+++ b/chrome/browser/resources/segmentation_internals/segmentation_internals_browser_proxy.ts
@@ -0,0 +1,25 @@
+// 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 {PageHandlerFactory, PageHandlerRemote} from './segmentation_internals.mojom-webui.js';
+
+export class SegmentationInternalsBrowserProxy {
+  private handler: PageHandlerRemote;
+
+  constructor() {
+    this.handler = new PageHandlerRemote();
+    const factory = PageHandlerFactory.getRemote();
+    factory.createPageHandler(this.handler.$.bindNewPipeAndPassReceiver());
+  }
+
+  getSegment(key: string) {
+    return this.handler.getSegment(key);
+  }
+
+  static getInstance(): SegmentationInternalsBrowserProxy {
+    return instance || (instance = new SegmentationInternalsBrowserProxy());
+  }
+}
+
+let instance: SegmentationInternalsBrowserProxy|null = null;
diff --git a/chrome/browser/resources/segmentation_internals/tsconfig_base.json b/chrome/browser/resources/segmentation_internals/tsconfig_base.json
new file mode 100644
index 0000000..f078dc06
--- /dev/null
+++ b/chrome/browser/resources/segmentation_internals/tsconfig_base.json
@@ -0,0 +1,6 @@
+{
+    "extends": "../../../../tools/typescript/tsconfig_base.json",
+    "compilerOptions": {
+        "allowJs": true
+    }
+}
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextCoordinator.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextCoordinator.java
index 3a488f575..1c56f4d2 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextCoordinator.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextCoordinator.java
@@ -42,6 +42,7 @@
     public static final String SHARED_HIGHLIGHTING_SUPPORT_URL =
             "https://support.google.com/chrome?p=shared_highlighting";
     public static final String TEXT_FRAGMENT_PREFIX = ":~:text=";
+    public static final String ADDITIONAL_TEXT_FRAGMENT_SELECTOR = "&text=";
 
     private static final String SHARE_TEXT_TEMPLATE = "\"%s\"\n";
     private static final String INVALID_SELECTOR = "";
@@ -171,8 +172,9 @@
                     @Override
                     public void call(String[] matches) {
                         mSelectedText = String.join(",", matches);
-                        getExistingSelectors(
-                                mProducer, (text) -> { onSelectorReady(String.join("", text)); });
+                        getExistingSelectors(mProducer, (text) -> {
+                            onSelectorReady(String.join(ADDITIONAL_TEXT_FRAGMENT_SELECTOR, text));
+                        });
                     }
                 });
     }
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextCoordinatorTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextCoordinatorTest.java
index 493c945e..8bcbf0f 100644
--- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextCoordinatorTest.java
+++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextCoordinatorTest.java
@@ -6,6 +6,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -24,23 +25,29 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
 
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.browser.share.ChromeShareExtras;
 import org.chromium.chrome.browser.share.share_sheet.ChromeOptionShareCallback;
+import org.chromium.chrome.browser.share.share_sheet.ShareSheetLinkToggleCoordinator.LinkToggleState;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.components.browser_ui.share.ShareParams;
 import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils;
 import org.chromium.components.dom_distiller.core.DomDistillerUrlUtilsJni;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.ui.base.WindowAndroid;
+import org.chromium.url.GURL;
 import org.chromium.url.JUnitTestGURLs;
+import org.chromium.url.ShadowGURL;
 
 /**
  * Tests for {@link LinkToTextCoordinator}.
  */
 @RunWith(BaseRobolectricTestRunner.class)
+@Config(shadows = {ShadowGURL.class})
 public class LinkToTextCoordinatorTest {
     @Rule
     public JniMocker jniMocker = new JniMocker();
@@ -78,8 +85,9 @@
         MockitoAnnotations.initMocks(this);
         jniMocker.mock(DomDistillerUrlUtilsJni.TEST_HOOKS, mDistillerUrlUtilsJniMock);
         when(mDistillerUrlUtilsJniMock.getOriginalUrlFromDistillerUrl(any(String.class)))
-                .thenReturn(JUnitTestGURLs.getGURL(VISIBLE_URL));
-
+                .thenAnswer((invocation) -> {
+                    return new GURL((String) invocation.getArguments()[0]);
+                });
         doNothing().when(mShareCallback).showThirdPartyShareSheet(any(), any(), anyLong());
         doNothing().when(mShareCallback).showShareSheet(any(), any(), anyLong());
         Mockito.when(mTab.getWebContents()).thenReturn(mWebContents);
@@ -125,21 +133,52 @@
     @Test
     @SmallTest
     public void showShareSheetTest_LinkGeneration() {
+        String selector = "selector";
+        String expectedUrlToShare = VISIBLE_URL + "#:~:text=selector";
+
         ChromeShareExtras chromeShareExtras = new ChromeShareExtras.Builder().build();
         LinkToTextCoordinator coordinator = new LinkToTextCoordinator(
                 mTab, mShareCallback, chromeShareExtras, 1, VISIBLE_URL, SELECTED_TEXT);
-        coordinator.onSelectorReady("selector");
-        verify(mShareCallback).showShareSheet(any(), any(), anyLong());
+        coordinator.onSelectorReady(selector);
+        ShareParams shareParams = coordinator.getShareParams(LinkToggleState.LINK);
+        verify(mShareCallback).showShareSheet(eq(shareParams), any(), anyLong());
+        Assert.assertEquals(expectedUrlToShare, shareParams.getUrl());
+        Assert.assertEquals(true, shareParams.getLinkToTextSuccessful());
+    }
+
+    @Test
+    @SmallTest
+    public void showShareSheetTest_LinkGenerationMultiHighlights() {
+        String[] selectors = {"selector1", "selector2", "selector3"};
+        String fragmentDirective =
+                String.join(LinkToTextCoordinator.ADDITIONAL_TEXT_FRAGMENT_SELECTOR, selectors);
+        String expectedUrlToShare =
+                VISIBLE_URL + "#:~:text=selector1&text=selector2&text=selector3";
+
+        ChromeShareExtras chromeShareExtras = new ChromeShareExtras.Builder().build();
+        LinkToTextCoordinator coordinator = new LinkToTextCoordinator(
+                mTab, mShareCallback, chromeShareExtras, 1, VISIBLE_URL, SELECTED_TEXT);
+        coordinator.onSelectorReady(fragmentDirective);
+        ShareParams shareParams = coordinator.getShareParams(LinkToggleState.LINK);
+        verify(mShareCallback).showShareSheet(eq(shareParams), any(), anyLong());
+        Assert.assertEquals(expectedUrlToShare, shareParams.getUrl());
+        Assert.assertEquals(true, shareParams.getLinkToTextSuccessful());
     }
 
     @Test
     @SmallTest
     public void showShareSheetTest_EmptySelector() {
+        String selector = "";
+        String expectedUrlToShare = "";
+
         ChromeShareExtras chromeShareExtras = new ChromeShareExtras.Builder().build();
         LinkToTextCoordinator coordinator = new LinkToTextCoordinator(
                 mTab, mShareCallback, chromeShareExtras, 1, VISIBLE_URL, SELECTED_TEXT);
-        coordinator.onSelectorReady("");
-        verify(mShareCallback).showShareSheet(any(), any(), anyLong());
+        coordinator.onSelectorReady(selector);
+        ShareParams shareParams = coordinator.getShareParams(LinkToggleState.NO_LINK);
+        verify(mShareCallback).showShareSheet(eq(shareParams), any(), anyLong());
+        Assert.assertEquals(expectedUrlToShare, shareParams.getUrl());
+        Assert.assertEquals(false, shareParams.getLinkToTextSuccessful());
     }
 
     @Test
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 94a08eb0..9829438 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -306,6 +306,10 @@
     "webui/quota_internals/quota_internals_types.h",
     "webui/quota_internals/quota_internals_ui.cc",
     "webui/quota_internals/quota_internals_ui.h",
+    "webui/segmentation_internals/segmentation_internals_page_handler_impl.cc",
+    "webui/segmentation_internals/segmentation_internals_page_handler_impl.h",
+    "webui/segmentation_internals/segmentation_internals_ui.cc",
+    "webui/segmentation_internals/segmentation_internals_ui.h",
     "webui/signin_internals_ui.cc",
     "webui/signin_internals_ui.h",
     "webui/support_tool_ui.cc",
@@ -432,6 +436,7 @@
     "//chrome/browser/ui/webui/read_later/side_panel:mojo_bindings",
     "//chrome/browser/ui/webui/read_later/side_panel/reader_mode:mojo_bindings",
     "//chrome/browser/ui/webui/realbox:mojo_bindings",
+    "//chrome/browser/ui/webui/segmentation_internals:mojo_bindings",
     "//chrome/browser/ui/webui/tab_search:mojo_bindings",
     "//chrome/browser/ui/webui/usb_internals:mojo_bindings",
     "//chrome/browser/video_tutorials",
@@ -554,6 +559,7 @@
     "//components/security_interstitials/core:unsafe_resource",
     "//components/security_state/content",
     "//components/security_state/core",
+    "//components/segmentation_platform/public",
     "//components/send_tab_to_self",
     "//components/sessions",
     "//components/signin/core/browser",
@@ -4862,14 +4868,13 @@
           "views/chrome_browser_main_extra_parts_views_linux.cc",
           "views/chrome_browser_main_extra_parts_views_linux.h",
         ]
+        deps += [
+          "//ui/base/cursor:cursor_base",
+          "//ui/ozone",
+        ]
+
         if (use_gtk) {
           deps += [ "//ui/gtk" ]
-          if (use_ozone) {
-            deps += [ "//ui/ozone" ]
-          }
-        }
-        if (use_ozone) {
-          deps += [ "//ui/base/cursor:cursor_base" ]
         }
       }
     }
diff --git a/chrome/browser/ui/app_list/app_list_model_updater.h b/chrome/browser/ui/app_list/app_list_model_updater.h
index 6b9e3d7..1448a0c 100644
--- a/chrome/browser/ui/app_list/app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/app_list_model_updater.h
@@ -54,8 +54,9 @@
 
   // For AppListModel:
   virtual void AddItem(std::unique_ptr<ChromeAppListItem> item) {}
-  virtual void AddItemToFolder(std::unique_ptr<ChromeAppListItem> item,
-                               const std::string& folder_id) {}
+  virtual void AddAppItemToFolder(std::unique_ptr<ChromeAppListItem> app_item,
+                                  const std::string& folder_id,
+                                  bool add_from_local) {}
   virtual void RemoveItem(const std::string& id) {}
   virtual void RemoveUninstalledItem(const std::string& id) {}
   virtual void SetStatus(ash::AppListModelStatus status) {}
diff --git a/chrome/browser/ui/app_list/app_list_sort_unittest.cc b/chrome/browser/ui/app_list/app_list_sort_unittest.cc
index 31637aad..e15bd6c 100644
--- a/chrome/browser/ui/app_list/app_list_sort_unittest.cc
+++ b/chrome/browser/ui/app_list/app_list_sort_unittest.cc
@@ -478,7 +478,6 @@
 // an item to an existed folder.
 TEST_F(TemporaryAppListSortTest, HandleMoveItemToFolder) {
   RemoveAllExistingItems();
-  syncer::SyncDataList sync_list;
 
   // Add one folder containing two apps.
   // Emulate to merge two items into a folder.
@@ -495,6 +494,7 @@
 
   const std::string kChildItemId1_1 = GenerateId("folder_child1");
   const std::string kChildItemId1_2 = GenerateId("folder_child2");
+  syncer::SyncDataList sync_list;
   sync_list.push_back(CreateAppRemoteData(
       kFolderItemId, "Folder", "",
       syncer::StringOrdinal::CreateInitialOrdinal().ToInternalValue(), kUnset,
@@ -563,3 +563,155 @@
   EXPECT_FALSE(IsUnderTemporarySort());
   EXPECT_EQ(ash::AppListSortOrder::kCustom, GetSortOrderFromPrefs());
 }
+
+// Verifies the temporary sorting behavior with local app installation.
+TEST_F(TemporaryAppListSortTest, InstallAppLocally) {
+  RemoveAllExistingItems();
+
+  // Install three apps.
+  const std::string kItemId1 = CreateNextAppId(GenerateId("app_id1"));
+  scoped_refptr<extensions::Extension> app1 =
+      MakeApp("B", kItemId1, extensions::Extension::NO_FLAGS);
+  InstallExtension(app1.get());
+
+  const std::string kItemId2 = CreateNextAppId(GenerateId("app_id2"));
+  scoped_refptr<extensions::Extension> app2 =
+      MakeApp("C", kItemId2, extensions::Extension::NO_FLAGS);
+  InstallExtension(app2.get());
+
+  const std::string kItemId3 = CreateNextAppId(GenerateId("app_id3"));
+  scoped_refptr<extensions::Extension> app3 =
+      MakeApp("E", kItemId3, extensions::Extension::NO_FLAGS);
+  InstallExtension(app3.get());
+
+  // Sort with the name alphabetical order then commit the order.
+  ChromeAppListModelUpdater* model_updater = GetChromeModelUpdater();
+  model_updater->RequestAppListSort(ash::AppListSortOrder::kNameAlphabetical);
+  Commit();
+
+  // Sort with the name reverse alphabetical order without committing. The
+  // permanent sort order and the permanent item positions should not change.
+  model_updater->RequestAppListSort(
+      ash::AppListSortOrder::kNameReverseAlphabetical);
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
+            std::vector<std::string>({"B", "C", "E"}));
+  EXPECT_EQ(GetOrderedNamesFromModelUpdater(),
+            std::vector<std::string>({"E", "C", "B"}));
+  EXPECT_EQ(ash::AppListSortOrder::kNameAlphabetical, GetSortOrderFromPrefs());
+
+  // Install the forth app.
+  const std::string kItemId4 = CreateNextAppId(GenerateId("app_id4"));
+  scoped_refptr<extensions::Extension> app4 =
+      MakeApp("A", kItemId4, extensions::Extension::NO_FLAGS);
+  InstallExtension(app4.get());
+
+  // Verify that the temporary sorting order is committed.
+  EXPECT_FALSE(IsUnderTemporarySort());
+  EXPECT_EQ(ash::AppListSortOrder::kNameReverseAlphabetical,
+            GetSortOrderFromPrefs());
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
+            std::vector<std::string>({"E", "C", "B", "A"}));
+  EXPECT_EQ(GetOrderedNamesFromModelUpdater(),
+            std::vector<std::string>({"E", "C", "B", "A"}));
+
+  // Sort with the name alphabetical order without committing.
+  model_updater->RequestAppListSort(ash::AppListSortOrder::kNameAlphabetical);
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
+            std::vector<std::string>({"E", "C", "B", "A"}));
+  EXPECT_EQ(GetOrderedNamesFromModelUpdater(),
+            std::vector<std::string>({"A", "B", "C", "E"}));
+  EXPECT_EQ(ash::AppListSortOrder::kNameReverseAlphabetical,
+            GetSortOrderFromPrefs());
+
+  // Install the fifth app.
+  const std::string kItemId5 = CreateNextAppId(GenerateId("app_id5"));
+  scoped_refptr<extensions::Extension> app5 =
+      MakeApp("D", kItemId5, extensions::Extension::NO_FLAGS);
+  InstallExtension(app5.get());
+
+  // Verify that the temporary sorting order is committed.
+  EXPECT_FALSE(IsUnderTemporarySort());
+  EXPECT_EQ(ash::AppListSortOrder::kNameAlphabetical, GetSortOrderFromPrefs());
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
+            std::vector<std::string>({"A", "B", "C", "D", "E"}));
+  EXPECT_EQ(GetOrderedNamesFromModelUpdater(),
+            std::vector<std::string>({"A", "B", "C", "D", "E"}));
+}
+
+// Verifies the temporary sorting behavior with remote installation.
+TEST_F(TemporaryAppListSortTest, InstallAppRemotely) {
+  // Start syncing.
+  app_list_syncable_service()->MergeDataAndStartSyncing(
+      syncer::APP_LIST, syncer::SyncDataList(),
+      std::make_unique<syncer::FakeSyncChangeProcessor>(),
+      std::make_unique<syncer::SyncErrorFactoryMock>());
+  content::RunAllTasksUntilIdle();
+  RemoveAllExistingItems();
+
+  // Install three apps.
+  const std::string kItemId1 = CreateNextAppId(GenerateId("app_id1"));
+  scoped_refptr<extensions::Extension> app1 =
+      MakeApp("B", kItemId1, extensions::Extension::NO_FLAGS);
+  InstallExtension(app1.get());
+
+  const std::string kItemId2 = CreateNextAppId(GenerateId("app_id2"));
+  scoped_refptr<extensions::Extension> app2 =
+      MakeApp("C", kItemId2, extensions::Extension::NO_FLAGS);
+  InstallExtension(app2.get());
+
+  const std::string kItemId3 = CreateNextAppId(GenerateId("app_id3"));
+  scoped_refptr<extensions::Extension> app3 =
+      MakeApp("E", kItemId3, extensions::Extension::NO_FLAGS);
+  InstallExtension(app3.get());
+
+  // Sort with the name alphabetical order then commit the order.
+  ChromeAppListModelUpdater* model_updater = GetChromeModelUpdater();
+  model_updater->RequestAppListSort(ash::AppListSortOrder::kNameAlphabetical);
+  Commit();
+
+  // Sort with the name reverse alphabetical order without committing. The
+  // permanent sort order and the permanent item positions should not change.
+  model_updater->RequestAppListSort(
+      ash::AppListSortOrder::kNameReverseAlphabetical);
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
+            std::vector<std::string>({"B", "C", "E"}));
+  EXPECT_EQ(GetOrderedNamesFromModelUpdater(),
+            std::vector<std::string>({"E", "C", "B"}));
+  EXPECT_EQ(ash::AppListSortOrder::kNameAlphabetical, GetSortOrderFromPrefs());
+
+  // Install an app remotely in the following steps:
+  // step 1: create a new sync data through sync service.
+  // step 2: install the new app that matches the data created in the step 1.
+  syncer::SyncChangeList change_list;
+  const std::string kItemId4 = CreateNextAppId(GenerateId("app_id4"));
+  const syncer::StringOrdinal target_position =
+      GetPositionFromSyncData(kItemId1).CreateBefore();
+  change_list.push_back(syncer::SyncChange(
+      FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
+      CreateAppRemoteData(kItemId4, "A", std::string(),
+                          target_position.ToInternalValue(), "")));
+  app_list_syncable_service()->ProcessSyncChanges(base::Location(),
+                                                  change_list);
+  content::RunAllTasksUntilIdle();
+  scoped_refptr<extensions::Extension> app4 =
+      MakeApp("A", kItemId4, extensions::Extension::NO_FLAGS);
+  InstallExtension(app4.get());
+
+  // Verify that the app list is still under temporary sorting order.
+  EXPECT_TRUE(IsUnderTemporarySort());
+  EXPECT_EQ(ash::AppListSortOrder::kNameAlphabetical, GetSortOrderFromPrefs());
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
+            std::vector<std::string>({"A", "B", "C", "E"}));
+  EXPECT_EQ(GetOrderedNamesFromModelUpdater(),
+            std::vector<std::string>({"E", "C", "B", "A"}));
+
+  // Revert the temporary sorting order. Verify that the new app is placed at
+  // the position that is specified by `change_list`.
+  model_updater->RequestAppListSortRevert();
+  EXPECT_FALSE(IsUnderTemporarySort());
+  EXPECT_EQ(ash::AppListSortOrder::kNameAlphabetical, GetSortOrderFromPrefs());
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
+            std::vector<std::string>({"A", "B", "C", "E"}));
+  EXPECT_EQ(GetOrderedNamesFromModelUpdater(),
+            std::vector<std::string>({"A", "B", "C", "E"}));
+}
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.cc b/chrome/browser/ui/app_list/app_list_syncable_service.cc
index bf996c5..539ab69 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service.cc
+++ b/chrome/browser/ui/app_list/app_list_syncable_service.cc
@@ -649,14 +649,21 @@
   if (!app_item->position().IsValid())
     InitNewItemPosition(app_item.get());
 
+  // When `app_item` is installed from the local device, `app_item`'s sync data
+  // does not exist until `FindOrAddSyncItem()` is called.
+  const bool is_item_new = !FindSyncItem(app_item->id());
+
   SyncItem* sync_item = FindOrAddSyncItem(app_item.get());
   if (!sync_item)
     return;  // Item is not valid.
 
-  if (AppIsOem(app_item->id())) {
+  if (app_item->is_folder() || app_item->is_page_break()) {
+    model_updater_->AddItem(std::move(app_item));
+  } else if (AppIsOem(app_item->id())) {
     VLOG(2) << this << ": AddItem to OEM folder: " << sync_item->ToString();
     EnsureOemFolderExists();
-    model_updater_->AddItemToFolder(std::move(app_item), ash::kOemFolderId);
+    model_updater_->AddAppItemToFolder(std::move(app_item), ash::kOemFolderId,
+                                       is_item_new);
   } else {
     std::string folder_id = sync_item->parent_id;
     VLOG(2) << this << ": AddItem: " << sync_item->ToString() << " Folder: '"
@@ -669,7 +676,8 @@
     if (!folder_id.empty())
       MaybeCreateFolderBeforeAddingItem(app_item.get(), folder_id);
 
-    model_updater_->AddItemToFolder(std::move(app_item), folder_id);
+    model_updater_->AddAppItemToFolder(std::move(app_item), folder_id,
+                                       is_item_new);
   }
 
   // Calculate this early since |sync_item| could be deleted in
@@ -1283,6 +1291,11 @@
   }
 }
 
+syncer::StringOrdinal AppListSyncableService::CalculateGlobalFrontPosition()
+    const {
+  return reorder::CalculateFrontPosition(sync_items_);
+}
+
 // AppListSyncableService private
 
 bool AppListSyncableService::ProcessSyncItemSpecifics(
@@ -1663,7 +1676,7 @@
   // should be placed at front. Also reset the sorting order.
   if (!is_successful) {
     DCHECK(!position.IsValid());
-    position = reorder::CalculateFrontPosition(sync_items_);
+    position = CalculateGlobalFrontPosition();
     profile()->GetPrefs()->SetInteger(
         prefs::kAppListPreferredOrder,
         static_cast<int>(ash::AppListSortOrder::kCustom));
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.h b/chrome/browser/ui/app_list/app_list_syncable_service.h
index 883d0d5..1602b7b 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service.h
+++ b/chrome/browser/ui/app_list/app_list_syncable_service.h
@@ -230,6 +230,7 @@
 
   // reorder::AppListReorderDelegate:
   void SetAppListPreferredOrder(ash::AppListSortOrder order) override;
+  syncer::StringOrdinal CalculateGlobalFrontPosition() const override;
 
  private:
   class ModelUpdaterObserver;
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
index 20edfb26..4954c3a0 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
+++ b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
@@ -1792,12 +1792,12 @@
 
   app_list_syncable_service()->SetAppListPreferredOrder(
       ash::AppListSortOrder::kNameAlphabetical);
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"A", "A", "B", "C", "C", "D"}));
 
   app_list_syncable_service()->SetAppListPreferredOrder(
       ash::AppListSortOrder::kNameReverseAlphabetical);
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"D", "C", "C", "B", "A", "A"}));
 }
 
@@ -1829,7 +1829,7 @@
       ash::AppListSortOrder::kNameReverseAlphabetical);
   EXPECT_EQ(ash::AppListSortOrder::kNameReverseAlphabetical,
             GetSortOrderFromPrefs());
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"E", "C", "B", "A"}));
 
   // Insert another app. Verify the order.
@@ -1837,7 +1837,7 @@
   scoped_refptr<extensions::Extension> app5 =
       MakeApp("D", kItemId5, extensions::Extension::NO_FLAGS);
   InstallExtension(app5.get());
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"E", "D", "C", "B", "A"}));
 
   // The longest subsequence in reverse alphabetical order is the whole
@@ -1856,11 +1856,11 @@
   app_list_syncable_service()->SetAppListPreferredOrder(
       ash::AppListSortOrder::kNameAlphabetical);
   EXPECT_EQ(ash::AppListSortOrder::kNameAlphabetical, GetSortOrderFromPrefs());
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"A", "B", "C", "D", "E"}));
 
   ChangeItemName(kItemId3, "Z");
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"A", "B", "Z", "D", "E"}));
 
   // The longest subsequence in order is ["A", "B", "D", "E"] so the entropy is
@@ -1874,12 +1874,12 @@
   scoped_refptr<extensions::Extension> app6 =
       MakeApp("C", kItemId6, extensions::Extension::NO_FLAGS);
   InstallExtension(app6.get());
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"A", "B", "C", "Z", "D", "E"}));
 
   // Change another app's name.
   ChangeItemName(kItemId2, "F");
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"A", "F", "C", "Z", "D", "E"}));
 
   // The longest subsequence in order is ["A", "C", "D", "E"] so the entropy is
@@ -1896,7 +1896,7 @@
   InstallExtension(app7.get());
 
   // The entropy is too high so the new app is inserted at the front.
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"G", "A", "F", "C", "Z", "D", "E"}));
 
   // The sort order is reset.
@@ -1909,7 +1909,7 @@
   InstallExtension(app8.get());
 
   // Because the sort order is kCustom, the new app is placed at the front.
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"H", "G", "A", "F", "C", "Z", "D", "E"}));
 }
 
@@ -1955,7 +1955,7 @@
   // Sort sync items then verify the item order.
   app_list_syncable_service()->SetAppListPreferredOrder(
       ash::AppListSortOrder::kNameAlphabetical);
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"", "Folder1", "Folder2"}));
 
   // Install a new app.
@@ -1965,7 +1965,7 @@
   InstallExtension(app.get());
 
   // Verify that the app is placed after folders.
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"", "Folder1", "Folder2", "B"}));
 
   // Verify that the entropy is zero.
@@ -1980,13 +1980,13 @@
   InstallExtension(app2.get());
 
   // Verify that the app is placed after folders.
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"", "Folder1", "Folder2", "B", "C"}));
 
   // Change folders' names so that folders are out of order.
   ChangeItemName(kFolderItemId1, "Folder2");
   ChangeItemName(kFolderItemId2, "Folder1");
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"", "Folder2", "Folder1", "B", "C"}));
 
   // There is one folder item out of order so the entropy should be 1/5 = 0.2.
@@ -2000,7 +2000,7 @@
       MakeApp("D", kNewAppId3, extensions::Extension::NO_FLAGS);
   InstallExtension(app3.get());
   EXPECT_EQ(
-      GetNamesOfSortedItemsFromSyncableService(),
+      GetOrderedNamesFromSyncableService(),
       std::vector<std::string>({"", "Folder2", "Folder1", "B", "C", "D"}));
 
   // Install the forth app. Verify that the new item is inserted between a
@@ -2010,7 +2010,7 @@
       MakeApp("A", kNewAppId4, extensions::Extension::NO_FLAGS);
   InstallExtension(app4.get());
   EXPECT_EQ(
-      GetNamesOfSortedItemsFromSyncableService(),
+      GetOrderedNamesFromSyncableService(),
       std::vector<std::string>({"", "Folder2", "Folder1", "A", "B", "C", "D"}));
 }
 
@@ -2035,13 +2035,13 @@
   InstallExtension(app3.get());
 
   // The sort order is not set. Therefore an app is always placed at the front.
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"D", "A", "C"}));
 
   app_list_syncable_service()->SetAppListPreferredOrder(
       ash::AppListSortOrder::kNameAlphabetical);
   EXPECT_EQ(ash::AppListSortOrder::kNameAlphabetical, GetSortOrderFromPrefs());
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"A", "C", "D"}));
 
   // A hacky way to emulate that an item is disabled locally (in other words,
@@ -2054,7 +2054,7 @@
   scoped_refptr<extensions::Extension> app4 =
       MakeApp("B", kItemId4, extensions::Extension::NO_FLAGS);
   InstallExtension(app4.get());
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"A", "B", "C", "D"}));
 
   // Remove another item from the model. Now only "A" and "B" are in the model.
@@ -2065,7 +2065,7 @@
   scoped_refptr<extensions::Extension> app5 =
       MakeApp("F", kItemId5, extensions::Extension::NO_FLAGS);
   InstallExtension(app5.get());
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"A", "B", "C", "D", "F"}));
 
   // Remove another item from the model. Now only "A" and "B" are in the model.
@@ -2076,7 +2076,7 @@
   scoped_refptr<extensions::Extension> app6 =
       MakeApp("E", kItemId6, extensions::Extension::NO_FLAGS);
   InstallExtension(app6.get());
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"A", "B", "C", "D", "E", "F"}));
 }
 
@@ -2119,7 +2119,7 @@
   app_list_syncable_service()->SetAppListPreferredOrder(
       ash::AppListSortOrder::kNameAlphabetical);
   EXPECT_EQ(ash::AppListSortOrder::kNameAlphabetical, GetSortOrderFromPrefs());
-  EXPECT_EQ(GetNamesOfSortedItemsFromSyncableService(),
+  EXPECT_EQ(GetOrderedNamesFromSyncableService(),
             std::vector<std::string>({"A", "B", "C", "D"}));
 }
 
diff --git a/chrome/browser/ui/app_list/chrome_app_list_item_browsertest.cc b/chrome/browser/ui/app_list/chrome_app_list_item_browsertest.cc
index 20badb6..fbe4109 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_item_browsertest.cc
+++ b/chrome/browser/ui/app_list/chrome_app_list_item_browsertest.cc
@@ -129,7 +129,8 @@
     TestChromeAppListItem* app_item = app_item_ptr.get();
     apps.push_back(app_item);
 
-    model_updater_->AddItemToFolder(std::move(app_item_ptr), kFakeFolderId);
+    model_updater_->AddAppItemToFolder(std::move(app_item_ptr), kFakeFolderId,
+                                       /*add_from_local=*/true);
     model_updater_->SetItemName(app_item->id(), app_name);
 
     // No icon loading on creating an app item.
@@ -149,7 +150,8 @@
   auto app_item_ptr = std::make_unique<TestChromeAppListItem>(
       profile(), "AnotherAppId", model_updater_);
   TestChromeAppListItem* app_item = app_item_ptr.get();
-  model_updater_->AddItemToFolder(std::move(app_item_ptr), kFakeFolderId);
+  model_updater_->AddAppItemToFolder(std::move(app_item_ptr), kFakeFolderId,
+                                     /*add_from_local=*/true);
   model_updater_->SetItemName(app_item->id(), "AnotherApp");
 
   // Icon load happens synchronously when UI is visible.
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
index bed3bbbf..464e80c 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
+++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
@@ -52,11 +52,8 @@
     DCHECK(ash::features::IsLauncherAppSortEnabled());
 
     // Fill permanent position storage.
-    for (const auto& id_item_pair : permanent_items) {
-      const std::string& id = id_item_pair.first;
-      DCHECK(!HasId(id));
-      permanent_position_storage_.emplace(id, id_item_pair.second->position());
-    }
+    for (const auto& id_item_pair : permanent_items)
+      AddPermanentPosition(id_item_pair.first, id_item_pair.second->position());
   }
   TemporarySortManager(const TemporarySortManager&) = delete;
   TemporarySortManager& operator=(const TemporarySortManager&) = delete;
@@ -74,6 +71,12 @@
     return iter->second;
   }
 
+  void AddPermanentPosition(const std::string& id,
+                            const syncer::StringOrdinal& position) {
+    DCHECK(!HasId(id));
+    permanent_position_storage_.emplace(id, position);
+  }
+
   void SetPermanentPosition(const std::string& id,
                             const syncer::StringOrdinal& position) {
     auto iter = permanent_position_storage_.find(id);
@@ -165,9 +168,40 @@
   }
 }
 
-void ChromeAppListModelUpdater::AddItemToFolder(
+void ChromeAppListModelUpdater::AddAppItemToFolder(
     std::unique_ptr<ChromeAppListItem> app_item,
-    const std::string& folder_id) {
+    const std::string& folder_id,
+    bool add_from_local) {
+  DCHECK(!app_item->is_folder());
+  DCHECK(!app_item->is_page_break());
+
+  if (is_under_temporary_sort()) {
+    // Store `app_item`'s position before calculating a new position under the
+    // temporary sorting order.
+    DCHECK(temporary_sort_manager_->is_active());
+    temporary_sort_manager_->AddPermanentPosition(app_item->id(),
+                                                  app_item->position());
+
+    // Calculate `app_item`'s position under the temporary order.
+    syncer::StringOrdinal position_under_temporary_order;
+    bool is_successful = app_list::reorder::CalculateNewItemPosition(
+        temporary_sort_manager_->temporary_order(), *app_item.get(), GetItems(),
+        /*global_items=*/nullptr, &position_under_temporary_order);
+
+    // When the app list is under temporary sorting, local items should be
+    // ordered. Therefore `is_successful` should be true.
+    DCHECK(is_successful);
+
+    if (!is_successful) {
+      DCHECK(!position_under_temporary_order.IsValid());
+      position_under_temporary_order =
+          order_delegate_->CalculateGlobalFrontPosition();
+    }
+
+    DCHECK(position_under_temporary_order.IsValid());
+    app_item->SetChromePosition(position_under_temporary_order);
+  }
+
   std::unique_ptr<ash::AppListItemMetadata> item_data =
       app_item->CloneMetadata();
   // Add to Chrome first leave all updates to observer methods.
@@ -188,6 +222,12 @@
     ash::AppListItem* item = model_.FindItem(item_added->id());
     item->SetDefaultIcon(item_added->icon());
   }
+
+  // If the app list is under temporary sort and the new app is installed from
+  // the local device (i.e. the device on which temporary sorting is initiated),
+  // commit the temporary sorting order.
+  if (is_under_temporary_sort() && add_from_local)
+    EndTemporarySortAndTakeAction(EndAction::kCommit);
 }
 
 void ChromeAppListModelUpdater::RemoveItem(const std::string& id) {
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
index a81fc525..43a318fd 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
@@ -43,8 +43,9 @@
 
   // AppListModelUpdater:
   void AddItem(std::unique_ptr<ChromeAppListItem> app_item) override;
-  void AddItemToFolder(std::unique_ptr<ChromeAppListItem> app_item,
-                       const std::string& folder_id) override;
+  void AddAppItemToFolder(std::unique_ptr<ChromeAppListItem> app_item,
+                          const std::string& folder_id,
+                          bool add_from_local) override;
   void RemoveItem(const std::string& id) override;
   void RemoveUninstalledItem(const std::string& id) override;
   void SetStatus(ash::AppListModelStatus status) override;
diff --git a/chrome/browser/ui/app_list/reorder/app_list_reorder_delegate.h b/chrome/browser/ui/app_list/reorder/app_list_reorder_delegate.h
index a1811f8..f38f7ac 100644
--- a/chrome/browser/ui/app_list/reorder/app_list_reorder_delegate.h
+++ b/chrome/browser/ui/app_list/reorder/app_list_reorder_delegate.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_UI_APP_LIST_REORDER_APP_LIST_REORDER_DELEGATE_H_
 #define CHROME_BROWSER_UI_APP_LIST_REORDER_APP_LIST_REORDER_DELEGATE_H_
 
+#include "components/sync/model/string_ordinal.h"
+
 namespace ash {
 enum class AppListSortOrder;
 }
@@ -19,6 +21,9 @@
 
   // Sets the preferred sorting order.
   virtual void SetAppListPreferredOrder(ash::AppListSortOrder order) = 0;
+
+  // Returns the front position among all sync items.
+  virtual syncer::StringOrdinal CalculateGlobalFrontPosition() const = 0;
 };
 
 }  // namespace reorder
diff --git a/chrome/browser/ui/app_list/test/app_list_syncable_service_test_base.cc b/chrome/browser/ui/app_list/test/app_list_syncable_service_test_base.cc
index fa8955fc..1fdec79 100644
--- a/chrome/browser/ui/app_list/test/app_list_syncable_service_test_base.cc
+++ b/chrome/browser/ui/app_list/test/app_list_syncable_service_test_base.cc
@@ -80,6 +80,16 @@
 }
 
 std::vector<std::string>
+AppListSyncableServiceTestBase::GetOrderedNamesFromModelUpdater() {
+  const std::vector<std::string> ids = GetOrderedItemIdsFromModelUpdater();
+  std::vector<std::string> names;
+  for (const auto& id : ids) {
+    names.push_back(GetModelUpdater()->FindItem(id)->name());
+  }
+  return names;
+}
+
+std::vector<std::string>
 AppListSyncableServiceTestBase::GetOrderedItemIdsFromSyncableService() {
   std::vector<std::string> ids;
   app_list::AppListSyncableService* service = app_list_syncable_service();
@@ -98,7 +108,7 @@
 }
 
 std::vector<std::string>
-AppListSyncableServiceTestBase::GetNamesOfSortedItemsFromSyncableService() {
+AppListSyncableServiceTestBase::GetOrderedNamesFromSyncableService() {
   const std::vector<std::string> ids = GetOrderedItemIdsFromSyncableService();
   std::vector<std::string> names;
   for (const auto& id : ids) {
diff --git a/chrome/browser/ui/app_list/test/app_list_syncable_service_test_base.h b/chrome/browser/ui/app_list/test/app_list_syncable_service_test_base.h
index 181bdf2f..93db654 100644
--- a/chrome/browser/ui/app_list/test/app_list_syncable_service_test_base.h
+++ b/chrome/browser/ui/app_list/test/app_list_syncable_service_test_base.h
@@ -39,6 +39,9 @@
   // position.
   std::vector<std::string> GetOrderedItemIdsFromModelUpdater();
 
+  // Gets the names of the items in model updater ordered by item's ordinal.
+  std::vector<std::string> GetOrderedNamesFromModelUpdater();
+
   // Similar to `GetOrderedItemIdsFromModelUpdater()`. But items are from
   // `AppListSyncableService` and they are ordered by positions in sync data.
   // Note that an item's position in model updater could be different from that
@@ -46,7 +49,7 @@
   std::vector<std::string> GetOrderedItemIdsFromSyncableService();
 
   // Gets the names of the items ordered by the positions stored in sync data.
-  std::vector<std::string> GetNamesOfSortedItemsFromSyncableService();
+  std::vector<std::string> GetOrderedNamesFromSyncableService();
 
   // Gets the names of items ordered by the positions stored in sync data,
   // grouped in pages (as defined by page break items). Lists themselves will
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
index 89389ca..e7841b8 100644
--- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
+++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
@@ -24,9 +24,10 @@
   items_.push_back(std::move(item));
 }
 
-void FakeAppListModelUpdater::AddItemToFolder(
+void FakeAppListModelUpdater::AddAppItemToFolder(
     std::unique_ptr<ChromeAppListItem> item,
-    const std::string& folder_id) {
+    const std::string& folder_id,
+    bool add_from_local) {
   ChromeAppListItem::TestApi test_api(item.get());
   test_api.SetFolderId(folder_id);
   items_.push_back(std::move(item));
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
index 563e857e..ae31bef 100644
--- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
@@ -27,8 +27,9 @@
 
   // For AppListModel:
   void AddItem(std::unique_ptr<ChromeAppListItem> item) override;
-  void AddItemToFolder(std::unique_ptr<ChromeAppListItem> item,
-                       const std::string& folder_id) override;
+  void AddAppItemToFolder(std::unique_ptr<ChromeAppListItem> item,
+                          const std::string& folder_id,
+                          bool add_from_local) override;
   void UpdateAppItemFromSyncItem(
       app_list::AppListSyncableService::SyncItem* sync_item,
       bool update_name,
diff --git a/chrome/browser/ui/apps/chrome_app_delegate.cc b/chrome/browser/ui/apps/chrome_app_delegate.cc
index 1eb796e..926bcab 100644
--- a/chrome/browser/ui/apps/chrome_app_delegate.cc
+++ b/chrome/browser/ui/apps/chrome_app_delegate.cc
@@ -201,8 +201,10 @@
   if (keep_alive) {
     keep_alive_ = std::make_unique<ScopedKeepAlive>(
         KeepAliveOrigin::CHROME_APP_DELEGATE, KeepAliveRestartOption::DISABLED);
-    profile_keep_alive_ = std::make_unique<ScopedProfileKeepAlive>(
-        profile_, ProfileKeepAliveOrigin::kAppWindow);
+    if (!profile_->IsOffTheRecord()) {
+      profile_keep_alive_ = std::make_unique<ScopedProfileKeepAlive>(
+          profile_, ProfileKeepAliveOrigin::kAppWindow);
+    }
   }
   registrar_.Add(this,
                  chrome::NOTIFICATION_APP_TERMINATING,
@@ -376,8 +378,10 @@
   is_hidden_ = false;
   keep_alive_ = std::make_unique<ScopedKeepAlive>(
       KeepAliveOrigin::CHROME_APP_DELEGATE, KeepAliveRestartOption::DISABLED);
-  profile_keep_alive_ = std::make_unique<ScopedProfileKeepAlive>(
-      profile_, ProfileKeepAliveOrigin::kAppWindow);
+  if (!profile_->IsOffTheRecord()) {
+    profile_keep_alive_ = std::make_unique<ScopedProfileKeepAlive>(
+        profile_, ProfileKeepAliveOrigin::kAppWindow);
+  }
 }
 
 bool ChromeAppDelegate::TakeFocus(content::WebContents* web_contents,
diff --git a/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc b/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc
index 9e68329..6c320a2 100644
--- a/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc
+++ b/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc
@@ -430,39 +430,9 @@
   EXPECT_FALSE(data2->desk_id.has_value());
 }
 
-// Tests that launching a desk template creates a desk with the given name.
-IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest, LaunchEmptyDeskTemplate) {
-  const base::GUID kDeskUuid = base::GUID::GenerateRandomV4();
-  const std::u16string kDeskName(u"Test Desk Name");
-
-  auto* desks_controller = ash::DesksController::Get();
-
-  ASSERT_EQ(0, desks_controller->GetActiveDeskIndex());
-
-  auto desk_template = std::make_unique<ash::DeskTemplate>(
-      kDeskUuid.AsLowercaseString(), ash::DeskTemplateSource::kUser,
-      base::UTF16ToUTF8(kDeskName), base::Time::Now());
-  SetAndLaunchTemplate(std::move(desk_template));
-
-  EXPECT_EQ(1, desks_controller->GetActiveDeskIndex());
-  EXPECT_EQ(kDeskName, desks_controller->GetDeskName(1));
-
-  // Verify that user prefs are updated with the correct desk names. This
-  // ensures that template created desk names are preserved on restart.
-  PrefService* primary_user_prefs =
-      ash::Shell::Get()->session_controller()->GetPrimaryUserPrefService();
-  ASSERT_TRUE(primary_user_prefs);
-  const base::ListValue* desks_names =
-      primary_user_prefs->GetList(ash::prefs::kDesksNamesList);
-  const auto& desks_names_list = desks_names->GetList();
-  EXPECT_EQ(2, desks_names->GetList().size());
-  EXPECT_EQ(base::UTF16ToUTF8(kDeskName), desks_names_list[1].GetString());
-}
-
 // Tests that launching the same desk template multiple times creates desks with
 // different/incremented names.
-IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
-                       LaunchMultipleEmptyDeskTemplates) {
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest, LaunchMultipleDeskTemplates) {
   const base::GUID kDeskUuid = base::GUID::GenerateRandomV4();
   const std::u16string kDeskName(u"Test Desk Name");
 
@@ -470,6 +440,10 @@
 
   ASSERT_EQ(0, desks_controller->GetActiveDeskIndex());
 
+  // TODO(crbug.com/1273532): Note that `SetTemplate` allows setting an empty
+  // desk template which shouldn't be possible in a real workflow. Make sure a
+  // non empty desks are launched when this test is updated to use the real
+  // workflow.
   auto desk_template = std::make_unique<ash::DeskTemplate>(
       kDeskUuid.AsLowercaseString(), ash::DeskTemplateSource::kUser,
       base::UTF16ToUTF8(kDeskName), base::Time::Now());
diff --git a/chrome/browser/ui/views/location_bar/omnibox_chip_button.cc b/chrome/browser/ui/views/location_bar/omnibox_chip_button.cc
index 065999f..47a2efe 100644
--- a/chrome/browser/ui/views/location_bar/omnibox_chip_button.cc
+++ b/chrome/browser/ui/views/location_bar/omnibox_chip_button.cc
@@ -7,12 +7,16 @@
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/ui/layout_constants.h"
 #include "components/vector_icons/vector_icons.h"
+#include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/base/theme_provider.h"
 #include "ui/color/color_id.h"
 #include "ui/color/color_provider.h"
+#include "ui/gfx/color_utils.h"
 #include "ui/gfx/paint_vector_icon.h"
+#include "ui/views/background.h"
 #include "ui/views/controls/highlight_path_generator.h"
+#include "ui/views/painter.h"
 
 namespace {
 
@@ -34,9 +38,7 @@
       icon_on_(icon_on),
       icon_off_(icon_off) {
   views::InstallPillHighlightPathGenerator(this);
-  SetProminent(is_prominent);
   SetText(message);
-  SetCornerRadius(GetIconSize());
   SetHorizontalAlignment(gfx::ALIGN_LEFT);
   SetElideBehavior(gfx::ElideBehavior::FADE_TAIL);
   SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
@@ -92,6 +94,12 @@
   UpdateIconAndColors();
 }
 
+void OmniboxChipButton::UpdateBackgroundColor() {
+  SetBackground(
+      CreateBackgroundFromPainter(views::Painter::CreateSolidRoundRectPainter(
+          GetBackgroundColor(), GetIconSize())));
+}
+
 void OmniboxChipButton::AnimationEnded(const gfx::Animation* animation) {
   if (animation != animation_.get())
     return;
@@ -123,24 +131,38 @@
                 ui::ImageModel::FromVectorIcon(
                     show_blocked_icon_ ? icon_off_ : icon_on_,
                     GetTextAndIconColor(), GetIconSize(), nullptr));
-  SetBgColorOverride(GetBackgroundColor());
 }
 
 SkColor OmniboxChipButton::GetTextAndIconColor() {
   switch (theme_) {
-    case Theme::kBlue:
-      // TODO(crbug.com/1003612): ui::kColorButtonBackgroundProminent does not
-      // always represent the blue color we need, but it is OK to use for now.
-      return GetColorProvider()->GetColor(ui::kColorButtonBackgroundProminent);
-    case Theme::kGray:
+    case Theme::kBlue: {
+      // TODO(crbug.com/1274118) Instead of using constants or toolbar colors,
+      // add the chip's properties.
+      return color_utils::IsDark(
+                 GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR))
+                 ? gfx::kGoogleBlue300
+                 : gfx::kGoogleBlue600;
+    }
+    case Theme::kGray: {
       return GetThemeProvider()->GetColor(
-          ThemeProperties::COLOR_OMNIBOX_TEXT_DIMMED);
+          ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE);
+    }
   }
 }
 
 SkColor OmniboxChipButton::GetBackgroundColor() {
-  return views::style::GetColor(*this, label()->GetTextContext(),
-                                views::style::STYLE_DIALOG_BUTTON_DEFAULT);
+  SkColor active_tab_color =
+      GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR);
+
+  if (theme_ == Theme::kGray) {
+    return active_tab_color;
+  }
+
+  // TODO(crbug.com/1274118) Instead of using constants or toolbar colors, add
+  // the chip's properties.
+  return ThemeProperties::GetDefaultColor(
+      ThemeProperties::COLOR_TOOLBAR, false,
+      /*dark_mode=*/color_utils::IsDark(active_tab_color));
 }
 
 void OmniboxChipButton::SetForceExpandedForTesting(
diff --git a/chrome/browser/ui/views/location_bar/omnibox_chip_button.h b/chrome/browser/ui/views/location_bar/omnibox_chip_button.h
index deb6218..b16c1cf3 100644
--- a/chrome/browser/ui/views/location_bar/omnibox_chip_button.h
+++ b/chrome/browser/ui/views/location_bar/omnibox_chip_button.h
@@ -46,6 +46,7 @@
   // views::MdTextButton:
   gfx::Size CalculatePreferredSize() const override;
   void OnThemeChanged() override;
+  void UpdateBackgroundColor() override;
 
   // Set the button theme.
   void SetTheme(Theme theme);
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
index 15c5e9b..53c5ddb 100644
--- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
@@ -33,6 +33,7 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
+#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_header_macros.h"
@@ -291,10 +292,9 @@
   }
 }
 
-void PaymentHandlerWebFlowViewController::DidStartNavigation(
-    content::NavigationHandle* navigation_handle) {
-  if (!navigation_handle->IsSameDocument())
-    UpdateHeaderView();
+void PaymentHandlerWebFlowViewController::PrimaryPageChanged(
+    content::Page& page) {
+  UpdateHeaderView();
 }
 
 void PaymentHandlerWebFlowViewController::AddNewContents(
@@ -348,6 +348,8 @@
     return;
   }
 
+  DCHECK(FrameSupportsPayments(navigation_handle->GetRenderFrameHost()));
+
   if (first_navigation_complete_callback_) {
     std::move(first_navigation_complete_callback_)
         .Run(true, web_contents()->GetMainFrame()->GetProcess()->GetID(),
@@ -369,6 +371,13 @@
   UpdateHeaderView();
 }
 
+bool PaymentHandlerWebFlowViewController::FrameSupportsPayments(
+    content::RenderFrameHost* rfh) const {
+  return rfh && rfh->IsActive() &&
+         rfh->IsFeatureEnabled(
+             blink::mojom::PermissionsPolicyFeature::kPayment);
+}
+
 void PaymentHandlerWebFlowViewController::AbortPayment() {
   if (web_contents())
     web_contents()->Close();
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h
index c0f43625..1f3cb61 100644
--- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h
+++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h
@@ -19,6 +19,11 @@
 
 class Profile;
 
+namespace content {
+class Page;
+class RenderFrameHost;
+}  // namespace content
+
 namespace views {
 class ProgressBar;
 }
@@ -85,13 +90,14 @@
       const content::NativeWebKeyboardEvent& event) override;
 
   // content::WebContentsObserver:
-  void DidStartNavigation(
-      content::NavigationHandle* navigation_handle) override;
+  void PrimaryPageChanged(content::Page& page) override;
   void DidFinishNavigation(
       content::NavigationHandle* navigation_handle) override;
   void LoadProgressChanged(double progress) override;
   void TitleWasSet(content::NavigationEntry* entry) override;
 
+  bool FrameSupportsPayments(content::RenderFrameHost* rfh) const;
+
   void AbortPayment();
 
   DeveloperConsoleLogger log_;
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 77d70ebc6..fb7b4c05 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -56,6 +56,7 @@
 #include "chrome/browser/ui/webui/policy/policy_ui.h"
 #include "chrome/browser/ui/webui/predictors/predictors_ui.h"
 #include "chrome/browser/ui/webui/quota_internals/quota_internals_ui.h"
+#include "chrome/browser/ui/webui/segmentation_internals/segmentation_internals_ui.h"
 #include "chrome/browser/ui/webui/signin_internals_ui.h"
 #include "chrome/browser/ui/webui/support_tool_ui.h"
 #include "chrome/browser/ui/webui/sync_internals/sync_internals_ui.h"
@@ -682,6 +683,8 @@
     return &NewWebUI<QuotaInternalsUI>;
   if (url.host_piece() == safe_browsing::kChromeUISafeBrowsingHost)
     return &NewWebUI<safe_browsing::SafeBrowsingUI>;
+  if (url.host_piece() == chrome::kChromeUISegmentationInternalsHost)
+    return &NewWebUI<SegmentationInternalsUI>;
   if (url.host_piece() == chrome::kChromeUISignInInternalsHost)
     return &NewWebUI<SignInInternalsUI>;
   if (url.host_piece() == chrome::kChromeUISupervisedUserPassphrasePageHost)
diff --git a/chrome/browser/ui/webui/conflicts/conflicts_handler.cc b/chrome/browser/ui/webui/conflicts/conflicts_handler.cc
index ebb56995..d1aa0e7 100644
--- a/chrome/browser/ui/webui/conflicts/conflicts_handler.cc
+++ b/chrome/browser/ui/webui/conflicts/conflicts_handler.cc
@@ -28,12 +28,13 @@
 
 void ConflictsHandler::HandleRequestModuleList(const base::ListValue* args) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  base::Value::ConstListView args_list = args->GetList();
 
   // Make sure the JS doesn't call 'requestModuleList' more than once.
   // TODO(739291): It would be better to kill the renderer instead of the
   // browser for malformed messages.
-  CHECK_EQ(1U, args->GetList().size());
-  CHECK(args->GetString(0, &module_list_callback_id_));
+  CHECK_EQ(1U, args_list.size());
+  module_list_callback_id_ = args_list[0].GetString();  // CHECKs if not string
 
   conflicts_data_fetcher_ = ConflictsDataFetcher::Create(
       base::BindOnce(&ConflictsHandler::OnConflictsDataFetched,
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler_unittest.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler_unittest.cc
index 607ae9e..73da5e0 100644
--- a/chrome/browser/ui/webui/ntp/app_launcher_handler_unittest.cc
+++ b/chrome/browser/ui/webui/ntp/app_launcher_handler_unittest.cc
@@ -22,12 +22,15 @@
 #include "content/public/test/test_renderer_host.h"
 #include "content/public/test/test_web_ui.h"
 #include "content/public/test/web_contents_tester.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace web_app {
 
 namespace {
 
+using ::testing::Optional;
+
 constexpr char kTestAppUrl[] = "https://www.example.com/";
 constexpr char kTestManifestUrl[] = "https://www.example.com/manifest.json";
 constexpr char kMethodNameAppAdded[] = "ntp.appAdded";
@@ -143,9 +146,7 @@
     app_info->GetString(kKeyAppId, &app_id);
     EXPECT_EQ(app_id, installed_app_id);
 
-    bool is_locally_installed = false;
-    app_info->GetBoolean(kKeyIsLocallyInstalled, &is_locally_installed);
-    EXPECT_TRUE(is_locally_installed);
+    EXPECT_THAT(app_info->FindBoolPath(kKeyIsLocallyInstalled), Optional(true));
   }
 
   std::unique_ptr<content::TestWebUI> CreateTestWebUI(
diff --git a/chrome/browser/ui/webui/segmentation_internals/BUILD.gn b/chrome/browser/ui/webui/segmentation_internals/BUILD.gn
new file mode 100644
index 0000000..63869a54
--- /dev/null
+++ b/chrome/browser/ui/webui/segmentation_internals/BUILD.gn
@@ -0,0 +1,10 @@
+# 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("mojo_bindings") {
+  sources = [ "segmentation_internals.mojom" ]
+  webui_module_path = "/"
+}
diff --git a/chrome/browser/ui/webui/segmentation_internals/OWNERS b/chrome/browser/ui/webui/segmentation_internals/OWNERS
new file mode 100644
index 0000000..849263b
--- /dev/null
+++ b/chrome/browser/ui/webui/segmentation_internals/OWNERS
@@ -0,0 +1,4 @@
+file://components/segmentation_platform/OWNERS
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chrome/browser/ui/webui/segmentation_internals/segmentation_internals.mojom b/chrome/browser/ui/webui/segmentation_internals/segmentation_internals.mojom
new file mode 100644
index 0000000..5b4c0b9d
--- /dev/null
+++ b/chrome/browser/ui/webui/segmentation_internals/segmentation_internals.mojom
@@ -0,0 +1,28 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module segmentation_internals.mojom;
+
+// Encapsulates information related to a selected segment. The information
+// includes whether the segment is ready and its optimization target.
+struct SegmentData {
+  // Whether the segment is ready.
+  bool is_ready;
+
+  // Enum value from components/optimization_guide/proto/models.proto. Or -1
+  // if the optimization target is empty.
+  int32 optimization_target;
+};
+
+// Used by the WebUI page to bootstrap bidirectional communication.
+interface PageHandlerFactory {
+  // The WebUI calls this method when the page is first initialized.
+  CreatePageHandler(pending_receiver<PageHandler> handler);
+};
+
+// Browser-side handler for requests from WebUI page.
+interface PageHandler {
+  // Gets the segment result for a given key.
+  GetSegment(string key) => (SegmentData result);
+};
diff --git a/chrome/browser/ui/webui/segmentation_internals/segmentation_internals_page_handler_impl.cc b/chrome/browser/ui/webui/segmentation_internals/segmentation_internals_page_handler_impl.cc
new file mode 100644
index 0000000..cd3ff0d
--- /dev/null
+++ b/chrome/browser/ui/webui/segmentation_internals/segmentation_internals_page_handler_impl.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 "chrome/browser/ui/webui/segmentation_internals/segmentation_internals_page_handler_impl.h"
+
+#include "base/bind.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/segmentation_platform/segmentation_platform_service_factory.h"
+#include "components/segmentation_platform/public/segmentation_platform_service.h"
+
+SegmentationInternalsPageHandlerImpl::SegmentationInternalsPageHandlerImpl(
+    mojo::PendingReceiver<segmentation_internals::mojom::PageHandler> receiver,
+    Profile* profile)
+    : receiver_(this, std::move(receiver)),
+      segmentation_platform_service_(
+          segmentation_platform::SegmentationPlatformServiceFactory::
+              GetForProfile(profile)) {}
+
+SegmentationInternalsPageHandlerImpl::~SegmentationInternalsPageHandlerImpl() =
+    default;
+
+void SegmentationInternalsPageHandlerImpl::GetSegment(
+    const std::string& key,
+    GetSegmentCallback callback) {
+  segmentation_platform_service_->GetSelectedSegment(
+      key, base::BindOnce(
+               &SegmentationInternalsPageHandlerImpl::OnGetSelectedSegmentDone,
+               weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+}
+
+void SegmentationInternalsPageHandlerImpl::OnGetSelectedSegmentDone(
+    GetSegmentCallback callback,
+    const segmentation_platform::SegmentSelectionResult& result) {
+  auto segment_data = segmentation_internals::mojom::SegmentData::New();
+  segment_data->is_ready = result.is_ready;
+  segment_data->optimization_target =
+      result.segment ? result.segment.value() : -1;
+  std::move(callback).Run(std::move(segment_data));
+}
diff --git a/chrome/browser/ui/webui/segmentation_internals/segmentation_internals_page_handler_impl.h b/chrome/browser/ui/webui/segmentation_internals/segmentation_internals_page_handler_impl.h
new file mode 100644
index 0000000..9162c2f
--- /dev/null
+++ b/chrome/browser/ui/webui/segmentation_internals/segmentation_internals_page_handler_impl.h
@@ -0,0 +1,52 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SEGMENTATION_INTERNALS_SEGMENTATION_INTERNALS_PAGE_HANDLER_IMPL_H_
+#define CHROME_BROWSER_UI_WEBUI_SEGMENTATION_INTERNALS_SEGMENTATION_INTERNALS_PAGE_HANDLER_IMPL_H_
+
+#include <string>
+
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/webui/segmentation_internals/segmentation_internals.mojom.h"
+#include "components/segmentation_platform/public/segment_selection_result.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+
+class Profile;
+
+namespace segmentation_platform {
+class SegmentationPlatformService;
+}
+
+class SegmentationInternalsPageHandlerImpl
+    : public segmentation_internals::mojom::PageHandler {
+ public:
+  SegmentationInternalsPageHandlerImpl(
+      mojo::PendingReceiver<segmentation_internals::mojom::PageHandler>
+          receiver,
+      Profile* profile);
+  ~SegmentationInternalsPageHandlerImpl() override;
+
+  SegmentationInternalsPageHandlerImpl(
+      const SegmentationInternalsPageHandlerImpl&) = delete;
+  SegmentationInternalsPageHandlerImpl& operator=(
+      const SegmentationInternalsPageHandlerImpl&) = delete;
+
+  // segmentation_internals::mojom::PageHandler:
+  void GetSegment(const std::string& key, GetSegmentCallback callback) override;
+
+ private:
+  // Called when segment result is retrieved.
+  void OnGetSelectedSegmentDone(
+      GetSegmentCallback callback,
+      const segmentation_platform::SegmentSelectionResult& result);
+
+  mojo::Receiver<segmentation_internals::mojom::PageHandler> receiver_;
+  segmentation_platform::SegmentationPlatformService*
+      segmentation_platform_service_;
+
+  base::WeakPtrFactory<SegmentationInternalsPageHandlerImpl> weak_ptr_factory_{
+      this};
+};
+
+#endif  // CHROME_BROWSER_UI_WEBUI_SEGMENTATION_INTERNALS_SEGMENTATION_INTERNALS_PAGE_HANDLER_IMPL_H_
diff --git a/chrome/browser/ui/webui/segmentation_internals/segmentation_internals_ui.cc b/chrome/browser/ui/webui/segmentation_internals/segmentation_internals_ui.cc
new file mode 100644
index 0000000..62210ac
--- /dev/null
+++ b/chrome/browser/ui/webui/segmentation_internals/segmentation_internals_ui.cc
@@ -0,0 +1,49 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/segmentation_internals/segmentation_internals_ui.h"
+
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/segmentation_internals/segmentation_internals_page_handler_impl.h"
+#include "chrome/browser/ui/webui/webui_util.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/grit/segmentation_internals_resources.h"
+#include "chrome/grit/segmentation_internals_resources_map.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui_data_source.h"
+
+SegmentationInternalsUI::SegmentationInternalsUI(content::WebUI* web_ui)
+    : MojoWebUIController(web_ui, /*enable_chrome_send=*/true) {
+  profile_ = Profile::FromWebUI(web_ui);
+  auto source = base::WrapUnique(content::WebUIDataSource::Create(
+      chrome::kChromeUISegmentationInternalsHost));
+  webui::SetupWebUIDataSource(
+      source.get(),
+      base::make_span(kSegmentationInternalsResources,
+                      kSegmentationInternalsResourcesSize),
+      IDR_SEGMENTATION_INTERNALS_SEGMENTATION_INTERNALS_HTML);
+
+  content::BrowserContext* browser_context =
+      web_ui->GetWebContents()->GetBrowserContext();
+  content::WebUIDataSource::Add(browser_context, source.release());
+}
+
+SegmentationInternalsUI::~SegmentationInternalsUI() = default;
+
+void SegmentationInternalsUI::BindInterface(
+    mojo::PendingReceiver<segmentation_internals::mojom::PageHandlerFactory>
+        receiver) {
+  segmentation_internals_page_factory_receiver_.reset();
+  segmentation_internals_page_factory_receiver_.Bind(std::move(receiver));
+}
+
+void SegmentationInternalsUI::CreatePageHandler(
+    mojo::PendingReceiver<segmentation_internals::mojom::PageHandler>
+        receiver) {
+  segmentation_internals_page_handler_ =
+      std::make_unique<SegmentationInternalsPageHandlerImpl>(
+          std::move(receiver), profile_);
+}
+
+WEB_UI_CONTROLLER_TYPE_IMPL(SegmentationInternalsUI)
diff --git a/chrome/browser/ui/webui/segmentation_internals/segmentation_internals_ui.h b/chrome/browser/ui/webui/segmentation_internals/segmentation_internals_ui.h
new file mode 100644
index 0000000..0724380a
--- /dev/null
+++ b/chrome/browser/ui/webui/segmentation_internals/segmentation_internals_ui.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_BROWSER_UI_WEBUI_SEGMENTATION_INTERNALS_SEGMENTATION_INTERNALS_UI_H_
+#define CHROME_BROWSER_UI_WEBUI_SEGMENTATION_INTERNALS_SEGMENTATION_INTERNALS_UI_H_
+
+#include "chrome/browser/ui/webui/segmentation_internals/segmentation_internals.mojom.h"  // nogncheck
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "ui/webui/mojo_web_ui_controller.h"
+
+class Profile;
+class SegmentationInternalsPageHandlerImpl;
+
+// The WebUI controller for chrome://segmentation-internals.
+class SegmentationInternalsUI
+    : public ui::MojoWebUIController,
+      public segmentation_internals::mojom::PageHandlerFactory {
+ public:
+  explicit SegmentationInternalsUI(content::WebUI* web_ui);
+  ~SegmentationInternalsUI() override;
+
+  SegmentationInternalsUI(const SegmentationInternalsUI&) = delete;
+  SegmentationInternalsUI& operator=(const SegmentationInternalsUI&) = delete;
+
+  void BindInterface(
+      mojo::PendingReceiver<segmentation_internals::mojom::PageHandlerFactory>
+          receiver);
+
+ private:
+  // segmentation_internals::mojom::PageHandlerFactory impls.
+  void CreatePageHandler(
+      mojo::PendingReceiver<segmentation_internals::mojom::PageHandler>
+          receiver) override;
+
+  Profile* profile_;
+  std::unique_ptr<SegmentationInternalsPageHandlerImpl>
+      segmentation_internals_page_handler_;
+  mojo::Receiver<segmentation_internals::mojom::PageHandlerFactory>
+      segmentation_internals_page_factory_receiver_{this};
+
+  WEB_UI_CONTROLLER_TYPE_DECL();
+};
+
+#endif  // CHROME_BROWSER_UI_WEBUI_SEGMENTATION_INTERNALS_SEGMENTATION_INTERNALS_UI_H_
diff --git a/chrome/browser/web_applications/test/profile_test_helper.cc b/chrome/browser/web_applications/test/profile_test_helper.cc
index f7c6f30..f4feb8f 100644
--- a/chrome/browser/web_applications/test/profile_test_helper.cc
+++ b/chrome/browser/web_applications/test/profile_test_helper.cc
@@ -58,8 +58,7 @@
     base::test::ScopedFeatureList* scoped_feature_list) {
   if (crosapi_state == web_app::test::CrosapiParam::kEnabled) {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-    scoped_feature_list->InitWithFeatures(
-        {chromeos::features::kLacrosSupport, features::kWebAppsCrosapi}, {});
+    scoped_feature_list->InitAndEnableFeature(features::kWebAppsCrosapi);
 #else
     NOTREACHED();
 #endif
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index a06ea438..19f1645 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1638251560-e64f3a70de4c4b4e962a792fa6d7e0b8c16f57a9.profdata
+chrome-mac-main-1638273499-9a8a113fdf615ddf51f5fe557de37e22b4c324aa.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index b14977c1..acb206d 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1638251560-b3e4b41386637f0ea327f46072d288f22733da1c.profdata
+chrome-win32-main-1638284357-9091a0b0a731132318f602547aa6d1e89c2e5a90.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 43da7d2..530facd 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1638262651-1869b44a7127e397854e6700c39af4fd2000a03d.profdata
+chrome-win64-main-1638284357-02a5a3874c55ec94c8ae9fd120b29a58c5e6dc7b.profdata
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni
index 8df2ead..645a7b0 100644
--- a/chrome/chrome_paks.gni
+++ b/chrome/chrome_paks.gni
@@ -95,6 +95,7 @@
       "$root_gen_dir/chrome/browser_resources.pak",
       "$root_gen_dir/chrome/chrome_unscaled_resources.pak",
       "$root_gen_dir/chrome/common_resources.pak",
+      "$root_gen_dir/chrome/segmentation_internals_resources.pak",
       "$root_gen_dir/components/autofill/core/browser/autofill_address_rewriter_resources.pak",
       "$root_gen_dir/components/components_resources.pak",
       "$root_gen_dir/content/content_resources.pak",
@@ -110,6 +111,7 @@
       "//base/tracing/protos:chrome_track_event_resources",
       "//chrome/app/theme:chrome_unscaled_resources",
       "//chrome/browser:resources",
+      "//chrome/browser/resources/segmentation_internals:resources",
       "//chrome/common:resources",
       "//components/autofill/core/browser:autofill_address_rewriter_resources",
       "//components/resources",
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc
index 3b52993..6297db0 100644
--- a/chrome/common/webui_url_constants.cc
+++ b/chrome/common/webui_url_constants.cc
@@ -161,6 +161,7 @@
 const char kChromeUIRestartURL[] = "chrome://restart/";
 const char kChromeUISafetyPixelbookURL[] = "https://g.co/Pixelbook/legal";
 const char kChromeUISafetyPixelSlateURL[] = "https://g.co/PixelSlate/legal";
+const char kChromeUISegmentationInternalsHost[] = "segmentation-internals";
 #if BUILDFLAG(ENABLE_SESSION_SERVICE)
 const char kChromeUISessionServiceInternalsPath[] = "session-service";
 #endif
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h
index de6e89e..a76df7b0 100644
--- a/chrome/common/webui_url_constants.h
+++ b/chrome/common/webui_url_constants.h
@@ -162,6 +162,7 @@
 extern const char kChromeUIRestartURL[];
 extern const char kChromeUISafetyPixelbookURL[];
 extern const char kChromeUISafetyPixelSlateURL[];
+extern const char kChromeUISegmentationInternalsHost[];
 #if BUILDFLAG(ENABLE_SESSION_SERVICE)
 extern const char kChromeUISessionServiceInternalsPath[];
 #endif
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 767b1d1..c4c8857 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1598,6 +1598,7 @@
       "../browser/media/webrtc/capture_handle_browsertest.cc",
       "../browser/media/webrtc/conditional_focus_browsertest.cc",
       "../browser/media/webrtc/media_stream_devices_controller_browsertest.cc",
+      "../browser/media/webrtc/region_capture_browsertest.cc",
       "../browser/media/webrtc/test_stats_dictionary_unittest.cc",
       "../browser/media/webrtc/webrtc_apprtc_browsertest.cc",
       "../browser/media/webrtc/webrtc_browsertest_perf.cc",
@@ -3217,6 +3218,7 @@
         "../browser/ash/login/saml/test_client_cert_saml_idp_mixin.h",
         "../browser/ash/login/screens/app_downloading_screen_browsertest.cc",
         "../browser/ash/login/screens/assistant_optin_flow_screen_browsertest.cc",
+        "../browser/ash/login/screens/consolidated_consent_screen_browsertest.cc",
         "../browser/ash/login/screens/edu_coexistence_login_browsertest.cc",
         "../browser/ash/login/screens/family_link_notice_browsertest.cc",
         "../browser/ash/login/screens/fingerprint_setup_browsertest.cc",
diff --git a/chrome/test/base/extension_js_browser_test.cc b/chrome/test/base/extension_js_browser_test.cc
index 28ff1d3..7427ae5 100644
--- a/chrome/test/base/extension_js_browser_test.cc
+++ b/chrome/test/base/extension_js_browser_test.cc
@@ -78,9 +78,9 @@
   CHECK_EQ(base::Value::Type::DICTIONARY, value_result->type());
   base::DictionaryValue* dict_value =
       static_cast<base::DictionaryValue*>(value_result.get());
-  bool test_result;
+
   std::string test_result_message;
-  CHECK(dict_value->GetBoolean("result", &test_result));
+  bool test_result = dict_value->FindBoolKey("result").value();
   CHECK(dict_value->GetString("message", &test_result_message));
   if (!test_result_message.empty())
     ADD_FAILURE() << test_result_message;
diff --git a/chrome/test/data/webrtc/region_capture_embedded.html b/chrome/test/data/webrtc/region_capture_embedded.html
new file mode 100644
index 0000000..04a1681
--- /dev/null
+++ b/chrome/test/data/webrtc/region_capture_embedded.html
@@ -0,0 +1,76 @@
+<html>
+  <head>
+    <link rel="icon" href="data:," />
+    <script>
+      "use strict";
+
+      let capturedStream;
+      let capturedVideoTrack;
+
+      async function startCapture() {
+        if (capturedStream) {
+          window.domAutomationController.send("error-multiple-embedded-captures");
+          return;
+        }
+
+        try {
+          capturedStream = await navigator.mediaDevices.getDisplayMedia();
+          [capturedVideoTrack] = capturedStream.getVideoTracks();
+          window.domAutomationController.send("embedded-capture-success");
+        } catch (e) {
+          window.domAutomationController.send("embedded-capture-failure");
+        }
+      }
+
+      async function produceCropId() {
+        const div = document.getElementById("div");
+        try {
+          const cropId = await navigator.mediaDevices.produceCropId(div);
+          // Explicitly note emptiness to make it clear this is genuine emptiness
+          // and not a test error on the C++/JS boundary.
+          window.domAutomationController.send(
+              cropId == "" ? "empty-crop-id" : cropId);
+        } catch (e) {
+          window.domAutomationController.send("produce-crop-id-embedded-failure");
+        }
+      }
+
+      async function crop(cropId) {
+        if (!capturedVideoTrack) {
+          window.domAutomationController.send("embedded-crop-error-no-track");
+          return;
+        }
+
+        try {
+          await capturedVideoTrack.cropTo(cropId);
+          window.domAutomationController.send("embedded-crop-success");
+          return;
+        } catch (e) {
+          window.domAutomationController.send("embedded-crop-error");
+        }
+      }
+
+      window.addEventListener("message", (event) => {
+        if (event.data == "start-capture") {
+          startCapture();
+        } else if (event.data == "produce-crop-id") {
+          produceCropId();
+        } else if (event.data.startsWith("crop-to:")) {
+          crop(event.data.substr("crop-to:".length));
+        } else {
+          window.domAutomationController.send("unrecognized-message");
+        }
+      });
+
+      function reportEmbeddingSuccess() {
+        window.domAutomationController.send("embedding-done");
+      }
+    </script>
+  </head>
+  <body onload="reportEmbeddingSuccess();">
+    <div id="div">
+      <!-- This DIV is just a convenient target for produceCropId. -->
+      <h1>Region Capture Test - Page 1 (Embedded)</h1>
+    </div>
+  </body>
+</html>
diff --git a/chrome/test/data/webrtc/region_capture_main.html b/chrome/test/data/webrtc/region_capture_main.html
new file mode 100644
index 0000000..a421b1f
--- /dev/null
+++ b/chrome/test/data/webrtc/region_capture_main.html
@@ -0,0 +1,81 @@
+<html>
+  <head>
+    <!-- The test scans for which source to share according to the title. -->
+    <title>Region Capture Test - Page 1 (Main)</title>
+    <link rel="icon" href="data:," />
+    <script>
+      "use strict";
+
+      let capturedStream;
+      let capturedVideoTrack;
+
+      function startEmbeddingFrame(url) {
+        document.getElementById("embedded_frame").src = url;
+        // window.domAutomationController.send() called by embedded page.
+      }
+
+      async function startCapture() {
+        if (capturedStream) {
+          window.domAutomationController.send("error-multiple-captures");
+          return;
+        }
+
+        try {
+          capturedStream = await navigator.mediaDevices.getDisplayMedia();
+          [capturedVideoTrack] = capturedStream.getVideoTracks();
+          window.domAutomationController.send("capture-success");
+        } catch (e) {
+          window.domAutomationController.send("capture-failure");
+        }
+      }
+
+      function startCaptureFromEmbeddedFrame() {
+        document
+          .getElementById("embedded_frame")
+          .contentWindow.postMessage("start-capture", "*");
+        // window.domAutomationController.send() called by embedded page.
+      }
+
+      async function produceCropId(targetFrame) {
+        if (targetFrame == "top") {
+          const div = document.getElementById("div");
+          const cropId = await navigator.mediaDevices.produceCropId(div);
+          // Explicitly note emptiness so as to make it clear that this is
+          // genuine emptiness and not a test error on the C++/JS boundary.
+          window.domAutomationController.send(
+              cropId == "" ? "empty-crop-id" : cropId);
+        } else {
+          document
+            .getElementById("embedded_frame")
+            .contentWindow.postMessage("produce-crop-id", "*");
+          // window.domAutomationController.send() called by embedded page.
+        }
+      }
+
+      async function cropTo(cropId) {
+        if (capturedVideoTrack) {
+          try {
+            await capturedVideoTrack.cropTo(cropId);
+            window.domAutomationController.send("top-level-crop-success");
+            return;
+          } catch (e) {
+            window.domAutomationController.send("top-level-crop-error");
+          }
+        } else {
+          document
+            .getElementById("embedded_frame")
+            .contentWindow.postMessage("crop-to:" + cropId, "*");
+          // window.domAutomationController.send() called by embedded page.
+        }
+      }
+    </script>
+  </head>
+  <body>
+    <div id="div">
+      <!-- This DIV is just a convenient target for produceCropId. -->
+      <h1>Region Capture Test - Page 1 (Main)</h1>
+      <br/>
+    </div>
+    <iframe id="embedded_frame" allow="display-capture *"></iframe>
+  </body>
+</html>
diff --git a/chrome/test/data/webrtc/region_capture_other_embedded.html b/chrome/test/data/webrtc/region_capture_other_embedded.html
new file mode 100644
index 0000000..afc1d69
--- /dev/null
+++ b/chrome/test/data/webrtc/region_capture_other_embedded.html
@@ -0,0 +1,39 @@
+<html>
+  <head>
+    <link rel="icon" href="data:," />
+    <script>
+      "use strict";
+
+      function reportEmbeddingSuccess() {
+        window.domAutomationController.send("embedding-done");
+      }
+
+      async function produceCropId() {
+        const div = document.getElementById("div");
+        try {
+          const cropId = await navigator.mediaDevices.produceCropId(div);
+          // Explicitly note emptiness to make it clear this is genuine emptiness
+          // and not a test error on the C++/JS boundary.
+          window.domAutomationController.send(
+              cropId == "" ? "empty-crop-id" : cropId);
+        } catch (e) {
+          window.domAutomationController.send("produce-crop-id-embedded-failure");
+        }
+      }
+
+      window.addEventListener("message", (event) => {
+        if (event.data == "produce-crop-id") {
+          produceCropId();
+        } else {
+          window.domAutomationController.send("unrecognized-message");
+        }
+      });
+    </script>
+  </head>
+  <body onload="reportEmbeddingSuccess();">
+    <div id="div">
+      <!-- This DIV is just a convenient target for produceCropId. -->
+      <h1>Region Capture Test - Page 2 (Embedded)</h1>
+    </div>
+  </body>
+</html>
diff --git a/chrome/test/data/webrtc/region_capture_other_main.html b/chrome/test/data/webrtc/region_capture_other_main.html
new file mode 100644
index 0000000..38b4efc5
--- /dev/null
+++ b/chrome/test/data/webrtc/region_capture_other_main.html
@@ -0,0 +1,39 @@
+<html>
+  <head>
+    <!-- The test scans for which source to share according to the title. -->
+    <title>Region Capture Test - Page 2 (Main)</title>
+    <link rel="icon" href="data:," />
+    <script>
+      "use strict";
+
+      function startEmbeddingFrame(url) {
+        document.getElementById("embedded_frame").src = url;
+        // window.domAutomationController.send() called by embedded page.
+      }
+
+      async function produceCropId(targetFrame) {
+        if (targetFrame == "top") {
+          const div = document.getElementById("div");
+          const cropId = await navigator.mediaDevices.produceCropId(div);
+          // Explicitly note emptiness so as to make it clear that this is
+          // genuine emptiness and not a test error on the C++/JS boundary.
+          window.domAutomationController.send(
+              cropId == "" ? "empty-crop-id" : cropId);
+        } else {
+          document
+            .getElementById("embedded_frame")
+            .contentWindow.postMessage("produce-crop-id", "*");
+          // window.domAutomationController.send() called by embedded page.
+        }
+      }
+    </script>
+  </head>
+  <body>
+    <div id="div">
+      <!-- This DIV is just a convenient target for produceCropId. -->
+      <h1>Region Capture Test - Page 2 (Main)</h1>
+      <br/>
+      <iframe id="embedded_frame" allow="display-capture *"></iframe>
+    </div>
+  </body>
+</html>
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc
index 1f49591..6b1f7fe 100644
--- a/chromecast/browser/cast_browser_main_parts.cc
+++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -743,11 +743,6 @@
 
   cast_browser_process_->cast_service()->Start();
 
-  if (parameters_.ui_task) {
-    std::move(parameters_.ui_task).Run();
-    run_message_loop_ = false;
-  }
-
   return content::RESULT_CODE_NORMAL_EXIT;
 }
 
@@ -776,16 +771,10 @@
 #if defined(OS_ANDROID)
   // Android does not use native main MessageLoop.
   NOTREACHED();
-#else
-  if (run_message_loop_) {
-#if !defined(OS_FUCHSIA)
-    // Fuchsia doesn't have signals.
-    RegisterClosureOnSignal(run_loop->QuitClosure());
+#elif !defined(OS_FUCHSIA)
+  // Fuchsia doesn't have signals.
+  RegisterClosureOnSignal(run_loop->QuitClosure());
 #endif  // !defined(OS_FUCHSIA)
-  } else {
-    run_loop.reset();
-  }
-#endif
 }
 
 void CastBrowserMainParts::PostMainMessageLoopRun() {
diff --git a/chromecast/browser/cast_browser_main_parts.h b/chromecast/browser/cast_browser_main_parts.h
index d9d2de35..bad446a 100644
--- a/chromecast/browser/cast_browser_main_parts.h
+++ b/chromecast/browser/cast_browser_main_parts.h
@@ -175,8 +175,6 @@
   // Only used when running with --enable-ui-devtools.
   std::unique_ptr<CastUIDevTools> ui_devtools_;
 #endif  // defined(USE_AURA) && !defined(OS_FUCHSIA)
-
-  bool run_message_loop_ = true;
 };
 
 }  // namespace shell
diff --git a/chromeos/lacros/BUILD.gn b/chromeos/lacros/BUILD.gn
index 11395471..13baf28 100644
--- a/chromeos/lacros/BUILD.gn
+++ b/chromeos/lacros/BUILD.gn
@@ -22,21 +22,12 @@
     "//build:chromeos_buildflags",
     "//chromeos/crosapi/cpp",
     "//chromeos/crosapi/mojom",
-    "//chromeos/dbus/constants",
-    "//chromeos/dbus/init",
-    "//chromeos/dbus/missive",
-    "//chromeos/dbus/permission_broker",
     "//chromeos/process_proxy",
     "//chromeos/startup",
-    "//dbus",
     "//mojo/public/cpp/bindings",
     "//ui/native_theme",
   ]
   sources = [
-    "lacros_dbus_helper.cc",
-    "lacros_dbus_helper.h",
-    "lacros_dbus_thread_manager.cc",
-    "lacros_dbus_thread_manager.h",
     "lacros_service.cc",
     "lacros_service.h",
     "lacros_service_never_blocking_state.cc",
diff --git a/chromeos/lacros/DEPS b/chromeos/lacros/DEPS
index 235c5679..c18b110 100644
--- a/chromeos/lacros/DEPS
+++ b/chromeos/lacros/DEPS
@@ -5,6 +5,5 @@
   "-chrome",
   "-content",
 
-  "+dbus",
   "+ui/native_theme",
 ]
diff --git a/chromeos/lacros/dbus/BUILD.gn b/chromeos/lacros/dbus/BUILD.gn
new file mode 100644
index 0000000..89faf18
--- /dev/null
+++ b/chromeos/lacros/dbus/BUILD.gn
@@ -0,0 +1,25 @@
+# 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("//build/config/chromeos/ui_mode.gni")
+
+assert(is_chromeos_lacros)
+
+source_set("dbus") {
+  deps = [
+    "//base",
+    "//chromeos/dbus/constants",
+    "//chromeos/dbus/init",
+    "//chromeos/dbus/missive",
+    "//chromeos/dbus/permission_broker",
+    "//dbus",
+    "//device/bluetooth",
+  ]
+  sources = [
+    "lacros_dbus_helper.cc",
+    "lacros_dbus_helper.h",
+    "lacros_dbus_thread_manager.cc",
+    "lacros_dbus_thread_manager.h",
+  ]
+}
diff --git a/chromeos/lacros/dbus/DEPS b/chromeos/lacros/dbus/DEPS
new file mode 100644
index 0000000..6f06cc5a
--- /dev/null
+++ b/chromeos/lacros/dbus/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+  "-chrome",
+  "-content",
+
+  "+dbus",
+]
diff --git a/chromeos/lacros/dbus/README.md b/chromeos/lacros/dbus/README.md
new file mode 100644
index 0000000..a07b20a
--- /dev/null
+++ b/chromeos/lacros/dbus/README.md
@@ -0,0 +1,4 @@
+This directory contains lacros-specific D-Bus initialization, shutdown, and
+utility code. Separation from //chromeos/lacros is necessary because this code
+can call D-Bus managers, which in turn may depend on //chromeos/lacros (for
+crosapi), whereas the the converse is disallowed.
diff --git a/chromeos/lacros/lacros_dbus_helper.cc b/chromeos/lacros/dbus/lacros_dbus_helper.cc
similarity index 89%
rename from chromeos/lacros/lacros_dbus_helper.cc
rename to chromeos/lacros/dbus/lacros_dbus_helper.cc
index a10c9f9b..e54f539f 100644
--- a/chromeos/lacros/lacros_dbus_helper.cc
+++ b/chromeos/lacros/dbus/lacros_dbus_helper.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/lacros/lacros_dbus_helper.h"
+#include "chromeos/lacros/dbus/lacros_dbus_helper.h"
 
 #include "chromeos/dbus/init/initialize_dbus_client.h"
 #include "chromeos/dbus/missive/missive_client.h"
 #include "chromeos/dbus/permission_broker/permission_broker_client.h"
-#include "chromeos/lacros/lacros_dbus_thread_manager.h"
+#include "chromeos/lacros/dbus/lacros_dbus_thread_manager.h"
 
 namespace chromeos {
 
diff --git a/chromeos/lacros/lacros_dbus_helper.h b/chromeos/lacros/dbus/lacros_dbus_helper.h
similarity index 77%
rename from chromeos/lacros/lacros_dbus_helper.h
rename to chromeos/lacros/dbus/lacros_dbus_helper.h
index 00b6c6f3..09ad6432 100644
--- a/chromeos/lacros/lacros_dbus_helper.h
+++ b/chromeos/lacros/dbus/lacros_dbus_helper.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_LACROS_LACROS_DBUS_HELPER_H_
-#define CHROMEOS_LACROS_LACROS_DBUS_HELPER_H_
+#ifndef CHROMEOS_LACROS_DBUS_LACROS_DBUS_HELPER_H_
+#define CHROMEOS_LACROS_DBUS_LACROS_DBUS_HELPER_H_
 
 #include "base/component_export.h"
 
@@ -17,4 +17,4 @@
 
 }  // namespace chromeos
 
-#endif  // CHROMEOS_LACROS_LACROS_DBUS_HELPER_H_
+#endif  // CHROMEOS_LACROS_DBUS_LACROS_DBUS_HELPER_H_
diff --git a/chromeos/lacros/lacros_dbus_thread_manager.cc b/chromeos/lacros/dbus/lacros_dbus_thread_manager.cc
similarity index 95%
rename from chromeos/lacros/lacros_dbus_thread_manager.cc
rename to chromeos/lacros/dbus/lacros_dbus_thread_manager.cc
index 7378a97..6085624d 100644
--- a/chromeos/lacros/lacros_dbus_thread_manager.cc
+++ b/chromeos/lacros/dbus/lacros_dbus_thread_manager.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/lacros/lacros_dbus_thread_manager.h"
+#include "chromeos/lacros/dbus/lacros_dbus_thread_manager.h"
 
 #include "base/logging.h"
 
diff --git a/chromeos/lacros/lacros_dbus_thread_manager.h b/chromeos/lacros/dbus/lacros_dbus_thread_manager.h
similarity index 88%
rename from chromeos/lacros/lacros_dbus_thread_manager.h
rename to chromeos/lacros/dbus/lacros_dbus_thread_manager.h
index f006a07..e417079 100644
--- a/chromeos/lacros/lacros_dbus_thread_manager.h
+++ b/chromeos/lacros/dbus/lacros_dbus_thread_manager.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_LACROS_LACROS_DBUS_THREAD_MANAGER_H_
-#define CHROMEOS_LACROS_LACROS_DBUS_THREAD_MANAGER_H_
+#ifndef CHROMEOS_LACROS_DBUS_LACROS_DBUS_THREAD_MANAGER_H_
+#define CHROMEOS_LACROS_DBUS_LACROS_DBUS_THREAD_MANAGER_H_
 
 #include "base/component_export.h"
 #include "chromeos/dbus/init/dbus_thread_manager_base.h"
@@ -41,4 +41,4 @@
 
 }  // namespace chromeos
 
-#endif  // CHROMEOS_LACROS_LACROS_DBUS_THREAD_MANAGER_H_
+#endif  // CHROMEOS_LACROS_DBUS_LACROS_DBUS_THREAD_MANAGER_H_
diff --git a/chromeos/profiles/orderfile.newest.txt b/chromeos/profiles/orderfile.newest.txt
index e05de12..54e50b0 100644
--- a/chromeos/profiles/orderfile.newest.txt
+++ b/chromeos/profiles/orderfile.newest.txt
@@ -1 +1 @@
-chromeos-chrome-orderfile-field-97-4669.0-1635154811-benchmark-97.0.4666.0-r1.orderfile.xz
+chromeos-chrome-orderfile-field-97-4685.4-1636370490-benchmark-97.0.4666.0-r1.orderfile.xz
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 84084f3..b7f2736 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -2093,11 +2093,11 @@
 }
 
 bool PersonalDataManager::ShouldShowCardsFromAccountOption() const {
-// The feature is only for Linux, Windows and Mac.
+// The feature is only for Linux, Windows, Mac, and Fuchsia.
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
-#if (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) || defined(OS_WIN) || \
-    defined(OS_APPLE)
+#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) || defined(OS_WIN) || \
+    defined(OS_APPLE) || defined(OS_FUCHSIA)
   // This option should only be shown for users that have not enabled the Sync
   // Feature and that have server credit cards available.
   if (!sync_service_ || sync_service_->IsSyncFeatureEnabled() ||
@@ -2118,8 +2118,8 @@
   return !is_opted_in;
 #else
   return false;
-#endif  // #if (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) ||
-        // defined(OS_WIN) || defined(OS_APPLE)
+#endif  // #if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) ||
+        // defined(OS_WIN) || defined(OS_APPLE) || defined(OS_FUCHSIA)
 }
 
 void PersonalDataManager::OnUserAcceptedCardsFromAccountOption() {
diff --git a/components/blocked_content/popup_blocker_tab_helper_unittest.cc b/components/blocked_content/popup_blocker_tab_helper_unittest.cc
index 7377c1e..a8cf87f8 100644
--- a/components/blocked_content/popup_blocker_tab_helper_unittest.cc
+++ b/components/blocked_content/popup_blocker_tab_helper_unittest.cc
@@ -51,13 +51,17 @@
 
 class PopupBlockerTabHelperTest : public content::RenderViewHostTestHarness {
  public:
+  PopupBlockerTabHelperTest() {
+    // Make sure the SafeBrowsingTriggeredPopupBlocker is not created.
+    // This needs to be done as early as possible to avoid tsan data races
+    // caused by other threads trying to access the feature list.
+    feature_list_.InitAndDisableFeature(kAbusiveExperienceEnforce);
+  }
   ~PopupBlockerTabHelperTest() override { settings_map_->ShutdownOnUIThread(); }
 
   // content::RenderViewHostTestHarness:
   void SetUp() override {
     content::RenderViewHostTestHarness::SetUp();
-    // Make sure the SafeBrowsingTriggeredPopupBlocker is not created.
-    feature_list_.InitAndDisableFeature(kAbusiveExperienceEnforce);
 
     HostContentSettingsMap::RegisterProfilePrefs(pref_service_.registry());
     settings_map_ = base::MakeRefCounted<HostContentSettingsMap>(
diff --git a/components/browsing_data/content/file_system_helper.cc b/components/browsing_data/content/file_system_helper.cc
index 8a3d96c..5245b71 100644
--- a/components/browsing_data/content/file_system_helper.cc
+++ b/components/browsing_data/content/file_system_helper.cc
@@ -62,8 +62,9 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   file_task_runner()->PostTask(
       FROM_HERE,
-      base::BindOnce(&FileSystemHelper::DeleteFileSystemOriginInFileThread,
-                     this, origin));
+      base::BindOnce(
+          &FileSystemHelper::DeleteFileSystemForStorageKeyInFileThread, this,
+          blink::StorageKey(origin)));
   native_io_context_->DeleteStorageKeyData(blink::StorageKey(origin),
                                            base::DoNothing());
 }
@@ -101,14 +102,10 @@
       FROM_HERE, base::BindOnce(std::move(callback), result));
 }
 
-// TODO(https://crbug.com/1254031): Refactor DeleteFileSystemOriginInFileThread
-// to replace url::Origin parameter with blink::StorageKey; replace in-line
-// conversion to StorageKey below with parameter
-void FileSystemHelper::DeleteFileSystemOriginInFileThread(
-    const url::Origin& origin) {
+void FileSystemHelper::DeleteFileSystemForStorageKeyInFileThread(
+    const blink::StorageKey& storage_key) {
   DCHECK(file_task_runner()->RunsTasksInCurrentSequence());
-  filesystem_context_->DeleteDataForStorageKeyOnFileTaskRunner(
-      blink::StorageKey(origin));
+  filesystem_context_->DeleteDataForStorageKeyOnFileTaskRunner(storage_key);
 }
 
 void FileSystemHelper::DidFetchFileSystemInfo(
diff --git a/components/browsing_data/content/file_system_helper.h b/components/browsing_data/content/file_system_helper.h
index ad2acde..af5bfb6 100644
--- a/components/browsing_data/content/file_system_helper.h
+++ b/components/browsing_data/content/file_system_helper.h
@@ -101,9 +101,10 @@
   // task runner.
   void FetchFileSystemInfoInFileThread(FetchCallback callback);
 
-  // Deletes all file systems associated with |origin|. This must be called on
-  // the file task runner.
-  void DeleteFileSystemOriginInFileThread(const url::Origin& origin);
+  // Deletes all file systems associated with `storage_key`. This must be called
+  // on the file task runner.
+  void DeleteFileSystemForStorageKeyInFileThread(
+      const blink::StorageKey& storage_key);
 
   // Called when FetchFileSystemInfoInFileThread completes and starts fetching
   // the NativeIOData.
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json
index 23c84ca..0e72e6d9 100644
--- a/components/certificate_transparency/data/log_list.json
+++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@
 {
-  "version": "4.43",
-  "log_list_timestamp": "2021-11-29T01:34:01Z",
+  "version": "4.44",
+  "log_list_timestamp": "2021-11-30T01:34:09Z",
   "operators": [
     {
       "name": "Google",
diff --git a/components/content_settings/core/browser/website_settings_registry.cc b/components/content_settings/core/browser/website_settings_registry.cc
index 45cc406..99e460e 100644
--- a/components/content_settings/core/browser/website_settings_registry.cc
+++ b/components/content_settings/core/browser/website_settings_registry.cc
@@ -93,7 +93,6 @@
 #elif defined(OS_FUCHSIA)
   if (!(platform & PLATFORM_FUCHSIA))
     return nullptr;
-  sync_status = WebsiteSettingsInfo::UNSYNCABLE;
 #else
 #error "Unsupported platform"
 #endif
diff --git a/components/cronet/host_cache_persistence_manager.cc b/components/cronet/host_cache_persistence_manager.cc
index 00b9d1f..dcaf6c10 100644
--- a/components/cronet/host_cache_persistence_manager.cc
+++ b/components/cronet/host_cache_persistence_manager.cc
@@ -79,9 +79,9 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   net_log_.AddEvent(net::NetLogEventType::HOST_CACHE_PREF_WRITE);
-  base::ListValue value;
-  cache_->GetAsListValue(&value, false,
-                         net::HostCache::SerializationType::kRestorable);
+  base::Value value(base::Value::Type::LIST);
+  cache_->GetList(&value, false,
+                  net::HostCache::SerializationType::kRestorable);
   writing_pref_ = true;
   pref_service_->Set(pref_name_, value);
   writing_pref_ = false;
diff --git a/components/cronet/host_cache_persistence_manager_unittest.cc b/components/cronet/host_cache_persistence_manager_unittest.cc
index 5b8f4ba8..4d1f2f6 100644
--- a/components/cronet/host_cache_persistence_manager_unittest.cc
+++ b/components/cronet/host_cache_persistence_manager_unittest.cc
@@ -80,9 +80,9 @@
     temp_cache.Set(key2, entry, base::TimeTicks::Now(), base::Seconds(1));
     temp_cache.Set(key3, entry, base::TimeTicks::Now(), base::Seconds(1));
 
-    base::ListValue value;
-    temp_cache.GetAsListValue(&value, false /* include_stale */,
-                              net::HostCache::SerializationType::kRestorable);
+    base::Value value(base::Value::Type::LIST);
+    temp_cache.GetList(&value, false /* include_stale */,
+                       net::HostCache::SerializationType::kRestorable);
     pref_service_->Set(kPrefName, value);
   }
 
diff --git a/components/mirroring/browser/single_client_video_capture_host.cc b/components/mirroring/browser/single_client_video_capture_host.cc
index 2057c24..5687b24 100644
--- a/components/mirroring/browser/single_client_video_capture_host.cc
+++ b/components/mirroring/browser/single_client_video_capture_host.cc
@@ -143,14 +143,6 @@
     launched_device_->ResumeDevice();
 }
 
-void SingleClientVideoCaptureHost::Crop(const base::UnguessableToken& device_id,
-                                        const base::Token& crop_id,
-                                        CropCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // TODO(crbug.com/1247761): Implement.
-  std::move(callback).Run(media::mojom::CropRequestResult::kNotImplemented);
-}
-
 void SingleClientVideoCaptureHost::RequestRefreshFrame(
     const base::UnguessableToken& device_id) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/components/mirroring/browser/single_client_video_capture_host.h b/components/mirroring/browser/single_client_video_capture_host.h
index d49bacf..cb90c34 100644
--- a/components/mirroring/browser/single_client_video_capture_host.h
+++ b/components/mirroring/browser/single_client_video_capture_host.h
@@ -63,9 +63,6 @@
   void Resume(const base::UnguessableToken& device_id,
               const base::UnguessableToken& session_id,
               const VideoCaptureParams& params) override;
-  void Crop(const base::UnguessableToken& device_id,
-            const base::Token& crop_id,
-            CropCallback callback) override;
   void RequestRefreshFrame(const base::UnguessableToken& device_id) override;
   void ReleaseBuffer(const base::UnguessableToken& device_id,
                      int32_t buffer_id,
diff --git a/components/mirroring/service/fake_video_capture_host.h b/components/mirroring/service/fake_video_capture_host.h
index 84885a4e..61a8c2b 100644
--- a/components/mirroring/service/fake_video_capture_host.h
+++ b/components/mirroring/service/fake_video_capture_host.h
@@ -39,10 +39,6 @@
                void(const base::UnguessableToken&,
                     const base::UnguessableToken&,
                     const media::VideoCaptureParams&));
-  MOCK_METHOD3(Crop,
-               void(const base::UnguessableToken&,
-                    const base::Token&,
-                    CropCallback));
   MOCK_METHOD0(OnStopped, void());
   MOCK_METHOD2(OnLog, void(const base::UnguessableToken&, const std::string&));
   MOCK_METHOD2(OnFrameDropped,
diff --git a/components/password_manager/core/browser/fake_password_store_backend.cc b/components/password_manager/core/browser/fake_password_store_backend.cc
index 6cad99d7..6e48b0c 100644
--- a/components/password_manager/core/browser/fake_password_store_backend.cc
+++ b/components/password_manager/core/browser/fake_password_store_backend.cc
@@ -41,7 +41,7 @@
 }
 
 void FakePasswordStoreBackend::GetAutofillableLoginsAsync(
-    LoginsReply callback) {
+    LoginsOrErrorReply callback) {
   base::SequencedTaskRunnerHandle::Get()->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&FakePasswordStoreBackend::GetAutofillableLoginsInternal,
diff --git a/components/password_manager/core/browser/fake_password_store_backend.h b/components/password_manager/core/browser/fake_password_store_backend.h
index 0957d6ae..516a9ee 100644
--- a/components/password_manager/core/browser/fake_password_store_backend.h
+++ b/components/password_manager/core/browser/fake_password_store_backend.h
@@ -35,7 +35,7 @@
                    base::OnceCallback<void(bool)> completion) override;
   void Shutdown(base::OnceClosure shutdown_completed) override;
   void GetAllLoginsAsync(LoginsOrErrorReply callback) override;
-  void GetAutofillableLoginsAsync(LoginsReply callback) override;
+  void GetAutofillableLoginsAsync(LoginsOrErrorReply callback) override;
   void FillMatchingLoginsAsync(
       LoginsReply callback,
       bool include_psl,
diff --git a/components/password_manager/core/browser/mock_password_store_backend.h b/components/password_manager/core/browser/mock_password_store_backend.h
index 0f4d1dc..df756d8 100644
--- a/components/password_manager/core/browser/mock_password_store_backend.h
+++ b/components/password_manager/core/browser/mock_password_store_backend.h
@@ -42,7 +42,7 @@
               (override));
   MOCK_METHOD(void,
               GetAutofillableLoginsAsync,
-              (LoginsReply callback),
+              (LoginsOrErrorReply callback),
               (override));
   MOCK_METHOD(void,
               FillMatchingLoginsAsync,
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc
index 6c97d49..766f3591 100644
--- a/components/password_manager/core/browser/password_store.cc
+++ b/components/password_manager/core/browser/password_store.cc
@@ -263,8 +263,10 @@
     return;  // Once the shutdown started, ignore new requests.
 
   backend_->GetAutofillableLoginsAsync(
-      base::BindOnce(&PasswordStoreConsumer::OnGetPasswordStoreResultsFrom,
-                     consumer, base::RetainedRef(this)));
+      base::BindOnce(&GetLoginsOrEmptyListOnFailure)
+          .Then(base::BindOnce(
+              &PasswordStoreConsumer::OnGetPasswordStoreResultsFrom, consumer,
+              base::RetainedRef(this))));
 }
 
 void PasswordStore::GetAllLogins(
diff --git a/components/password_manager/core/browser/password_store_backend.h b/components/password_manager/core/browser/password_store_backend.h
index 54a3e61..71dd161 100644
--- a/components/password_manager/core/browser/password_store_backend.h
+++ b/components/password_manager/core/browser/password_store_backend.h
@@ -81,7 +81,7 @@
 
   // Returns the complete list of non-blocklist PasswordForms. Callback is
   // called on the main sequence.
-  virtual void GetAutofillableLoginsAsync(LoginsReply callback) = 0;
+  virtual void GetAutofillableLoginsAsync(LoginsOrErrorReply callback) = 0;
 
   // Returns all PasswordForms with the same signon_realm as a form in |forms|.
   // If |include_psl|==true, the PSL-matched forms are also included.
diff --git a/components/password_manager/core/browser/password_store_backend_migration_decorator.cc b/components/password_manager/core/browser/password_store_backend_migration_decorator.cc
index ff6ec7b74..aee99a9 100644
--- a/components/password_manager/core/browser/password_store_backend_migration_decorator.cc
+++ b/components/password_manager/core/browser/password_store_backend_migration_decorator.cc
@@ -90,7 +90,7 @@
 }
 
 void PasswordStoreBackendMigrationDecorator::GetAutofillableLoginsAsync(
-    LoginsReply callback) {
+    LoginsOrErrorReply callback) {
   active_backend_->GetAutofillableLoginsAsync(std::move(callback));
 }
 
diff --git a/components/password_manager/core/browser/password_store_backend_migration_decorator.h b/components/password_manager/core/browser/password_store_backend_migration_decorator.h
index c9aacc39..9353be1 100644
--- a/components/password_manager/core/browser/password_store_backend_migration_decorator.h
+++ b/components/password_manager/core/browser/password_store_backend_migration_decorator.h
@@ -49,7 +49,7 @@
                    base::OnceCallback<void(bool)> completion) override;
   void Shutdown(base::OnceClosure shutdown_completed) override;
   void GetAllLoginsAsync(LoginsOrErrorReply callback) override;
-  void GetAutofillableLoginsAsync(LoginsReply callback) override;
+  void GetAutofillableLoginsAsync(LoginsOrErrorReply callback) override;
   void FillMatchingLoginsAsync(
       LoginsReply callback,
       bool include_psl,
diff --git a/components/password_manager/core/browser/password_store_built_in_backend.cc b/components/password_manager/core/browser/password_store_built_in_backend.cc
index 267479f..a272280 100644
--- a/components/password_manager/core/browser/password_store_built_in_backend.cc
+++ b/components/password_manager/core/browser/password_store_built_in_backend.cc
@@ -293,7 +293,7 @@
 }
 
 void PasswordStoreBuiltInBackend::GetAutofillableLoginsAsync(
-    LoginsReply callback) {
+    LoginsOrErrorReply callback) {
   DCHECK(!was_shutdown_);
   DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
   background_task_runner_->PostTaskAndReplyWithResult(
diff --git a/components/password_manager/core/browser/password_store_built_in_backend.h b/components/password_manager/core/browser/password_store_built_in_backend.h
index 55530c4..ba23748 100644
--- a/components/password_manager/core/browser/password_store_built_in_backend.h
+++ b/components/password_manager/core/browser/password_store_built_in_backend.h
@@ -85,7 +85,7 @@
                    base::OnceCallback<void(bool)> completion) override;
   void Shutdown(base::OnceClosure shutdown_completed) override;
   void GetAllLoginsAsync(LoginsOrErrorReply callback) override;
-  void GetAutofillableLoginsAsync(LoginsReply callback) override;
+  void GetAutofillableLoginsAsync(LoginsOrErrorReply callback) override;
   void FillMatchingLoginsAsync(
       LoginsReply callback,
       bool include_psl,
diff --git a/components/password_manager/core/browser/password_store_built_in_backend_unittest.cc b/components/password_manager/core/browser/password_store_built_in_backend_unittest.cc
index e042d146..1283709d 100644
--- a/components/password_manager/core/browser/password_store_built_in_backend_unittest.cc
+++ b/components/password_manager/core/browser/password_store_built_in_backend_unittest.cc
@@ -66,6 +66,9 @@
   void HandleLogins(std::vector<std::unique_ptr<PasswordForm>> results) {
     LoginsReceivedConstRef(results);
   }
+  void HandleLoginsOrError(LoginsResultOrError results) {
+    LoginsReceivedConstRef(std::move(absl::get<LoginsResult>(results)));
+  }
 };
 
 // A mock LoginDatabase that simulates a failing Init() method.
@@ -185,7 +188,7 @@
           password_manager::UnorderedPasswordFormElementsAre(&expected_forms)));
 
   backend->GetAutofillableLoginsAsync(
-      base::BindOnce(&MockPasswordStoreBackendTester::HandleLogins,
+      base::BindOnce(&MockPasswordStoreBackendTester::HandleLoginsOrError,
                      base::Unretained(&tester)));
 
   RunUntilIdle();
@@ -268,6 +271,9 @@
   base::RepeatingCallback<void(LoginsResult)> handle_logins =
       base::BindRepeating(&MockPasswordStoreBackendTester::HandleLogins,
                           base::Unretained(&tester));
+  base::RepeatingCallback<void(LoginsResultOrError)> handle_logins_or_error =
+      base::BindRepeating(&MockPasswordStoreBackendTester::HandleLoginsOrError,
+                          base::Unretained(&tester));
 
   EXPECT_CALL(tester, HandleChanges(IsEmpty()));
   bad_backend->AddLoginAsync(*form, handle_changes);
@@ -287,7 +293,7 @@
   testing::Mock::VerifyAndClearExpectations(&tester);
 
   EXPECT_CALL(tester, LoginsReceivedConstRef(IsEmpty()));
-  bad_backend->GetAutofillableLoginsAsync(handle_logins);
+  bad_backend->GetAutofillableLoginsAsync(handle_logins_or_error);
   RunUntilIdle();
   testing::Mock::VerifyAndClearExpectations(&tester);
 
diff --git a/components/password_manager/core/browser/password_store_proxy_backend.cc b/components/password_manager/core/browser/password_store_proxy_backend.cc
index 5f696ee0..ff57a1f 100644
--- a/components/password_manager/core/browser/password_store_proxy_backend.cc
+++ b/components/password_manager/core/browser/password_store_proxy_backend.cc
@@ -23,13 +23,17 @@
 
 namespace {
 
+using MethodName = base::StrongAlias<struct MethodNameTag, std::string>;
+
 void InvokeCallbackWithCombinedStatus(base::OnceCallback<void(bool)> completion,
                                       std::vector<bool> statuses) {
   std::move(completion).Run(base::ranges::all_of(statuses, base::identity()));
 }
 
-// Records the difference metrics between |main_result| and |backend_result|.
-void RecordMetrics(const LoginsResult& main_result,
+// Records the difference metrics between |main_result| and |backend_result|
+// when returned by |method_name|.
+void RecordMetrics(const MethodName& method_name,
+                   const LoginsResult& main_result,
                    const LoginsResult& backend_result) {
   struct IsLess {
     bool operator()(const PasswordForm* lhs, const PasswordForm* rhs) const {
@@ -64,11 +68,11 @@
   });
 
   // Emits a pair of absolute and relative metrics.
-  auto Emit = [](base::StringPiece metric_infix, size_t nominator,
-                 size_t denominator) {
-    std::string prefix = base::StrCat(
-        {"PasswordManager.PasswordStoreProxyBackend.GetAllLoginsAsync.",
-         metric_infix, "."});
+  auto Emit = [&method_name](base::StringPiece metric_infix, size_t nominator,
+                             size_t denominator) {
+    std::string prefix =
+        base::StrCat({"PasswordManager.PasswordStoreProxyBackend.",
+                      method_name.value(), ".", metric_infix, "."});
     base::UmaHistogramCounts1M(prefix + "Abs", nominator);
     if (denominator != 0) {
       size_t ceiling_of_percentage =
@@ -82,53 +86,59 @@
   Emit("InconsistentPasswords", inconsistent, common_logins.size());
 }
 
-// Records the metrics of a pair of GetAllLoginsAsync() calls to the main and
+// Records the metrics of a pair of MethodName calls to the main and
 // the shadow backends once both calls are finished.
 //
 // The class is ref-counted because it is equally owned by the two parallel
-// GetAllLoginsAsync() calls: it must outlive the first returning one and shall
-// be destroyed after the second one returns.
-class GetAllLoginsAsyncMetricsRecorder
-    : public base::RefCounted<GetAllLoginsAsyncMetricsRecorder> {
+// method calls : it must outlive the first returning one and shall  be
+// destroyed after the second one returns.
+class ShadowTrafficMetricsRecorder
+    : public base::RefCounted<ShadowTrafficMetricsRecorder> {
  public:
+  explicit ShadowTrafficMetricsRecorder(MethodName method_name)
+      : method_name_(std::move(method_name)) {}
+
   // Returns the unchanged |result| so it can be passed to the main handler.
-  LoginsResultOrError RecordMainResult(LoginsResultOrError result) {
-    if (absl::holds_alternative<PasswordStoreBackendError>(result)) {
-      return result;
+  LoginsResultOrError RecordMainLoginsResultOrError(
+      LoginsResultOrError logins_or_error) {
+    if (absl::holds_alternative<PasswordStoreBackendError>(logins_or_error)) {
+      return logins_or_error;
     }
 
-    LoginsResult logins = std::move(absl::get<LoginsResult>(result));
-
+    LoginsResult logins = std::move(absl::get<LoginsResult>(logins_or_error));
     if (!first_result_) {
       first_result_ = absl::make_optional<LoginsResult>();
       first_result_->reserve(logins.size());
       for (const auto& login : logins)
         first_result_->push_back(std::make_unique<PasswordForm>(*login));
     } else {
-      RecordMetrics(/*main_result=*/logins, /*shadow_result=*/*first_result_);
+      RecordMetrics(method_name_, /*main_result=*/logins,
+                    /*shadow_result=*/*first_result_);
     }
 
     return logins;
   }
 
-  void RecordShadowResult(LoginsResultOrError result) {
-    if (absl::holds_alternative<PasswordStoreBackendError>(result)) {
+  void RecordShadowLoginsResultOrError(LoginsResultOrError logins_or_error) {
+    if (absl::holds_alternative<PasswordStoreBackendError>(logins_or_error)) {
       return;
     }
-    LoginsResult logins = std::move(absl::get<LoginsResult>(result));
 
+    LoginsResult logins = std::move(absl::get<LoginsResult>(logins_or_error));
     if (!first_result_)
       first_result_ = std::move(logins);
     else
-      RecordMetrics(/*main_result=*/*first_result_, /*shadow_result=*/logins);
+      RecordMetrics(method_name_, /*main_result=*/*first_result_,
+                    /*shadow_result=*/logins);
   }
 
  private:
-  friend class RefCounted<GetAllLoginsAsyncMetricsRecorder>;
-  ~GetAllLoginsAsyncMetricsRecorder() = default;
+  friend class RefCounted<ShadowTrafficMetricsRecorder>;
+  ~ShadowTrafficMetricsRecorder() = default;
 
   // Stores the result of the backend that returns first.
   absl::optional<LoginsResult> first_result_;
+  const MethodName method_name_;
 };
 
 }  // namespace
@@ -172,23 +182,25 @@
 }
 
 void PasswordStoreProxyBackend::GetAllLoginsAsync(LoginsOrErrorReply callback) {
-  scoped_refptr<GetAllLoginsAsyncMetricsRecorder> handler =
-      base::MakeRefCounted<GetAllLoginsAsyncMetricsRecorder>();
+  scoped_refptr<ShadowTrafficMetricsRecorder> handler =
+      base::MakeRefCounted<ShadowTrafficMetricsRecorder>(
+          MethodName("GetAllLoginsAsync"));
   main_backend_->GetAllLoginsAsync(
-      base::BindOnce(&GetAllLoginsAsyncMetricsRecorder::RecordMainResult,
-                     handler)
+      base::BindOnce(
+          &ShadowTrafficMetricsRecorder::RecordMainLoginsResultOrError, handler)
           .Then(std::move(callback)));
 
   if (is_syncing_passwords_callback_.Run() &&
       base::FeatureList::IsEnabled(
           features::kUnifiedPasswordManagerShadowAndroid)) {
     shadow_backend_->GetAllLoginsAsync(base::BindOnce(
-        &GetAllLoginsAsyncMetricsRecorder::RecordShadowResult, handler));
+        &ShadowTrafficMetricsRecorder::RecordShadowLoginsResultOrError,
+        handler));
   }
 }
 
 void PasswordStoreProxyBackend::GetAutofillableLoginsAsync(
-    LoginsReply callback) {
+    LoginsOrErrorReply callback) {
   main_backend_->GetAutofillableLoginsAsync(std::move(callback));
   // TODO(crbug.com/1229655): Request shadow_backend_ and compare results.
 }
diff --git a/components/password_manager/core/browser/password_store_proxy_backend.h b/components/password_manager/core/browser/password_store_proxy_backend.h
index 8d37d9b7..0724074e 100644
--- a/components/password_manager/core/browser/password_store_proxy_backend.h
+++ b/components/password_manager/core/browser/password_store_proxy_backend.h
@@ -40,7 +40,7 @@
                    base::OnceCallback<void(bool)> completion) override;
   void Shutdown(base::OnceClosure shutdown_completed) override;
   void GetAllLoginsAsync(LoginsOrErrorReply callback) override;
-  void GetAutofillableLoginsAsync(LoginsReply callback) override;
+  void GetAutofillableLoginsAsync(LoginsOrErrorReply callback) override;
   void FillMatchingLoginsAsync(
       LoginsReply callback,
       bool include_psl,
diff --git a/components/password_manager/core/browser/password_store_proxy_backend_unittest.cc b/components/password_manager/core/browser/password_store_proxy_backend_unittest.cc
index 1cf66e2a..cd6e7fbb 100644
--- a/components/password_manager/core/browser/password_store_proxy_backend_unittest.cc
+++ b/components/password_manager/core/browser/password_store_proxy_backend_unittest.cc
@@ -154,13 +154,12 @@
 
 TEST_F(PasswordStoreProxyBackendTest,
        UseMainBackendToGetAutofillableLoginsAsync) {
-  base::MockCallback<LoginsReply> mock_reply;
+  base::MockCallback<LoginsOrErrorReply> mock_reply;
   std::vector<std::unique_ptr<PasswordForm>> expected_logins =
       CreateTestLogins();
-  EXPECT_CALL(mock_reply,
-              Run(UnorderedPasswordFormElementsAre(&expected_logins)));
+  EXPECT_CALL(mock_reply, Run(LoginsResultsOrErrorAre(&expected_logins)));
   EXPECT_CALL(main_backend(), GetAutofillableLoginsAsync)
-      .WillOnce(WithArg<0>(Invoke([](LoginsReply reply) -> void {
+      .WillOnce(WithArg<0>(Invoke([](LoginsOrErrorReply reply) -> void {
         std::move(reply).Run(CreateTestLogins());
       })));
   proxy_backend().GetAutofillableLoginsAsync(mock_reply.Get());
diff --git a/components/password_manager/core/browser/test_password_store.cc b/components/password_manager/core/browser/test_password_store.cc
index 10355365..28a6675c 100644
--- a/components/password_manager/core/browser/test_password_store.cc
+++ b/components/password_manager/core/browser/test_password_store.cc
@@ -173,7 +173,8 @@
       std::move(callback));
 }
 
-void TestPasswordStore::GetAutofillableLoginsAsync(LoginsReply callback) {
+void TestPasswordStore::GetAutofillableLoginsAsync(
+    LoginsOrErrorReply callback) {
   background_task_runner_->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(&TestPasswordStore::GetAutofillableLoginsInternal,
diff --git a/components/password_manager/core/browser/test_password_store.h b/components/password_manager/core/browser/test_password_store.h
index 98568ca..da5b071 100644
--- a/components/password_manager/core/browser/test_password_store.h
+++ b/components/password_manager/core/browser/test_password_store.h
@@ -71,7 +71,7 @@
                    base::OnceCallback<void(bool)> completion) override;
   void Shutdown(base::OnceClosure shutdown_completed) override;
   void GetAllLoginsAsync(LoginsOrErrorReply callback) override;
-  void GetAutofillableLoginsAsync(LoginsReply callback) override;
+  void GetAutofillableLoginsAsync(LoginsOrErrorReply callback) override;
   void FillMatchingLoginsAsync(
       LoginsReply callback,
       bool include_psl,
diff --git a/components/payments/content/service_worker_payment_app_factory.cc b/components/payments/content/service_worker_payment_app_factory.cc
index 926ccda..68efab99 100644
--- a/components/payments/content/service_worker_payment_app_factory.cc
+++ b/components/payments/content/service_worker_payment_app_factory.cc
@@ -21,6 +21,7 @@
 #include "content/public/browser/stored_payment_app.h"
 #include "content/public/browser/supported_delegations.h"
 #include "content/public/browser/web_contents.h"
+#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
 
 namespace payments {
 namespace {
@@ -186,8 +187,11 @@
 
 void ServiceWorkerPaymentAppFactory::Create(base::WeakPtr<Delegate> delegate) {
   auto* rfh = delegate->GetInitiatorRenderFrameHost();
-  if (!rfh || !rfh->IsActive() || !delegate->GetWebContents())
-    return;  // The frame or page is being unloaded.
+  // Exit if frame or page is being unloaded or payments are otherwise
+  // disallowed.
+  if (!rfh || !rfh->IsActive() || !delegate->GetWebContents() ||
+      !rfh->IsFeatureEnabled(blink::mojom::PermissionsPolicyFeature::kPayment))
+    return;
 
   auto creator = std::make_unique<ServiceWorkerPaymentAppCreator>(
       /*owner=*/this, delegate);
diff --git a/components/services/paint_preview_compositor/paint_preview_compositor_impl.cc b/components/services/paint_preview_compositor/paint_preview_compositor_impl.cc
index ad652eb..16752ed7 100644
--- a/components/services/paint_preview_compositor/paint_preview_compositor_impl.cc
+++ b/components/services/paint_preview_compositor/paint_preview_compositor_impl.cc
@@ -283,11 +283,10 @@
     return;
   }
 
-  // TODO(crbug/1199857): Investigate if CONTINUE_ON_SHUTDOWN is a good option.
   base::ThreadPool::PostTaskAndReplyWithResult(
       FROM_HERE,
       {base::TaskPriority::USER_VISIBLE, base::WithBaseSyncPrimitives(),
-       base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
+       base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
       base::BindOnce(&CreateBitmap, discardable_shared_memory_manager_,
                      frame_it->second.skp, clip_rect, scale_factor),
       base::BindOnce(
@@ -387,7 +386,7 @@
   base::ThreadPool::PostTaskAndReplyWithResult(
       FROM_HERE,
       {base::TaskPriority::USER_VISIBLE, base::WithBaseSyncPrimitives(),
-       base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
+       base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
       base::BindOnce(&CreateBitmap, discardable_shared_memory_manager_,
                      root_frame_, clip_rect, scale_factor),
       base::BindOnce(
diff --git a/content/browser/accessibility/browser_accessibility_auralinux.h b/content/browser/accessibility/browser_accessibility_auralinux.h
index 3affe4f..13976fd 100644
--- a/content/browser/accessibility/browser_accessibility_auralinux.h
+++ b/content/browser/accessibility/browser_accessibility_auralinux.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_AURALINUX_H_
 #define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_AURALINUX_H_
 
-#include "base/compiler_specific.h"
 #include "content/browser/accessibility/browser_accessibility.h"
 #include "content/common/content_export.h"
 #include "ui/accessibility/ax_node.h"
diff --git a/content/browser/accessibility/browser_accessibility_com_win.h b/content/browser/accessibility/browser_accessibility_com_win.h
index d5ae3b1..f484f5db 100644
--- a/content/browser/accessibility/browser_accessibility_com_win.h
+++ b/content/browser/accessibility/browser_accessibility_com_win.h
@@ -14,7 +14,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/win/atl.h"
 #include "content/browser/accessibility/browser_accessibility.h"
diff --git a/content/browser/accessibility/browser_accessibility_state_impl.h b/content/browser/accessibility/browser_accessibility_state_impl.h
index 05200028..b61e95d 100644
--- a/content/browser/accessibility/browser_accessibility_state_impl.h
+++ b/content/browser/accessibility/browser_accessibility_state_impl.h
@@ -7,7 +7,6 @@
 
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "build/build_config.h"
 #include "components/metrics/metrics_provider.h"
 #include "content/common/content_export.h"
diff --git a/content/browser/background_fetch/background_fetch_test_base.h b/content/browser/background_fetch/background_fetch_test_base.h
index fe0fa12e..ac9a2557 100644
--- a/content/browser/background_fetch/background_fetch_test_base.h
+++ b/content/browser/background_fetch/background_fetch_test_base.h
@@ -9,7 +9,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
diff --git a/content/browser/browser_child_process_host_impl.h b/content/browser/browser_child_process_host_impl.h
index 3bb425e6..ff9285c8d3b 100644
--- a/content/browser/browser_child_process_host_impl.h
+++ b/content/browser/browser_child_process_host_impl.h
@@ -10,7 +10,6 @@
 #include <list>
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 14a3afdc..eaa4e8c 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -505,8 +505,18 @@
     parameters_.startup_data.reset();
   }
 
+  // As of https://crrev.com/c/3244976 + https://crrev.com/c/3187153, embedders
+  // no longer own running `ui_task`. Some still query its boolean value
+  // however, fake it here. TODO(gab): As a follow-up, update
+  // ContentBrowserClient::CreateBrowserMainParts to take a `bool
+  // is_integration_test` instead of the entire `MainFunctionParams` which none
+  // of the parts impl use beyond ui_task's boolean value:
+  // https://bit.ly/3Eq9v36
+  MainFunctionParams fake_params(parameters_.command_line);
+  if (parameters_.ui_task)
+    fake_params.ui_task = base::DoNothing();
   parts_ = GetContentClient()->browser()->CreateBrowserMainParts(
-      std::move(parameters_));
+      std::move(fake_params));
 }
 
 // BrowserMainLoop stages ==================================================
@@ -853,6 +863,22 @@
       &BrowserMainLoop::PreMainMessageLoopRun, base::Unretained(this));
   startup_task_runner_->AddTask(std::move(pre_main_message_loop_run));
 
+// On Android, the native message loop is already running when the app is
+// entered and startup tasks are run asynchrously from it.
+// InterceptMainMessageLoopRun() thus needs to be forced instead of happening
+// from MainMessageLoopRun().
+#if defined(OS_ANDROID)
+  StartupTask intercept_main_message_loop_run = base::BindOnce(
+      [](BrowserMainLoop* self) {
+        // Lambda to ignore the return value and always keep a clean exit code
+        // for this StartupTask.
+        self->InterceptMainMessageLoopRun();
+        return self->result_code_;
+      },
+      base::Unretained(this));
+  startup_task_runner_->AddTask(std::move(intercept_main_message_loop_run));
+#endif
+
 #if defined(OS_ANDROID)
   startup_task_runner_->StartRunningTasksAsync();
 #else
@@ -970,16 +996,33 @@
   return result_code_;
 }
 
+BrowserMainLoop::ProceedWithMainMessageLoopRun
+BrowserMainLoop::InterceptMainMessageLoopRun() {
+  // Embedders can request not to run the loop (also voids |ui_task|).
+  if (parts_ && !parts_->ShouldInterceptMainMessageLoopRun())
+    return ProceedWithMainMessageLoopRun(false);
+
+  // The |ui_task| can be injected by tests to replace the main message loop.
+  if (parameters_.ui_task) {
+    std::move(parameters_.ui_task).Run();
+    return ProceedWithMainMessageLoopRun(false);
+  }
+
+  return ProceedWithMainMessageLoopRun(true);
+}
+
 void BrowserMainLoop::RunMainMessageLoop() {
 #if defined(OS_ANDROID)
   // Android's main message loop is the Java message loop.
   NOTREACHED();
 #else   // defined(OS_ANDROID)
+  if (InterceptMainMessageLoopRun() != ProceedWithMainMessageLoopRun(true))
+    return;
+
   auto main_run_loop = std::make_unique<base::RunLoop>();
   if (parts_)
     parts_->WillRunMainMessageLoop(main_run_loop);
-  if (!main_run_loop)
-    return;
+  DCHECK(main_run_loop);
 
   main_run_loop->RunUntilIdle();
   // |parts_| may have captured a quit closure in WillRunMainMessageLoop(). If
diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h
index 5f19adb1..e660d54 100644
--- a/content/browser/browser_main_loop.h
+++ b/content/browser/browser_main_loop.h
@@ -11,6 +11,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/task/thread_pool/thread_pool_instance.h"
+#include "base/types/strong_alias.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "content/browser/browser_process_io_thread.h"
@@ -246,6 +247,13 @@
 
   int PreMainMessageLoopRun();
 
+  // One last opportunity to intercept the upcoming MainMessageLoopRun (or
+  // before yielding to the native loop on Android). Returns false iff the run
+  // should proceed after this call.
+  using ProceedWithMainMessageLoopRun =
+      base::StrongAlias<class ProceedWithMainMessageLoopRunTag, bool>;
+  ProceedWithMainMessageLoopRun InterceptMainMessageLoopRun();
+
   void MainMessageLoopRun();
 
   void InitializeMojo();
diff --git a/content/browser/child_process_security_policy_impl.h b/content/browser/child_process_security_policy_impl.h
index 104c4356..b51e746 100644
--- a/content/browser/child_process_security_policy_impl.h
+++ b/content/browser/child_process_security_policy_impl.h
@@ -11,7 +11,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
 #include "base/gtest_prod_util.h"
diff --git a/content/browser/devtools/devtools_agent_host_impl.h b/content/browser/devtools/devtools_agent_host_impl.h
index fefa27a..dab989d 100644
--- a/content/browser/devtools/devtools_agent_host_impl.h
+++ b/content/browser/devtools/devtools_agent_host_impl.h
@@ -9,7 +9,6 @@
 
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/containers/flat_map.h"
 #include "base/process/kill.h"
 #include "content/browser/devtools/devtools_io_context.h"
diff --git a/content/browser/devtools/devtools_frame_trace_recorder.h b/content/browser/devtools/devtools_frame_trace_recorder.h
index e675c1f7..9327f97 100644
--- a/content/browser/devtools/devtools_frame_trace_recorder.h
+++ b/content/browser/devtools/devtools_frame_trace_recorder.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_FRAME_TRACE_RECORDER_H_
 #define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_FRAME_TRACE_RECORDER_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 
 namespace cc {
diff --git a/content/browser/devtools/protocol/devtools_download_manager_delegate.h b/content/browser/devtools/protocol/devtools_download_manager_delegate.h
index f810033..1155095 100644
--- a/content/browser/devtools/protocol/devtools_download_manager_delegate.h
+++ b/content/browser/devtools/protocol/devtools_download_manager_delegate.h
@@ -9,7 +9,6 @@
 #include <string>
 
 #include "base/callback_forward.h"
-#include "base/compiler_specific.h"
 #include "base/files/file_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
diff --git a/content/browser/devtools/protocol/input_handler.cc b/content/browser/devtools/protocol/input_handler.cc
index 18ccc68..30f1ad5f 100644
--- a/content/browser/devtools/protocol/input_handler.cc
+++ b/content/browser/devtools/protocol/input_handler.cc
@@ -526,12 +526,14 @@
   base::WeakPtrFactory<InputHandler::InputInjector> weak_ptr_factory_{this};
 };
 
-InputHandler::InputHandler(bool allow_file_access)
+InputHandler::InputHandler(bool allow_file_access,
+                           bool allow_sending_input_to_browser)
     : DevToolsDomainHandler(Input::Metainfo::domainName),
       host_(nullptr),
       page_scale_factor_(1.0),
       last_id_(0),
-      allow_file_access_(allow_file_access) {}
+      allow_file_access_(allow_file_access),
+      allow_sending_input_to_browser_(allow_sending_input_to_browser) {}
 
 InputHandler::~InputHandler() = default;
 
@@ -669,7 +671,7 @@
 
   // We do not pass events to browser if there is no native key event
   // due to Mac needing the actual os_event.
-  if (event.native_key_code)
+  if (event.native_key_code && allow_sending_input_to_browser_)
     event.os_event = NativeInputEventBuilder::CreateEvent(event);
   else
     event.skip_in_browser = true;
diff --git a/content/browser/devtools/protocol/input_handler.h b/content/browser/devtools/protocol/input_handler.h
index ac17a83..cfdaa21 100644
--- a/content/browser/devtools/protocol/input_handler.h
+++ b/content/browser/devtools/protocol/input_handler.h
@@ -34,7 +34,7 @@
 
 class InputHandler : public DevToolsDomainHandler, public Input::Backend {
  public:
-  explicit InputHandler(bool allow_file_access);
+  InputHandler(bool allow_file_access, bool allow_sending_input_to_browser);
 
   InputHandler(const InputHandler&) = delete;
   InputHandler& operator=(const InputHandler&) = delete;
@@ -246,6 +246,7 @@
   bool ignore_input_events_ = false;
   bool intercept_drags_ = false;
   const bool allow_file_access_;
+  const bool allow_sending_input_to_browser_ = false;
   std::set<int> pointer_ids_;
   std::unique_ptr<SyntheticPointerDriver> synthetic_pointer_driver_;
   base::flat_map<int, blink::WebTouchPoint> touch_points_;
diff --git a/content/browser/devtools/protocol/page_handler.h b/content/browser/devtools/protocol/page_handler.h
index c0aa0a4..e8a0df8 100644
--- a/content/browser/devtools/protocol/page_handler.h
+++ b/content/browser/devtools/protocol/page_handler.h
@@ -12,7 +12,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
 #include "build/build_config.h"
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index 6562d5f8..dbb0b2e5 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -308,7 +308,8 @@
       session->GetClient()->MayReadLocalFiles()));
   session->AddHandler(std::move(emulation_handler));
   auto input_handler = std::make_unique<protocol::InputHandler>(
-      session->GetClient()->MayReadLocalFiles());
+      session->GetClient()->MayReadLocalFiles(),
+      session->GetClient()->MaySendInputEventsToBrowser());
   input_handler->OnPageScaleFactorChanged(page_scale_factor_);
   session->AddHandler(std::move(input_handler));
   session->AddHandler(std::make_unique<protocol::InspectorHandler>());
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.h b/content/browser/devtools/render_frame_devtools_agent_host.h
index d2bc386..a82c97e 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.h
+++ b/content/browser/devtools/render_frame_devtools_agent_host.h
@@ -9,7 +9,6 @@
 #include <memory>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/containers/flat_set.h"
 #include "build/build_config.h"
 #include "content/browser/devtools/devtools_agent_host_impl.h"
diff --git a/content/browser/download/drag_download_file.h b/content/browser/download/drag_download_file.h
index d653cf7..031b643 100644
--- a/content/browser/download/drag_download_file.h
+++ b/content/browser/download/drag_download_file.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/memory/raw_ptr.h"
diff --git a/content/browser/file_system_access/file_system_access_manager_impl.cc b/content/browser/file_system_access/file_system_access_manager_impl.cc
index 731abd87b..e3673de 100644
--- a/content/browser/file_system_access/file_system_access_manager_impl.cc
+++ b/content/browser/file_system_access/file_system_access_manager_impl.cc
@@ -621,12 +621,9 @@
     const storage::FileSystemURL& url,
     GetEntryFromDataTransferTokenCallback token_resolved_callback,
     HandleType file_type) {
-  // TODO(https://crbug.com/1241476): Determine whether
-  // GetSharedHandleStateForPath should be refactored to accept StorageKey as a
-  // parameter instead of origin.
-  SharedHandleState shared_handle_state = GetSharedHandleStateForPath(
-      file_path, binding_context.storage_key.origin(), file_type,
-      UserAction::kDragAndDrop);
+  SharedHandleState shared_handle_state =
+      GetSharedHandleStateForPath(file_path, binding_context.storage_key,
+                                  file_type, UserAction::kDragAndDrop);
 
   blink::mojom::FileSystemAccessEntryPtr entry;
   if (file_type == HandleType::kDirectory) {
@@ -779,11 +776,8 @@
       auto permission_grant =
           base::MakeRefCounted<FixedFileSystemAccessPermissionGrant>(
               PermissionStatus::GRANTED, base::FilePath());
-      // TODO(https://crbug.com/1241534): Determine whether
-      // CreateTransferTokenImpl should be refactored to accept StorageKey as a
-      // parameter instead of origin.
       CreateTransferTokenImpl(
-          url, storage_key.origin(),
+          url, storage_key,
           SharedHandleState(permission_grant, permission_grant),
           data.handle_type() == FileSystemAccessHandleData::kDirectory
               ? HandleType::kDirectory
@@ -818,15 +812,12 @@
       // SharedHandleState for a directory even if the handle represents a
       // file.
       SharedHandleState handle_state = GetSharedHandleStateForPath(
-          root_path, storage_key.origin(),
+          root_path, storage_key,
           (is_directory || !relative_path.empty()) ? HandleType::kDirectory
                                                    : HandleType::kFile,
           FileSystemAccessPermissionContext::UserAction::kLoadFromStorage);
-      // TODO(https://crbug.com/1241534): Determine whether
-      // CreateTransferTokenImpl should be refactored to accept StorageKey as a
-      // parameter instead of origin.
       CreateTransferTokenImpl(
-          child, storage_key.origin(), handle_state,
+          child, storage_key, handle_state,
           is_directory ? HandleType::kDirectory : HandleType::kFile,
           std::move(token));
       break;
@@ -847,8 +838,7 @@
       CreateFileSystemURLFromPath(path_type, file_path);
 
   SharedHandleState shared_handle_state = GetSharedHandleStateForPath(
-      file_path, binding_context.storage_key.origin(), HandleType::kFile,
-      user_action);
+      file_path, binding_context.storage_key, HandleType::kFile, user_action);
 
   return blink::mojom::FileSystemAccessEntry::New(
       blink::mojom::FileSystemAccessHandle::NewFile(
@@ -866,9 +856,9 @@
   storage::FileSystemURL url =
       CreateFileSystemURLFromPath(path_type, file_path);
 
-  SharedHandleState shared_handle_state = GetSharedHandleStateForPath(
-      file_path, binding_context.storage_key.origin(), HandleType::kDirectory,
-      user_action);
+  SharedHandleState shared_handle_state =
+      GetSharedHandleStateForPath(file_path, binding_context.storage_key,
+                                  HandleType::kDirectory, user_action);
 
   return blink::mojom::FileSystemAccessEntry::New(
       blink::mojom::FileSystemAccessHandle::NewDirectory(
@@ -991,21 +981,17 @@
     const FileSystemAccessFileHandleImpl& file,
     mojo::PendingReceiver<blink::mojom::FileSystemAccessTransferToken>
         receiver) {
-  // TODO(https://crbug.com/1241534): Determine whether CreateTransferTokenImpl
-  // should be refactored to accept StorageKey as a parameter instead of origin.
-  return CreateTransferTokenImpl(
-      file.url(), file.context().storage_key.origin(), file.handle_state(),
-      HandleType::kFile, std::move(receiver));
+  return CreateTransferTokenImpl(file.url(), file.context().storage_key,
+                                 file.handle_state(), HandleType::kFile,
+                                 std::move(receiver));
 }
 
 void FileSystemAccessManagerImpl::CreateTransferToken(
     const FileSystemAccessDirectoryHandleImpl& directory,
     mojo::PendingReceiver<blink::mojom::FileSystemAccessTransferToken>
         receiver) {
-  // TODO(https://crbug.com/1241534): Determine whether CreateTransferTokenImpl
-  // should be refactored to accept StorageKey as a parameter instead of origin.
   return CreateTransferTokenImpl(
-      directory.url(), directory.context().storage_key.origin(),
+      directory.url(), directory.context().storage_key,
       directory.handle_state(), HandleType::kDirectory, std::move(receiver));
 }
 
@@ -1194,7 +1180,7 @@
   if (options.type() == ui::SelectFileDialog::SELECT_FOLDER) {
     DCHECK_EQ(entries.size(), 1u);
     SharedHandleState shared_handle_state = GetSharedHandleStateForPath(
-        entries.front().path, binding_context.storage_key.origin(),
+        entries.front().path, binding_context.storage_key,
         HandleType::kDirectory,
         FileSystemAccessPermissionContext::UserAction::kOpen);
     // Ask for both read and write permission at the same time. The permission
@@ -1220,14 +1206,12 @@
     auto fs_url =
         CreateFileSystemURLFromPath(entries.front().type, entries.front().path);
 
-    operation_runner().PostTaskWithThisObject(
+    operation_runner().PostTaskWithThisObject(base::BindOnce(
+        &CreateAndTruncateFile, fs_url,
         base::BindOnce(
-            &CreateAndTruncateFile, fs_url,
-            base::BindOnce(
-                &FileSystemAccessManagerImpl::DidCreateAndTruncateSaveFile,
-                this, binding_context, entries.front(), fs_url,
-                std::move(callback)),
-            base::SequencedTaskRunnerHandle::Get()));
+            &FileSystemAccessManagerImpl::DidCreateAndTruncateSaveFile, this,
+            binding_context, entries.front(), fs_url, std::move(callback)),
+        base::SequencedTaskRunnerHandle::Get()));
     return;
   }
 
@@ -1261,9 +1245,9 @@
     return;
   }
 
-  SharedHandleState shared_handle_state = GetSharedHandleStateForPath(
-      entry.path, binding_context.storage_key.origin(), HandleType::kFile,
-      UserAction::kSave);
+  SharedHandleState shared_handle_state =
+      GetSharedHandleStateForPath(entry.path, binding_context.storage_key,
+                                  HandleType::kFile, UserAction::kSave);
 
   result_entries.push_back(blink::mojom::FileSystemAccessEntry::New(
       blink::mojom::FileSystemAccessHandle::NewFile(
@@ -1307,11 +1291,9 @@
                           std::move(result_entries));
 }
 
-// TODO(https://crbug.com/1241534): Determine whether CreateTransferTokenImpl
-// should be refactored to accept StorageKey as a parameter instead of origin.
 void FileSystemAccessManagerImpl::CreateTransferTokenImpl(
     const storage::FileSystemURL& url,
-    const url::Origin& origin,
+    const blink::StorageKey& storage_key,
     const SharedHandleState& handle_state,
     HandleType handle_type,
     mojo::PendingReceiver<blink::mojom::FileSystemAccessTransferToken>
@@ -1319,7 +1301,8 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   auto token_impl = std::make_unique<FileSystemAccessTransferTokenImpl>(
-      url, origin, handle_state, handle_type, this, std::move(receiver));
+      url, storage_key.origin(), handle_state, handle_type, this,
+      std::move(receiver));
   auto token = token_impl->token();
   transfer_tokens_.emplace(token, std::move(token_impl));
 }
@@ -1395,15 +1378,15 @@
 FileSystemAccessManagerImpl::SharedHandleState
 FileSystemAccessManagerImpl::GetSharedHandleStateForPath(
     const base::FilePath& path,
-    const url::Origin& origin,
+    const blink::StorageKey& storage_key,
     HandleType handle_type,
     FileSystemAccessPermissionContext::UserAction user_action) {
   scoped_refptr<FileSystemAccessPermissionGrant> read_grant, write_grant;
   if (permission_context_) {
     read_grant = permission_context_->GetReadPermissionGrant(
-        origin, path, handle_type, user_action);
+        storage_key.origin(), path, handle_type, user_action);
     write_grant = permission_context_->GetWritePermissionGrant(
-        origin, path, handle_type, user_action);
+        storage_key.origin(), path, handle_type, user_action);
   } else {
     // Auto-deny all write grants if no permisson context is available, unless
     // Experimental Web Platform features are enabled.
diff --git a/content/browser/file_system_access/file_system_access_manager_impl.h b/content/browser/file_system_access/file_system_access_manager_impl.h
index ffaa68ba..0eb9f3019 100644
--- a/content/browser/file_system_access/file_system_access_manager_impl.h
+++ b/content/browser/file_system_access/file_system_access_manager_impl.h
@@ -281,7 +281,7 @@
 
   SharedHandleState GetSharedHandleStateForPath(
       const base::FilePath& path,
-      const url::Origin& origin,
+      const blink::StorageKey& storage_key,
       FileSystemAccessPermissionContext::HandleType handle_type,
       FileSystemAccessPermissionContext::UserAction user_action);
 
@@ -414,7 +414,7 @@
 
   void CreateTransferTokenImpl(
       const storage::FileSystemURL& url,
-      const url::Origin& origin,
+      const blink::StorageKey& storage_key,
       const SharedHandleState& handle_state,
       FileSystemAccessPermissionContext::HandleType handle_type,
       mojo::PendingReceiver<blink::mojom::FileSystemAccessTransferToken>
diff --git a/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc b/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc
index de89eadb4..4110dec 100644
--- a/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc
+++ b/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc
@@ -119,23 +119,6 @@
     feature_list_.InitAndEnableFeature(features::kFontSrcLocalMatching);
   }
 
-#if defined(OS_WIN)
-  void PreRunTestOnMainThread() override {
-    DWriteFontLookupTableBuilder* table_builder =
-        DWriteFontLookupTableBuilder::GetInstance();
-    table_builder->ResetStateForTesting();
-    table_builder->SchedulePrepareFontUniqueNameTableIfNeeded();
-    DevToolsProtocolTest::PreRunTestOnMainThread();
-  }
-
-  void PostRunTestOnMainThread() override {
-    DWriteFontLookupTableBuilder* table_builder =
-        DWriteFontLookupTableBuilder::GetInstance();
-    table_builder->ResetStateForTesting();
-    DevToolsProtocolTest::PostRunTestOnMainThread();
-  }
-#endif
-
   void LoadAndWait(const std::string& url) {
     base::ScopedAllowBlockingForTesting blocking_for_load;
     ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/content/browser/gpu/gpu_data_manager_impl.h b/content/browser/gpu/gpu_data_manager_impl.h
index 8e80ced..bb9a9768 100644
--- a/content/browser/gpu/gpu_data_manager_impl.h
+++ b/content/browser/gpu/gpu_data_manager_impl.h
@@ -11,7 +11,6 @@
 #include <memory>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/no_destructor.h"
 #include "base/process/kill.h"
 #include "base/synchronization/lock.h"
diff --git a/content/browser/host_zoom_map_impl.h b/content/browser/host_zoom_map_impl.h
index 4a69e1ab..85ad0b75 100644
--- a/content/browser/host_zoom_map_impl.h
+++ b/content/browser/host_zoom_map_impl.h
@@ -10,7 +10,6 @@
 #include <tuple>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/task/sequenced_task_runner_helpers.h"
 #include "content/common/content_export.h"
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h
index e30c180..4b874b2 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.h
+++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -14,7 +14,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
diff --git a/content/browser/media/cdm_registry_impl.h b/content/browser/media/cdm_registry_impl.h
index 9d977bc..e360cc3 100644
--- a/content/browser/media/cdm_registry_impl.h
+++ b/content/browser/media/cdm_registry_impl.h
@@ -7,7 +7,6 @@
 
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
 #include "content/common/content_export.h"
diff --git a/content/browser/media/media_internals.h b/content/browser/media/media_internals.h
index 00edc3a..72528a63 100644
--- a/content/browser/media/media_internals.h
+++ b/content/browser/media/media_internals.h
@@ -13,7 +13,6 @@
 #include <vector>
 
 #include "base/callback_forward.h"
-#include "base/compiler_specific.h"
 #include "base/synchronization/lock.h"
 #include "base/values.h"
 #include "content/browser/media/media_internals_audio_focus_helper.h"
diff --git a/content/browser/media/media_internals_handler.h b/content/browser/media/media_internals_handler.h
index 23dea7a..cf057e7 100644
--- a/content/browser/media/media_internals_handler.h
+++ b/content/browser/media/media_internals_handler.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_BROWSER_MEDIA_MEDIA_INTERNALS_HANDLER_H_
 #define CONTENT_BROWSER_MEDIA_MEDIA_INTERNALS_HANDLER_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "content/public/browser/web_ui_message_handler.h"
 
diff --git a/content/browser/media/session/media_session_controller.h b/content/browser/media/session/media_session_controller.h
index 1ce19b1..95a1769d 100644
--- a/content/browser/media/session/media_session_controller.h
+++ b/content/browser/media/session/media_session_controller.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_BROWSER_MEDIA_SESSION_MEDIA_SESSION_CONTROLLER_H_
 #define CONTENT_BROWSER_MEDIA_SESSION_MEDIA_SESSION_CONTROLLER_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
diff --git a/content/browser/notifications/platform_notification_context_impl.h b/content/browser/notifications/platform_notification_context_impl.h
index 43feafaf..9510757 100644
--- a/content/browser/notifications/platform_notification_context_impl.h
+++ b/content/browser/notifications/platform_notification_context_impl.h
@@ -12,7 +12,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
diff --git a/content/browser/plugin_service_impl.h b/content/browser/plugin_service_impl.h
index c00c8c8..e76794b 100644
--- a/content/browser/plugin_service_impl.h
+++ b/content/browser/plugin_service_impl.h
@@ -18,7 +18,6 @@
 #include <map>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/singleton.h"
 #include "base/sequence_checker.h"
diff --git a/content/browser/presentation/presentation_service_impl.h b/content/browser/presentation/presentation_service_impl.h
index d7b1251f..364e498 100644
--- a/content/browser/presentation/presentation_service_impl.h
+++ b/content/browser/presentation/presentation_service_impl.h
@@ -12,7 +12,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h
index 88860f0..811af41 100644
--- a/content/browser/renderer_host/compositor_impl_android.h
+++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -10,7 +10,6 @@
 #include <memory>
 
 #include "base/cancelable_callback.h"
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
diff --git a/content/browser/renderer_host/embedded_frame_sink_impl.h b/content/browser/renderer_host/embedded_frame_sink_impl.h
index 20bbbc04..5133c297 100644
--- a/content/browser/renderer_host/embedded_frame_sink_impl.h
+++ b/content/browser/renderer_host/embedded_frame_sink_impl.h
@@ -6,7 +6,6 @@
 #define CONTENT_BROWSER_RENDERER_HOST_EMBEDDED_FRAME_SINK_IMPL_H_
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/time/time.h"
 #include "components/viz/common/surfaces/frame_sink_bundle_id.h"
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
index 01f23e0..febe6b3a 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -13,8 +13,10 @@
 #include "base/task/bind_post_task.h"
 #include "base/task/post_task.h"
 #include "base/task/task_runner_util.h"
+#include "build/build_config.h"
 #include "content/browser/bad_message.h"
 #include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/browser/renderer_host/media/video_capture_manager.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_frame_host.h"
@@ -28,6 +30,10 @@
 #include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
 #include "url/origin.h"
 
+#if !defined(OS_ANDROID)
+#include "content/browser/media/capture/crop_id_web_contents_helper.h"
+#endif
+
 namespace content {
 
 namespace {
@@ -63,6 +69,41 @@
   return web_contents_observer;
 }
 
+#if !defined(OS_ANDROID)
+// Checks whether a track living in the WebContents indicated by
+// (render_process_id, render_frame_id) may be cropped to the crop-target
+// indicated by |crop_id|.
+bool IsCropTargetValid(int render_process_id,
+                       int render_frame_id,
+                       const base::Token& crop_id) {
+  RenderFrameHost* const rfh =
+      RenderFrameHost::FromID(render_process_id, render_frame_id);
+  if (!rfh) {
+    return false;
+  }
+
+  WebContents* const web_contents =
+      WebContents::FromRenderFrameHost(rfh->GetMainFrame());
+  if (!web_contents) {
+    return false;
+  }
+
+  CropIdWebContentsHelper* const helper =
+      CropIdWebContentsHelper::FromWebContents(web_contents);
+  if (!helper) {
+    // No crop-IDs were ever produced on this WebContents.
+    // Any non-zero crop-ID should be rejected on account of being
+    // invalid. A zero crop-ID would ultimately be rejected on account
+    // of the track being uncropped, so we can unconditionally reject.
+    return false;
+  }
+
+  // * crop_id.is_zero() = uncrop-request.
+  // * !crop_id.is_zero() = crop-request.
+  return crop_id.is_zero() || helper->IsAssociatedWithCropId(crop_id);
+}
+#endif
+
 }  // namespace
 
 int MediaStreamDispatcherHost::next_requester_id_ = 0;
@@ -423,6 +464,39 @@
       /*is_from_microtask=*/false,
       /*is_from_timer=*/false);
 }
+
+void MediaStreamDispatcherHost::Crop(const base::UnguessableToken& device_id,
+                                     const base::Token& crop_id,
+                                     CropCallback callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  // Hop to the UI thread to verify that cropping to |crop_id| is permitted
+  // from this particular context. Namely, cropping is currently only allowed
+  // for self-capture, so the crop_id has to be associated with the top-level
+  // WebContents belonging to this very tab.
+  GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
+      FROM_HERE,
+      base::BindOnce(&IsCropTargetValid, render_process_id_, render_frame_id_,
+                     crop_id),
+      base::BindOnce(&MediaStreamDispatcherHost::OnCropValidationComplete,
+                     weak_factory_.GetWeakPtr(), device_id, crop_id,
+                     std::move(callback)));
+}
+
+void MediaStreamDispatcherHost::OnCropValidationComplete(
+    const base::UnguessableToken& device_id,
+    const base::Token& crop_id,
+    CropCallback callback,
+    bool crop_id_passed_validation) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  if (!crop_id_passed_validation) {
+    std::move(callback).Run(media::mojom::CropRequestResult::kErrorGeneric);
+    return;
+  }
+  media_stream_manager_->video_capture_manager()->Crop(device_id, crop_id,
+                                                       std::move(callback));
+}
 #endif
 
 }  // namespace content
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.h b/content/browser/renderer_host/media/media_stream_dispatcher_host.h
index 290ecde7..dd12a56 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.h
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.h
@@ -94,6 +94,14 @@
   void OnStreamStarted(const std::string& label) override;
 #if !defined(OS_ANDROID)
   void FocusCapturedSurface(const std::string& label, bool focus) override;
+  void Crop(const base::UnguessableToken& device_id,
+            const base::Token& crop_id,
+            CropCallback callback) override;
+
+  void OnCropValidationComplete(const base::UnguessableToken& device_id,
+                                const base::Token& crop_id,
+                                CropCallback callback,
+                                bool crop_id_passed_validation);
 #endif
 
   void DoGenerateStream(
diff --git a/content/browser/renderer_host/media/video_capture_controller.h b/content/browser/renderer_host/media/video_capture_controller.h
index 67ad613..8194a18 100644
--- a/content/browser/renderer_host/media/video_capture_controller.h
+++ b/content/browser/renderer_host/media/video_capture_controller.h
@@ -9,7 +9,6 @@
 #include <memory>
 
 #include "base/callback_forward.h"
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
diff --git a/content/browser/renderer_host/media/video_capture_host.cc b/content/browser/renderer_host/media/video_capture_host.cc
index 991fb44..93134eef 100644
--- a/content/browser/renderer_host/media/video_capture_host.cc
+++ b/content/browser/renderer_host/media/video_capture_host.cc
@@ -287,34 +287,6 @@
   }
 }
 
-void VideoCaptureHost::Crop(const base::UnguessableToken& device_id,
-                            const base::Token& crop_id,
-                            CropCallback callback) {
-  DVLOG(1) << __func__ << " " << device_id;
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  const VideoCaptureControllerID& controller_id(device_id);
-  const auto it = controllers_.find(controller_id);
-  if (it == controllers_.end() || !it->second) {
-    std::move(callback).Run(
-        media::mojom::CropRequestResult::kErrorUnknownDeviceId);
-    return;
-  }
-  VideoCaptureController* const controller = it->second.get();
-  DCHECK(controller);  // Verified above.
-
-  if (!controller->IsDeviceAlive()) {
-    std::move(callback).Run(media::mojom::CropRequestResult::kErrorGeneric);
-    return;
-  }
-
-  // TODO(crbug.com/1247761): Validate that the crop-ID was produced
-  // by produceCropId(), and that this was done for this specific tab,
-  // thereby rejecting (a) unknown crop-IDs and (b) other-tab-crops.
-
-  controller->Crop(crop_id, std::move(callback));
-}
-
 void VideoCaptureHost::RequestRefreshFrame(
     const base::UnguessableToken& device_id) {
   DVLOG(1) << __func__ << " " << device_id;
diff --git a/content/browser/renderer_host/media/video_capture_host.h b/content/browser/renderer_host/media/video_capture_host.h
index 560cb91..70a8919 100644
--- a/content/browser/renderer_host/media/video_capture_host.h
+++ b/content/browser/renderer_host/media/video_capture_host.h
@@ -88,9 +88,6 @@
   void Resume(const base::UnguessableToken& device_id,
               const base::UnguessableToken& session_id,
               const media::VideoCaptureParams& params) override;
-  void Crop(const base::UnguessableToken& device_id,
-            const base::Token& crop_id,
-            CropCallback callback) override;
   void RequestRefreshFrame(const base::UnguessableToken& device_id) override;
   void ReleaseBuffer(const base::UnguessableToken& device_id,
                      int32_t buffer_id,
diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc
index 2c604b0c..2e297659 100644
--- a/content/browser/renderer_host/media/video_capture_manager.cc
+++ b/content/browser/renderer_host/media/video_capture_manager.cc
@@ -212,6 +212,21 @@
   sessions_.erase(session_it);
 }
 
+void VideoCaptureManager::Crop(
+    const base::UnguessableToken& session_id,
+    const base::Token& crop_id,
+    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  VideoCaptureController* const controller =
+      LookupControllerBySessionId(session_id);
+  if (!controller || !controller->IsDeviceAlive()) {
+    std::move(callback).Run(media::mojom::CropRequestResult::kErrorGeneric);
+    return;
+  }
+  controller->Crop(crop_id, std::move(callback));
+}
+
 void VideoCaptureManager::QueueStartDevice(
     const media::VideoCaptureSessionId& session_id,
     VideoCaptureController* controller,
diff --git a/content/browser/renderer_host/media/video_capture_manager.h b/content/browser/renderer_host/media/video_capture_manager.h
index 31a16ee..6c4ea67 100644
--- a/content/browser/renderer_host/media/video_capture_manager.h
+++ b/content/browser/renderer_host/media/video_capture_manager.h
@@ -80,6 +80,14 @@
   base::UnguessableToken Open(const blink::MediaStreamDevice& device) override;
   void Close(const base::UnguessableToken& capture_session_id) override;
 
+  // Start/stop cropping the video track.
+  // Non-empty |crop_id| sets (or changes) the crop-target.
+  // Empty |crop_id| reverts the capture to its original, uncropped state.
+  // The callback reports success/failure.
+  void Crop(const base::UnguessableToken& session_id,
+            const base::Token& crop_id,
+            base::OnceCallback<void(media::mojom::CropRequestResult)> callback);
+
   // Called by VideoCaptureHost to locate a capture device for |capture_params|,
   // adding the Host as a client of the device's controller if successful. The
   // value of |session_id| controls which device is selected;
diff --git a/content/browser/renderer_host/navigation_controller_android.h b/content/browser/renderer_host/navigation_controller_android.h
index a35bd8d8..ea42a9e 100644
--- a/content/browser/renderer_host/navigation_controller_android.h
+++ b/content/browser/renderer_host/navigation_controller_android.h
@@ -8,7 +8,6 @@
 #include <jni.h>
 
 #include "base/android/scoped_java_ref.h"
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "content/common/content_export.h"
 #include "url/origin.h"
diff --git a/content/browser/renderer_host/navigation_controller_impl.h b/content/browser/renderer_host/navigation_controller_impl.h
index c36ee04f..ff3e18a 100644
--- a/content/browser/renderer_host/navigation_controller_impl.h
+++ b/content/browser/renderer_host/navigation_controller_impl.h
@@ -14,7 +14,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
diff --git a/content/browser/renderer_host/overscroll_controller.h b/content/browser/renderer_host/overscroll_controller.h
index 12fff70..239bdfc3 100644
--- a/content/browser/renderer_host/overscroll_controller.h
+++ b/content/browser/renderer_host/overscroll_controller.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_BROWSER_RENDERER_HOST_OVERSCROLL_CONTROLLER_H_
 #define CONTENT_BROWSER_RENDERER_HOST_OVERSCROLL_CONTROLLER_H_
 
-#include "base/compiler_specific.h"
 #include "base/time/time.h"
 #include "cc/input/overscroll_behavior.h"
 #include "content/common/content_export.h"
diff --git a/content/browser/renderer_host/overscroll_controller_delegate.h b/content/browser/renderer_host/overscroll_controller_delegate.h
index f56c4735c..1de1f71 100644
--- a/content/browser/renderer_host/overscroll_controller_delegate.h
+++ b/content/browser/renderer_host/overscroll_controller_delegate.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_BROWSER_RENDERER_HOST_OVERSCROLL_CONTROLLER_DELEGATE_H_
 #define CONTENT_BROWSER_RENDERER_HOST_OVERSCROLL_CONTROLLER_DELEGATE_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "content/browser/renderer_host/overscroll_controller.h"
 #include "content/common/content_export.h"
diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h
index 848d7566..edd8873 100644
--- a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h
+++ b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h
@@ -10,7 +10,6 @@
 #include <unordered_map>
 #include <utility>
 
-#include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
diff --git a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h
index 6f0625b1..de61e54 100644
--- a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h
+++ b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
diff --git a/content/browser/renderer_host/pepper/pepper_gamepad_host.h b/content/browser/renderer_host/pepper/pepper_gamepad_host.h
index 397e9ce83..ebb52f0 100644
--- a/content/browser/renderer_host/pepper/pepper_gamepad_host.h
+++ b/content/browser/renderer_host/pepper/pepper_gamepad_host.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "content/common/content_export.h"
diff --git a/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h b/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h
index b4e8605..dc2b03d 100644
--- a/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h
+++ b/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h
@@ -10,7 +10,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "content/public/common/process_type.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "ppapi/c/pp_instance.h"
diff --git a/content/browser/renderer_host/pepper/pepper_network_monitor_host.h b/content/browser/renderer_host/pepper/pepper_network_monitor_host.h
index ea4d880b..7bffaab 100644
--- a/content/browser/renderer_host/pepper/pepper_network_monitor_host.h
+++ b/content/browser/renderer_host/pepper/pepper_network_monitor_host.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_NETWORK_MONITOR_HOST_H_
 #define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_NETWORK_MONITOR_HOST_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "net/base/network_interfaces.h"
diff --git a/content/browser/renderer_host/pepper/pepper_network_proxy_host.h b/content/browser/renderer_host/pepper/pepper_network_proxy_host.h
index 662b436a..ba3afc4 100644
--- a/content/browser/renderer_host/pepper/pepper_network_proxy_host.h
+++ b/content/browser/renderer_host/pepper/pepper_network_proxy_host.h
@@ -11,7 +11,6 @@
 #include <set>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/containers/queue.h"
 #include "base/containers/unique_ptr_adapters.h"
 #include "base/memory/weak_ptr.h"
diff --git a/content/browser/renderer_host/pepper/pepper_print_settings_manager.h b/content/browser/renderer_host/pepper/pepper_print_settings_manager.h
index c9701354..87f0d8e 100644
--- a/content/browser/renderer_host/pepper/pepper_print_settings_manager.h
+++ b/content/browser/renderer_host/pepper/pepper_print_settings_manager.h
@@ -8,7 +8,6 @@
 #include <stdint.h>
 
 #include "base/bind.h"
-#include "base/compiler_specific.h"
 #include "ppapi/c/dev/pp_print_settings_dev.h"
 
 namespace content {
diff --git a/content/browser/renderer_host/pepper/pepper_printing_host.h b/content/browser/renderer_host/pepper/pepper_printing_host.h
index 0b6d8e5..46242d6 100644
--- a/content/browser/renderer_host/pepper/pepper_printing_host.h
+++ b/content/browser/renderer_host/pepper/pepper_printing_host.h
@@ -9,7 +9,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "content/browser/renderer_host/pepper/pepper_print_settings_manager.h"
 #include "content/common/content_export.h"
diff --git a/content/browser/renderer_host/pepper/pepper_renderer_connection.h b/content/browser/renderer_host/pepper/pepper_renderer_connection.h
index 77af23373..447b483 100644
--- a/content/browser/renderer_host/pepper/pepper_renderer_connection.h
+++ b/content/browser/renderer_host/pepper/pepper_renderer_connection.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "content/common/pepper_plugin.mojom.h"
 #include "content/public/browser/browser_message_filter.h"
diff --git a/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h b/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h
index ce31694..0350c00 100644
--- a/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h
+++ b/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h
@@ -10,7 +10,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h
index 6baca2d6..fdd9f1b 100644
--- a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h
+++ b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h
@@ -12,7 +12,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
diff --git a/content/browser/renderer_host/pepper/pepper_truetype_font_host.h b/content/browser/renderer_host/pepper/pepper_truetype_font_host.h
index effd851c..9da7c62c 100644
--- a/content/browser/renderer_host/pepper/pepper_truetype_font_host.h
+++ b/content/browser/renderer_host/pepper/pepper_truetype_font_host.h
@@ -11,7 +11,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "base/task/sequenced_task_runner.h"
 #include "content/browser/renderer_host/pepper/pepper_truetype_font.h"
diff --git a/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h b/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h
index 4cac299a..f240e95 100644
--- a/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h
+++ b/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h
@@ -13,7 +13,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/containers/queue.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
diff --git a/content/browser/renderer_host/popup_menu_helper_mac.h b/content/browser/renderer_host/popup_menu_helper_mac.h
index cc1391c1b..8ce4d28 100644
--- a/content/browser/renderer_host/popup_menu_helper_mac.h
+++ b/content/browser/renderer_host/popup_menu_helper_mac.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
 #include "content/common/content_export.h"
diff --git a/content/browser/renderer_host/render_frame_host_android.h b/content/browser/renderer_host/render_frame_host_android.h
index 1d564ec..f4f1525 100644
--- a/content/browser/renderer_host/render_frame_host_android.h
+++ b/content/browser/renderer_host/render_frame_host_android.h
@@ -10,7 +10,6 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_weak_ref.h"
 #include "base/android/scoped_java_ref.h"
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/supports_user_data.h"
 
diff --git a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
index db775c8..3f6b3b2 100644
--- a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
@@ -7569,8 +7569,17 @@
                     ActionAfterPagehide::kNavigation, 1);
 }
 
+// TODO(crbug.com/1274974): Make this work with NavigationThreadingOptimizations
+// enabled.
+#if defined(OS_MAC)
+#define MAYBE_PostMessageAfterPagehideHistogram \
+  DISABLED_PostMessageAfterPagehideHistogram
+#else
+#define MAYBE_PostMessageAfterPagehideHistogram \
+  PostMessageAfterPagehideHistogram
+#endif
 IN_PROC_BROWSER_TEST_P(ProactivelySwapBrowsingInstancesSameSiteTest,
-                       PostMessageAfterPagehideHistogram) {
+                       MAYBE_PostMessageAfterPagehideHistogram) {
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL url_a1(embedded_test_server()->GetURL("a.com", "/title1.html"));
   GURL url_a2(embedded_test_server()->GetURL("a.com", "/title2.html"));
@@ -7624,8 +7633,17 @@
   }
 }
 
+// TODO(crbug.com/1274974): Make this work with NavigationThreadingOptimizations
+// enabled.
+#if defined(OS_MAC)
+#define MAYBE_PostMessageAfterPagehideHistogramSubframe \
+  DISABLED_PostMessageAfterPagehideHistogramSubframe
+#else
+#define MAYBE_PostMessageAfterPagehideHistogramSubframe \
+  PostMessageAfterPagehideHistogramSubframe
+#endif
 IN_PROC_BROWSER_TEST_P(ProactivelySwapBrowsingInstancesSameSiteTest,
-                       PostMessageAfterPagehideHistogramSubframe) {
+                       MAYBE_PostMessageAfterPagehideHistogramSubframe) {
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL url_a1(embedded_test_server()->GetURL(
       "a.com", "/cross_site_iframe_factory.html?a(a)"));
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h
index 7f80bfbf..0bbf5b0a 100644
--- a/content/browser/renderer_host/render_view_host_impl.h
+++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -14,7 +14,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index 525c32cf..f13fd54f6 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -15,7 +15,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
diff --git a/content/browser/screen_orientation/screen_orientation_provider.h b/content/browser/screen_orientation/screen_orientation_provider.h
index 2787407..1d09f408 100644
--- a/content/browser/screen_orientation/screen_orientation_provider.h
+++ b/content/browser/screen_orientation/screen_orientation_provider.h
@@ -6,7 +6,6 @@
 #define CONTENT_BROWSER_SCREEN_ORIENTATION_SCREEN_ORIENTATION_PROVIDER_H_
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/render_frame_host_receiver_set.h"
 #include "content/public/browser/web_contents_observer.h"
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc
index 5512ae6..46e885f 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -394,6 +394,9 @@
     const blink::StorageKey& key) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
+  if (is_deleting_and_starting_over_)
+    return;
+
   // TODO(crbug.com/1199077): Update this when ServiceWorkerContextCoreObserver
   // implements StorageKey.
   auto insertion_result = running_service_workers_.insert(std::make_pair(
@@ -418,6 +421,7 @@
 }
 
 void ServiceWorkerContextWrapper::OnDeleteAndStartOver() {
+  is_deleting_and_starting_over_ = true;
   ClearRunningServiceWorkers();
 }
 
@@ -1270,6 +1274,8 @@
 void ServiceWorkerContextWrapper::DidDeleteAndStartOver(
     blink::ServiceWorkerStatusCode status) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DCHECK(running_service_workers_.empty());
+  is_deleting_and_starting_over_ = false;
   storage_control_.reset();
   if (status != blink::ServiceWorkerStatusCode::kOk) {
     context_core_.reset();
diff --git a/content/browser/service_worker/service_worker_context_wrapper.h b/content/browser/service_worker/service_worker_context_wrapper.h
index 21e61d1..ffd6d90 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.h
+++ b/content/browser/service_worker/service_worker_context_wrapper.h
@@ -535,6 +535,10 @@
   // Initialized in Init(); true if the user data directory is empty.
   bool is_incognito_ = false;
 
+  // Indicates if we are in the middle of deleting the `context_core_` in
+  // order to start over.
+  bool is_deleting_and_starting_over_ = false;
+
   // Raw pointer to the StoragePartitionImpl owning |this|.
   raw_ptr<StoragePartitionImpl> storage_partition_ = nullptr;
 
diff --git a/content/browser/speech/speech_recognition_manager_impl.h b/content/browser/speech/speech_recognition_manager_impl.h
index 5cc93966..d81533c 100644
--- a/content/browser/speech/speech_recognition_manager_impl.h
+++ b/content/browser/speech/speech_recognition_manager_impl.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/containers/flat_map.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
diff --git a/content/browser/web_contents/web_contents_android.h b/content/browser/web_contents/web_contents_android.h
index a0d8166..32f1cd3 100644
--- a/content/browser/web_contents/web_contents_android.h
+++ b/content/browser/web_contents/web_contents_android.h
@@ -10,7 +10,6 @@
 #include <memory>
 
 #include "base/android/jni_android.h"
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "content/browser/renderer_host/navigation_controller_android.h"
diff --git a/content/browser/webui/url_data_manager_backend.h b/content/browser/webui/url_data_manager_backend.h
index 3bb29ef..a1dcd226 100644
--- a/content/browser/webui/url_data_manager_backend.h
+++ b/content/browser/webui/url_data_manager_backend.h
@@ -10,7 +10,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "base/supports_user_data.h"
 #include "base/values.h"
diff --git a/content/browser/webui/web_ui_data_source_impl.h b/content/browser/webui/web_ui_data_source_impl.h
index 2d92bfe2..a05ed92 100644
--- a/content/browser/webui/web_ui_data_source_impl.h
+++ b/content/browser/webui/web_ui_data_source_impl.h
@@ -11,7 +11,6 @@
 #include <string>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/containers/flat_map.h"
 #include "base/gtest_prod_util.h"
 #include "base/values.h"
diff --git a/content/browser/webui/web_ui_impl.h b/content/browser/webui/web_ui_impl.h
index f1ef9b80..1a17f8f 100644
--- a/content/browser/webui/web_ui_impl.h
+++ b/content/browser/webui/web_ui_impl.h
@@ -11,7 +11,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "content/common/content_export.h"
diff --git a/content/browser/worker_host/shared_worker_service_impl.h b/content/browser/worker_host/shared_worker_service_impl.h
index 8582a0e..8e762db 100644
--- a/content/browser/worker_host/shared_worker_service_impl.h
+++ b/content/browser/worker_host/shared_worker_service_impl.h
@@ -10,7 +10,6 @@
 #include <string>
 #include <utility>
 
-#include "base/compiler_specific.h"
 #include "base/containers/unique_ptr_adapters.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h
index 7f2dc700..09c5bc09 100644
--- a/content/child/blink_platform_impl.h
+++ b/content/child/blink_platform_impl.h
@@ -8,7 +8,6 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "base/compiler_specific.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/timer/timer.h"
 #include "build/build_config.h"
diff --git a/content/ppapi_plugin/ppapi_thread.h b/content/ppapi_plugin/ppapi_thread.h
index 79974b14..654c49e 100644
--- a/content/ppapi_plugin/ppapi_thread.h
+++ b/content/ppapi_plugin/ppapi_thread.h
@@ -11,7 +11,6 @@
 #include <memory>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/process/process.h"
 #include "base/scoped_native_library.h"
 #include "build/build_config.h"
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
index 9e140076..de8003c1 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
@@ -19,6 +19,7 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.test.util.Batch;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.FlakyTest;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.content_public.browser.test.ContentJUnit4ClassRunner;
@@ -31,6 +32,7 @@
 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
 @SuppressLint("VisibleForTests")
 @Batch(Batch.UNIT_TESTS)
+@DisabledTest(message = "https://crbug.com/1261677")
 public class WebContentsAccessibilityEventsTest {
     // File path that holds all the relevant tests.
     private static final String BASE_FILE_PATH = "content/test/data/accessibility/event/";
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index 21cfede5..3e9f997 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -442,6 +442,7 @@
   }
 
   public_deps = [
+    "//base",
     "//build:chromecast_buildflags",
     "//components/download/public/common:public",
     "//components/services/storage/public/mojom",
diff --git a/content/public/browser/browser_main_parts.cc b/content/public/browser/browser_main_parts.cc
index e1a07b5..05efd69b 100644
--- a/content/public/browser/browser_main_parts.cc
+++ b/content/public/browser/browser_main_parts.cc
@@ -20,4 +20,8 @@
   return RESULT_CODE_NORMAL_EXIT;
 }
 
+bool BrowserMainParts::ShouldInterceptMainMessageLoopRun() {
+  return true;
+}
+
 }  // namespace content
diff --git a/content/public/browser/browser_main_parts.h b/content/public/browser/browser_main_parts.h
index 497eb07..da32e765 100644
--- a/content/public/browser/browser_main_parts.h
+++ b/content/public/browser/browser_main_parts.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/callback.h"
+#include "base/types/strong_alias.h"
 #include "content/common/content_export.h"
 
 namespace base {
@@ -131,9 +132,24 @@
   virtual void PostCreateThreads() {}
   virtual int PreMainMessageLoopRun();
 
+  // This method returns true by default, telling InterceptMainMessageLoopRun
+  // that it should attempt to intercept the main message loop run. Overriding
+  // it enables the embedder to conditionally cancel that attempt and the
+  // message loop run itself(by returning false). This is key in some
+  // integration tests that verify early exit by testing that the test body
+  // (entered when the main message loop run is intercepted) is never entered.
+  // On Android, BrowserMainLoop never enters MainMessageLoopRun() but this
+  // method is still relevant to control whether InterceptMainMessageLoopRun()
+  // is allowed to take control of the browser main loop (browser tests).
+  virtual bool ShouldInterceptMainMessageLoopRun();
+
   // This gives BrowserMainParts one last opportunity to tweak the upcoming main
   // message loop run. The embedder may replace |run_loop| to alter the default
-  // RunLoop about to be run or even reset() it to cancel the upcoming run.
+  // RunLoop about to be run (must not be nullified, override
+  // CanRunMainMessageLoop to cancel the run). Note: This point is never
+  // reached on Android as it never invokes MainMessageLoopRun(),
+  // InterceptMainMessageLoopRun() is Android's last chance at altering the
+  // default native loop run.
   virtual void WillRunMainMessageLoop(
       std::unique_ptr<base::RunLoop>& run_loop) {}
 
diff --git a/content/public/browser/devtools_agent_host_client.cc b/content/public/browser/devtools_agent_host_client.cc
index 34f075a..e6f7cd5 100644
--- a/content/public/browser/devtools_agent_host_client.cc
+++ b/content/public/browser/devtools_agent_host_client.cc
@@ -15,6 +15,10 @@
   return true;
 }
 
+bool DevToolsAgentHostClient::MaySendInputEventsToBrowser() {
+  return MayAttachToBrowser();
+}
+
 // File access is allowed by default, only restricted clients that represent
 // not entirely trusted protocol peers override this to false.
 bool DevToolsAgentHostClient::MayReadLocalFiles() {
diff --git a/content/public/browser/devtools_agent_host_client.h b/content/public/browser/devtools_agent_host_client.h
index 1d4e818..221e9da 100644
--- a/content/public/browser/devtools_agent_host_client.h
+++ b/content/public/browser/devtools_agent_host_client.h
@@ -35,6 +35,9 @@
   // manipulate browser altogether.
   virtual bool MayAttachToBrowser();
 
+  // Returns true if the client is allowed to send input events to the browser.
+  virtual bool MaySendInputEventsToBrowser();
+
   // Returns true if the client is allowed to read local files over the
   // protocol. Example would be exposing file content to the page under debug.
   virtual bool MayReadLocalFiles();
diff --git a/content/public/browser/native_web_keyboard_event.h b/content/public/browser/native_web_keyboard_event.h
index 906fe46..f5c7dfa 100644
--- a/content/public/browser/native_web_keyboard_event.h
+++ b/content/public/browser/native_web_keyboard_event.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_PUBLIC_BROWSER_NATIVE_WEB_KEYBOARD_EVENT_H_
 #define CONTENT_PUBLIC_BROWSER_NATIVE_WEB_KEYBOARD_EVENT_H_
 
-#include "base/compiler_specific.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "content/common/content_export.h"
diff --git a/content/public/browser/provision_fetcher_impl.h b/content/public/browser/provision_fetcher_impl.h
index c697689..69ae1f6c 100644
--- a/content/public/browser/provision_fetcher_impl.h
+++ b/content/public/browser/provision_fetcher_impl.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/provision_fetcher_factory.h"
diff --git a/content/public/browser/screenlock_observer.h b/content/public/browser/screenlock_observer.h
index 9eff0ab..b3c28fb 100644
--- a/content/public/browser/screenlock_observer.h
+++ b/content/public/browser/screenlock_observer.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_PUBLIC_BROWSER_SCREENLOCK_OBSERVER_H_
 #define CONTENT_PUBLIC_BROWSER_SCREENLOCK_OBSERVER_H_
 
-#include "base/compiler_specific.h"
 #include "content/common/content_export.h"
 
 namespace content {
diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h
index 316b673..f6d262f1b 100644
--- a/content/public/renderer/render_frame_observer.h
+++ b/content/public/renderer/render_frame_observer.h
@@ -9,7 +9,6 @@
 
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/memory/read_only_shared_memory_region.h"
 #include "build/build_config.h"
 #include "content/common/content_export.h"
diff --git a/content/public/test/browser_test.h b/content/public/test/browser_test.h
index 08ce269f..74734c3 100644
--- a/content/public/test/browser_test.h
+++ b/content/public/test/browser_test.h
@@ -15,7 +15,6 @@
 #error Can't reliably terminate hanging event tests without OOP test runner.
 #endif
 
-#include "base/compiler_specific.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 #define IN_PROC_BROWSER_TEST_(                                               \
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc
index 904b8eed..8c181cab 100644
--- a/content/public/test/browser_test_base.cc
+++ b/content/public/test/browser_test_base.cc
@@ -765,6 +765,14 @@
 #endif
 
 void BrowserTestBase::ProxyRunTestOnMainThreadLoop() {
+  // Chrome bans unresponsive tasks just before starting the main message loop.
+  // Re-allow such tasks while for init / tear down
+  // (ScopedDisallowBlocking objects below ensure the test body is tested under
+  // the same blocking-ban as the regular main message loop).
+  // TODO(crbug.com/1253634): Remove this wide allowance in favor of localized
+  // allowances for init/teardown phases.
+  base::ScopedAllowUnresponsiveTasksForTesting allow_for_init;
+
 #if !defined(OS_ANDROID)
   // All FeatureList overrides should have been registered prior to browser test
   // SetUp(). Note that on Android, this scoper lives in SetUp() above.
diff --git a/content/public/test/browser_test_base.h b/content/public/test/browser_test_base.h
index b0aa9f5f..76730e0 100644
--- a/content/public/test/browser_test_base.h
+++ b/content/public/test/browser_test_base.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/metrics/field_trial.h"
 #include "base/threading/thread.h"
diff --git a/content/public/test/content_test_suite_base.h b/content/public/test/content_test_suite_base.h
index 32b4da3..ee3285e 100644
--- a/content/public/test/content_test_suite_base.h
+++ b/content/public/test/content_test_suite_base.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_PUBLIC_TEST_CONTENT_TEST_SUITE_BASE_H_
 #define CONTENT_PUBLIC_TEST_CONTENT_TEST_SUITE_BASE_H_
 
-#include "base/compiler_specific.h"
 #include "base/test/test_suite.h"
 
 namespace content {
diff --git a/content/public/test/javascript_test_observer.h b/content/public/test/javascript_test_observer.h
index 3969d5a..27d066b 100644
--- a/content/public/test/javascript_test_observer.h
+++ b/content/public/test/javascript_test_observer.h
@@ -7,7 +7,6 @@
 
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
diff --git a/content/public/test/mock_resource_context.h b/content/public/test/mock_resource_context.h
index 191ddd4c..dddd466 100644
--- a/content/public/test/mock_resource_context.h
+++ b/content/public/test/mock_resource_context.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_PUBLIC_TEST_MOCK_RESOURCE_CONTEXT_H_
 #define CONTENT_PUBLIC_TEST_MOCK_RESOURCE_CONTEXT_H_
 
-#include "base/compiler_specific.h"
 #include "content/public/browser/resource_context.h"
 
 namespace content {
diff --git a/content/public/test/nested_message_pump_android.h b/content/public/test/nested_message_pump_android.h
index 48f9e05..48e685c9 100644
--- a/content/public/test/nested_message_pump_android.h
+++ b/content/public/test/nested_message_pump_android.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_PUBLIC_TEST_NESTED_MESSAGE_PUMP_ANDROID_H_
 #define CONTENT_PUBLIC_TEST_NESTED_MESSAGE_PUMP_ANDROID_H_
 
-#include "base/compiler_specific.h"
 #include "base/message_loop/message_pump_android.h"
 
 namespace content {
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc
index 4dcf28d..3e83516 100644
--- a/content/public/test/render_view_test.cc
+++ b/content/public/test/render_view_test.cc
@@ -629,8 +629,7 @@
 
 void RenderViewTest::SendInputEvent(const blink::WebInputEvent& input_event) {
   GetWebFrameWidget()->ProcessInputEventSynchronouslyForTesting(
-      blink::WebCoalescedInputEvent(input_event, ui::LatencyInfo()),
-      base::DoNothing());
+      blink::WebCoalescedInputEvent(input_event, ui::LatencyInfo()));
 }
 
 void RenderViewTest::SendWebKeyboardEvent(
@@ -711,12 +710,10 @@
   mouse_event.SetPositionInWidget(point.x(), point.y());
   mouse_event.click_count = 1;
   GetWebFrameWidget()->ProcessInputEventSynchronouslyForTesting(
-      blink::WebCoalescedInputEvent(mouse_event, ui::LatencyInfo()),
-      base::DoNothing());
+      blink::WebCoalescedInputEvent(mouse_event, ui::LatencyInfo()));
   mouse_event.SetType(WebInputEvent::Type::kMouseUp);
   GetWebFrameWidget()->ProcessInputEventSynchronouslyForTesting(
-      blink::WebCoalescedInputEvent(mouse_event, ui::LatencyInfo()),
-      base::DoNothing());
+      blink::WebCoalescedInputEvent(mouse_event, ui::LatencyInfo()));
 }
 
 bool RenderViewTest::SimulateElementRightClick(const std::string& element_id) {
@@ -734,12 +731,10 @@
   mouse_event.SetPositionInWidget(point.x(), point.y());
   mouse_event.click_count = 1;
   GetWebFrameWidget()->ProcessInputEventSynchronouslyForTesting(
-      blink::WebCoalescedInputEvent(mouse_event, ui::LatencyInfo()),
-      base::DoNothing());
+      blink::WebCoalescedInputEvent(mouse_event, ui::LatencyInfo()));
   mouse_event.SetType(WebInputEvent::Type::kMouseUp);
   GetWebFrameWidget()->ProcessInputEventSynchronouslyForTesting(
-      blink::WebCoalescedInputEvent(mouse_event, ui::LatencyInfo()),
-      base::DoNothing());
+      blink::WebCoalescedInputEvent(mouse_event, ui::LatencyInfo()));
 }
 
 void RenderViewTest::SimulateRectTap(const gfx::Rect& rect) {
@@ -751,8 +746,7 @@
   gesture_event.data.tap.width = rect.width();
   gesture_event.data.tap.height = rect.height();
   GetWebFrameWidget()->ProcessInputEventSynchronouslyForTesting(
-      blink::WebCoalescedInputEvent(gesture_event, ui::LatencyInfo()),
-      base::DoNothing());
+      blink::WebCoalescedInputEvent(gesture_event, ui::LatencyInfo()));
 }
 
 void RenderViewTest::SetFocused(const blink::WebElement& element) {
diff --git a/content/public/test/test_browser_context.h b/content/public/test/test_browser_context.h
index f459c8c..1e492def 100644
--- a/content/public/test/test_browser_context.h
+++ b/content/public/test/test_browser_context.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/ref_counted.h"
diff --git a/content/public/test/test_fileapi_operation_waiter.h b/content/public/test/test_fileapi_operation_waiter.h
index d870606..e6b79e4 100644
--- a/content/public/test/test_fileapi_operation_waiter.h
+++ b/content/public/test/test_fileapi_operation_waiter.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include "base/compiler_specific.h"
 #include "base/files/file.h"
 #include "base/run_loop.h"
 #include "storage/browser/file_system/file_observers.h"
diff --git a/content/public/test/test_notification_tracker.h b/content/public/test/test_notification_tracker.h
index 1592223e..a1928cce 100644
--- a/content/public/test/test_notification_tracker.h
+++ b/content/public/test/test_notification_tracker.h
@@ -9,7 +9,6 @@
 
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
diff --git a/content/renderer/pepper/content_renderer_pepper_host_factory.h b/content/renderer/pepper/content_renderer_pepper_host_factory.h
index 013736c..57accf36 100644
--- a/content/renderer/pepper/content_renderer_pepper_host_factory.h
+++ b/content/renderer/pepper/content_renderer_pepper_host_factory.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_RENDERER_PEPPER_CONTENT_RENDERER_PEPPER_HOST_FACTORY_H_
 #define CONTENT_RENDERER_PEPPER_CONTENT_RENDERER_PEPPER_HOST_FACTORY_H_
 
-#include "base/compiler_specific.h"
 #include "ppapi/host/host_factory.h"
 #include "ppapi/shared_impl/ppapi_permissions.h"
 
diff --git a/content/renderer/pepper/host_globals.h b/content/renderer/pepper/host_globals.h
index 160eb41b..ff93b473 100644
--- a/content/renderer/pepper/host_globals.h
+++ b/content/renderer/pepper/host_globals.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_RENDERER_PEPPER_HOST_GLOBALS_H_
 #define CONTENT_RENDERER_PEPPER_HOST_GLOBALS_H_
 
-#include "base/compiler_specific.h"
 #include "content/renderer/pepper/host_var_tracker.h"
 #include "ppapi/shared_impl/callback_tracker.h"
 #include "ppapi/shared_impl/ppapi_globals.h"
diff --git a/content/renderer/pepper/host_var_tracker.h b/content/renderer/pepper/host_var_tracker.h
index 58ea0db7..86fefe147 100644
--- a/content/renderer/pepper/host_var_tracker.h
+++ b/content/renderer/pepper/host_var_tracker.h
@@ -9,7 +9,6 @@
 
 #include <map>
 
-#include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "content/common/content_export.h"
 #include "ppapi/c/pp_instance.h"
diff --git a/content/renderer/pepper/pepper_audio_input_host.h b/content/renderer/pepper/pepper_audio_input_host.h
index 66699bec..abfab59 100644
--- a/content/renderer/pepper/pepper_audio_input_host.h
+++ b/content/renderer/pepper/pepper_audio_input_host.h
@@ -11,7 +11,6 @@
 #include <memory>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/memory/read_only_shared_memory_region.h"
 #include "base/sync_socket.h"
 #include "content/renderer/pepper/pepper_device_enumeration_host_helper.h"
diff --git a/content/renderer/pepper/pepper_audio_output_host.h b/content/renderer/pepper/pepper_audio_output_host.h
index 5a08a2f..d17c28e 100644
--- a/content/renderer/pepper/pepper_audio_output_host.h
+++ b/content/renderer/pepper/pepper_audio_output_host.h
@@ -11,7 +11,6 @@
 #include <memory>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/memory/unsafe_shared_memory_region.h"
 #include "base/sync_socket.h"
 #include "content/renderer/pepper/pepper_device_enumeration_host_helper.h"
diff --git a/content/renderer/pepper/pepper_graphics_2d_host.h b/content/renderer/pepper/pepper_graphics_2d_host.h
index 430ace5..db6addd9 100644
--- a/content/renderer/pepper/pepper_graphics_2d_host.h
+++ b/content/renderer/pepper/pepper_graphics_2d_host.h
@@ -9,7 +9,6 @@
 
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "cc/paint/paint_canvas.h"
 #include "cc/resources/shared_bitmap_id_registrar.h"
diff --git a/content/renderer/pepper/pepper_media_stream_audio_track_host.h b/content/renderer/pepper/pepper_media_stream_audio_track_host.h
index ab9672e..2c1c8f44 100644
--- a/content/renderer/pepper/pepper_media_stream_audio_track_host.h
+++ b/content/renderer/pepper/pepper_media_stream_audio_track_host.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include "base/compiler_specific.h"
 #include "base/containers/circular_deque.h"
 #include "base/memory/weak_ptr.h"
 #include "base/synchronization/lock.h"
diff --git a/content/renderer/pepper/pepper_media_stream_track_host_base.h b/content/renderer/pepper/pepper_media_stream_track_host_base.h
index 90664c3..e987fb40 100644
--- a/content/renderer/pepper/pepper_media_stream_track_host_base.h
+++ b/content/renderer/pepper/pepper_media_stream_track_host_base.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include "base/compiler_specific.h"
 #include "ppapi/host/resource_host.h"
 #include "ppapi/shared_impl/media_stream_buffer_manager.h"
 
diff --git a/content/renderer/pepper/pepper_media_stream_video_track_host.h b/content/renderer/pepper/pepper_media_stream_video_track_host.h
index c4e3699..6ef832c 100644
--- a/content/renderer/pepper/pepper_media_stream_video_track_host.h
+++ b/content/renderer/pepper/pepper_media_stream_video_track_host.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "content/renderer/pepper/pepper_media_stream_track_host_base.h"
 #include "media/base/video_frame.h"
diff --git a/content/renderer/pepper/pepper_platform_audio_input.h b/content/renderer/pepper/pepper_platform_audio_input.h
index 4ae6c97..0812896 100644
--- a/content/renderer/pepper/pepper_platform_audio_input.h
+++ b/content/renderer/pepper/pepper_platform_audio_input.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "ipc/ipc_message.h"
diff --git a/content/renderer/pepper/pepper_platform_camera_device.h b/content/renderer/pepper/pepper_platform_camera_device.h
index a7d0511b..1849d2f 100644
--- a/content/renderer/pepper/pepper_platform_camera_device.h
+++ b/content/renderer/pepper/pepper_platform_camera_device.h
@@ -9,7 +9,6 @@
 #include <string>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
 #include "base/unguessable_token.h"
diff --git a/content/renderer/pepper/pepper_platform_video_capture.h b/content/renderer/pepper/pepper_platform_video_capture.h
index d34bf27..9132fdb 100644
--- a/content/renderer/pepper/pepper_platform_video_capture.h
+++ b/content/renderer/pepper/pepper_platform_video_capture.h
@@ -9,7 +9,6 @@
 #include <string>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h
index e282df69..68f28f2 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.h
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.h
@@ -16,7 +16,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "build/build_config.h"
diff --git a/content/renderer/pepper/pepper_proxy_channel_delegate_impl.h b/content/renderer/pepper/pepper_proxy_channel_delegate_impl.h
index f75a84b..efd09a4 100644
--- a/content/renderer/pepper/pepper_proxy_channel_delegate_impl.h
+++ b/content/renderer/pepper/pepper_proxy_channel_delegate_impl.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_RENDERER_PEPPER_PEPPER_PROXY_CHANNEL_DELEGATE_IMPL_H_
 #define CONTENT_RENDERER_PEPPER_PEPPER_PROXY_CHANNEL_DELEGATE_IMPL_H_
 
-#include "base/compiler_specific.h"
 #include "ppapi/proxy/proxy_channel.h"
 
 namespace content {
diff --git a/content/renderer/pepper/pepper_video_capture_host.h b/content/renderer/pepper/pepper_video_capture_host.h
index 31ac5062b..09b7999 100644
--- a/content/renderer/pepper/pepper_video_capture_host.h
+++ b/content/renderer/pepper/pepper_video_capture_host.h
@@ -10,7 +10,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "content/public/renderer/renderer_ppapi_host.h"
 #include "content/renderer/pepper/pepper_device_enumeration_host_helper.h"
diff --git a/content/renderer/pepper/ppb_video_decoder_impl.h b/content/renderer/pepper/ppb_video_decoder_impl.h
index c4c3e9b..9638bdf 100644
--- a/content/renderer/pepper/ppb_video_decoder_impl.h
+++ b/content/renderer/pepper/ppb_video_decoder_impl.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "media/video/video_decode_accelerator.h"
 #include "ppapi/c/dev/pp_video_dev.h"
diff --git a/content/renderer/pepper/resource_converter.h b/content/renderer/pepper/resource_converter.h
index 8e223d13..c37e19a 100644
--- a/content/renderer/pepper/resource_converter.h
+++ b/content/renderer/pepper/resource_converter.h
@@ -8,7 +8,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "content/common/content_export.h"
 #include "content/renderer/pepper/host_resource_var.h"
diff --git a/content/renderer/pepper/resource_creation_impl.h b/content/renderer/pepper/resource_creation_impl.h
index ce446c4ad9..73adbe1 100644
--- a/content/renderer/pepper/resource_creation_impl.h
+++ b/content/renderer/pepper/resource_creation_impl.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include "base/compiler_specific.h"
 #include "ppapi/thunk/resource_creation_api.h"
 
 namespace content {
diff --git a/content/renderer/pepper/v8_var_converter.h b/content/renderer/pepper/v8_var_converter.h
index 86c8a4e7..69fa2fe 100644
--- a/content/renderer/pepper/v8_var_converter.h
+++ b/content/renderer/pepper/v8_var_converter.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "content/common/content_export.h"
 #include "ppapi/c/pp_instance.h"
 #include "ppapi/c/pp_var.h"
diff --git a/content/renderer/pepper/v8object_var.h b/content/renderer/pepper/v8object_var.h
index e27cfc8c..51c8d4d 100644
--- a/content/renderer/pepper/v8object_var.h
+++ b/content/renderer/pepper/v8object_var.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_RENDERER_PEPPER_V8OBJECT_VAR_H_
 #define CONTENT_RENDERER_PEPPER_V8OBJECT_VAR_H_
 
-#include "base/compiler_specific.h"
 #include "content/common/content_export.h"
 #include "ppapi/c/pp_instance.h"
 #include "ppapi/shared_impl/var.h"
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index d1e44b52..a00e5ab 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -11,7 +11,6 @@
 #include <memory>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/containers/id_map.h"
 #include "base/synchronization/lock.h"
 #include "base/task/single_thread_task_runner.h"
diff --git a/content/renderer/service_worker/web_service_worker_provider_impl.h b/content/renderer/service_worker/web_service_worker_provider_impl.h
index 6360f69..92440056 100644
--- a/content/renderer/service_worker/web_service_worker_provider_impl.h
+++ b/content/renderer/service_worker/web_service_worker_provider_impl.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "content/common/content_export.h"
diff --git a/content/renderer/v8_value_converter_impl.h b/content/renderer/v8_value_converter_impl.h
index 9e1e915..f0484c1 100644
--- a/content/renderer/v8_value_converter_impl.h
+++ b/content/renderer/v8_value_converter_impl.h
@@ -7,7 +7,6 @@
 
 #include <map>
 
-#include "base/compiler_specific.h"
 #include "content/common/content_export.h"
 #include "content/public/renderer/v8_value_converter.h"
 
diff --git a/content/renderer/v8_value_converter_impl_unittest.cc b/content/renderer/v8_value_converter_impl_unittest.cc
index 33dcea1..28b76424 100644
--- a/content/renderer/v8_value_converter_impl_unittest.cc
+++ b/content/renderer/v8_value_converter_impl_unittest.cc
@@ -111,12 +111,12 @@
   }
 
   std::string GetString(base::ListValue* value, uint32_t index) {
-    std::string temp;
-    if (!value->GetString(static_cast<size_t>(index), &temp)) {
+    base::Value::ConstListView value_list = value->GetList();
+    if (index >= value_list.size() || !value_list[index].is_string()) {
       ADD_FAILURE();
       return std::string();
     }
-    return temp;
+    return value_list[index].GetString();
   }
 
   std::string GetString(v8::Local<v8::Array> value, uint32_t index) {
diff --git a/content/renderer/webgraphicscontext3d_provider_impl.h b/content/renderer/webgraphicscontext3d_provider_impl.h
index b7466c4..c96bd8fe 100644
--- a/content/renderer/webgraphicscontext3d_provider_impl.h
+++ b/content/renderer/webgraphicscontext3d_provider_impl.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_RENDERER_WEBGRAPHICSCONTEXT3D_PROVIDER_IMPL_H_
 #define CONTENT_RENDERER_WEBGRAPHICSCONTEXT3D_PROVIDER_IMPL_H_
 
-#include "base/compiler_specific.h"
 #include "base/containers/flat_map.h"
 #include "base/memory/ref_counted.h"
 #include "components/viz/common/gpu/context_provider.h"
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index 141b435..36d36ad3 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -366,7 +366,7 @@
   if (is_chromeos_lacros) {
     deps += [
       "//chromeos/dbus/constants",
-      "//chromeos/lacros",
+      "//chromeos/lacros/dbus",
     ]
   }
 
diff --git a/content/shell/app/shell_crash_reporter_client.h b/content/shell/app/shell_crash_reporter_client.h
index 2da83e0..3add8ba 100644
--- a/content/shell/app/shell_crash_reporter_client.h
+++ b/content/shell/app/shell_crash_reporter_client.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_SHELL_APP_SHELL_CRASH_REPORTER_CLIENT_H_
 #define CONTENT_SHELL_APP_SHELL_CRASH_REPORTER_CLIENT_H_
 
-#include "base/compiler_specific.h"
 #include "build/build_config.h"
 #include "components/crash/core/app/crash_reporter_client.h"
 
diff --git a/content/shell/app/shell_main_delegate.h b/content/shell/app/shell_main_delegate.h
index f10a031a..48f5c21 100644
--- a/content/shell/app/shell_main_delegate.h
+++ b/content/shell/app/shell_main_delegate.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "build/build_config.h"
 #include "content/public/app/content_main_delegate.h"
 
diff --git a/content/shell/browser/shell_browser_context.h b/content/shell/browser/shell_browser_context.h
index a424a6e..2366744 100644
--- a/content/shell/browser/shell_browser_context.h
+++ b/content/shell/browser/shell_browser_context.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
diff --git a/content/shell/browser/shell_browser_main_parts.cc b/content/shell/browser/shell_browser_main_parts.cc
index 9f4a1128..559a35de 100644
--- a/content/shell/browser/shell_browser_main_parts.cc
+++ b/content/shell/browser/shell_browser_main_parts.cc
@@ -61,7 +61,7 @@
 #endif  // #elif (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
-#include "chromeos/lacros/lacros_dbus_thread_manager.h"
+#include "chromeos/lacros/dbus/lacros_dbus_thread_manager.h"
 #endif
 
 #if BUILDFLAG(USE_GTK)
@@ -110,7 +110,7 @@
 }  // namespace
 
 ShellBrowserMainParts::ShellBrowserMainParts(MainFunctionParams parameters)
-    : parameters_(std::move(parameters)), run_message_loop_(true) {}
+    : parameters_(std::move(parameters)) {}
 
 ShellBrowserMainParts::~ShellBrowserMainParts() = default;
 
@@ -185,21 +185,12 @@
   net::NetModule::SetResourceProvider(PlatformResourceProvider);
   ShellDevToolsManagerDelegate::StartHttpHandler(browser_context_.get());
   InitializeMessageLoopContext();
-
-  if (parameters_.ui_task) {
-    std::move(parameters_.ui_task).Run();
-    run_message_loop_ = false;
-  }
-
   return 0;
 }
 
 void ShellBrowserMainParts::WillRunMainMessageLoop(
     std::unique_ptr<base::RunLoop>& run_loop) {
-  if (run_message_loop_)
-    Shell::SetMainMessageLoopQuitClosure(run_loop->QuitClosure());
-  else
-    run_loop.reset();
+  Shell::SetMainMessageLoopQuitClosure(run_loop->QuitClosure());
 }
 
 void ShellBrowserMainParts::PostMainMessageLoopRun() {
diff --git a/content/shell/browser/shell_browser_main_parts.h b/content/shell/browser/shell_browser_main_parts.h
index 1973101..583ffe0 100644
--- a/content/shell/browser/shell_browser_main_parts.h
+++ b/content/shell/browser/shell_browser_main_parts.h
@@ -69,7 +69,6 @@
 
   // For running content_browsertests.
   MainFunctionParams parameters_;
-  bool run_message_loop_;
 
   std::unique_ptr<performance_manager::PerformanceManagerLifetime>
       performance_manager_lifetime_;
diff --git a/content/shell/browser/shell_content_browser_client.h b/content/shell/browser/shell_content_browser_client.h
index 99fa840..1c762e4 100644
--- a/content/shell/browser/shell_content_browser_client.h
+++ b/content/shell/browser/shell_content_browser_client.h
@@ -9,7 +9,6 @@
 #include <string>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/memory/raw_ptr.h"
 #include "build/build_config.h"
diff --git a/content/shell/browser/shell_devtools_bindings.h b/content/shell/browser/shell_devtools_bindings.h
index d62da29e..9a06d1d6 100644
--- a/content/shell/browser/shell_devtools_bindings.h
+++ b/content/shell/browser/shell_devtools_bindings.h
@@ -9,7 +9,6 @@
 #include <set>
 
 #include "base/callback_helpers.h"
-#include "base/compiler_specific.h"
 #include "base/containers/span.h"
 #include "base/containers/unique_ptr_adapters.h"
 #include "base/memory/raw_ptr.h"
diff --git a/content/shell/browser/shell_devtools_frontend.h b/content/shell/browser/shell_devtools_frontend.h
index 7760e1ab..9eca200 100644
--- a/content/shell/browser/shell_devtools_frontend.h
+++ b/content/shell/browser/shell_devtools_frontend.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "content/public/browser/web_contents_observer.h"
diff --git a/content/shell/browser/shell_devtools_manager_delegate.h b/content/shell/browser/shell_devtools_manager_delegate.h
index 7dedfd32..4ab4593c6 100644
--- a/content/shell/browser/shell_devtools_manager_delegate.h
+++ b/content/shell/browser/shell_devtools_manager_delegate.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_SHELL_BROWSER_SHELL_DEVTOOLS_MANAGER_DELEGATE_H_
 #define CONTENT_SHELL_BROWSER_SHELL_DEVTOOLS_MANAGER_DELEGATE_H_
 
-#include "base/compiler_specific.h"
 #include "base/containers/flat_set.h"
 #include "base/memory/raw_ptr.h"
 #include "content/public/browser/devtools_manager_delegate.h"
diff --git a/content/shell/browser/shell_download_manager_delegate.h b/content/shell/browser/shell_download_manager_delegate.h
index 8b5de32..88a799c 100644
--- a/content/shell/browser/shell_download_manager_delegate.h
+++ b/content/shell/browser/shell_download_manager_delegate.h
@@ -8,7 +8,6 @@
 #include <stdint.h>
 
 #include "base/callback_forward.h"
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "content/public/browser/download_manager_delegate.h"
diff --git a/content/shell/browser/shell_javascript_dialog_manager.h b/content/shell/browser/shell_javascript_dialog_manager.h
index cb76481..243046c 100644
--- a/content/shell/browser/shell_javascript_dialog_manager.h
+++ b/content/shell/browser/shell_javascript_dialog_manager.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "build/build_config.h"
 #include "content/public/browser/javascript_dialog_manager.h"
 
diff --git a/content/shell/browser/shell_quota_permission_context.h b/content/shell/browser/shell_quota_permission_context.h
index 26f0346..2bc9e1f 100644
--- a/content/shell/browser/shell_quota_permission_context.h
+++ b/content/shell/browser/shell_quota_permission_context.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_SHELL_BROWSER_SHELL_QUOTA_PERMISSION_CONTEXT_H_
 #define CONTENT_SHELL_BROWSER_SHELL_QUOTA_PERMISSION_CONTEXT_H_
 
-#include "base/compiler_specific.h"
 #include "content/public/browser/quota_permission_context.h"
 
 namespace content {
diff --git a/content/shell/browser/shell_speech_recognition_manager_delegate.h b/content/shell/browser/shell_speech_recognition_manager_delegate.h
index 1d4a405..4127bd5c 100644
--- a/content/shell/browser/shell_speech_recognition_manager_delegate.h
+++ b/content/shell/browser/shell_speech_recognition_manager_delegate.h
@@ -6,7 +6,6 @@
 #define CONTENT_SHELL_BROWSER_SHELL_SPEECH_RECOGNITION_MANAGER_DELEGATE_H_
 
 #include "base/bind.h"
-#include "base/compiler_specific.h"
 #include "content/public/browser/speech_recognition_event_listener.h"
 #include "content/public/browser/speech_recognition_manager_delegate.h"
 
diff --git a/content/shell/common/shell_content_client.h b/content/shell/common/shell_content_client.h
index 65147df..6026b945 100644
--- a/content/shell/common/shell_content_client.h
+++ b/content/shell/common/shell_content_client.h
@@ -8,7 +8,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "content/public/common/content_client.h"
 #include "content/shell/common/shell_origin_trial_policy.h"
 
diff --git a/content/shell/renderer/shell_content_renderer_client.h b/content/shell/renderer/shell_content_renderer_client.h
index f2a94f85..51801ff 100644
--- a/content/shell/renderer/shell_content_renderer_client.h
+++ b/content/shell/renderer/shell_content_renderer_client.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "build/build_config.h"
 #include "content/public/renderer/content_renderer_client.h"
 #include "media/mojo/buildflags.h"
diff --git a/content/test/content_browser_test_test.cc b/content/test/content_browser_test_test.cc
index baaa030d..0ca274b 100644
--- a/content/test/content_browser_test_test.cc
+++ b/content/test/content_browser_test_test.cc
@@ -268,13 +268,25 @@
 class ContentBrowserTestSanityTest : public ContentBrowserTest {
  public:
   void SetUpCommandLine(base::CommandLine* command_line) override {
+    ASSERT_FALSE(ran_);
+
     const testing::TestInfo* const test_info =
         testing::UnitTest::GetInstance()->current_test_info();
     if (std::string(test_info->name()) == "SingleProcess")
       command_line->AppendSwitch(switches::kSingleProcess);
   }
 
+  void SetUp() override {
+    ASSERT_FALSE(ran_);
+    BrowserTestBase::SetUp();
+  }
+
+  void SetUpOnMainThread() override { ASSERT_FALSE(ran_); }
+
   void Test() {
+    ASSERT_FALSE(ran_);
+    ran_ = true;
+
     GURL url = GetTestUrl(".", "simple_page.html");
 
     std::u16string expected_title(u"OK");
@@ -283,6 +295,18 @@
     std::u16string title = title_watcher.WaitAndGetTitle();
     EXPECT_EQ(expected_title, title);
   }
+
+  void TearDownOnMainThread() override { ASSERT_TRUE(ran_); }
+
+  void TearDown() override {
+    ASSERT_TRUE(ran_);
+    BrowserTestBase::TearDown();
+  }
+
+ private:
+  // Verify that Test() is invoked once and only once between SetUp and TearDown
+  // phases.
+  bool ran_ = false;
 };
 
 IN_PROC_BROWSER_TEST_F(ContentBrowserTestSanityTest, Basic) {
diff --git a/content/test/content_test_suite.h b/content/test/content_test_suite.h
index dd8ab18b5..10470b1 100644
--- a/content/test/content_test_suite.h
+++ b/content/test/content_test_suite.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/test/test_discardable_memory_allocator.h"
 #include "build/build_config.h"
 #include "content/public/test/content_test_suite_base.h"
diff --git a/content/test/mock_background_sync_controller.h b/content/test/mock_background_sync_controller.h
index 30fa560..fd13ee35 100644
--- a/content/test/mock_background_sync_controller.h
+++ b/content/test/mock_background_sync_controller.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include "base/compiler_specific.h"
 #include "base/time/time.h"
 #include "content/public/browser/background_sync_controller.h"
 #include "content/public/browser/background_sync_parameters.h"
diff --git a/content/test/ppapi/ppapi_test.h b/content/test/ppapi/ppapi_test.h
index 58a4e1b8..b3e45ca 100644
--- a/content/test/ppapi/ppapi_test.h
+++ b/content/test/ppapi/ppapi_test.h
@@ -7,7 +7,6 @@
 
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/javascript_test_observer.h"
 #include "url/gurl.h"
diff --git a/content/test/test_blink_web_unit_test_support.h b/content/test/test_blink_web_unit_test_support.h
index 487d305..f2a70ae 100644
--- a/content/test/test_blink_web_unit_test_support.h
+++ b/content/test/test_blink_web_unit_test_support.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "build/build_config.h"
 #include "cc/test/test_task_graph_runner.h"
diff --git a/content/test/test_content_browser_client.h b/content/test/test_content_browser_client.h
index 9f6e896..54407e1 100644
--- a/content/test/test_content_browser_client.h
+++ b/content/test/test_content_browser_client.h
@@ -7,7 +7,6 @@
 
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/files/scoped_temp_dir.h"
 #include "build/build_config.h"
 #include "content/public/browser/content_browser_client.h"
diff --git a/content/test/test_content_client.h b/content/test/test_content_client.h
index 5f4d025..ac055035 100644
--- a/content/test/test_content_client.h
+++ b/content/test/test_content_client.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_TEST_TEST_CONTENT_CLIENT_H_
 #define CONTENT_TEST_TEST_CONTENT_CLIENT_H_
 
-#include "base/compiler_specific.h"
 #include "content/public/common/content_client.h"
 
 namespace content {
diff --git a/content/test/test_render_frame_host_factory.h b/content/test/test_render_frame_host_factory.h
index e546d58..687aeea 100644
--- a/content/test/test_render_frame_host_factory.h
+++ b/content/test/test_render_frame_host_factory.h
@@ -9,7 +9,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "content/browser/renderer_host/render_frame_host_factory.h"
 
 namespace content {
diff --git a/content/test/test_render_view_host_factory.h b/content/test/test_render_view_host_factory.h
index a3c8160..7eeedfb5 100644
--- a/content/test/test_render_view_host_factory.h
+++ b/content/test/test_render_view_host_factory.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include "base/compiler_specific.h"
 #include "content/browser/renderer_host/render_view_host_factory.h"
 
 namespace content {
diff --git a/content/test/test_render_widget_host_factory.h b/content/test/test_render_widget_host_factory.h
index 1193e72..2589c423 100644
--- a/content/test/test_render_widget_host_factory.h
+++ b/content/test/test_render_widget_host_factory.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include "base/compiler_specific.h"
 #include "content/browser/renderer_host/render_widget_host_factory.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 
diff --git a/content/utility/utility_thread_impl.h b/content/utility/utility_thread_impl.h
index da3e00c..2f006d61 100644
--- a/content/utility/utility_thread_impl.h
+++ b/content/utility/utility_thread_impl.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "build/build_config.h"
 #include "content/child/child_thread_impl.h"
 #include "content/public/utility/utility_thread.h"
diff --git a/content/web_test/browser/web_test_browser_context.h b/content/web_test/browser/web_test_browser_context.h
index 23e953d..bd8a956 100644
--- a/content/web_test/browser/web_test_browser_context.h
+++ b/content/web_test/browser/web_test_browser_context.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_WEB_TEST_BROWSER_WEB_TEST_BROWSER_CONTEXT_H_
 #define CONTENT_WEB_TEST_BROWSER_WEB_TEST_BROWSER_CONTEXT_H_
 
-#include "base/compiler_specific.h"
 #include "content/shell/browser/shell_browser_context.h"
 
 namespace device {
diff --git a/content/web_test/browser/web_test_devtools_bindings.h b/content/web_test/browser/web_test_devtools_bindings.h
index 708a76b..e74a170 100644
--- a/content/web_test/browser/web_test_devtools_bindings.h
+++ b/content/web_test/browser/web_test_devtools_bindings.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_WEB_TEST_BROWSER_WEB_TEST_DEVTOOLS_BINDINGS_H_
 #define CONTENT_WEB_TEST_BROWSER_WEB_TEST_DEVTOOLS_BINDINGS_H_
 
-#include "base/compiler_specific.h"
 #include "content/shell/browser/shell_devtools_frontend.h"
 
 namespace content {
diff --git a/content/web_test/browser/web_test_download_manager_delegate.h b/content/web_test/browser/web_test_download_manager_delegate.h
index e965500..bdb454f8 100644
--- a/content/web_test/browser/web_test_download_manager_delegate.h
+++ b/content/web_test/browser/web_test_download_manager_delegate.h
@@ -6,7 +6,6 @@
 #define CONTENT_WEB_TEST_BROWSER_WEB_TEST_DOWNLOAD_MANAGER_DELEGATE_H_
 
 #include "base/callback_forward.h"
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "content/public/browser/download_manager_delegate.h"
 #include "content/shell/browser/shell_download_manager_delegate.h"
diff --git a/content/web_test/browser/web_test_javascript_dialog_manager.h b/content/web_test/browser/web_test_javascript_dialog_manager.h
index 5fe00c79..3c70443 100644
--- a/content/web_test/browser/web_test_javascript_dialog_manager.h
+++ b/content/web_test/browser/web_test_javascript_dialog_manager.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "base/callback_forward.h"
-#include "base/compiler_specific.h"
 #include "content/shell/browser/shell_javascript_dialog_manager.h"
 
 namespace content {
diff --git a/content/web_test/renderer/fake_screen_orientation_impl.h b/content/web_test/renderer/fake_screen_orientation_impl.h
index e54ed0d..c8a03b2 100644
--- a/content/web_test/renderer/fake_screen_orientation_impl.h
+++ b/content/web_test/renderer/fake_screen_orientation_impl.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_WEB_TEST_RENDERER_FAKE_SCREEN_ORIENTATION_IMPL_H_
 #define CONTENT_WEB_TEST_RENDERER_FAKE_SCREEN_ORIENTATION_IMPL_H_
 
-#include "base/compiler_specific.h"
 #include "mojo/public/cpp/bindings/associated_receiver_set.h"
 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
 #include "services/device/public/mojom/screen_orientation.mojom.h"
diff --git a/docs/clang.md b/docs/clang.md
index c856cbd..3675820 100644
--- a/docs/clang.md
+++ b/docs/clang.md
@@ -100,3 +100,6 @@
 
 * [Clang Sheriffing](clang_sheriffing.md) contains instructions for how to debug
   compiler bugs, for clang sheriffs.
+
+* [Clang Tool Refactoring](clang_tool_refactoring.md) has notes on how to build
+  and run refactoring tools based on clang's libraries.
diff --git a/extensions/browser/extension_registrar.cc b/extensions/browser/extension_registrar.cc
index fe35259..cb0c2aa 100644
--- a/extensions/browser/extension_registrar.cc
+++ b/extensions/browser/extension_registrar.cc
@@ -68,8 +68,6 @@
       UMA_HISTOGRAM_ENUMERATION(
           "Extensions.AttemptedToDowngradeVersionLocation",
           extension->location());
-      UMA_HISTOGRAM_ENUMERATION("Extensions.AttemptedToDowngradeVersionType",
-                                extension->GetType(), Manifest::NUM_LOAD_TYPES);
 
       // TODO(https://crbug.com/810799): It would be awfully nice to CHECK this,
       // but that's caused problems. There are apparently times when this
diff --git a/extensions/renderer/binding_generating_native_handler.cc b/extensions/renderer/binding_generating_native_handler.cc
index 7f59b31..34fab61 100644
--- a/extensions/renderer/binding_generating_native_handler.cc
+++ b/extensions/renderer/binding_generating_native_handler.cc
@@ -5,8 +5,6 @@
 #include "extensions/renderer/binding_generating_native_handler.h"
 
 #include "base/cxx17_backports.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/timer/elapsed_timer.h"
 #include "extensions/renderer/script_context.h"
 #include "extensions/renderer/v8_helpers.h"
 #include "gin/data_object_builder.h"
@@ -32,7 +30,6 @@
 }
 
 v8::Local<v8::Object> BindingGeneratingNativeHandler::NewInstance() {
-  base::ElapsedTimer timer;
   // This long sequence of commands effectively runs the JavaScript code,
   // such that result[bind_to] is the compiled schema for |api_name|:
   //
@@ -127,12 +124,6 @@
   v8::Local<v8::Object> object =
       gin::DataObjectBuilder(isolate).Set(bind_to_, compiled_schema).Build();
 
-  // Log UMA with microsecond accuracy*; maxes at 10 seconds.
-  // *Obviously, limited by our TimeTicks implementation, but as close as
-  // possible.
-  UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions.ApiBindingObjectGenerationTime",
-                              timer.Elapsed().InMicroseconds(),
-                              1, 10000000, 100);
   // return result;
   return scope.Escape(object);
 }
diff --git a/extensions/renderer/module_system.cc b/extensions/renderer/module_system.cc
index 1255b81..5e0aa6b9a 100644
--- a/extensions/renderer/module_system.cc
+++ b/extensions/renderer/module_system.cc
@@ -8,10 +8,8 @@
 #include "base/command_line.h"
 #include "base/cxx17_backports.h"
 #include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
-#include "base/timer/elapsed_timer.h"
 #include "base/trace_event/trace_event.h"
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_view.h"
@@ -396,7 +394,6 @@
     v8::Local<v8::String> property,
     const v8::PropertyCallbackInfo<v8::Value>& info,
     RequireFunction require_function) {
-  base::ElapsedTimer timer;
   CHECK(!info.Data().IsEmpty());
   CHECK(info.Data()->IsObject());
   v8::Isolate* isolate = info.GetIsolate();
@@ -502,8 +499,6 @@
     NOTREACHED();
   }
   info.GetReturnValue().Set(new_field);
-
-  UMA_HISTOGRAM_TIMES("Extensions.ApiBindingGenerationTime", timer.Elapsed());
 }
 
 void ModuleSystem::SetLazyField(v8::Local<v8::Object> object,
diff --git a/extensions/shell/BUILD.gn b/extensions/shell/BUILD.gn
index ec331810..84730ac 100644
--- a/extensions/shell/BUILD.gn
+++ b/extensions/shell/BUILD.gn
@@ -246,7 +246,7 @@
   }
 
   if (is_chromeos_lacros) {
-    deps += [ "//chromeos/lacros" ]
+    deps += [ "//chromeos/lacros/dbus" ]
   }
   if (enable_nacl) {
     sources += [
diff --git a/extensions/shell/browser/shell_browser_main_parts.cc b/extensions/shell/browser/shell_browser_main_parts.cc
index 37236316..8353e0d1 100644
--- a/extensions/shell/browser/shell_browser_main_parts.cc
+++ b/extensions/shell/browser/shell_browser_main_parts.cc
@@ -73,7 +73,7 @@
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
-#include "chromeos/lacros/lacros_dbus_thread_manager.h"
+#include "chromeos/lacros/dbus/lacros_dbus_thread_manager.h"
 #endif
 
 #if BUILDFLAG(ENABLE_NACL)
@@ -106,7 +106,6 @@
     ShellBrowserMainDelegate* browser_main_delegate)
     : extension_system_(nullptr),
       parameters_(std::move(parameters)),
-      run_message_loop_(true),
       browser_main_delegate_(browser_main_delegate) {}
 
 ShellBrowserMainParts::~ShellBrowserMainParts() = default;
@@ -242,25 +241,18 @@
           ::switches::kBrowserCrashTest))
     CrashForTest();
 
-  if (parameters_.ui_task) {
-    // For running browser tests.
-    std::move(parameters_.ui_task).Run();
-    run_message_loop_ = false;
-  } else {
+  // Skip these steps in integration tests.
+  if (!parameters_.ui_task) {
     browser_main_delegate_->Start(browser_context_.get());
+    desktop_controller_->PreMainMessageLoopRun();
   }
 
-  desktop_controller_->PreMainMessageLoopRun();
-
   return content::RESULT_CODE_NORMAL_EXIT;
 }
 
 void ShellBrowserMainParts::WillRunMainMessageLoop(
     std::unique_ptr<base::RunLoop>& run_loop) {
-  if (run_message_loop_)
-    desktop_controller_->WillRunMainMessageLoop(run_loop);
-  else
-    run_loop.reset();
+  desktop_controller_->WillRunMainMessageLoop(run_loop);
 }
 
 void ShellBrowserMainParts::PostMainMessageLoopRun() {
diff --git a/extensions/shell/browser/shell_browser_main_parts.h b/extensions/shell/browser/shell_browser_main_parts.h
index 343519cd..b71f1b6f 100644
--- a/extensions/shell/browser/shell_browser_main_parts.h
+++ b/extensions/shell/browser/shell_browser_main_parts.h
@@ -90,10 +90,6 @@
   // For running app browsertests.
   content::MainFunctionParams parameters_;
 
-  // If true, indicates the main message loop should be run
-  // in MainMessageLoopRun. If false, it has already been run.
-  bool run_message_loop_;
-
   std::unique_ptr<ShellBrowserMainDelegate> browser_main_delegate_;
 };
 
diff --git a/fuchsia/engine/browser/web_engine_browser_main_parts.cc b/fuchsia/engine/browser/web_engine_browser_main_parts.cc
index 6df6710..4217816 100644
--- a/fuchsia/engine/browser/web_engine_browser_main_parts.cc
+++ b/fuchsia/engine/browser/web_engine_browser_main_parts.cc
@@ -230,9 +230,6 @@
   if (parameters_.ui_task) {
     // Since the main loop won't run, there is nothing to quit.
     quit_closure_ = base::DoNothing();
-
-    std::move(parameters_.ui_task).Run();
-    run_message_loop_ = false;
   }
 
   return content::RESULT_CODE_NORMAL_EXIT;
@@ -240,11 +237,7 @@
 
 void WebEngineBrowserMainParts::WillRunMainMessageLoop(
     std::unique_ptr<base::RunLoop>& run_loop) {
-  if (run_message_loop_) {
-    quit_closure_ = run_loop->QuitClosure();
-  } else {
-    run_loop = nullptr;
-  }
+  quit_closure_ = run_loop->QuitClosure();
 }
 
 void WebEngineBrowserMainParts::PostMainMessageLoopRun() {
diff --git a/fuchsia/engine/browser/web_engine_browser_main_parts.h b/fuchsia/engine/browser/web_engine_browser_main_parts.h
index 20f120e..be060448 100644
--- a/fuchsia/engine/browser/web_engine_browser_main_parts.h
+++ b/fuchsia/engine/browser/web_engine_browser_main_parts.h
@@ -110,7 +110,6 @@
   // Used to respond to changes to the system's current locale.
   std::unique_ptr<base::FuchsiaIntlProfileWatcher> intl_profile_watcher_;
 
-  bool run_message_loop_ = true;
   base::OnceClosure quit_closure_;
 };
 
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
index 63f802a..eaebf00 100644
--- a/gpu/config/gpu_driver_bug_list.json
+++ b/gpu/config/gpu_driver_bug_list.json
@@ -3893,6 +3893,22 @@
       "features": [
         "disable_accelerated_h264_encode"
       ]
+    },
+    {
+      "id": 386,
+      "cr_bugs": [1253962],
+      "description": "Older Adreno 4xx drivers drop draws sometimes with oop-c",
+      "os": {
+        "type" : "android"
+      },
+      "driver_version": {
+        "op": "<",
+        "value": "145"
+      },
+      "gl_renderer": ".*Adreno \\(TM\\) 4.*",
+      "features": [
+        "disable_canvas_oop_rasterization"
+      ]
     }
   ]
 }
diff --git a/headless/lib/browser/headless_browser_main_parts.cc b/headless/lib/browser/headless_browser_main_parts.cc
index bcb61ce0..d7a794b 100644
--- a/headless/lib/browser/headless_browser_main_parts.cc
+++ b/headless/lib/browser/headless_browser_main_parts.cc
@@ -57,21 +57,12 @@
   MaybeStartLocalDevToolsHttpHandler();
   browser_->PlatformInitialize();
   browser_->RunOnStartCallback();
-
-  if (parameters_.ui_task) {
-    std::move(parameters_.ui_task).Run();
-    run_message_loop_ = false;
-  }
-
   return content::RESULT_CODE_NORMAL_EXIT;
 }
 
 void HeadlessBrowserMainParts::WillRunMainMessageLoop(
     std::unique_ptr<base::RunLoop>& run_loop) {
-  if (run_message_loop_)
-    quit_main_message_loop_ = run_loop->QuitClosure();
-  else
-    run_loop.reset();
+  quit_main_message_loop_ = run_loop->QuitClosure();
 }
 
 void HeadlessBrowserMainParts::PostMainMessageLoopRun() {
diff --git a/headless/lib/browser/headless_browser_main_parts.h b/headless/lib/browser/headless_browser_main_parts.h
index f364735..0f2e76f8 100644
--- a/headless/lib/browser/headless_browser_main_parts.h
+++ b/headless/lib/browser/headless_browser_main_parts.h
@@ -86,7 +86,6 @@
   std::unique_ptr<PrefService> local_state_;
 #endif
 
-  bool run_message_loop_ = true;
   bool devtools_http_handler_started_ = false;
   base::OnceClosure quit_main_message_loop_;
 #if defined(OS_MAC)
diff --git a/infra/config/generated/builders/try/android-marshmallow-arm64-rel/properties.textpb b/infra/config/generated/builders/try/android-marshmallow-arm64-rel/properties.textpb
index edcef336..558a52c 100644
--- a/infra/config/generated/builders/try/android-marshmallow-arm64-rel/properties.textpb
+++ b/infra/config/generated/builders/try/android-marshmallow-arm64-rel/properties.textpb
@@ -1,4 +1,8 @@
 {
+  "$build/chromium_orchestrator": {
+    "compilator": "android-marshmallow-arm64-rel-compilator",
+    "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649"
+  },
   "$build/code_coverage": {
     "coverage_test_types": [
       "unit",
@@ -8,7 +12,6 @@
   },
   "$build/goma": {
     "enable_ats": true,
-    "jobs": 300,
     "rpc_extra_params": "?prod",
     "server_host": "goma.chromium.org",
     "use_luci_auth": true
@@ -21,5 +24,5 @@
     ]
   },
   "builder_group": "tryserver.chromium.android",
-  "recipe": "chromium_trybot"
+  "recipe": "chromium/orchestrator"
 }
\ No newline at end of file
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 87c3b5f..2095ea19 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -52466,11 +52466,10 @@
       name: "android-marshmallow-arm64-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builder:android-marshmallow-arm64-rel"
-      dimensions: "cores:32"
+      dimensions: "cores:4"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04|Ubuntu-18.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.try"
-      dimensions: "ssd:1"
       exe {
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/main"
@@ -52478,6 +52477,10 @@
       }
       properties:
         '{'
+        '  "$build/chromium_orchestrator": {'
+        '    "compilator": "android-marshmallow-arm64-rel-compilator",'
+        '    "compilator_watcher_git_revision": "5fd7f4ae276865742fe632642ec4633dd9f81649"'
+        '  },'
         '  "$build/code_coverage": {'
         '    "coverage_test_types": ['
         '      "unit",'
@@ -52487,7 +52490,6 @@
         '  },'
         '  "$build/goma": {'
         '    "enable_ats": true,'
-        '    "jobs": 300,'
         '    "rpc_extra_params": "?prod",'
         '    "server_host": "goma.chromium.org",'
         '    "use_luci_auth": true'
@@ -52500,7 +52502,7 @@
         '    ]'
         '  },'
         '  "builder_group": "tryserver.chromium.android",'
-        '  "recipe": "chromium_trybot"'
+        '  "recipe": "chromium/orchestrator"'
         '}'
       execution_timeout_secs: 14400
       expiration_secs: 7200
@@ -52512,7 +52514,7 @@
         path: "win_toolchain"
       }
       build_numbers: YES
-      service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
+      service_account: "chromium-orchestrator@chops-service-accounts.iam.gserviceaccount.com"
       task_template_canary_percentage {
         value: 5
       }
@@ -52521,10 +52523,6 @@
         value: 100
       }
       experiments {
-        key: "luci.recipes.use_python3"
-        value: 5
-      }
-      experiments {
         key: "luci.use_realms"
         value: 100
       }
@@ -52560,6 +52558,7 @@
           use_invocation_timestamp: true
         }
       }
+      description_html: "This is the orchestrator half of an orchestrator + compilator pair of builders. The compilator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/android-marshmallow-arm64-rel-compilator\">android-marshmallow-arm64-rel-compilator</a>."
     }
     builders {
       name: "android-marshmallow-arm64-rel-compilator"
@@ -52663,6 +52662,7 @@
           use_invocation_timestamp: true
         }
       }
+      description_html: "This is the compilator half of an orchestrator + compilator pair of builders. The orchestrator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/android-marshmallow-arm64-rel\">android-marshmallow-arm64-rel</a>."
     }
     builders {
       name: "android-marshmallow-arm64-rel-rts"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index 70f123b..1eaab099 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -2387,6 +2387,9 @@
     name: "buildbucket/luci.chromium.try/android-marshmallow-arm64-rel"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/android-marshmallow-arm64-rel-compilator"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/android-marshmallow-arm64-rel-rts"
   }
   builders {
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star
index ccafdae..9a7b667 100644
--- a/infra/config/subprojects/chromium/try.star
+++ b/infra/config/subprojects/chromium/try.star
@@ -412,36 +412,17 @@
     name = "android-inverse-fieldtrials-pie-x86-fyi-rel",
 )
 
-try_.chromium_android_builder(
+try_.chromium_android_orchestrator_pair(
     name = "android-marshmallow-arm64-rel",
     branch_selector = branches.STANDARD_MILESTONE,
-    builderless = not settings.is_main,
-    cores = 32 if settings.is_main else 16,
-    goma_jobs = goma.jobs.J300,
     main_list_view = "try",
-    ssd = True,
     use_java_coverage = True,
     coverage_test_types = ["unit", "overall"],
-    tryjob = try_.job(),
-    # TODO(crbug/1202741)
-    os = os.LINUX_XENIAL_OR_BIONIC_REMOVE,
-)
-
-try_.chromium_android_builder(
-    name = "android-marshmallow-arm64-rel-compilator",
-    builderless = False,
-    cores = 64,
-    goma_jobs = goma.jobs.J300,
-    ssd = True,
-    use_java_coverage = True,
-    coverage_test_types = ["unit", "overall"],
-    properties = {
-        "orchestrator": {
-            "builder_group": "tryserver.chromium.android",
-            "builder_name": "android-marshmallow-arm64-rel",
-        },
-    },
-    executable = "recipe:chromium/compilator",
+    orchestrator_cores = 4,
+    orchestrator_tryjob = try_.job(),
+    compilator_cores = 64 if settings.is_main else 32,
+    compilator_goma_jobs = goma.jobs.J300,
+    compilator_name = "android-marshmallow-arm64-rel-compilator",
 )
 
 try_.chromium_android_builder(
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index a942765..34ebee1 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -324,6 +324,28 @@
      base::size(kFREDefaultPromoTestingShortDelay), nullptr},
 };
 
+const FeatureEntry::FeatureVariation kEnableFREUIModuleIOSVariations[] = {
+    {"TOP | OLD",
+     (FeatureEntry::FeatureParam[]){
+         {kFREUIIdentitySwitcherPositionParam, "top"},
+         {kFREUIStringsSetParam, "old"}},
+     2, nullptr},
+    {"BOTTOM | OLD",
+     (FeatureEntry::FeatureParam[]){
+         {kFREUIIdentitySwitcherPositionParam, "bottom"},
+         {kFREUIStringsSetParam, "old"}},
+     2, nullptr},
+    {"TOP | NEW",
+     (FeatureEntry::FeatureParam[]){
+         {kFREUIIdentitySwitcherPositionParam, "top"},
+         {kFREUIStringsSetParam, "new"}},
+     2, nullptr},
+    {"BOTTOM | NEW",
+     (FeatureEntry::FeatureParam[]){
+         {kFREUIIdentitySwitcherPositionParam, "bottom"},
+         {kFREUIStringsSetParam, "new"}},
+     2, nullptr}};
+
 // To add a new entry, add to the end of kFeatureEntries. There are four
 // distinct types of entries:
 // . ENABLE_DISABLE_VALUE: entry is either enabled, disabled, or uses the
@@ -487,9 +509,12 @@
     {"shared-highlighting-ios", flag_descriptions::kSharedHighlightingIOSName,
      flag_descriptions::kSharedHighlightingIOSDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(kSharedHighlightingIOS)},
-    {"enable-fre-ui-module-ios", flag_descriptions::kEnableFREUIModuleIOSName,
+    {"enable-fre-ui-module-ios-with-options",
+     flag_descriptions::kEnableFREUIModuleIOSName,
      flag_descriptions::kEnableFREUIModuleIOSDescription, flags_ui::kOsIos,
-     FEATURE_VALUE_TYPE(kEnableFREUIModuleIOS)},
+     FEATURE_WITH_PARAMS_VALUE_TYPE(kEnableFREUIModuleIOS,
+                                    kEnableFREUIModuleIOSVariations,
+                                    "EnableFREUIModuleIOS")},
     {"enable-long-message-duration",
      flag_descriptions::kEnableLongMessageDurationName,
      flag_descriptions::kEnableLongMessageDurationDescription, flags_ui::kOsIos,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
index b063506..46a4372 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -188,9 +188,11 @@
     "This test display the FRE default browser screen and other default "
     "browser promo depending on experiment.";
 
-const char kEnableFREUIModuleIOSName[] = "Enable FRE UI module";
+const char kEnableFREUIModuleIOSName[] = "Enable FRE UI module with options";
 const char kEnableFREUIModuleIOSDescription[] =
-    "Enable the option of using new FRE UI module to show first run screens.";
+    "Use the new FRE UI module for first run. There are 4 UI options: Identity "
+    "switcher at the TOP or BOTTOM and using OLD or NEW strings set for the "
+    "sign-in sync screen.";
 
 const char kEnableLongMessageDurationName[] = "Enable long message duration";
 const char kEnableLongMessageDurationDescription[] =
diff --git a/ios/chrome/browser/ui/authentication/cells/table_view_identity_cell.mm b/ios/chrome/browser/ui/authentication/cells/table_view_identity_cell.mm
index a59af61..f37c0ef5 100644
--- a/ios/chrome/browser/ui/authentication/cells/table_view_identity_cell.mm
+++ b/ios/chrome/browser/ui/authentication/cells/table_view_identity_cell.mm
@@ -54,7 +54,7 @@
   self.identityView.titleColor = titleColor;
   self.accessoryType = checked ? UITableViewCellAccessoryCheckmark
                                : UITableViewCellAccessoryNone;
-  if (checked) {
+  if (checked && identityViewStyle != IdentityViewStyleConsistency) {
     self.directionalLayoutMargins =
         NSDirectionalEdgeInsetsMake(0, 0, 0, kCheckmarkMagin);
   } else {
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index 6dad0b60..33bdfb30 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -2892,7 +2892,13 @@
             : [self.tabStripView
                   adjustTransformForRTL:CGAffineTransformMakeTranslation(
                                             0, self.tabStripView.frame.size
-                                                   .height)];
+                                                       .height +
+                                                   self.headerOffset)];
+    self.tabStripSnapshot.alpha =
+        currentViewRevealState == ViewRevealState::Revealed ||
+                currentViewRevealState == ViewRevealState::Fullscreen
+            ? 0
+            : 1;
     [self.contentArea addSubview:self.tabStripSnapshot];
     AddSameConstraints(self.tabStripSnapshot, self.tabStripView);
   }
@@ -2966,6 +2972,7 @@
       if (!base::FeatureList::IsEnabled(kModernTabStrip)) {
         self.tabStripSnapshot.transform =
             [self.tabStripView adjustTransformForRTL:CGAffineTransformIdentity];
+        self.tabStripSnapshot.alpha = 1;
       }
       break;
     case ViewRevealState::Peeked:
@@ -2975,6 +2982,7 @@
             CGAffineTransformMakeTranslation(0, tabStripHeight);
         self.tabStripSnapshot.transform =
             [self.tabStripView adjustTransformForRTL:transform];
+        self.tabStripSnapshot.alpha = 1;
       }
       break;
     case ViewRevealState::Revealed:
@@ -2985,6 +2993,7 @@
             CGAffineTransformMakeTranslation(0, tabStripHeight);
         self.tabStripSnapshot.transform =
             [self.tabStripView adjustTransformForRTL:transform];
+        self.tabStripSnapshot.alpha = 0;
       }
       break;
   }
diff --git a/ios/chrome/browser/ui/first_run/fre_field_trial.cc b/ios/chrome/browser/ui/first_run/fre_field_trial.cc
index 632668cd..ab9f93a 100644
--- a/ios/chrome/browser/ui/first_run/fre_field_trial.cc
+++ b/ios/chrome/browser/ui/first_run/fre_field_trial.cc
@@ -20,6 +20,30 @@
 const char kFREDefaultPromoTestingOnlyParam[] = "variant_fre_only_enabled";
 const char kFREDefaultPromoTestingShortDelayParam[] =
     "variant_short_delay_enabled";
+const char kFREUIIdentitySwitcherPositionParam[] =
+    "signin_sync_screen_identity_position";
+const char kFREUIStringsSetParam[] = "signin_sync_screen_strings_set";
+
+// Feature param and options for the identity switcher position.
+constexpr base::FeatureParam<SigninSyncScreenUIIdentitySwitcherPosition>::Option
+    kIdentitySwitcherPositionOptions[] = {
+        {SigninSyncScreenUIIdentitySwitcherPosition::kTop, "top"},
+        {SigninSyncScreenUIIdentitySwitcherPosition::kBottom, "bottom"}};
+
+constexpr base::FeatureParam<SigninSyncScreenUIIdentitySwitcherPosition>
+    kIdentitySwitcherPositionParam{
+        &kEnableFREUIModuleIOS, kFREUIIdentitySwitcherPositionParam,
+        SigninSyncScreenUIIdentitySwitcherPosition::kTop,
+        &kIdentitySwitcherPositionOptions};
+
+// Feature param and options for the sign-in & sync screen strings set.
+constexpr base::FeatureParam<SigninSyncScreenUIStringSet>::Option
+    kStringSetOptions[] = {{SigninSyncScreenUIStringSet::kOld, "old"},
+                           {SigninSyncScreenUIStringSet::kNew, "new"}};
+
+constexpr base::FeatureParam<SigninSyncScreenUIStringSet> kStringSetParam{
+    &kEnableFREUIModuleIOS, kFREUIStringsSetParam,
+    SigninSyncScreenUIStringSet::kOld, &kStringSetOptions};
 
 namespace {
 // String local state preference with the name of the assigned trial group.
@@ -88,6 +112,17 @@
          IsInDefaultBrowserPromoAtFirstRunOnlyGroup();
 }
 
+SigninSyncScreenUIIdentitySwitcherPosition
+GetSigninSyncScreenUIIdentitySwitcherPosition() {
+  // Default: TOP position.
+  return kIdentitySwitcherPositionParam.Get();
+}
+
+SigninSyncScreenUIStringSet GetSigninSyncScreenUIStringSet() {
+  // Default: OLD strings set.
+  return kStringSetParam.Get();
+}
+
 // Creates a trial for the first run (when there is no variations seed) if
 // necessary and enables the feature based on the randomly selected trial group.
 // Returns the group number.
diff --git a/ios/chrome/browser/ui/first_run/fre_field_trial.h b/ios/chrome/browser/ui/first_run/fre_field_trial.h
index d26f4112..8a3584d 100644
--- a/ios/chrome/browser/ui/first_run/fre_field_trial.h
+++ b/ios/chrome/browser/ui/first_run/fre_field_trial.h
@@ -10,6 +10,16 @@
 class PrefRegistrySimple;
 class PrefService;
 
+enum class SigninSyncScreenUIIdentitySwitcherPosition : int {
+  kTop,
+  kBottom,
+};
+
+enum class SigninSyncScreenUIStringSet : int {
+  kOld,
+  kNew,
+};
+
 namespace base {
 class FeatureList;
 }  // namespace base
@@ -26,6 +36,14 @@
 // default promo" is enabled.
 extern const char kFREDefaultPromoTestingShortDelayParam[];
 
+// Indicates which option of the identity position to use for the FRE UI (TOP or
+// BOTTOM).
+extern const char kFREUIIdentitySwitcherPositionParam[];
+
+// Indicates which option of the sign-in & sync strings set to use for the FRE
+// UI (OLD or NEW).
+extern const char kFREUIStringsSetParam[];
+
 namespace fre_field_trial {
 
 // Returns true if the user is in the group that will show the default browser
@@ -45,6 +63,13 @@
 // Returns true if the default browser screen in FRE is enabled.
 bool IsFREDefaultBrowserScreenEnabled();
 
+// Returns the UI option for the sign-in & sync screen identity position.
+SigninSyncScreenUIIdentitySwitcherPosition
+GetSigninSyncScreenUIIdentitySwitcherPosition();
+
+// Returns the UI option for the sign-in & sync screen strings set.
+SigninSyncScreenUIStringSet GetSigninSyncScreenUIStringSet();
+
 // Registers the local state pref used to manage grouping for this field trial.
 void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
 
diff --git a/ios/chrome/browser/ui/gestures/view_revealing_vertical_pan_handler.mm b/ios/chrome/browser/ui/gestures/view_revealing_vertical_pan_handler.mm
index 9c4a2ab..87e877ab 100644
--- a/ios/chrome/browser/ui/gestures/view_revealing_vertical_pan_handler.mm
+++ b/ios/chrome/browser/ui/gestures/view_revealing_vertical_pan_handler.mm
@@ -139,10 +139,12 @@
 - (void)addAnimatee:(id<ViewRevealingAnimatee>)animatee {
   [self.animatees addObject:animatee];
   // Make sure the newly added animatee is in the correct state.
-  [animatee willAnimateViewRevealFromState:self.currentState
-                                   toState:self.currentState];
-  [animatee animateViewReveal:self.currentState];
-  [animatee didAnimateViewReveal:self.currentState];
+  [UIView performWithoutAnimation:^{
+    [animatee willAnimateViewRevealFromState:self.currentState
+                                     toState:self.currentState];
+    [animatee animateViewReveal:self.currentState];
+    [animatee didAnimateViewReveal:self.currentState];
+  }];
 }
 
 - (void)setBaseViewHeight:(CGFloat)baseViewHeight {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
index ea6f0eb..b0189f2 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
@@ -121,10 +121,14 @@
 @property(nonatomic, strong)
     UICollectionViewTransitionLayout* gridHorizontalTransitionLayout;
 
-// Gesture recognizer to dismiss the thumb strip.
+// Tap gesture recognizer to dismiss the thumb strip.
 @property(nonatomic, strong)
     UITapGestureRecognizer* thumbStripDismissRecognizer;
 
+// Swipe up gesture recognizer to dismiss the thumb strip.
+@property(nonatomic, strong)
+    UISwipeGestureRecognizer* thumbStripSwipeUpDismissRecognizer;
+
 // YES while batch updates and the batch update completion are being performed.
 @property(nonatomic) BOOL updating;
 
@@ -934,15 +938,19 @@
 
   // If the dismiss recognizer needs to be disabled, do it now so the user won't
   // trigger it during the transformation.
-  if (!thumbStripDismissEnabled)
+  if (!thumbStripDismissEnabled) {
     self.thumbStripDismissRecognizer.enabled = NO;
+    self.thumbStripSwipeUpDismissRecognizer.enabled = NO;
+  }
 
   __weak __typeof(self) weakSelf = self;
   auto completionBlock = ^(BOOL completed, BOOL finished) {
     weakSelf.collectionView.scrollEnabled = YES;
     weakSelf.currentLayout = nextLayout;
-    if (thumbStripDismissEnabled)
+    if (thumbStripDismissEnabled) {
       self.thumbStripDismissRecognizer.enabled = YES;
+      self.thumbStripSwipeUpDismissRecognizer.enabled = YES;
+    }
     if (completion) {
       completion(completed, finished);
     }
@@ -1351,14 +1359,25 @@
     [collectionView.backgroundView
         addGestureRecognizer:self.thumbStripDismissRecognizer];
   }
+  if (!self.thumbStripSwipeUpDismissRecognizer) {
+    self.thumbStripSwipeUpDismissRecognizer = [[UISwipeGestureRecognizer alloc]
+        initWithTarget:self
+                action:@selector(handleThumbStripBackgroundSwipeUpGesture:)];
+    self.thumbStripSwipeUpDismissRecognizer.direction =
+        UISwipeGestureRecognizerDirectionUp;
+    [collectionView.backgroundView
+        addGestureRecognizer:self.thumbStripSwipeUpDismissRecognizer];
+  }
 
   if (panHandler.currentState == ViewRevealState::Revealed ||
       panHandler.currentState == ViewRevealState::Fullscreen) {
     self.thumbStripDismissRecognizer.enabled = NO;
+    self.thumbStripSwipeUpDismissRecognizer.enabled = NO;
     collectionView.collectionViewLayout = self.gridLayout;
     self.currentLayout = self.gridLayout;
   } else {
     self.thumbStripDismissRecognizer.enabled = YES;
+    self.thumbStripSwipeUpDismissRecognizer.enabled = YES;
     collectionView.collectionViewLayout = self.horizontalLayout;
     self.currentLayout = self.horizontalLayout;
   }
@@ -1380,7 +1399,10 @@
 
   [collectionView.backgroundView
       removeGestureRecognizer:self.thumbStripDismissRecognizer];
+  [collectionView.backgroundView
+      removeGestureRecognizer:self.thumbStripSwipeUpDismissRecognizer];
   self.thumbStripDismissRecognizer = nil;
+  self.thumbStripSwipeUpDismissRecognizer = nil;
 
   collectionView.collectionViewLayout = gridLayout;
   self.currentLayout = gridLayout;
@@ -1418,4 +1440,9 @@
   [self.thumbStripHandler closeThumbStrip];
 }
 
+- (void)handleThumbStripBackgroundSwipeUpGesture:
+    (UIGestureRecognizer*)recognizer {
+  [self.thumbStripHandler closeThumbStrip];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_thumb_strip_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_thumb_strip_egtest.mm
index 52386e9b..5ee637e 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_thumb_strip_egtest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_thumb_strip_egtest.mm
@@ -222,6 +222,38 @@
       assertWithMatcher:grey_notVisible()];
 }
 
+- (void)testSwappingUpBackgroundClosesThumbStrip {
+  // The feature only works on iPad.
+  if (![ChromeEarlGrey isIPadIdiom]) {
+    EARL_GREY_TEST_SKIPPED(@"Thumb strip is not enabled on iPhone");
+  }
+
+  [self setUpTestServer];
+
+  const GURL URL = self.testServer->GetURL("/querytitle?Tab1");
+  [ChromeEarlGrey loadURL:URL];
+  [ChromeEarlGrey waitForWebStateContainingText:"Tab1"];
+
+  // Swipe down to reveal the thumb strip.
+  [[EarlGrey selectElementWithMatcher:PrimaryToolbar()]
+      performAction:grey_swipeSlowInDirection(kGREYDirectionDown)];
+
+  // Make sure that the entire tab thumbnail is fully visible and not covered.
+  // This acts as a good proxy to the entire thumbstrip being visible.
+  [[EarlGrey selectElementWithMatcher:cellWithLabel(@"Tab1")]
+      assertWithMatcher:grey_minimumVisiblePercent(1)];
+
+  // Now swipe up the background. This should dismiss the thumb strip.
+  [[EarlGrey
+      selectElementWithMatcher:grey_allOf(TabGridBackground(),
+                                          grey_ancestor(RegularTabGrid()), nil)]
+      performAction:grey_swipeSlowInDirection(kGREYDirectionUp)];
+
+  // Check that the thumb strip is indeed dismissed.
+  [[EarlGrey selectElementWithMatcher:cellWithLabel(@"Tab1")]
+      assertWithMatcher:grey_notVisible()];
+}
+
 // After scrolling the thumb strip so the currently selected tab is offscreen,
 // when opening the thumb strip again, the selected tab should be back onscreen.
 - (void)testThumbnailVisibleWhenThumbStripOpens {
diff --git a/media/capture/mojom/video_capture.mojom b/media/capture/mojom/video_capture.mojom
index 0c989d2..32675d2 100644
--- a/media/capture/mojom/video_capture.mojom
+++ b/media/capture/mojom/video_capture.mojom
@@ -7,7 +7,6 @@
 import "media/capture/mojom/video_capture_buffer.mojom";
 import "media/capture/mojom/video_capture_types.mojom";
 import "ui/gfx/geometry/mojom/geometry.mojom";
-import "mojo/public/mojom/base/token.mojom";
 import "mojo/public/mojom/base/unguessable_token.mojom";
 
 // This file decribes the communication between a given Renderer Host interface
@@ -99,14 +98,6 @@
          mojo_base.mojom.UnguessableToken session_id,
          VideoCaptureParams params);
 
-  // Start/stop cropping the video track.
-  // Non-empty |crop_id| sets (or changes) the crop-target.
-  // Empty |crop_id| reverts the capture to its original, uncropped state.
-  // The callback reports success/failure.
-  Crop(mojo_base.mojom.UnguessableToken device_id,
-       mojo_base.mojom.Token crop_id)
-    => (CropRequestResult crop_result);
-
   // Requests that the video capturer send a frame "soon" (e.g., to resolve
   // picture loss or quality issues).
   RequestRefreshFrame(mojo_base.mojom.UnguessableToken device_id);
diff --git a/media/gpu/v4l2/v4l2_video_decoder_delegate_h264.cc b/media/gpu/v4l2/v4l2_video_decoder_delegate_h264.cc
index 0e16b2fc..8a890c7 100644
--- a/media/gpu/v4l2/v4l2_video_decoder_delegate_h264.cc
+++ b/media/gpu/v4l2/v4l2_video_decoder_delegate_h264.cc
@@ -87,8 +87,13 @@
 
     struct v4l2_h264_dpb_entry& entry = priv_->v4l2_decode_param.dpb[i++];
     entry.reference_ts = index;
-    entry.pic_num = pic->pic_num;
-    entry.frame_num = pic->frame_num;
+    if (pic->long_term) {
+      entry.frame_num = pic->long_term_pic_num;
+      entry.pic_num = pic->long_term_frame_idx;
+    } else {
+      entry.frame_num = pic->frame_num;
+      entry.pic_num = pic->pic_num;
+    }
     entry.top_field_order_cnt = pic->top_field_order_cnt;
     entry.bottom_field_order_cnt = pic->bottom_field_order_cnt;
     entry.flags = V4L2_H264_DPB_ENTRY_FLAG_VALID |
diff --git a/media/gpu/v4l2/v4l2_video_decoder_delegate_h264_legacy.cc b/media/gpu/v4l2/v4l2_video_decoder_delegate_h264_legacy.cc
index 6f701d863..d496834f 100644
--- a/media/gpu/v4l2/v4l2_video_decoder_delegate_h264_legacy.cc
+++ b/media/gpu/v4l2/v4l2_video_decoder_delegate_h264_legacy.cc
@@ -101,8 +101,13 @@
 
     struct v4l2_h264_dpb_entry& entry = priv_->v4l2_decode_param.dpb[i++];
     entry.buf_index = index;
-    entry.frame_num = pic->frame_num;
-    entry.pic_num = pic->pic_num;
+    if (pic->long_term) {
+      entry.frame_num = pic->long_term_pic_num;
+      entry.pic_num = pic->long_term_frame_idx;
+    } else {
+      entry.frame_num = pic->frame_num;
+      entry.pic_num = pic->pic_num;
+    }
     entry.top_field_order_cnt = pic->top_field_order_cnt;
     entry.bottom_field_order_cnt = pic->bottom_field_order_cnt;
     entry.flags = (pic->ref ? V4L2_H264_DPB_ENTRY_FLAG_ACTIVE : 0) |
diff --git a/net/dns/host_cache.cc b/net/dns/host_cache.cc
index 6a66063..15958b7 100644
--- a/net/dns/host_cache.cc
+++ b/net/dns/host_cache.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <string>
+#include <unordered_set>
 #include <vector>
 
 #include "base/bind.h"
@@ -731,10 +732,11 @@
     delegate_->ScheduleWrite();
 }
 
-void HostCache::GetAsListValue(base::ListValue* entry_list,
-                               bool include_staleness,
-                               SerializationType serialization_type) const {
+void HostCache::GetList(base::Value* entry_list,
+                        bool include_staleness,
+                        SerializationType serialization_type) const {
   DCHECK(entry_list);
+  DCHECK(entry_list->is_list());
   entry_list->ClearList();
 
   for (const auto& pair : entries_) {
@@ -775,11 +777,11 @@
                        std::move(network_isolation_key_value));
     entry_dict->SetBoolKey(kSecureKey, static_cast<bool>(key.secure));
 
-    entry_list->Append(std::move(entry_dict));
+    entry_list->Append(std::move(*entry_dict));
   }
 }
 
-bool HostCache::RestoreFromListValue(const base::ListValue& old_cache) {
+bool HostCache::RestoreFromListValue(const base::Value& old_cache) {
   // Reset the restore size to 0.
   restore_size_ = 0;
 
diff --git a/net/dns/host_cache.h b/net/dns/host_cache.h
index dc6a003..a7752c4 100644
--- a/net/dns/host_cache.h
+++ b/net/dns/host_cache.h
@@ -38,7 +38,6 @@
 #include "url/scheme_host_port.h"
 
 namespace base {
-class ListValue;
 class TickClock;
 }  // namespace base
 
@@ -379,16 +378,16 @@
   void ClearForHosts(
       const base::RepeatingCallback<bool(const std::string&)>& host_filter);
 
-  // Fills the provided base::ListValue with the contents of the cache for
-  // serialization. |entry_list| must be non-null and will be cleared before
-  // adding the cache contents.
-  void GetAsListValue(base::ListValue* entry_list,
-                      bool include_staleness,
-                      SerializationType serialization_type) const;
-  // Takes a base::ListValue representing cache entries and stores them in the
+  // Fills the provided base::Value with the contents of the cache for
+  // serialization. `entry_list` must be non-null list, and will be cleared
+  // before adding the cache contents.
+  void GetList(base::Value* entry_list,
+               bool include_staleness,
+               SerializationType serialization_type) const;
+  // Takes a base::Value list representing cache entries and stores them in the
   // cache, skipping any that already have entries. Returns true on success,
   // false on failure.
-  bool RestoreFromListValue(const base::ListValue& old_cache);
+  bool RestoreFromListValue(const base::Value& old_cache);
   // Returns the number of entries that were restored in the last call to
   // RestoreFromListValue().
   size_t last_restore_size() const { return restore_size_; }
diff --git a/net/dns/host_cache_fuzzer.cc b/net/dns/host_cache_fuzzer.cc
index e431ffc6..c35adbc 100644
--- a/net/dns/host_cache_fuzzer.cc
+++ b/net/dns/host_cache_fuzzer.cc
@@ -74,21 +74,19 @@
     return;
   ++valid_json_count;
 
-  const base::ListValue& list_input = base::Value::AsListValue(*value);
-
   // Parse the HostCache.
   constexpr size_t kMaxEntries = 1000;
   HostCache host_cache(kMaxEntries);
-  if (!host_cache.RestoreFromListValue(list_input))
+  if (!host_cache.RestoreFromListValue(*value))
     return;
 
   // Serialize the HostCache.
-  base::ListValue serialized;
-  host_cache.GetAsListValue(
+  base::Value serialized(base::Value::Type::LIST);
+  host_cache.GetList(
       &serialized /* entry_list */, true /* include_staleness */,
       HostCache::SerializationType::kRestorable /* serialization_type */);
 
-  CHECK_EQ(list_input, serialized);
+  CHECK_EQ(*value, serialized);
   return;
 }
 }  // namespace net
diff --git a/net/dns/host_cache_unittest.cc b/net/dns/host_cache_unittest.cc
index e6a48363..e10d61d 100644
--- a/net/dns/host_cache_unittest.cc
+++ b/net/dns/host_cache_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "net/dns/host_cache.h"
 
+#include <algorithm>
 #include <string>
 #include <utility>
 
@@ -1204,9 +1205,9 @@
   // Advance to t=12, ansd serialize the cache.
   now += base::Seconds(7);
 
-  base::ListValue serialized_cache;
-  cache.GetAsListValue(&serialized_cache, false /* include_staleness */,
-                       HostCache::SerializationType::kRestorable);
+  base::Value serialized_cache(base::Value::Type::LIST);
+  cache.GetList(&serialized_cache, false /* include_staleness */,
+                HostCache::SerializationType::kRestorable);
   HostCache restored_cache(kMaxCacheEntries);
 
   // Add entries for "foobar3.com" and "foobar4.com" to the cache before
@@ -1297,9 +1298,9 @@
   ASSERT_TRUE(cache.Lookup(key, now));
   ASSERT_EQ(cache.size(), 1u);
 
-  base::ListValue serialized_cache;
-  cache.GetAsListValue(&serialized_cache, /*include_staleness=*/false,
-                       HostCache::SerializationType::kRestorable);
+  base::Value serialized_cache(base::Value::Type::LIST);
+  cache.GetList(&serialized_cache, /*include_staleness=*/false,
+                HostCache::SerializationType::kRestorable);
   HostCache restored_cache(kMaxCacheEntries);
   EXPECT_TRUE(restored_cache.RestoreFromListValue(serialized_cache));
   EXPECT_EQ(restored_cache.size(), 1u);
@@ -1342,9 +1343,9 @@
             cache.Lookup(key2, now)->first.network_isolation_key);
   EXPECT_EQ(2u, cache.size());
 
-  base::ListValue serialized_cache;
-  cache.GetAsListValue(&serialized_cache, false /* include_staleness */,
-                       HostCache::SerializationType::kRestorable);
+  base::Value serialized_cache(base::Value::Type::LIST);
+  cache.GetList(&serialized_cache, false /* include_staleness */,
+                HostCache::SerializationType::kRestorable);
   HostCache restored_cache(kMaxCacheEntries);
   EXPECT_TRUE(restored_cache.RestoreFromListValue(serialized_cache));
   EXPECT_EQ(1u, restored_cache.size());
@@ -1384,9 +1385,9 @@
             cache.Lookup(key, now)->first.network_isolation_key);
   EXPECT_EQ(1u, cache.size());
 
-  base::ListValue serialized_cache;
-  cache.GetAsListValue(&serialized_cache, false /* include_staleness */,
-                       HostCache::SerializationType::kDebug);
+  base::Value serialized_cache(base::Value::Type::LIST);
+  cache.GetList(&serialized_cache, false /* include_staleness */,
+                HostCache::SerializationType::kDebug);
   HostCache restored_cache(kMaxCacheEntries);
   EXPECT_FALSE(restored_cache.RestoreFromListValue(serialized_cache));
 
@@ -1414,9 +1415,9 @@
   cache.Set(key, entry, now, ttl);
   EXPECT_EQ(1u, cache.size());
 
-  base::ListValue serialized_cache;
-  cache.GetAsListValue(&serialized_cache, false /* include_staleness */,
-                       HostCache::SerializationType::kRestorable);
+  base::Value serialized_cache(base::Value::Type::LIST);
+  cache.GetList(&serialized_cache, false /* include_staleness */,
+                HostCache::SerializationType::kRestorable);
   HostCache restored_cache(kMaxCacheEntries);
   restored_cache.RestoreFromListValue(serialized_cache);
 
@@ -1449,9 +1450,9 @@
   cache.Set(key, entry, now, ttl);
   EXPECT_EQ(1u, cache.size());
 
-  base::ListValue serialized_cache;
-  cache.GetAsListValue(&serialized_cache, false /* include_staleness */,
-                       HostCache::SerializationType::kRestorable);
+  base::Value serialized_cache(base::Value::Type::LIST);
+  cache.GetList(&serialized_cache, false /* include_staleness */,
+                HostCache::SerializationType::kRestorable);
   HostCache restored_cache(kMaxCacheEntries);
   restored_cache.RestoreFromListValue(serialized_cache);
 
diff --git a/net/log/net_log_util.cc b/net/log/net_log_util.cc
index b104e8ca..fb4fa2c 100644
--- a/net/log/net_log_util.cc
+++ b/net/log/net_log_util.cc
@@ -372,10 +372,10 @@
                                 static_cast<int>(cache->max_entries()));
       cache_info_dict.SetIntKey("network_changes", cache->network_changes());
 
-      base::ListValue* list_value = nullptr;
-      if (cache_contents_list.GetAsList(&list_value))
-        cache->GetAsListValue(list_value, true /* include_staleness */,
-                              HostCache::SerializationType::kDebug);
+      if (cache_contents_list.is_list()) {
+        cache->GetList(&cache_contents_list, true /* include_staleness */,
+                       HostCache::SerializationType::kDebug);
+      }
       cache_info_dict.SetKey("entries", std::move(cache_contents_list));
 
       dict.SetKey("cache", std::move(cache_info_dict));
diff --git a/testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter
index 20a723b4..0f75c2c 100644
--- a/testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter
+++ b/testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter
@@ -124,3 +124,27 @@
 
 # crbug.com/1187536
 -org.chromium.chrome.browser.customtabs.CustomTabExternalNavigationTest.testIntentPickerNotShownForNormalUrl
+
+# crbug.com/1272997
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantFormActionTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantChromeTabIntegrationTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantTriggerScriptIntegrationTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantBackButtonIntegrationTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantCollectUserDataIntegrationTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantGenericUiTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantChromeTabIntegrationTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantNavigationIntegrationTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantInterruptIntegrationTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantPersonalDataManagerTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantInputActionIntegrationTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantOverlayIntegrationTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantBottomsheetTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantKeyboardIntegrationTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUpdateClientSettingsIntegrationTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantTtsIntegrationTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantAutostartTest*
+-org.chromium.chrome.browser.autofill_assistant.AutofillAssistantPasswordManagerIntegrationTest*
+
+
+
+
diff --git a/testing/buildbot/filters/fuchsia.components_unittests.filter b/testing/buildbot/filters/fuchsia.components_unittests.filter
index 7e61e3f..924988f 100644
--- a/testing/buildbot/filters/fuchsia.components_unittests.filter
+++ b/testing/buildbot/filters/fuchsia.components_unittests.filter
@@ -29,7 +29,6 @@
 -OfflinePageMetadataStoreTest.LoadVersion*
 -PaintPreviewSerialUtils.TestSerialTypeface
 -PaintPreviewSubset*
--PersonalDataManagerTest.Should*
 -ProfilingJsonExporterTest.Memory*
 -RealtimeReportingJobConfigurationTest.Validate*
 -SSLErrorAssistantTest.*
@@ -44,4 +43,3 @@
 -UIDev*
 -VariationsCrash*
 -WebAppOriginAssociationFetcher*
--WebsiteSettingsRegistryTest.Properties
diff --git a/testing/test.gni b/testing/test.gni
index abae088..aceed03 100644
--- a/testing/test.gni
+++ b/testing/test.gni
@@ -855,9 +855,6 @@
     if (defined(invoker.run_under_python2) && invoker.run_under_python2) {
       use_vpython3 = false
       data += [ "//.vpython" ]
-    } else {
-      use_vpython3 = true
-      data += [ "//.vpython3" ]
     }
 
     if (defined(invoker.data)) {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 4e6d2a6..eb30303 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -4584,6 +4584,26 @@
             ]
         }
     ],
+    "IncludeBackgroundSVGInLCP": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "chromeos_lacros",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "IncludeBackgroundSVGInLCP"
+                    ]
+                }
+            ]
+        }
+    ],
     "IncludeInitiallyInvisibleImagesInLCP": [
         {
             "platforms": [
diff --git a/third_party/blink/public/mojom/mediastream/media_stream.mojom b/third_party/blink/public/mojom/mediastream/media_stream.mojom
index 53db62d..a70a2310 100644
--- a/third_party/blink/public/mojom/mediastream/media_stream.mojom
+++ b/third_party/blink/public/mojom/mediastream/media_stream.mojom
@@ -7,6 +7,7 @@
 import "media/capture/mojom/video_capture_types.mojom";
 import "media/mojo/mojom/audio_parameters.mojom";
 import "media/mojo/mojom/display_media_information.mojom";
+import "mojo/public/mojom/base/token.mojom";
 import "mojo/public/mojom/base/unguessable_token.mojom";
 
 // Types of media streams. When updating this list, make sure to update the
@@ -191,6 +192,15 @@
 
   // Tells the browser process that the stream has been started successfully.
   OnStreamStarted(string label);
+
+  // Start/stop cropping the video track.
+  // Non-empty |crop_id| sets (or changes) the crop-target.
+  // Empty |crop_id| reverts the capture to its original, uncropped state.
+  // The callback reports success/failure.
+  [EnableIfNot=is_android]
+  Crop(mojo_base.mojom.UnguessableToken device_id,
+       mojo_base.mojom.Token crop_id)
+    => (media.mojom.CropRequestResult crop_result);
 };
 
 // Browser-side interface that is used by the renderer process to notify the
diff --git a/third_party/blink/public/platform/modules/video_capture/web_video_capture_impl_manager.h b/third_party/blink/public/platform/modules/video_capture/web_video_capture_impl_manager.h
index ff69c21..9b0f8586 100644
--- a/third_party/blink/public/platform/modules/video_capture/web_video_capture_impl_manager.h
+++ b/third_party/blink/public/platform/modules/video_capture/web_video_capture_impl_manager.h
@@ -89,14 +89,6 @@
   void Suspend(const media::VideoCaptureSessionId& id);
   void Resume(const media::VideoCaptureSessionId& id);
 
-  // Start/stop cropping a video track.
-  // Non-empty |crop_id| sets (or changes) the crop-target.
-  // Empty |crop_id| reverts the capture to its original, uncropped state.
-  // The callback reports success/failure.
-  void Crop(const media::VideoCaptureSessionId& id,
-            const base::Token& crop_id,
-            base::OnceCallback<void(media::mojom::CropRequestResult)> callback);
-
   // Get supported formats supported by the device for the given session
   // ID. |callback| will be called on the IO thread.
   void GetDeviceSupportedFormats(const media::VideoCaptureSessionId& id,
diff --git a/third_party/blink/public/web/modules/mediastream/media_stream_video_source.h b/third_party/blink/public/web/modules/mediastream/media_stream_video_source.h
index 17c8e87..a82f5757 100644
--- a/third_party/blink/public/web/modules/mediastream/media_stream_video_source.h
+++ b/third_party/blink/public/web/modules/mediastream/media_stream_video_source.h
@@ -14,6 +14,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/token.h"
+#include "build/build_config.h"
 #include "media/base/video_frame.h"
 #include "media/capture/mojom/video_capture_types.mojom-shared.h"
 #include "media/capture/video_capture_types.h"
@@ -176,6 +177,7 @@
   // Returns true if encoded output can be enabled in the source.
   virtual bool SupportsEncodedOutput() const;
 
+#if !defined(OS_ANDROID)
   // Start/stop cropping a video track.
   // Non-empty |crop_id| sets (or changes) the crop-target.
   // Empty |crop_id| reverts the capture to its original, uncropped state.
@@ -183,6 +185,7 @@
   virtual void Crop(
       const base::Token& crop_id,
       base::OnceCallback<void(media::mojom::CropRequestResult)> callback);
+#endif
 
   // Notifies the source about that the number of encoded sinks have been
   // updated. Note: Can only be called if the number of encoded sinks have
diff --git a/third_party/blink/public/web/web_widget.h b/third_party/blink/public/web/web_widget.h
index 30b95b19..0f70b5d4 100644
--- a/third_party/blink/public/web/web_widget.h
+++ b/third_party/blink/public/web/web_widget.h
@@ -31,7 +31,6 @@
 #ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_WIDGET_H_
 #define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_WIDGET_H_
 
-#include "base/callback.h"
 #include "build/build_config.h"
 #include "cc/input/browser_controls_state.h"
 #include "cc/metrics/begin_main_frame_metrics.h"
@@ -39,12 +38,10 @@
 #include "cc/trees/layer_tree_host_client.h"
 #include "third_party/blink/public/common/input/web_menu_source_type.h"
 #include "third_party/blink/public/common/metrics/document_update_reason.h"
-#include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h"
 #include "third_party/blink/public/mojom/input/pointer_lock_context.mojom-shared.h"
 #include "third_party/blink/public/mojom/input/pointer_lock_result.mojom-shared.h"
 #include "third_party/blink/public/mojom/manifest/display_mode.mojom-shared.h"
 #include "third_party/blink/public/platform/cross_variant_mojo_util.h"
-#include "third_party/blink/public/platform/input/input_handler_proxy.h"
 #include "third_party/blink/public/platform/scheduler/web_agent_group_scheduler.h"
 #include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/public/platform/web_input_event_result.h"
@@ -66,7 +63,6 @@
 
 namespace ui {
 class Cursor;
-class LatencyInfo;
 }
 
 namespace blink {
@@ -157,17 +153,9 @@
   // Set state that the widget is in the process of handling input events.
   virtual void SetHandlingInputEvent(bool handling) = 0;
 
-  using HandledEventCallback = base::OnceCallback<void(
-      mojom::InputEventResultState ack_state,
-      const ui::LatencyInfo& latency_info,
-      std::unique_ptr<InputHandlerProxy::DidOverscrollParams>,
-      absl::optional<cc::TouchAction>)>;
-
-  // Process the input event, invoking the callback when complete. This
-  // method will call the callback synchronously.
+  // Process the input event, blocking until complete.
   virtual void ProcessInputEventSynchronouslyForTesting(
-      const WebCoalescedInputEvent&,
-      HandledEventCallback) = 0;
+      const WebCoalescedInputEvent&) = 0;
 
   virtual void DidOverscrollForTesting(
       const gfx::Vector2dF& overscroll_delta,
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_test.cc b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_test.cc
index 71a7b8d..a44e2e32 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_test.cc
@@ -7,7 +7,7 @@
 #include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_factory.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_file.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_image_data.h"
@@ -135,7 +135,8 @@
   ASSERT_EQ(file_path, original_file->GetPath());
 
   v8::Local<v8::Value> v8_original_file =
-      ToV8(original_file, scope.GetContext()->Global(), scope.GetIsolate());
+      ToV8Traits<File>::ToV8(scope.GetScriptState(), original_file)
+          .ToLocalChecked();
   scoped_refptr<SerializedScriptValue> serialized_script_value =
       SerializedScriptValue::Serialize(
           scope.GetIsolate(), v8_original_file,
@@ -160,7 +161,8 @@
   ASSERT_EQ("hello.txt", original_file->name());
 
   v8::Local<v8::Value> v8_original_file =
-      ToV8(original_file, scope.GetContext()->Global(), scope.GetIsolate());
+      ToV8Traits<File>::ToV8(scope.GetScriptState(), original_file)
+          .ToLocalChecked();
   scoped_refptr<SerializedScriptValue> serialized_script_value =
       SerializedScriptValue::Serialize(
           scope.GetIsolate(), v8_original_file,
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_threaded_test.cc b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_threaded_test.cc
index 683836b7..02cd09b 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_threaded_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_threaded_test.cc
@@ -7,6 +7,7 @@
 #include "base/synchronization/waitable_event.h"
 #include "build/build_config.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -40,7 +41,8 @@
   scoped_refptr<SerializedScriptValue> serialized =
       SerializedScriptValue::Serialize(
           scope.GetIsolate(),
-          ToV8(array_buffer, scope.GetContext()->Global(), scope.GetIsolate()),
+          ToV8Traits<DOMArrayBuffer>::ToV8(scope.GetScriptState(), array_buffer)
+              .ToLocalChecked(),
           options, ASSERT_NO_EXCEPTION);
   EXPECT_TRUE(serialized);
   EXPECT_TRUE(array_buffer->IsDetached());
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
index 0974ffb..7f7c6d8 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/public/platform/web_blob_info.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h"
+#include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_blob.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
@@ -238,7 +239,8 @@
   V8TestingScope scope;
   DOMPoint* point = DOMPoint::Create(1, 2, 3, 4);
   v8::Local<v8::Value> wrapper =
-      ToV8(point, scope.GetContext()->Global(), scope.GetIsolate());
+      ToV8Traits<DOMPoint>::ToV8(scope.GetScriptState(), point)
+          .ToLocalChecked();
   v8::Local<v8::Value> result = RoundTrip(wrapper, scope);
   ASSERT_TRUE(V8DOMPoint::HasInstance(result, scope.GetIsolate()));
   DOMPoint* new_point = V8DOMPoint::ToImpl(result.As<v8::Object>());
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni
index 31b89fc..4aea961 100644
--- a/third_party/blink/renderer/bindings/generated_in_modules.gni
+++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -941,8 +941,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wave_shaper_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_id_logout_request.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_id_logout_request.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_id_request_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_id_request_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_transport_close_info.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_transport_close_info.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_transport_error_init.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni
index 9f7b8b7..a45b802 100644
--- a/third_party/blink/renderer/bindings/idl_in_modules.gni
+++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -1029,7 +1029,6 @@
           "//third_party/blink/renderer/modules/webid/navigator_web_id.idl",
           "//third_party/blink/renderer/modules/webid/web_id.idl",
           "//third_party/blink/renderer/modules/webid/web_id_logout_request.idl",
-          "//third_party/blink/renderer/modules/webid/web_id_request_options.idl",
           "//third_party/blink/renderer/modules/webmidi/midi_access.idl",
           "//third_party/blink/renderer/modules/webmidi/midi_connection_event.idl",
           "//third_party/blink/renderer/modules/webmidi/midi_connection_event_init.idl",
diff --git a/third_party/blink/renderer/core/css/style_traversal_root.cc b/third_party/blink/renderer/core/css/style_traversal_root.cc
index d61c50c..95b7d76 100644
--- a/third_party/blink/renderer/core/css/style_traversal_root.cc
+++ b/third_party/blink/renderer/core/css/style_traversal_root.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/css/style_traversal_root.h"
 #include "third_party/blink/renderer/core/css/style_engine.h"
+#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/node_traversal.h"
 
@@ -11,9 +12,12 @@
 
 void StyleTraversalRoot::Update(ContainerNode* common_ancestor,
                                 Node* dirty_node) {
+#if DCHECK_IS_ON()
   DCHECK(dirty_node);
   DCHECK(dirty_node->isConnected());
+  DCHECK(DisplayLockUtilities::AssertStyleAllowed(*dirty_node));
   AssertRootNodeInvariants();
+#endif
 
   if (!common_ancestor) {
     // This is either first dirty node in which case we are using it as a
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.cc b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
index d654777..10a14ef220 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_context.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
@@ -333,9 +333,12 @@
 }
 
 void DisplayLockContext::DidStyleChildren() {
-  // TODO(vmpstr): Is this needed here?
-  if (element_->ChildNeedsReattachLayoutTree())
-    element_->MarkAncestorsWithChildNeedsReattachLayoutTree();
+  if (!element_->ChildNeedsReattachLayoutTree())
+    return;
+  auto* parent = element_->GetReattachParent();
+  if (!parent || parent->ChildNeedsReattachLayoutTree())
+    return;
+  element_->MarkAncestorsWithChildNeedsReattachLayoutTree();
 }
 
 bool DisplayLockContext::ShouldLayoutChildren() const {
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
index 4de5142f..0bf79a5 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
@@ -181,6 +181,12 @@
     return context->render_affecting_state_[static_cast<int>(
         DisplayLockContext::RenderAffectingState::kSubtreeHasSelection)];
   }
+  DisplayLockUtilities::ScopedForcedUpdate GetScopedForcedUpdate(
+      const Node* node,
+      DisplayLockContext::ForcedPhase phase,
+      bool include_self = false) {
+    return DisplayLockUtilities::ScopedForcedUpdate(node, phase, include_self);
+  }
 
   const int FAKE_FIND_ID = 1;
 
@@ -3518,4 +3524,55 @@
   EXPECT_TRUE(locked->nextSibling()->nextSibling()->GetLayoutObject());
 }
 
+TEST_F(DisplayLockContextTest, ReattachPropagationBlockedByDisplayLock) {
+  GetDocument().documentElement()->setInnerHTML(R"HTML(
+    <style>
+      #locked { content-visibility: hidden; }
+    </style>
+    <div id=parent>
+      <div id=locked>
+        <div id=child>
+          <div id=grandchild></div>
+        </div>
+      </div>
+    </div>
+  )HTML");
+
+  UpdateAllLifecyclePhasesForTest();
+
+  auto* locked = GetDocument().getElementById("locked");
+  auto* grandchild = GetDocument().getElementById("grandchild");
+  auto* parent = GetDocument().getElementById("parent");
+
+  // Force update all layout objects
+  grandchild->getBoundingClientRect();
+
+  ASSERT_TRUE(locked->GetLayoutObject());
+  ASSERT_TRUE(grandchild->GetLayoutObject());
+  ASSERT_TRUE(parent->GetLayoutObject());
+
+  GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
+  grandchild->SetNeedsReattachLayoutTree();
+  GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kStyleClean);
+
+  EXPECT_TRUE(locked->ChildNeedsReattachLayoutTree());
+  EXPECT_TRUE(grandchild->NeedsReattachLayoutTree());
+  EXPECT_FALSE(parent->ChildNeedsReattachLayoutTree());
+
+  EXPECT_FALSE(GetDocument().GetStyleEngine().NeedsLayoutTreeRebuild());
+
+  auto scope = GetScopedForcedUpdate(
+      grandchild, DisplayLockContext::ForcedPhase::kStyleAndLayoutTree);
+  // Pretend we styled the children.
+  GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
+  locked->GetDisplayLockContext()->DidStyleChildren();
+  GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kStyleClean);
+
+  EXPECT_TRUE(locked->ChildNeedsReattachLayoutTree());
+  EXPECT_TRUE(grandchild->NeedsReattachLayoutTree());
+  EXPECT_TRUE(parent->ChildNeedsReattachLayoutTree());
+
+  EXPECT_TRUE(GetDocument().GetStyleEngine().NeedsLayoutTreeRebuild());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc b/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
index c44d01f..2636ab4 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
@@ -10,6 +10,7 @@
 #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
 #include "third_party/blink/renderer/core/dom/node.h"
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
+#include "third_party/blink/renderer/core/dom/slot_assignment_engine.h"
 #include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/editing/editing_boundary.h"
 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
@@ -770,6 +771,18 @@
   });
 }
 
+#if DCHECK_IS_ON()
+bool DisplayLockUtilities::AssertStyleAllowed(const Node& node) {
+  if (node.GetDocument().IsFlatTreeTraversalForbidden() ||
+      node.GetDocument()
+          .GetSlotAssignmentEngine()
+          .HasPendingSlotAssignmentRecalc()) {
+    return true;
+  }
+  return !LockedAncestorPreventingStyle(node);
+}
+#endif
+
 bool DisplayLockUtilities::PrePaintBlockedInParentFrame(LayoutView* view) {
   auto* owner = view->GetFrameView()->GetFrame().OwnerLayoutObject();
   if (!owner)
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_utilities.h b/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
index 8291a7d..c9caec7 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
+++ b/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_DISPLAY_LOCK_UTILITIES_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_DISPLAY_LOCK_UTILITIES_H_
 
+#include "base/dcheck_is_on.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
 #include "third_party/blink/renderer/core/dom/range.h"
@@ -61,6 +62,7 @@
 
     // Test friends.
     friend class DisplayLockContextRenderingTest;
+    friend class DisplayLockContextTest;
 
     explicit ScopedForcedUpdate(const Node* node,
                                 DisplayLockContext::ForcedPhase phase,
@@ -213,6 +215,13 @@
   static Element* LockedAncestorPreventingPrePaint(const LayoutObject& object);
   static Element* LockedAncestorPreventingStyle(const Node& element);
 
+  // Returns true if the style is allowed on this node. Note that this can
+  // provide false positives if the flat tree traversal is forbidden, so this is
+  // only appropriate for us in DCHECKs.
+#if DCHECK_IS_ON()
+  static bool AssertStyleAllowed(const Node& node);
+#endif
+
   // Use these functions to check for locked node preventing paint if the
   // actual Element that has the lock is not important. These functions can be
   // significantly faster if the memoization scope has been created. If the
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc b/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc
index b52fb3e..bbe1600 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc
@@ -331,4 +331,24 @@
             PhysicalRect());
 }
 
+TEST_F(DisplayLockUtilitiesTest, ContainerQueryCrash) {
+  ScopedCSSContainerQueriesForTest cq_enabled(true);
+
+  SetHtmlInnerHTML(R"HTML(
+    <style>
+      #container {
+        content-visibility: hidden;
+        container-type: size;
+      }
+    </style>
+    <div id="container"><div id="child"></div></div>
+  )HTML");
+
+  auto* child = DynamicTo<HTMLElement>(GetDocument().getElementById("child"));
+  ASSERT_TRUE(child);
+
+  // Should not fail DCHECKs or crash.
+  child->offsetTopForBinding();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc
index acae590..6daab42 100644
--- a/third_party/blink/renderer/core/dom/node.cc
+++ b/third_party/blink/renderer/core/dom/node.cc
@@ -1292,16 +1292,42 @@
   DCHECK(isConnected());
   Element* ancestor = GetReattachParent();
   bool parent_dirty = ancestor && ancestor->IsDirtyForRebuildLayoutTree();
+  DCHECK(!ancestor || !ChildNeedsReattachLayoutTree() ||
+         !ancestor->ChildNeedsReattachLayoutTree() || NeedsReattachLayoutTree())
+      << "If both this and the parent are already marked with "
+         "ChildNeedsReattachLayoutTree(), something is broken and "
+         "UpdateLayoutTreeRebuildRoot() will be confused about common "
+         "ancestors.";
   for (; ancestor && !ancestor->ChildNeedsReattachLayoutTree();
        ancestor = ancestor->GetReattachParent()) {
     ancestor->SetChildNeedsReattachLayoutTree();
     if (ancestor->IsDirtyForRebuildLayoutTree())
       break;
+
+    // If we reach a locked ancestor, we should abort since the ancestor marking
+    // will be done when the context is unlocked.
+    if (ancestor->ChildStyleRecalcBlockedByDisplayLock())
+      break;
   }
   // If the parent node is already dirty, we can keep the same rebuild root. The
   // early return here is a performance optimization.
   if (parent_dirty)
     return;
+
+  // If we're in a locked subtree, then we should not update the layout tree
+  // rebuild root. It would be updated when we unlock the context. In other
+  // words, the only way we have a node in the locked subtree is if the ancestor
+  // has a locked display lock context or it is dirty for reattach. In either of
+  // those cases, we have a dirty bit trail up to the display lock context,
+  // which will be propagated when the lock is removed.
+  if (GetDocument().GetDisplayLockDocumentState().LockedDisplayLockCount() >
+      0) {
+    for (Element* ancestor_copy = ancestor; ancestor_copy;
+         ancestor_copy = ancestor_copy->GetReattachParent()) {
+      if (ancestor_copy->ChildStyleRecalcBlockedByDisplayLock())
+        return;
+    }
+  }
   GetDocument().GetStyleEngine().UpdateLayoutTreeRebuildRoot(ancestor, this);
 }
 
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
index c352cba3..43ad269b 100644
--- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -480,10 +480,9 @@
 }
 
 void WebPagePopupImpl::ProcessInputEventSynchronouslyForTesting(
-    const WebCoalescedInputEvent& event,
-    HandledEventCallback callback) {
+    const WebCoalescedInputEvent& event) {
   widget_base_->input_handler().HandleInputEvent(event, nullptr,
-                                                 std::move(callback));
+                                                 base::DoNothing());
 }
 
 void WebPagePopupImpl::UpdateTextInputState() {
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.h b/third_party/blink/renderer/core/exported/web_page_popup_impl.h
index 225395f..ae71b9e 100644
--- a/third_party/blink/renderer/core/exported/web_page_popup_impl.h
+++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.h
@@ -169,8 +169,8 @@
   void SetCursor(const ui::Cursor& cursor) override;
   bool HandlingInputEvent() override;
   void SetHandlingInputEvent(bool handling) override;
-  void ProcessInputEventSynchronouslyForTesting(const WebCoalescedInputEvent&,
-                                                HandledEventCallback) override;
+  void ProcessInputEventSynchronouslyForTesting(
+      const WebCoalescedInputEvent&) override;
   void UpdateTextInputState() override;
   void UpdateSelectionBounds() override;
   void ShowVirtualKeyboard() override;
diff --git a/third_party/blink/renderer/core/fragment_directive/css_selector_fragment_anchor_test.cc b/third_party/blink/renderer/core/fragment_directive/css_selector_fragment_anchor_test.cc
index 0cfb665e..63294489 100644
--- a/third_party/blink/renderer/core/fragment_directive/css_selector_fragment_anchor_test.cc
+++ b/third_party/blink/renderer/core/fragment_directive/css_selector_fragment_anchor_test.cc
@@ -58,7 +58,7 @@
                         base::TimeTicks::Now());
     event.SetFrameScale(1);
     WebView().MainFrameWidget()->ProcessInputEventSynchronouslyForTesting(
-        WebCoalescedInputEvent(event, ui::LatencyInfo()), base::DoNothing());
+        WebCoalescedInputEvent(event, ui::LatencyInfo()));
   }
 
   bool IsVisibleInViewport(Element& element) {
diff --git a/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_test.cc b/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_test.cc
index 6255416..9c8b99cf 100644
--- a/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_test.cc
+++ b/third_party/blink/renderer/core/fragment_directive/text_fragment_anchor_test.cc
@@ -95,7 +95,7 @@
                         base::TimeTicks::Now());
     event.SetFrameScale(1);
     WebView().MainFrameWidget()->ProcessInputEventSynchronouslyForTesting(
-        WebCoalescedInputEvent(event, ui::LatencyInfo()), base::DoNothing());
+        WebCoalescedInputEvent(event, ui::LatencyInfo()));
   }
 
   void SimulateRightClick(int x, int y) {
@@ -105,7 +105,7 @@
                         base::TimeTicks::Now());
     event.SetFrameScale(1);
     WebView().MainFrameWidget()->ProcessInputEventSynchronouslyForTesting(
-        WebCoalescedInputEvent(event, ui::LatencyInfo()), base::DoNothing());
+        WebCoalescedInputEvent(event, ui::LatencyInfo()));
   }
 
   void SimulateTap(int x, int y) {
@@ -145,7 +145,7 @@
       event.SetFrameScale(1);
 
       WebView().MainFrameWidget()->ProcessInputEventSynchronouslyForTesting(
-          WebCoalescedInputEvent(event, ui::LatencyInfo()), base::DoNothing());
+          WebCoalescedInputEvent(event, ui::LatencyInfo()));
     } else if (WebInputEvent::IsTouchEventType(type)) {
       WebTouchEvent event(type, WebInputEvent::kNoModifiers,
                           base::TimeTicks::Now());
@@ -161,7 +161,7 @@
         event.touches[0].state = WebTouchPoint::State::kStateReleased;
 
       WebView().MainFrameWidget()->ProcessInputEventSynchronouslyForTesting(
-          WebCoalescedInputEvent(event, ui::LatencyInfo()), base::DoNothing());
+          WebCoalescedInputEvent(event, ui::LatencyInfo()));
       WebView().MainFrameWidget()->DispatchBufferedTouchEvents();
     } else {
       NOTREACHED() << "Only needed to support Gesture/Touch until now. "
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
index 0fc96c3..2c85012 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -2400,11 +2400,16 @@
 
 void WebFrameWidgetImpl::ProcessInputEventSynchronouslyForTesting(
     const WebCoalescedInputEvent& event,
-    HandledEventCallback callback) {
+    WidgetBaseInputHandler::HandledEventCallback callback) {
   widget_base_->input_handler().HandleInputEvent(event, nullptr,
                                                  std::move(callback));
 }
 
+void WebFrameWidgetImpl::ProcessInputEventSynchronouslyForTesting(
+    const WebCoalescedInputEvent& event) {
+  ProcessInputEventSynchronouslyForTesting(event, base::DoNothing());
+}
+
 WebInputEventResult WebFrameWidgetImpl::DispatchBufferedTouchEvents() {
   CHECK(LocalRootImpl());
 
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
index 5d4b2597a..c28682e 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
@@ -69,6 +69,7 @@
 #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
 #include "third_party/blink/renderer/platform/text/text_direction.h"
 #include "third_party/blink/renderer/platform/widget/frame_widget.h"
+#include "third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h"
 #include "third_party/blink/renderer/platform/widget/widget_base_client.h"
 #include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h"
@@ -188,6 +189,12 @@
       base::OnceCallback<void(base::TimeTicks)> swap_callback,
       base::OnceCallback<void(base::TimeTicks)> presentation_callback);
 
+  // Process the input event, invoking the callback when complete. This
+  // method will call the callback synchronously.
+  void ProcessInputEventSynchronouslyForTesting(
+      const WebCoalescedInputEvent&,
+      WidgetBaseInputHandler::HandledEventCallback);
+
   // FrameWidget overrides.
   cc::AnimationHost* AnimationHost() const final;
   void SetOverscrollBehavior(
@@ -354,8 +361,8 @@
   void SetCursor(const ui::Cursor& cursor) override;
   bool HandlingInputEvent() override;
   void SetHandlingInputEvent(bool handling) override;
-  void ProcessInputEventSynchronouslyForTesting(const WebCoalescedInputEvent&,
-                                                HandledEventCallback) override;
+  void ProcessInputEventSynchronouslyForTesting(
+      const WebCoalescedInputEvent&) override;
   WebInputEventResult DispatchBufferedTouchEvents() override;
   WebInputEventResult HandleInputEvent(const WebCoalescedInputEvent&) override;
   void UpdateTextInputState() override;
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_test.cc b/third_party/blink/renderer/core/frame/web_frame_widget_test.cc
index 421649a..40bc045 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_test.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_test.cc
@@ -214,7 +214,7 @@
                       InputHandlerProxy::DidOverscrollParams*,
                       absl::optional<cc::TouchAction>));
 
-  WebWidget::HandledEventCallback GetCallback() {
+  WidgetBaseInputHandler::HandledEventCallback GetCallback() {
     return base::BindOnce(&MockHandledEventCallback::HandleCallback,
                           base::Unretained(this));
   }
@@ -283,7 +283,7 @@
   }
 
   void SendInputEvent(const WebInputEvent& event,
-                      WebWidget::HandledEventCallback callback) {
+                      WidgetBaseInputHandler::HandledEventCallback callback) {
     MockMainFrameWidget()->ProcessInputEventSynchronouslyForTesting(
         WebCoalescedInputEvent(event.Clone(), {}, {}, ui::LatencyInfo()),
         std::move(callback));
diff --git a/third_party/blink/renderer/core/input/touch_action_test.cc b/third_party/blink/renderer/core/input/touch_action_test.cc
index 1d159e7..2110e7b 100644
--- a/third_party/blink/renderer/core/input/touch_action_test.cc
+++ b/third_party/blink/renderer/core/input/touch_action_test.cc
@@ -414,7 +414,7 @@
     event.touch_start_or_first_touch_move = true;
 
   web_view->MainFrameWidget()->ProcessInputEventSynchronouslyForTesting(
-      WebCoalescedInputEvent(event, ui::LatencyInfo()), base::DoNothing());
+      WebCoalescedInputEvent(event, ui::LatencyInfo()));
   web_view->MainFrameWidget()->DispatchBufferedTouchEvents();
   RunPendingTasks();
 }
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
index cf639175..9e30ee7 100644
--- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
@@ -770,12 +770,19 @@
 }
 
 scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
-  if (auto result = LayoutInternal())
-    return result;
-
-  // We may have aborted layout due to a child changing scrollbars, relayout
-  // with the new scrollbar information.
-  return RelayoutIgnoringChildScrollbarChanges();
+  auto result = LayoutInternal();
+  switch (result->Status()) {
+    case NGLayoutResult::kNeedsEarlierBreak:
+      // If we found a good break somewhere inside this block, re-layout and
+      // break at that location.
+      DCHECK(result->GetEarlyBreak());
+      return RelayoutAndBreakEarlier<NGFlexLayoutAlgorithm>(
+          *result->GetEarlyBreak());
+    case NGLayoutResult::kNeedsRelayoutWithNoChildScrollbarChanges:
+      return RelayoutIgnoringChildScrollbarChanges();
+    default:
+      return result;
+  }
 }
 
 scoped_refptr<const NGLayoutResult>
@@ -832,8 +839,10 @@
 
   if (!IsResumingLayout(BreakToken())) {
     ApplyFinalAlignmentAndReversals(&flex_line_outputs);
-    if (!GiveItemsFinalPositionAndSize(&flex_line_outputs))
-      return nullptr;
+    NGLayoutResult::EStatus status =
+        GiveItemsFinalPositionAndSize(&flex_line_outputs);
+    if (status != NGLayoutResult::kSuccess)
+      return container_builder_.Abort(status);
   }
 
   LayoutUnit previously_consumed_block_size;
@@ -849,8 +858,11 @@
   }
 
   if (has_block_fragmentation_) {
-    GiveItemsFinalPositionAndSizeForFragmentation(&flex_line_outputs,
-                                                  &total_intrinsic_block_size);
+    NGLayoutResult::EStatus status =
+        GiveItemsFinalPositionAndSizeForFragmentation(
+            &flex_line_outputs, &total_intrinsic_block_size);
+    if (status != NGLayoutResult::kSuccess)
+      return container_builder_.Abort(status);
   }
 
   LayoutUnit block_size;
@@ -876,9 +888,11 @@
     container_builder_.SetHasDescendantThatDependsOnPercentageBlockSize(true);
 
   if (UNLIKELY(InvolvedInBlockFragmentation(container_builder_))) {
-    FinishFragmentation(Node(), ConstraintSpace(), BorderPadding().block_end,
-                        FragmentainerSpaceAtBfcStart(ConstraintSpace()),
-                        &container_builder_);
+    NGBreakStatus break_status = FinishFragmentation(
+        Node(), ConstraintSpace(), BorderPadding().block_end,
+        FragmentainerSpaceAtBfcStart(ConstraintSpace()), &container_builder_);
+    if (break_status == NGBreakStatus::kNeedsEarlierBreak)
+      return container_builder_.Abort(NGLayoutResult::kNeedsEarlierBreak);
   } else {
 #if DCHECK_IS_ON()
     // If we're not participating in a fragmentation context, no block
@@ -892,7 +906,7 @@
     CheckFlexLines(flex_line_outputs);
 #endif
 
-  if (ConstraintSpace().HasKnownFragmentainerBlockSize()) {
+  if (ConstraintSpace().HasBlockFragmentation()) {
     container_builder_.SetFlexBreakTokenData(
         std::make_unique<NGFlexBreakTokenData>(flex_line_outputs,
                                                total_intrinsic_block_size));
@@ -1057,7 +1071,7 @@
   }
 }
 
-bool NGFlexLayoutAlgorithm::GiveItemsFinalPositionAndSize(
+NGLayoutResult::EStatus NGFlexLayoutAlgorithm::GiveItemsFinalPositionAndSize(
     Vector<NGFlexLine>* flex_line_outputs) {
   DCHECK(!IsResumingLayout(BreakToken()));
   LayoutUnit final_content_cross_size;
@@ -1072,7 +1086,7 @@
   }
 
   absl::optional<LayoutUnit> fallback_baseline;
-  bool success = true;
+  NGLayoutResult::EStatus status = NGLayoutResult::kSuccess;
   for (wtf_size_t flex_line_idx = 0; flex_line_idx < flex_line_outputs->size();
        ++flex_line_idx) {
     NGFlexLine& line_output = (*flex_line_outputs)[flex_line_idx];
@@ -1118,8 +1132,12 @@
       } else {
         flex_item.total_remaining_block_size = fragment.BlockSize();
       }
-      success &= PropagateFlexItemInfo(item, flex_line_idx, location,
-                                       physical_fragment.Size());
+
+      if (PropagateFlexItemInfo(item, flex_line_idx, location,
+                                physical_fragment.Size()) ==
+          NGLayoutResult::kNeedsRelayoutWithNoChildScrollbarChanges) {
+        status = NGLayoutResult::kNeedsRelayoutWithNoChildScrollbarChanges;
+      }
     }
   }
 
@@ -1140,10 +1158,11 @@
   }
 
   // Signal if we need to relayout with new child scrollbar information.
-  return success;
+  return status;
 }
 
-void NGFlexLayoutAlgorithm::GiveItemsFinalPositionAndSizeForFragmentation(
+NGLayoutResult::EStatus
+NGFlexLayoutAlgorithm::GiveItemsFinalPositionAndSizeForFragmentation(
     Vector<NGFlexLine>* flex_line_outputs,
     LayoutUnit* total_intrinsic_block_size) {
   DCHECK(has_block_fragmentation_);
@@ -1158,6 +1177,29 @@
     NGFlexLine& line_output = (*flex_line_outputs)[flex_line_idx];
     const NGBreakToken* item_break_token = entry.token;
 
+    const NGEarlyBreak* early_break_in_child = nullptr;
+    if (UNLIKELY(early_break_)) {
+      if (IsEarlyBreakTarget(*early_break_, container_builder_,
+                             flex_item->ng_input_node)) {
+        container_builder_.AddBreakBeforeChild(flex_item->ng_input_node,
+                                               kBreakAppealPerfect,
+                                               /* is_forced_break */ false);
+        ConsumeRemainingFragmentainerSpace(line_output);
+        return NGLayoutResult::kSuccess;
+      } else {
+        early_break_in_child =
+            EnterEarlyBreakInChild(flex_item->ng_input_node, *early_break_);
+      }
+    }
+
+    // A child break in a parallel flow doesn't affect whether we should
+    // break here or not.
+    if (container_builder_.HasInflowChildBreakInside()) {
+      // But if the break happened in the same flow, we'll now just finish
+      // layout of the fragment. No more siblings should be processed.
+      break;
+    }
+
     // flex_item.offset stores the main axis offset in X and the
     // cross axis offset in Y. But AddChild wants offset from parent
     // rectangle, so we have to transpose for columns. AddChild takes care of
@@ -1179,24 +1221,36 @@
         DoesItemStretch(flex_item->ng_input_node)
             ? absl::optional<LayoutUnit>(line_output.line_cross_size)
             : absl::nullopt;
-
     const bool min_block_size_should_encompass_intrinsic_size =
         MinBlockSizeShouldEncompassIntrinsicSize(*flex_item);
+
     NGConstraintSpace child_space = BuildSpaceForLayout(
         flex_item->ng_input_node, flex_item->main_axis_final_size,
         line_cross_size_for_stretch, location.Y(),
         min_block_size_should_encompass_intrinsic_size);
-    // TODO(almaher): Handle a break before.
     scoped_refptr<const NGLayoutResult> layout_result =
-        flex_item->ng_input_node.Layout(
-            child_space, To<NGBlockBreakToken>(item_break_token));
+        flex_item->ng_input_node.Layout(child_space,
+                                        To<NGBlockBreakToken>(item_break_token),
+                                        early_break_in_child);
 
-    // A child break in a parallel flow doesn't affect whether we should
-    // break here or not.
-    if (container_builder_.HasInflowChildBreakInside()) {
-      // But if the break happened in the same flow, we'll now just finish
-      // layout of the fragment. No more siblings should be processed.
-      break;
+    // TODO(almaher): Special break behavior will be needed for row flex
+    // containers.
+    NGBreakStatus break_status = NGBreakStatus::kContinue;
+    if (!early_break_) {
+      bool has_container_separation =
+          last_line_idx_to_process_first_child_ == flex_line_idx;
+      break_status = BreakBeforeChildIfNeeded(
+          ConstraintSpace(), flex_item->ng_input_node, *layout_result,
+          ConstraintSpace().FragmentainerOffsetAtBfc() + location.Y(),
+          has_container_separation, &container_builder_);
+    }
+
+    if (break_status == NGBreakStatus::kBrokeBefore) {
+      ConsumeRemainingFragmentainerSpace(line_output);
+      return NGLayoutResult::kSuccess;
+    }
+    if (break_status == NGBreakStatus::kNeedsEarlierBreak) {
+      return NGLayoutResult::kNeedsEarlierBreak;
     }
 
     const auto& physical_fragment =
@@ -1232,6 +1286,7 @@
       PropagateBaselineFromChild(flex_item->Style(), fragment, location.Y(),
                                  &fallback_baseline);
     }
+    last_line_idx_to_process_first_child_ = flex_line_idx;
   }
 
   if (!container_builder_.HasInflowChildBreakInside() &&
@@ -1243,14 +1298,17 @@
   // baseline alignment.
   if (!container_builder_.Baseline() && fallback_baseline)
     container_builder_.SetBaseline(*fallback_baseline);
+
+  return NGLayoutResult::kSuccess;
 }
 
-bool NGFlexLayoutAlgorithm::PropagateFlexItemInfo(FlexItem* flex_item,
-                                                  wtf_size_t flex_line_idx,
-                                                  LayoutPoint location,
-                                                  PhysicalSize fragment_size) {
+NGLayoutResult::EStatus NGFlexLayoutAlgorithm::PropagateFlexItemInfo(
+    FlexItem* flex_item,
+    wtf_size_t flex_line_idx,
+    LayoutPoint location,
+    PhysicalSize fragment_size) {
   DCHECK(flex_item);
-  bool success = true;
+  NGLayoutResult::EStatus status = NGLayoutResult::kSuccess;
 
   // TODO(almaher): How should devtools be handled for multiple fragments?
   if (UNLIKELY(layout_info_for_devtools_)) {
@@ -1285,18 +1343,18 @@
   if (!ignore_child_scrollbar_changes_) {
     if (flex_item->scrollbars_ !=
         ComputeScrollbarsForNonAnonymous(flex_item->ng_input_node_))
-      success = false;
+      status = NGLayoutResult::kNeedsRelayoutWithNoChildScrollbarChanges;
 
     // The flex-item scrollbars may not have changed, but an descendant's
     // scrollbars might have causing the min/max sizes to be incorrect.
     if (flex_item->depends_on_min_max_sizes_ &&
         flex_item->ng_input_node_.GetLayoutBox()->IntrinsicLogicalWidthsDirty())
-      success = false;
+      status = NGLayoutResult::kNeedsRelayoutWithNoChildScrollbarChanges;
   } else {
     DCHECK_EQ(flex_item->scrollbars_,
               ComputeScrollbarsForNonAnonymous(flex_item->ng_input_node_));
   }
-  return success;
+  return status;
 }
 
 void NGFlexLayoutAlgorithm::AdjustButtonBaseline(
@@ -1446,6 +1504,23 @@
   return MinMaxSizesResult(sizes, depends_on_block_constraints);
 }
 
+LayoutUnit NGFlexLayoutAlgorithm::FragmentainerSpaceAvailable() const {
+  return (FragmentainerSpaceAtBfcStart(ConstraintSpace()) -
+          intrinsic_block_size_)
+      .ClampNegativeToZero();
+}
+
+void NGFlexLayoutAlgorithm::ConsumeRemainingFragmentainerSpace(
+    NGFlexLine& flex_line) {
+  if (ConstraintSpace().HasKnownFragmentainerBlockSize()) {
+    // The remaining part of the fragmentainer (the unusable space for child
+    // content, due to the break) should still be occupied by this container.
+    LayoutUnit expansion = FragmentainerSpaceAvailable();
+    intrinsic_block_size_ += expansion;
+    flex_line.item_offset_adjustment += expansion;
+  }
+}
+
 #if DCHECK_IS_ON()
 void NGFlexLayoutAlgorithm::CheckFlexLines(
     const Vector<NGFlexLine>& flex_line_outputs) const {
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h
index 05520cf..7ac426e 100644
--- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h
@@ -73,14 +73,15 @@
       bool min_block_size_should_encompass_intrinsic_size = false) const;
   void ConstructAndAppendFlexItems();
   void ApplyFinalAlignmentAndReversals(Vector<NGFlexLine>* flex_line_outputs);
-  bool GiveItemsFinalPositionAndSize(Vector<NGFlexLine>* flex_line_outputs);
-  void GiveItemsFinalPositionAndSizeForFragmentation(
+  NGLayoutResult::EStatus GiveItemsFinalPositionAndSize(
+      Vector<NGFlexLine>* flex_line_outputs);
+  NGLayoutResult::EStatus GiveItemsFinalPositionAndSizeForFragmentation(
       Vector<NGFlexLine>* flex_line_outputs,
       LayoutUnit* total_intrinsic_block_size);
-  bool PropagateFlexItemInfo(FlexItem* flex_item,
-                             wtf_size_t flex_line_idx,
-                             LayoutPoint location,
-                             PhysicalSize fragment_size);
+  NGLayoutResult::EStatus PropagateFlexItemInfo(FlexItem* flex_item,
+                                                wtf_size_t flex_line_idx,
+                                                LayoutPoint location,
+                                                PhysicalSize fragment_size);
   void LayoutColumnReverse(LayoutUnit main_axis_content_size);
 
   // This is same method as FlexItem but we need that logic before FlexItem is
@@ -99,6 +100,16 @@
       LayoutUnit block_offset,
       absl::optional<LayoutUnit>* fallback_baseline);
 
+  // Return the amount of block space available in the current fragmentainer
+  // for the node being laid out by this algorithm.
+  LayoutUnit FragmentainerSpaceAvailable() const;
+
+  // Consume all remaining fragmentainer space. This happens when we decide to
+  // break before a child.
+  //
+  // https://www.w3.org/TR/css-break-3/#box-splitting
+  void ConsumeRemainingFragmentainerSpace(NGFlexLine& flex_line);
+
 #if DCHECK_IS_ON()
   void CheckFlexLines(const Vector<NGFlexLine>& flex_line_outputs) const;
 #endif
@@ -111,6 +122,12 @@
   bool has_column_percent_flex_basis_ = false;
   bool ignore_child_scrollbar_changes_ = false;
   bool has_block_fragmentation_ = false;
+
+  // This will be set during block fragmentation once we've processed the first
+  // flex item in a given line. It is used to check if we're at a valid class A
+  // or B breakpoint within a column flex container.
+  wtf_size_t last_line_idx_to_process_first_child_ = kNotFound;
+
   FlexLayoutAlgorithm algorithm_;
   DevtoolsFlexInfo* layout_info_for_devtools_;
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
index b0f92e7e..05a41be 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
@@ -346,7 +346,7 @@
   const bool is_table = node.IsTable();
   const bool can_compute_block_size_without_layout =
       CanComputeBlockSizeWithoutLayout(node);
-  bool is_shrink_to_fit = is_table || node.ShouldBeConsideredAsReplaced();
+  bool is_shrink_to_fit = is_table;
 
   auto MinMaxSizesFunc = [&](MinMaxSizesType type) -> MinMaxSizesResult {
     DCHECK(!node.IsReplaced());
@@ -458,7 +458,6 @@
 
   scoped_refptr<const NGLayoutResult> result;
 
-  // NOTE: |is_shrink_to_fit| isn't symmetrical with the inline calculations.
   const auto& style = node.Style();
   const bool is_table = node.IsTable();
   bool is_shrink_to_fit = is_table;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_result.h b/third_party/blink/renderer/core/layout/ng/ng_layout_result.h
index 11781d6..9b66095 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_result.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_result.h
@@ -46,6 +46,7 @@
     kOutOfFragmentainerSpace = 3,
     kNeedsRelayoutWithNoForcedTruncateAtLineClamp = 4,
     kDisableFragmentation = 5,
+    kNeedsRelayoutWithNoChildScrollbarChanges = 6,
     // When adding new values, make sure the bit size of |Bitfields::status| is
     // large enough to store.
   };
diff --git a/third_party/blink/renderer/core/testing/mock_function_scope.cc b/third_party/blink/renderer/core/testing/mock_function_scope.cc
index 1bae0c2..76e4c4f 100644
--- a/third_party/blink/renderer/core/testing/mock_function_scope.cc
+++ b/third_party/blink/renderer/core/testing/mock_function_scope.cc
@@ -23,43 +23,44 @@
 v8::Local<v8::Function> MockFunctionScope::ExpectCall(String* captor) {
   mock_functions_.push_back(
       MakeGarbageCollected<MockFunction>(script_state_, captor));
-  EXPECT_CALL(*mock_functions_.back(), Call(testing::_));
-  return mock_functions_.back()->Bind();
+  EXPECT_CALL(*mock_functions_.back(), Call(script_state_, testing::_));
+  return MakeGarbageCollected<NewScriptFunction>(script_state_,
+                                                 mock_functions_.back())
+      ->V8Function();
 }
 
 v8::Local<v8::Function> MockFunctionScope::ExpectCall() {
-  mock_functions_.push_back(MakeGarbageCollected<MockFunction>(script_state_));
-  EXPECT_CALL(*mock_functions_.back(), Call(testing::_));
-  return mock_functions_.back()->Bind();
+  mock_functions_.push_back(MakeGarbageCollected<MockFunction>());
+  EXPECT_CALL(*mock_functions_.back(), Call(script_state_, testing::_));
+  return MakeGarbageCollected<NewScriptFunction>(script_state_,
+                                                 mock_functions_.back())
+      ->V8Function();
 }
 
 v8::Local<v8::Function> MockFunctionScope::ExpectNoCall() {
-  mock_functions_.push_back(MakeGarbageCollected<MockFunction>(script_state_));
-  EXPECT_CALL(*mock_functions_.back(), Call(testing::_)).Times(0);
-  return mock_functions_.back()->Bind();
+  mock_functions_.push_back(MakeGarbageCollected<MockFunction>());
+  EXPECT_CALL(*mock_functions_.back(), Call(script_state_, testing::_))
+      .Times(0);
+  return MakeGarbageCollected<NewScriptFunction>(script_state_,
+                                                 mock_functions_.back())
+      ->V8Function();
 }
 
 ACTION_P2(SaveValueIn, script_state, captor) {
   *captor = ToCoreString(
-      arg0.V8Value()->ToString(script_state->GetContext()).ToLocalChecked());
+      arg1.V8Value()->ToString(script_state->GetContext()).ToLocalChecked());
 }
 
-MockFunctionScope::MockFunction::MockFunction(ScriptState* script_state)
-    : ScriptFunction(script_state) {
-  ON_CALL(*this, Call(testing::_)).WillByDefault(testing::ReturnArg<0>());
+MockFunctionScope::MockFunction::MockFunction() {
+  ON_CALL(*this, Call(testing::_, testing::_))
+      .WillByDefault(testing::ReturnArg<1>());
 }
 
 MockFunctionScope::MockFunction::MockFunction(ScriptState* script_state,
-                                              String* captor)
-    : ScriptFunction(script_state) {
-  ON_CALL(*this, Call(testing::_))
-      .WillByDefault(
-          testing::DoAll(SaveValueIn(WrapPersistent(script_state), captor),
-                         testing::ReturnArg<0>()));
-}
-
-v8::Local<v8::Function> MockFunctionScope::MockFunction::Bind() {
-  return BindToV8Function();
+                                              String* captor) {
+  ON_CALL(*this, Call(script_state, testing::_))
+      .WillByDefault(testing::DoAll(SaveValueIn(script_state, captor),
+                                    testing::ReturnArg<1>()));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/testing/mock_function_scope.h b/third_party/blink/renderer/core/testing/mock_function_scope.h
index e575c5c..915c779a 100644
--- a/third_party/blink/renderer/core/testing/mock_function_scope.h
+++ b/third_party/blink/renderer/core/testing/mock_function_scope.h
@@ -28,14 +28,13 @@
   v8::Local<v8::Function> ExpectNoCall();
 
  private:
-  class MockFunction : public ScriptFunction {
+  class MockFunction : public NewScriptFunction::Callable {
    public:
-    explicit MockFunction(ScriptState*);
+    MockFunction();
     // TODO(http://crbug.com/1159794): add other convenience methods that allow
     // the test case to capture non-String values.
     MockFunction(ScriptState*, String* captor);
-    v8::Local<v8::Function> Bind();
-    MOCK_METHOD1(Call, ScriptValue(ScriptValue));
+    MOCK_METHOD2(Call, ScriptValue(ScriptState*, ScriptValue));
   };
 
   ScriptState* script_state_;
diff --git a/third_party/blink/renderer/core/testing/module_test_base.cc b/third_party/blink/renderer/core/testing/module_test_base.cc
index 73ffae7..6697df81 100644
--- a/third_party/blink/renderer/core/testing/module_test_base.cc
+++ b/third_party/blink/renderer/core/testing/module_test_base.cc
@@ -57,12 +57,9 @@
   ParametrizedModuleTestBase::SetUp(UseTopLevelAwait());
 }
 
-class SaveResultFunction final : public ScriptFunction {
+class SaveResultFunction final : public NewScriptFunction::Callable {
  public:
-  explicit SaveResultFunction(ScriptState* script_state)
-      : ScriptFunction(script_state) {}
-
-  v8::Local<v8::Function> Bind() { return BindToV8Function(); }
+  SaveResultFunction() = default;
 
   v8::Local<v8::Value> GetResult() {
     EXPECT_TRUE(result_);
@@ -70,26 +67,20 @@
     return result_->V8Value();
   }
 
- private:
-  ScriptValue Call(ScriptValue value) override {
+  ScriptValue Call(ScriptState*, ScriptValue value) override {
     *result_ = value;
     return value;
   }
 
+ private:
   ScriptValue* result_ = nullptr;
 };
 
-class ExpectNotReached final : public ScriptFunction {
+class ExpectNotReached final : public NewScriptFunction::Callable {
  public:
-  static v8::Local<v8::Function> Create(ScriptState* script_state) {
-    auto* self = MakeGarbageCollected<ExpectNotReached>(script_state);
-    return self->BindToV8Function();
-  }
-  explicit ExpectNotReached(ScriptState* script_state)
-      : ScriptFunction(script_state) {}
+  ExpectNotReached() = default;
 
- private:
-  ScriptValue Call(ScriptValue value) override {
+  ScriptValue Call(ScriptState*, ScriptValue value) override {
     ADD_FAILURE() << "ExpectNotReached was reached";
     return value;
   }
@@ -110,10 +101,12 @@
     return promise->Result();
   }
 
-  auto* resolve_function =
-      MakeGarbageCollected<SaveResultFunction>(script_state);
+  auto* resolve_function = MakeGarbageCollected<SaveResultFunction>();
   result.GetPromise(script_state)
-      .Then(resolve_function->Bind(), ExpectNotReached::Create(script_state));
+      .Then(MakeGarbageCollected<NewScriptFunction>(script_state,
+                                                    resolve_function),
+            MakeGarbageCollected<NewScriptFunction>(
+                script_state, MakeGarbageCollected<ExpectNotReached>()));
 
   v8::MicrotasksScope::PerformCheckpoint(script_state->GetIsolate());
 
@@ -138,10 +131,11 @@
     return promise->Result();
   }
 
-  auto* reject_function =
-      MakeGarbageCollected<SaveResultFunction>(script_state);
-  script_promise.Then(ExpectNotReached::Create(script_state),
-                      reject_function->Bind());
+  auto* reject_function = MakeGarbageCollected<SaveResultFunction>();
+  script_promise.Then(
+      MakeGarbageCollected<NewScriptFunction>(
+          script_state, MakeGarbageCollected<ExpectNotReached>()),
+      MakeGarbageCollected<NewScriptFunction>(script_state, reject_function));
 
   v8::MicrotasksScope::PerformCheckpoint(script_state->GetIsolate());
 
diff --git a/third_party/blink/renderer/modules/credentialmanager/federated_credential_request_options.idl b/third_party/blink/renderer/modules/credentialmanager/federated_credential_request_options.idl
index 6f93a77..a35aa05 100644
--- a/third_party/blink/renderer/modules/credentialmanager/federated_credential_request_options.idl
+++ b/third_party/blink/renderer/modules/credentialmanager/federated_credential_request_options.idl
@@ -2,6 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+enum Mode {
+  "mediated",
+  "permission"
+};
+
 // https://w3c.github.io/webappsec-credential-management/#dictdef-federatedcredentialrequestoptions
 dictionary FederatedCredentialRequestOptions {
     sequence<(DOMString or FederatedIdentityProvider)> providers;
diff --git a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc
index ea22a72..b553007 100644
--- a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc
+++ b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc
@@ -6,6 +6,7 @@
 
 #include "base/guid.h"
 #include "base/token.h"
+#include "build/build_config.h"
 #include "media/capture/mojom/video_capture_types.mojom-blink.h"
 #include "media/capture/video_capture_types.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -20,6 +21,7 @@
 
 namespace {
 
+#if !defined(OS_ANDROID)
 // If crop_id is the empty string, returns an empty base::Token.
 // If crop_id is a valid UUID, returns a base::Token representing the ID.
 // Otherwise, returns nullopt.
@@ -76,6 +78,7 @@
 
   NOTREACHED();
 }
+#endif
 
 }  // namespace
 
@@ -115,6 +118,12 @@
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
+#if defined(OS_ANDROID)
+  resolver->Reject(MakeGarbageCollected<DOMException>(
+      DOMExceptionCode::kUnknownError, "Not supported on Android."));
+  return promise;
+#else
+
   const absl::optional<base::Token> crop_id_token =
       CropIdStringToToken(crop_id);
   if (!crop_id_token.has_value()) {
@@ -138,6 +147,7 @@
                       WTF::Bind(&ResolveCropPromise, WrapPersistent(resolver)));
 
   return promise;
+#endif
 }
 
 BrowserCaptureMediaStreamTrack* BrowserCaptureMediaStreamTrack::clone(
diff --git a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track_test.cc b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track_test.cc
index 9f1455b..2b9b192 100644
--- a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track_test.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.h"
 
 #include "base/guid.h"
+#include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/web/web_heap.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
@@ -49,6 +50,7 @@
   }
 };
 
+#if !defined(OS_ANDROID)
 TEST_F(BrowserCaptureMediaStreamTrackTest, CropToOnValidId) {
   V8TestingScope v8_scope;
 
@@ -68,7 +70,7 @@
       v8_scope.GetExceptionState());
 }
 
-TEST_F(BrowserCaptureMediaStreamTrackTest, CropToInvalidIdRaisesException) {
+TEST_F(BrowserCaptureMediaStreamTrackTest, CropToInvalidIdIsRejected) {
   V8TestingScope v8_scope;
 
   std::unique_ptr<MockMediaStreamVideoSource> media_stream_video_source =
@@ -79,12 +81,32 @@
   BrowserCaptureMediaStreamTrack* const track =
       MakeTrack(v8_scope, std::move(media_stream_video_source));
 
-  ASSERT_FALSE(v8_scope.GetExceptionState().HadException());
   const ScriptPromise promise =
       track->cropTo(v8_scope.GetScriptState(), WTF::String("INVALID-ID"),
                     v8_scope.GetExceptionState());
-  EXPECT_FALSE(v8_scope.GetExceptionState().HadException());
   EXPECT_EQ(promise.V8Promise()->State(), v8::Promise::kRejected);
 }
 
+#else
+
+TEST_F(BrowserCaptureMediaStreamTrackTest, CropToFailsOnAndroid) {
+  V8TestingScope v8_scope;
+
+  const base::GUID valid_id = base::GUID::GenerateRandomV4();
+
+  std::unique_ptr<MockMediaStreamVideoSource> media_stream_video_source =
+      MakeMockMediaStreamVideoSource();
+
+  EXPECT_CALL(*media_stream_video_source, Crop(_, _)).Times(0);
+
+  BrowserCaptureMediaStreamTrack* const track =
+      MakeTrack(v8_scope, std::move(media_stream_video_source));
+
+  const ScriptPromise promise = track->cropTo(
+      v8_scope.GetScriptState(), WTF::String(valid_id.AsLowercaseString()),
+      v8_scope.GetExceptionState());
+  EXPECT_EQ(promise.V8Promise()->State(), v8::Promise::kRejected);
+}
+#endif
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/local_video_capturer_source.cc b/third_party/blink/renderer/modules/mediastream/local_video_capturer_source.cc
index c8baafa..db6b4fe4 100644
--- a/third_party/blink/renderer/modules/mediastream/local_video_capturer_source.cc
+++ b/third_party/blink/renderer/modules/mediastream/local_video_capturer_source.cc
@@ -80,14 +80,6 @@
   manager_->Resume(session_id_);
 }
 
-void LocalVideoCapturerSource::Crop(
-    const base::Token& crop_id,
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  manager_->Crop(session_id_, crop_id,
-                 base::BindPostTask(task_runner_, std::move(callback)));
-}
-
 void LocalVideoCapturerSource::StopCapture() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   // Immediately make sure we don't provide more frames.
diff --git a/third_party/blink/renderer/modules/mediastream/local_video_capturer_source.h b/third_party/blink/renderer/modules/mediastream/local_video_capturer_source.h
index 9e4c87ba..a7e6429 100644
--- a/third_party/blink/renderer/modules/mediastream/local_video_capturer_source.h
+++ b/third_party/blink/renderer/modules/mediastream/local_video_capturer_source.h
@@ -59,9 +59,6 @@
   void RequestRefreshFrame() override;
   void MaybeSuspend() override;
   void Resume() override;
-  void Crop(const base::Token& crop_id,
-            base::OnceCallback<void(media::mojom::CropRequestResult)> callback)
-      override;
   void StopCapture() override;
   void OnFrameDropped(media::VideoCaptureFrameDropReason reason) override;
   void OnLog(const std::string& message) override;
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc
index 2fb181be..3ff92d3 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc
@@ -8,6 +8,7 @@
 
 #include "base/callback.h"
 #include "base/token.h"
+#include "build/build_config.h"
 #include "media/capture/mojom/video_capture_types.mojom-blink.h"
 #include "media/capture/video_capture_types.h"
 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
@@ -191,12 +192,21 @@
                          WTF::Unretained(this), capture_params_));
 }
 
+#if !defined(OS_ANDROID)
 void MediaStreamVideoCapturerSource::Crop(
     const base::Token& crop_id,
     base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  source_->Crop(crop_id, std::move(callback));
+  const absl::optional<base::UnguessableToken>& session_id =
+      device().serializable_session_id();
+  if (!session_id.has_value()) {
+    std::move(callback).Run(media::mojom::CropRequestResult::kErrorGeneric);
+    return;
+  }
+  GetMediaStreamDispatcherHost()->Crop(session_id.value(), crop_id,
+                                       std::move(callback));
 }
+#endif
 
 base::WeakPtr<MediaStreamVideoSource>
 MediaStreamVideoCapturerSource::GetWeakPtr() const {
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h b/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h
index 60e28d2..5253ec9 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h
@@ -13,6 +13,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
 #include "base/token.h"
+#include "build/build_config.h"
 #include "media/capture/mojom/video_capture_types.mojom-blink.h"
 #include "media/capture/video_capture_types.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -86,9 +87,11 @@
   absl::optional<media::VideoCaptureParams> GetCurrentCaptureParams()
       const override;
   void ChangeSourceImpl(const MediaStreamDevice& new_device) override;
+#if !defined(OS_ANDROID)
   void Crop(const base::Token& crop_id,
             base::OnceCallback<void(media::mojom::CropRequestResult)> callback)
       override;
+#endif
   base::WeakPtr<MediaStreamVideoSource> GetWeakPtr() const override;
 
   // Method to bind as RunningCallback in VideoCapturerSource::StartCapture().
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc
index 4456aeb..e8c7437a 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc
@@ -17,6 +17,7 @@
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/token.h"
+#include "build/build_config.h"
 #include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h"
@@ -517,11 +518,13 @@
   return false;
 }
 
+#if !defined(OS_ANDROID)
 void MediaStreamVideoSource::Crop(
     const base::Token& crop_id,
     base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
   std::move(callback).Run(media::mojom::CropRequestResult::kErrorGeneric);
 }
+#endif
 
 VideoCaptureFeedbackCB MediaStreamVideoSource::GetFeedbackCallback() const {
   // Each source implementation has to implement its own feedback callbacks.
diff --git a/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h b/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h
index 3b046ea4..05ea455 100644
--- a/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h
+++ b/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h
@@ -53,6 +53,10 @@
   MOCK_METHOD1(OnStreamStarted, void(const WTF::String&));
 #if !defined(OS_ANDROID)
   MOCK_METHOD2(FocusCapturedSurface, void(const WTF::String&, bool));
+  MOCK_METHOD3(Crop,
+               void(const base::UnguessableToken&,
+                    const base::Token&,
+                    CropCallback));
 #endif
 
   void ResetSessionId() { session_id_ = base::UnguessableToken::Create(); }
diff --git a/third_party/blink/renderer/modules/webid/web_id.cc b/third_party/blink/renderer/modules/webid/web_id.cc
index 8c83a16..4d71f0d 100644
--- a/third_party/blink/renderer/modules/webid/web_id.cc
+++ b/third_party/blink/renderer/modules/webid/web_id.cc
@@ -8,7 +8,6 @@
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_web_id_logout_request.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_web_id_request_options.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/modules/webid/web_id_type_converters.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
diff --git a/third_party/blink/renderer/modules/webid/web_id_request_options.idl b/third_party/blink/renderer/modules/webid/web_id_request_options.idl
deleted file mode 100644
index eb747c7..0000000
--- a/third_party/blink/renderer/modules/webid/web_id_request_options.idl
+++ /dev/null
@@ -1,19 +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.
-
-// https://github.com/WICG/WebID
-
-enum Mode {
-  "mediated",
-  "permission"
-};
-
-dictionary WebIdRequestOptions {
-  // URL for the Identity Provider.
-  required USVString provider;
-  USVString client_id;
-  USVString nonce;
-  Mode mode = "permission";
-  boolean preferAutoSignIn = false;
-};
diff --git a/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager.cc b/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager.cc
index dbd2906..4c326ee 100644
--- a/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager.cc
+++ b/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager.cc
@@ -188,19 +188,6 @@
                                 it->impl->GetWeakPtr(), false));
 }
 
-void WebVideoCaptureImplManager::Crop(
-    const media::VideoCaptureSessionId& id,
-    const base::Token& crop_id,
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
-  DCHECK(render_main_task_runner_->BelongsToCurrentThread());
-  const auto it = base::ranges::find(devices_, id, &DeviceEntry::session_id);
-  if (it == devices_.end())
-    return;
-  Platform::Current()->GetIOTaskRunner()->PostTask(
-      FROM_HERE, base::BindOnce(&VideoCaptureImpl::Crop, it->impl->GetWeakPtr(),
-                                crop_id, std::move(callback)));
-}
-
 void WebVideoCaptureImplManager::GetDeviceSupportedFormats(
     const media::VideoCaptureSessionId& id,
     VideoCaptureDeviceFormatsCB callback) {
diff --git a/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc b/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc
index 8afa7b630..a236bd3 100644
--- a/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc
+++ b/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc
@@ -86,11 +86,6 @@
     pause_callback_->OnResumed(session_id);
   }
 
-  MOCK_METHOD3(Crop,
-               void(const base::UnguessableToken&,
-                    const base::Token&,
-                    CropCallback));
-
   MOCK_METHOD1(RequestRefreshFrame, void(const base::UnguessableToken&));
   MOCK_METHOD3(ReleaseBuffer,
                void(const base::UnguessableToken&,
diff --git a/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc b/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
index ed81a700..dbbfa2de1 100644
--- a/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
+++ b/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
@@ -641,16 +641,6 @@
     GetVideoCaptureHost()->Resume(device_id_, session_id_, params_);
 }
 
-void VideoCaptureImpl::Crop(
-    const base::Token& crop_id,
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
-  DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
-  GetVideoCaptureHost()->Crop(
-      device_id_, crop_id,
-      base::BindOnce(&VideoCaptureImpl::OnCropResult,
-                     weak_factory_.GetWeakPtr(), std::move(callback)));
-}
-
 void VideoCaptureImpl::StartCapture(
     int client_id,
     const media::VideoCaptureParams& params,
@@ -1124,13 +1114,6 @@
   std::move(callback).Run(formats_in_use);
 }
 
-void VideoCaptureImpl::OnCropResult(
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback,
-    media::mojom::CropRequestResult result) {
-  DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
-  std::move(callback).Run(result);
-}
-
 bool VideoCaptureImpl::RemoveClient(int client_id, ClientInfoMap* clients) {
   DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
 
diff --git a/third_party/blink/renderer/platform/video_capture/video_capture_impl.h b/third_party/blink/renderer/platform/video_capture/video_capture_impl.h
index 1b92f9b..7c68827 100644
--- a/third_party/blink/renderer/platform/video_capture/video_capture_impl.h
+++ b/third_party/blink/renderer/platform/video_capture/video_capture_impl.h
@@ -70,13 +70,6 @@
   // Stop/resume delivering video frames to clients, based on flag |suspend|.
   void SuspendCapture(bool suspend);
 
-  // Start/stop cropping a video track.
-  // Non-empty |crop_id| sets (or changes) the crop-target.
-  // Empty |crop_id| reverts the capture to its original, uncropped state.
-  // The callback reports success/failure.
-  void Crop(const base::Token& crop_id,
-            base::OnceCallback<void(media::mojom::CropRequestResult)> callback);
-
   // Start capturing using the provided parameters.
   // |client_id| must be unique to this object in the render process. It is
   // used later to stop receiving video frames.
@@ -217,10 +210,6 @@
       VideoCaptureDeviceFormatsCallback callback,
       const Vector<media::VideoCaptureFormat>& formats_in_use);
 
-  void OnCropResult(
-      base::OnceCallback<void(media::mojom::CropRequestResult)> callback,
-      media::mojom::CropRequestResult result);
-
   // Tries to remove |client_id| from |clients|, returning false if not found.
   bool RemoveClient(int client_id, ClientInfoMap* clients);
 
diff --git a/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc b/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc
index 94e5f15c..f8ba2d1 100644
--- a/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc
+++ b/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc
@@ -81,10 +81,6 @@
                void(const base::UnguessableToken&,
                     const base::UnguessableToken&,
                     const media::VideoCaptureParams&));
-  MOCK_METHOD3(Crop,
-               void(const base::UnguessableToken&,
-                    const base::Token&,
-                    CropCallback));
   MOCK_METHOD1(RequestRefreshFrame, void(const base::UnguessableToken&));
   MOCK_METHOD3(ReleaseBuffer,
                void(const base::UnguessableToken&,
diff --git a/third_party/blink/renderer/platform/video_capture/video_capturer_source.h b/third_party/blink/renderer/platform/video_capture/video_capturer_source.h
index 6d09da4..fdc0d72 100644
--- a/third_party/blink/renderer/platform/video_capture/video_capturer_source.h
+++ b/third_party/blink/renderer/platform/video_capture/video_capturer_source.h
@@ -85,14 +85,6 @@
   // StopCapture(). Otherwise, its behavior is undefined.
   virtual void Resume() {}
 
-  // Start/stop cropping a video track.
-  // Non-empty |crop_id| sets (or changes) the crop-target.
-  // Empty |crop_id| reverts the capture to its original, uncropped state.
-  // The callback reports success/failure.
-  virtual void Crop(
-      const base::Token& crop_id,
-      base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {}
-
   // Stops capturing frames and clears all callbacks including the
   // SupportedFormatsCallback callback. Note that queued frame callbacks
   // may still occur after this call, so the caller must take care to
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
index adca5d6f..686af73 100755
--- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
+++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -108,6 +108,7 @@
             'absl::make_optional',
             'base::make_span',
             'absl::nullopt',
+            'absl::nullopt_t',
             'base::ranges::.+',
             'base::sequence_manager::TaskTimeObserver',
             'base::size',
@@ -624,8 +625,11 @@
             'base::(scoped_nsobject|ScopedCFTypeRef)',
 
             # absl::variant and getters:
-            'absl::variant',
+            'absl::get',
             'absl::get_if',
+            'absl::holds_alternative',
+            'absl::variant',
+            'absl::visit',
         ],
         'disallowed': [
             ('base::Bind(|Once|Repeating)',
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
index a3c489c3..13cbf0c 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
+++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -256,6 +256,9 @@
 crbug.com/591099 external/wpt/css/css-position/position-absolute-in-inline-004.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-position/position-absolute-replaced-intrinsic-size.tentative.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-position/position-absolute-replaced-no-intrinsic-size.tentative.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-position/position-absolute-semi-replaced-stretch-button.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-position/position-absolute-semi-replaced-stretch-input.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-position/position-absolute-semi-replaced-stretch-other.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-position/position-relative-001.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-position/position-relative-002.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-position/position-relative-004.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index c8e4c0a4..f34e4d91 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -1507,6 +1507,14 @@
 virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/flex-container-fragmentation-007.tentative.html [ Pass ]
 virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-012.html [ Pass ]
 virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-014.html [ Pass ]
+virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-015.html [ Pass ]
+virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-016.html [ Pass ]
+virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-017.html [ Pass ]
+virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-018.html [ Pass ]
+virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-019.html [ Pass ]
+virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-020.html [ Pass ]
+virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-022.html [ Pass ]
+virtual/layout_ng_flex_frag/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-023.html [ Pass ]
 
 ### Tests failing with LayoutNGFlexFragmentation enabled:
 crbug.com/660611 virtual/layout_ng_flex_frag/fast/multicol/flexbox/doubly-nested-with-zero-width-flexbox-and-forced-break-crash.html [ Skip ]
@@ -4112,6 +4120,14 @@
 crbug.com/660611 external/wpt/css/css-break/flexbox/flex-container-fragmentation-007.tentative.html [ Failure ]
 crbug.com/660611 external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-012.html [ Failure ]
 crbug.com/660611 external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-014.html [ Failure ]
+crbug.com/660611 external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-015.html [ Failure ]
+crbug.com/660611 external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-016.html [ Failure ]
+crbug.com/660611 external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-017.html [ Failure ]
+crbug.com/660611 external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-018.html [ Failure ]
+crbug.com/660611 external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-019.html [ Failure ]
+crbug.com/660611 external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-020.html [ Failure ]
+crbug.com/660611 external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-022.html [ Failure ]
+crbug.com/660611 external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-023.html [ Failure ]
 crbug.com/829028 external/wpt/css/css-break/forced-break-at-fragmentainer-start-000.html [ Failure ]
 crbug.com/614667 external/wpt/css/css-break/grid/grid-item-fragmentation-020.html [ Failure ]
 crbug.com/614667 external/wpt/css/css-break/grid/grid-item-fragmentation-027.tentative.html [ Failure ]
@@ -7301,8 +7317,6 @@
 crbug.com/1266221 [ Mac11-arm64 ] virtual/fsa-incognito/external/wpt/file-system-access/sandboxed_FileSystemFileHandle-create-sync-access-handle.https.tentative.window.html [ Failure Pass ]
 crbug.com/1263354 [ Linux ] virtual/plz-dedicated-worker/external/wpt/resource-timing/object-not-found-adds-entry.html [ Failure Pass Timeout ]
 
-crbug.com/1267076 wpt_internal/fenced_frame/navigator-keyboard-layout-map.https.html [ Failure ]
-
 # Sheriff 2021-11-08
 crbug.com/1267734 [ Win7 ] virtual/plz-dedicated-worker/external/wpt/resource-timing/object-not-found-after-TAO-cross-origin-redirect.html [ Failure Pass ]
 crbug.com/1267736 [ Win ] http/tests/devtools/bindings/jssourcemap-bindings-overlapping-sources.js [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-015.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-015.html
new file mode 100644
index 0000000..b8e9133
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-015.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<title>
+  Single-line column flex fragmentation with break-inside: avoid.
+</title>
+<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination">
+<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
+<style>
+  .multicol {
+    column-count: 4;
+    column-fill: auto;
+    column-gap: 0px;
+    height: 100px;
+    width: 100px;
+    position: relative;
+    background: red;
+  }
+  .abs {
+    position: absolute;
+    height: 50px;
+    width: 25px;
+    top: 50px;
+    left: 50px;
+    background: green;
+  }
+</style>
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div class="multicol">
+  <div style="display: flex; flex-direction: column; width: 25px;">
+    <div style="height: 250px; break-inside: avoid; background: green;"></div>
+    <div style="height: 100px; break-inside: avoid; background: green;"></div>
+  </div>
+  <div class="abs"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-016.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-016.html
new file mode 100644
index 0000000..f079e11
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-016.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title>
+  Single-line column flex fragmentation with break-before: avoid.
+</title>
+<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination">
+<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
+<style>
+  .multicol {
+    column-count: 4;
+    column-fill: auto;
+    column-gap: 0px;
+    height: 100px;
+    width: 100px;
+    position: relative;
+    background: red;
+  }
+  .abs {
+    position: absolute;
+    height: 50px;
+    width: 25px;
+  }
+</style>
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div class="multicol">
+  <div style="display: flex; flex-direction: column; width: 25px;">
+    <div style="height: 50px; background: green;"></div>
+    <div style="height: 50px; background: green;"></div>
+    <div style="height: 300px; break-before: avoid; background: green;"></div>
+  </div>
+  <div class="abs" style="background: green; top: 50px; left: 0px;"></div>
+  <div class="abs" style="background: white; top: 0px;"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-017.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-017.html
new file mode 100644
index 0000000..4c4dad31
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-017.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title>
+  Single-line column flex fragmentation with break-after: avoid.
+</title>
+<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination">
+<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
+<style>
+  .multicol {
+    column-count: 4;
+    column-fill: auto;
+    column-gap: 0px;
+    height: 100px;
+    width: 100px;
+    position: relative;
+    background: red;
+  }
+  .abs {
+    position: absolute;
+    height: 50px;
+    width: 25px;
+  }
+</style>
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div class="multicol">
+  <div style="display: flex; flex-direction: column; width: 25px;">
+    <div style="height: 50px; background: green;"></div>
+    <div style="height: 50px; break-after: avoid; background: green;"></div>
+    <div style="height: 300px; background: green;"></div>
+  </div>
+  <div class="abs" style="background: green; top: 50px; left: 0px;"></div>
+  <div class="abs" style="background: white; top: 0px;"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-018.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-018.html
new file mode 100644
index 0000000..d06e1bf9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-018.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<title>
+  Single-line column flex fragmentation with break-before: column.
+</title>
+<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination">
+<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
+<style>
+  .multicol {
+    column-count: 4;
+    column-gap: 0px;
+    height: 100px;
+    width: 100px;
+    position: relative;
+    background: red;
+  }
+  .abs {
+    position: absolute;
+    height: 50px;
+    width: 25px;
+  }
+</style>
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div class="multicol">
+  <div style="display: flex; flex-direction: column; width: 25px;">
+    <div style="height: 50px; background: green;"></div>
+    <div style="height: 50px; break-before: column; background: green;"></div>
+    <div style="height: 300px; background: green;"></div>
+  </div>
+  <div class="abs" style="background: green; top: 50px; left: 0px;"></div>
+  <div class="abs" style="background: white; top: 0px;"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-019.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-019.html
new file mode 100644
index 0000000..74f7caa0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-019.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<title>
+  Single-line column flex fragmentation: break-before values on the first item
+  are propagated to the flex container.
+</title>
+<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination">
+<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
+<style>
+  .multicol {
+    column-count: 4;
+    column-gap: 0px;
+    column-fill: auto;
+    height: 100px;
+    width: 100px;
+    position: relative;
+    background: red;
+  }
+  .abs {
+    position: absolute;
+    height: 50px;
+    width: 25px;
+  }
+</style>
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div class="multicol">
+  <div style="width: 25px; height: 50px; background: green;"></div>
+  <div style="width: 25px; height: 50px; background: green;"></div>
+  <div style="display: flex; flex-direction: column; width: 25px;">
+    <div style="height: 50px; break-before: avoid; background: green;"></div>
+    <div style="height: 200px; background: green;"></div>
+  </div>
+  <div class="abs" style="background: green; top: 50px; left: 0px;"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-020.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-020.html
new file mode 100644
index 0000000..8b23027
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-020.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>
+  Single-line column flex fragmentation: break-after values on the last item
+  are propagated to the flex container.
+</title>
+<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination">
+<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
+<style>
+  .multicol {
+    column-count: 4;
+    column-gap: 0px;
+    column-fill: auto;
+    height: 100px;
+    width: 100px;
+    position: relative;
+    background: red;
+  }
+  .abs {
+    position: absolute;
+    height: 50px;
+    width: 25px;
+    top: 50px;
+    left: 25px;
+    background: green;
+  }
+</style>
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div class="multicol">
+  <div style="width: 25px; height: 50px; background: green;"></div>
+  <div style="width: 25px; height: 50px; background: green;"></div>
+  <div style="display: flex; flex-direction: column; width: 25px;">
+    <div style="height: 50px; background: green;"></div>
+    <div style="height: 50px; break-after: avoid; background: green;"></div>
+  </div>
+  <div style="width: 25px; height: 150px; background: green;"></div>
+  <div class="abs"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-021.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-021.html
new file mode 100644
index 0000000..6248205
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-021.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>
+  Single-line column flex fragmentation: we shouldn't insert a forced break if
+  there's no preceding content at the start of a fragmentainer.
+</title>
+<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination">
+<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
+<style>
+  .multicol {
+    column-count: 2;
+    column-gap: 0px;
+    column-fill: auto;
+    height: 100px;
+    width: 100px;
+    background: red;
+  }
+</style>
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div class="multicol">
+  <div style="display: flex; flex-direction: column; width: 50px;">
+    <div style="height: 100px; break-before: column; background: green;"></div>
+    <div style="height: 100px; break-before: column; background: green;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-022.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-022.html
new file mode 100644
index 0000000..b0439be
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-022.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>
+  Single-line column flex fragmentation: the flex container consumes the
+  remaining fragmentainer space if an item breaks before.
+</title>
+<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination">
+<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
+<style>
+  .multicol {
+    column-count: 2;
+    column-gap: 0px;
+    column-fill: auto;
+    height: 100px;
+    width: 100px;
+    background: red;
+  }
+</style>
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div class="multicol">
+  <div style="display: flex; flex-direction: column; width: 50px; background: green;">
+    <div style="height: 50px;"></div>
+    <div style="height: 100px; break-before: column;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-023.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-023.html
new file mode 100644
index 0000000..dd5c8a7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-023.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>
+  Single-line column flex fragmentation with break-inside: avoid and border-bottom.
+</title>
+<link rel="help" href="https://www.w3.org/TR/css-break-3/#breaking-rules">
+<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="width:100px; height:100px; background:red;">
+  <div style="columns:2; column-fill:auto; column-gap:0; height:160px;">
+    <div style="height:40px; background:green;"></div>
+    <div style="display:flex; flex-direction:column; width:50px; border-bottom:40px solid green;">
+      <div style="break-inside:avoid; height:60px; background:green;"></div>
+      <div style="break-inside:avoid; height:60px; background:green;"></div>
+    </div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-center-005.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-center-005.html
deleted file mode 100644
index c586719..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-center-005.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<link rel="help" href="https://crbug.com/1236657">
-<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
-<meta name="assert" content="A button element should be centered with auto margins and zero insets.">
-<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
-<div style="position: relative; width: 200px; height: 100px; margin-left: -50px;">
-  <button style="position: absolute; background: green; appearance: none; padding: 0; border: none; left: 0; right: 0; margin: auto; height: 100px;">
-    <div style="width: 100px;"></div>
-  </button>
-</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-button-ref.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-button-ref.html
new file mode 100644
index 0000000..296b87b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-button-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<style>
+.cb {
+  position: relative;
+  border: 3px solid black;
+  height: 100px;
+  width: 150px;
+  display: inline-block;
+  vertical-align: top;
+  margin: 5px;
+}
+.abs {
+  margin: 0;
+  position: absolute;
+  box-sizing: border-box;
+  top: 3px;
+  left: 3px;
+  outline: 2px solid lime;
+  width: calc(100% - 6px);
+  height: calc(100% - 6px);
+}
+</style>
+<div class="cb"><button class="abs">button</button></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-button.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-button.html
new file mode 100644
index 0000000..fbcdbec
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-button.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/6789">
+<link rel="match" href="position-absolute-semi-replaced-stretch-button-ref.html">
+<title>Semi-replaced elements should stretch with an auto main size, and explicit insets in that direction.</title>
+<style>
+.cb {
+  position: relative;
+  border: 3px solid black;
+  height: 100px;
+  width: 150px;
+  display: inline-block;
+  vertical-align: top;
+  margin: 5px;
+}
+.abs {
+  margin: 0;
+  position: absolute;
+  box-sizing: border-box;
+  top: 3px;
+  right: 3px;
+  bottom: 3px;
+  left: 3px;
+  outline: 2px solid lime;
+  width: auto;
+  height: auto;
+}
+</style>
+<div class="cb"><button class="abs">button</button></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-input-ref.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-input-ref.html
new file mode 100644
index 0000000..554173c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-input-ref.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<style>
+.cb {
+  position: relative;
+  border: 3px solid black;
+  height: 100px;
+  width: 150px;
+  display: inline-block;
+  vertical-align: top;
+  margin: 5px;
+}
+.wide {
+  width: 350px;
+}
+.abs {
+  margin: 0;
+  position: absolute;
+  box-sizing: border-box;
+  top: 3px;
+  left: 3px;
+  outline: 2px solid lime;
+  width: calc(100% - 6px);
+  height: calc(100% - 6px);
+}
+</style>
+<div class="cb"><input type="button" class="abs" value="input-btn"></div>
+<div class="cb"><input type="submit" class="abs"></div>
+<div class="cb"><input type="reset" class="abs"></div>
+<div class="cb"><input type="color" class="abs"></div>
+<div class="cb wide"><input type="text" class="abs" value="text"></div>
+<div class="cb wide"><input type="password" class="abs" value="pass"></div>
+<div class="cb wide"><input type="date" class="abs" value="text"></div>
+<div class="cb wide"><input type="file" class="abs"></div>
+<div class="cb wide"><input type="range" class="abs"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-input.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-input.html
new file mode 100644
index 0000000..6080f63
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-input.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/6789">
+<link rel="match" href="position-absolute-semi-replaced-stretch-input-ref.html">
+<title>Semi-replaced elements should stretch with an auto main size, and explicit insets in that direction.</title>
+<style>
+.cb {
+  position: relative;
+  border: 3px solid black;
+  height: 100px;
+  width: 150px;
+  display: inline-block;
+  vertical-align: top;
+  margin: 5px;
+}
+.wide {
+  /* Some of the form controls are wider than others
+     and need a wider CB in order to see if they're
+     stretching or shrinking. */
+  width: 350px;
+}
+.abs {
+  margin: 0;
+  position: absolute;
+  box-sizing: border-box;
+  top: 3px;
+  right: 3px;
+  bottom: 3px;
+  left: 3px;
+  outline: 2px solid lime;
+  width: auto;
+  height: auto;
+}
+</style>
+<div class="cb"><input type="button" class="abs" value="input-btn"></div>
+<div class="cb"><input type="submit" class="abs"></div>
+<div class="cb"><input type="reset" class="abs"></div>
+<div class="cb"><input type="color" class="abs"></div>
+<div class="cb wide"><input type="text" class="abs" value="text"></div>
+<div class="cb wide"><input type="password" class="abs" value="pass"></div>
+<div class="cb wide"><input type="date" class="abs" value="text"></div>
+<div class="cb wide"><input type="file" class="abs"></div>
+<div class="cb wide"><input type="range" class="abs"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-other-ref.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-other-ref.html
new file mode 100644
index 0000000..e334bc0f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-other-ref.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<style>
+.cb {
+  position: relative;
+  border: 3px solid black;
+  height: 100px;
+  width: 150px;
+  display: inline-block;
+  vertical-align: top;
+  margin: 5px;
+}
+.wide {
+  width: 350px;
+}
+.abs {
+  margin: 0;
+  position: absolute;
+  box-sizing: border-box;
+  top: 3px;
+  left: 3px;
+  outline: 2px solid lime;
+  width: calc(100% - 6px);
+  height: calc(100% - 6px);
+}
+</style>
+<div class="cb"><select class="abs"><option>select</option></select></div>
+<div class="cb"><output class="abs">output</output></div>
+<div class="cb"><label class="abs">label</output></div>
+<div class="cb"><fieldset class="abs">fieldset</fieldset></div>
+<div class="cb wide"><textarea class="abs">textarea</textarea></div>
+<div class="cb wide"><progress value="0.4" class="abs"></div>
+<div class="cb wide"><meter value="0.4" class="abs"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-other.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-other.html
new file mode 100644
index 0000000..21fc2c84
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-semi-replaced-stretch-other.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/6789">
+<link rel="match" href="position-absolute-semi-replaced-stretch-other-ref.html">
+<title>Semi-replaced elements should stretch with an auto main size, and explicit insets in that direction.</title>
+<style>
+.cb {
+  position: relative;
+  border: 3px solid black;
+  height: 100px;
+  width: 150px;
+  display: inline-block;
+  vertical-align: top;
+  margin: 5px;
+}
+.wide {
+  /* Some of the form controls are wider than others
+     and need a wider CB in order to see if they're
+     stretching or shrinking. */
+  width: 350px;
+}
+.abs {
+  margin: 0;
+  position: absolute;
+  box-sizing: border-box;
+  top: 3px;
+  right: 3px;
+  bottom: 3px;
+  left: 3px;
+  outline: 2px solid lime;
+  width: auto;
+  height: auto;
+}
+</style>
+<div class="cb"><select class="abs"><option>select</option></select></div>
+<div class="cb"><output class="abs">output</output></div>
+<div class="cb"><label class="abs">label</output></div>
+<div class="cb"><fieldset class="abs">fieldset</fieldset></div>
+<div class="cb wide"><textarea class="abs">textarea</textarea></div>
+<div class="cb wide"><progress value="0.4" class="abs"></div>
+<div class="cb wide"><meter value="0.4" class="abs"></div>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/widgets/button-layout/abspos.html b/third_party/blink/web_tests/external/wpt/html/rendering/widgets/button-layout/abspos.html
deleted file mode 100644
index c3089b1..0000000
--- a/third_party/blink/web_tests/external/wpt/html/rendering/widgets/button-layout/abspos.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!doctype html>
-<title>abspos button with auto width, non-auto left/right</title>
-<script src=/resources/testharness.js></script>
-<script src=/resources/testharnessreport.js></script>
-<link rel=help href=https://html.spec.whatwg.org/multipage/rendering.html#button-layout>
-<!--
-If the element is absolutely positioned, then for the purpose of the CSS visual formatting model, act as if the element is a replaced element.  [CSS]
--->
-<link rel=help href=https://drafts.csswg.org/css2/visudet.html#abs-replaced-width>
-<!--
-If at this point the values are over-constrained, ignore the value for either 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value.
--->
-<style>
-#overconstrained { position: absolute; left: 100px; right: 100px; }
-#ltr { position: absolute; left: 100px; margin-top: 2em }
-#rtl { position: absolute; right: 100px; margin-top: 2em }
-</style>
-<button id=overconstrained>test</button>
-<button id=ltr>test</button>
-<button id=rtl>test</button>
-<script>
-for (const dir of ['rtl', 'ltr']) {
-  test(() => {
-    document.documentElement.dir = dir;
-    const overconstrained = document.getElementById('overconstrained');
-    const ref = document.getElementById(dir);
-    assert_equals(overconstrained.offsetLeft, ref.offsetLeft, 'offsetLeft');
-    assert_equals(overconstrained.clientWidth, ref.clientWidth, 'clientWidth');
-  }, `${document.title} (${dir})`);
-}
-</script>
diff --git a/third_party/blink/web_tests/fast/replaced/absolute-position-auto-width-and-left-and-right-and-intrinsic-width-expected.html b/third_party/blink/web_tests/fast/replaced/absolute-position-auto-width-and-left-and-right-and-intrinsic-width-expected.html
deleted file mode 100644
index eb37124..0000000
--- a/third_party/blink/web_tests/fast/replaced/absolute-position-auto-width-and-left-and-right-and-intrinsic-width-expected.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<style>
-.container {
-  position: relative;
-  height: 50px;
-  background-color: gray;
-}
-
-.auto-width {
-  position: absolute;
-  left: 0;
-}
-
-.with-border-padding {
-  border: 2px;
-  padding: 5px;
-}
-
-.border-box {
-  box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  width: 200px;
-  height: 20px;
-}
-</style>
-</head>
-<body>
-<div>Check if the elements shrink to fit as per their 'intrinsic' width for Button, input, select and textarea.  If you see any the elements strech to available width, then the test has failed.</div>
-<div class="container">
-<button id="button" class="auto-width">Button</button>
-</div>
-<div class="container">
-<input id="inputText" type="text" class="auto-width">
-</div>
-<div class="container">
-<select id="select" class="auto-width"></select>
-</div>
-<div class="container">
-<textarea id="textarea" class="auto-width">Text area</textarea>
-</div>
-<div class="container">
-<button id="buttonBorderPadding" class="auto-width with-border-padding">Button</button>
-</div>
-<div class="container">
-<input id="inputTextBorderPadding" type="text" class="auto-width with-border-padding">
-</div>
-<div class="container">
-<select id="selectBorderPadding" class="auto-width with-border-padding"></select>
-</div>
-<div class="container">
-<textarea id="textareaBorderPadding" class="auto-width with-border-padding">Text area</textarea>
-</div>
-<div class="container">
-<button id="button-border-box" class="auto-width border-box with-border-padding">Button</button>
-</div>
-<div class="container">
-<input id="inputText-border-box" type="text" class="auto-width border-box with-border-padding">
-</div>
-<div class="container">
-<select id="select-border-box" class="auto-width border-box with-border-padding"></select>
-</div>
-<div class="container">
-<textarea id="textarea-border-box" class="auto-width border-box with-border-padding">Text area</textarea>
-</div>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/fast/replaced/absolute-position-auto-width-and-left-and-right-and-intrinsic-width-quirks-expected.html b/third_party/blink/web_tests/fast/replaced/absolute-position-auto-width-and-left-and-right-and-intrinsic-width-quirks-expected.html
deleted file mode 100644
index 2f7e3d7..0000000
--- a/third_party/blink/web_tests/fast/replaced/absolute-position-auto-width-and-left-and-right-and-intrinsic-width-quirks-expected.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<html>
-<head>
-<style>
-.container {
-  position: relative;
-  height: 50px;
-  background-color: gray;
-}
-
-.auto-width {
-  position: absolute;
-  left: 0;
-}
-
-.with-border-padding {
-  border: 2px;
-  padding: 5px;
-}
-
-.border-box {
-  box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  width: 200px;
-  height: 20px;
-}
-</style>
-</head>
-<body>
-<div>Check if the elements shrink to fit as per their 'intrinsic' width for Button, input, select and textarea.  If you see any the elements strech to available width, then the test has failed.</div>
-<div class="container">
-<button id="button" class="auto-width">Button</button>
-</div>
-<div class="container">
-<input id="inputText" type="text" class="auto-width">
-</div>
-<div class="container">
-<select id="select" class="auto-width"></select>
-</div>
-<div class="container">
-<textarea id="textarea" class="auto-width">Text area</textarea>
-</div>
-<div class="container">
-<button id="buttonBorderPadding" class="auto-width with-border-padding">Button</button>
-</div>
-<div class="container">
-<input id="inputTextBorderPadding" type="text" class="auto-width with-border-padding">
-</div>
-<div class="container">
-<select id="selectBorderPadding" class="auto-width with-border-padding"></select>
-</div>
-<div class="container">
-<textarea id="textareaBorderPadding" class="auto-width with-border-padding">Text area</textarea>
-</div>
-<div class="container">
-<button id="button-border-box" class="auto-width border-box with-border-padding">Button</button>
-</div>
-<div class="container">
-<input id="inputText-border-box" type="text" class="auto-width border-box with-border-padding">
-</div>
-<div class="container">
-<select id="select-border-box" class="auto-width border-box with-border-padding"></select>
-</div>
-<div class="container">
-<textarea id="textarea-border-box" class="auto-width border-box with-border-padding">Text area</textarea>
-</div>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/fast/replaced/absolute-position-auto-width-and-left-and-right-and-intrinsic-width-quirks.html b/third_party/blink/web_tests/fast/replaced/absolute-position-auto-width-and-left-and-right-and-intrinsic-width-quirks.html
deleted file mode 100644
index 5f84624..0000000
--- a/third_party/blink/web_tests/fast/replaced/absolute-position-auto-width-and-left-and-right-and-intrinsic-width-quirks.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<html>
-<head>
-<style>
-.container {
-  position: relative;
-  height: 50px;
-  background-color: gray;
-}
-
-.auto-width {
-  position: absolute;
-  left: 0;
-  right: 0;
-}
-
-.with-border-padding {
-  border: 2px;
-  padding: 5px;
-}
-
-.border-box {
-  box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  width: 200px;
-  height: 20px;
-}
-</style>
-</head>
-<body>
-<div>Check if the elements shrink to fit as per their 'intrinsic' width for Button, input, select and textarea.  If you see any the elements strech to available width, then the test has failed.</div>
-<div class="container">
-<button id="button" class="auto-width">Button</button>
-</div>
-<div class="container">
-<input id="inputText" type="text" class="auto-width">
-</div>
-<div class="container">
-<select id="select" class="auto-width"></select>
-</div>
-<div class="container">
-<textarea id="textarea" class="auto-width">Text area</textarea>
-</div>
-<div class="container">
-<button id="buttonBorderPadding" class="auto-width with-border-padding">Button</button>
-</div>
-<div class="container">
-<input id="inputTextBorderPadding" type="text" class="auto-width with-border-padding">
-</div>
-<div class="container">
-<select id="selectBorderPadding" class="auto-width with-border-padding"></select>
-</div>
-<div class="container">
-<textarea id="textareaBorderPadding" class="auto-width with-border-padding">Text area</textarea>
-</div>
-<div class="container">
-<button id="button-border-box" class="auto-width border-box with-border-padding">Button</button>
-</div>
-<div class="container">
-<input id="inputText-border-box" type="text" class="auto-width border-box with-border-padding">
-</div>
-<div class="container">
-<select id="select-border-box" class="auto-width border-box with-border-padding"></select>
-</div>
-<div class="container">
-<textarea id="textarea-border-box" class="auto-width border-box with-border-padding">Text area</textarea>
-</div>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/fast/replaced/absolute-position-auto-width-and-left-and-right-and-intrinsic-width.html b/third_party/blink/web_tests/fast/replaced/absolute-position-auto-width-and-left-and-right-and-intrinsic-width.html
deleted file mode 100644
index dbad531b..0000000
--- a/third_party/blink/web_tests/fast/replaced/absolute-position-auto-width-and-left-and-right-and-intrinsic-width.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<style>
-.container {
-  position: relative;
-  height: 50px;
-  background-color: gray;
-}
-
-.auto-width {
-  position: absolute;
-  left: 0;
-  right: 0;
-}
-
-.with-border-padding {
-  border: 2px;
-  padding: 5px;
-}
-
-.border-box {
-  box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  width: 200px;
-  height: 20px;
-}
-</style>
-</head>
-<body>
-<div>Check if the elements shrink to fit as per their 'intrinsic' width for Button, input, select and textarea.  If you see any the elements strech to available width, then the test has failed.</div>
-<div class="container">
-<button id="button" class="auto-width">Button</button>
-</div>
-<div class="container">
-<input id="inputText" type="text" class="auto-width">
-</div>
-<div class="container">
-<select id="select" class="auto-width"></select>
-</div>
-<div class="container">
-<textarea id="textarea" class="auto-width">Text area</textarea>
-</div>
-<div class="container">
-<button id="buttonBorderPadding" class="auto-width with-border-padding">Button</button>
-</div>
-<div class="container">
-<input id="inputTextBorderPadding" type="text" class="auto-width with-border-padding">
-</div>
-<div class="container">
-<select id="selectBorderPadding" class="auto-width with-border-padding"></select>
-</div>
-<div class="container">
-<textarea id="textareaBorderPadding" class="auto-width with-border-padding">Text area</textarea>
-</div>
-<div class="container">
-<button id="button-border-box" class="auto-width border-box with-border-padding">Button</button>
-</div>
-<div class="container">
-<input id="inputText-border-box" type="text" class="auto-width border-box with-border-padding">
-</div>
-<div class="container">
-<select id="select-border-box" class="auto-width border-box with-border-padding"></select>
-</div>
-<div class="container">
-<textarea id="textarea-border-box" class="auto-width border-box with-border-padding">Text area</textarea>
-</div>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/platform/win7/virtual/plz-dedicated-worker/external/wpt/resource-timing/object-not-found-after-TAO-cross-origin-redirect-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/plz-dedicated-worker/external/wpt/resource-timing/object-not-found-after-TAO-cross-origin-redirect-expected.txt
deleted file mode 100644
index 0db2045..0000000
--- a/third_party/blink/web_tests/platform/win7/virtual/plz-dedicated-worker/external/wpt/resource-timing/object-not-found-after-TAO-cross-origin-redirect-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = Uncaught TypeError: Cannot read properties of undefined (reading 'redirectStart')
-PASS window.performance is defined
-PASS window.performance.getEntriesByName is defined
-FAIL There should be one entry. assert_equals: There should be one entry. expected 1 but got 0
-Harness: the test ran to completion.
-
diff --git a/third_party/logdog/README.chromium b/third_party/logdog/README.chromium
index 1e7bcd40..959cc27 100644
--- a/third_party/logdog/README.chromium
+++ b/third_party/logdog/README.chromium
@@ -1,8 +1,8 @@
 Name: logdog
 Short Name: logdog
 URL: https://chromium.googlesource.com/infra/luci/luci-py/client/libs/logdog
-Version: 9a84af84d3fa62b230569cf1d3abf69cc7c576e2
-Revision: 9a84af84d3fa62b230569cf1d3abf69cc7c576e2
+Version: 17ec234f823f7bff6ada6584fdbbee9d54b8fc58
+Revision: 17ec234f823f7bff6ada6584fdbbee9d54b8fc58
 License: Apache 2.0
 License File: NOT_SHIPPED
 Security Critical: no
diff --git a/third_party/logdog/get.sh b/third_party/logdog/get.sh
index 87e75ab..ea97f90f3 100755
--- a/third_party/logdog/get.sh
+++ b/third_party/logdog/get.sh
@@ -5,7 +5,7 @@
 
 set -eux
 
-revision=9a84af84d3fa62b230569cf1d3abf69cc7c576e2
+revision=17ec234f823f7bff6ada6584fdbbee9d54b8fc58
 
 cd $(dirname $0)
 
diff --git a/third_party/logdog/logdog/bootstrap.py b/third_party/logdog/logdog/bootstrap.py
index aa88cef7..e213a58 100644
--- a/third_party/logdog/logdog/bootstrap.py
+++ b/third_party/logdog/logdog/bootstrap.py
@@ -41,7 +41,7 @@
       env (dict): The environment to probe. If None, `os.getenv` will be used.
 
     Raises:
-      NotBootstrappedError if the current environment is not boostrapped.
+      NotBootstrappedError if the current environment is not bootstrapped.
     """
     if env is None:
       env = os.environ
diff --git a/third_party/logdog/logdog/stream.py b/third_party/logdog/logdog/stream.py
index 6da02d4..2959c9b1 100644
--- a/third_party/logdog/logdog/stream.py
+++ b/third_party/logdog/logdog/stream.py
@@ -19,6 +19,9 @@
   from ctypes import GetLastError
 
 
+_PY2 = sys.version_info[0] == 2
+_MAPPING = collections.Mapping if _PY2 else collections.abc.Mapping
+
 _StreamParamsBase = collections.namedtuple(
     '_StreamParamsBase', ('name', 'type', 'content_type', 'tags'))
 
@@ -27,7 +30,7 @@
 #
 # See "ProtocolFrameHeaderMagic" in:
 # <luci-go>/logdog/client/butlerlib/streamproto
-BUTLER_MAGIC = 'BTLR1\x1e'
+BUTLER_MAGIC = b'BTLR1\x1e'
 
 
 class StreamParams(_StreamParamsBase):
@@ -59,7 +62,7 @@
       raise ValueError('Invalid type (%s)' % (self.type,))
 
     if self.tags is not None:
-      if not isinstance(self.tags, collections.Mapping):
+      if not isinstance(self.tags, _MAPPING):
         raise ValueError('Invalid tags type (%s)' % (self.tags,))
       for k, v in self.tags.items():
         streamname.validate_tag(k, v)
@@ -192,6 +195,29 @@
       return self._fd.close()
 
 
+  class _TextStream(_BasicStream):
+    """Extends _BasicStream, ensuring data written is UTF-8 text."""
+
+    def __init__(self, stream_client, params, fd):
+      super(StreamClient._TextStream, self).__init__(stream_client, params, fd)
+      self._fd = fd
+
+    def write(self, data):
+      if _PY2 and isinstance(data, str):
+        # byte string is unfortunately accepted in py2 because of
+        # undifferentiated usage of `str` and `unicode` but it should be
+        # discontinued in py3. User should switch to binary stream instead
+        # if there's a need to write bytes.
+        return self._fd.write(data)
+      elif _PY2 and isinstance(data, unicode):
+        return self._fd.write(data.encode('utf-8'))
+      elif not _PY2 and isinstance(data, str):
+        return self._fd.write(data.encode('utf-8'))
+      else:
+        raise ValueError(
+            'expect str, got %r that is type %s' % (data, type(data),))
+
+
   class _DatagramStream(_StreamBase):
     """Wraps a stream object to write length-prefixed datagrams."""
 
@@ -348,12 +374,12 @@
       are not valid.
     """
     self._register_new_stream(params.name)
-    params_json = params.to_json()
+    params_bytes = params.to_json().encode('utf-8')
 
     fobj = self._connect_raw()
     fobj.write(BUTLER_MAGIC)
-    varint.write_uvarint(fobj, len(params_json))
-    fobj.write(params_json)
+    varint.write_uvarint(fobj, len(params_bytes))
+    fobj.write(params_bytes)
     return fobj
 
   @contextlib.contextmanager
@@ -399,7 +425,7 @@
         type=StreamParams.TEXT,
         content_type=content_type,
         tags=tags)
-    return self._BasicStream(self, params, self.new_connection(params))
+    return self._TextStream(self, params, self.new_connection(params))
 
   @contextlib.contextmanager
   def binary(self, name, **kwargs):
diff --git a/third_party/logdog/logdog/streamname.py b/third_party/logdog/logdog/streamname.py
index 8e9bf33..91037b2 100644
--- a/third_party/logdog/logdog/streamname.py
+++ b/third_party/logdog/logdog/streamname.py
@@ -54,7 +54,7 @@
 
 
 def normalize_segment(seg, prefix=None):
-  """Given a string (str|unicode), mutate it into a valid segment name (str).
+  """Given a string, mutate it into a valid segment name.
 
   This operates by replacing invalid segment name characters with underscores
   (_) when encountered.
@@ -88,15 +88,11 @@
   if _SEGMENT_RE.match(seg) is None:
     raise AssertionError('Normalized segment is still invalid: %r' % seg)
 
-  # v could be of type unicode. As a valid stream name contains only ascii
-  # characters, it is safe to transcode v to ascii encoding (become str type).
-  if isinstance(seg, unicode):
-    return seg.encode('ascii')
   return seg
 
 
 def normalize(v, prefix=None):
-  """Given a string (str|unicode), mutate it into a valid stream name (str).
+  """Given a string, mutate it into a valid stream name.
 
   This operates by replacing invalid stream name characters with underscores (_)
   when encountered.
@@ -162,14 +158,12 @@
     try:
       validate_stream_name(self.prefix)
     except ValueError as e:
-      raise ValueError('Invalid prefix component [%s]: %s' % (
-          self.prefix, e.message,))
+      raise ValueError('Invalid prefix component [%s]: %s' % (self.prefix, e,))
 
     try:
       validate_stream_name(self.name)
     except ValueError as e:
-      raise ValueError('Invalid name component [%s]: %s' % (
-          self.name, e.message,))
+      raise ValueError('Invalid name component [%s]: %s' % (self.name, e,))
 
   def __str__(self):
     return '%s/+/%s' % (self.prefix, self.name)
diff --git a/third_party/logdog/logdog/varint.py b/third_party/logdog/logdog/varint.py
index 7bf3cca..c40bb5f61 100644
--- a/third_party/logdog/logdog/varint.py
+++ b/third_party/logdog/logdog/varint.py
@@ -3,6 +3,7 @@
 # that can be found in the LICENSE file.
 
 import os
+import struct
 import sys
 
 
@@ -28,7 +29,7 @@
     if val > 0:
       byte |= 0b10000000
 
-    w.write(chr(byte))
+    w.write(struct.pack('B', byte))
     count += 1
   return count
 
@@ -55,7 +56,7 @@
     if len(byte) == 0:
       raise ValueError('UVarint was not terminated')
 
-    byte = ord(byte)
+    byte = struct.unpack('B', byte)[0]
     result |= ((byte & 0b01111111) << (7 * count))
     count += 1
     if byte & 0b10000000 == 0:
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
index cd60500..9ce426e 100644
--- a/tools/gritsettings/resource_ids.spec
+++ b/tools/gritsettings/resource_ids.spec
@@ -233,6 +233,10 @@
     "META": {"sizes": {"includes": [10],}},
     "includes": [1920],
   },
+  "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/segmentation_internals/resources.grd": {
+    "META": {"sizes": {"includes": [10]}},
+    "includes": [1930],
+  },
   "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/settings/chromeos/os_settings_resources.grd": {
     "META": {"sizes": {"includes": [1000],}},
     "includes": [1940],
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml
index 9937ecf..228b243 100644
--- a/tools/metrics/histograms/metadata/extensions/histograms.xml
+++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -82,6 +82,9 @@
 
 <histogram name="Extensions.ApiBindingGenerationTime" units="ms"
     expires_after="2021-06-01">
+  <obsolete>
+    Code removed 2021-11.
+  </obsolete>
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -95,6 +98,9 @@
 
 <histogram name="Extensions.ApiBindingObjectGenerationTime"
     units="microseconds" expires_after="2021-06-01">
+  <obsolete>
+    Code removed 2021-11.
+  </obsolete>
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -191,6 +197,9 @@
 
 <histogram name="Extensions.AttemptedToDowngradeVersionType"
     enum="ExtensionType" expires_after="2021-06-01">
+  <obsolete>
+    Code removed 2021-11.
+  </obsolete>
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -1395,6 +1404,9 @@
 
 <histogram name="Extensions.ExtensionServiceInitTime" units="units"
     expires_after="2021-12-01">
+  <obsolete>
+    Code removed 2021-11.
+  </obsolete>
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -1407,6 +1419,9 @@
 
 <histogram name="Extensions.ExtensionServiceNotifyReadyListenersTime"
     units="units" expires_after="2021-06-01">
+  <obsolete>
+    Code removed 2021-11.
+  </obsolete>
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -3789,6 +3804,9 @@
 
 <histogram name="Extensions.UninstallDialogAction"
     enum="ExtensionUninstallDialogAction" expires_after="2021-12-01">
+  <obsolete>
+    Code removed 2021-11.
+  </obsolete>
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/gpu/histograms.xml b/tools/metrics/histograms/metadata/gpu/histograms.xml
index e05a88e..90da7c55 100644
--- a/tools/metrics/histograms/metadata/gpu/histograms.xml
+++ b/tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -22,6 +22,224 @@
 
 <histograms>
 
+<histogram name="ConfigureDisplays.External.Modeset.AttemptSucceeded"
+    enum="BooleanSuccess" expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@chromium.org</owner>
+  <summary>
+    Modeset attempt result of an external display. Every time an external
+    display is connected/disconnected, or when the display mode of the external
+    screen is changed by the user, Chrome attempts to modeset the display. This
+    metric tracks the result of those attempts. Resolution and RefreshRate
+    metrics will be recorded for each attempt.
+  </summary>
+</histogram>
+
+<histogram name="ConfigureDisplays.External.Modeset.FinalStatus"
+    enum="BooleanSuccess" expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@chromium.org</owner>
+  <summary>
+    Modeset attempt result of an internal display. This is recorded after Chrome
+    attempted all the available modes and finally modeset the display. All the
+    previously attempted modes and refreshes, including the successful one will
+    be recorded.
+  </summary>
+</histogram>
+
+<histogram name="ConfigureDisplays.External.Modeset.RefreshRate" units="Hz"
+    expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@chromium.org</owner>
+  <summary>
+    Refresh rate of the mode for the display we're about to modeset. This is
+    recorded every time an external display is connected/disconnected, or when
+    the display mode of the external screen is about to change.
+  </summary>
+</histogram>
+
+<histogram name="ConfigureDisplays.External.Modeset.Resolution"
+    enum="DisplayResolution" expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@chromium.org</owner>
+  <summary>
+    DisplayResolution of the mode for the external display we're about to
+    modeset. 0 means the display was powered off. This is recorded every time an
+    external display is connected/disconnected, or when the display mode of the
+    external screen is about to change.
+  </summary>
+</histogram>
+
+<histogram name="ConfigureDisplays.Internal.Modeset.AttemptSucceeded"
+    enum="BooleanSuccess" expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@chromium.org</owner>
+  <summary>
+    Modeset attempt result of an internal display. Chrome might try additional
+    modes after a failed attempt. Every time an external display is
+    connected/disconnected, or when the display mode of the external screen is
+    changed by the user, Chrome attempts to modeset the display. This metric
+    tracks the result of those attempts. Resolution and RefreshRate metrics will
+    be recorded for each attempt.
+  </summary>
+</histogram>
+
+<histogram name="ConfigureDisplays.Internal.Modeset.FinalStatus"
+    enum="BooleanSuccess" expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@chromium.org</owner>
+  <summary>
+    Modeset attempt result of an internal display. This is recorded after Chrome
+    attempted all the available modes and finally modeset the display. All the
+    previously attempted modes and refreshes, including the successful one will
+    be recorded.
+  </summary>
+</histogram>
+
+<histogram name="ConfigureDisplays.Internal.Modeset.RefreshRate" units="Hz"
+    expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@chromium.org</owner>
+  <summary>
+    Refresh rate of the mode for the display we're about to modeset. This is
+    recorded every time the internal display is powered on/off, or when an
+    external monitor is plugged in.
+  </summary>
+</histogram>
+
+<histogram name="ConfigureDisplays.Internal.Modeset.Resolution"
+    enum="DisplayResolution" expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@chromium.org</owner>
+  <summary>
+    DisplayResolution of the mode for the internal display we're about to
+    modeset. 0 means the display was powered off. This is recorded every time
+    the internal display is powered on/off, or when an external monitor is
+    plugged in.
+  </summary>
+</histogram>
+
+<histogram name="ConfigureDisplays.Modeset.MstExternalDisplaysCount"
+    units="count" expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@chromium.org</owner>
+  <summary>
+    Total number of external displays connected via MST and being configured.
+    This is recorded every time an external display is connected/disconnected,
+    or when the display mode of a screen is about to change.
+  </summary>
+</histogram>
+
+<histogram name="ConfigureDisplays.Modeset.MstExternalDisplaysPercentage"
+    units="%" expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@chromium.org</owner>
+  <summary>
+    Percentage of external displays connected via MST and being configured. This
+    is recorded every time an external display is connected/disconnected, or
+    when the display mode of a screen is about to change.
+  </summary>
+</histogram>
+
+<histogram name="ConfigureDisplays.Modeset.TotalExternalDisplaysCount"
+    units="count" expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@chromium.org</owner>
+  <summary>
+    Total number of external displays being configured. This is recorded every
+    time an external display is connected/disconnected, or when the display mode
+    of a screen is about to change.
+  </summary>
+</histogram>
+
+<histogram name="Display.External.BlockZeroSerialNumberType"
+    enum="BlockZeroSerialNumberType" expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@google.com</owner>
+  <summary>
+    The type of serial number retrieved from block zero of a display's EDID
+    during EDID parsing.
+  </summary>
+</histogram>
+
+<histogram name="Display.External.NumOfSerialNumbersProvided" units="count"
+    expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@google.com</owner>
+  <summary>
+    The number of serial numbers provided in an EDID (i.e. via block zero and/or
+    the serial number descriptor block). Values should be in the range of 0-2.
+  </summary>
+</histogram>
+
+<histogram name="Display.External.ParseEdidOptionals" enum="ParseEdidOptionals"
+    expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@google.com</owner>
+  <summary>
+    The availability (or lack thereof) of tracked optional fields during EDID
+    parsing of external.
+  </summary>
+</histogram>
+
+<histogram name="Display.GenerateDisplayId.CollisionDetection"
+    enum="BooleanDisplayIdCollision" expires_after="2022-09-01">
+  <obsolete>
+    Replaced by Display.MultipleDisplays.GenerateId.CollisionDetection in M95.
+  </obsolete>
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@google.com</owner>
+  <summary>
+    Whether or not displays produced identical display IDs due to insufficient
+    EDIDs. This may occur when identical displays (same make and model) lack
+    serial numbers in both the EDID's block zero or S/N descriptor block.
+    Recorded every time Chrome OS detects a change in display configuration and
+    attempts to get an updated list of available displays.
+  </summary>
+</histogram>
+
+<histogram name="Display.MultipleDisplays.GenerateId.CollisionDetection"
+    enum="BooleanDisplayIdCollision" expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@google.com</owner>
+  <summary>
+    Whether or not multiple connected displays produced identical display IDs
+    due to incomplete EDIDs. This may occur when identical displays (same make
+    and model) lack serial numbers in both the EDID's block zero or S/N
+    descriptor block. Recorded every time Chrome OS detects a change in display
+    configuration and attempts to get an updated list of available displays.
+  </summary>
+</histogram>
+
+<histogram name="Display.ParseEdidFailure" enum="ParseEdidFailure"
+    expires_after="2022-09-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>sashamcintosh@chromium.org</owner>
+  <owner>seanpaul@chromium.org</owner>
+  <owner>chromeos-gfx-display@google.com</owner>
+  <summary>
+    Type of failure that occurs during EDID parsing. Typically the failure is
+    caused by a mismatch between the EDID size and the expected offset of the
+    data component.
+  </summary>
+</histogram>
+
 <histogram name="GPU.AcceleratedSurfaceRefreshRate" units="hz"
     expires_after="M97">
   <owner>vmiura@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index 6935857..515e9c5 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -3427,147 +3427,6 @@
   </summary>
 </histogram>
 
-<histogram name="ConfigureDisplays.External.Modeset.AttemptSucceeded"
-    enum="BooleanSuccess" expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@chromium.org</owner>
-  <summary>
-    Modeset attempt result of an external display. Every time an external
-    display is connected/disconnected, or when the display mode of the external
-    screen is changed by the user, Chrome attempts to modeset the display. This
-    metric tracks the result of those attempts. Resolution and RefreshRate
-    metrics will be recorded for each attempt.
-  </summary>
-</histogram>
-
-<histogram name="ConfigureDisplays.External.Modeset.FinalStatus"
-    enum="BooleanSuccess" expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@chromium.org</owner>
-  <summary>
-    Modeset attempt result of an internal display. This is recorded after Chrome
-    attempted all the available modes and finally modeset the display. All the
-    previously attempted modes and refreshes, including the successful one will
-    be recorded.
-  </summary>
-</histogram>
-
-<histogram name="ConfigureDisplays.External.Modeset.RefreshRate" units="Hz"
-    expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@chromium.org</owner>
-  <summary>
-    Refresh rate of the mode for the display we're about to modeset. This is
-    recorded every time an external display is connected/disconnected, or when
-    the display mode of the external screen is about to change.
-  </summary>
-</histogram>
-
-<histogram name="ConfigureDisplays.External.Modeset.Resolution"
-    enum="DisplayResolution" expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@chromium.org</owner>
-  <summary>
-    DisplayResolution of the mode for the external display we're about to
-    modeset. 0 means the display was powered off. This is recorded every time an
-    external display is connected/disconnected, or when the display mode of the
-    external screen is about to change.
-  </summary>
-</histogram>
-
-<histogram name="ConfigureDisplays.Internal.Modeset.AttemptSucceeded"
-    enum="BooleanSuccess" expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@chromium.org</owner>
-  <summary>
-    Modeset attempt result of an internal display. Chrome might try additional
-    modes after a failed attempt. Every time an external display is
-    connected/disconnected, or when the display mode of the external screen is
-    changed by the user, Chrome attempts to modeset the display. This metric
-    tracks the result of those attempts. Resolution and RefreshRate metrics will
-    be recorded for each attempt.
-  </summary>
-</histogram>
-
-<histogram name="ConfigureDisplays.Internal.Modeset.FinalStatus"
-    enum="BooleanSuccess" expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@chromium.org</owner>
-  <summary>
-    Modeset attempt result of an internal display. This is recorded after Chrome
-    attempted all the available modes and finally modeset the display. All the
-    previously attempted modes and refreshes, including the successful one will
-    be recorded.
-  </summary>
-</histogram>
-
-<histogram name="ConfigureDisplays.Internal.Modeset.RefreshRate" units="Hz"
-    expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@chromium.org</owner>
-  <summary>
-    Refresh rate of the mode for the display we're about to modeset. This is
-    recorded every time the internal display is powered on/off, or when an
-    external monitor is plugged in.
-  </summary>
-</histogram>
-
-<histogram name="ConfigureDisplays.Internal.Modeset.Resolution"
-    enum="DisplayResolution" expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@chromium.org</owner>
-  <summary>
-    DisplayResolution of the mode for the internal display we're about to
-    modeset. 0 means the display was powered off. This is recorded every time
-    the internal display is powered on/off, or when an external monitor is
-    plugged in.
-  </summary>
-</histogram>
-
-<histogram name="ConfigureDisplays.Modeset.MstExternalDisplaysCount"
-    units="count" expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@chromium.org</owner>
-  <summary>
-    Total number of external displays connected via MST and being configured.
-    This is recorded every time an external display is connected/disconnected,
-    or when the display mode of a screen is about to change.
-  </summary>
-</histogram>
-
-<histogram name="ConfigureDisplays.Modeset.MstExternalDisplaysPercentage"
-    units="%" expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@chromium.org</owner>
-  <summary>
-    Percentage of external displays connected via MST and being configured. This
-    is recorded every time an external display is connected/disconnected, or
-    when the display mode of a screen is about to change.
-  </summary>
-</histogram>
-
-<histogram name="ConfigureDisplays.Modeset.TotalExternalDisplaysCount"
-    units="count" expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@chromium.org</owner>
-  <summary>
-    Total number of external displays being configured. This is recorded every
-    time an external display is connected/disconnected, or when the display mode
-    of a screen is about to change.
-  </summary>
-</histogram>
-
 <histogram name="Conflicts.ConfirmedBadModules" units="modules"
     expires_after="2018-08-30">
   <owner>chrisha@chromium.org</owner>
@@ -5012,83 +4871,6 @@
   </summary>
 </histogram>
 
-<histogram name="Display.External.BlockZeroSerialNumberType"
-    enum="BlockZeroSerialNumberType" expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@google.com</owner>
-  <summary>
-    The type of serial number retrieved from block zero of a display's EDID
-    during EDID parsing.
-  </summary>
-</histogram>
-
-<histogram name="Display.External.NumOfSerialNumbersProvided" units="count"
-    expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@google.com</owner>
-  <summary>
-    The number of serial numbers provided in an EDID (i.e. via block zero and/or
-    the serial number descriptor block). Values should be in the range of 0-2.
-  </summary>
-</histogram>
-
-<histogram name="Display.External.ParseEdidOptionals" enum="ParseEdidOptionals"
-    expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@google.com</owner>
-  <summary>
-    The availability (or lack thereof) of tracked optional fields during EDID
-    parsing of external.
-  </summary>
-</histogram>
-
-<histogram name="Display.GenerateDisplayId.CollisionDetection"
-    enum="BooleanDisplayIdCollision" expires_after="2022-09-01">
-  <obsolete>
-    Replaced by Display.MultipleDisplays.GenerateId.CollisionDetection in M95.
-  </obsolete>
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@google.com</owner>
-  <summary>
-    Whether or not displays produced identical display IDs due to insufficient
-    EDIDs. This may occur when identical displays (same make and model) lack
-    serial numbers in both the EDID's block zero or S/N descriptor block.
-    Recorded every time Chrome OS detects a change in display configuration and
-    attempts to get an updated list of available displays.
-  </summary>
-</histogram>
-
-<histogram name="Display.MultipleDisplays.GenerateId.CollisionDetection"
-    enum="BooleanDisplayIdCollision" expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@google.com</owner>
-  <summary>
-    Whether or not multiple connected displays produced identical display IDs
-    due to incomplete EDIDs. This may occur when identical displays (same make
-    and model) lack serial numbers in both the EDID's block zero or S/N
-    descriptor block. Recorded every time Chrome OS detects a change in display
-    configuration and attempts to get an updated list of available displays.
-  </summary>
-</histogram>
-
-<histogram name="Display.ParseEdidFailure" enum="ParseEdidFailure"
-    expires_after="2022-09-01">
-  <owner>gildekel@chromium.org</owner>
-  <owner>sashamcintosh@chromium.org</owner>
-  <owner>seanpaul@chromium.org</owner>
-  <owner>chromeos-gfx-display@google.com</owner>
-  <summary>
-    Type of failure that occurs during EDID parsing. Typically the failure is
-    caused by a mismatch between the EDID size and the expected offset of the
-    data component.
-  </summary>
-</histogram>
-
 <histogram name="DisplayManager.InternalDisplayZoomPercentage" units="%"
     expires_after="2022-06-15">
   <owner>zentaro@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml
index d69d571..74d18fed 100644
--- a/tools/metrics/histograms/metadata/password/histograms.xml
+++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -2273,6 +2273,8 @@
   <token key="Function">
     <variant name="AddLoginAsync" summary="add a login to"/>
     <variant name="GetAllLoginsAsync" summary="retrieve all logins from"/>
+    <variant name="GetAutofillableLoginsAsync"
+        summary="retrieve autofillable logins from"/>
     <variant name="RemoveLoginAsync" summary="remove a login from"/>
     <variant name="UpdateLoginAsync" summary="update a login in"/>
   </token>
@@ -2293,6 +2295,9 @@
         summary="AddLoginAsync() succeeded to add a login to"/>
     <variant name="GetAllLoginsAsync"
         summary="GetAllLoginsAsync() succeeded in retrieving all logins from"/>
+    <variant name="GetAutofillableLoginsAsync"
+        summary="GetAutofillableLoginsAsync() succeeded in retrieving
+                 autofillable logins from"/>
     <variant name="RemoveLoginAsync"
         summary="RemoveLoginAsync() succeeded in removing a login from"/>
     <variant name="UpdateLoginAsync"
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index a401c333..55c05b2 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -17,8 +17,8 @@
             "remote_path": "perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "linux": {
-            "hash": "de1e69173caee82057527f96d693b457363e05d3",
-            "remote_path": "perfetto_binaries/trace_processor_shell/linux/b9dad73621357b1698837d1abb64c020c5547172/trace_processor_shell"
+            "hash": "b40ba3b1569d3fb0229ae69c0996b6d7020c9689",
+            "remote_path": "perfetto_binaries/trace_processor_shell/linux/d6e08a1daedf6bfad1790f768f58c5a30757860a/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h
index 6efd5eaa..e79e303 100644
--- a/ui/accessibility/platform/ax_platform_node_win.h
+++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -17,7 +17,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/observer_list.h"
diff --git a/ui/accessibility/platform/ax_platform_relation_win.h b/ui/accessibility/platform/ax_platform_relation_win.h
index eb180e31..b5cc5c4 100644
--- a/ui/accessibility/platform/ax_platform_relation_win.h
+++ b/ui/accessibility/platform/ax_platform_relation_win.h
@@ -10,7 +10,6 @@
 #include <set>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/win/atl.h"
 #include "third_party/iaccessible2/ia2_api_all.h"
diff --git a/ui/aura/input_state_lookup_win.h b/ui/aura/input_state_lookup_win.h
index 88751c0..43bac07 100644
--- a/ui/aura/input_state_lookup_win.h
+++ b/ui/aura/input_state_lookup_win.h
@@ -5,7 +5,6 @@
 #ifndef UI_AURA_INPUT_STATE_LOOKUP_WIN_H_
 #define UI_AURA_INPUT_STATE_LOOKUP_WIN_H_
 
-#include "base/compiler_specific.h"
 #include "ui/aura/input_state_lookup.h"
 
 namespace aura {
diff --git a/ui/aura/test/aura_test_base.h b/ui/aura/test/aura_test_base.h
index 09d74ed..e5b7e6a1 100644
--- a/ui/aura/test/aura_test_base.h
+++ b/ui/aura/test/aura_test_base.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/test/task_environment.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ui/aura/test/test_cursor_client.h b/ui/aura/test/test_cursor_client.h
index f313fa3..00fbdf4 100644
--- a/ui/aura/test/test_cursor_client.h
+++ b/ui/aura/test/test_cursor_client.h
@@ -5,7 +5,6 @@
 #ifndef UI_AURA_TEST_TEST_CURSOR_CLIENT_H_
 #define UI_AURA_TEST_TEST_CURSOR_CLIENT_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/observer_list.h"
 #include "ui/aura/client/cursor_client.h"
diff --git a/ui/aura/test/test_focus_client.h b/ui/aura/test/test_focus_client.h
index d61c6bb..e1b1209 100644
--- a/ui/aura/test/test_focus_client.h
+++ b/ui/aura/test/test_focus_client.h
@@ -5,7 +5,6 @@
 #ifndef UI_AURA_TEST_TEST_FOCUS_CLIENT_H_
 #define UI_AURA_TEST_TEST_FOCUS_CLIENT_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/observer_list.h"
 #include "base/scoped_observation.h"
diff --git a/ui/aura/test/test_screen.h b/ui/aura/test/test_screen.h
index ff49c2c..61ffd9d6 100644
--- a/ui/aura/test/test_screen.h
+++ b/ui/aura/test/test_screen.h
@@ -5,7 +5,6 @@
 #ifndef UI_AURA_TEST_TEST_SCREEN_H_
 #define UI_AURA_TEST_TEST_SCREEN_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/aura/window_observer.h"
 #include "ui/display/display.h"
diff --git a/ui/aura/test/test_window_delegate.h b/ui/aura/test/test_window_delegate.h
index fe6f8d1..1073dc4 100644
--- a/ui/aura/test/test_window_delegate.h
+++ b/ui/aura/test/test_window_delegate.h
@@ -7,7 +7,6 @@
 
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/aura/window_delegate.h"
 #include "ui/events/keycodes/keyboard_codes.h"
diff --git a/ui/aura/test/test_window_parenting_client.h b/ui/aura/test/test_window_parenting_client.h
index 1d4673a..62700e8 100644
--- a/ui/aura/test/test_window_parenting_client.h
+++ b/ui/aura/test/test_window_parenting_client.h
@@ -5,7 +5,6 @@
 #ifndef UI_AURA_TEST_TEST_WINDOW_PARENTING_CLIENT_H_
 #define UI_AURA_TEST_TEST_WINDOW_PARENTING_CLIENT_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/aura/client/window_parenting_client.h"
 
diff --git a/ui/aura/test/test_windows.h b/ui/aura/test/test_windows.h
index af3434a..d2ad0dfc 100644
--- a/ui/aura/test/test_windows.h
+++ b/ui/aura/test/test_windows.h
@@ -7,7 +7,6 @@
 
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/aura/client/window_types.h"
 #include "ui/aura/test/aura_test_base.h"
diff --git a/ui/aura/window_delegate.h b/ui/aura/window_delegate.h
index 67fd3e78..b8abd78 100644
--- a/ui/aura/window_delegate.h
+++ b/ui/aura/window_delegate.h
@@ -5,7 +5,6 @@
 #ifndef UI_AURA_WINDOW_DELEGATE_H_
 #define UI_AURA_WINDOW_DELEGATE_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "ui/aura/aura_export.h"
 #include "ui/aura/window.h"
diff --git a/ui/aura/window_tree_host_platform.h b/ui/aura/window_tree_host_platform.h
index 89d42517..8a4bbc2 100644
--- a/ui/aura/window_tree_host_platform.h
+++ b/ui/aura/window_tree_host_platform.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "ui/aura/aura_export.h"
 #include "ui/aura/client/window_types.h"
 #include "ui/aura/window.h"
diff --git a/ui/base/base_window.h b/ui/base/base_window.h
index c469532..0d4fb25 100644
--- a/ui/base/base_window.h
+++ b/ui/base/base_window.h
@@ -5,7 +5,6 @@
 #ifndef UI_BASE_BASE_WINDOW_H_
 #define UI_BASE_BASE_WINDOW_H_
 
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "build/build_config.h"
 #include "ui/base/ui_base_types.h"
diff --git a/ui/base/clipboard/clipboard.h b/ui/base/clipboard/clipboard.h
index 43360dc4..7b0014e 100644
--- a/ui/base/clipboard/clipboard.h
+++ b/ui/base/clipboard/clipboard.h
@@ -14,7 +14,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/containers/flat_map.h"
 #include "base/process/process.h"
diff --git a/ui/base/ime/ash/fake_ime_keyboard.h b/ui/base/ime/ash/fake_ime_keyboard.h
index eee8a6f..c7d4063 100644
--- a/ui/base/ime/ash/fake_ime_keyboard.h
+++ b/ui/base/ime/ash/fake_ime_keyboard.h
@@ -9,7 +9,6 @@
 
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 
 namespace ash {
diff --git a/ui/base/ime/ash/fake_input_method_delegate.h b/ui/base/ime/ash/fake_input_method_delegate.h
index 5194305..79fee6c 100644
--- a/ui/base/ime/ash/fake_input_method_delegate.h
+++ b/ui/base/ime/ash/fake_input_method_delegate.h
@@ -8,7 +8,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "ui/base/ime/ash/input_method_delegate.h"
 
diff --git a/ui/base/ime/init/input_method_factory.h b/ui/base/ime/init/input_method_factory.h
index b172258..87c319f 100644
--- a/ui/base/ime/init/input_method_factory.h
+++ b/ui/base/ime/init/input_method_factory.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "ui/base/ime/init/input_method_initializer.h"
 #include "ui/gfx/native_widget_types.h"
diff --git a/ui/base/ime/win/input_method_win_base.h b/ui/base/ime/win/input_method_win_base.h
index a41c2cd..68fb3fbf 100644
--- a/ui/base/ime/win/input_method_win_base.h
+++ b/ui/base/ime/win/input_method_win_base.h
@@ -7,7 +7,6 @@
 
 #include <windows.h>
 
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "ui/base/ime/input_method_base.h"
 #include "ui/base/ime/win/imm32_manager.h"
diff --git a/ui/base/ime/win/input_method_win_imm32.h b/ui/base/ime/win/input_method_win_imm32.h
index 10c200c1..8c4500b 100644
--- a/ui/base/ime/win/input_method_win_imm32.h
+++ b/ui/base/ime/win/input_method_win_imm32.h
@@ -7,8 +7,6 @@
 
 #include <windows.h>
 
-
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "ui/base/ime/win/imm32_manager.h"
 #include "ui/base/ime/win/input_method_win_base.h"
diff --git a/ui/base/ime/win/mock_tsf_bridge.h b/ui/base/ime/win/mock_tsf_bridge.h
index 3e830ef3..c5e531bf 100644
--- a/ui/base/ime/win/mock_tsf_bridge.h
+++ b/ui/base/ime/win/mock_tsf_bridge.h
@@ -8,7 +8,6 @@
 #include <msctf.h>
 #include <wrl/client.h>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/base/ime/input_method_delegate.h"
 #include "ui/base/ime/text_input_type.h"
diff --git a/ui/base/ime/win/tsf_event_router.h b/ui/base/ime/win/tsf_event_router.h
index 20aa6b3..844f7c7 100644
--- a/ui/base/ime/win/tsf_event_router.h
+++ b/ui/base/ime/win/tsf_event_router.h
@@ -9,7 +9,6 @@
 #include <wrl/client.h>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/base/ime/text_input_type.h"
diff --git a/ui/base/ime/win/tsf_text_store.h b/ui/base/ime/win/tsf_text_store.h
index 1592300..968b72d 100644
--- a/ui/base/ime/win/tsf_text_store.h
+++ b/ui/base/ime/win/tsf_text_store.h
@@ -10,7 +10,6 @@
 #include <deque>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/base/ime/ime_text_span.h"
diff --git a/ui/base/models/button_menu_item_model.h b/ui/base/models/button_menu_item_model.h
index 6891f97..da600e8 100644
--- a/ui/base/models/button_menu_item_model.h
+++ b/ui/base/models/button_menu_item_model.h
@@ -8,7 +8,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/base/accelerators/accelerator.h"
diff --git a/ui/base/models/simple_menu_model.h b/ui/base/models/simple_menu_model.h
index 2a830f4..bd2ebaf9 100644
--- a/ui/base/models/simple_menu_model.h
+++ b/ui/base/models/simple_menu_model.h
@@ -8,7 +8,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
diff --git a/ui/base/resource/resource_data_dll_win.h b/ui/base/resource/resource_data_dll_win.h
index f75f8b7..e90b65a 100644
--- a/ui/base/resource/resource_data_dll_win.h
+++ b/ui/base/resource/resource_data_dll_win.h
@@ -8,7 +8,6 @@
 #include <windows.h>
 #include <stdint.h>
 
-#include "base/compiler_specific.h"
 #include "ui/base/resource/resource_handle.h"
 
 namespace ui {
diff --git a/ui/base/test/cocoa_helper.h b/ui/base/test/cocoa_helper.h
index 1bce440..a7665cd 100644
--- a/ui/base/test/cocoa_helper.h
+++ b/ui/base/test/cocoa_helper.h
@@ -9,7 +9,6 @@
 
 #import <Cocoa/Cocoa.h>
 
-#include "base/compiler_specific.h"
 #import "base/mac/scoped_nsautorelease_pool.h"
 #import "base/mac/scoped_nsobject.h"
 #import "base/strings/sys_string_conversions.h"
diff --git a/ui/base/user_activity/user_activity_detector.h b/ui/base/user_activity/user_activity_detector.h
index afae5ba..5c539b0 100644
--- a/ui/base/user_activity/user_activity_detector.h
+++ b/ui/base/user_activity/user_activity_detector.h
@@ -5,7 +5,6 @@
 #ifndef UI_BASE_USER_ACTIVITY_USER_ACTIVITY_DETECTOR_H_
 #define UI_BASE_USER_ACTIVITY_USER_ACTIVITY_DETECTOR_H_
 
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/observer_list.h"
 #include "base/time/time.h"
diff --git a/ui/base/win/accessibility_misc_utils.h b/ui/base/win/accessibility_misc_utils.h
index 3fba82b..04a555b 100644
--- a/ui/base/win/accessibility_misc_utils.h
+++ b/ui/base/win/accessibility_misc_utils.h
@@ -10,7 +10,6 @@
 
 #include <UIAutomationCore.h>
 
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 
 namespace base {
diff --git a/ui/base/win/atl_module.h b/ui/base/win/atl_module.h
index 645e8a8..71acaf6a 100644
--- a/ui/base/win/atl_module.h
+++ b/ui/base/win/atl_module.h
@@ -5,7 +5,6 @@
 #ifndef UI_BASE_WIN_ATL_MODULE_H_
 #define UI_BASE_WIN_ATL_MODULE_H_
 
-#include "base/compiler_specific.h"
 #include "base/win/atl.h"
 
 namespace ui {
diff --git a/ui/base/x/x11_desktop_window_move_client.h b/ui/base/x/x11_desktop_window_move_client.h
index dfd8b01..c17a2780 100644
--- a/ui/base/x/x11_desktop_window_move_client.h
+++ b/ui/base/x/x11_desktop_window_move_client.h
@@ -6,7 +6,6 @@
 #define UI_BASE_X_X11_DESKTOP_WINDOW_MOVE_CLIENT_H_
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "ui/base/x/x11_move_loop_delegate.h"
 #include "ui/base/x/x11_whole_screen_move_loop.h"
diff --git a/ui/base/x/x11_whole_screen_move_loop.h b/ui/base/x/x11_whole_screen_move_loop.h
index f7ea159..0ae70b2a 100644
--- a/ui/base/x/x11_whole_screen_move_loop.h
+++ b/ui/base/x/x11_whole_screen_move_loop.h
@@ -10,7 +10,6 @@
 #include <memory>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/memory/weak_ptr.h"
 #include "ui/base/x/x11_move_loop.h"
diff --git a/ui/chromeos/user_activity_power_manager_notifier.h b/ui/chromeos/user_activity_power_manager_notifier.h
index 9fa07c9..0e7bf68 100644
--- a/ui/chromeos/user_activity_power_manager_notifier.h
+++ b/ui/chromeos/user_activity_power_manager_notifier.h
@@ -5,7 +5,6 @@
 #ifndef UI_CHROMEOS_USER_ACTIVITY_POWER_MANAGER_NOTIFIER_H_
 #define UI_CHROMEOS_USER_ACTIVITY_POWER_MANAGER_NOTIFIER_H_
 
-#include "base/compiler_specific.h"
 #include "base/time/time.h"
 #include "chromeos/dbus/power/power_manager_client.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
diff --git a/ui/compositor/layer_animation_observer.h b/ui/compositor/layer_animation_observer.h
index c58f37a..edcdd16 100644
--- a/ui/compositor/layer_animation_observer.h
+++ b/ui/compositor/layer_animation_observer.h
@@ -8,7 +8,6 @@
 #include <map>
 #include <set>
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "ui/compositor/compositor_export.h"
 #include "ui/compositor/layer_animation_element.h"
diff --git a/ui/compositor/layer_owner.h b/ui/compositor/layer_owner.h
index 30defed..8f88765a 100644
--- a/ui/compositor/layer_owner.h
+++ b/ui/compositor/layer_owner.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/observer_list.h"
 #include "ui/compositor/compositor_export.h"
diff --git a/ui/compositor/test/test_layer_animation_delegate.h b/ui/compositor/test/test_layer_animation_delegate.h
index 95ace37a..294a2f5 100644
--- a/ui/compositor/test/test_layer_animation_delegate.h
+++ b/ui/compositor/test/test_layer_animation_delegate.h
@@ -5,7 +5,6 @@
 #ifndef UI_COMPOSITOR_TEST_TEST_LAYER_ANIMATION_DELEGATE_H_
 #define UI_COMPOSITOR_TEST_TEST_LAYER_ANIMATION_DELEGATE_H_
 
-#include "base/compiler_specific.h"
 #include "cc/layers/layer.h"
 #include "ui/compositor/layer_animation_delegate.h"
 #include "ui/compositor/layer_threaded_animation_delegate.h"
diff --git a/ui/compositor/test/test_layer_animation_observer.h b/ui/compositor/test/test_layer_animation_observer.h
index f0915c5..65c86e4 100644
--- a/ui/compositor/test/test_layer_animation_observer.h
+++ b/ui/compositor/test/test_layer_animation_observer.h
@@ -5,7 +5,6 @@
 #ifndef UI_COMPOSITOR_TEST_TEST_LAYER_ANIMATION_OBSERVER_H_
 #define UI_COMPOSITOR_TEST_TEST_LAYER_ANIMATION_OBSERVER_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/compositor/layer_animation_observer.h"
diff --git a/ui/display/display.h b/ui/display/display.h
index 3e90c61..e8574a1 100644
--- a/ui/display/display.h
+++ b/ui/display/display.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include "base/compiler_specific.h"
 #include "mojo/public/cpp/bindings/struct_traits.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/display/display_export.h"
diff --git a/ui/display/display_switches.h b/ui/display/display_switches.h
index 0c79d94..7c24ee2 100644
--- a/ui/display/display_switches.h
+++ b/ui/display/display_switches.h
@@ -5,7 +5,6 @@
 #ifndef UI_DISPLAY_DISPLAY_SWITCHES_H_
 #define UI_DISPLAY_DISPLAY_SWITCHES_H_
 
-#include "base/compiler_specific.h"
 #include "base/feature_list.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
diff --git a/ui/display/manager/display_manager.h b/ui/display/manager/display_manager.h
index 44cf185d..73936196 100644
--- a/ui/display/manager/display_manager.h
+++ b/ui/display/manager/display_manager.h
@@ -18,7 +18,6 @@
 
 #include "base/callback.h"
 #include "base/check_op.h"
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
diff --git a/ui/display/util/edid_parser.h b/ui/display/util/edid_parser.h
index b41072e..33544b1c 100644
--- a/ui/display/util/edid_parser.h
+++ b/ui/display/util/edid_parser.h
@@ -10,7 +10,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/containers/flat_set.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColorSpace.h"
diff --git a/ui/events/event.h b/ui/events/event.h
index 8bf692f..ae5e40a 100644
--- a/ui/events/event.h
+++ b/ui/events/event.h
@@ -10,7 +10,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/containers/flat_map.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
diff --git a/ui/events/event_switches.h b/ui/events/event_switches.h
index f23c159..6be5aa93 100644
--- a/ui/events/event_switches.h
+++ b/ui/events/event_switches.h
@@ -5,7 +5,6 @@
 #ifndef UI_EVENTS_EVENT_SWITCHES_H_
 #define UI_EVENTS_EVENT_SWITCHES_H_
 
-#include "base/compiler_specific.h"
 #include "build/build_config.h"
 #include "ui/events/events_base_export.h"
 
diff --git a/ui/events/event_target.h b/ui/events/event_target.h
index 2e5395f5..d18f029 100644
--- a/ui/events/event_target.h
+++ b/ui/events/event_target.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/events/event_handler.h"
 #include "ui/events/events_export.h"
diff --git a/ui/events/event_targeter.h b/ui/events/event_targeter.h
index fbe7a0e..4ef40cf 100644
--- a/ui/events/event_targeter.h
+++ b/ui/events/event_targeter.h
@@ -5,7 +5,6 @@
 #ifndef UI_EVENTS_EVENT_TARGETER_H_
 #define UI_EVENTS_EVENT_TARGETER_H_
 
-#include "base/compiler_specific.h"
 #include "ui/events/events_export.h"
 
 namespace ui {
diff --git a/ui/events/gestures/blink/web_gesture_curve_impl.h b/ui/events/gestures/blink/web_gesture_curve_impl.h
index be1d66ae..4c1f3fb3 100644
--- a/ui/events/gestures/blink/web_gesture_curve_impl.h
+++ b/ui/events/gestures/blink/web_gesture_curve_impl.h
@@ -9,7 +9,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "third_party/blink/public/common/input/web_gesture_device.h"
 #include "third_party/blink/public/platform/web_gesture_curve.h"
 #include "ui/gfx/geometry/point_f.h"
diff --git a/ui/events/null_event_targeter.h b/ui/events/null_event_targeter.h
index 28e94d00..424dc40 100644
--- a/ui/events/null_event_targeter.h
+++ b/ui/events/null_event_targeter.h
@@ -5,7 +5,6 @@
 #ifndef UI_EVENTS_NULL_EVENT_TARGETER_H_
 #define UI_EVENTS_NULL_EVENT_TARGETER_H_
 
-#include "base/compiler_specific.h"
 #include "ui/events/event_targeter.h"
 #include "ui/events/events_export.h"
 
diff --git a/ui/events/ozone/evdev/event_factory_evdev.h b/ui/events/ozone/evdev/event_factory_evdev.h
index eaed862..dade0d36 100644
--- a/ui/events/ozone/evdev/event_factory_evdev.h
+++ b/ui/events/ozone/evdev/event_factory_evdev.h
@@ -6,7 +6,6 @@
 #define UI_EVENTS_OZONE_EVDEV_EVENT_FACTORY_EVDEV_H_
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/memory/ref_counted.h"
 #include "base/task/task_runner.h"
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.h b/ui/events/ozone/evdev/input_device_factory_evdev.h
index b946085..0959112 100644
--- a/ui/events/ozone/evdev/input_device_factory_evdev.h
+++ b/ui/events/ozone/evdev/input_device_factory_evdev.h
@@ -11,7 +11,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/files/file_path.h"
 #include "base/memory/ref_counted.h"
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev_proxy.h b/ui/events/ozone/evdev/input_device_factory_evdev_proxy.h
index 35a9b8f..800accc 100644
--- a/ui/events/ozone/evdev/input_device_factory_evdev_proxy.h
+++ b/ui/events/ozone/evdev/input_device_factory_evdev_proxy.h
@@ -5,8 +5,6 @@
 #ifndef UI_EVENTS_OZONE_EVDEV_INPUT_DEVICE_FACTORY_EVDEV_PROXY_H_
 #define UI_EVENTS_OZONE_EVDEV_INPUT_DEVICE_FACTORY_EVDEV_PROXY_H_
 
-
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/files/file_path.h"
 #include "base/memory/ref_counted.h"
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.h b/ui/events/ozone/evdev/touch_event_converter_evdev.h
index 8aca439..97e5e34 100644
--- a/ui/events/ozone/evdev/touch_event_converter_evdev.h
+++ b/ui/events/ozone/evdev/touch_event_converter_evdev.h
@@ -18,7 +18,6 @@
 #define MT_TOOL_PALM 2
 #endif
 
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_file.h"
diff --git a/ui/events/test/test_event_handler.h b/ui/events/test/test_event_handler.h
index 426f3ef..46081d6 100644
--- a/ui/events/test/test_event_handler.h
+++ b/ui/events/test/test_event_handler.h
@@ -8,7 +8,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/events/event_handler.h"
 
diff --git a/ui/events/test/test_event_targeter.h b/ui/events/test/test_event_targeter.h
index 83bdb84..757f101 100644
--- a/ui/events/test/test_event_targeter.h
+++ b/ui/events/test/test_event_targeter.h
@@ -5,7 +5,6 @@
 #ifndef UI_EVENTS_TEST_TEST_EVENT_TARGETER_H_
 #define UI_EVENTS_TEST_TEST_EVENT_TARGETER_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/events/event_targeter.h"
 
diff --git a/ui/gfx/animation/animation.h b/ui/gfx/animation/animation.h
index 20afe6a..1937760a 100644
--- a/ui/gfx/animation/animation.h
+++ b/ui/gfx/animation/animation.h
@@ -5,7 +5,6 @@
 #ifndef UI_GFX_ANIMATION_ANIMATION_H_
 #define UI_GFX_ANIMATION_ANIMATION_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/time/time.h"
diff --git a/ui/gfx/color_analysis.h b/ui/gfx/color_analysis.h
index fdaa8f3..35c22589 100644
--- a/ui/gfx/color_analysis.h
+++ b/ui/gfx/color_analysis.h
@@ -8,7 +8,6 @@
 #include <stdint.h>
 
 #include "base/callback_forward.h"
-#include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/ref_counted_memory.h"
 #include "third_party/skia/include/core/SkColor.h"
diff --git a/ui/gfx/geometry/size.h b/ui/gfx/geometry/size.h
index a702339c..1590a7c 100644
--- a/ui/gfx/geometry/size.h
+++ b/ui/gfx/geometry/size.h
@@ -9,7 +9,6 @@
 #include <iosfwd>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/numerics/safe_math.h"
 #include "build/build_config.h"
 #include "ui/gfx/geometry/geometry_export.h"
diff --git a/ui/gfx/geometry/size_f.h b/ui/gfx/geometry/size_f.h
index b46835b2..5a056af 100644
--- a/ui/gfx/geometry/size_f.h
+++ b/ui/gfx/geometry/size_f.h
@@ -8,7 +8,6 @@
 #include <iosfwd>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "build/build_config.h"
 #include "ui/gfx/geometry/geometry_export.h"
diff --git a/ui/gfx/image/canvas_image_source.h b/ui/gfx/image/canvas_image_source.h
index f40eb9e9..a607f90 100644
--- a/ui/gfx/image/canvas_image_source.h
+++ b/ui/gfx/image/canvas_image_source.h
@@ -7,7 +7,6 @@
 
 #include <utility>
 
-#include "base/compiler_specific.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/gfx_export.h"
 #include "ui/gfx/image/image_skia.h"
diff --git a/ui/gfx/platform_font_mac.h b/ui/gfx/platform_font_mac.h
index 966e6a8..c007c5f48 100644
--- a/ui/gfx/platform_font_mac.h
+++ b/ui/gfx/platform_font_mac.h
@@ -5,7 +5,6 @@
 #ifndef UI_GFX_PLATFORM_FONT_MAC_H_
 #define UI_GFX_PLATFORM_FONT_MAC_H_
 
-#include "base/compiler_specific.h"
 #include "base/mac/scoped_nsobject.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/font_render_params.h"
diff --git a/ui/gfx/platform_font_skia.h b/ui/gfx/platform_font_skia.h
index 4265648..e9a878f3 100644
--- a/ui/gfx/platform_font_skia.h
+++ b/ui/gfx/platform_font_skia.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "build/build_config.h"
 #include "third_party/skia/include/core/SkTypeface.h"
 #include "ui/gfx/font_render_params.h"
diff --git a/ui/gl/gl_context_egl.h b/ui/gl/gl_context_egl.h
index de64e1ac..142d179a8 100644
--- a/ui/gl/gl_context_egl.h
+++ b/ui/gl/gl_context_egl.h
@@ -7,7 +7,6 @@
 
 #include <map>
 
-#include "base/compiler_specific.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_export.h"
 
diff --git a/ui/gl/gl_context_glx.h b/ui/gl/gl_context_glx.h
index 26167526..0f3a6a3 100644
--- a/ui/gl/gl_context_glx.h
+++ b/ui/gl/gl_context_glx.h
@@ -5,7 +5,6 @@
 #ifndef UI_GL_GL_CONTEXT_GLX_H_
 #define UI_GL_GL_CONTEXT_GLX_H_
 
-#include "base/compiler_specific.h"
 #include "ui/gfx/x/connection.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_export.h"
diff --git a/ui/gl/gl_egl_api_implementation.h b/ui/gl/gl_egl_api_implementation.h
index 6e80f661..e11d0dd 100644
--- a/ui/gl/gl_egl_api_implementation.h
+++ b/ui/gl/gl_egl_api_implementation.h
@@ -9,7 +9,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_export.h"
diff --git a/ui/gl/gl_gl_api_implementation.h b/ui/gl/gl_gl_api_implementation.h
index 147cde11..8c89e56 100644
--- a/ui/gl/gl_gl_api_implementation.h
+++ b/ui/gl/gl_gl_api_implementation.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_export.h"
diff --git a/ui/gl/gl_glx_api_implementation.h b/ui/gl/gl_glx_api_implementation.h
index aa8ca0e..97a21ee6 100644
--- a/ui/gl/gl_glx_api_implementation.h
+++ b/ui/gl/gl_glx_api_implementation.h
@@ -8,7 +8,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "gl_bindings.h"
 #include "ui/gl/gl_export.h"
 
diff --git a/ui/gl/gl_surface_egl.h b/ui/gl/gl_surface_egl.h
index 3aac23c..5493db7 100644
--- a/ui/gl/gl_surface_egl.h
+++ b/ui/gl/gl_surface_egl.h
@@ -18,7 +18,6 @@
 #include <vector>
 
 #include "base/command_line.h"
-#include "base/compiler_specific.h"
 #include "base/containers/queue.h"
 #include "base/time/time.h"
 #include "ui/gfx/geometry/size.h"
diff --git a/ui/gl/gl_surface_glx.h b/ui/gl/gl_surface_glx.h
index 4ae78480..f424fa1 100644
--- a/ui/gl/gl_surface_glx.h
+++ b/ui/gl/gl_surface_glx.h
@@ -10,7 +10,6 @@
 #include <memory>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/gfx/x/event.h"
diff --git a/ui/gl/scoped_make_current.h b/ui/gl/scoped_make_current.h
index 4f9004e..3b92ce7 100644
--- a/ui/gl/scoped_make_current.h
+++ b/ui/gl/scoped_make_current.h
@@ -5,7 +5,6 @@
 #ifndef UI_GL_SCOPED_MAKE_CURRENT_H_
 #define UI_GL_SCOPED_MAKE_CURRENT_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "ui/gl/gl_export.h"
 
diff --git a/ui/gtk/gtk_ui.h b/ui/gtk/gtk_ui.h
index 13e17e9c..23b5e47 100644
--- a/ui/gtk/gtk_ui.h
+++ b/ui/gtk/gtk_ui.h
@@ -9,7 +9,6 @@
 #include <memory>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/observer_list.h"
 #include "ui/base/glib/glib_signal.h"
 #include "ui/gfx/color_utils.h"
diff --git a/ui/gtk/printing/print_dialog_gtk.h b/ui/gtk/printing/print_dialog_gtk.h
index 9dd5e12..7ede1593 100644
--- a/ui/gtk/printing/print_dialog_gtk.h
+++ b/ui/gtk/printing/print_dialog_gtk.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/memory/ref_counted_delete_on_sequence.h"
 #include "printing/print_dialog_gtk_interface.h"
diff --git a/ui/gtk/select_file_dialog_impl.h b/ui/gtk/select_file_dialog_impl.h
index 6e8e58f9..4b4176e 100644
--- a/ui/gtk/select_file_dialog_impl.h
+++ b/ui/gtk/select_file_dialog_impl.h
@@ -12,7 +12,6 @@
 #include <memory>
 #include <set>
 
-#include "base/compiler_specific.h"
 #include "base/nix/xdg_util.h"
 #include "ui/aura/window.h"
 #include "ui/shell_dialogs/select_file_dialog.h"
diff --git a/ui/native_theme/native_theme_base.h b/ui/native_theme/native_theme_base.h
index 8e0e899a..5b736fc 100644
--- a/ui/native_theme/native_theme_base.h
+++ b/ui/native_theme/native_theme_base.h
@@ -5,8 +5,6 @@
 #ifndef UI_NATIVE_THEME_NATIVE_THEME_BASE_H_
 #define UI_NATIVE_THEME_NATIVE_THEME_BASE_H_
 
-
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "cc/paint/paint_flags.h"
 #include "ui/native_theme/native_theme.h"
diff --git a/ui/native_theme/native_theme_win.h b/ui/native_theme/native_theme_win.h
index 7008488..054c797 100644
--- a/ui/native_theme/native_theme_win.h
+++ b/ui/native_theme/native_theme_win.h
@@ -12,7 +12,6 @@
 // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp
 #include <windows.h>
 
-#include "base/compiler_specific.h"
 #include "base/no_destructor.h"
 #include "base/win/registry.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/ui/ozone/public/ozone_switches.h b/ui/ozone/public/ozone_switches.h
index dc215f6..890ad63 100644
--- a/ui/ozone/public/ozone_switches.h
+++ b/ui/ozone/public/ozone_switches.h
@@ -5,7 +5,6 @@
 #ifndef UI_OZONE_PUBLIC_OZONE_SWITCHES_H_
 #define UI_OZONE_PUBLIC_OZONE_SWITCHES_H_
 
-#include "base/compiler_specific.h"
 #include "base/component_export.h"
 
 // TODO(rjkroege): Specify this at the time of ::InitializeUI to avoid the habit
diff --git a/ui/platform_window/stub/stub_window.h b/ui/platform_window/stub/stub_window.h
index 48889c6..6ed9f686 100644
--- a/ui/platform_window/stub/stub_window.h
+++ b/ui/platform_window/stub/stub_window.h
@@ -5,7 +5,6 @@
 #ifndef UI_PLATFORM_WINDOW_STUB_STUB_WINDOW_H_
 #define UI_PLATFORM_WINDOW_STUB_STUB_WINDOW_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/platform_window/platform_window.h"
diff --git a/ui/platform_window/win/win_window.h b/ui/platform_window/win/win_window.h
index f2562cb..43dc9d7 100644
--- a/ui/platform_window/win/win_window.h
+++ b/ui/platform_window/win/win_window.h
@@ -5,7 +5,6 @@
 #ifndef UI_PLATFORM_WINDOW_WIN_WIN_WINDOW_H_
 #define UI_PLATFORM_WINDOW_WIN_WIN_WINDOW_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
diff --git a/ui/snapshot/screenshot_grabber.h b/ui/snapshot/screenshot_grabber.h
index c42213a..6131e5c 100644
--- a/ui/snapshot/screenshot_grabber.h
+++ b/ui/snapshot/screenshot_grabber.h
@@ -9,7 +9,6 @@
 #include <string>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
diff --git a/ui/views/accessibility/ax_aura_obj_wrapper.h b/ui/views/accessibility/ax_aura_obj_wrapper.h
index fd1cae6ee..602e704 100644
--- a/ui/views/accessibility/ax_aura_obj_wrapper.h
+++ b/ui/views/accessibility/ax_aura_obj_wrapper.h
@@ -10,7 +10,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/gfx/geometry/point.h"
diff --git a/ui/views/animation/bounds_animator.h b/ui/views/animation/bounds_animator.h
index 86a412d..87364f5 100644
--- a/ui/views/animation/bounds_animator.h
+++ b/ui/views/animation/bounds_animator.h
@@ -8,7 +8,6 @@
 #include <map>
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/observer_list.h"
diff --git a/ui/views/bubble/bubble_frame_view.h b/ui/views/bubble/bubble_frame_view.h
index c682c17..f1a77ab 100644
--- a/ui/views/bubble/bubble_frame_view.h
+++ b/ui/views/bubble/bubble_frame_view.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/base/metadata/metadata_header_macros.h"
diff --git a/ui/views/bubble/info_bubble.h b/ui/views/bubble/info_bubble.h
index 1d9e460..992d9df 100644
--- a/ui/views/bubble/info_bubble.h
+++ b/ui/views/bubble/info_bubble.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/views/bubble/bubble_dialog_delegate_view.h"
 
diff --git a/ui/views/color_chooser/color_chooser_view.h b/ui/views/color_chooser/color_chooser_view.h
index efe3fc2b..1858d938 100644
--- a/ui/views/color_chooser/color_chooser_view.h
+++ b/ui/views/color_chooser/color_chooser_view.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/core/SkScalar.h"
diff --git a/ui/views/controls/button/label_button.h b/ui/views/controls/button/label_button.h
index 1faf04de..75d1292c 100644
--- a/ui/views/controls/button/label_button.h
+++ b/ui/views/controls/button/label_button.h
@@ -9,7 +9,6 @@
 #include <memory>
 
 #include "base/bind.h"
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/ui/views/controls/button/label_button_border.h b/ui/views/controls/button/label_button_border.h
index 54c4c39..8866d4a 100644
--- a/ui/views/controls/button/label_button_border.h
+++ b/ui/views/controls/button/label_button_border.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "ui/gfx/geometry/insets.h"
 #include "ui/views/border.h"
 #include "ui/views/controls/button/button.h"
diff --git a/ui/views/controls/focusable_border.h b/ui/views/controls/focusable_border.h
index bf5ffed..eeb3876 100644
--- a/ui/views/controls/focusable_border.h
+++ b/ui/views/controls/focusable_border.h
@@ -5,7 +5,6 @@
 #ifndef UI_VIEWS_CONTROLS_FOCUSABLE_BORDER_H_
 #define UI_VIEWS_CONTROLS_FOCUSABLE_BORDER_H_
 
-#include "base/compiler_specific.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/color/color_id.h"
 #include "ui/views/border.h"
diff --git a/ui/views/controls/menu/menu_controller.h b/ui/views/controls/menu/menu_controller.h
index b8a6bff..6147d0fb3 100644
--- a/ui/views/controls/menu/menu_controller.h
+++ b/ui/views/controls/menu/menu_controller.h
@@ -13,7 +13,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/containers/flat_set.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
diff --git a/ui/views/controls/menu/menu_host.h b/ui/views/controls/menu/menu_host.h
index 723452d..4776504 100644
--- a/ui/views/controls/menu/menu_host.h
+++ b/ui/views/controls/menu/menu_host.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "build/build_config.h"
 #include "ui/base/ui_base_types.h"
diff --git a/ui/views/controls/menu/menu_runner.h b/ui/views/controls/menu/menu_runner.h
index 9bfac77..d8d7d59 100644
--- a/ui/views/controls/menu/menu_runner.h
+++ b/ui/views/controls/menu/menu_runner.h
@@ -10,7 +10,6 @@
 #include <memory>
 
 #include "base/callback.h"
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/gfx/native_widget_types.h"
diff --git a/ui/views/controls/menu/menu_runner_impl.h b/ui/views/controls/menu/menu_runner_impl.h
index b287b185..c99ef21 100644
--- a/ui/views/controls/menu/menu_runner_impl.h
+++ b/ui/views/controls/menu/menu_runner_impl.h
@@ -10,7 +10,6 @@
 #include <memory>
 #include <set>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
diff --git a/ui/views/controls/menu/menu_separator.h b/ui/views/controls/menu/menu_separator.h
index e4b21300..7dfc90a 100644
--- a/ui/views/controls/menu/menu_separator.h
+++ b/ui/views/controls/menu/menu_separator.h
@@ -5,7 +5,6 @@
 #ifndef UI_VIEWS_CONTROLS_MENU_MENU_SEPARATOR_H_
 #define UI_VIEWS_CONTROLS_MENU_MENU_SEPARATOR_H_
 
-#include "base/compiler_specific.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/base/models/menu_separator_types.h"
 #include "ui/views/view.h"
diff --git a/ui/views/controls/menu/submenu_view.h b/ui/views/controls/menu/submenu_view.h
index fcecb8a..0474f8e 100644
--- a/ui/views/controls/menu/submenu_view.h
+++ b/ui/views/controls/menu/submenu_view.h
@@ -10,7 +10,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/views/animation/scroll_animator.h"
 #include "ui/views/controls/menu/menu_delegate.h"
diff --git a/ui/views/controls/native/native_view_host_aura.h b/ui/views/controls/native/native_view_host_aura.h
index bc288d5..e486a40 100644
--- a/ui/views/controls/native/native_view_host_aura.h
+++ b/ui/views/controls/native/native_view_host_aura.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/aura/window_observer.h"
 #include "ui/compositor/layer_owner.h"
diff --git a/ui/views/controls/progress_bar.h b/ui/views/controls/progress_bar.h
index 7e344e3..05b5b70 100644
--- a/ui/views/controls/progress_bar.h
+++ b/ui/views/controls/progress_bar.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/animation/animation_delegate.h"
 #include "ui/views/view.h"
diff --git a/ui/views/controls/scroll_view.h b/ui/views/controls/scroll_view.h
index 75a23eb..c6ba19918 100644
--- a/ui/views/controls/scroll_view.h
+++ b/ui/views/controls/scroll_view.h
@@ -9,7 +9,6 @@
 #include <utility>
 
 #include "base/callback_list.h"
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/ui/views/controls/scrollbar/scroll_bar.h b/ui/views/controls/scrollbar/scroll_bar.h
index 9943325..1d98e18 100644
--- a/ui/views/controls/scrollbar/scroll_bar.h
+++ b/ui/views/controls/scrollbar/scroll_bar.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/ui/views/controls/scrollbar/scroll_bar_views.h b/ui/views/controls/scrollbar/scroll_bar_views.h
index f799b6b..96cfa28 100644
--- a/ui/views/controls/scrollbar/scroll_bar_views.h
+++ b/ui/views/controls/scrollbar/scroll_bar_views.h
@@ -5,7 +5,6 @@
 #ifndef UI_VIEWS_CONTROLS_SCROLLBAR_SCROLL_BAR_VIEWS_H_
 #define UI_VIEWS_CONTROLS_SCROLLBAR_SCROLL_BAR_VIEWS_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/views/controls/button/button.h"
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.h b/ui/views/controls/tabbed_pane/tabbed_pane.h
index a00a61ef..cc9622c 100644
--- a/ui/views/controls/tabbed_pane/tabbed_pane.h
+++ b/ui/views/controls/tabbed_pane/tabbed_pane.h
@@ -9,7 +9,6 @@
 #include <string>
 #include <utility>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/gfx/animation/animation_delegate.h"
 #include "ui/gfx/animation/linear_animation.h"
diff --git a/ui/views/controls/table/test_table_model.h b/ui/views/controls/table/test_table_model.h
index c71acb7..6144898 100644
--- a/ui/views/controls/table/test_table_model.h
+++ b/ui/views/controls/table/test_table_model.h
@@ -5,7 +5,6 @@
 #ifndef UI_VIEWS_CONTROLS_TABLE_TEST_TABLE_MODEL_H_
 #define UI_VIEWS_CONTROLS_TABLE_TEST_TABLE_MODEL_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/base/models/table_model.h"
 
diff --git a/ui/views/controls/throbber.h b/ui/views/controls/throbber.h
index d6ca2de..4451e1db 100644
--- a/ui/views/controls/throbber.h
+++ b/ui/views/controls/throbber.h
@@ -5,7 +5,6 @@
 #ifndef UI_VIEWS_CONTROLS_THROBBER_H_
 #define UI_VIEWS_CONTROLS_THROBBER_H_
 
-#include "base/compiler_specific.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "ui/views/view.h"
diff --git a/ui/views/controls/tree/tree_view.h b/ui/views/controls/tree/tree_view.h
index e1a0474..fbb83931 100644
--- a/ui/views/controls/tree/tree_view.h
+++ b/ui/views/controls/tree/tree_view.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/base/models/tree_node_model.h"
 #include "ui/gfx/font_list.h"
diff --git a/ui/views/corewm/tooltip_win.h b/ui/views/corewm/tooltip_win.h
index 7d2143b3..0ee6fae 100644
--- a/ui/views/corewm/tooltip_win.h
+++ b/ui/views/corewm/tooltip_win.h
@@ -11,7 +11,6 @@
 
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/win/scoped_gdi_object.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/views/corewm/tooltip.h"
diff --git a/ui/views/focus/external_focus_tracker.h b/ui/views/focus/external_focus_tracker.h
index 337345a2a1..1a60633 100644
--- a/ui/views/focus/external_focus_tracker.h
+++ b/ui/views/focus/external_focus_tracker.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/views/focus/focus_manager.h"
 
diff --git a/ui/views/layout/fill_layout.h b/ui/views/layout/fill_layout.h
index 31bc5a8..8929363 100644
--- a/ui/views/layout/fill_layout.h
+++ b/ui/views/layout/fill_layout.h
@@ -5,7 +5,6 @@
 #ifndef UI_VIEWS_LAYOUT_FILL_LAYOUT_H_
 #define UI_VIEWS_LAYOUT_FILL_LAYOUT_H_
 
-#include "base/compiler_specific.h"
 #include "ui/views/layout/layout_manager_base.h"
 #include "ui/views/view.h"
 
diff --git a/ui/views/layout/flex_layout.h b/ui/views/layout/flex_layout.h
index 34a7582..a4b5d52 100644
--- a/ui/views/layout/flex_layout.h
+++ b/ui/views/layout/flex_layout.h
@@ -12,7 +12,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/class_property.h"
diff --git a/ui/views/painter.h b/ui/views/painter.h
index 60aa3798..99d06e8 100644
--- a/ui/views/painter.h
+++ b/ui/views/painter.h
@@ -9,7 +9,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "third_party/skia/include/core/SkBlendMode.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/nine_image_painter_factory.h"
diff --git a/ui/views/test/capture_tracking_view.h b/ui/views/test/capture_tracking_view.h
index 2be57e6b..d79fa5f 100644
--- a/ui/views/test/capture_tracking_view.h
+++ b/ui/views/test/capture_tracking_view.h
@@ -5,7 +5,6 @@
 #ifndef UI_VIEWS_TEST_CAPTURE_TRACKING_VIEW_H_
 #define UI_VIEWS_TEST_CAPTURE_TRACKING_VIEW_H_
 
-#include "base/compiler_specific.h"
 #include "ui/views/view.h"
 
 namespace views {
diff --git a/ui/views/test/test_platform_native_widget.h b/ui/views/test/test_platform_native_widget.h
index a9be8e45f..ed0aca8 100644
--- a/ui/views/test/test_platform_native_widget.h
+++ b/ui/views/test/test_platform_native_widget.h
@@ -5,7 +5,6 @@
 #ifndef UI_VIEWS_TEST_TEST_PLATFORM_NATIVE_WIDGET_H_
 #define UI_VIEWS_TEST_TEST_PLATFORM_NATIVE_WIDGET_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/views/view.h"
 
diff --git a/ui/views/test/test_widget_observer.h b/ui/views/test/test_widget_observer.h
index 13eb8a4..1b41bd4 100644
--- a/ui/views/test/test_widget_observer.h
+++ b/ui/views/test/test_widget_observer.h
@@ -7,7 +7,6 @@
 
 #include <stddef.h>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/views/widget/widget_observer.h"
 
diff --git a/ui/views/test/widget_test.h b/ui/views/test/widget_test.h
index ec150bc5..24b792f 100644
--- a/ui/views/test/widget_test.h
+++ b/ui/views/test/widget_test.h
@@ -9,7 +9,6 @@
 #include <string>
 #include <utility>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
 #include "base/scoped_observation.h"
diff --git a/ui/views/widget/desktop_aura/desktop_capture_client.h b/ui/views/widget/desktop_aura/desktop_capture_client.h
index 750a873..bf65608a 100644
--- a/ui/views/widget/desktop_aura/desktop_capture_client.h
+++ b/ui/views/widget/desktop_aura/desktop_capture_client.h
@@ -7,7 +7,6 @@
 
 #include <set>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/observer_list.h"
 #include "ui/aura/client/capture_client.h"
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h b/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h
index 359cadf..32e61e5 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h
@@ -9,7 +9,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
diff --git a/ui/views/widget/desktop_aura/desktop_event_client.h b/ui/views/widget/desktop_aura/desktop_event_client.h
index 60af8b1..0892e9a 100644
--- a/ui/views/widget/desktop_aura/desktop_event_client.h
+++ b/ui/views/widget/desktop_aura/desktop_event_client.h
@@ -5,7 +5,6 @@
 #ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_EVENT_CLIENT_H_
 #define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_EVENT_CLIENT_H_
 
-#include "base/compiler_specific.h"
 #include "ui/aura/client/event_client.h"
 #include "ui/views/views_export.h"
 
diff --git a/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h b/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
index 0ce59421..7f90e0d2 100644
--- a/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
+++ b/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <set>
 
-#include "base/compiler_specific.h"
 #include "ui/aura/cursor/cursor_loader.h"
 #include "ui/views/views_export.h"
 #include "ui/wm/core/native_cursor_manager.h"
diff --git a/ui/views/widget/desktop_aura/window_event_filter_linux.h b/ui/views/widget/desktop_aura/window_event_filter_linux.h
index 8fe1af4..08fc96d 100644
--- a/ui/views/widget/desktop_aura/window_event_filter_linux.h
+++ b/ui/views/widget/desktop_aura/window_event_filter_linux.h
@@ -5,7 +5,6 @@
 #ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_WINDOW_EVENT_FILTER_LINUX_H_
 #define UI_VIEWS_WIDGET_DESKTOP_AURA_WINDOW_EVENT_FILTER_LINUX_H_
 
-#include "base/compiler_specific.h"
 #include "ui/base/hit_test.h"
 #include "ui/views/views_export.h"
 
diff --git a/ui/views/widget/tooltip_manager_aura.h b/ui/views/widget/tooltip_manager_aura.h
index 93b358a..a30500a5 100644
--- a/ui/views/widget/tooltip_manager_aura.h
+++ b/ui/views/widget/tooltip_manager_aura.h
@@ -7,7 +7,6 @@
 
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/views/views_export.h"
diff --git a/ui/views/widget/widget_deletion_observer.h b/ui/views/widget/widget_deletion_observer.h
index aa285a7..87731a2e 100644
--- a/ui/views/widget/widget_deletion_observer.h
+++ b/ui/views/widget/widget_deletion_observer.h
@@ -5,7 +5,6 @@
 #ifndef UI_VIEWS_WIDGET_WIDGET_DELETION_OBSERVER_H_
 #define UI_VIEWS_WIDGET_WIDGET_DELETION_OBSERVER_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/views/views_export.h"
 #include "ui/views/widget/widget_observer.h"
diff --git a/ui/views/widget/window_reorderer.h b/ui/views/widget/window_reorderer.h
index 91186d0..2c7f234 100644
--- a/ui/views/widget/window_reorderer.h
+++ b/ui/views/widget/window_reorderer.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/aura/window_observer.h"
 
diff --git a/ui/views/win/hwnd_message_handler.h b/ui/views/win/hwnd_message_handler.h
index e73604b..ae1efc5c 100644
--- a/ui/views/win/hwnd_message_handler.h
+++ b/ui/views/win/hwnd_message_handler.h
@@ -14,7 +14,6 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/lazy_instance.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
diff --git a/ui/views/window/custom_frame_view.h b/ui/views/window/custom_frame_view.h
index 8fce763..3e8e7df6 100644
--- a/ui/views/window/custom_frame_view.h
+++ b/ui/views/window/custom_frame_view.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/views/controls/button/button.h"
diff --git a/ui/web_dialogs/test/test_web_contents_handler.h b/ui/web_dialogs/test/test_web_contents_handler.h
index bfeaeff..b8df928 100644
--- a/ui/web_dialogs/test/test_web_contents_handler.h
+++ b/ui/web_dialogs/test/test_web_contents_handler.h
@@ -5,7 +5,6 @@
 #ifndef UI_WEB_DIALOGS_TEST_TEST_WEB_CONTENTS_HANDLER_H_
 #define UI_WEB_DIALOGS_TEST_TEST_WEB_CONTENTS_HANDLER_H_
 
-#include "base/compiler_specific.h"
 #include "ui/web_dialogs/web_dialog_web_contents_delegate.h"
 
 namespace ui {
diff --git a/ui/web_dialogs/test/test_web_dialog_delegate.h b/ui/web_dialogs/test/test_web_dialog_delegate.h
index 97190717..357766ed 100644
--- a/ui/web_dialogs/test/test_web_dialog_delegate.h
+++ b/ui/web_dialogs/test/test_web_dialog_delegate.h
@@ -7,7 +7,6 @@
 
 #include <string>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/web_dialogs/web_dialog_delegate.h"
diff --git a/ui/web_dialogs/web_dialog_ui.h b/ui/web_dialogs/web_dialog_ui.h
index c731bd6..78f30d7b 100644
--- a/ui/web_dialogs/web_dialog_ui.h
+++ b/ui/web_dialogs/web_dialog_ui.h
@@ -5,7 +5,6 @@
 #ifndef UI_WEB_DIALOGS_WEB_DIALOG_UI_H_
 #define UI_WEB_DIALOGS_WEB_DIALOG_UI_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "content/public/browser/web_contents_delegate.h"
 #include "content/public/browser/web_ui_controller.h"
diff --git a/ui/wm/core/base_focus_rules.h b/ui/wm/core/base_focus_rules.h
index 266526b..79aba7f 100644
--- a/ui/wm/core/base_focus_rules.h
+++ b/ui/wm/core/base_focus_rules.h
@@ -5,7 +5,6 @@
 #ifndef UI_WM_CORE_BASE_FOCUS_RULES_H_
 #define UI_WM_CORE_BASE_FOCUS_RULES_H_
 
-#include "base/compiler_specific.h"
 #include "ui/wm/core/focus_rules.h"
 
 namespace wm {
diff --git a/ui/wm/core/compound_event_filter.h b/ui/wm/core/compound_event_filter.h
index 30e41690..b0f127e4 100644
--- a/ui/wm/core/compound_event_filter.h
+++ b/ui/wm/core/compound_event_filter.h
@@ -5,7 +5,6 @@
 #ifndef UI_WM_CORE_COMPOUND_EVENT_FILTER_H_
 #define UI_WM_CORE_COMPOUND_EVENT_FILTER_H_
 
-#include "base/compiler_specific.h"
 #include "base/observer_list.h"
 #include "base/strings/string_piece.h"
 #include "ui/events/event.h"
diff --git a/ui/wm/core/cursor_manager.h b/ui/wm/core/cursor_manager.h
index 07f96dee..7e65b6c 100644
--- a/ui/wm/core/cursor_manager.h
+++ b/ui/wm/core/cursor_manager.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/observer_list.h"
 #include "ui/aura/client/cursor_client.h"
 #include "ui/display/display.h"
diff --git a/ui/wm/core/default_activation_client.h b/ui/wm/core/default_activation_client.h
index ca85a69..3575e2cb 100644
--- a/ui/wm/core/default_activation_client.h
+++ b/ui/wm/core/default_activation_client.h
@@ -7,7 +7,6 @@
 
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/observer_list.h"
 #include "ui/aura/window_observer.h"
diff --git a/ui/wm/core/focus_controller.h b/ui/wm/core/focus_controller.h
index eaf0f76..1caeba4 100644
--- a/ui/wm/core/focus_controller.h
+++ b/ui/wm/core/focus_controller.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/observer_list.h"
 #include "base/scoped_multi_source_observation.h"
diff --git a/ui/wm/core/shadow_controller.h b/ui/wm/core/shadow_controller.h
index b8b06c69..7584634a 100644
--- a/ui/wm/core/shadow_controller.h
+++ b/ui/wm/core/shadow_controller.h
@@ -7,7 +7,6 @@
 
 #include <map>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "ui/wm/core/wm_core_export.h"
diff --git a/ui/wm/core/visibility_controller.h b/ui/wm/core/visibility_controller.h
index 2ffc722..96efbf7 100644
--- a/ui/wm/core/visibility_controller.h
+++ b/ui/wm/core/visibility_controller.h
@@ -5,7 +5,6 @@
 #ifndef UI_WM_CORE_VISIBILITY_CONTROLLER_H_
 #define UI_WM_CORE_VISIBILITY_CONTROLLER_H_
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/aura/client/visibility_client.h"
 #include "ui/wm/core/wm_core_export.h"
diff --git a/ui/wm/core/window_modality_controller.h b/ui/wm/core/window_modality_controller.h
index 880cc3b0..2d1c724 100644
--- a/ui/wm/core/window_modality_controller.h
+++ b/ui/wm/core/window_modality_controller.h
@@ -7,7 +7,6 @@
 
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "base/strings/string_piece.h"
 #include "ui/aura/env_observer.h"
diff --git a/ui/wm/core/window_util.h b/ui/wm/core/window_util.h
index 6f10c5c..6c8bd30 100644
--- a/ui/wm/core/window_util.h
+++ b/ui/wm/core/window_util.h
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/callback_forward.h"
-#include "base/compiler_specific.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/wm/core/wm_core_export.h"
 
diff --git a/ui/wm/public/animation_host.h b/ui/wm/public/animation_host.h
index 5bd75a8..f81e052 100644
--- a/ui/wm/public/animation_host.h
+++ b/ui/wm/public/animation_host.h
@@ -5,7 +5,6 @@
 #ifndef UI_WM_PUBLIC_ANIMATION_HOST_H_
 #define UI_WM_PUBLIC_ANIMATION_HOST_H_
 
-#include "base/compiler_specific.h"
 #include "ui/wm/public/wm_public_export.h"
 
 namespace aura {
diff --git a/ui/wm/test/wm_test_helper.h b/ui/wm/test/wm_test_helper.h
index 40a5020..9af9327 100644
--- a/ui/wm/test/wm_test_helper.h
+++ b/ui/wm/test/wm_test_helper.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/compiler_specific.h"
 #include "base/run_loop.h"
 #include "ui/aura/client/window_parenting_client.h"
 #include "ui/aura/window_tree_host.h"
diff --git a/url/android/test/java/src/org/chromium/url/JUnitTestGURLs.java b/url/android/test/java/src/org/chromium/url/JUnitTestGURLs.java
index 74e2f1b9..1b64d39 100644
--- a/url/android/test/java/src/org/chromium/url/JUnitTestGURLs.java
+++ b/url/android/test/java/src/org/chromium/url/JUnitTestGURLs.java
@@ -47,6 +47,9 @@
             "https://www.google.com/amp/www.nyt.com/ampthml/blogs.html";
     public static final String AMP_CACHE_URL =
             "https://www.google.com/amp/s/www.nyt.com/ampthml/blogs.html";
+    public static final String TEXT_FRAGMENT_URL = "https://www.example.com/#:~:text=selector";
+    public static final String MULTI_TEXT_FRAGMENT_URL =
+            "https://www.example.com/#:~:text=selector1&text=selector2&text=selector3";
 
     // Map of URL string to GURL serialization.
     /* package */ static final Map<String, String> sGURLMap;
@@ -114,6 +117,10 @@
                 "116,1,true,0,5,0,-1,0,-1,8,14,0,-1,22,35,0,-1,0,-1,false,false,https://www.google.com/amp/www.nyt.com/ampthml/blogs.html");
         map.put(AMP_CACHE_URL,
                 "118,1,true,0,5,0,-1,0,-1,8,14,0,-1,22,37,0,-1,0,-1,false,false,https://www.google.com/amp/s/www.nyt.com/ampthml/blogs.html");
+        map.put(TEXT_FRAGMENT_URL,
+                "100,1,true,0,5,0,-1,0,-1,8,15,0,-1,23,1,0,-1,25,16,false,false,https://www.example.com/#:~:text=selector");
+        map.put(MULTI_TEXT_FRAGMENT_URL,
+                "131,1,true,0,5,0,-1,0,-1,8,15,0,-1,23,1,0,-1,25,47,false,false,https://www.example.com/#:~:text=selector1&text=selector2&text=selector3");
         sGURLMap = Collections.unmodifiableMap(map);
     }
 
diff --git a/weblayer/browser/browser_main_parts_impl.cc b/weblayer/browser/browser_main_parts_impl.cc
index 7896632..f653ad34 100644
--- a/weblayer/browser/browser_main_parts_impl.cc
+++ b/weblayer/browser/browser_main_parts_impl.cc
@@ -251,11 +251,6 @@
           FROM_HERE,
           base::BindOnce(&PublishSubresourceFilterRulesetFromResourceBundle));
 
-  if (main_function_params_.ui_task) {
-    std::move(main_function_params_.ui_task).Run();
-    run_message_loop_ = false;
-  }
-
 #if defined(OS_ANDROID)
   // On Android, retrieve the application start time from Java and record it. On
   // other platforms, the application start time was already recorded in the
@@ -289,14 +284,10 @@
 
 void BrowserMainPartsImpl::WillRunMainMessageLoop(
     std::unique_ptr<base::RunLoop>& run_loop) {
-  if (run_message_loop_) {
-    // Wrap the method that stops the message loop so we can do other shutdown
-    // cleanup inside content.
-    params_->delegate->SetMainMessageLoopQuitClosure(
-        base::BindOnce(StopMessageLoop, run_loop->QuitClosure()));
-  } else {
-    run_loop.reset();
-  }
+  // Wrap the method that stops the message loop so we can do other shutdown
+  // cleanup inside content.
+  params_->delegate->SetMainMessageLoopQuitClosure(
+      base::BindOnce(StopMessageLoop, run_loop->QuitClosure()));
 }
 
 void BrowserMainPartsImpl::OnFirstIdle() {
diff --git a/weblayer/browser/browser_main_parts_impl.h b/weblayer/browser/browser_main_parts_impl.h
index c02222e..92824b5e 100644
--- a/weblayer/browser/browser_main_parts_impl.h
+++ b/weblayer/browser/browser_main_parts_impl.h
@@ -57,7 +57,6 @@
 
   // For running weblayer_browsertests.
   content::MainFunctionParams main_function_params_;
-  bool run_message_loop_ = true;
 
   // Ownership of this moves to BrowserProcess. See
   // ContentBrowserClientImpl::local_state_ for details.