diff --git a/DEPS b/DEPS
index 37bcc06..1bfc370 100644
--- a/DEPS
+++ b/DEPS
@@ -303,15 +303,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': 'd85e872b336fa12f2f66d003f49ff34f09b26c5b',
+  'skia_revision': '511353c8d5455f50c845f4e206f937e4d8e38754',
   # 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': '368b7329925f927a1ef4c730a919006e24f9f057',
+  'v8_revision': 'b2e5ef8011cee8809a12db46b21125489187ac2c',
   # 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': '64680f530426b854ca498adfa0688dee14dc8f1e',
+  'angle_revision': 'e482d4b282f895a8196fac8427cd31b2de39bd18',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -390,7 +390,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': '20d011f51febc179e9223cc6de818a80ba27fb40',
+  'devtools_frontend_revision': '51bff05f036b45846ec67bb3a152230c81ace347',
   # 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.
@@ -1220,7 +1220,7 @@
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '817bf0a426cdb7a93304e1a3a088faec5deb9bd6',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'b83f85441b58753bf118c4583a0dd9ad8add783b',
     'condition': 'checkout_src_internal',
   },
 
@@ -1684,7 +1684,7 @@
     Var('pdfium_git') + '/pdfium.git' + '@' +  Var('pdfium_revision'),
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '5bab1b7d3f12c1fd5c9ff12abd93a7c672fa2ab5',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '9371254ec42c2ed81384067b2b1480f3244f3794',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1866,10 +1866,10 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'd1b65aa5a88f6efd900604dfcda840154e9f16e2',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '5c2aef630221ebabe44df69b6afcb51d125ff97b',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'e73da284fceba421d4465e267adbc510cff7590e',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'e0034a800e358bed704bc1b331310d609ed8c8be',
+    Var('webrtc_git') + '/src.git' + '@' + '522380ff734174faab694e1b67c9d20fffa8738e',
 
   # Wuffs' canonical repository is at github.com/google/wuffs, but we use
   # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file.
@@ -1989,7 +1989,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/help_app/app',
-        'version': '7dysgYmbs7PhMBV6qzOHQ4YdiEgpCsJ1xRAdVoQfxWwC',
+        'version': 'ZI5GbVjUHhOwXBXMpvsi15R2s7fDynAZP8xV4ZR8M8gC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/ash/display/cursor_window_controller.cc b/ash/display/cursor_window_controller.cc
index 9462aa7..232c30ab 100644
--- a/ash/display/cursor_window_controller.cc
+++ b/ash/display/cursor_window_controller.cc
@@ -27,6 +27,7 @@
 #include "ui/aura/window_delegate.h"
 #include "ui/base/hit_test.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "ui/base/resource/resource_scale_factor.h"
 #include "ui/compositor/paint_recorder.h"
 #include "ui/display/display.h"
 #include "ui/display/manager/display_manager.h"
@@ -476,8 +477,9 @@
     // by compositor. HW cursor will not be scaled by display zoom, so the
     // physical size will be inconsistent.
     int resource_id;
-    cursor_scale =
-        gfx::ImageSkia::MapToResourceScale(display_.device_scale_factor());
+    cursor_scale = ui::GetScaleForResourceScaleFactor(
+        ui::GetSupportedResourceScaleFactorForRescale(
+            display_.device_scale_factor()));
     if (!wm::GetCursorDataFor(cursor_size_, cursor_.type(), cursor_scale,
                               &resource_id, &hot_point_in_physical_pixels)) {
       return;
diff --git a/ash/display/cursor_window_controller_unittest.cc b/ash/display/cursor_window_controller_unittest.cc
index 7d2a1e3..a06f47f 100644
--- a/ash/display/cursor_window_controller_unittest.cc
+++ b/ash/display/cursor_window_controller_unittest.cc
@@ -299,10 +299,10 @@
     EXPECT_EQ(GetCursorImage().size(), kCursorSize);
 
     // TODO(hferreiro): the cursor hotspot for non-custom cursors cannot be
-    // checked, since the software cursor uses `ImageSkia::MapToResourceScale`,
-    // and `CursorLoader::GetCursorData` uses
-    // `ui::GetSupportedResourceScaleFactor`, and 2x cursor hotspots are not
-    // just twice the 1x hotspots.
+    // checked, since the software cursor uses
+    // `ui::GetSupportedResourceScaleFactorForRescale`, and
+    // `CursorLoader::GetCursorData` uses `ui::GetSupportedResourceScaleFactor`,
+    // and 2x cursor hotspots are not just twice the 1x hotspots.
     if (cursor.type() == CursorType::kCustom) {
       const gfx::Point kHotspot = gfx::ToFlooredPoint(
           gfx::ConvertPointToDips(cursor_data->hotspot, cursor_scale));
diff --git a/ash/system/audio/audio_detailed_view_pixeltest.cc b/ash/system/audio/audio_detailed_view_pixeltest.cc
index 778ee82..a003c5a 100644
--- a/ash/system/audio/audio_detailed_view_pixeltest.cc
+++ b/ash/system/audio/audio_detailed_view_pixeltest.cc
@@ -48,7 +48,7 @@
 
   EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
       "qs_audio_detailed_view",
-      /*revision_number=*/1, detailed_view));
+      /*revision_number=*/2, detailed_view));
 }
 
 }  // namespace ash
diff --git a/ash/system/cast/cast_notification_controller.cc b/ash/system/cast/cast_notification_controller.cc
index cb0fad77..518a0f2 100644
--- a/ash/system/cast/cast_notification_controller.cc
+++ b/ash/system/cast/cast_notification_controller.cc
@@ -89,6 +89,10 @@
     return;
   }
 
+  // The cast notification controller outlives cast sessions. Ensure
+  // `freeze_button_index_` starts reset when creating a new notification.
+  freeze_button_index_.reset();
+
   for (const auto& device : devices) {
     const CastSink& sink = device.sink;
     const CastRoute& route = device.route;
diff --git a/ash/system/cast/cast_notification_controller_unittest.cc b/ash/system/cast/cast_notification_controller_unittest.cc
index 7518c68..e92bedd 100644
--- a/ash/system/cast/cast_notification_controller_unittest.cc
+++ b/ash/system/cast/cast_notification_controller_unittest.cc
@@ -242,4 +242,34 @@
   EXPECT_EQ(GetNotification()->message(), casting_paused_message);
 }
 
+// Regression test for b/280864232
+TEST_F(CastNotificationControllerTest, NewRouteStop) {
+  // Create notification.
+  cast_config_.set_has_sinks_and_routes(true);
+  cast_config_.set_has_active_route(true);
+  SinkAndRoute device = CreateDeviceLocalRoute();
+  // Make the device "freezable" so the freeze (pause) button appears.
+  device.route.freeze_info.can_freeze = true;
+  notification_controller_->OnDevicesUpdated({device});
+
+  // There should be a notfiication with 2 buttons.
+  EXPECT_TRUE(GetNotification()->pinned());
+  EXPECT_EQ(GetNotification()->buttons().size(), 2u);
+
+  // Update the list of devices so that now there is a non-freezable route.
+  device.route.freeze_info.can_freeze = false;
+  notification_controller_->OnDevicesUpdated({device});
+
+  // There should be a notification with 1 button.
+  EXPECT_TRUE(GetNotification()->pinned());
+  EXPECT_EQ(GetNotification()->buttons().size(), 1u);
+
+  // Clicking the button should stop the route, and not call freeze / unfreeze.
+  ClickOnNotificationButton(0);
+  EXPECT_EQ(cast_config_.freeze_route_count(), 0u);
+  EXPECT_EQ(cast_config_.unfreeze_route_count(), 0u);
+  EXPECT_EQ(cast_config_.stop_casting_count(), 1u);
+  EXPECT_EQ(cast_config_.stop_casting_route_id(), device.route.id);
+}
+
 }  // namespace ash
diff --git a/ash/system/privacy/privacy_indicators_tray_item_view.cc b/ash/system/privacy/privacy_indicators_tray_item_view.cc
index aeeeb25..60080016 100644
--- a/ash/system/privacy/privacy_indicators_tray_item_view.cc
+++ b/ash/system/privacy/privacy_indicators_tray_item_view.cc
@@ -590,10 +590,11 @@
 }
 
 void PrivacyIndicatorsTrayItemView::RecordRepeatedShows() {
-  // We are only interested in more than 1 repeated shows per 100ms. Also only
-  // records in primary display.
-  if (count_repeated_shows_ <= 1 || !IsInPrimaryDisplay(GetWidget())) {
-    count_repeated_shows_ = 0;
+  // Only records in primary display. Note that we also record the metric when
+  // `count_repeated_shows_` is one even though this is not a bad signal. This
+  // is because we want to record proper shows so we can analyze the repeated
+  // shows in context.
+  if (count_repeated_shows_ == 0 || !IsInPrimaryDisplay(GetWidget())) {
     return;
   }
 
diff --git a/ash/system/privacy/privacy_indicators_tray_item_view_unittest.cc b/ash/system/privacy/privacy_indicators_tray_item_view_unittest.cc
index bf54234..07d48e1 100644
--- a/ash/system/privacy/privacy_indicators_tray_item_view_unittest.cc
+++ b/ash/system/privacy/privacy_indicators_tray_item_view_unittest.cc
@@ -725,23 +725,25 @@
 
   base::HistogramTester histograms;
 
+  auto flicker_indicator = [](int number_of_flicker,
+                              base::test::TaskEnvironment* task_environment) {
+    // Makes the view flicker (show then hide) for `number_of_flicker` of times.
+    for (auto i = 0; i < number_of_flicker; i++) {
+      UpdateCameraAndMicrophoneUsage(/*is_camera_used=*/true,
+                                     /*is_microphone_used=*/true);
+      UpdateCameraAndMicrophoneUsage(/*is_camera_used=*/false,
+                                     /*is_microphone_used=*/false);
+      task_environment->FastForwardBy(base::Milliseconds(80));
+    }
+    task_environment->FastForwardBy(base::Milliseconds(100));
+  };
+
   int expected_sample = 6;
-
-  // Makes the view flicker (show then hide) for `expected_sample` of times.
-  // Metric should be recorded for this repeated shows.
-  for (auto i = 0; i < expected_sample; i++) {
-    UpdateCameraAndMicrophoneUsage(/*is_camera_used=*/true,
-                                   /*is_microphone_used=*/true);
-    UpdateCameraAndMicrophoneUsage(/*is_camera_used=*/false,
-                                   /*is_microphone_used=*/false);
-    task_environment()->FastForwardBy(base::Milliseconds(80));
-  }
-  task_environment()->FastForwardBy(base::Milliseconds(100));
-
+  flicker_indicator(expected_sample, task_environment());
   histograms.ExpectBucketCount(kRepeatedShowsHistogramName, expected_sample, 1);
 
   // Makes one more flickering after 100ms. This flicker should not count
-  // towards the previous ones.
+  // towards the previous ones, but this will be counted in a bucket for 1 show.
   UpdateCameraAndMicrophoneUsage(/*is_camera_used=*/true,
                                  /*is_microphone_used=*/true);
   UpdateCameraAndMicrophoneUsage(/*is_camera_used=*/false,
@@ -750,22 +752,17 @@
 
   histograms.ExpectBucketCount(kRepeatedShowsHistogramName, expected_sample + 1,
                                0);
+  histograms.ExpectBucketCount(kRepeatedShowsHistogramName, 1, 1);
 
   // Make sure it works again.
-  expected_sample = 8;
+  flicker_indicator(8, task_environment());
+  histograms.ExpectBucketCount(kRepeatedShowsHistogramName, 8, 1);
 
-  // Makes the view flicker (show then hide) for `expected_sample` of times.
-  // Metric should be recorded for this repeated shows.
-  for (auto i = 0; i < expected_sample; i++) {
-    UpdateCameraAndMicrophoneUsage(/*is_camera_used=*/true,
-                                   /*is_microphone_used=*/true);
-    UpdateCameraAndMicrophoneUsage(/*is_camera_used=*/false,
-                                   /*is_microphone_used=*/false);
-    task_environment()->FastForwardBy(base::Milliseconds(80));
-  }
-  task_environment()->FastForwardBy(base::Milliseconds(100));
+  flicker_indicator(2, task_environment());
+  histograms.ExpectBucketCount(kRepeatedShowsHistogramName, 2, 1);
 
-  histograms.ExpectBucketCount(kRepeatedShowsHistogramName, expected_sample, 1);
+  flicker_indicator(1, task_environment());
+  histograms.ExpectBucketCount(kRepeatedShowsHistogramName, 1, 2);
 }
 
 }  // namespace ash
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_app.html b/ash/webui/diagnostics_ui/resources/diagnostics_app.html
index 0771a4a9..e01c2cd 100644
--- a/ash/webui/diagnostics_ui/resources/diagnostics_app.html
+++ b/ash/webui/diagnostics_ui/resources/diagnostics_app.html
@@ -8,6 +8,10 @@
   :host-context(body.jelly-enabled) navigation-view-panel {
     --navigation-view-panel-bg-color: var(--cros-sys-app_base_shaded);
   }
+  
+  #diagnosticsAppContainer {
+    height: 100%;
+  }
 
   #navigationPanel::part(top-nav) {
     height: 56px;
diff --git a/base/power_monitor/thermal_state_observer_mac.mm b/base/power_monitor/thermal_state_observer_mac.mm
index 0047f6a4..f682781 100644
--- a/base/power_monitor/thermal_state_observer_mac.mm
+++ b/base/power_monitor/thermal_state_observer_mac.mm
@@ -43,7 +43,7 @@
 namespace base {
 
 struct ThermalStateObserverMac::ObjCStorage {
-  id thermal_state_update_observer_ = nil;
+  id thermal_state_update_observer = nil;
 };
 
 ThermalStateObserverMac::ThermalStateObserverMac(
@@ -68,7 +68,7 @@
     state_update_callback.Run(state);
   };
 
-  objc_storage_->thermal_state_update_observer_ =
+  objc_storage_->thermal_state_update_observer =
       [[NSNotificationCenter defaultCenter]
           addObserverForName:NSProcessInfoThermalStateDidChangeNotification
                       object:nil
@@ -97,7 +97,7 @@
 
 ThermalStateObserverMac::~ThermalStateObserverMac() {
   [[NSNotificationCenter defaultCenter]
-      removeObserver:objc_storage_->thermal_state_update_observer_];
+      removeObserver:objc_storage_->thermal_state_update_observer];
   notify_cancel(speed_limit_notification_token_);
 }
 
diff --git a/base/scoped_observation.h b/base/scoped_observation.h
index e8236b8..77403392 100644
--- a/base/scoped_observation.h
+++ b/base/scoped_observation.h
@@ -132,7 +132,7 @@
   const raw_ptr<Observer, DanglingUntriaged> observer_;
 
   // The observed source, if any.
-  raw_ptr<Source> source_ = nullptr;
+  raw_ptr<Source, DanglingUntriaged> source_ = nullptr;
 };
 
 }  // namespace base
diff --git a/build/android/gyp/create_java_binary_script.py b/build/android/gyp/create_java_binary_script.py
index f9e665f..b6adf6b 100755
--- a/build/android/gyp/create_java_binary_script.py
+++ b/build/android/gyp/create_java_binary_script.py
@@ -95,9 +95,6 @@
   parser.add_argument('--tiered-stop-at-level-one',
                       action='store_true',
                       help='JVM flag: -XX:TieredStopAtLevel=1.')
-  parser.add_argument('--use-jdk-11',
-                      action='store_true',
-                      help='Use older JDK11 instead of modern JDK.')
   parser.add_argument('extra_program_args',
                       nargs='*',
                       help='This captures all '
@@ -116,11 +113,8 @@
   run_dir = os.path.dirname(args.output)
   classpath = [os.path.relpath(p, run_dir) for p in classpath]
 
-  if args.use_jdk_11:
-    java_home = build_utils.JAVA_11_HOME_DEPRECATED
-  else:
-    java_home = build_utils.JAVA_HOME
-  java_path = os.path.relpath(os.path.join(java_home, 'bin', 'java'), run_dir)
+  java_path = os.path.relpath(
+      os.path.join(build_utils.JAVA_HOME, 'bin', 'java'), run_dir)
 
   with action_helpers.atomic_output(args.output, mode='w') as script:
     script.write(
diff --git a/build/android/gyp/util/build_utils.py b/build/android/gyp/util/build_utils.py
index f885182..4617d0bf 100644
--- a/build/android/gyp/util/build_utils.py
+++ b/build/android/gyp/util/build_utils.py
@@ -40,10 +40,6 @@
 JAVAP_PATH = os.path.join(JAVA_HOME, 'bin', 'javap')
 KOTLIN_HOME = os.path.join(DIR_SOURCE_ROOT, 'third_party', 'kotlinc', 'current')
 KOTLINC_PATH = os.path.join(KOTLIN_HOME, 'bin', 'kotlinc')
-# Please avoid using this. Our JAVA_HOME is using a newer and actively patched
-# JDK.
-JAVA_11_HOME_DEPRECATED = os.path.join(DIR_SOURCE_ROOT, 'third_party', 'jdk11',
-                                       'current')
 
 def JavaCmd(xmx='1G'):
   ret = [os.path.join(JAVA_HOME, 'bin', 'java')]
diff --git a/build/android/gyp/write_native_libraries_java.py b/build/android/gyp/write_native_libraries_java.py
index fb4d2ad..e96dabc2 100755
--- a/build/android/gyp/write_native_libraries_java.py
+++ b/build/android/gyp/write_native_libraries_java.py
@@ -28,6 +28,7 @@
     public static final int CPU_FAMILY_ARM = 1;
     public static final int CPU_FAMILY_MIPS = 2;
     public static final int CPU_FAMILY_X86 = 3;
+    public static final int CPU_FAMILY_RISCV = 4;
 
     // Set to true to enable the use of the Chromium Linker.
     public static {MAYBE_FINAL}boolean sUseLinker{USE_LINKER};
@@ -60,15 +61,14 @@
       help='Enable Chromium linker.')
   parser.add_argument(
       '--native-libraries-list', help='File with list of native libraries.')
-  parser.add_argument(
-      '--cpu-family',
-      choices={
-          'CPU_FAMILY_ARM', 'CPU_FAMILY_X86', 'CPU_FAMILY_MIPS',
-          'CPU_FAMILY_UNKNOWN'
-      },
-      required=True,
-      default='CPU_FAMILY_UNKNOWN',
-      help='CPU family.')
+  parser.add_argument('--cpu-family',
+                      choices={
+                          'CPU_FAMILY_ARM', 'CPU_FAMILY_X86', 'CPU_FAMILY_MIPS',
+                          'CPU_FAMILY_RISCV', 'CPU_FAMILY_UNKNOWN'
+                      },
+                      required=True,
+                      default='CPU_FAMILY_UNKNOWN',
+                      help='CPU family.')
   parser.add_argument(
       '--main-component-library',
       help='If used, the list of native libraries will only contain this '
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index 3eaaa26..813acec 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -1398,7 +1398,7 @@
   #
   template("java_binary_script") {
     action_with_pydeps(target_name) {
-      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps" ])
+      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
 
       _main_class = invoker.main_class
       _build_config = invoker.build_config
@@ -1423,6 +1423,10 @@
         "--max-heap-size=$_max_heap_size",
       ]
       data = []
+      deps = [ "//third_party/jdk:java_data" ]
+      if (defined(invoker.deps)) {
+        deps += invoker.deps
+      }
 
       if (use_jacoco_coverage) {
         args += [
@@ -1444,12 +1448,6 @@
       if (defined(invoker.wrapper_script_args)) {
         args += [ "--" ] + invoker.wrapper_script_args
       }
-      if (defined(invoker.use_jdk_11) && invoker.use_jdk_11) {
-        args += [ "--use-jdk-11" ]
-        deps += [ "//third_party/jdk11:java_data" ]
-      } else {
-        deps += [ "//third_party/jdk:java_data" ]
-      }
     }
   }
 
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 364d9b91..ac9fe80c 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -795,6 +795,8 @@
       _cpu_family = "CPU_FAMILY_X86"
     } else if (current_cpu == "mipsel" || current_cpu == "mips64el") {
       _cpu_family = "CPU_FAMILY_MIPS"
+    } else if (current_cpu == "riscv64") {
+      _cpu_family = "CPU_FAMILY_RISCV"
     } else {
       assert(false, "Unsupported CPU family")
     }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 5e43136..62b25f4 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -1310,7 +1310,7 @@
         ldflags += [ "-m64" ]
       }
     } else if (current_cpu == "riscv64") {
-      if (is_clang) {
+      if (is_clang && !is_android) {
         cflags += [ "--target=riscv64-linux-gnu" ]
         ldflags += [ "--target=riscv64-linux-gnu" ]
       }
diff --git a/build/config/rust.gni b/build/config/rust.gni
index c0b8450..1a8bb4d 100644
--- a/build/config/rust.gni
+++ b/build/config/rust.gni
@@ -155,6 +155,11 @@
   } else {
     rust_sysroot = get_path_info(rust_sysroot_absolute, "abspath")
   }
+
+  # Prebuilt toolchains won't come with bindgen, so we unconditionally use the
+  # bindgen we ship with the Rust toolchain. This could be made configurable
+  # if folks want to supply a bindgen with their toolchain.
+  rust_bindgen_root = "//third_party/rust-toolchain"
 }
 
 # Figure out the Rust target triple (aka 'rust_abi_target')
diff --git a/build/rust/cargo_crate.gni b/build/rust/cargo_crate.gni
index 9583471c..a376029c 100644
--- a/build/rust/cargo_crate.gni
+++ b/build/rust/cargo_crate.gni
@@ -217,7 +217,12 @@
     rustenv = _rustenv
 
     if (!defined(build_native_rust_unit_tests)) {
-      build_native_rust_unit_tests = true
+      build_native_rust_unit_tests = _crate_type != "proc-macro"
+    }
+    if (build_native_rust_unit_tests) {
+      # Unit tests in a proc-macro crate type don't make sense, you can't
+      # compile executables against the `proc_macro` crate.
+      assert(_crate_type != "proc-macro")
     }
 
     # The unit tests for each target, if generated, should be unique as well.
diff --git a/build/rust/run_bindgen.py b/build/rust/run_bindgen.py
index a77c555..c9d192fe 100755
--- a/build/rust/run_bindgen.py
+++ b/build/rust/run_bindgen.py
@@ -42,6 +42,8 @@
   parser.add_argument("--ld-library-path",
                       help="LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH on Mac) to "
                       "set")
+  parser.add_argument("--libclang-path",
+                      help="Path to the libclang shared libray.")
   parser.add_argument("-I", "--include", help="include path", action="append")
   parser.add_argument("--bindgen-flags",
                       help="flags to pass to bindgen",
@@ -80,6 +82,8 @@
       env["DYLD_LIBRARY_PATH"] = args.ld_library_path
     else:
       env["LD_LIBRARY_PATH"] = args.ld_library_path
+  if args.libclang_path:
+    env["LIBCLANG_PATH"] = args.libclang_path
   returncode = subprocess.run([args.exe, *genargs], env=env).returncode
   if returncode != 0:
     # Make sure we don't emit anything if bindgen failed.
diff --git a/build/rust/rust_bindgen.gni b/build/rust/rust_bindgen.gni
index c992b8e..0661cffb 100644
--- a/build/rust/rust_bindgen.gni
+++ b/build/rust/rust_bindgen.gni
@@ -11,20 +11,20 @@
   import("//build/toolchain/win/win_toolchain_data.gni")
 }
 
-_rustc_base_path = rust_sysroot
-
-# TODO(danakj): When we're using the Android prebuilt toolchain, there's no
-# bindgen present. bindgen is for the host platform so using the linux one will
-# work.
-if (!use_chromium_rust_toolchain) {
-  _rustc_base_path = "//third_party/rust-toolchain"
-}
-
-_bindgen_path = "${_rustc_base_path}/bin/bindgen"
+_bindgen_path = "${rust_bindgen_root}/bin/bindgen"
 if (is_win) {
   _bindgen_path = "${_bindgen_path}.exe"
 }
 
+# On Windows, the libclang.dll is beside the bindgen.exe, otherwise it is in
+# ../lib.
+_libclang_path = rust_bindgen_root
+if (is_win) {
+  _libclang_path += "/bin"
+} else {
+  _libclang_path += "/lib"
+}
+
 # Template to build Rust/C bindings with bindgen.
 #
 # This template expands to a static_library containing the Rust side of the
@@ -79,16 +79,6 @@
     depfile = "$target_out_dir/${target_name}.d"
     outputs = [ out_gen_rs ]
 
-    lib_path = ""
-    if (is_linux) {
-      # Linux clang, and clang libs, use a shared libstdc++, which we must
-      # point to.
-      clang_ld_path = rebase_path(clang_base_path + "/lib", root_build_dir)
-      lib_path += "${clang_ld_path}:"
-    }
-    rust_ld_path = rebase_path(_rustc_base_path + "/lib", root_build_dir)
-    lib_path += "${rust_ld_path}"
-
     args = [
       "--exe",
       rebase_path(_bindgen_path),
@@ -98,10 +88,19 @@
       rebase_path(depfile, root_build_dir),
       "--output",
       rebase_path(out_gen_rs, root_build_dir),
-      "--ld-library-path",
-      lib_path,
+      "--libclang-path",
+      rebase_path(_libclang_path, root_build_dir),
     ]
 
+    if (is_linux) {
+      # Linux clang, and clang libs, use a shared libstdc++, which we must
+      # point to.
+      args += [
+        "--ld-library-path",
+        rebase_path(clang_base_path + "/lib", root_build_dir),
+      ]
+    }
+
     if (defined(invoker.bindgen_flags)) {
       args += [ "--bindgen-flags" ]
       foreach(flag, invoker.bindgen_flags) {
diff --git a/build/rust/std/BUILD.gn b/build/rust/std/BUILD.gn
index 60aea480..4482166 100644
--- a/build/rust/std/BUILD.gn
+++ b/build/rust/std/BUILD.gn
@@ -28,6 +28,7 @@
 import("//build/config/compiler/compiler.gni")
 import("//build/config/coverage/coverage.gni")
 import("//build/config/rust.gni")
+import("//build/config/sanitizers/sanitizers.gni")
 
 if (toolchain_has_rust) {
   # Equivalent of allocator symbols injected by rustc.
@@ -187,6 +188,48 @@
       visibility = [ ":*" ]
     }
 
+    # When given -Zsanitize=..., rustc insists on passing a sanitizer runtime to
+    # the linker it invokes. Unfortunately, our C++ ldflags already tell the
+    # linker to link against a C++ sanitizer runtime - which contains the same
+    # symbols. So, make a blank library.
+    # The list of relevant sanitizers here is taken from
+    # https://github.com/rust-lang/rust/blob/7e7483d26e3cec7a44ef00cf7ae6c9c8c918bec6/compiler/rustc_codegen_ssa/src/back/link.rs#L1148
+    template("rustc_sanitizer_runtime") {
+      rt_name = target_name
+      not_needed([ "invoker" ])
+      static_library("sanitizer_rt_$rt_name") {
+        sources = []
+        output_name = "librustc-nightly_rt.$rt_name"
+        output_dir = "$local_rustc_sysroot/$sysroot_lib_subdir"
+      }
+    }
+    rustc_sanitizer_runtimes = []
+    if (is_asan) {
+      rustc_sanitizer_runtime("asan") {
+      }
+      rustc_sanitizer_runtimes += [ ":sanitizer_rt_asan" ]
+    }
+    if (is_lsan) {
+      rustc_sanitizer_runtime("lsan") {
+      }
+      rustc_sanitizer_runtimes += [ ":sanitizer_rt_lsan" ]
+    }
+    if (is_msan) {
+      rustc_sanitizer_runtime("msan") {
+      }
+      rustc_sanitizer_runtimes += [ ":sanitizer_rt_msan" ]
+    }
+    if (is_tsan) {
+      rustc_sanitizer_runtime("tsan") {
+      }
+      rustc_sanitizer_runtimes += [ ":sanitizer_rt_tsan" ]
+    }
+    if (is_hwasan) {
+      rustc_sanitizer_runtime("hwasan") {
+      }
+      rustc_sanitizer_runtimes += [ ":sanitizer_rt_hwasan" ]
+    }
+
     group("local_stdlib_libs") {
       assert(toolchain_has_rust,
              "Some C++ target is depending on Rust code even though " +
@@ -198,6 +241,7 @@
       foreach(libname, stdlib_files + skip_stdlib_files) {
         deps += [ "rules:$libname" ]
       }
+      deps += rustc_sanitizer_runtimes
       visibility = [ ":*" ]
     }
 
diff --git a/build/rust/tests/BUILD.gn b/build/rust/tests/BUILD.gn
index 22c74b6..f9bd344 100644
--- a/build/rust/tests/BUILD.gn
+++ b/build/rust/tests/BUILD.gn
@@ -77,11 +77,6 @@
         deps +=
             [ "test_rust_shared_library:test_rust_shared_library_unittests" ]
       }
-      if (current_toolchain == host_toolchain_no_sanitizers) {
-        # Build these proc macro tests only on toolchains where we'd build the
-        # proc macro itself.
-        deps += [ "test_proc_macro_crate:test_proc_macro_crate_v0_2_unittests" ]
-      }
     }
 
     if (is_win) {
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTabSwitcherTest.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTabSwitcherTest.java
index b1fd475b..01ed09f 100644
--- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTabSwitcherTest.java
+++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTabSwitcherTest.java
@@ -115,7 +115,7 @@
     @Rule
     public ChromeRenderTestRule mRenderTestRule =
             ChromeRenderTestRule.Builder.withPublicCorpus()
-                    .setRevision(3)
+                    .setRevision(4)
                     .setBugComponent(ChromeRenderTestRule.Component.UI_BROWSER_MOBILE_START)
                     .build();
     @Rule
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
index 634a277..af14cf33 100644
--- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
+++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
@@ -151,14 +151,12 @@
     @SmallTest
     @EnableFeatures({ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID + "<Study"})
     // clang-format off
-    @Restriction({Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE,
-        UiRestriction.RESTRICTION_TYPE_PHONE, UiRestriction.RESTRICTION_TYPE_TABLET})
+    @Restriction({Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION,
-            "force-fieldtrial-params=Study.Group:allow_to_refetch/true/thumbnail_aspect_ratio/2.0"})
+            "force-fieldtrial-params=Study.Group:thumbnail_aspect_ratio/2.0"})
     public void fetchThumbnailsPreNativeTest() {
         // clang-format on
         StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule);
-        Assert.assertTrue(TabContentManager.ALLOW_TO_REFETCH_TAB_THUMBNAIL_VARIATION.getValue());
 
         int tabId = 0;
         mThumbnailFetchCount = 0;
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java
index b637687d..7ff94fb 100644
--- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java
+++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java
@@ -41,6 +41,7 @@
 import org.junit.Assert;
 
 import org.chromium.base.CommandLine;
+import org.chromium.base.ContextUtils;
 import org.chromium.base.NativeLibraryLoadedStatus;
 import org.chromium.base.StreamUtil;
 import org.chromium.base.library_loader.LibraryLoader;
@@ -62,6 +63,7 @@
 import org.chromium.chrome.browser.suggestions.tile.TileTitleSource;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabState;
+import org.chromium.chrome.browser.tab.TabUtils;
 import org.chromium.chrome.browser.tabmodel.TabModelUtils;
 import org.chromium.chrome.browser.tabmodel.TabPersistentStore;
 import org.chromium.chrome.browser.tabmodel.TabbedModeTabPersistencePolicy;
@@ -358,7 +360,10 @@
      * @return The bitmap created.
      */
     public static Bitmap createThumbnailBitmapAndWriteToFile(int tabId) {
-        final Bitmap thumbnailBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
+        final int height = 100;
+        final int width = (int) Math.round(
+                height * TabUtils.getTabThumbnailAspectRatio(ContextUtils.getApplicationContext()));
+        final Bitmap thumbnailBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
 
         try {
             File thumbnailFile = TabContentManager.getTabThumbnailFileJpeg(tabId);
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherAndStartSurfaceLayoutTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherAndStartSurfaceLayoutTest.java
index a919c4b2..2805f1f 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherAndStartSurfaceLayoutTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherAndStartSurfaceLayoutTest.java
@@ -1297,7 +1297,6 @@
     @UseMethodParameter(RefactorTestParams.class)
     @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
     @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/2.0/allow_to_refetch/true"})
-    @DisabledTest(message = "crbug.com/1315676#c20")
     public void testThumbnailFetchingResult_changingAspectRatio(
             boolean isStartSurfaceRefactorEnabled) throws Exception {
         var histograms = HistogramWatcher.newSingleRecordWatcher(
@@ -1306,7 +1305,7 @@
 
         prepareTabs(1, 0, "about:blank");
         // Simulate Jpeg has cached with default aspect ratio.
-        simulateJpegHasCachedWithDefaultAspectRatio();
+        simulateJpegHasCachedWithAspectRatio(0.85);
         enterTabSwitcher(mActivityTestRule.getActivity());
         // There might be an additional one from capturing thumbnail for the live layer.
         CriteriaHelper.pollUiThread(
@@ -1539,12 +1538,15 @@
                             (ViewLookupCachingFrameLayout) viewHolder.itemView;
                     TabGridThumbnailView thumbnail =
                             (TabGridThumbnailView) tabView.fastFindViewById(R.id.tab_thumbnail);
-                    double thumbnailViewRatio = thumbnail.getWidth() * 1.0 / thumbnail.getHeight();
 
-                    assertTrue("Actual ratio: " + thumbnailViewRatio
-                                    + "; Expected ratio: " + mExpectedRatio,
-                            Math.abs(thumbnailViewRatio - mExpectedRatio)
-                                    <= TabContentManager.ASPECT_RATIO_PRECISION);
+                    double thumbnailViewRatio = thumbnail.getWidth() * 1.0 / thumbnail.getHeight();
+                    int pixelDelta =
+                            Math.abs((int) Math.round(thumbnail.getHeight() * mExpectedRatio)
+                                    - thumbnail.getWidth());
+                    assertTrue("Actual ratio: " + thumbnailViewRatio + "; Expected ratio: "
+                                    + mExpectedRatio + "; Pixel delta: " + pixelDelta,
+                            pixelDelta <= thumbnail.getWidth()
+                                            * TabContentManager.PIXEL_TOLERANCE_PERCENT);
                 }
             }
             assertTrue("should have at least one valid ViewHolder", hasAtLeastOneValidViewHolder);
@@ -2209,11 +2211,10 @@
         return true;
     }
 
-    private void simulateJpegHasCachedWithDefaultAspectRatio() throws IOException {
+    private void simulateJpegHasCachedWithAspectRatio(double aspectRatio) throws IOException {
         TabModel currentModel = mActivityTestRule.getActivity().getCurrentTabModel();
         int jpegWidth = 125;
-        int jpegHeight = (int) (jpegWidth * 1.0
-                / TabUtils.getTabThumbnailAspectRatio(mActivityTestRule.getActivity()));
+        int jpegHeight = (int) (jpegWidth * 1.0 / aspectRatio);
         for (int i = 0; i < currentModel.getCount(); i++) {
             Tab tab = currentModel.getTabAt(i);
             Bitmap bitmap = Bitmap.createBitmap(jpegWidth, jpegHeight, Config.ARGB_8888);
@@ -2221,6 +2222,11 @@
         }
     }
 
+    private void simulateJpegHasCachedWithDefaultAspectRatio() throws IOException {
+        simulateJpegHasCachedWithAspectRatio(
+                TabUtils.getTabThumbnailAspectRatio(mActivityTestRule.getActivity()));
+    }
+
     private void simulateAspectRatioChangedToPoint75() throws IOException {
         TabModel currentModel = mActivityTestRule.getActivity().getCurrentTabModel();
         for (int i = 0; i < currentModel.getCount(); i++) {
@@ -2245,8 +2251,11 @@
             Tab tab = currentModel.getTabAt(i);
             Bitmap bitmap = TabContentManager.getJpegForTab(tab.getId(), null);
             double bitmapRatio = bitmap.getWidth() * 1.0 / bitmap.getHeight();
-            assertTrue("Actual ratio: " + bitmapRatio + "; Expected ratio: " + ratio,
-                    Math.abs(bitmapRatio - ratio) <= TabContentManager.ASPECT_RATIO_PRECISION);
+            int pixelDelta =
+                    Math.abs((int) Math.round(bitmap.getHeight() * ratio) - bitmap.getWidth());
+            assertTrue("Actual ratio: " + bitmapRatio + "; Expected ratio: " + ratio
+                            + "; Pixel delta: " + pixelDelta,
+                    pixelDelta <= bitmap.getWidth() * TabContentManager.PIXEL_TOLERANCE_PERCENT);
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
index 99f95b9..9834a2fa 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -1024,16 +1024,6 @@
                 && tab != null) {
             tab.hide(TabHidingType.ACTIVITY_HIDDEN);
         }
-
-        if (mNativeInitialized
-                && ChromeFeatureList.isEnabled(ChromeFeatureList.KEEP_ANDROID_TINTED_RESOURCES)
-                && mCompositorViewHolderSupplier.hasValue()) {
-            LayoutManagerImpl layoutManager =
-                    mCompositorViewHolderSupplier.get().getLayoutManager();
-            if (layoutManager != null && layoutManager.getResourceManager() != null) {
-                layoutManager.getResourceManager().clearTintedResourceCache();
-            }
-        }
     }
 
     private boolean useWindowFocusForVisibility() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
index d589e07..5f9b7fd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -10,7 +10,6 @@
 import org.chromium.chrome.browser.WarmupManager;
 import org.chromium.chrome.browser.app.ChromeActivity;
 import org.chromium.chrome.browser.back_press.MinimizeAppAndCloseTabBackPressHandler;
-import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider;
 import org.chromium.chrome.browser.customtabs.features.branding.BrandingController;
@@ -168,7 +167,6 @@
                 StartSurfaceConfiguration.START_SURFACE_LAST_ACTIVE_TAB_ONLY,
                 StartSurfaceConfiguration.START_SURFACE_OPEN_NTP_INSTEAD_OF_START,
                 StartSurfaceConfiguration.START_SURFACE_OPEN_START_AS_HOMEPAGE,
-                TabContentManager.ALLOW_TO_REFETCH_TAB_THUMBNAIL_VARIATION,
                 TabPersistentStore.CRITICAL_PERSISTED_TAB_DATA_SAVE_ONLY_PARAM,
                 TabUiFeatureUtilities.ENABLE_TAB_GROUP_AUTO_CREATION,
                 TabUiFeatureUtilities.GTS_ACCESSIBILITY_LIST_MODE,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java
index 6467380..df45e9e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java
@@ -129,34 +129,60 @@
         @Override
         public void bookmarkNodeRemoved(BookmarkItem parent, int oldIndex, BookmarkItem node,
                 boolean isDoingExtensiveChanges) {
-            // If the folder is removed in folder mode, show the parent folder or falls back to all
-            // bookmarks mode.
-            if (getCurrentUiMode() == BookmarkUiMode.FOLDER
-                    && node.getId().equals(mStateStack.peek().mFolder)) {
-                if (mBookmarkModel.getTopLevelFolderIds(true, true).contains(node.getId())) {
-                    openFolder(mBookmarkModel.getDefaultFolderViewLocation());
+            clearHighlight();
+
+            if (getCurrentUiMode() == BookmarkUiMode.FOLDER) {
+                // If the folder is removed in folder mode, show the parent folder or falls back to
+                // all bookmarks mode.
+                if (Objects.equals(node.getId(), getCurrentFolderId())) {
+                    if (mBookmarkModel.getTopLevelFolderIds(true, true).contains(node.getId())) {
+                        openFolder(mBookmarkModel.getDefaultFolderViewLocation());
+                    } else {
+                        openFolder(parent.getId());
+                    }
                 } else {
-                    openFolder(parent.getId());
+                    if (node.isFolder()) {
+                        refresh();
+                    } else {
+                        int deletedPosition = getPositionForBookmark(node.getId());
+                        if (deletedPosition >= 0) {
+                            mModelList.removeAt(deletedPosition);
+                            syncAdapterAndSelectionDelegate();
+                        }
+                    }
                 }
+            } else if (getCurrentUiMode() == BookmarkUiMode.SEARCHING) {
+                // We cannot rely on removing the specific list item that corresponds to the
+                // removed node because the node might be a parent with children also shown
+                // in the list.
+                search(mSearchText);
             }
         }
 
         @Override
         public void bookmarkNodeChanged(BookmarkItem node) {
-            if (getCurrentUiMode() == BookmarkUiMode.FOLDER && !mStateStack.isEmpty()
-                    && node.getId().equals(mStateStack.peek().mFolder)) {
-                notifyUi(mStateStack.peek());
-                return;
+            clearHighlight();
+
+            if (getCurrentUiMode() == BookmarkUiMode.FOLDER
+                    && Objects.equals(node.getId(), getCurrentFolderId())) {
+                refresh();
+            } else {
+                super.bookmarkNodeChanged(node);
             }
-            super.bookmarkNodeChanged(node);
         }
 
         @Override
         public void bookmarkModelChanged() {
-            // If the folder no longer exists in folder mode, we need to fall back. Relying on the
-            // default behavior by setting the folder mode again.
-            if (getCurrentUiMode() == BookmarkUiMode.FOLDER) {
-                setState(mStateStack.peek());
+            clearHighlight();
+
+            if (getCurrentUiMode() == BookmarkUiMode.SEARCHING) {
+                if (!TextUtils.equals(mSearchText, EMPTY_QUERY)) {
+                    search(mSearchText);
+                } else {
+                    onEndSearch();
+                }
+            } else {
+                refresh();
             }
         }
     };
@@ -179,59 +205,10 @@
         }
     };
 
-    // TODO(https://crbug.com/1413463): Combine with mBookmarkModelObserver.
-    private BookmarkModelObserver mBookmarkModelObserver2 = new BookmarkModelObserver() {
-        @Override
-        public void bookmarkNodeChanged(BookmarkItem node) {
-            clearHighlight();
-            int position = getPositionForBookmark(node.getId());
-            if (position >= 0) mDragReorderableRecyclerViewAdapter.notifyItemChanged(position);
-        }
-
-        @Override
-        public void bookmarkNodeRemoved(BookmarkItem parent, int oldIndex, BookmarkItem node,
-                boolean isDoingExtensiveChanges) {
-            clearHighlight();
-
-            if (getCurrentUiMode() == BookmarkUiMode.SEARCHING) {
-                // We cannot rely on removing the specific list item that corresponds to the
-                // removed node because the node might be a parent with children also shown
-                // in the list.
-                search(mSearchText);
-                return;
-            }
-
-            if (node.isFolder()) {
-                notifyStateChange(mBookmarkUiObserver);
-            } else {
-                int deletedPosition = getPositionForBookmark(node.getId());
-                if (deletedPosition >= 0) {
-                    mModelList.removeAt(deletedPosition);
-                    syncAdapterAndSelectionDelegate();
-                }
-            }
-        }
-
-        @Override
-        public void bookmarkModelChanged() {
-            clearHighlight();
-            notifyStateChange(mBookmarkUiObserver);
-
-            if (getCurrentUiMode() == BookmarkUiMode.SEARCHING) {
-                if (!TextUtils.equals(mSearchText, EMPTY_QUERY)) {
-                    search(mSearchText);
-                } else {
-                    onEndSearch();
-                }
-            }
-        }
-    };
-
     private final BookmarkUiObserver mBookmarkUiObserver = new BookmarkUiObserver() {
         @Override
         public void onDestroy() {
             removeUiObserver(mBookmarkUiObserver);
-            mBookmarkModel.removeObserver(mBookmarkModelObserver2);
             getSelectionDelegate().removeObserver(mSelectionObserver);
             mPromoHeaderManager.destroy();
         }
@@ -305,10 +282,8 @@
 
     private final BookmarkUiPrefs.Observer mBookmarkUiPrefsObserver = new Observer() {
         @Override
-        @SuppressWarnings("NotifyDataSetChanged")
         public void onBookmarkRowDisplayPrefChanged(@BookmarkRowDisplayPref int displayPref) {
             mModelList.clear();
-            mDragReorderableRecyclerViewAdapter.notifyDataSetChanged();
             if (getCurrentUiMode() == BookmarkUiMode.SEARCHING) {
                 search(mSearchText);
             } else {
@@ -427,7 +402,6 @@
         // from when it was in the original adapter. It doesn't conceptually make sense to be here,
         // and should happen earlier.
         addUiObserver(mBookmarkUiObserver);
-        mBookmarkModel.addObserver(mBookmarkModelObserver2);
         mSelectionDelegate.addObserver(mSelectionObserver);
 
         if (!TextUtils.isEmpty(mInitialUrl)) {
@@ -632,7 +606,7 @@
         observer.onUiModeChanged(state);
         switch (state) {
             case BookmarkUiMode.FOLDER:
-                observer.onFolderStateSet(mStateStack.peek().mFolder);
+                observer.onFolderStateSet(getCurrentFolderId());
                 break;
             case BookmarkUiMode.LOADING:
                 break;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
index 42a95d63..bb09a79 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
@@ -15,7 +15,6 @@
 import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab;
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.layouts.EventFilter;
 import org.chromium.chrome.browser.layouts.LayoutType;
 import org.chromium.chrome.browser.layouts.animation.CompositorAnimationHandler;
@@ -458,8 +457,7 @@
             mNextTabId = Tab.INVALID_TAB_ID;
         }
         mUpdateHost.doneHiding();
-        if (mRenderHost != null && mRenderHost.getResourceManager() != null
-                && !ChromeFeatureList.isEnabled(ChromeFeatureList.KEEP_ANDROID_TINTED_RESOURCES)) {
+        if (mRenderHost != null && mRenderHost.getResourceManager() != null) {
             mRenderHost.getResourceManager().clearTintedResourceCache();
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java
index 00ed4c6..19abcb5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java
@@ -31,7 +31,6 @@
 import org.chromium.base.task.PostTask;
 import org.chromium.base.task.TaskTraits;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.flags.BooleanCachedFieldTrialParameter;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.flags.PostNativeFlag;
@@ -48,9 +47,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 /**
  * The TabContentManager is responsible for serving tab contents to the UI components. Contents
@@ -74,17 +71,13 @@
         int GOT_DIFFERENT_ASPECT_RATIO_JPEG = 3;
         int NUM_ENTRIES = 4;
     }
-    public static final double ASPECT_RATIO_PRECISION = 0.01;
 
-    // Whether to allow to refetch tab thumbnail if the aspect ratio is not matching.
-    public static final BooleanCachedFieldTrialParameter ALLOW_TO_REFETCH_TAB_THUMBNAIL_VARIATION =
-            new BooleanCachedFieldTrialParameter(
-                    ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, "allow_to_refetch", true);
+    // This is to accommodate for pixel rounding errors.
+    public static final double PIXEL_TOLERANCE_PERCENT = 0.02;
 
     @VisibleForTesting
     public static final String UMA_THUMBNAIL_FETCHING_RESULT =
-            "GridTabSwitcher.ThumbnailFetchingResult";
-    private final Set<Integer> mRefectchedTabIds = new HashSet<>();
+            "Android.GridTabSwitcher.ThumbnailFetchingResult";
 
     private float mThumbnailScale;
     /**
@@ -210,7 +203,6 @@
      * Destroy the native component.
      */
     public void destroy() {
-        if (mRefectchedTabIds != null) mRefectchedTabIds.clear();
         if (mNativeTabContentManager != 0) {
             TabContentManagerJni.get().destroy(mNativeTabContentManager);
             mNativeTabContentManager = 0;
@@ -437,37 +429,37 @@
         TraceEvent.startAsync("GetTabThumbnailFromDisk", tabId);
         PostTask.postTask(TaskTraits.USER_VISIBLE_MAY_BLOCK, () -> {
             Bitmap bitmap = getJpegForTab(tabId, thumbnailSize);
-            PostTask.postTask(
-                    TaskTraits.UI_USER_VISIBLE, () -> { onBitmapRead(tabId, bitmap, callback); });
+            PostTask.postTask(TaskTraits.UI_USER_VISIBLE,
+                    () -> { onBitmapRead(tabId, thumbnailSize, bitmap, callback); });
         });
     }
 
-    private void onBitmapRead(@NonNull int tabId, Bitmap jpeg, @NonNull Callback<Bitmap> callback) {
+    private void onBitmapRead(@NonNull int tabId, @NonNull Size thumbnailSize, Bitmap jpeg,
+            @NonNull Callback<Bitmap> callback) {
         TraceEvent.finishAsync("GetTabThumbnailFromDisk", tabId);
         if (jpeg != null) {
-            if (ALLOW_TO_REFETCH_TAB_THUMBNAIL_VARIATION.getValue()) {
-                // TODO(crbug.com/1344354): compare the height instead of pixel tolerance.
-                double jpegAspectRatio =
-                        jpeg.getHeight() == 0 ? 0 : 1.0 * jpeg.getWidth() / jpeg.getHeight();
-                // Retry fetching thumbnail once for all tabs that are:
-                //  * Thumbnail's aspect ratio is different from the expected ratio.
-                if (!mRefectchedTabIds.contains(tabId)
-                        && Math.abs(jpegAspectRatio - getTabCaptureAspectRatio())
-                                >= ASPECT_RATIO_PRECISION) {
-                    recordThumbnailFetchingResult(
-                            ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG);
+            // Pixel difference between the real aspect ratio and the actual aspect ratio.
+            final int aspectRatioPixelError =
+                    Math.abs((int) Math.round(jpeg.getHeight() * getTabCaptureAspectRatio())
+                            - jpeg.getWidth());
+            // Allow a pixel error proportional to the size of the thumbnail that will be shown.
+            // thumbnailSize will be within a factor of 2 of the size of jpeg due to resizeJpeg.
+            final int aspectRatioAllowedError =
+                    (int) Math.round(Math.min(thumbnailSize.getWidth(), thumbnailSize.getHeight())
+                            * PIXEL_TOLERANCE_PERCENT);
+            if (aspectRatioPixelError >= aspectRatioAllowedError) {
+                recordThumbnailFetchingResult(
+                        ThumbnailFetchingResult.GOT_DIFFERENT_ASPECT_RATIO_JPEG);
 
-                    if (mNativeTabContentManager == 0) {
-                        callback.onResult(jpeg);
-                        return;
-                    }
-                    if (!mSnapshotsEnabled) return;
-
-                    mRefectchedTabIds.add(tabId);
-                    TabContentManagerJni.get().getEtc1TabThumbnail(
-                            mNativeTabContentManager, tabId, getTabCaptureAspectRatio(), callback);
+                if (mNativeTabContentManager == 0) {
+                    callback.onResult(jpeg);
                     return;
                 }
+                if (!mSnapshotsEnabled) return;
+
+                TabContentManagerJni.get().getEtc1TabThumbnail(
+                        mNativeTabContentManager, tabId, getTabCaptureAspectRatio(), callback);
+                return;
             }
             recordThumbnailFetchingResult(ThumbnailFetchingResult.GOT_JPEG);
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/GeolocationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/GeolocationTest.java
index dbbc570..ce2d4c1 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/GeolocationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/permissions/GeolocationTest.java
@@ -64,6 +64,7 @@
      */
     @Test
     @MediumTest
+    @DisabledTest(message = "https://crbug.com/1444083")
     @Feature({"Location", "Main"})
     public void testGeolocationPlumbingAllowedDialog() throws Exception {
         runTest("initiate_getCurrentPosition()", 1, true, true);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BasicBookmarkQueryHandlerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BasicBookmarkQueryHandlerTest.java
index 7708469..f8cd8a0 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BasicBookmarkQueryHandlerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BasicBookmarkQueryHandlerTest.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.browser.bookmarks;
 
+import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.doReturn;
 
 import static org.chromium.chrome.browser.bookmarks.SharedBookmarkModelMocks.FOLDER_BOOKMARK_ID_A;
@@ -14,7 +15,6 @@
 import static org.chromium.chrome.browser.bookmarks.SharedBookmarkModelMocks.URL_BOOKMARK_ID_D;
 import static org.chromium.chrome.browser.bookmarks.SharedBookmarkModelMocks.URL_BOOKMARK_ID_E;
 
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -32,7 +32,7 @@
 import java.util.Arrays;
 import java.util.List;
 
-/** Unit tests for {@link BasicmHandler}. */
+/** Unit tests for {@link BasicBookmarkQueryHandler}. */
 @Batch(Batch.UNIT_TESTS)
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
@@ -57,9 +57,9 @@
     public void testBuildBookmarkListForParent_nonRootFolder() {
         List<BookmarkListEntry> result = mHandler.buildBookmarkListForParent(MOBILE_BOOKMARK_ID);
 
-        Assert.assertEquals(2, result.size());
-        Assert.assertEquals(FOLDER_BOOKMARK_ID_A, result.get(0).getBookmarkItem().getId());
-        Assert.assertEquals(URL_BOOKMARK_ID_A, result.get(1).getBookmarkItem().getId());
+        assertEquals(2, result.size());
+        assertEquals(FOLDER_BOOKMARK_ID_A, result.get(0).getBookmarkItem().getId());
+        assertEquals(URL_BOOKMARK_ID_A, result.get(1).getBookmarkItem().getId());
     }
 
     @Test
@@ -69,8 +69,8 @@
 
         // Both URL_BOOKMARK_ID_B and URL_BOOKMARK_ID_C will be returned as children of
         // BookmarkId.SHOPPING_FOLDER , but only URL_BOOKMARK_ID_B will have a correct meta.
-        Assert.assertEquals(1, result.size());
-        Assert.assertEquals(URL_BOOKMARK_ID_B, result.get(0).getBookmarkItem().getId());
+        assertEquals(1, result.size());
+        assertEquals(URL_BOOKMARK_ID_B, result.get(0).getBookmarkItem().getId());
     }
 
     @Test
@@ -78,13 +78,13 @@
         List<BookmarkListEntry> result =
                 mHandler.buildBookmarkListForParent(READING_LIST_BOOKMARK_ID);
 
-        Assert.assertEquals(4, result.size());
+        assertEquals(4, result.size());
         // While the getChildIds call will return [D, E], due to the read status, they should get
         // flipped around to show the unread E first. Headers will also be inserted.
-        Assert.assertEquals(ViewType.SECTION_HEADER, result.get(0).getViewType());
-        Assert.assertEquals(URL_BOOKMARK_ID_E, result.get(1).getBookmarkItem().getId());
-        Assert.assertEquals(ViewType.SECTION_HEADER, result.get(2).getViewType());
-        Assert.assertEquals(URL_BOOKMARK_ID_D, result.get(3).getBookmarkItem().getId());
+        assertEquals(ViewType.SECTION_HEADER, result.get(0).getViewType());
+        assertEquals(URL_BOOKMARK_ID_E, result.get(1).getBookmarkItem().getId());
+        assertEquals(ViewType.SECTION_HEADER, result.get(2).getViewType());
+        assertEquals(URL_BOOKMARK_ID_D, result.get(3).getBookmarkItem().getId());
     }
 
     @Test
@@ -93,6 +93,6 @@
                 .when(mBookmarkModel)
                 .searchBookmarks("A", 500);
         List<BookmarkListEntry> result = mHandler.buildBookmarkListForSearch("A");
-        Assert.assertEquals(2, result.size());
+        assertEquals(2, result.size());
     }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinatorTest.java
index d1f1407..45508810 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinatorTest.java
@@ -4,13 +4,14 @@
 
 package org.chromium.chrome.browser.bookmarks;
 
+import static org.junit.Assert.assertNotNull;
+
 import android.app.Activity;
 import android.view.View;
 import android.widget.FrameLayout;
 
 import androidx.test.ext.junit.rules.ActivityScenarioRule;
 
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -42,7 +43,7 @@
 import org.chromium.ui.base.DeviceFormFactor;
 import org.chromium.ui.base.TestActivity;
 
-/** Unit tests for BookmarkManagerCoordinator. */
+/** Unit tests for {@link BookmarkManagerCoordinator}. */
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
 @CommandLineFlags.
@@ -79,8 +80,6 @@
     BookmarkModel mBookmarkModel;
     @Mock
     BookmarkUiPrefs mBookmarkUiPrefs;
-    @Mock
-    View mView;
 
     private Activity mActivity;
     private BookmarkManagerCoordinator mCoordinator;
@@ -112,23 +111,23 @@
     public void testGetView() {
         View mainView = mCoordinator.getView();
 
-        Assert.assertNotNull(mainView);
-        Assert.assertNotNull(mainView.findViewById(R.id.selectable_list));
-        Assert.assertNotNull(mainView.findViewById(R.id.action_bar));
+        assertNotNull(mainView);
+        assertNotNull(mainView.findViewById(R.id.selectable_list));
+        assertNotNull(mainView.findViewById(R.id.action_bar));
     }
 
     @Test
     public void testCreateView() {
         FrameLayout parent = new FrameLayout(mActivity);
-        Assert.assertNotNull(mCoordinator.buildPersonalizedPromoView(parent));
-        Assert.assertNotNull(mCoordinator.buildLegacyPromoView(parent));
-        Assert.assertNotNull(BookmarkManagerCoordinator.buildSectionHeaderView(parent));
-        Assert.assertNotNull(mCoordinator.buildAndInitBookmarkFolderView(parent));
-        Assert.assertNotNull(mCoordinator.buildAndInitBookmarkItemRow(parent));
-        Assert.assertNotNull(mCoordinator.buildAndInitShoppingItemView(parent));
-        Assert.assertNotNull(BookmarkManagerCoordinator.buildDividerView(parent));
-        Assert.assertNotNull(BookmarkManagerCoordinator.buildShoppingFilterView(parent));
-        Assert.assertNotNull(mCoordinator.buildAndInitCompactImprovedBookmarkRow(parent));
-        Assert.assertNotNull(mCoordinator.buildAndInitVisualImprovedBookmarkRow(parent));
+        assertNotNull(mCoordinator.buildPersonalizedPromoView(parent));
+        assertNotNull(mCoordinator.buildLegacyPromoView(parent));
+        assertNotNull(BookmarkManagerCoordinator.buildSectionHeaderView(parent));
+        assertNotNull(mCoordinator.buildAndInitBookmarkFolderView(parent));
+        assertNotNull(mCoordinator.buildAndInitBookmarkItemRow(parent));
+        assertNotNull(mCoordinator.buildAndInitShoppingItemView(parent));
+        assertNotNull(BookmarkManagerCoordinator.buildDividerView(parent));
+        assertNotNull(BookmarkManagerCoordinator.buildShoppingFilterView(parent));
+        assertNotNull(mCoordinator.buildAndInitCompactImprovedBookmarkRow(parent));
+        assertNotNull(mCoordinator.buildAndInitVisualImprovedBookmarkRow(parent));
     }
 }
\ No newline at end of file
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java
index 84221a1..b2ade61 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java
@@ -422,14 +422,9 @@
         assertEquals(2, mModelList.size());
 
         doReturn(Arrays.asList(mFolderId3)).when(mBookmarkModel).getChildIds(mFolderId1);
-        verify(mBookmarkModel, times(2))
-                .addObserver(mBookmarkModelObserverArgumentCaptor.capture());
-        for (BookmarkModelObserver bookmarkModelObserver :
-                mBookmarkModelObserverArgumentCaptor.getAllValues()) {
-            bookmarkModelObserver.bookmarkNodeRemoved(
-                    mFolderItem1, 0, mFolderItem2, /*isDoingExtensiveChanges*/ false);
-        }
-
+        verify(mBookmarkModel).addObserver(mBookmarkModelObserverArgumentCaptor.capture());
+        mBookmarkModelObserverArgumentCaptor.getValue().bookmarkNodeRemoved(
+                mFolderItem1, 0, mFolderItem2, /*isDoingExtensiveChanges*/ false);
         assertEquals(1, mModelList.size());
     }
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkQueryHandlerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkQueryHandlerTest.java
index 965abdd5..65024020 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkQueryHandlerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkQueryHandlerTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.chrome.browser.bookmarks;
 
+import static org.junit.Assert.assertEquals;
+
 import static org.chromium.chrome.browser.bookmarks.SharedBookmarkModelMocks.DESKTOP_BOOKMARK_ID;
 import static org.chromium.chrome.browser.bookmarks.SharedBookmarkModelMocks.FOLDER_BOOKMARK_ID_A;
 import static org.chromium.chrome.browser.bookmarks.SharedBookmarkModelMocks.READING_LIST_BOOKMARK_ID;
@@ -12,7 +14,6 @@
 import static org.chromium.chrome.browser.bookmarks.SharedBookmarkModelMocks.URL_BOOKMARK_ID_D;
 import static org.chromium.chrome.browser.bookmarks.SharedBookmarkModelMocks.URL_BOOKMARK_ID_E;
 
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -30,7 +31,7 @@
 
 import java.util.List;
 
-/** Unit tests for {@link ImprovedmHandler}. */
+/** Unit tests for {@link ImprovedBookmarkQueryHandler}. */
 @Batch(Batch.UNIT_TESTS)
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
@@ -61,12 +62,12 @@
     @Test
     public void testBuildBookmarkListForParent_rootFolder() {
         List<BookmarkListEntry> result = mHandler.buildBookmarkListForParent(ROOT_BOOKMARK_ID);
-        Assert.assertEquals(6, result.size());
-        Assert.assertEquals(DESKTOP_BOOKMARK_ID, result.get(0).getBookmarkItem().getId());
-        Assert.assertEquals(FOLDER_BOOKMARK_ID_A, result.get(1).getBookmarkItem().getId());
-        Assert.assertEquals(READING_LIST_BOOKMARK_ID, result.get(2).getBookmarkItem().getId());
-        Assert.assertEquals(URL_BOOKMARK_ID_A, result.get(3).getBookmarkItem().getId());
-        Assert.assertEquals(URL_BOOKMARK_ID_D, result.get(4).getBookmarkItem().getId());
-        Assert.assertEquals(URL_BOOKMARK_ID_E, result.get(5).getBookmarkItem().getId());
+        assertEquals(6, result.size());
+        assertEquals(DESKTOP_BOOKMARK_ID, result.get(0).getBookmarkItem().getId());
+        assertEquals(FOLDER_BOOKMARK_ID_A, result.get(1).getBookmarkItem().getId());
+        assertEquals(READING_LIST_BOOKMARK_ID, result.get(2).getBookmarkItem().getId());
+        assertEquals(URL_BOOKMARK_ID_A, result.get(3).getBookmarkItem().getId());
+        assertEquals(URL_BOOKMARK_ID_D, result.get(4).getBookmarkItem().getId());
+        assertEquals(URL_BOOKMARK_ID_E, result.get(5).getBookmarkItem().getId());
     }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/LegacyBookmarkQueryHandlerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/LegacyBookmarkQueryHandlerTest.java
index 68669b78..d3320650 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/LegacyBookmarkQueryHandlerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/LegacyBookmarkQueryHandlerTest.java
@@ -47,7 +47,7 @@
 import java.util.Arrays;
 import java.util.List;
 
-/** Unit tests for {@link LegacymHandler}. */
+/** Unit tests for {@link LegacyBookmarkQueryHandler}. */
 @Batch(Batch.UNIT_TESTS)
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index cb8db8d..cd728eed 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -7537,6 +7537,9 @@
       <message name="IDS_SIDE_PANEL_COMPANION_TOOLBAR_TOOLTIP" desc="The tooltip for the companion feature toolbar button.">
         Google Search side panel
       </message>
+      <message name="IDS_SIDE_PANEL_COMPANION_PROMO" desc="Text shown on promotional UI appearing next to the pinned companion button, which excourages users to try the feature.">
+        Get additional useful info as you explore this page
+      </message>
       <message name="IDS_SIDE_PANEL_CUSTOMIZE_CHROME_TITLE" desc="The name of the Customize Chrome feature in the side panel combo box.">
         Customize Chrome
       </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 690f71a..69b89dc7 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -6792,10 +6792,15 @@
       "signin/bound_session_credentials/bound_session_cookie_refresh_service_factory.h",
       "signin/bound_session_credentials/bound_session_cookie_refresh_service_impl.cc",
       "signin/bound_session_credentials/bound_session_cookie_refresh_service_impl.h",
-      "signin/bound_session_credentials/bound_session_refresh_cookie_fetcher.cc",
       "signin/bound_session_credentials/bound_session_refresh_cookie_fetcher.h",
       "signin/bound_session_credentials/bound_session_request_throttled_listener_browser_impl.cc",
       "signin/bound_session_credentials/bound_session_request_throttled_listener_browser_impl.h",
+
+      # TODO(b/273920907): Move`fake_bound_session_refresh_cookie_fetcher.*`
+      # to test only once`bound_session_refresh_cookie_fetcher_impl.*` is
+      # implemented.
+      "signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher.cc",
+      "signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher.h",
       "signin/bound_session_credentials/registration_token_helper.cc",
       "signin/bound_session_credentials/registration_token_helper.h",
       "signin/bound_session_credentials/unexportable_key_service_factory.cc",
diff --git a/chrome/browser/accessibility/ax_screen_ai_annotator_factory.cc b/chrome/browser/accessibility/ax_screen_ai_annotator_factory.cc
index b5d2ebb..19e3f83 100644
--- a/chrome/browser/accessibility/ax_screen_ai_annotator_factory.cc
+++ b/chrome/browser/accessibility/ax_screen_ai_annotator_factory.cc
@@ -33,7 +33,12 @@
     : ProfileKeyedServiceFactory(
           "AXScreenAIAnnotator",
           // Incognito profiles should use their own instance.
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 AXScreenAIAnnotatorFactory::~AXScreenAIAnnotatorFactory() = default;
 
diff --git a/chrome/browser/accessibility/pdf_ocr_controller_factory.cc b/chrome/browser/accessibility/pdf_ocr_controller_factory.cc
index 03f6a9aa..5045273 100644
--- a/chrome/browser/accessibility/pdf_ocr_controller_factory.cc
+++ b/chrome/browser/accessibility/pdf_ocr_controller_factory.cc
@@ -22,7 +22,12 @@
 PdfOcrControllerFactory::PdfOcrControllerFactory()
     : ProfileKeyedServiceFactory(
           "PdfOcrController",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 PdfOcrControllerFactory::~PdfOcrControllerFactory() = default;
 
diff --git a/chrome/browser/android/compositor/scene_layer/top_toolbar_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/top_toolbar_scene_layer.cc
index 923e2ec..a021294 100644
--- a/chrome/browser/android/compositor/scene_layer/top_toolbar_scene_layer.cc
+++ b/chrome/browser/android/compositor/scene_layer/top_toolbar_scene_layer.cc
@@ -6,10 +6,8 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_array.h"
-#include "base/feature_list.h"
 #include "cc/slim/solid_color_layer.h"
 #include "chrome/browser/android/compositor/layer/toolbar_layer.h"
-#include "chrome/browser/browser_features.h"
 #include "chrome/browser/ui/android/toolbar/jni_headers/TopToolbarSceneLayer_jni.h"
 #include "ui/android/resources/resource_manager_impl.h"
 #include "ui/gfx/android/java_bitmap.h"
@@ -44,10 +42,10 @@
     bool show_shadow,
     bool visible,
     bool anonymize) {
-  ui::ResourceManager* resource_manager =
-      ui::ResourceManagerImpl::FromJavaObject(jresource_manager);
   // If the toolbar layer has not been created yet, create it.
   if (!toolbar_layer_) {
+    ui::ResourceManager* resource_manager =
+        ui::ResourceManagerImpl::FromJavaObject(jresource_manager);
     toolbar_layer_ = ToolbarLayer::Create(resource_manager);
     toolbar_layer_->layer()->SetHideLayerAndSubtree(true);
     layer_->AddChild(toolbar_layer_->layer());
@@ -55,12 +53,6 @@
 
   toolbar_layer_->layer()->SetHideLayerAndSubtree(!visible);
   if (!visible) {
-    if (base::FeatureList::IsEnabled(features::kKeepToolbarTexture)) {
-      // Uploading the Toolbar texture on scroll is a source of jank, and the
-      // toolbar becomes visible frequently enough for it to be worth holding
-      // onto the texture even when not visible.
-      resource_manager->MarkTintNonDiscardable(url_bar_color);
-    }
     return;
   }
 
diff --git a/chrome/browser/app_controller_mac.h b/chrome/browser/app_controller_mac.h
index 47bb86c8..6b8be9d2 100644
--- a/chrome/browser/app_controller_mac.h
+++ b/chrome/browser/app_controller_mac.h
@@ -75,7 +75,7 @@
   // pointer to a BookmarkMenuBridge for each profile. |bookmarkMenuBridge_| is
   // a weak pointer that is updated to match the corresponding cache entry
   // during a profile switch.
-  raw_ptr<BookmarkMenuBridge> _bookmarkMenuBridge;
+  raw_ptr<BookmarkMenuBridge, DanglingUntriaged> _bookmarkMenuBridge;
   std::map<base::FilePath, std::unique_ptr<BookmarkMenuBridge>>
       _profileBookmarkMenuBridgeMap;
 
diff --git a/chrome/browser/apps/platform_apps/api/media_galleries/blob_data_source_factory.h b/chrome/browser/apps/platform_apps/api/media_galleries/blob_data_source_factory.h
index 8498a4a8..b4c0a8d 100644
--- a/chrome/browser/apps/platform_apps/api/media_galleries/blob_data_source_factory.h
+++ b/chrome/browser/apps/platform_apps/api/media_galleries/blob_data_source_factory.h
@@ -37,7 +37,7 @@
       mojo::PendingReceiver<chrome::mojom::MediaDataSource> receiver,
       MediaDataCallback media_data_callback) override;
 
-  raw_ptr<content::BrowserContext> browser_context_;
+  raw_ptr<content::BrowserContext, DanglingUntriaged> browser_context_;
   std::string blob_uuid_;
   MediaDataCallback callback_;
 };
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index 342182c..192f4a7 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -613,6 +613,8 @@
     "arc/vmm/arc_vmm_manager.h",
     "arc/vmm/arc_vmm_swap_scheduler.cc",
     "arc/vmm/arc_vmm_swap_scheduler.h",
+    "arc/vmm/arcvm_working_set_trim_executor.cc",
+    "arc/vmm/arcvm_working_set_trim_executor.h",
     "arc/wallpaper/arc_wallpaper_service.cc",
     "arc/wallpaper/arc_wallpaper_service.h",
     "arc/window_predictor/arc_predictor_app_launch_handler.cc",
diff --git a/chrome/browser/ash/app_mode/app_launch_utils.cc b/chrome/browser/ash/app_mode/app_launch_utils.cc
index 6fd09f6..d43aa591 100644
--- a/chrome/browser/ash/app_mode/app_launch_utils.cc
+++ b/chrome/browser/ash/app_mode/app_launch_utils.cc
@@ -118,7 +118,7 @@
   }
 
   const KioskAppId kiosk_app_id_;
-  const raw_ptr<Profile> profile_;
+  const raw_ptr<Profile, DanglingUntriaged> profile_;
   const bool should_start_app_session_ash_;
 
   std::unique_ptr<app_mode::LacrosLauncher> lacros_launcher_;
diff --git a/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service.cc b/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service.cc
index fe9fde7..33bc9ff7 100644
--- a/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service.cc
+++ b/chrome/browser/ash/arc/enterprise/cert_store/cert_store_service.cc
@@ -71,7 +71,12 @@
   CertStoreServiceFactory()
       : ProfileKeyedServiceFactory(
             "CertStoreService",
-            ProfileSelections::BuildForRegularAndIncognito()) {
+            ProfileSelections::Builder()
+                .WithRegular(ProfileSelection::kOwnInstance)
+                // TODO(crbug.com/1418376): Check if this service is needed in
+                // Guest mode.
+                .WithGuest(ProfileSelection::kOwnInstance)
+                .Build()) {
     DependsOn(NssServiceFactory::GetInstance());
   }
 
diff --git a/chrome/browser/ash/arc/vmm/arcvm_working_set_trim_executor.cc b/chrome/browser/ash/arc/vmm/arcvm_working_set_trim_executor.cc
new file mode 100644
index 0000000..32a1399
--- /dev/null
+++ b/chrome/browser/ash/arc/vmm/arcvm_working_set_trim_executor.cc
@@ -0,0 +1,147 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/arc/vmm/arcvm_working_set_trim_executor.h"
+
+#include "ash/components/arc/arc_features.h"
+#include "ash/components/arc/memory/arc_memory_bridge.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
+#include "chrome/browser/ash/arc/session/arc_session_manager.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace arc {
+
+namespace {
+constexpr char BROWSER_CONTEXT_ERROR_MSG[] = "BrowserContext unavailable";
+}
+
+void ArcVmWorkingSetTrimExecutor::Trim(content::BrowserContext* context,
+                                       ResultCallback callback,
+                                       ArcVmReclaimType reclaim_type,
+                                       int page_limit) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  DCHECK_NE(ArcVmReclaimType::kReclaimNone, reclaim_type);
+  const char* error = nullptr;
+
+  // Before trimming, drop ARCVM's page caches.
+  if (!context) {
+    error = BROWSER_CONTEXT_ERROR_MSG;
+  }
+
+  auto* bridge =
+      context ? arc::ArcMemoryBridge::GetForBrowserContext(context) : nullptr;
+  if (!bridge) {
+    error = "ArcMemoryBridge unavailable";
+  }
+
+  if (error) {
+    LOG(ERROR) << error;
+    if (reclaim_type == ArcVmReclaimType::kReclaimGuestPageCaches) {
+      // Failed to drop caches. When the type if kReclaimGuestPageCaches, run
+      // the |callback| now with the |error| message. No further action is
+      // necessary.
+      std::move(callback).Run(false, error);
+    } else {
+      // Otherwise, continue without dropping them.
+      OnDropArcVmCaches(context, std::move(callback), reclaim_type, page_limit,
+                        /*result=*/false);
+    }
+    return;
+  }
+
+  bridge->DropCaches(
+      base::BindOnce(&ArcVmWorkingSetTrimExecutor::OnDropArcVmCaches, context,
+                     std::move(callback), reclaim_type, page_limit));
+}
+
+void ArcVmWorkingSetTrimExecutor::OnDropArcVmCaches(
+    content::BrowserContext* context,
+    ResultCallback callback,
+    ArcVmReclaimType reclaim_type,
+    int page_limit,
+    bool result) {
+  constexpr const char kErrorMessage[] =
+      "Failed to drop ARCVM's guest page caches";
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  LOG_IF(WARNING, !result) << kErrorMessage;
+
+  if (reclaim_type == ArcVmReclaimType::kReclaimGuestPageCaches) {
+    // TrimVmMemory() is unnecessary. Just run the |callback| with the
+    // DropCaches() result.
+    std::move(callback).Run(result, result ? "" : kErrorMessage);
+    return;
+  }
+
+  // Do the actual VM trimming regardless of the |result|. When "ArcGuestZram"
+  // feature is enabled, guest memory is locked and should be reclaimed from
+  // guest through ArcMemoryBridge's reclaim API (if "guest_reclaim_enabled"
+  // param is enabled). Otherwise the memory should be reclaimed from host
+  // through ArcSessionManager's TrimVmMemory.
+  if (base::FeatureList::IsEnabled(arc::kGuestZram) &&
+      arc::kGuestReclaimEnabled.Get()) {
+    if (!context) {
+      LogErrorAndInvokeCallback(BROWSER_CONTEXT_ERROR_MSG, std::move(callback));
+      return;
+    }
+
+    auto* bridge =
+        context ? arc::ArcMemoryBridge::GetForBrowserContext(context) : nullptr;
+    if (!bridge) {
+      LogErrorAndInvokeCallback("ArcMemoryBridge unavailable",
+                                std::move(callback));
+      return;
+    }
+
+    auto reclaim_request = arc::mojom::ReclaimRequest::New(
+        arc::kGuestReclaimOnlyAnonymous.Get() ? arc::mojom::ReclaimType::ANON
+                                              : arc::mojom::ReclaimType::ALL);
+    bridge->Reclaim(
+        std::move(reclaim_request),
+        base::BindOnce(&ArcVmWorkingSetTrimExecutor::OnArcVmMemoryGuestReclaim,
+                       std::make_unique<base::ElapsedTimer>(),
+                       std::move(callback)));
+  } else {
+    arc::ArcSessionManager* arc_session_manager = arc::ArcSessionManager::Get();
+    if (!arc_session_manager) {
+      LogErrorAndInvokeCallback("ArcSessionManager unavailable",
+                                std::move(callback));
+      return;
+    }
+
+    arc_session_manager->TrimVmMemory(std::move(callback), page_limit);
+  }
+}
+
+void ArcVmWorkingSetTrimExecutor::OnArcVmMemoryGuestReclaim(
+    std::unique_ptr<base::ElapsedTimer> elapsed_timer,
+    ResultCallback callback,
+    arc::mojom::ReclaimResultPtr result) {
+  VLOG(2) << "Finished trimming memory from guest. " << result->reclaimed
+          << " processes were reclaimed successfully. " << result->unreclaimed
+          << " processes were not reclaimed.";
+  base::UmaHistogramBoolean("Arc.GuestZram.SuccessfulReclaim",
+                            (result->reclaimed > 0));
+  if (result->reclaimed == 0) {
+    std::move(callback).Run(false, "No guest process was reclaimed");
+  } else {
+    base::UmaHistogramCounts1000("Arc.GuestZram.ReclaimedProcess",
+                                 result->reclaimed);
+    base::UmaHistogramCounts1000("Arc.GuestZram.UnreclaimedProcess",
+                                 result->unreclaimed);
+    base::UmaHistogramMediumTimes("Arc.GuestZram.TotalReclaimTime",
+                                  elapsed_timer->Elapsed());
+    std::move(callback).Run(true, "");
+  }
+}
+
+void ArcVmWorkingSetTrimExecutor::LogErrorAndInvokeCallback(
+    const char* error,
+    ResultCallback callback) {
+  LOG(ERROR) << error;
+  std::move(callback).Run(false, error);
+}
+
+}  // namespace arc
diff --git a/chrome/browser/ash/arc/vmm/arcvm_working_set_trim_executor.h b/chrome/browser/ash/arc/vmm/arcvm_working_set_trim_executor.h
new file mode 100644
index 0000000..9867f574
--- /dev/null
+++ b/chrome/browser/ash/arc/vmm/arcvm_working_set_trim_executor.h
@@ -0,0 +1,58 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ASH_ARC_VMM_ARCVM_WORKING_SET_TRIM_EXECUTOR_H_
+#define CHROME_BROWSER_ASH_ARC_VMM_ARCVM_WORKING_SET_TRIM_EXECUTOR_H_
+
+#include <string>
+
+#include "ash/components/arc/mojom/memory.mojom-forward.h"
+#include "base/functional/callback_forward.h"
+#include "base/timer/elapsed_timer.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace arc {
+
+enum class ArcVmReclaimType {
+  kReclaimNone = 0,
+  kReclaimGuestPageCaches,
+  kReclaimAll,  // both guest page caches and shmem
+};
+
+class ArcVmWorkingSetTrimExecutor {
+ public:
+  using ResultCallback =
+      base::OnceCallback<void(bool result, const std::string& failure_reason)>;
+
+  // Asks vm_concierge to trim ARCVM's memory in the same way as TrimWorkingSet.
+  // |callback| is invoked upon completion.
+  // |page_limit| is the maximum number of pages to reclaim
+  //             (arc::ArcSession::kNoPageLimit for no limit)
+  // The function must be called on the UI thread.
+  static void Trim(content::BrowserContext* context,
+                   ResultCallback callback,
+                   ArcVmReclaimType reclaim_type,
+                   int page_limit);
+
+ private:
+  static void OnDropArcVmCaches(content::BrowserContext* context,
+                                ResultCallback callback,
+                                ArcVmReclaimType reclaim_type,
+                                int page_limit,
+                                bool result);
+
+  static void OnArcVmMemoryGuestReclaim(
+      std::unique_ptr<base::ElapsedTimer> elapsed_timer,
+      ResultCallback callback,
+      arc::mojom::ReclaimResultPtr result);
+
+  static void LogErrorAndInvokeCallback(const char* error,
+                                        ResultCallback callback);
+};
+}  // namespace arc
+
+#endif  // CHROME_BROWSER_ASH_ARC_VMM_ARCVM_WORKING_SET_TRIM_EXECUTOR_H_
diff --git a/chrome/browser/ash/extensions/file_manager/event_router_factory.cc b/chrome/browser/ash/extensions/file_manager/event_router_factory.cc
index 8857fa1e..257d163 100644
--- a/chrome/browser/ash/extensions/file_manager/event_router_factory.cc
+++ b/chrome/browser/ash/extensions/file_manager/event_router_factory.cc
@@ -32,7 +32,12 @@
     : ProfileKeyedServiceFactory(
           "EventRouter",
           // Explicitly and always allow this router in guest login mode.
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(drive::DriveIntegrationServiceFactory::GetInstance());
   DependsOn(extensions::EventRouterFactory::GetInstance());
   DependsOn(
diff --git a/chrome/browser/ash/extensions/speech/speech_recognition_private_manager.cc b/chrome/browser/ash/extensions/speech/speech_recognition_private_manager.cc
index 7b60266..e071d51 100644
--- a/chrome/browser/ash/extensions/speech/speech_recognition_private_manager.cc
+++ b/chrome/browser/ash/extensions/speech/speech_recognition_private_manager.cc
@@ -91,7 +91,12 @@
           "SpeechRecognitionApiManager",
           // Incognito profiles should use their own instance of the browser
           // context.
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(EventRouterFactory::GetInstance());
 }
 
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest.cc b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
index 79f291e9..d6e0ce2 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
@@ -1336,8 +1336,11 @@
             .EnableBulkPinning(),
         TestCase("toolbarCloudIconWhenPressedShouldOpenCloudPanel")
             .EnableBulkPinning(),
+// TODO(https://crbug.com/1444076): Flaky on linux-chromeos-rel
+#if !BUILDFLAG(IS_CHROMEOS)
         TestCase("toolbarCloudIconShouldNotShowWhenPrefDisabled")
             .EnableBulkPinning(),
+#endif
         TestCase("toolbarCloudIconShouldShowOnStartupEvenIfSyncing")
             .EnableBulkPinning(),
         TestCase("toolbarCloudIconShouldShowWhenPausedState")
diff --git a/chrome/browser/ash/file_manager/volume_manager_factory.cc b/chrome/browser/ash/file_manager/volume_manager_factory.cc
index 343dd506..54b705d 100644
--- a/chrome/browser/ash/file_manager/volume_manager_factory.cc
+++ b/chrome/browser/ash/file_manager/volume_manager_factory.cc
@@ -51,7 +51,12 @@
     : ProfileKeyedServiceFactory(
           "VolumeManagerFactory",
           // Explicitly allow this manager in guest login mode.
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(drive::DriveIntegrationServiceFactory::GetInstance());
   DependsOn(ash::file_system_provider::ServiceFactory::GetInstance());
 }
diff --git a/chrome/browser/ash/file_suggest/file_suggest_keyed_service_factory.cc b/chrome/browser/ash/file_suggest/file_suggest_keyed_service_factory.cc
index 350c9949..4db3d36 100644
--- a/chrome/browser/ash/file_suggest/file_suggest_keyed_service_factory.cc
+++ b/chrome/browser/ash/file_suggest/file_suggest_keyed_service_factory.cc
@@ -21,7 +21,12 @@
 FileSuggestKeyedServiceFactory::FileSuggestKeyedServiceFactory()
     : ProfileKeyedServiceFactory(
           "FileSuggestKeyedService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(drive::DriveIntegrationServiceFactory::GetInstance());
   DependsOn(file_manager::file_tasks::FileTasksNotifierFactory::GetInstance());
 }
diff --git a/chrome/browser/ash/login/app_mode/test/chome_app_kiosk_lacros_browsertest.cc b/chrome/browser/ash/login/app_mode/test/chome_app_kiosk_lacros_browsertest.cc
new file mode 100644
index 0000000..16622ed
--- /dev/null
+++ b/chrome/browser/ash/login/app_mode/test/chome_app_kiosk_lacros_browsertest.cc
@@ -0,0 +1,62 @@
+// Copyright 2023 The Chromium Authors
+// 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/app_mode/test/kiosk_ash_browser_test_starter.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_base_test.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h"
+#include "chrome/browser/ash/login/app_mode/test/new_aura_window_watcher.h"
+#include "content/public/test/browser_test.h"
+
+namespace ash {
+
+namespace {
+
+// The default kiosk app from `KioskBaseTest` uses `chrome.test` API which does
+// not exist in Ash+Lacros tests. Chrome App Kiosk Ash+Lacros browser tests
+// should use Kiosk Base Test App.
+const char kKioskBaseTestAppId[] = "epancfbahpnkphlhpeefecinmgclhjlj";
+
+}  // namespace
+
+// Tests Ash-side of the chrome app kiosk when Lacros is enabled.
+// To run these tests with pixel output, add
+// `--lacros-chrome-additional-args=--gpu-sandbox-start-early` flag.
+class ChromeAppKioskLacrosTest : public KioskBaseTest {
+ public:
+  void SetUpInProcessBrowserTestFixture() override {
+    if (kiosk_ash_starter_.HasLacrosArgument()) {
+      kiosk_ash_starter_.PrepareEnvironmentForKioskLacros();
+    }
+    KioskBaseTest::SetUpInProcessBrowserTestFixture();
+  }
+
+  void SetUpOnMainThread() override {
+    SetTestApp(kKioskBaseTestAppId);
+
+    KioskBaseTest::SetUpOnMainThread();
+    if (kiosk_ash_starter_.HasLacrosArgument()) {
+      kiosk_ash_starter_.SetLacrosAvailabilityPolicy();
+    }
+  }
+
+ protected:
+  KioskAshBrowserTestStarter kiosk_ash_starter_;
+};
+
+IN_PROC_BROWSER_TEST_F(ChromeAppKioskLacrosTest, RegularOnlineKiosk) {
+  if (!kiosk_ash_starter_.HasLacrosArgument()) {
+    return;
+  }
+  NewAuraWindowWatcher watcher;
+  StartAppLaunchFromLoginScreen(
+      NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE);
+
+  aura::Window* window = watcher.WaitForWindow();
+  KioskSessionInitializedWaiter().Wait();
+
+  EXPECT_TRUE(crosapi::browser_util::IsLacrosWindow(window));
+  EXPECT_TRUE(crosapi::BrowserManager::Get()->IsRunning());
+}
+
+}  // namespace ash
diff --git a/chrome/browser/ash/login/app_mode/test/kiosk_base_test.cc b/chrome/browser/ash/login/app_mode/test/kiosk_base_test.cc
index 9c370e0..938c940 100644
--- a/chrome/browser/ash/login/app_mode/test/kiosk_base_test.cc
+++ b/chrome/browser/ash/login/app_mode/test/kiosk_base_test.cc
@@ -372,4 +372,12 @@
   }
 }
 
+void KioskBaseTest::SetTestApp(const std::string& app_id,
+                               const std::string& crx_file,
+                               const std::string& version) {
+  test_app_id_ = app_id;
+  test_crx_file_ = (crx_file == "") ? app_id + ".crx" : crx_file;
+  test_app_version_ = version;
+}
+
 }  // namespace ash
diff --git a/chrome/browser/ash/login/app_mode/test/kiosk_base_test.h b/chrome/browser/ash/login/app_mode/test/kiosk_base_test.h
index ee203db6..0841a8b6 100644
--- a/chrome/browser/ash/login/app_mode/test/kiosk_base_test.h
+++ b/chrome/browser/ash/login/app_mode/test/kiosk_base_test.h
@@ -119,6 +119,13 @@
 
   void BlockAppLaunch(bool block);
 
+  // TODO(b/280777751): update usages of `set_test_app_id` with
+  // `SetTestApp`.
+  // If `crx_file` is empty string, sets `test_crx_file_` to `app_id` + ".crx".
+  void SetTestApp(const std::string& app_id,
+                  const std::string& crx_file = "",
+                  const std::string& version = "1.0.0");
+
   void set_test_app_id(const std::string& test_app_id) {
     test_app_id_ = test_app_id;
   }
diff --git a/chrome/browser/ash/login/helper.cc b/chrome/browser/ash/login/helper.cc
index 9dbc4fd..b2e399f 100644
--- a/chrome/browser/ash/login/helper.cc
+++ b/chrome/browser/ash/login/helper.cc
@@ -36,9 +36,9 @@
 #include "services/network/public/mojom/network_context.mojom.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_scale_factor.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
-#include "ui/gfx/image/image_skia.h"
 
 namespace ash {
 
@@ -59,7 +59,8 @@
   float scale_factor = display::Display::GetForcedDeviceScaleFactor();
   if (scale_factor > 1.0f)
     return static_cast<int>(scale_factor * kBaseUserImageSize);
-  return kBaseUserImageSize * gfx::ImageSkia::GetMaxSupportedScale();
+  const float max_scale = ui::GetScaleForMaxSupportedResourceScaleFactor();
+  return kBaseUserImageSize * max_scale;
 }
 
 namespace login {
diff --git a/chrome/browser/ash/login/signin_partition_manager.cc b/chrome/browser/ash/login/signin_partition_manager.cc
index 7040a23f..ab4fdad 100644
--- a/chrome/browser/ash/login/signin_partition_manager.cc
+++ b/chrome/browser/ash/login/signin_partition_manager.cc
@@ -158,7 +158,12 @@
 SigninPartitionManager::Factory::Factory()
     : ProfileKeyedServiceFactory(
           "SigninPartitionManager",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 SigninPartitionManager::Factory::~Factory() = default;
 
diff --git a/chrome/browser/ash/nearby/nearby_dependencies_provider_factory.cc b/chrome/browser/ash/nearby/nearby_dependencies_provider_factory.cc
index ba1193a7..3ecdbe9 100644
--- a/chrome/browser/ash/nearby/nearby_dependencies_provider_factory.cc
+++ b/chrome/browser/ash/nearby/nearby_dependencies_provider_factory.cc
@@ -17,7 +17,12 @@
   // This needs to be overridden because the default implementation returns
   // nullptr for OTR profiles, which would prevent using this with Quick Start.
   if (features::IsOobeQuickStartEnabled()) {
-    return ProfileSelections::BuildForRegularAndIncognito();
+    return ProfileSelections::Builder()
+        .WithRegular(ProfileSelection::kOwnInstance)
+        // TODO(crbug.com/1418376): Check if this service is needed in
+        // Guest mode.
+        .WithGuest(ProfileSelection::kOwnInstance)
+        .Build();
   }
 
   return ProfileSelections::Builder()
diff --git a/chrome/browser/ash/nearby/quick_start_connectivity_service_factory.cc b/chrome/browser/ash/nearby/quick_start_connectivity_service_factory.cc
index 96b4adb..6d55e5f 100644
--- a/chrome/browser/ash/nearby/quick_start_connectivity_service_factory.cc
+++ b/chrome/browser/ash/nearby/quick_start_connectivity_service_factory.cc
@@ -26,7 +26,12 @@
 QuickStartConnectivityServiceFactory::QuickStartConnectivityServiceFactory()
     : ProfileKeyedServiceFactory(
           "QuickStartConnectivityService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(nearby::NearbyProcessManagerFactory::GetInstance());
 }
 
diff --git a/chrome/browser/ash/notifications/multi_capture_login_notification.cc b/chrome/browser/ash/notifications/multi_capture_login_notification.cc
index d3b0dfa..4222403 100644
--- a/chrome/browser/ash/notifications/multi_capture_login_notification.cc
+++ b/chrome/browser/ash/notifications/multi_capture_login_notification.cc
@@ -42,8 +42,7 @@
   if (!browser_context) {
     return false;
   }
-  return capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowedForAnySite(
-      browser_context);
+  return capture_policy::IsGetAllScreensMediaAllowedForAnySite(browser_context);
 }
 
 void CreateAndShowNotification(bool is_multi_capture_allowed) {
diff --git a/chrome/browser/ash/notifications/multi_capture_notification.h b/chrome/browser/ash/notifications/multi_capture_notification.h
index 6770a03f..36ffaac 100644
--- a/chrome/browser/ash/notifications/multi_capture_notification.h
+++ b/chrome/browser/ash/notifications/multi_capture_notification.h
@@ -23,7 +23,7 @@
 
 // MultiCaptureNotification manages the notification informing the user of
 // automatic multi captures being started. On managed devices, administrators
-// can enforce automatic capturing by using the getDisplayMediaSet API.
+// can enforce automatic capturing by using the getAllScreensMedia API.
 // Users are notified to make sure their privacy is respected.
 class MultiCaptureNotification : public MultiCaptureServiceClient::Observer {
  public:
diff --git a/chrome/browser/ash/policy/dlp/dlp_files_controller_ash_browsertest.cc b/chrome/browser/ash/policy/dlp/dlp_files_controller_ash_browsertest.cc
index 0d4827cd..53bdf6f 100644
--- a/chrome/browser/ash/policy/dlp/dlp_files_controller_ash_browsertest.cc
+++ b/chrome/browser/ash/policy/dlp/dlp_files_controller_ash_browsertest.cc
@@ -10,6 +10,7 @@
 #include "base/strings/string_piece_forward.h"
 #include "chrome/browser/ash/policy/dlp/dlp_files_controller_ash.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_file_destination.h"
+#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.h"
 #include "chrome/browser/chromeos/policy/dlp/mock_dlp_rules_manager.h"
 #include "chrome/browser/extensions/api/file_system/file_entry_picker.h"
@@ -223,4 +224,25 @@
   EXPECT_NE(files_controller_->GetWarnDialogForTesting(), nullptr);
 }
 
+// (b/281495499): This is a test for the crash that happens upon showing a
+// warning dialog for downloads.
+IN_PROC_BROWSER_TEST_F(DlpFilesControllerAshBrowserTest,
+                       WarningDialog_Download) {
+  EXPECT_CALL(*mock_rules_manager_, GetReportingManager);
+  EXPECT_CALL(*mock_rules_manager_,
+              IsRestrictedComponent(
+                  GURL(kExampleUrl), DlpRulesManager::Component::kDrive,
+                  DlpRulesManager::Restriction::kFiles, testing::_, testing::_))
+      .WillOnce(testing::Return(DlpRulesManager::Level::kWarn));
+
+  std::vector<DlpFilesControllerAsh::FileDaemonInfo> transferred_files;
+  transferred_files.emplace_back(1234, base::FilePath("file1.txt"),
+                                 kExampleUrl);
+  EXPECT_EQ(files_controller_->GetWarnDialogForTesting(), nullptr);
+  files_controller_->IsFilesTransferRestricted(
+      transferred_files, DlpFileDestination(DlpRulesManager::Component::kDrive),
+      DlpFilesControllerAsh::FileAction::kDownload, base::DoNothing());
+  EXPECT_NE(files_controller_->GetWarnDialogForTesting(), nullptr);
+}
+
 }  // namespace policy
diff --git a/chrome/browser/ash/printing/printer_event_tracker_factory.cc b/chrome/browser/ash/printing/printer_event_tracker_factory.cc
index 89b630af..7304528a6 100644
--- a/chrome/browser/ash/printing/printer_event_tracker_factory.cc
+++ b/chrome/browser/ash/printing/printer_event_tracker_factory.cc
@@ -31,7 +31,12 @@
 PrinterEventTrackerFactory::PrinterEventTrackerFactory()
     : ProfileKeyedServiceFactory(
           "PrinterEventTracker",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 PrinterEventTrackerFactory::~PrinterEventTrackerFactory() = default;
 
 void PrinterEventTrackerFactory::SetLogging(bool enabled) {
diff --git a/chrome/browser/autofill/autocomplete_history_manager_factory.cc b/chrome/browser/autofill/autocomplete_history_manager_factory.cc
index aca1257..a0cd4f6 100644
--- a/chrome/browser/autofill/autocomplete_history_manager_factory.cc
+++ b/chrome/browser/autofill/autocomplete_history_manager_factory.cc
@@ -28,7 +28,12 @@
 AutocompleteHistoryManagerFactory::AutocompleteHistoryManagerFactory()
     : ProfileKeyedServiceFactory(
           "AutocompleteHistoryManager",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(WebDataServiceFactory::GetInstance());
 }
 
diff --git a/chrome/browser/autofill/iban_manager_factory.cc b/chrome/browser/autofill/iban_manager_factory.cc
index f94b1630..a7502448 100644
--- a/chrome/browser/autofill/iban_manager_factory.cc
+++ b/chrome/browser/autofill/iban_manager_factory.cc
@@ -25,7 +25,12 @@
 IBANManagerFactory::IBANManagerFactory()
     : ProfileKeyedServiceFactory(
           "IBANManager",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(PersonalDataManagerFactory::GetInstance());
 }
 
diff --git a/chrome/browser/autofill/merchant_promo_code_manager_factory.cc b/chrome/browser/autofill/merchant_promo_code_manager_factory.cc
index 31eb8ec..43bdd9d9 100644
--- a/chrome/browser/autofill/merchant_promo_code_manager_factory.cc
+++ b/chrome/browser/autofill/merchant_promo_code_manager_factory.cc
@@ -27,7 +27,12 @@
 MerchantPromoCodeManagerFactory::MerchantPromoCodeManagerFactory()
     : ProfileKeyedServiceFactory(
           "MerchantPromoCodeManager",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(PersonalDataManagerFactory::GetInstance());
 }
 
diff --git a/chrome/browser/autofill/personal_data_manager_factory.cc b/chrome/browser/autofill/personal_data_manager_factory.cc
index 1a2b903..f7d3393e 100644
--- a/chrome/browser/autofill/personal_data_manager_factory.cc
+++ b/chrome/browser/autofill/personal_data_manager_factory.cc
@@ -58,7 +58,12 @@
 PersonalDataManagerFactory::PersonalDataManagerFactory()
     : ProfileKeyedServiceFactory(
           "PersonalDataManager",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(IdentityManagerFactory::GetInstance());
   DependsOn(HistoryServiceFactory::GetInstance());
   DependsOn(WebDataServiceFactory::GetInstance());
diff --git a/chrome/browser/background/background_contents_service_factory.cc b/chrome/browser/background/background_contents_service_factory.cc
index 1851c00..bf4e78d 100644
--- a/chrome/browser/background/background_contents_service_factory.cc
+++ b/chrome/browser/background/background_contents_service_factory.cc
@@ -31,7 +31,12 @@
 BackgroundContentsServiceFactory::BackgroundContentsServiceFactory()
     : ProfileKeyedServiceFactory(
           "BackgroundContentsService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(extensions::ExtensionRegistryFactory::GetInstance());
   DependsOn(extensions::ExtensionSystemFactory::GetInstance());
   DependsOn(extensions::ExtensionHostRegistry::GetFactory());
diff --git a/chrome/browser/background_fetch/background_fetch_delegate_factory.cc b/chrome/browser/background_fetch/background_fetch_delegate_factory.cc
index a900a822..72c640a2 100644
--- a/chrome/browser/background_fetch/background_fetch_delegate_factory.cc
+++ b/chrome/browser/background_fetch/background_fetch_delegate_factory.cc
@@ -28,7 +28,12 @@
 BackgroundFetchDelegateFactory::BackgroundFetchDelegateFactory()
     : ProfileKeyedServiceFactory(
           "BackgroundFetchService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(BackgroundDownloadServiceFactory::GetInstance());
   DependsOn(HostContentSettingsMapFactory::GetInstance());
   DependsOn(OfflineContentAggregatorFactory::GetInstance());
diff --git a/chrome/browser/background_sync/background_sync_controller_factory.cc b/chrome/browser/background_sync/background_sync_controller_factory.cc
index 527cae5..e8de786 100644
--- a/chrome/browser/background_sync/background_sync_controller_factory.cc
+++ b/chrome/browser/background_sync/background_sync_controller_factory.cc
@@ -26,7 +26,12 @@
 BackgroundSyncControllerFactory::BackgroundSyncControllerFactory()
     : ProfileKeyedServiceFactory(
           "BackgroundSyncService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(ukm::UkmBackgroundRecorderFactory::GetInstance());
   DependsOn(site_engagement::SiteEngagementServiceFactory::GetInstance());
 }
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc
index ff4be9a1..da329809 100644
--- a/chrome/browser/banners/app_banner_manager_browsertest.cc
+++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -220,14 +220,15 @@
  public:
   AppBannerManagerBrowserTest()
       : disable_banner_trigger_(&test::g_disable_banner_triggering_for_testing,
-                                true) {}
+                                true),
+        total_engagement_(
+            AppBannerSettingsHelper::ScopeTotalEngagementForTesting(10)) {}
 
   AppBannerManagerBrowserTest(const AppBannerManagerBrowserTest&) = delete;
   AppBannerManagerBrowserTest& operator=(const AppBannerManagerBrowserTest&) =
       delete;
 
   void SetUpOnMainThread() override {
-    AppBannerSettingsHelper::SetTotalEngagementToTrigger(10);
     site_engagement::SiteEngagementScore::SetParamValuesForTesting();
 
     AppBannerManagerBrowserTestBase::SetUpOnMainThread();
@@ -317,6 +318,7 @@
  private:
   // Disable the banners in the browser so it won't interfere with the test.
   base::AutoReset<bool> disable_banner_trigger_;
+  base::AutoReset<double> total_engagement_;
 };
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
@@ -580,7 +582,8 @@
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTest,
                        WebAppBannerNeedsEngagement) {
-  AppBannerSettingsHelper::SetTotalEngagementToTrigger(1);
+  base::AutoReset<double> scoped_engagement =
+      AppBannerSettingsHelper::ScopeTotalEngagementForTesting(1);
   std::unique_ptr<AppBannerManagerTest> manager(
       CreateAppBannerManager(browser()));
   base::HistogramTester histograms;
@@ -785,6 +788,9 @@
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerBrowserTestWithChromeBFCache,
                        VerifyBFCacheBehavior) {
+  base::AutoReset<double> scoped_engagement =
+      AppBannerSettingsHelper::ScopeTotalEngagementForTesting(1);
+
   ASSERT_TRUE(embedded_test_server()->Start());
   std::unique_ptr<AppBannerManagerTest> manager(
       CreateAppBannerManager(browser()));
diff --git a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
index c35ca8a..49cd6ca 100644
--- a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
+++ b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
@@ -6,6 +6,7 @@
 #include <string>
 #include <utility>
 
+#include "base/auto_reset.h"
 #include "base/functional/callback.h"
 #include "base/run_loop.h"
 #include "base/strings/strcat.h"
@@ -66,7 +67,9 @@
 class AppBannerManagerDesktopBrowserTest
     : public AppBannerManagerBrowserTestBase {
  public:
-  AppBannerManagerDesktopBrowserTest() = default;
+  AppBannerManagerDesktopBrowserTest()
+      : total_engagement_(
+            AppBannerSettingsHelper::ScopeTotalEngagementForTesting(0)) {}
 
   void SetUp() override {
     scoped_feature_list_.InitWithFeatures({}, GetDisabledFeatures());
@@ -75,8 +78,6 @@
   }
 
   void SetUpOnMainThread() override {
-    // Trigger banners instantly.
-    AppBannerSettingsHelper::SetTotalEngagementToTrigger(0);
     chrome::SetAutoAcceptPWAInstallConfirmationForTesting(true);
 
     AppBannerManagerBrowserTestBase::SetUpOnMainThread();
@@ -93,6 +94,8 @@
 
  protected:
   base::test::ScopedFeatureList scoped_feature_list_;
+  // Scope engagement needed to trigger banners instantly.
+  base::AutoReset<double> total_engagement_;
 };
 
 IN_PROC_BROWSER_TEST_F(AppBannerManagerDesktopBrowserTest,
diff --git a/chrome/browser/bluetooth/bluetooth_chooser_context_factory.cc b/chrome/browser/bluetooth/bluetooth_chooser_context_factory.cc
index ea30a64..c834ad1 100644
--- a/chrome/browser/bluetooth/bluetooth_chooser_context_factory.cc
+++ b/chrome/browser/bluetooth/bluetooth_chooser_context_factory.cc
@@ -32,7 +32,12 @@
 BluetoothChooserContextFactory::BluetoothChooserContextFactory()
     : ProfileKeyedServiceFactory(
           "BluetoothChooserContext",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
diff --git a/chrome/browser/breadcrumbs/breadcrumb_manager_keyed_service_factory.cc b/chrome/browser/breadcrumbs/breadcrumb_manager_keyed_service_factory.cc
index 0f8a423..9525438 100644
--- a/chrome/browser/breadcrumbs/breadcrumb_manager_keyed_service_factory.cc
+++ b/chrome/browser/breadcrumbs/breadcrumb_manager_keyed_service_factory.cc
@@ -26,7 +26,12 @@
 BreadcrumbManagerKeyedServiceFactory::BreadcrumbManagerKeyedServiceFactory()
     : ProfileKeyedServiceFactory(
           "BreadcrumbManagerService",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 BreadcrumbManagerKeyedServiceFactory::~BreadcrumbManagerKeyedServiceFactory() =
     default;
diff --git a/chrome/browser/browser_features.cc b/chrome/browser/browser_features.cc
index db082c32..b79d3f7 100644
--- a/chrome/browser/browser_features.cc
+++ b/chrome/browser/browser_features.cc
@@ -45,13 +45,6 @@
              "DevToolsTabTarget",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// Normally the toolbar texture is discarded when the toolbar is no longer
-// visible. This feature keeps the texture around so it does not need to get
-// re-uploaded when the toolbar becomes visible again.
-BASE_FEATURE(kKeepToolbarTexture,
-             "KeepToolbarTexture",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 // Nukes profile directory before creating a new profile using
 // ProfileManager::CreateMultiProfileAsync().
 BASE_FEATURE(kNukeProfileBeforeCreateMultiAsync,
diff --git a/chrome/browser/browser_features.h b/chrome/browser/browser_features.h
index d4c3989..65daffe 100644
--- a/chrome/browser/browser_features.h
+++ b/chrome/browser/browser_features.h
@@ -25,8 +25,6 @@
 
 BASE_DECLARE_FEATURE(kDevToolsTabTarget);
 
-BASE_DECLARE_FEATURE(kKeepToolbarTexture);
-
 BASE_DECLARE_FEATURE(kNukeProfileBeforeCreateMultiAsync);
 
 BASE_DECLARE_FEATURE(kPromoBrowserCommands);
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_factory.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_factory.cc
index bf06fd92..ea67b27 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_factory.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_factory.cc
@@ -54,7 +54,12 @@
     ChromeBrowsingDataRemoverDelegateFactory()
     : ProfileKeyedServiceFactory(
           "BrowsingDataRemover",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(autofill::PersonalDataManagerFactory::GetInstance());
 #if BUILDFLAG(IS_ANDROID)
 #if BUILDFLAG(ENABLE_FEED_V2)
diff --git a/chrome/browser/captive_portal/captive_portal_service_factory.cc b/chrome/browser/captive_portal/captive_portal_service_factory.cc
index 691631a..741cde2 100644
--- a/chrome/browser/captive_portal/captive_portal_service_factory.cc
+++ b/chrome/browser/captive_portal/captive_portal_service_factory.cc
@@ -22,7 +22,12 @@
 CaptivePortalServiceFactory::CaptivePortalServiceFactory()
     : ProfileKeyedServiceFactory(
           "captive_portal::CaptivePortalService",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 CaptivePortalServiceFactory::~CaptivePortalServiceFactory() {
 }
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index fe7dbc59..360065f2 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -2543,11 +2543,10 @@
 #endif
 }
 
-bool ChromeContentBrowserClient::IsGetDisplayMediaSetSelectAllScreensAllowed(
+bool ChromeContentBrowserClient::IsGetAllScreensMediaAllowed(
     content::BrowserContext* context,
     const url::Origin& origin) {
-  return capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowed(
-      context, origin.GetURL());
+  return capture_policy::IsGetAllScreensMediaAllowed(context, origin.GetURL());
 }
 
 bool ChromeContentBrowserClient::IsFileAccessAllowed(
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 633217c..6c2ecc5 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -248,9 +248,8 @@
       const GURL& url) override;
   bool IsIsolatedContextAllowedForUrl(content::BrowserContext* browser_context,
                                       const GURL& lock_url) override;
-  bool IsGetDisplayMediaSetSelectAllScreensAllowed(
-      content::BrowserContext* context,
-      const url::Origin& origin) override;
+  bool IsGetAllScreensMediaAllowed(content::BrowserContext* context,
+                                   const url::Origin& origin) override;
   bool IsFileAccessAllowed(const base::FilePath& path,
                            const base::FilePath& absolute_path,
                            const base::FilePath& profile_path) override;
diff --git a/chrome/browser/chromeos/extensions/login_screen/login/cleanup/cleanup_manager_lacros_factory.cc b/chrome/browser/chromeos/extensions/login_screen/login/cleanup/cleanup_manager_lacros_factory.cc
index 6a40f44..14229ba 100644
--- a/chrome/browser/chromeos/extensions/login_screen/login/cleanup/cleanup_manager_lacros_factory.cc
+++ b/chrome/browser/chromeos/extensions/login_screen/login/cleanup/cleanup_manager_lacros_factory.cc
@@ -27,7 +27,12 @@
     : ProfileKeyedServiceFactory(
           "CleanupManagerLacros",
           // Service is available for incognito profiles.
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 CleanupManagerLacrosFactory::~CleanupManagerLacrosFactory() = default;
 
diff --git a/chrome/browser/chromeos/policy/dlp/dialogs/files_policy_dialog.cc b/chrome/browser/chromeos/policy/dlp/dialogs/files_policy_dialog.cc
index 6ddd44b..99b2a972 100644
--- a/chrome/browser/chromeos/policy/dlp/dialogs/files_policy_dialog.cc
+++ b/chrome/browser/chromeos/policy/dlp/dialogs/files_policy_dialog.cc
@@ -101,7 +101,9 @@
 }
 
 void FilesPolicyDialog::MaybeAddConfidentialRows() {
-  DCHECK(!files_.empty());
+  if (files_.empty()) {
+    return;
+  }
 
   SetupScrollView();
   for (const DlpConfidentialFile& file : files_) {
@@ -172,10 +174,13 @@
   int message_id;
   switch (action_) {
     case DlpFilesController::FileAction::kDownload:
-      DCHECK(files_.size() == 1);
       destination_str = GetDestinationComponent(destination_);
-      message_id = IDS_POLICY_DLP_FILES_DOWNLOAD_WARN_MESSAGE;
-      break;
+      // Download action is only allowed for one file.
+      return base::ReplaceStringPlaceholders(
+          l10n_util::GetPluralStringFUTF16(
+              IDS_POLICY_DLP_FILES_DOWNLOAD_WARN_MESSAGE, 1),
+          destination_str,
+          /*offset=*/nullptr);
     case DlpFilesController::FileAction::kUpload:
       destination_str = GetDestinationURL(destination_);
       message_id = IDS_POLICY_DLP_FILES_UPLOAD_WARN_MESSAGE;
diff --git a/chrome/browser/client_hints/client_hints_factory.cc b/chrome/browser/client_hints/client_hints_factory.cc
index b685640..b1f7b40 100644
--- a/chrome/browser/client_hints/client_hints_factory.cc
+++ b/chrome/browser/client_hints/client_hints_factory.cc
@@ -35,7 +35,12 @@
 ClientHintsFactory::ClientHintsFactory()
     : ProfileKeyedServiceFactory(
           "ClientHints",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
   DependsOn(CookieSettingsFactory::GetInstance());
 }
diff --git a/chrome/browser/content_index/content_index_provider_factory.cc b/chrome/browser/content_index/content_index_provider_factory.cc
index 7793b7a..fda2c44 100644
--- a/chrome/browser/content_index/content_index_provider_factory.cc
+++ b/chrome/browser/content_index/content_index_provider_factory.cc
@@ -25,7 +25,12 @@
 ContentIndexProviderFactory::ContentIndexProviderFactory()
     : ProfileKeyedServiceFactory(
           "ContentIndexProvider",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(OfflineContentAggregatorFactory::GetInstance());
   DependsOn(ukm::UkmBackgroundRecorderFactory::GetInstance());
   DependsOn(site_engagement::SiteEngagementServiceFactory::GetInstance());
diff --git a/chrome/browser/content_settings/cookie_settings_factory.cc b/chrome/browser/content_settings/cookie_settings_factory.cc
index 39aa739..4c168f8 100644
--- a/chrome/browser/content_settings/cookie_settings_factory.cc
+++ b/chrome/browser/content_settings/cookie_settings_factory.cc
@@ -43,7 +43,12 @@
           "CookieSettings",
           // The incognito profile has its own content settings map. Therefore,
           // it should get its own CookieSettings.
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
diff --git a/chrome/browser/content_settings/host_content_settings_map_factory.cc b/chrome/browser/content_settings/host_content_settings_map_factory.cc
index 5e4d0b2..6bcdf281 100644
--- a/chrome/browser/content_settings/host_content_settings_map_factory.cc
+++ b/chrome/browser/content_settings/host_content_settings_map_factory.cc
@@ -53,7 +53,12 @@
 HostContentSettingsMapFactory::HostContentSettingsMapFactory()
     : RefcountedProfileKeyedServiceFactory(
           "HostContentSettingsMap",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
   DependsOn(SupervisedUserSettingsServiceFactory::GetInstance());
 #endif
diff --git a/chrome/browser/dips/dips_bounce_detector.cc b/chrome/browser/dips/dips_bounce_detector.cc
index d372383..baadeeb 100644
--- a/chrome/browser/dips/dips_bounce_detector.cc
+++ b/chrome/browser/dips/dips_bounce_detector.cc
@@ -26,6 +26,7 @@
 #include "chrome/browser/dips/dips_service.h"
 #include "chrome/browser/dips/dips_storage.h"
 #include "chrome/browser/dips/dips_utils.h"
+#include "components/content_settings/browser/page_specific_content_settings.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/cookie_access_details.h"
 #include "content/public/browser/navigation_handle.h"
@@ -78,7 +79,9 @@
 DIPSWebContentsObserver::DIPSWebContentsObserver(
     content::WebContents* web_contents,
     DIPSService* dips_service)
-    : content::WebContentsObserver(web_contents),
+    : content_settings::PageSpecificContentSettings::SiteDataObserver(
+          web_contents),
+      content::WebContentsObserver(web_contents),
       content::WebContentsUserData<DIPSWebContentsObserver>(*web_contents),
       dips_service_(dips_service),
       detector_(this,
@@ -86,42 +89,10 @@
                 base::DefaultClock::GetInstance()) {
   issue_reporting_callback_ = base::BindRepeating(
       &DIPSWebContentsObserver::EmitDIPSIssue, weak_factory_.GetWeakPtr());
-  dips_site_data_observer_ =
-      std::make_unique<DIPSSiteDataObserver>(web_contents, this);
 }
 
 DIPSWebContentsObserver::~DIPSWebContentsObserver() = default;
 
-DIPSWebContentsObserver::DIPSSiteDataObserver::DIPSSiteDataObserver(
-    content::WebContents* web_contents,
-    DIPSWebContentsObserver* dips_web_contents_observer)
-    : content_settings::PageSpecificContentSettings::SiteDataObserver(
-          web_contents),
-      dips_web_contents_observer_(dips_web_contents_observer) {}
-
-void DIPSWebContentsObserver::DIPSSiteDataObserver::OnSiteDataAccessed(
-    const content_settings::AccessDetails& access_details) {
-  // NOTE: The current implementation is only acting on all site data types
-  // collapsed under `content_settings::SiteDataType::kStorage` with the
-  // exception of WebLocks (not monitored by the
-  // `content_settings::PageSpecificContentSettings`) as it's not persistent.
-  if (access_details.site_data_type !=
-      content_settings::SiteDataType::kStorage) {
-    return;
-  }
-
-  DCHECK(access_details.render_frame_host);
-
-  // TODO(crbug.com/1434764): handle same-site iframes.
-  if (!access_details.render_frame_host->IsInPrimaryMainFrame() ||
-      access_details.blocked_by_policy) {
-    return;
-  }
-
-  dips_web_contents_observer_->detector_.OnClientSiteDataAccessed(
-      access_details.url, ToCookieOperation(access_details.access_type));
-}
-
 const base::TimeDelta DIPSBounceDetector::kTimestampUpdateInterval =
     base::Minutes(1);
 
@@ -466,6 +437,29 @@
           client_detection_state_->last_activation_time.has_value());
 }
 
+void DIPSWebContentsObserver::OnSiteDataAccessed(
+    const content_settings::AccessDetails& access_details) {
+  // NOTE: The current implementation is only acting on all site data types
+  // collapsed under `content_settings::SiteDataType::kStorage` with the
+  // exception of WebLocks (not monitored by the
+  // `content_settings::PageSpecificContentSettings`) as it's not persistent.
+  if (access_details.site_data_type !=
+      content_settings::SiteDataType::kStorage) {
+    return;
+  }
+
+  DCHECK(access_details.render_frame_host);
+
+  // TODO(crbug.com/1434764): handle same-site iframes.
+  if (!access_details.render_frame_host->IsInPrimaryMainFrame() ||
+      access_details.blocked_by_policy) {
+    return;
+  }
+
+  detector_.OnClientSiteDataAccessed(
+      access_details.url, ToCookieOperation(access_details.access_type));
+}
+
 void DIPSBounceDetector::OnClientSiteDataAccessed(const GURL& url,
                                                   CookieOperation op) {
   auto now = clock_->Now();
@@ -663,7 +657,6 @@
 }
 
 void DIPSWebContentsObserver::WebContentsDestroyed() {
-  dips_site_data_observer_.reset();
   detector_.BeforeDestruction();
 }
 
diff --git a/chrome/browser/dips/dips_bounce_detector.h b/chrome/browser/dips/dips_bounce_detector.h
index 755af45..ff01ac30 100644
--- a/chrome/browser/dips/dips_bounce_detector.h
+++ b/chrome/browser/dips/dips_bounce_detector.h
@@ -241,7 +241,8 @@
 
 // A thin wrapper around DIPSBounceDetector to use it as a WebContentsObserver.
 class DIPSWebContentsObserver
-    : public content::WebContentsObserver,
+    : public content_settings::PageSpecificContentSettings::SiteDataObserver,
+      public content::WebContentsObserver,
       public content::WebContentsUserData<DIPSWebContentsObserver>,
       public DIPSBounceDetectorDelegate {
  public:
@@ -299,23 +300,10 @@
       content::RenderFrameHost* render_frame_host) override;
   void WebContentsDestroyed() override;
 
-  class DIPSSiteDataObserver
-      : public content_settings::PageSpecificContentSettings::SiteDataObserver {
-   public:
-    DIPSSiteDataObserver(content::WebContents* web_contents,
-                         DIPSWebContentsObserver* dips_web_contents_observer);
-
-    DIPSSiteDataObserver(const DIPSSiteDataObserver&) = delete;
-    DIPSSiteDataObserver& operator=(const DIPSSiteDataObserver&) = delete;
-
-   private:
-    // Start SiteDataObserver overrides:
-    void OnSiteDataAccessed(
-        const content_settings::AccessDetails& access_details) override;
-    // End SiteDataObserver overrides.
-
-    raw_ptr<DIPSWebContentsObserver> dips_web_contents_observer_;
-  };
+  // Start SiteDataObserver overrides:
+  void OnSiteDataAccessed(
+      const content_settings::AccessDetails& access_details) override;
+  // End SiteDataObserver overrides.
 
   // raw_ptr<> is safe here because DIPSService is a KeyedService, associated
   // with the BrowserContext/Profile which will outlive the WebContents that
@@ -323,7 +311,6 @@
   raw_ptr<DIPSService> dips_service_;
   DIPSBounceDetector detector_;
   DIPSIssueReportingCallback issue_reporting_callback_;
-  std::unique_ptr<DIPSSiteDataObserver> dips_site_data_observer_;
 
   base::WeakPtrFactory<DIPSWebContentsObserver> weak_factory_{this};
 
diff --git a/chrome/browser/dips/dips_bounce_detector_browsertest.cc b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
index 8decb20..c4e1f5c 100644
--- a/chrome/browser/dips/dips_bounce_detector_browsertest.cc
+++ b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
@@ -177,7 +177,8 @@
 // Keeps a log of DidStartNavigation, OnCookiesAccessed, and DidFinishNavigation
 // executions.
 class WCOCallbackLogger
-    : public content::WebContentsObserver,
+    : public content_settings::PageSpecificContentSettings::SiteDataObserver,
+      public content::WebContentsObserver,
       public content::WebContentsUserData<WCOCallbackLogger> {
  public:
   WCOCallbackLogger(const WCOCallbackLogger&) = delete;
@@ -197,39 +198,23 @@
   void OnCookiesAccessed(NavigationHandle* navigation_handle,
                          const content::CookieAccessDetails& details) override;
   void DidFinishNavigation(NavigationHandle* navigation_handle) override;
-  void WebContentsDestroyed() override;
   // End WebContentsObserver overrides.
 
-  class DIPSSiteDataObserver
-      : public content_settings::PageSpecificContentSettings::SiteDataObserver {
-   public:
-    DIPSSiteDataObserver(content::WebContents* web_contents,
-                         WCOCallbackLogger* dips_web_contents_observer);
-
-    DIPSSiteDataObserver(const DIPSSiteDataObserver&) = delete;
-    DIPSSiteDataObserver& operator=(const DIPSSiteDataObserver&) = delete;
-
-   private:
-    // Start SiteDataObserver overrides:
-    void OnSiteDataAccessed(
-        const content_settings::AccessDetails& access_details) override;
-    // End SiteDataObserver overrides.
-
-    raw_ptr<WCOCallbackLogger> wco_callback_logger_;
-  };
+  // Start SiteDataObserver overrides:
+  void OnSiteDataAccessed(
+      const content_settings::AccessDetails& access_details) override;
+  // End SiteDataObserver overrides.
 
   std::vector<std::string> log_;
-  std::unique_ptr<DIPSSiteDataObserver> dips_site_data_observer_;
 
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 };
 
 WCOCallbackLogger::WCOCallbackLogger(content::WebContents* web_contents)
-    : content::WebContentsObserver(web_contents),
-      content::WebContentsUserData<WCOCallbackLogger>(*web_contents) {
-  dips_site_data_observer_ =
-      std::make_unique<DIPSSiteDataObserver>(web_contents, this);
-}
+    : content_settings::PageSpecificContentSettings::SiteDataObserver(
+          web_contents),
+      content::WebContentsObserver(web_contents),
+      content::WebContentsUserData<WCOCallbackLogger>(*web_contents) {}
 
 void WCOCallbackLogger::DidStartNavigation(
     NavigationHandle* navigation_handle) {
@@ -275,17 +260,6 @@
                          FormatURL(navigation_handle->GetURL()).c_str()));
 }
 
-void WCOCallbackLogger::WebContentsDestroyed() {
-  dips_site_data_observer_.reset();
-}
-
-WCOCallbackLogger::DIPSSiteDataObserver::DIPSSiteDataObserver(
-    content::WebContents* web_contents,
-    WCOCallbackLogger* wco_callback_logger)
-    : content_settings::PageSpecificContentSettings::SiteDataObserver(
-          web_contents),
-      wco_callback_logger_(wco_callback_logger) {}
-
 inline std::string SiteDataTypeToString(
     const content_settings::SiteDataType& type) {
   switch (type) {
@@ -319,7 +293,7 @@
   }
 }
 
-void WCOCallbackLogger::DIPSSiteDataObserver::OnSiteDataAccessed(
+void WCOCallbackLogger::OnSiteDataAccessed(
     const content_settings::AccessDetails& access_details) {
   // Avoids logging notification from the PSCS that are due to cookie accesses,
   // in order not to impact the other cookie access notification logs from the
@@ -329,7 +303,7 @@
     return;
   }
 
-  wco_callback_logger_->log_.push_back(base::StringPrintf(
+  log_.push_back(base::StringPrintf(
       "OnSiteDataAccessed(AccessDetails, %s: %s: %s)",
       SiteDataTypeToString(access_details.site_data_type).c_str(),
       AccessTypeToString(access_details.access_type).c_str(),
diff --git a/chrome/browser/download/download_core_service_factory.cc b/chrome/browser/download/download_core_service_factory.cc
index 1d3ea33..4847c258 100644
--- a/chrome/browser/download/download_core_service_factory.cc
+++ b/chrome/browser/download/download_core_service_factory.cc
@@ -29,7 +29,12 @@
 DownloadCoreServiceFactory::DownloadCoreServiceFactory()
     : ProfileKeyedServiceFactory(
           "DownloadCoreService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
 #if !BUILDFLAG(IS_ANDROID)
   DependsOn(DownloadBubbleUpdateServiceFactory::GetInstance());
 #endif  // !BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/download/offline_item_model_manager_factory.cc b/chrome/browser/download/offline_item_model_manager_factory.cc
index d0353f92..bfbf237 100644
--- a/chrome/browser/download/offline_item_model_manager_factory.cc
+++ b/chrome/browser/download/offline_item_model_manager_factory.cc
@@ -23,7 +23,12 @@
 OfflineItemModelManagerFactory::OfflineItemModelManagerFactory()
     : ProfileKeyedServiceFactory(
           "OfflineItemModelManager",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 OfflineItemModelManagerFactory::~OfflineItemModelManagerFactory() = default;
 
diff --git a/chrome/browser/engagement/site_engagement_service_factory.cc b/chrome/browser/engagement/site_engagement_service_factory.cc
index 713b48b..a65c81a 100644
--- a/chrome/browser/engagement/site_engagement_service_factory.cc
+++ b/chrome/browser/engagement/site_engagement_service_factory.cc
@@ -36,7 +36,12 @@
 SiteEngagementServiceFactory::SiteEngagementServiceFactory()
     : ProfileKeyedServiceFactory(
           "SiteEngagementService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HistoryServiceFactory::GetInstance());
   DependsOn(HostContentSettingsMapFactory::GetInstance());
   DependsOn(prerender::NoStatePrefetchManagerFactory::GetInstance());
diff --git a/chrome/browser/enterprise/browser_management/management_service_factory.cc b/chrome/browser/enterprise/browser_management/management_service_factory.cc
index 2c2b0292..fc73cb0 100644
--- a/chrome/browser/enterprise/browser_management/management_service_factory.cc
+++ b/chrome/browser/enterprise/browser_management/management_service_factory.cc
@@ -57,7 +57,12 @@
 ManagementServiceFactory::ManagementServiceFactory()
     : ProfileKeyedServiceFactory(
           "EnterpriseManagementService",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 ManagementServiceFactory::~ManagementServiceFactory() = default;
 
diff --git a/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service_factory.cc b/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service_factory.cc
index fa53cf1..5c80e37 100644
--- a/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service_factory.cc
+++ b/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service_factory.cc
@@ -27,7 +27,12 @@
 LocalBinaryUploadServiceFactory::LocalBinaryUploadServiceFactory()
     : ProfileKeyedServiceFactory(
           "LocalBinaryUploadService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(enterprise_signals::SystemSignalsServiceHostFactory::GetInstance());
 }
 
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_factory.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_factory.cc
index a839e4f6..885868b4 100644
--- a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_factory.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_factory.cc
@@ -55,7 +55,7 @@
 DeviceTrustConnectorServiceFactory::DeviceTrustConnectorServiceFactory()
     : ProfileKeyedServiceFactory(
           "DeviceTrustConnectorService",
-          ProfileSelections::BuildForRegularAndIncognitoNonExperimental()) {}
+          ProfileSelections::BuildForRegularAndIncognito()) {}
 
 DeviceTrustConnectorServiceFactory::~DeviceTrustConnectorServiceFactory() =
     default;
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc
index 78569da7..cefcc80 100644
--- a/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc
@@ -74,7 +74,7 @@
 DeviceTrustServiceFactory::DeviceTrustServiceFactory()
     : ProfileKeyedServiceFactory(
           "DeviceTrustService",
-          ProfileSelections::BuildForRegularAndIncognitoNonExperimental()) {
+          ProfileSelections::BuildForRegularAndIncognito()) {
   DependsOn(DeviceTrustConnectorServiceFactory::GetInstance());
   DependsOn(policy::ManagementServiceFactory::GetInstance());
 
diff --git a/chrome/browser/extensions/api/bookmarks/bookmarks_api_watcher.cc b/chrome/browser/extensions/api/bookmarks/bookmarks_api_watcher.cc
index 1fb814b..d21f2a49 100644
--- a/chrome/browser/extensions/api/bookmarks/bookmarks_api_watcher.cc
+++ b/chrome/browser/extensions/api/bookmarks/bookmarks_api_watcher.cc
@@ -26,7 +26,12 @@
   BookmarksApiWatcherFactory()
       : ProfileKeyedServiceFactory(
             "BookmarksApiWatcher",
-            ProfileSelections::BuildForRegularAndIncognito()) {}
+            ProfileSelections::Builder()
+                .WithRegular(ProfileSelection::kOwnInstance)
+                // TODO(crbug.com/1418376): Check if this service is needed in
+                // Guest mode.
+                .WithGuest(ProfileSelection::kOwnInstance)
+                .Build()) {}
 
  private:
   // BrowserContextKeyedServiceFactory overrides
diff --git a/chrome/browser/extensions/api/notifications/extension_notification_display_helper_factory.cc b/chrome/browser/extensions/api/notifications/extension_notification_display_helper_factory.cc
index 9dc4e8d..c1c21e09 100644
--- a/chrome/browser/extensions/api/notifications/extension_notification_display_helper_factory.cc
+++ b/chrome/browser/extensions/api/notifications/extension_notification_display_helper_factory.cc
@@ -28,7 +28,12 @@
     ExtensionNotificationDisplayHelperFactory()
     : ProfileKeyedServiceFactory(
           "ExtensionNotificationDisplayHelperFactory",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 ExtensionNotificationDisplayHelperFactory::
     ~ExtensionNotificationDisplayHelperFactory() {}
diff --git a/chrome/browser/extensions/api/notifications/notifications_api.cc b/chrome/browser/extensions/api/notifications/notifications_api.cc
index 0a850ca..027b548 100644
--- a/chrome/browser/extensions/api/notifications/notifications_api.cc
+++ b/chrome/browser/extensions/api/notifications/notifications_api.cc
@@ -219,8 +219,7 @@
 
   NotificationBitmapSizes bitmap_sizes = GetNotificationBitmapSizes();
 
-  float image_scale = ui::GetScaleForResourceScaleFactor(
-      ui::GetMaxSupportedResourceScaleFactor());
+  const float image_scale = ui::GetScaleForMaxSupportedResourceScaleFactor();
 
   // Extract required fields: type, title, message, and icon.
   message_center::NotificationType type =
@@ -377,8 +376,7 @@
 #endif
 
   NotificationBitmapSizes bitmap_sizes = GetNotificationBitmapSizes();
-  float image_scale = ui::GetScaleForResourceScaleFactor(
-      ui::GetMaxSupportedResourceScaleFactor());
+  const float image_scale = ui::GetScaleForMaxSupportedResourceScaleFactor();
 
   // Update optional fields if provided.
   if (options->type != api::notifications::TEMPLATE_TYPE_NONE)
diff --git a/chrome/browser/extensions/api/pdf_viewer_private/pdf_viewer_private_event_router_factory.cc b/chrome/browser/extensions/api/pdf_viewer_private/pdf_viewer_private_event_router_factory.cc
index eb6e6abe..ca8ad9e 100644
--- a/chrome/browser/extensions/api/pdf_viewer_private/pdf_viewer_private_event_router_factory.cc
+++ b/chrome/browser/extensions/api/pdf_viewer_private/pdf_viewer_private_event_router_factory.cc
@@ -28,7 +28,12 @@
 PdfViewerPrivateEventRouterFactory::PdfViewerPrivateEventRouterFactory()
     : ProfileKeyedServiceFactory(
           "PdfViewerPrivateEventRouter",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
   DependsOn(EventRouterFactory::GetInstance());
 }
diff --git a/chrome/browser/extensions/api/settings_private/generated_prefs_factory.cc b/chrome/browser/extensions/api/settings_private/generated_prefs_factory.cc
index a9e1f3e..8ffd2eb28 100644
--- a/chrome/browser/extensions/api/settings_private/generated_prefs_factory.cc
+++ b/chrome/browser/extensions/api/settings_private/generated_prefs_factory.cc
@@ -27,7 +27,12 @@
     : ProfileKeyedServiceFactory(
           "GeneratedPrefs",
           // Use |context| even if it is off-the-record/incognito.
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 GeneratedPrefsFactory::~GeneratedPrefsFactory() {}
 
diff --git a/chrome/browser/extensions/api/settings_private/settings_private_delegate_factory.cc b/chrome/browser/extensions/api/settings_private/settings_private_delegate_factory.cc
index 74e0ba53..a4bf6c5 100644
--- a/chrome/browser/extensions/api/settings_private/settings_private_delegate_factory.cc
+++ b/chrome/browser/extensions/api/settings_private/settings_private_delegate_factory.cc
@@ -28,7 +28,12 @@
 SettingsPrivateDelegateFactory::SettingsPrivateDelegateFactory()
     : ProfileKeyedServiceFactory(
           "SettingsPrivateDelegate",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 SettingsPrivateDelegateFactory::~SettingsPrivateDelegateFactory() {
 }
diff --git a/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.cc b/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.cc
index 043847e..712515f 100644
--- a/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.cc
+++ b/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.cc
@@ -30,7 +30,12 @@
 SettingsPrivateEventRouterFactory::SettingsPrivateEventRouterFactory()
     : ProfileKeyedServiceFactory(
           "SettingsPrivateEventRouter",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
   DependsOn(EventRouterFactory::GetInstance());
   DependsOn(settings_private::GeneratedPrefsFactory::GetInstance());
diff --git a/chrome/browser/extensions/api/tab_groups/tab_groups_api_apitest.cc b/chrome/browser/extensions/api/tab_groups/tab_groups_api_apitest.cc
index 8a8b438..d091f9a 100644
--- a/chrome/browser/extensions/api/tab_groups/tab_groups_api_apitest.cc
+++ b/chrome/browser/extensions/api/tab_groups/tab_groups_api_apitest.cc
@@ -20,7 +20,7 @@
 using TabGroupsApiTest = ExtensionApiTest;
 
 // TODO(crbug.com/1441814): Test is flaky.
-IN_PROC_BROWSER_TEST_F(TabGroupsApiTest, DISABLED_TestTabGroupsWorks) {
+IN_PROC_BROWSER_TEST_F(TabGroupsApiTest, TestTabGroupsWorks) {
   ASSERT_TRUE(RunExtensionTest("tab_groups")) << message_;
 }
 
diff --git a/chrome/browser/extensions/api/tab_groups/tab_groups_event_router_factory.cc b/chrome/browser/extensions/api/tab_groups/tab_groups_event_router_factory.cc
index 92ac13b..def4529 100644
--- a/chrome/browser/extensions/api/tab_groups/tab_groups_event_router_factory.cc
+++ b/chrome/browser/extensions/api/tab_groups/tab_groups_event_router_factory.cc
@@ -27,7 +27,12 @@
 TabGroupsEventRouterFactory::TabGroupsEventRouterFactory()
     : ProfileKeyedServiceFactory(
           "TabGroupsEventRouter",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(EventRouterFactory::GetInstance());
 }
 
diff --git a/chrome/browser/extensions/api/web_authentication_proxy/web_authentication_proxy_service.cc b/chrome/browser/extensions/api/web_authentication_proxy/web_authentication_proxy_service.cc
index c148806..4e8c743 100644
--- a/chrome/browser/extensions/api/web_authentication_proxy/web_authentication_proxy_service.cc
+++ b/chrome/browser/extensions/api/web_authentication_proxy/web_authentication_proxy_service.cc
@@ -602,7 +602,12 @@
 WebAuthenticationProxyServiceFactory::WebAuthenticationProxyServiceFactory()
     : ProfileKeyedServiceFactory(
           "WebAuthenticationProxyService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(EventRouterFactory::GetInstance());
   DependsOn(ExtensionRegistryFactory::GetInstance());
 }
diff --git a/chrome/browser/extensions/chrome_extension_cookies_factory.cc b/chrome/browser/extensions/chrome_extension_cookies_factory.cc
index da4024f9..49361f3 100644
--- a/chrome/browser/extensions/chrome_extension_cookies_factory.cc
+++ b/chrome/browser/extensions/chrome_extension_cookies_factory.cc
@@ -27,7 +27,12 @@
     : ProfileKeyedServiceFactory(
           "ChromeExtensionCookies",
           // Incognito gets separate extension cookies, too.
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 ChromeExtensionCookiesFactory::~ChromeExtensionCookiesFactory() {}
 
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.cc b/chrome/browser/extensions/chrome_extensions_browser_client.cc
index 387ae00..07398eb 100644
--- a/chrome/browser/extensions/chrome_extensions_browser_client.cc
+++ b/chrome/browser/extensions/chrome_extensions_browser_client.cc
@@ -248,9 +248,15 @@
     content::BrowserContext* context,
     bool force_guest_profile,
     bool force_system_profile) {
-  const ProfileSelections selections =
-      ProfileSelections::BuildForRegularAndIncognito(force_guest_profile,
-                                                     force_system_profile);
+  ProfileSelections::Builder builder;
+  builder.WithRegular(ProfileSelection::kOwnInstance);
+  if (force_guest_profile) {
+    builder.WithGuest(ProfileSelection::kOwnInstance);
+  }
+  if (force_system_profile) {
+    builder.WithSystem(ProfileSelection::kOwnInstance);
+  }
+  const ProfileSelections selections = builder.Build();
   return selections.ApplyProfileSelection(Profile::FromBrowserContext(context));
 }
 
@@ -258,8 +264,14 @@
     content::BrowserContext* context,
     bool force_guest_profile,
     bool force_system_profile) {
-  const ProfileSelections selections = ProfileSelections::BuildDefault(
-      force_guest_profile, force_system_profile);
+  ProfileSelections::Builder builder;
+  if (force_guest_profile) {
+    builder.WithGuest(ProfileSelection::kOriginalOnly);
+  }
+  if (force_system_profile) {
+    builder.WithSystem(ProfileSelection::kOriginalOnly);
+  }
+  ProfileSelections selections = builder.Build();
   return selections.ApplyProfileSelection(Profile::FromBrowserContext(context));
 }
 
diff --git a/chrome/browser/extensions/extension_install_prompt.cc b/chrome/browser/extensions/extension_install_prompt.cc
index 2e786c29..4c0cb26 100644
--- a/chrome/browser/extensions/extension_install_prompt.cc
+++ b/chrome/browser/extensions/extension_install_prompt.cc
@@ -40,6 +40,7 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "ui/base/resource/resource_scale_factor.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_skia_rep.h"
@@ -63,7 +64,8 @@
   const gfx::ImageSkia& image = is_app ?
       extensions::util::GetDefaultAppIcon() :
       extensions::util::GetDefaultExtensionIcon();
-  return image.GetRepresentation(gfx::ImageSkia::GetMaxSupportedScale())
+  return image
+      .GetRepresentation(ui::GetScaleForMaxSupportedResourceScaleFactor())
       .GetBitmap();
 }
 
diff --git a/chrome/browser/extensions/extension_system_factory.cc b/chrome/browser/extensions/extension_system_factory.cc
index 5d4d1d5..e432156 100644
--- a/chrome/browser/extensions/extension_system_factory.cc
+++ b/chrome/browser/extensions/extension_system_factory.cc
@@ -101,8 +101,12 @@
 
 content::BrowserContext* ExtensionSystemFactory::GetBrowserContextToUse(
     content::BrowserContext* context) const {
-  return ProfileSelections::BuildForRegularAndIncognito(
-             /*force_guest=*/true, /*force_system=*/false)
+  return ProfileSelections::Builder()
+      .WithRegular(ProfileSelection::kOwnInstance)
+      // TODO(crbug.com/1418376): Check if this service is needed in
+      // Guest mode.
+      .WithGuest(ProfileSelection::kOwnInstance)
+      .Build()
       .ApplyProfileSelection(Profile::FromBrowserContext(context));
 }
 
diff --git a/chrome/browser/file_system_access/file_system_access_permission_context_factory.cc b/chrome/browser/file_system_access/file_system_access_permission_context_factory.cc
index b7271da..cecbc661 100644
--- a/chrome/browser/file_system_access/file_system_access_permission_context_factory.cc
+++ b/chrome/browser/file_system_access/file_system_access_permission_context_factory.cc
@@ -36,7 +36,12 @@
     FileSystemAccessPermissionContextFactory()
     : ProfileKeyedServiceFactory(
           "FileSystemAccessPermissionContext",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index a4ac6e65..8913c034 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -3970,7 +3970,7 @@
   {
     "name": "feed-loading-placeholder",
     "owners": [ "//chrome/android/feed/OWNERS", "dewittj@chromium.org" ],
-    "expiry_milestone": 115
+    "expiry_milestone": 120
   },
   {
     "name": "feed-share",
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index aed0593..47e6af9 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -134,7 +134,6 @@
     &features::kWebNfc,
     &features::kIncognitoDownloadsWarning,
     &features::kIncognitoNtpRevamp,
-    &features::kKeepAndroidTintedResources,
     &feature_engagement::kIPHNewTabPageHomeButtonFeature,
     &feature_engagement::kIPHTabSwitcherButtonFeature,
     &feature_engagement::kUseClientConfigIPH,
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index 6b1a85f..d82ec23 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -352,7 +352,6 @@
     public static final String INTEREST_FEED_V2 = "InterestFeedV2";
     public static final String INTEREST_FEED_V2_AUTOPLAY = "InterestFeedV2Autoplay";
     public static final String INTEREST_FEED_V2_HEARTS = "InterestFeedV2Hearts";
-    public static final String KEEP_ANDROID_TINTED_RESOURCES = "KeepAndroidTintedResources";
     public static final String LENS_CAMERA_ASSISTED_SEARCH = "LensCameraAssistedSearch";
     public static final String LENS_ON_QUICK_ACTION_SEARCH_WIDGET = "LensOnQuickActionSearchWidget";
     public static final String LOCAL_WEB_APPROVALS = "LocalWebApprovals";
diff --git a/chrome/browser/gcm/gcm_profile_service_factory.cc b/chrome/browser/gcm/gcm_profile_service_factory.cc
index 88f4793..cc4ad4f 100644
--- a/chrome/browser/gcm/gcm_profile_service_factory.cc
+++ b/chrome/browser/gcm/gcm_profile_service_factory.cc
@@ -109,7 +109,12 @@
 GCMProfileServiceFactory::GCMProfileServiceFactory()
     : ProfileKeyedServiceFactory(
           "GCMProfileService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(IdentityManagerFactory::GetInstance());
 #if BUILDFLAG(ENABLE_OFFLINE_PAGES)
   DependsOn(offline_pages::PrefetchServiceFactory::GetInstance());
diff --git a/chrome/browser/gcm/instance_id/instance_id_profile_service_factory.cc b/chrome/browser/gcm/instance_id/instance_id_profile_service_factory.cc
index 01a3a52d..f7416ec 100644
--- a/chrome/browser/gcm/instance_id/instance_id_profile_service_factory.cc
+++ b/chrome/browser/gcm/instance_id/instance_id_profile_service_factory.cc
@@ -33,7 +33,12 @@
 InstanceIDProfileServiceFactory::InstanceIDProfileServiceFactory()
     : ProfileKeyedServiceFactory(
           "InstanceIDProfileService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   // GCM is needed for device ID.
   DependsOn(gcm::GCMProfileServiceFactory::GetInstance());
 }
diff --git a/chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.cc b/chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.cc
index 76c6241..1e30b697 100644
--- a/chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.cc
+++ b/chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.cc
@@ -30,7 +30,12 @@
 HeavyAdServiceFactory::HeavyAdServiceFactory()
     : ProfileKeyedServiceFactory(
           "HeavyAdService",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 HeavyAdServiceFactory::~HeavyAdServiceFactory() {}
 
diff --git a/chrome/browser/hid/hid_chooser_context_factory.cc b/chrome/browser/hid/hid_chooser_context_factory.cc
index 236d4e8..1102a2af 100644
--- a/chrome/browser/hid/hid_chooser_context_factory.cc
+++ b/chrome/browser/hid/hid_chooser_context_factory.cc
@@ -31,7 +31,12 @@
 HidChooserContextFactory::HidChooserContextFactory()
     : ProfileKeyedServiceFactory(
           "HidChooserContext",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
diff --git a/chrome/browser/hid/hid_connection_tracker_factory.cc b/chrome/browser/hid/hid_connection_tracker_factory.cc
index 0e75174..f19841f 100644
--- a/chrome/browser/hid/hid_connection_tracker_factory.cc
+++ b/chrome/browser/hid/hid_connection_tracker_factory.cc
@@ -27,7 +27,12 @@
 HidConnectionTrackerFactory::HidConnectionTrackerFactory()
     : ProfileKeyedServiceFactory(
           "HidConnectionTracker",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
diff --git a/chrome/browser/history_clusters/history_clusters_service_factory.cc b/chrome/browser/history_clusters/history_clusters_service_factory.cc
index cca54f7e..34ae927 100644
--- a/chrome/browser/history_clusters/history_clusters_service_factory.cc
+++ b/chrome/browser/history_clusters/history_clusters_service_factory.cc
@@ -38,7 +38,12 @@
     : ProfileKeyedServiceFactory(
           "HistoryClustersService",
           // Give incognito its own isolated service.
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HistoryServiceFactory::GetInstance());
   DependsOn(PageContentAnnotationsServiceFactory::GetInstance());
   DependsOn(site_engagement::SiteEngagementServiceFactory::GetInstance());
diff --git a/chrome/browser/k_anonymity_service/k_anonymity_service_factory.cc b/chrome/browser/k_anonymity_service/k_anonymity_service_factory.cc
index f196d33..74df93dc 100644
--- a/chrome/browser/k_anonymity_service/k_anonymity_service_factory.cc
+++ b/chrome/browser/k_anonymity_service/k_anonymity_service_factory.cc
@@ -21,7 +21,12 @@
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   if (!base::FeatureList::IsEnabled(features::kKAnonymityService))
     return ProfileSelections::BuildNoProfilesSelected();
-  return ProfileSelections::BuildForRegularAndIncognito();
+  return ProfileSelections::Builder()
+      .WithRegular(ProfileSelection::kOwnInstance)
+      // TODO(crbug.com/1418376): Check if this service is needed in
+      // Guest mode.
+      .WithGuest(ProfileSelection::kOwnInstance)
+      .Build();
 #else
   return ProfileSelections::BuildNoProfilesSelected();
 #endif
diff --git a/chrome/browser/language/accept_languages_service_factory.cc b/chrome/browser/language/accept_languages_service_factory.cc
index f6d896d..3e5a5e86 100644
--- a/chrome/browser/language/accept_languages_service_factory.cc
+++ b/chrome/browser/language/accept_languages_service_factory.cc
@@ -25,7 +25,12 @@
 AcceptLanguagesServiceFactory::AcceptLanguagesServiceFactory()
     : ProfileKeyedServiceFactory(
           "AcceptLanguagesService",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 AcceptLanguagesServiceFactory::~AcceptLanguagesServiceFactory() {}
 
diff --git a/chrome/browser/lookalikes/lookalike_url_service.cc b/chrome/browser/lookalikes/lookalike_url_service.cc
index 2da8cc3..3e7c788 100644
--- a/chrome/browser/lookalikes/lookalike_url_service.cc
+++ b/chrome/browser/lookalikes/lookalike_url_service.cc
@@ -65,7 +65,12 @@
   LookalikeUrlServiceFactory()
       : ProfileKeyedServiceFactory(
             "LookalikeUrlServiceFactory",
-            ProfileSelections::BuildForRegularAndIncognito()) {
+            ProfileSelections::Builder()
+                .WithRegular(ProfileSelection::kOwnInstance)
+                // TODO(crbug.com/1418376): Check if this service is needed in
+                // Guest mode.
+                .WithGuest(ProfileSelection::kOwnInstance)
+                .Build()) {
     DependsOn(site_engagement::SiteEngagementServiceFactory::GetInstance());
   }
 
diff --git a/chrome/browser/media/history/media_history_keyed_service_factory.cc b/chrome/browser/media/history/media_history_keyed_service_factory.cc
index b1211f4b..65633c3e 100644
--- a/chrome/browser/media/history/media_history_keyed_service_factory.cc
+++ b/chrome/browser/media/history/media_history_keyed_service_factory.cc
@@ -28,7 +28,12 @@
     : ProfileKeyedServiceFactory(
           "MediaHistoryKeyedService",
           // Enable incognito profiles.
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HistoryServiceFactory::GetInstance());
 }
 
diff --git a/chrome/browser/media/media_engagement_service_factory.cc b/chrome/browser/media/media_engagement_service_factory.cc
index ca92411..54242ee 100644
--- a/chrome/browser/media/media_engagement_service_factory.cc
+++ b/chrome/browser/media/media_engagement_service_factory.cc
@@ -24,7 +24,12 @@
 MediaEngagementServiceFactory::MediaEngagementServiceFactory()
     : ProfileKeyedServiceFactory(
           "MediaEngagementServiceFactory",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HistoryServiceFactory::GetInstance());
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
diff --git a/chrome/browser/media/webrtc/capture_policy_utils.cc b/chrome/browser/media/webrtc/capture_policy_utils.cc
index 2bbc78e..7cd9845c1 100644
--- a/chrome/browser/media/webrtc/capture_policy_utils.cc
+++ b/chrome/browser/media/webrtc/capture_policy_utils.cc
@@ -123,8 +123,7 @@
   return AllowedScreenCaptureLevel::kDisallowed;
 }
 
-bool IsGetDisplayMediaSetSelectAllScreensAllowedForAnySite(
-    content::BrowserContext* context) {
+bool IsGetAllScreensMediaAllowedForAnySite(content::BrowserContext* context) {
 #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
   Profile* profile = Profile::FromBrowserContext(context);
   if (!profile) {
@@ -159,9 +158,8 @@
 #endif
 }
 
-bool IsGetDisplayMediaSetSelectAllScreensAllowed(
-    content::BrowserContext* context,
-    const GURL& url) {
+bool IsGetAllScreensMediaAllowed(content::BrowserContext* context,
+                                 const GURL& url) {
 #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
   Profile* profile = Profile::FromBrowserContext(context);
   if (!profile) {
diff --git a/chrome/browser/media/webrtc/capture_policy_utils.h b/chrome/browser/media/webrtc/capture_policy_utils.h
index 4719e9c2..42939d5 100644
--- a/chrome/browser/media/webrtc/capture_policy_utils.h
+++ b/chrome/browser/media/webrtc/capture_policy_utils.h
@@ -61,12 +61,10 @@
 void ShowCaptureTerminatedDialog(content::WebContents* contents);
 
 // TODO(crbug.com/1342069): Use Origin instead of GURL.
-bool IsGetDisplayMediaSetSelectAllScreensAllowed(
-    content::BrowserContext* context,
-    const GURL& url);
+bool IsGetAllScreensMediaAllowed(content::BrowserContext* context,
+                                 const GURL& url);
 
-bool IsGetDisplayMediaSetSelectAllScreensAllowedForAnySite(
-    content::BrowserContext* context);
+bool IsGetAllScreensMediaAllowedForAnySite(content::BrowserContext* context);
 
 #if !BUILDFLAG(IS_ANDROID)
 bool IsTransientActivationRequiredForGetDisplayMedia(
diff --git a/chrome/browser/media/webrtc/capture_policy_utils_unittest.cc b/chrome/browser/media/webrtc/capture_policy_utils_unittest.cc
index 4b07d40..dda9131 100644
--- a/chrome/browser/media/webrtc/capture_policy_utils_unittest.cc
+++ b/chrome/browser/media/webrtc/capture_policy_utils_unittest.cc
@@ -321,15 +321,13 @@
 
 TEST_P(MultiCaptureTest, IsMultiCaptureAllowedBasedOnPolicy) {
   EXPECT_EQ(ExpectedIsMultiCaptureAllowed(),
-            capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowed(
-                profile(), GURL(CurrentOrigin())));
+            capture_policy::IsGetAllScreensMediaAllowed(profile(),
+                                                        GURL(CurrentOrigin())));
 }
 
 TEST_P(MultiCaptureTest, IsMultiCaptureAllowedForAnyUrl) {
-  EXPECT_EQ(
-      ExpectedIsMultiCaptureAllowedForAnyUrl(),
-      capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowedForAnySite(
-          profile()));
+  EXPECT_EQ(ExpectedIsMultiCaptureAllowedForAnyUrl(),
+            capture_policy::IsGetAllScreensMediaAllowedForAnySite(profile()));
 }
 
 INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/media/webrtc/chrome_screen_enumerator.cc b/chrome/browser/media/webrtc/chrome_screen_enumerator.cc
index be6339b..f0d57cd 100644
--- a/chrome/browser/media/webrtc/chrome_screen_enumerator.cc
+++ b/chrome/browser/media/webrtc/chrome_screen_enumerator.cc
@@ -141,10 +141,7 @@
     blink::mojom::MediaStreamType stream_type,
     ScreensCallback screens_callback) const {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-  DCHECK((base::FeatureList::IsEnabled(features::kGetDisplayMediaSet) &&
-          base::FeatureList::IsEnabled(
-              features::kGetDisplayMediaSetAutoSelectAllScreens)) ||
-         base::FeatureList::IsEnabled(blink::features::kGetAllScreensMedia));
+  DCHECK(base::FeatureList::IsEnabled(blink::features::kGetAllScreensMedia));
 
 #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
   content::GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
diff --git a/chrome/browser/media/webrtc/chrome_screen_enumerator_ash_unittest.cc b/chrome/browser/media/webrtc/chrome_screen_enumerator_ash_unittest.cc
index b8161ec..76c270a7 100644
--- a/chrome/browser/media/webrtc/chrome_screen_enumerator_ash_unittest.cc
+++ b/chrome/browser/media/webrtc/chrome_screen_enumerator_ash_unittest.cc
@@ -30,7 +30,7 @@
     enumerator_ = std::make_unique<ChromeScreenEnumerator>();
     scoped_feature_list_.InitFromCommandLine(
         /*enable_features=*/
-        "GetDisplayMediaSet,GetDisplayMediaSetAutoSelectAllScreens",
+        "GetAllScreensMedia",
         /*disable_features=*/"");
   }
 
diff --git a/chrome/browser/media/webrtc/chrome_screen_enumerator_lacros_unittest.cc b/chrome/browser/media/webrtc/chrome_screen_enumerator_lacros_unittest.cc
index fff01631..944bd9d5 100644
--- a/chrome/browser/media/webrtc/chrome_screen_enumerator_lacros_unittest.cc
+++ b/chrome/browser/media/webrtc/chrome_screen_enumerator_lacros_unittest.cc
@@ -59,7 +59,7 @@
     enumerator_ = std::make_unique<ChromeScreenEnumerator>();
     scoped_feature_list_.InitFromCommandLine(
         /*enable_features=*/
-        "GetDisplayMediaSet,GetDisplayMediaSetAutoSelectAllScreens",
+        "GetAllScreensMedia",
         /*disable_features=*/"");
   }
 
diff --git a/chrome/browser/media/webrtc/get_all_screen_media_browsertest.cc b/chrome/browser/media/webrtc/get_all_screen_media_browsertest.cc
index c159c3b8..18c9ed0 100644
--- a/chrome/browser/media/webrtc/get_all_screen_media_browsertest.cc
+++ b/chrome/browser/media/webrtc/get_all_screen_media_browsertest.cc
@@ -91,13 +91,12 @@
 
 class ContentBrowserClientMock : public ChromeContentBrowserClient {
  public:
-  bool IsGetDisplayMediaSetSelectAllScreensAllowed(
-      content::BrowserContext* context,
-      const url::Origin& origin) override {
+  bool IsGetAllScreensMediaAllowed(content::BrowserContext* context,
+                                   const url::Origin& origin) override {
     return is_get_display_media_set_select_all_screens_allowed_;
   }
 
-  void SetIsGetDisplayMediaSetSelectAllScreensAllowed(bool is_allowed) {
+  void SetIsGetAllScreensMediaAllowed(bool is_allowed) {
     is_get_display_media_set_select_all_screens_allowed_ = is_allowed;
   }
 
@@ -222,7 +221,7 @@
 IN_PROC_BROWSER_TEST_F(GetAllScreensMediaBrowserTest,
                        AutoSelectAllScreensNotAllowed) {
   SetScreens(/*screen_count=*/1u);
-  browser_client_->SetIsGetDisplayMediaSetSelectAllScreensAllowed(
+  browser_client_->SetIsGetAllScreensMediaAllowed(
       /*is_allowed=*/false);
   std::set<std::string> stream_ids;
   std::set<std::string> track_ids;
diff --git a/chrome/browser/media/webrtc/multi_capture_browsertest.cc b/chrome/browser/media/webrtc/multi_capture_browsertest.cc
index 6d8a1d9b..3bbd7e3 100644
--- a/chrome/browser/media/webrtc/multi_capture_browsertest.cc
+++ b/chrome/browser/media/webrtc/multi_capture_browsertest.cc
@@ -57,7 +57,7 @@
   TabStripModel* current_tab_strip_model = current_browser->tab_strip_model();
   content::WebContents* current_web_contents =
       current_tab_strip_model->GetWebContentsAt(0);
-  EXPECT_FALSE(capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowed(
+  EXPECT_FALSE(capture_policy::IsGetAllScreensMediaAllowed(
       current_web_contents->GetBrowserContext(), GURL("")));
 }
 
@@ -75,7 +75,7 @@
   TabStripModel* current_tab_strip_model = current_browser->tab_strip_model();
   content::WebContents* current_web_contents =
       current_tab_strip_model->GetWebContentsAt(0);
-  EXPECT_FALSE(capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowed(
+  EXPECT_FALSE(capture_policy::IsGetAllScreensMediaAllowed(
       current_web_contents->GetBrowserContext(), GURL("")));
 }
 
@@ -97,7 +97,7 @@
   content::WebContents* current_web_contents =
       current_tab_strip_model->GetWebContentsAt(0);
   const bool multi_capture_allowed =
-      capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowed(
+      capture_policy::IsGetAllScreensMediaAllowed(
           current_web_contents->GetBrowserContext(),
           GURL("https://www.chromium.org"));
   EXPECT_EQ(multi_capture_allowed, MULTI_CAPTURE_SUPPORTED_ON_PLATFORM);
@@ -121,7 +121,7 @@
   content::WebContents* current_web_contents =
       current_tab_strip_model->GetWebContentsAt(0);
   const bool multi_capture_allowed =
-      capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowed(
+      capture_policy::IsGetAllScreensMediaAllowed(
           current_web_contents->GetBrowserContext(),
           GURL("https://sub.chromium.org"));
   EXPECT_EQ(multi_capture_allowed, MULTI_CAPTURE_SUPPORTED_ON_PLATFORM);
@@ -145,7 +145,7 @@
   TabStripModel* current_tab_strip_model = current_browser->tab_strip_model();
   content::WebContents* current_web_contents =
       current_tab_strip_model->GetWebContentsAt(0);
-  EXPECT_FALSE(capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowed(
+  EXPECT_FALSE(capture_policy::IsGetAllScreensMediaAllowed(
       current_web_contents->GetBrowserContext(),
       GURL("https://www.chromium.org")));
 }
@@ -169,7 +169,7 @@
   content::WebContents* current_web_contents =
       current_tab_strip_model->GetWebContentsAt(0);
   const bool multi_capture_allowed =
-      capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowed(
+      capture_policy::IsGetAllScreensMediaAllowed(
           current_web_contents->GetBrowserContext(),
           GURL("https://www.chromium.org"));
   EXPECT_EQ(multi_capture_allowed, MULTI_CAPTURE_SUPPORTED_ON_PLATFORM);
@@ -193,10 +193,9 @@
   content::WebContents* current_web_contents =
       current_tab_strip_model->GetWebContentsAt(0);
 
-  bool multi_capture_allowed =
-      capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowed(
-          current_web_contents->GetBrowserContext(),
-          GURL("https://www.chromium.org"));
+  bool multi_capture_allowed = capture_policy::IsGetAllScreensMediaAllowed(
+      current_web_contents->GetBrowserContext(),
+      GURL("https://www.chromium.org"));
   EXPECT_FALSE(multi_capture_allowed);
 
   policies.Clear();
@@ -211,10 +210,9 @@
 
   base::RunLoop().RunUntilIdle();
 
-  multi_capture_allowed =
-      capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowed(
-          current_web_contents->GetBrowserContext(),
-          GURL("https://www.chromium.org"));
+  multi_capture_allowed = capture_policy::IsGetAllScreensMediaAllowed(
+      current_web_contents->GetBrowserContext(),
+      GURL("https://www.chromium.org"));
   EXPECT_EQ(multi_capture_allowed, MULTI_CAPTURE_SUPPORTED_ON_PLATFORM);
 }
 #endif  // BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc b/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc
index a812358..48270674 100644
--- a/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc
+++ b/chrome/browser/media/webrtc/permission_bubble_media_access_handler.cc
@@ -326,7 +326,7 @@
   }
 
   // At most one stream is expected as this function is not used with the
-  // getDisplayMediaSet API (only used with getUserMedia).
+  // getAllScreensMedia API (only used with getUserMedia).
   DCHECK_LE(stream_devices_set.stream_devices.size(), 1u);
   blink::mojom::StreamDevices devices;
   if (!stream_devices_set.stream_devices.empty()) {
diff --git a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
index 557960a..ad073923 100644
--- a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
+++ b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
@@ -1424,8 +1424,7 @@
   ~WebRtcScreenCaptureSelectAllScreensTest() override = default;
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
-    // Enables GetDisplayMedia and GetDisplayMediaSetAutoSelectAllScreens
-    // features for multi surface capture.
+    // Enables GetAllScreensMedia features for multi surface capture.
     // TODO(simonha): remove when feature becomes stable.
     if (test_config_.enable_select_all_screens) {
       command_line->AppendSwitch(switches::kEnableBlinkTestFeatures);
diff --git a/chrome/browser/metrics/ukm_background_recorder_service.cc b/chrome/browser/metrics/ukm_background_recorder_service.cc
index eae52986..b2588d28 100644
--- a/chrome/browser/metrics/ukm_background_recorder_service.cc
+++ b/chrome/browser/metrics/ukm_background_recorder_service.cc
@@ -72,7 +72,12 @@
 UkmBackgroundRecorderFactory::UkmBackgroundRecorderFactory()
     : ProfileKeyedServiceFactory(
           "UkmBackgroundRecorderService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HistoryServiceFactory::GetInstance());
 }
 
diff --git a/chrome/browser/net/dns_probe_service_factory.cc b/chrome/browser/net/dns_probe_service_factory.cc
index 64497ff..b9cfcaa 100644
--- a/chrome/browser/net/dns_probe_service_factory.cc
+++ b/chrome/browser/net/dns_probe_service_factory.cc
@@ -408,7 +408,12 @@
     : ProfileKeyedServiceFactory(
           "DnsProbeService",
           // Create separate service for incognito profiles.
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 DnsProbeServiceFactory::~DnsProbeServiceFactory() {}
 
diff --git a/chrome/browser/net/nss_service_factory.cc b/chrome/browser/net/nss_service_factory.cc
index dfe2ff4..317c4b96 100644
--- a/chrome/browser/net/nss_service_factory.cc
+++ b/chrome/browser/net/nss_service_factory.cc
@@ -22,7 +22,12 @@
     : ProfileKeyedServiceFactory(
           "NssServiceFactory",
           // Create separate service for incognito profiles.
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   DependsOn(CertDbInitializerFactory::GetInstance());
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/net/profile_network_context_service_factory.cc b/chrome/browser/net/profile_network_context_service_factory.cc
index c1a68ee6..5489f9a 100644
--- a/chrome/browser/net/profile_network_context_service_factory.cc
+++ b/chrome/browser/net/profile_network_context_service_factory.cc
@@ -31,7 +31,12 @@
     : ProfileKeyedServiceFactory(
           "ProfileNetworkContextService",
           // Create separate service for incognito profiles.
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   DependsOn(chromeos::CertificateProviderServiceFactory::GetInstance());
 #endif
diff --git a/chrome/browser/notifications/notification_display_service_factory.cc b/chrome/browser/notifications/notification_display_service_factory.cc
index 4add742..4e5e2b70 100644
--- a/chrome/browser/notifications/notification_display_service_factory.cc
+++ b/chrome/browser/notifications/notification_display_service_factory.cc
@@ -32,7 +32,12 @@
 NotificationDisplayServiceFactory::NotificationDisplayServiceFactory()
     : ProfileKeyedServiceFactory(
           "NotificationDisplayService",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 KeyedService* NotificationDisplayServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
diff --git a/chrome/browser/notifications/notifier_state_tracker_factory.cc b/chrome/browser/notifications/notifier_state_tracker_factory.cc
index 414c845..7195a9e 100644
--- a/chrome/browser/notifications/notifier_state_tracker_factory.cc
+++ b/chrome/browser/notifications/notifier_state_tracker_factory.cc
@@ -24,7 +24,12 @@
 NotifierStateTrackerFactory::NotifierStateTrackerFactory()
     : ProfileKeyedServiceFactory(
           "NotifierStateTracker",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(PermissionManagerFactory::GetInstance());
 }
 
diff --git a/chrome/browser/notifications/platform_notification_service_factory.cc b/chrome/browser/notifications/platform_notification_service_factory.cc
index 6e4fb0c..5cf36391 100644
--- a/chrome/browser/notifications/platform_notification_service_factory.cc
+++ b/chrome/browser/notifications/platform_notification_service_factory.cc
@@ -30,7 +30,12 @@
 PlatformNotificationServiceFactory::PlatformNotificationServiceFactory()
     : ProfileKeyedServiceFactory(
           "PlatformNotificationService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
   DependsOn(NotificationDisplayServiceFactory::GetInstance());
   DependsOn(NotificationMetricsLoggerFactory::GetInstance());
diff --git a/chrome/browser/optimization_guide/model_validator_keyed_service_factory.cc b/chrome/browser/optimization_guide/model_validator_keyed_service_factory.cc
index da85159..854350d 100644
--- a/chrome/browser/optimization_guide/model_validator_keyed_service_factory.cc
+++ b/chrome/browser/optimization_guide/model_validator_keyed_service_factory.cc
@@ -24,7 +24,12 @@
 ModelValidatorKeyedServiceFactory::ModelValidatorKeyedServiceFactory()
     : ProfileKeyedServiceFactory(
           "ModelValidatorKeyedService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DCHECK(switches::ShouldValidateModel());
   DependsOn(OptimizationGuideKeyedServiceFactory::GetInstance());
 }
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_memory_tracker_factory.cc b/chrome/browser/page_load_metrics/page_load_metrics_memory_tracker_factory.cc
index d9ba91e..34a4465a 100644
--- a/chrome/browser/page_load_metrics/page_load_metrics_memory_tracker_factory.cc
+++ b/chrome/browser/page_load_metrics/page_load_metrics_memory_tracker_factory.cc
@@ -24,7 +24,12 @@
 PageLoadMetricsMemoryTrackerFactory::PageLoadMetricsMemoryTrackerFactory()
     : ProfileKeyedServiceFactory(
           "PageLoadMetricsMemoryTracker",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 bool PageLoadMetricsMemoryTrackerFactory::ServiceIsCreatedWithBrowserContext()
     const {
diff --git a/chrome/browser/payments/payment_request_display_manager_factory.cc b/chrome/browser/payments/payment_request_display_manager_factory.cc
index 2811e3e..33a50314 100644
--- a/chrome/browser/payments/payment_request_display_manager_factory.cc
+++ b/chrome/browser/payments/payment_request_display_manager_factory.cc
@@ -25,7 +25,12 @@
           "PaymentRequestDisplayManager",
           // Returns non-NULL even for Incognito contexts so that a separate
           // instance of a service is created for the Incognito context.
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 PaymentRequestDisplayManagerFactory::~PaymentRequestDisplayManagerFactory() {}
 
diff --git a/chrome/browser/performance_manager/mechanisms/working_set_trimmer_chromeos.cc b/chrome/browser/performance_manager/mechanisms/working_set_trimmer_chromeos.cc
index 0c8dc98..214b34a 100644
--- a/chrome/browser/performance_manager/mechanisms/working_set_trimmer_chromeos.cc
+++ b/chrome/browser/performance_manager/mechanisms/working_set_trimmer_chromeos.cc
@@ -17,6 +17,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/ash/arc/session/arc_session_manager.h"
+#include "chrome/browser/ash/arc/vmm/arcvm_working_set_trim_executor.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "components/performance_manager/public/graph/process_node.h"
@@ -76,129 +77,10 @@
     ArcVmReclaimType reclaim_type,
     int page_limit) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK_NE(ArcVmReclaimType::kReclaimNone, reclaim_type);
-  const char* error = nullptr;
 
-  // Before trimming, drop ARCVM's page caches.
-  content::BrowserContext* context =
-      context_for_testing_ ? context_for_testing_.get() : GetContext();
-  if (!context)
-    error = "BrowserContext unavailable";
-
-  auto* bridge =
-      context ? arc::ArcMemoryBridge::GetForBrowserContext(context) : nullptr;
-  if (!bridge)
-    error = "ArcMemoryBridge unavailable";
-
-  if (error) {
-    LOG(ERROR) << error;
-    if (reclaim_type == ArcVmReclaimType::kReclaimGuestPageCaches) {
-      // Failed to drop caches. When the type if kReclaimGuestPageCaches, run
-      // the |callback| now with the |error| message. No further action is
-      // necessary.
-      std::move(callback).Run(false, error);
-    } else {
-      // Otherwise, continue without dropping them.
-      OnDropArcVmCaches(std::move(callback), reclaim_type, page_limit,
-                        /*result=*/false);
-    }
-    return;
-  }
-
-  bridge->DropCaches(base::BindOnce(
-      &WorkingSetTrimmerChromeOS::OnDropArcVmCaches, weak_factory_.GetWeakPtr(),
-      std::move(callback), reclaim_type, page_limit));
-}
-
-void WorkingSetTrimmerChromeOS::OnDropArcVmCaches(
-    TrimArcVmWorkingSetCallback callback,
-    ArcVmReclaimType reclaim_type,
-    int page_limit,
-    bool result) {
-  constexpr const char kErrorMessage[] =
-      "Failed to drop ARCVM's guest page caches";
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
-  LOG_IF(WARNING, !result) << kErrorMessage;
-
-  if (reclaim_type == ArcVmReclaimType::kReclaimGuestPageCaches) {
-    // TrimVmMemory() is unnecessary. Just run the |callback| with the
-    // DropCaches() result.
-    std::move(callback).Run(result, result ? "" : kErrorMessage);
-    return;
-  }
-
-  // Do the actual VM trimming regardless of the |result|. When "ArcGuestZram"
-  // feature is enabled, guest memory is locked and should be reclaimed from
-  // guest through ArcMemoryBridge's reclaim API (if "guest_reclaim_enabled"
-  // param is enabled). Otherwise the memory should be reclaimed from host
-  // through ArcSessionManager's TrimVmMemory.
-  if (base::FeatureList::IsEnabled(arc::kGuestZram) &&
-      arc::kGuestReclaimEnabled.Get()) {
-    content::BrowserContext* context =
-        context_for_testing_ ? context_for_testing_.get() : GetContext();
-    if (!context) {
-      LogErrorAndInvokeCallback("BrowserContext unavailable",
-                                std::move(callback));
-      return;
-    }
-
-    auto* bridge =
-        context ? arc::ArcMemoryBridge::GetForBrowserContext(context) : nullptr;
-    if (!bridge) {
-      LogErrorAndInvokeCallback("ArcMemoryBridge unavailable",
-                                std::move(callback));
-      return;
-    }
-
-    auto reclaim_request = arc::mojom::ReclaimRequest::New(
-        arc::kGuestReclaimOnlyAnonymous.Get() ? arc::mojom::ReclaimType::ANON
-                                              : arc::mojom::ReclaimType::ALL);
-    bridge->Reclaim(
-        std::move(reclaim_request),
-        base::BindOnce(&WorkingSetTrimmerChromeOS::OnArcVmMemoryGuestReclaim,
-                       weak_factory_.GetMutableWeakPtr(),
-                       std::make_unique<base::ElapsedTimer>(),
-                       std::move(callback)));
-  } else {
-    arc::ArcSessionManager* arc_session_manager = arc::ArcSessionManager::Get();
-    if (!arc_session_manager) {
-      LogErrorAndInvokeCallback("ArcSessionManager unavailable",
-                                std::move(callback));
-      return;
-    }
-
-    arc_session_manager->TrimVmMemory(std::move(callback), page_limit);
-  }
-}
-
-void WorkingSetTrimmerChromeOS::OnArcVmMemoryGuestReclaim(
-    std::unique_ptr<base::ElapsedTimer> elapsed_timer,
-    TrimArcVmWorkingSetCallback callback,
-    arc::mojom::ReclaimResultPtr result) {
-  VLOG(2) << "Finished trimming memory from guest. " << result->reclaimed
-          << " processes were reclaimed successfully. " << result->unreclaimed
-          << " processes were not reclaimed.";
-  base::UmaHistogramBoolean("Arc.GuestZram.SuccessfulReclaim",
-                            (result->reclaimed > 0));
-  if (result->reclaimed == 0) {
-    std::move(callback).Run(false, "No guest process was reclaimed");
-  } else {
-    base::UmaHistogramCounts1000("Arc.GuestZram.ReclaimedProcess",
-                                 result->reclaimed);
-    base::UmaHistogramCounts1000("Arc.GuestZram.UnreclaimedProcess",
-                                 result->unreclaimed);
-    base::UmaHistogramMediumTimes("Arc.GuestZram.TotalReclaimTime",
-                                  elapsed_timer->Elapsed());
-    std::move(callback).Run(true, "");
-  }
-}
-
-void WorkingSetTrimmerChromeOS::LogErrorAndInvokeCallback(
-    const char* error,
-    TrimArcVmWorkingSetCallback callback) {
-  LOG(ERROR) << error;
-  std::move(callback).Run(false, error);
+  arc::ArcVmWorkingSetTrimExecutor::Trim(
+      context_for_testing_ ? context_for_testing_.get() : GetContext(),
+      std::move(callback), reclaim_type, page_limit);
 }
 
 void WorkingSetTrimmerChromeOS::TrimWorkingSet(
diff --git a/chrome/browser/performance_manager/mechanisms/working_set_trimmer_chromeos.h b/chrome/browser/performance_manager/mechanisms/working_set_trimmer_chromeos.h
index 8ee0ec2..fd4606c 100644
--- a/chrome/browser/performance_manager/mechanisms/working_set_trimmer_chromeos.h
+++ b/chrome/browser/performance_manager/mechanisms/working_set_trimmer_chromeos.h
@@ -18,6 +18,9 @@
 class BrowserContext;
 }  // namespace content
 
+namespace arc {
+enum class ArcVmReclaimType;
+}
 namespace performance_manager {
 
 namespace policies {
@@ -26,11 +29,8 @@
 
 namespace mechanism {
 
-enum class ArcVmReclaimType {
-  kReclaimNone = 0,
-  kReclaimGuestPageCaches,
-  kReclaimAll,  // both guest page caches and shmem
-};
+// For name compatibility of mechanism::ArcVmReclaimType.
+using arc::ArcVmReclaimType;
 
 // WorkingSetTrimmerChromeOS is the platform specific implementation of a
 // working set trimmer for ChromeOS. This class should not be used directly it
@@ -62,28 +62,10 @@
   // TrimWorkingSet based on ProcessId |pid|.
   void TrimWorkingSet(base::ProcessId pid);
 
-  // Asks vm_concierge to trim ARCVM's memory in the same way as TrimWorkingSet.
-  // The function must be called on the UI thread.
-  // |callback| is invoked upon completion.
-  // |page_limit| is the maximum number of pages to reclaim
-  //             (arc::ArcSession::kNoPageLimit for no limit)
   // Note: made virtual to ease unit testing (redefine in derived mock).
   virtual void TrimArcVmWorkingSet(TrimArcVmWorkingSetCallback callback,
                                    ArcVmReclaimType reclaim_type,
                                    int page_limit);
-  void OnDropArcVmCaches(TrimArcVmWorkingSetCallback callback,
-                         ArcVmReclaimType reclaim_type,
-                         int page_limit,
-                         bool result);
-
-  // |elapsed_timer| measures the time since the reclaim operation started.
-  void OnArcVmMemoryGuestReclaim(
-      std::unique_ptr<base::ElapsedTimer> elapsed_timer,
-      TrimArcVmWorkingSetCallback callback,
-      arc::mojom::ReclaimResultPtr result);
-
-  void LogErrorAndInvokeCallback(const char* error,
-                                 TrimArcVmWorkingSetCallback callback);
 
   // The constructor is made private to prevent instantiation of this class
   // directly, it should always be retrieved via
diff --git a/chrome/browser/performance_manager/mechanisms/working_set_trimmer_chromeos_unittest.cc b/chrome/browser/performance_manager/mechanisms/working_set_trimmer_chromeos_unittest.cc
index 8ee0352..deab719 100644
--- a/chrome/browser/performance_manager/mechanisms/working_set_trimmer_chromeos_unittest.cc
+++ b/chrome/browser/performance_manager/mechanisms/working_set_trimmer_chromeos_unittest.cc
@@ -22,6 +22,7 @@
 #include "base/timer/elapsed_timer.h"
 #include "chrome/browser/ash/arc/session/arc_session_manager.h"
 #include "chrome/browser/ash/arc/test/test_arc_session_manager.h"
+#include "chrome/browser/ash/arc/vmm/arcvm_working_set_trim_executor.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/concierge/concierge_client.h"
 #include "content/public/test/browser_task_environment.h"
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_facade_factory.cc b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_facade_factory.cc
index 2d7eda5..e543a12 100644
--- a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_facade_factory.cc
+++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_facade_factory.cc
@@ -43,10 +43,13 @@
 }
 
 SiteDataCacheFacadeFactory::SiteDataCacheFacadeFactory()
-    : ProfileKeyedServiceFactory("SiteDataCacheFacadeFactory",
-                                 ProfileSelections::BuildForRegularAndIncognito(
-                                     /*force_guest=*/true,
-                                     /*force_system=*/true)) {
+    : ProfileKeyedServiceFactory(
+          "SiteDataCacheFacadeFactory",
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .WithSystem(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HistoryServiceFactory::GetInstance());
 }
 
diff --git a/chrome/browser/performance_manager/policies/working_set_trimmer_policy_arcvm.cc b/chrome/browser/performance_manager/policies/working_set_trimmer_policy_arcvm.cc
index 8ae5f608..a4640a0 100644
--- a/chrome/browser/performance_manager/policies/working_set_trimmer_policy_arcvm.cc
+++ b/chrome/browser/performance_manager/policies/working_set_trimmer_policy_arcvm.cc
@@ -14,6 +14,7 @@
 #include "base/memory/singleton.h"
 #include "base/no_destructor.h"
 #include "chrome/browser/ash/arc/session/arc_session_manager.h"
+#include "chrome/browser/ash/arc/vmm/arcvm_working_set_trim_executor.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "components/exo/wm_helper.h"
diff --git a/chrome/browser/performance_manager/policies/working_set_trimmer_policy_arcvm_unittest.cc b/chrome/browser/performance_manager/policies/working_set_trimmer_policy_arcvm_unittest.cc
index 23b100a..aa6d49c 100644
--- a/chrome/browser/performance_manager/policies/working_set_trimmer_policy_arcvm_unittest.cc
+++ b/chrome/browser/performance_manager/policies/working_set_trimmer_policy_arcvm_unittest.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/ash/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h"
 #include "chrome/browser/ash/arc/session/arc_session_manager.h"
 #include "chrome/browser/ash/arc/test/test_arc_session_manager.h"
+#include "chrome/browser/ash/arc/vmm/arcvm_working_set_trim_executor.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/concierge/concierge_client.h"
 #include "components/arc/test/fake_intent_helper_host.h"
diff --git a/chrome/browser/performance_manager/policies/working_set_trimmer_policy_chromeos.cc b/chrome/browser/performance_manager/policies/working_set_trimmer_policy_chromeos.cc
index 911e9f6..79a7187 100644
--- a/chrome/browser/performance_manager/policies/working_set_trimmer_policy_chromeos.cc
+++ b/chrome/browser/performance_manager/policies/working_set_trimmer_policy_chromeos.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/ash/arc/arc_util.h"
 #include "chrome/browser/ash/arc/process/arc_process.h"
 #include "chrome/browser/ash/arc/session/arc_session_manager.h"
+#include "chrome/browser/ash/arc/vmm/arcvm_working_set_trim_executor.h"
 #include "chrome/browser/performance_manager/mechanisms/working_set_trimmer.h"
 #include "chrome/browser/performance_manager/policies/policy_features.h"
 #include "chrome/browser/performance_manager/policies/working_set_trimmer_policy_arcvm.h"
diff --git a/chrome/browser/performance_manager/policies/working_set_trimmer_policy_chromeos_unittest.cc b/chrome/browser/performance_manager/policies/working_set_trimmer_policy_chromeos_unittest.cc
index ea29cb7..3cf1486b 100644
--- a/chrome/browser/performance_manager/policies/working_set_trimmer_policy_chromeos_unittest.cc
+++ b/chrome/browser/performance_manager/policies/working_set_trimmer_policy_chromeos_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/ash/arc/process/arc_process.h"
 #include "chrome/browser/ash/arc/process/arc_process_service.h"
+#include "chrome/browser/ash/arc/vmm/arcvm_working_set_trim_executor.h"
 #include "chrome/browser/performance_manager/policies/policy_features.h"
 #include "chrome/browser/performance_manager/policies/working_set_trimmer_policy_arcvm.h"
 #include "components/performance_manager/graph/graph_impl_operations.h"
diff --git a/chrome/browser/permissions/one_time_permissions_tracker_factory.cc b/chrome/browser/permissions/one_time_permissions_tracker_factory.cc
index ba28b2c..1e5d602 100644
--- a/chrome/browser/permissions/one_time_permissions_tracker_factory.cc
+++ b/chrome/browser/permissions/one_time_permissions_tracker_factory.cc
@@ -23,7 +23,12 @@
 OneTimePermissionsTrackerFactory::OneTimePermissionsTrackerFactory()
     : ProfileKeyedServiceFactory(
           "OneTimePermissionsTrackerKeyedService",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 OneTimePermissionsTrackerFactory::~OneTimePermissionsTrackerFactory() = default;
 
diff --git a/chrome/browser/permissions/origin_keyed_permission_action_service_factory.cc b/chrome/browser/permissions/origin_keyed_permission_action_service_factory.cc
index c7d3384..a3f5cb1 100644
--- a/chrome/browser/permissions/origin_keyed_permission_action_service_factory.cc
+++ b/chrome/browser/permissions/origin_keyed_permission_action_service_factory.cc
@@ -25,7 +25,12 @@
     OriginKeyedPermissionActionServiceFactory()
     : ProfileKeyedServiceFactory(
           "OriginKeyedPermissionActionService",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 OriginKeyedPermissionActionServiceFactory::
     ~OriginKeyedPermissionActionServiceFactory() = default;
diff --git a/chrome/browser/permissions/permission_actions_history_factory.cc b/chrome/browser/permissions/permission_actions_history_factory.cc
index 561e586..dd14719 100644
--- a/chrome/browser/permissions/permission_actions_history_factory.cc
+++ b/chrome/browser/permissions/permission_actions_history_factory.cc
@@ -23,7 +23,12 @@
 PermissionActionsHistoryFactory::PermissionActionsHistoryFactory()
     : ProfileKeyedServiceFactory(
           "PermissionActionsHistory",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 PermissionActionsHistoryFactory::~PermissionActionsHistoryFactory() = default;
 
diff --git a/chrome/browser/permissions/permission_decision_auto_blocker_factory.cc b/chrome/browser/permissions/permission_decision_auto_blocker_factory.cc
index e4368d6..d34463c3 100644
--- a/chrome/browser/permissions/permission_decision_auto_blocker_factory.cc
+++ b/chrome/browser/permissions/permission_decision_auto_blocker_factory.cc
@@ -24,7 +24,12 @@
 PermissionDecisionAutoBlockerFactory::PermissionDecisionAutoBlockerFactory()
     : ProfileKeyedServiceFactory(
           "PermissionDecisionAutoBlocker",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
diff --git a/chrome/browser/permissions/permission_manager_factory.cc b/chrome/browser/permissions/permission_manager_factory.cc
index a6d47eeb..e70f9fcc 100644
--- a/chrome/browser/permissions/permission_manager_factory.cc
+++ b/chrome/browser/permissions/permission_manager_factory.cc
@@ -160,7 +160,12 @@
 PermissionManagerFactory::PermissionManagerFactory()
     : ProfileKeyedServiceFactory(
           "PermissionManagerFactory",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
diff --git a/chrome/browser/permissions/prediction_model_handler_provider_factory.cc b/chrome/browser/permissions/prediction_model_handler_provider_factory.cc
index 5effb90..977b418 100644
--- a/chrome/browser/permissions/prediction_model_handler_provider_factory.cc
+++ b/chrome/browser/permissions/prediction_model_handler_provider_factory.cc
@@ -30,7 +30,12 @@
 PredictionModelHandlerProviderFactory::PredictionModelHandlerProviderFactory()
     : ProfileKeyedServiceFactory(
           "PredictionModelHandlerProvider",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(OptimizationGuideKeyedServiceFactory::GetInstance());
 }
 
diff --git a/chrome/browser/permissions/prediction_service_factory.cc b/chrome/browser/permissions/prediction_service_factory.cc
index 0d055b99..6eb6286d 100644
--- a/chrome/browser/permissions/prediction_service_factory.cc
+++ b/chrome/browser/permissions/prediction_service_factory.cc
@@ -25,7 +25,12 @@
 PredictionServiceFactory::PredictionServiceFactory()
     : ProfileKeyedServiceFactory(
           "PredictionService",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 PredictionServiceFactory::~PredictionServiceFactory() = default;
 
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index 461ff00..70f4718 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -1081,9 +1081,6 @@
   { key::kEasyUnlockAllowed,
     ash::multidevice_setup::kSmartLockAllowedPrefName,
     base::Value::Type::BOOLEAN },
-  { key::kSmartLockSigninAllowed,
-    ash::multidevice_setup::kSmartLockSigninAllowedPrefName,
-    base::Value::Type::BOOLEAN },
   { key::kInstantTetheringAllowed,
     ash::multidevice_setup::kInstantTetheringAllowedPrefName,
     base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/policy/networking/policy_cert_service_factory.cc b/chrome/browser/policy/networking/policy_cert_service_factory.cc
index dc1541f..7651c63 100644
--- a/chrome/browser/policy/networking/policy_cert_service_factory.cc
+++ b/chrome/browser/policy/networking/policy_cert_service_factory.cc
@@ -129,7 +129,12 @@
 PolicyCertServiceFactory::PolicyCertServiceFactory()
     : ProfileKeyedServiceFactory(
           "PolicyCertService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(UserNetworkConfigurationUpdaterFactory::GetInstance());
 }
 
diff --git a/chrome/browser/predictors/autocomplete_action_predictor_factory.cc b/chrome/browser/predictors/autocomplete_action_predictor_factory.cc
index aa98b17c..ca77a7f 100644
--- a/chrome/browser/predictors/autocomplete_action_predictor_factory.cc
+++ b/chrome/browser/predictors/autocomplete_action_predictor_factory.cc
@@ -27,7 +27,12 @@
 AutocompleteActionPredictorFactory::AutocompleteActionPredictorFactory()
     : ProfileKeyedServiceFactory(
           "AutocompleteActionPredictor",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HistoryServiceFactory::GetInstance());
   DependsOn(PredictorDatabaseFactory::GetInstance());
 }
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index f0d6d64b..7861303 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -517,28 +517,6 @@
 // Please keep the list of deprecated prefs in chronological order. i.e. Add to
 // the bottom of the list, not here at the top.
 
-#if !BUILDFLAG(IS_ANDROID)
-// Deprecated 05/2022.
-const char kAccessCodeCastDiscoveredNetworks[] =
-    "media_router.access_code_cast.discovered_networks";
-#endif  // !BUILDFLAG(IS_ANDROID)
-
-#if !BUILDFLAG(IS_CHROMEOS_ASH)
-// Deprecated on non-ChromeOS on 05/2022.
-extern const char kAccountIdMigrationState[] = "account_id_migration_state";
-#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-// Deprecated 05/2022.
-const char kColorModeThemed[] = "ash.dark_mode.color_mode_themed";
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-// Deprecated 05/2022.
-const char kNativeBridge64BitSupportExperimentEnabled[] =
-    "arc.native_bridge_64bit_support_experiment";
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
 // Deprecated 06/2022.
 const char kBackgroundTracingLastUpload[] = "background_tracing.last_upload";
 const char kStabilityGpuCrashCount[] =
@@ -825,15 +803,14 @@
     "chromad.last_migration_attempt_time";
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
+// Deprecated 05/2023.
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+const char kSmartLockSigninAllowed[] = "smart_lock_signin.allowed";
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 // Register local state used only for migration (clearing or moving to a new
 // key).
 void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  // Deprecated 05/2022.
-  registry->RegisterBooleanPref(kNativeBridge64BitSupportExperimentEnabled,
-                                false);
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
   // Deprecated 06/2022.
   registry->RegisterInt64Pref(kBackgroundTracingLastUpload, 0);
   registry->RegisterIntegerPref(kStabilityGpuCrashCount, 0);
@@ -949,18 +926,6 @@
       prefs::kManagedProfileSerialAllowUsbDevicesForUrlsDeprecated);
 #endif
 
-#if !BUILDFLAG(IS_ANDROID)
-  registry->RegisterDictionaryPref(kAccessCodeCastDiscoveredNetworks);
-#endif  // !BUILDFLAG(IS_ANDROID)
-
-#if !BUILDFLAG(IS_CHROMEOS_ASH)
-  registry->RegisterIntegerPref(kAccountIdMigrationState, 0);
-#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  registry->RegisterBooleanPref(kColorModeThemed, true);
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
   registry->RegisterBooleanPref(kTokenServiceDiceCompatible, false);
 #endif  // BUILDFLAG(ENABLE_DICE_SUPPORT)
@@ -1138,6 +1103,11 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   registry->RegisterBooleanPref(kProximityAuthIsChromeOSLoginEnabled, false);
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+// Deprecated 05/2023.
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  registry->RegisterBooleanPref(kSmartLockSigninAllowed, false);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 }  // namespace
@@ -1814,16 +1784,6 @@
   // BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS
   // Please don't delete the preceding line. It is used by PRESUBMIT.py.
 
-  // Added 05/2022.
-#if !BUILDFLAG(IS_ANDROID)
-  local_state->ClearPref(prefs::kTabFreezingEnabled);
-#endif
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  // Added 05/2022.
-  local_state->ClearPref(kNativeBridge64BitSupportExperimentEnabled);
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
   // Added 06/2022.
   local_state->ClearPref(kBackgroundTracingLastUpload);
   local_state->ClearPref(kStabilityGpuCrashCount);
@@ -1947,21 +1907,6 @@
   chrome_browser_net::secure_dns::MigrateProbesSettingToOrFromBackup(
       profile_prefs);
 
-#if !BUILDFLAG(IS_ANDROID)
-  // Added 05/2022
-  profile_prefs->ClearPref(kAccessCodeCastDiscoveredNetworks);
-#endif  // !BUILDFLAG(IS_ANDROID)
-
-#if !BUILDFLAG(IS_CHROMEOS_ASH)
-  // Added 05/2022
-  profile_prefs->ClearPref(kAccountIdMigrationState);
-#endif
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  // Added 05/2022.
-  profile_prefs->ClearPref(kColorModeThemed);
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
   // Added 06/2022.
   profile_prefs->ClearPref(kTokenServiceDiceCompatible);
@@ -2195,6 +2140,11 @@
   profile_prefs->ClearPref(kProximityAuthIsChromeOSLoginEnabled);
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
+// Added 05/2023.
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  profile_prefs->ClearPref(kSmartLockSigninAllowed);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
   // Please don't delete the following line. It is used by PRESUBMIT.py.
   // END_MIGRATE_OBSOLETE_PROFILE_PREFS
 
diff --git a/chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_link_manager_factory.cc b/chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_link_manager_factory.cc
index 9f87ca8..7237363 100644
--- a/chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_link_manager_factory.cc
+++ b/chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_link_manager_factory.cc
@@ -27,7 +27,12 @@
 NoStatePrefetchLinkManagerFactory::NoStatePrefetchLinkManagerFactory()
     : ProfileKeyedServiceFactory(
           "NoStatePrefetchLinkManager",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(NoStatePrefetchManagerFactory::GetInstance());
 }
 
diff --git a/chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.cc b/chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.cc
index 2fa2d65..cf9371a 100644
--- a/chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.cc
+++ b/chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.cc
@@ -36,7 +36,12 @@
 NoStatePrefetchManagerFactory::NoStatePrefetchManagerFactory()
     : ProfileKeyedServiceFactory(
           "NoStatePrefetchManager",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   DependsOn(
       extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service_factory.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_service_factory.cc
index 8e0aac34..0bec023b 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_service_factory.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service_factory.cc
@@ -37,7 +37,12 @@
           "PrivacySandboxService",
           // TODO(crbug.com/1284295): Determine whether this actually needs to
           // be created, or whether all usage in OTR contexts can be removed.
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(PrivacySandboxSettingsFactory::GetInstance());
   DependsOn(CookieSettingsFactory::GetInstance());
   DependsOn(HostContentSettingsMapFactory::GetInstance());
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.cc
index 2cbfdacdb..2ecf355 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.cc
@@ -26,7 +26,12 @@
 PrivacySandboxSettingsFactory::PrivacySandboxSettingsFactory()
     : ProfileKeyedServiceFactory(
           "PrivacySandboxSettings",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   // This service implicitly DependsOn the CookieSettingsFactory,
   // HostContentSettingsMapFactory, and through the delegate, the
   // IdentityManagerFactory but for reasons, cannot explicitly depend on them
diff --git a/chrome/browser/profiles/profile_keyed_service_factory.cc b/chrome/browser/profiles/profile_keyed_service_factory.cc
index f14db439..30a7e6a6 100644
--- a/chrome/browser/profiles/profile_keyed_service_factory.cc
+++ b/chrome/browser/profiles/profile_keyed_service_factory.cc
@@ -8,7 +8,7 @@
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 
 ProfileKeyedServiceFactory::ProfileKeyedServiceFactory(const char* name)
-    : ProfileKeyedServiceFactory(name, ProfileSelections::BuildDefault()) {}
+    : ProfileKeyedServiceFactory(name, ProfileSelections::Builder().Build()) {}
 
 ProfileKeyedServiceFactory::ProfileKeyedServiceFactory(
     const char* name,
diff --git a/chrome/browser/profiles/profile_keyed_service_factory.h b/chrome/browser/profiles/profile_keyed_service_factory.h
index a6c89db..f674426 100644
--- a/chrome/browser/profiles/profile_keyed_service_factory.h
+++ b/chrome/browser/profiles/profile_keyed_service_factory.h
@@ -62,8 +62,6 @@
  protected:
   // Default constructor, will build the Factory with the default implementation
   // for `ProfileSelections`.
-  // Check `ProfileSelections::BuildDefault()` for details on which Profile the
-  // service will be constructed for.
   explicit ProfileKeyedServiceFactory(const char* name);
   // Constructor taking in the overridden `ProfileSelections` for customized
   // Profile types service creation. This is the only way to override the
diff --git a/chrome/browser/profiles/profile_keyed_service_factory_unittest.cc b/chrome/browser/profiles/profile_keyed_service_factory_unittest.cc
index 50bcdf3..511ac4d3 100644
--- a/chrome/browser/profiles/profile_keyed_service_factory_unittest.cc
+++ b/chrome/browser/profiles/profile_keyed_service_factory_unittest.cc
@@ -260,7 +260,12 @@
   PredefinedRefcountedProfileSelectionsFactoryTest()
       : RefcountedProfileKeyedServiceFactoryTest(
             "PredefinedRefcountedProfileSelectionsFactoryTest",
-            ProfileSelections::BuildForRegularAndIncognito()) {}
+            ProfileSelections::Builder()
+                .WithRegular(ProfileSelection::kOwnInstance)
+                // TODO(crbug.com/1418376): Check if this service is needed in
+                // Guest mode.
+                .WithGuest(ProfileSelection::kOwnInstance)
+                .Build()) {}
 };
 
 TEST_P(ProfileKeyedServiceFactoryUnittest,
diff --git a/chrome/browser/profiles/profile_selections.cc b/chrome/browser/profiles/profile_selections.cc
index b0515bd..02d2775f 100644
--- a/chrome/browser/profiles/profile_selections.cc
+++ b/chrome/browser/profiles/profile_selections.cc
@@ -101,8 +101,7 @@
       .Build();
 }
 
-ProfileSelections
-ProfileSelections::BuildForRegularAndIncognitoNonExperimental() {
+ProfileSelections ProfileSelections::BuildForRegularAndIncognito() {
   return ProfileSelections::Builder()
       .WithRegular(ProfileSelection::kOwnInstance)
       .WithGuest(ProfileSelection::kNone)
@@ -127,16 +126,6 @@
       .Build();
 }
 
-ProfileSelections ProfileSelections::BuildDefault(bool force_guest,
-                                                  bool force_system) {
-  Builder builder;
-  if (force_guest)
-    builder.WithGuest(ProfileSelection::kOriginalOnly);
-  if (force_system)
-    builder.WithSystem(ProfileSelection::kOriginalOnly);
-  return builder.Build();
-}
-
 ProfileSelections ProfileSelections::BuildRedirectedInIncognito(
     bool force_guest,
     bool force_system) {
@@ -149,18 +138,6 @@
   return builder.Build();
 }
 
-ProfileSelections ProfileSelections::BuildForRegularAndIncognito(
-    bool force_guest,
-    bool force_system) {
-  Builder builder;
-  builder.WithRegular(ProfileSelection::kOwnInstance);
-  if (force_guest)
-    builder.WithGuest(ProfileSelection::kOwnInstance);
-  if (force_system)
-    builder.WithSystem(ProfileSelection::kOwnInstance);
-  return builder.Build();
-}
-
 Profile* ProfileSelections::ApplyProfileSelection(Profile* profile) const {
   DCHECK(profile);
 
diff --git a/chrome/browser/profiles/profile_selections.h b/chrome/browser/profiles/profile_selections.h
index 6a4cc8f..e208532e 100644
--- a/chrome/browser/profiles/profile_selections.h
+++ b/chrome/browser/profiles/profile_selections.h
@@ -150,7 +150,7 @@
   // | System  | no profile | no profile |
   // | Ash Int.| self       | self       |
   // +---------+------------+------------+
-  static ProfileSelections BuildForRegularAndIncognitoNonExperimental();
+  static ProfileSelections BuildForRegularAndIncognito();
 
   // Redirects incognito profiles to their original regular profile. No
   // profiles for Guest and System profiles. "NonExperimental" is added to
@@ -195,36 +195,6 @@
   // behavior is described per experimental builder. The parameters force_* will
   // allow to have an easier transition when adapting to the experiment.
 
-  // Default implementation:
-  // Without any parameters explicitly set, this is equivalent to
-  // `ProfileSlections::Builder().Build()`, where the following selection
-  // happens:
-  // +---------+------------+------------+
-  // |         |  Original  |    OTR     |
-  // +---------+------------+------------+
-  // | Regular | self       | no profile |
-  // | Guest   | no profile | no profile |
-  // | System  | experiment*| no profile |
-  // | Ash Int.| self       | no profile |
-  // +---------+------------+------------+
-  //
-  // experiment*: System Profile default value is set through this constructor,
-  // however the default value is experiment dependant
-  // (`kSystemProfileSelectionDefaultNone`):
-  // - enabled (future behavior): no profile
-  // - disabled: self
-  //
-  // Parameters:
-  // - force_guest: if true, force Guest with `ProfileSelection::kOriginalOnly`,
-  // note* below. This is not recommended, consider using explicit
-  // `ProfileSlections::Builder::WithGuest()` instead.
-  // - force_system: if true, force System with
-  // `ProfileSelection::kOriginalOnly` to by pass the
-  // `kSystemProfileSelectionDefaultNone`. This is not recommended, use explicit
-  // `ProfileSlections::Builder::WithSystem()` instead.
-  static ProfileSelections BuildDefault(bool force_guest = false,
-                                        bool force_system = false);
-
   // Without the experiment:
   // - Returns Regular for Regular, incognito and other regular OTR profiles.
   // - Returns Guest Original for GuestOriginal  and GuestOTR (same as Regular).
@@ -264,33 +234,6 @@
       bool force_guest = true,
       bool force_system = false);
 
-  // Without the experiment:
-  // +---------+------------+------------+
-  // |         |  Original  |    OTR     |
-  // +---------+------------+------------+
-  // | Regular | self       | self       |
-  // | Guest   | self       | self       |
-  // | System  | self       | self       |
-  // | Ash Int.| self       | self       |
-  // +---------+------------+------------+
-  //
-  // With the experiment:
-  // +---------+------------+------------+
-  // |         |  Original  |    OTR     |
-  // +---------+------------+------------+
-  // | Regular | self       | self       |
-  // | Guest   | no profile | no profile |
-  // | System  | no profile | no profile |
-  // | Ash Int.| self       | self       |
-  // +---------+------------+------------+
-  //
-  // Parameters: (used during the experiment)
-  // - force_guest: true, force Guest with `ProfileSelecion::kOwnInstance`.
-  // - force_system: true, force System with `ProfileSelecion::kOwnInstance`.
-  static ProfileSelections BuildForRegularAndIncognito(
-      bool force_guest = true,
-      bool force_system = false);
-
   // Given a Profile and a ProfileSelection enum, returns the right profile
   // (can potentially return nullptr).
   Profile* ApplyProfileSelection(Profile* profile) const;
diff --git a/chrome/browser/profiles/profile_selections_unittest.cc b/chrome/browser/profiles/profile_selections_unittest.cc
index d06cc395..f83181c 100644
--- a/chrome/browser/profiles/profile_selections_unittest.cc
+++ b/chrome/browser/profiles/profile_selections_unittest.cc
@@ -86,7 +86,7 @@
 
 TEST_F(ProfileSelectionsTest, RegularAndIncognito) {
   ProfileSelections selections =
-      ProfileSelections::BuildForRegularAndIncognitoNonExperimental();
+      ProfileSelections::BuildForRegularAndIncognito();
 
   TestProfileSelection(selections, regular_profile(), regular_profile());
   TestProfileSelection(selections, incognito_profile(), incognito_profile());
@@ -295,70 +295,6 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
-TEST_P(ProfileSelectionsTestWithParams, BuildDefault_WithDefaultValues) {
-  ProfileSelections selections = ProfileSelections::BuildDefault();
-
-  TestProfileSelection(selections, regular_profile(), regular_profile());
-  TestProfileSelection(selections, incognito_profile(), nullptr);
-
-  TestProfileSelection(selections, guest_profile(), nullptr);
-  TestProfileSelection(selections, guest_profile_otr(), nullptr);
-
-#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
-  bool system_experiment = IsSystemExperimentActive();
-  TestProfileSelection(selections, system_profile(),
-                       system_experiment ? nullptr : system_profile());
-  TestProfileSelection(selections, system_profile_otr(), nullptr);
-#endif  // !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  TestProfileSelection(selections, signin_profile(), signin_profile());
-  TestProfileSelection(selections, signin_profile_otr(), nullptr);
-
-  TestProfileSelection(selections, lockscreen_profile(), lockscreen_profile());
-  TestProfileSelection(selections, lockscreen_profile_otr(), nullptr);
-
-  TestProfileSelection(selections, lockscreenapp_profile(),
-                       lockscreenapp_profile());
-  TestProfileSelection(selections, lockscreenapp_profile_otr(), nullptr);
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-}
-
-TEST_P(ProfileSelectionsTestWithParams, BuildDefault) {
-  bool force_guest = std::get<0>(GetParam());
-  bool force_system = std::get<1>(GetParam());
-
-  ProfileSelections selections =
-      ProfileSelections::BuildDefault(force_guest, force_system);
-
-  TestProfileSelection(selections, regular_profile(), regular_profile());
-  TestProfileSelection(selections, incognito_profile(), nullptr);
-
-  TestProfileSelection(selections, guest_profile(),
-                       force_guest ? guest_profile() : nullptr);
-  TestProfileSelection(selections, guest_profile_otr(), nullptr);
-
-#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
-  bool system_experiment = IsSystemExperimentActive();
-  TestProfileSelection(
-      selections, system_profile(),
-      force_system || !system_experiment ? system_profile() : nullptr);
-  TestProfileSelection(selections, system_profile_otr(), nullptr);
-#endif  // !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  TestProfileSelection(selections, signin_profile(), signin_profile());
-  TestProfileSelection(selections, signin_profile_otr(), nullptr);
-
-  TestProfileSelection(selections, lockscreen_profile(), lockscreen_profile());
-  TestProfileSelection(selections, lockscreen_profile_otr(), nullptr);
-
-  TestProfileSelection(selections, lockscreenapp_profile(),
-                       lockscreenapp_profile());
-  TestProfileSelection(selections, lockscreenapp_profile_otr(), nullptr);
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-}
-
 TEST_P(ProfileSelectionsTestWithParams, BuildRedirectedInIncognito) {
   bool force_guest = std::get<0>(GetParam());
   bool force_system = std::get<1>(GetParam());
@@ -399,46 +335,6 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
-TEST_P(ProfileSelectionsTestWithParams, BuildForRegularAndIncognito) {
-  bool force_guest = std::get<0>(GetParam());
-  bool force_system = std::get<1>(GetParam());
-
-  ProfileSelections selections =
-      ProfileSelections::BuildForRegularAndIncognito(force_guest, force_system);
-
-  TestProfileSelection(selections, regular_profile(), regular_profile());
-  TestProfileSelection(selections, incognito_profile(), incognito_profile());
-
-  TestProfileSelection(selections, guest_profile(),
-                       force_guest ? guest_profile() : nullptr);
-  TestProfileSelection(selections, guest_profile_otr(),
-                       force_guest ? guest_profile_otr() : nullptr);
-
-#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
-  bool system_experiment = IsSystemExperimentActive();
-  TestProfileSelection(
-      selections, system_profile(),
-      force_system || !system_experiment ? system_profile() : nullptr);
-  TestProfileSelection(
-      selections, system_profile_otr(),
-      force_system || !system_experiment ? system_profile_otr() : nullptr);
-#endif  // !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  TestProfileSelection(selections, signin_profile(), signin_profile());
-  TestProfileSelection(selections, signin_profile_otr(), signin_profile_otr());
-
-  TestProfileSelection(selections, lockscreen_profile(), lockscreen_profile());
-  TestProfileSelection(selections, lockscreen_profile_otr(),
-                       lockscreen_profile_otr());
-
-  TestProfileSelection(selections, lockscreenapp_profile(),
-                       lockscreenapp_profile());
-  TestProfileSelection(selections, lockscreenapp_profile_otr(),
-                       lockscreenapp_profile_otr());
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-}
-
 INSTANTIATE_TEST_SUITE_P(ExperimentalBuilders,
                          ProfileSelectionsTestWithParams,
                          ::testing::Combine(::testing::Bool(),
diff --git a/chrome/browser/profiles/refcounted_profile_keyed_service_factory.cc b/chrome/browser/profiles/refcounted_profile_keyed_service_factory.cc
index 6205ea7..4765b52 100644
--- a/chrome/browser/profiles/refcounted_profile_keyed_service_factory.cc
+++ b/chrome/browser/profiles/refcounted_profile_keyed_service_factory.cc
@@ -9,8 +9,9 @@
 
 RefcountedProfileKeyedServiceFactory::RefcountedProfileKeyedServiceFactory(
     const char* name)
-    : RefcountedProfileKeyedServiceFactory(name,
-                                           ProfileSelections::BuildDefault()) {}
+    : RefcountedProfileKeyedServiceFactory(
+          name,
+          ProfileSelections::Builder().Build()) {}
 
 RefcountedProfileKeyedServiceFactory::RefcountedProfileKeyedServiceFactory(
     const char* name,
diff --git a/chrome/browser/profiles/refcounted_profile_keyed_service_factory.h b/chrome/browser/profiles/refcounted_profile_keyed_service_factory.h
index 925ed44..ba18450 100644
--- a/chrome/browser/profiles/refcounted_profile_keyed_service_factory.h
+++ b/chrome/browser/profiles/refcounted_profile_keyed_service_factory.h
@@ -27,8 +27,6 @@
  protected:
   // Default constructor, will build the Factory with the default implementation
   // for `ProfileSelections`.
-  // Check `ProfileSelections::BuildDefault()` for details on which Profile the
-  // service will be constructed for.
   explicit RefcountedProfileKeyedServiceFactory(const char* name);
   // Constructor taking in the overridden `ProfileSelections` for customized
   // Profile types service creation. This is the only way to override the
diff --git a/chrome/browser/profiles/renderer_updater_factory.cc b/chrome/browser/profiles/renderer_updater_factory.cc
index 51fae48..908a1c3 100644
--- a/chrome/browser/profiles/renderer_updater_factory.cc
+++ b/chrome/browser/profiles/renderer_updater_factory.cc
@@ -16,7 +16,12 @@
 RendererUpdaterFactory::RendererUpdaterFactory()
     : ProfileKeyedServiceFactory(
           "RendererUpdater",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(IdentityManagerFactory::GetInstance());
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 #if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS)
diff --git a/chrome/browser/push_messaging/push_messaging_service_factory.cc b/chrome/browser/push_messaging/push_messaging_service_factory.cc
index 8fe81fb45..ca562ef 100644
--- a/chrome/browser/push_messaging/push_messaging_service_factory.cc
+++ b/chrome/browser/push_messaging/push_messaging_service_factory.cc
@@ -43,7 +43,12 @@
 PushMessagingServiceFactory::PushMessagingServiceFactory()
     : ProfileKeyedServiceFactory(
           "PushMessagingProfileService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(gcm::GCMProfileServiceFactory::GetInstance());
   DependsOn(instance_id::InstanceIDProfileServiceFactory::GetInstance());
   DependsOn(HostContentSettingsMapFactory::GetInstance());
diff --git a/chrome/browser/reduce_accept_language/reduce_accept_language_factory.cc b/chrome/browser/reduce_accept_language/reduce_accept_language_factory.cc
index d2548345..ac3d4bce 100644
--- a/chrome/browser/reduce_accept_language/reduce_accept_language_factory.cc
+++ b/chrome/browser/reduce_accept_language/reduce_accept_language_factory.cc
@@ -24,7 +24,12 @@
 ReduceAcceptLanguageFactory::ReduceAcceptLanguageFactory()
     : ProfileKeyedServiceFactory(
           "ReduceAcceptLanguage",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
diff --git a/chrome/browser/resources/chromeos/parent_access/parent_access_before.html b/chrome/browser/resources/chromeos/parent_access/parent_access_before.html
index 493eac7..517ac496 100644
--- a/chrome/browser/resources/chromeos/parent_access/parent_access_before.html
+++ b/chrome/browser/resources/chromeos/parent_access/parent_access_before.html
@@ -31,7 +31,7 @@
   <picture>
     <source srcset="images/request_approval_dark.svg"
         media="(prefers-color-scheme: dark)">
-    <img src="images/request_approval.svg" id="illustration">
+    <img src="images/request_approval.svg" id="illustration" alt="">
   </picture>
   <div id="before-screen-body" aria-live="polite"></div>
   <div id="before-screen-buttons">
diff --git a/chrome/browser/resources/chromeos/parent_access/parent_access_disabled.html b/chrome/browser/resources/chromeos/parent_access/parent_access_disabled.html
index d9d86b5..6f6fb76 100644
--- a/chrome/browser/resources/chromeos/parent_access/parent_access_disabled.html
+++ b/chrome/browser/resources/chromeos/parent_access/parent_access_disabled.html
@@ -31,7 +31,7 @@
   <picture>
     <source srcset="images/request_approval_dark.svg"
         media="(prefers-color-scheme: dark)">
-    <img src="images/request_approval.svg" id="illustration">
+    <img src="images/request_approval.svg" id="illustration" alt="">
   </picture>
   <div id="disabled-screen-content"></div>
   <div id="disabled-screen-buttons">
diff --git a/chrome/browser/resources/net_internals/dns_view.js b/chrome/browser/resources/net_internals/dns_view.js
index ab9ebb3..9eed796 100644
--- a/chrome/browser/resources/net_internals/dns_view.js
+++ b/chrome/browser/resources/net_internals/dns_view.js
@@ -47,22 +47,16 @@
           div.textContent =
               `Resolved IP addresses of "${hostname}": ${resolvedAddresses}.`;
           div.style.fontWeight = 'bold';
-          if (result.endpoint_results_with_metadata.length > 0) {
-            result.endpoint_results_with_metadata.map(
-                (endpoint_result_with_metadata) => {
-                  const ipEndpoints = JSON.stringify(
-                      endpoint_result_with_metadata.ip_endpoints);
-                  const supportedProtocolAlpns =
-                      JSON.stringify(endpoint_result_with_metadata.metadata
-                                         .supported_protocol_alpns);
-                  const div = addNode(span, 'div');
-                  div.textContent = 'Supported protocol alpns of ' +
-                      `"${ipEndpoints}": ${supportedProtocolAlpns}.`;
-                  div.style.fontWeight = 'bold';
-                });
+          if (result.alternative_endpoints.length > 0) {
+            result.alternative_endpoints.forEach((endpoint) => {
+              const json = JSON.stringify(endpoint);
+              const div = addNode(span, 'div');
+              div.textContent = `Alternative endpoint: ${json}.`;
+              div.style.fontWeight = 'bold';
+            });
           } else {
             const div = addNode(span, 'div');
-            div.textContent = `No data on which protocols are supported.`;
+            div.textContent = `No alternative endpoints.`;
             div.style.fontWeight = 'bold';
           }
         })
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.ts b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.ts
index 2dae98fe..b351035 100644
--- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.ts
+++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.ts
@@ -39,12 +39,6 @@
   setUpAndroidSms(): void;
 
   /**
-   * Returns the value of the preference controlling whether Smart Lock
-   * sign-in is allowed.
-   */
-  getSmartLockSignInAllowed(): Promise<boolean>;
-
-  /**
    * Returns android messages info with messages feature state
    * and messages for web permissions origin.
    */
@@ -163,10 +157,6 @@
     chrome.send('setUpAndroidSms');
   }
 
-  getSmartLockSignInAllowed(): Promise<boolean> {
-    return sendWithPromise('getSmartLockSignInAllowed');
-  }
-
   getAndroidSmsInfo(): Promise<AndroidSmsInfo> {
     return sendWithPromise('getAndroidSmsInfo');
   }
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_factory.cc b/chrome/browser/safe_browsing/certificate_reporting_service_factory.cc
index 5d4ed6f..30aea69 100644
--- a/chrome/browser/safe_browsing/certificate_reporting_service_factory.cc
+++ b/chrome/browser/safe_browsing/certificate_reporting_service_factory.cc
@@ -77,7 +77,12 @@
 CertificateReportingServiceFactory::CertificateReportingServiceFactory()
     : ProfileKeyedServiceFactory(
           "cert_reporting::Factory",
-          ProfileSelections::BuildForRegularAndIncognito()),
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()),
       server_public_key_(nullptr),
       server_public_key_version_(0),
       clock_(base::DefaultClock::GetInstance()),
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.h b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.h
index 182a9a6..95b793c 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.h
+++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.h
@@ -83,7 +83,8 @@
   bool prompt_pending_ = false;
   raw_ptr<Browser, DanglingUntriaged> browser_ = nullptr;
   std::unique_ptr<ChromeCleanerPromptDelegate> prompt_delegate_impl_;
-  raw_ptr<ChromeCleanerPromptDelegate> prompt_delegate_ = nullptr;
+  raw_ptr<ChromeCleanerPromptDelegate, DanglingUntriaged> prompt_delegate_ =
+      nullptr;
 };
 
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_factory.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_factory.cc
index c1562fe..3433c2c 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service_factory.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service_factory.cc
@@ -37,7 +37,12 @@
 ChromePasswordProtectionServiceFactory::ChromePasswordProtectionServiceFactory()
     : ProfileKeyedServiceFactory(
           "ChromePasswordProtectionService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HistoryServiceFactory::GetInstance());
   DependsOn(VerdictCacheManagerFactory::GetInstance());
   DependsOn(IdentityManagerFactory::GetInstance());
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service_factory.cc b/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service_factory.cc
index f31d1c8..57e427b9 100644
--- a/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service_factory.cc
+++ b/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service_factory.cc
@@ -30,7 +30,12 @@
 CloudBinaryUploadServiceFactory::CloudBinaryUploadServiceFactory()
     : ProfileKeyedServiceFactory(
           "CloudBinaryUploadService",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 KeyedService* CloudBinaryUploadServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc
index df48ec7..8d04219 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc
@@ -30,7 +30,12 @@
     SafeBrowsingNavigationObserverManagerFactory()
     : ProfileKeyedServiceFactory(
           "SafeBrowsingNavigationObserverManager",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 KeyedService*
 SafeBrowsingNavigationObserverManagerFactory::BuildServiceInstanceFor(
diff --git a/chrome/browser/safe_browsing/verdict_cache_manager_factory.cc b/chrome/browser/safe_browsing/verdict_cache_manager_factory.cc
index 94e60786..22563b4 100644
--- a/chrome/browser/safe_browsing/verdict_cache_manager_factory.cc
+++ b/chrome/browser/safe_browsing/verdict_cache_manager_factory.cc
@@ -30,7 +30,12 @@
 VerdictCacheManagerFactory::VerdictCacheManagerFactory()
     : ProfileKeyedServiceFactory(
           "VerdictCacheManager",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HistoryServiceFactory::GetInstance());
   DependsOn(HostContentSettingsMapFactory::GetInstance());
   DependsOn(SyncServiceFactory::GetInstance());
diff --git a/chrome/browser/search/instant_service_factory.cc b/chrome/browser/search/instant_service_factory.cc
index d10b6f0..3d299c24 100644
--- a/chrome/browser/search/instant_service_factory.cc
+++ b/chrome/browser/search/instant_service_factory.cc
@@ -25,7 +25,12 @@
 InstantServiceFactory::InstantServiceFactory()
     : ProfileKeyedServiceFactory(
           "InstantService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(ThemeServiceFactory::GetInstance());
 }
 
diff --git a/chrome/browser/serial/serial_chooser_context_factory.cc b/chrome/browser/serial/serial_chooser_context_factory.cc
index 864746a..ce4c309 100644
--- a/chrome/browser/serial/serial_chooser_context_factory.cc
+++ b/chrome/browser/serial/serial_chooser_context_factory.cc
@@ -11,7 +11,12 @@
 SerialChooserContextFactory::SerialChooserContextFactory()
     : ProfileKeyedServiceFactory(
           "SerialChooserContext",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.cc b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.cc
index c25dc65..ce8a802db 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.cc
@@ -9,8 +9,9 @@
 #include "base/functional/bind.h"
 #include "base/time/time.h"
 #include "chrome/browser/signin/bound_session_credentials/bound_session_cookie_observer.h"
-#include "chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher.h"
+#include "chrome/browser/signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher.h"
 #include "components/signin/public/base/signin_client.h"
+#include "net/http/http_status_code.h"
 
 BoundSessionCookieControllerImpl::BoundSessionCookieControllerImpl(
     SigninClient* client,
@@ -65,9 +66,15 @@
 
 std::unique_ptr<BoundSessionRefreshCookieFetcher>
 BoundSessionCookieControllerImpl::CreateRefreshCookieFetcher() const {
+  // TODO(b/273920907): Replace with `BoundSessionRefreshCookieFetcherImpl` once
+  // implemented.
+  constexpr base::TimeDelta kFakeNetworkRequestEquivalentDelay(
+      base::Milliseconds(100));
   return refresh_cookie_fetcher_factory_for_testing_.is_null()
-             ? std::make_unique<BoundSessionRefreshCookieFetcher>(client_, url_,
-                                                                  cookie_name_)
+             ? std::make_unique<FakeBoundSessionRefreshCookieFetcher>(
+                   client_, url_, cookie_name_,
+                   /*unlock_automatically_in=*/
+                   kFakeNetworkRequestEquivalentDelay)
              : refresh_cookie_fetcher_factory_for_testing_.Run(client_, url_,
                                                                cookie_name_);
 }
@@ -86,22 +93,21 @@
 }
 
 void BoundSessionCookieControllerImpl::OnCookieRefreshFetched(
-    absl::optional<base::Time> expiration_time) {
+    BoundSessionRefreshCookieFetcher::Result result) {
   refresh_cookie_fetcher_.reset();
-  if (expiration_time.has_value()) {
-    // Cookie fetch succeeded.
-    // We do not check for null time and honor the expiration date of the cookie
-    // sent by the server.
-    // TODO(b/263264391): Rely on the observer notification to complete the
-    // request.
-    if (expiration_time.value() < base::Time::Now()) {
-      NOTIMPLEMENTED();
+  if (result.net_error == net::OK && result.response_code.has_value() &&
+      result.response_code.value() == net::HTTP_OK) {
+    // Requests are resumed once the cookie is set in the cookie jar. The cookie
+    // is expected to be fresh and `this` is notified with its expiration date
+    // before `OnCookieRefreshFetched` is called.
+    if (cookie_expiration_time_ > base::Time::Now()) {
+      CHECK(resume_blocked_requests_.empty());
+      return;
     }
-    SetCookieExpirationTimeAndNotify(expiration_time.value());
-  } else {
-    ResumeBlockedRequests();
   }
   // TODO(b/263263352): Handle error cases.
+  ResumeBlockedRequests();
+  NOTIMPLEMENTED();
 }
 
 void BoundSessionCookieControllerImpl::ResumeBlockedRequests() {
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.h b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.h
index 01eee7ab..21e189ed 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.h
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.h
@@ -56,7 +56,7 @@
 
   void MaybeRefreshCookie();
   void SetCookieExpirationTimeAndNotify(base::Time expiration_time);
-  void OnCookieRefreshFetched(absl::optional<base::Time> expiration_time);
+  void OnCookieRefreshFetched(BoundSessionRefreshCookieFetcher::Result result);
   void ResumeBlockedRequests();
 
   void set_refresh_cookie_fetcher_factory_for_testing(
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl_unittest.cc b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl_unittest.cc
index baeb976..a0a5a72 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl_unittest.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl_unittest.cc
@@ -12,8 +12,8 @@
 #include "base/time/time.h"
 #include "chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller.h"
 #include "chrome/browser/signin/bound_session_credentials/bound_session_cookie_observer.h"
-#include "chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher.h"
 #include "chrome/browser/signin/bound_session_credentials/bound_session_test_cookie_manager.h"
+#include "chrome/browser/signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher.h"
 #include "components/signin/public/base/test_signin_client.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "google_apis/gaia/gaia_urls.h"
@@ -27,29 +27,6 @@
 base::Time GetTimeInTenMinutes() {
   return base::Time::Now() + base::Minutes(10);
 }
-
-class FakeBoundSessionRefreshCookieFetcher
-    : public BoundSessionRefreshCookieFetcher {
- public:
-  FakeBoundSessionRefreshCookieFetcher(SigninClient* client,
-                                       const GURL& url,
-                                       const std::string& cookie_name)
-      : BoundSessionRefreshCookieFetcher(client, url, cookie_name) {}
-
-  void Start(RefreshCookieCompleteCallback callback) override {
-    callback_ = std::move(callback);
-  }
-
-  void SimulateCompleteRefreshRequest(
-      absl::optional<base::Time> cookie_expiration) {
-    if (cookie_expiration.has_value()) {
-      // Synchronous since tests use `BoundSessionTestCookieManager`.
-      OnRefreshCookieCompleted(CreateFakeCookie(cookie_expiration.value()));
-    } else {
-      std::move(callback_).Run(cookie_expiration);
-    }
-  }
-};
 }  // namespace
 
 class BoundSessionCookieControllerImplTest
@@ -95,6 +72,7 @@
       return false;
     }
     SimulateCompleteRefreshRequest(GetTimeInTenMinutes());
+    task_environment_.RunUntilIdle();
     return true;
   }
 
@@ -260,6 +238,7 @@
 
   // Simulate refresh complete.
   SimulateCompleteRefreshRequest(GetTimeInTenMinutes());
+  task_environment()->RunUntilIdle();
   EXPECT_TRUE(future.IsReady());
   EXPECT_EQ(controller->cookie_expiration_time(), GetTimeInTenMinutes());
 }
@@ -281,8 +260,8 @@
   EXPECT_FALSE(future.IsReady());
 
   // Simulate refresh complete with failure.
-  // Callbacks should be called regardless of success, failure.
   SimulateCompleteRefreshRequest(absl::nullopt);
+  task_environment()->RunUntilIdle();
   EXPECT_TRUE(future.IsReady());
   EXPECT_EQ(controller->cookie_expiration_time(), cookie_expiration);
 }
@@ -302,6 +281,7 @@
   }
 
   SimulateCompleteRefreshRequest(GetTimeInTenMinutes());
+  task_environment()->RunUntilIdle();
   for (auto& future : futures) {
     EXPECT_TRUE(future.IsReady());
   }
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher.cc b/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher.cc
deleted file mode 100644
index f826cf40..0000000
--- a/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher.h"
-
-#include "base/functional/callback.h"
-#include "base/task/sequenced_task_runner.h"
-#include "base/time/time.h"
-#include "components/signin/public/base/signin_client.h"
-#include "mojo/public/cpp/bindings/callback_helpers.h"
-#include "net/cookies/canonical_cookie.h"
-#include "services/network/public/mojom/cookie_manager.mojom.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
-
-BoundSessionRefreshCookieFetcher::BoundSessionRefreshCookieFetcher(
-    SigninClient* client,
-    const GURL& url,
-    const std::string& cookie_name)
-    : client_(client), url_(url), cookie_name_(cookie_name) {}
-
-BoundSessionRefreshCookieFetcher::~BoundSessionRefreshCookieFetcher() = default;
-
-void BoundSessionRefreshCookieFetcher::Start(
-    RefreshCookieCompleteCallback callback) {
-  const base::TimeDelta kMaxAge = base::Minutes(10);
-  DCHECK(!callback_);
-  callback_ = std::move(callback);
-
-  constexpr base::TimeDelta kFakeNetworkRequestEquivalentDelay(
-      base::Milliseconds(100));
-  base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
-      FROM_HERE,
-      base::BindOnce(
-          &BoundSessionRefreshCookieFetcher::OnRefreshCookieCompleted,
-          weak_ptr_factory_.GetWeakPtr(),
-          CreateFakeCookie(base::Time::Now() + kMaxAge)),
-      kFakeNetworkRequestEquivalentDelay);
-}
-
-void BoundSessionRefreshCookieFetcher::OnRefreshCookieCompleted(
-    std::unique_ptr<net::CanonicalCookie> cookie) {
-  InsertCookieInCookieJar(std::move(cookie));
-}
-
-void BoundSessionRefreshCookieFetcher::InsertCookieInCookieJar(
-    std::unique_ptr<net::CanonicalCookie> cookie) {
-  DCHECK(client_);
-  base::OnceCallback<void(net::CookieAccessResult)> callback =
-      base::BindOnce(&BoundSessionRefreshCookieFetcher::OnCookieSet,
-                     weak_ptr_factory_.GetWeakPtr(), cookie->ExpiryDate());
-  net::CookieOptions options;
-  options.set_include_httponly();
-  // Permit it to set a SameSite cookie if it wants to.
-  options.set_same_site_cookie_context(
-      net::CookieOptions::SameSiteCookieContext::MakeInclusive());
-  client_->GetCookieManager()->SetCanonicalCookie(
-      *cookie, url_, options,
-      mojo::WrapCallbackWithDefaultInvokeIfNotRun(
-          std::move(callback),
-          net::CookieAccessResult(net::CookieInclusionStatus(
-              net::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR))));
-}
-
-void BoundSessionRefreshCookieFetcher::OnCookieSet(
-    base::Time expiry_date,
-    net::CookieAccessResult access_result) {
-  bool success = access_result.status.IsInclude();
-  if (!success) {
-    std::move(callback_).Run(absl::nullopt);
-  } else {
-    std::move(callback_).Run(expiry_date);
-  }
-  // |This| may be destroyed
-}
-
-std::unique_ptr<net::CanonicalCookie>
-BoundSessionRefreshCookieFetcher::CreateFakeCookie(
-    base::Time cookie_expiration) {
-  constexpr char kFakeCookieValue[] = "FakeCookieValue";
-
-  base::Time now = base::Time::Now();
-  // Create fake SIDTS cookie until the server endpoint is available.
-  std::unique_ptr<net::CanonicalCookie> new_cookie =
-      net::CanonicalCookie::CreateSanitizedCookie(
-          /*url=*/url_, /*name=*/cookie_name_,
-          /*value=*/kFakeCookieValue,
-          /*domain=*/url_.host(), /*path=*/"/",
-          /*creation_time=*/now, /*expiration_time=*/cookie_expiration,
-          /*last_access_time=*/now, /*secure=*/true,
-          /*http_only=*/true, net::CookieSameSite::UNSPECIFIED,
-          net::CookiePriority::COOKIE_PRIORITY_HIGH,
-          /*same_party=*/true, /*partition_key=*/absl::nullopt);
-
-  DCHECK(new_cookie);
-  return new_cookie;
-}
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher.h b/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher.h
index d4da368b..2f2f61de 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher.h
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher.h
@@ -1,50 +1,37 @@
-// Copyright 2022 The Chromium Authors
+// Copyright 2023 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #ifndef CHROME_BROWSER_SIGNIN_BOUND_SESSION_CREDENTIALS_BOUND_SESSION_REFRESH_COOKIE_FETCHER_H_
 #define CHROME_BROWSER_SIGNIN_BOUND_SESSION_CREDENTIALS_BOUND_SESSION_REFRESH_COOKIE_FETCHER_H_
 
-#include "base/functional/callback.h"
-#include "base/memory/raw_ptr.h"
-#include "base/time/time.h"
+#include "net/base/net_errors.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
-#include "net/cookies/canonical_cookie.h"
-
-class SigninClient;
-
+// This class makes the network request to the Gaia cookie rotation endpoint to
+// refresh bound Google authentication cookies. A new fetcher instance should be
+// created per request.
 class BoundSessionRefreshCookieFetcher {
  public:
-  // Returns the expected expiration date of the cookie. This is optional as
-  // set cookie might fail.
-  using RefreshCookieCompleteCallback =
-      base::OnceCallback<void(absl::optional<base::Time>)>;
+  struct Result {
+    net::Error net_error;
+    absl::optional<int> response_code;
+  };
+  // Reports the result of the fetch request.
+  using RefreshCookieCompleteCallback = base::OnceCallback<void(Result)>;
 
-  BoundSessionRefreshCookieFetcher(SigninClient* client,
-                                   const GURL& url,
-                                   const std::string& cookie_name);
-  virtual ~BoundSessionRefreshCookieFetcher();
+  BoundSessionRefreshCookieFetcher() = default;
+  virtual ~BoundSessionRefreshCookieFetcher() = default;
 
   BoundSessionRefreshCookieFetcher(const BoundSessionRefreshCookieFetcher&) =
       delete;
   BoundSessionRefreshCookieFetcher& operator=(
       const BoundSessionRefreshCookieFetcher&) = delete;
 
-  virtual void Start(RefreshCookieCompleteCallback callback);
-
- protected:
-  std::unique_ptr<net::CanonicalCookie> CreateFakeCookie(
-      base::Time cookie_expiration);
-  void OnRefreshCookieCompleted(std::unique_ptr<net::CanonicalCookie> cookie);
-  void InsertCookieInCookieJar(std::unique_ptr<net::CanonicalCookie> cookie);
-  void OnCookieSet(base::Time expiry_date,
-                   net::CookieAccessResult access_result);
-
-  const raw_ptr<SigninClient> client_;
-  const GURL url_;
-  const std::string cookie_name_;
-  RefreshCookieCompleteCallback callback_;
-  base::WeakPtrFactory<BoundSessionRefreshCookieFetcher> weak_ptr_factory_{
-      this};
+  // Starts the network request to the Gaia rotation endpoint. `callback` is
+  // called with the fetch results upon completion. Should be called no more
+  // than once per instance.
+  virtual void Start(RefreshCookieCompleteCallback callback) = 0;
 };
+
 #endif  // CHROME_BROWSER_SIGNIN_BOUND_SESSION_CREDENTIALS_BOUND_SESSION_REFRESH_COOKIE_FETCHER_H_
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_test_cookie_manager.cc b/chrome/browser/signin/bound_session_credentials/bound_session_test_cookie_manager.cc
index fe291d240..d1d5f6b6e 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_test_cookie_manager.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_test_cookie_manager.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/signin/bound_session_credentials/bound_session_test_cookie_manager.h"
 
 #include "net/cookies/cookie_access_result.h"
+#include "net/cookies/cookie_change_dispatcher.h"
 
 // static
 net::CanonicalCookie BoundSessionTestCookieManager::CreateCookie(
@@ -29,6 +30,8 @@
     const net::CookieOptions& cookie_options,
     SetCanonicalCookieCallback callback) {
   cookie_ = cookie;
+  DispatchCookieChange(net::CookieChangeInfo(cookie_, net::CookieAccessResult(),
+                                             net::CookieChangeCause::INSERTED));
   if (callback) {
     std::move(callback).Run(net::CookieAccessResult());
   }
diff --git a/chrome/browser/signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher.cc b/chrome/browser/signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher.cc
new file mode 100644
index 0000000..b4b1a07
--- /dev/null
+++ b/chrome/browser/signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher.cc
@@ -0,0 +1,113 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher.h"
+
+#include "base/functional/callback.h"
+#include "base/task/sequenced_task_runner.h"
+#include "base/time/time.h"
+#include "components/signin/public/base/signin_client.h"
+#include "mojo/public/cpp/bindings/callback_helpers.h"
+#include "net/base/net_errors.h"
+#include "net/cookies/canonical_cookie.h"
+#include "net/http/http_status_code.h"
+#include "services/network/public/mojom/cookie_manager.mojom.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+FakeBoundSessionRefreshCookieFetcher::FakeBoundSessionRefreshCookieFetcher(
+    SigninClient* client,
+    const GURL& url,
+    const std::string& cookie_name,
+    absl::optional<base::TimeDelta> unlock_automatically_in)
+    : client_(client),
+      url_(url),
+      cookie_name_(cookie_name),
+      unlock_automatically_in_(unlock_automatically_in) {}
+
+FakeBoundSessionRefreshCookieFetcher::~FakeBoundSessionRefreshCookieFetcher() =
+    default;
+
+void FakeBoundSessionRefreshCookieFetcher::Start(
+    RefreshCookieCompleteCallback callback) {
+  DCHECK(!callback_);
+  callback_ = std::move(callback);
+
+  if (unlock_automatically_in_.has_value()) {
+    const base::TimeDelta kMaxAge = base::Minutes(10);
+    base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
+        FROM_HERE,
+        base::BindOnce(&FakeBoundSessionRefreshCookieFetcher::
+                           SimulateCompleteRefreshRequest,
+                       weak_ptr_factory_.GetWeakPtr(),
+                       base::Time::Now() + kMaxAge),
+        unlock_automatically_in_.value());
+  }
+}
+
+void FakeBoundSessionRefreshCookieFetcher::SimulateCompleteRefreshRequest(
+    absl::optional<base::Time> cookie_expiration) {
+  if (cookie_expiration.has_value()) {
+    // Synchronous since tests use `BoundSessionTestCookieManager`.
+    OnRefreshCookieCompleted(CreateFakeCookie(cookie_expiration.value()));
+  } else {
+    std::move(callback_).Run(Result(net::Error::OK, net::HTTP_FORBIDDEN));
+  }
+}
+
+void FakeBoundSessionRefreshCookieFetcher::OnRefreshCookieCompleted(
+    std::unique_ptr<net::CanonicalCookie> cookie) {
+  InsertCookieInCookieJar(std::move(cookie));
+}
+
+void FakeBoundSessionRefreshCookieFetcher::InsertCookieInCookieJar(
+    std::unique_ptr<net::CanonicalCookie> cookie) {
+  DCHECK(client_);
+  base::OnceCallback<void(net::CookieAccessResult)> callback =
+      base::BindOnce(&FakeBoundSessionRefreshCookieFetcher::OnCookieSet,
+                     weak_ptr_factory_.GetWeakPtr());
+  net::CookieOptions options;
+  options.set_include_httponly();
+  // Permit it to set a SameSite cookie if it wants to.
+  options.set_same_site_cookie_context(
+      net::CookieOptions::SameSiteCookieContext::MakeInclusive());
+  client_->GetCookieManager()->SetCanonicalCookie(
+      *cookie, url_, options,
+      mojo::WrapCallbackWithDefaultInvokeIfNotRun(
+          std::move(callback),
+          net::CookieAccessResult(net::CookieInclusionStatus(
+              net::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR))));
+}
+
+void FakeBoundSessionRefreshCookieFetcher::OnCookieSet(
+    net::CookieAccessResult access_result) {
+  bool success = access_result.status.IsInclude();
+  if (!success) {
+    std::move(callback_).Run(Result(net::Error::OK, net::HTTP_FORBIDDEN));
+  } else {
+    std::move(callback_).Run(Result(net::Error::OK, net::HTTP_OK));
+  }
+  // |This| may be destroyed
+}
+
+std::unique_ptr<net::CanonicalCookie>
+FakeBoundSessionRefreshCookieFetcher::CreateFakeCookie(
+    base::Time cookie_expiration) {
+  constexpr char kFakeCookieValue[] = "FakeCookieValue";
+
+  base::Time now = base::Time::Now();
+  // Create fake SIDTS cookie until the server endpoint is available.
+  std::unique_ptr<net::CanonicalCookie> new_cookie =
+      net::CanonicalCookie::CreateSanitizedCookie(
+          /*url=*/url_, /*name=*/cookie_name_,
+          /*value=*/kFakeCookieValue,
+          /*domain=*/url_.host(), /*path=*/"/",
+          /*creation_time=*/now, /*expiration_time=*/cookie_expiration,
+          /*last_access_time=*/now, /*secure=*/true,
+          /*http_only=*/true, net::CookieSameSite::UNSPECIFIED,
+          net::CookiePriority::COOKIE_PRIORITY_HIGH,
+          /*same_party=*/true, /*partition_key=*/absl::nullopt);
+
+  DCHECK(new_cookie);
+  return new_cookie;
+}
diff --git a/chrome/browser/signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher.h b/chrome/browser/signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher.h
new file mode 100644
index 0000000..9fc6c97
--- /dev/null
+++ b/chrome/browser/signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher.h
@@ -0,0 +1,56 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SIGNIN_BOUND_SESSION_CREDENTIALS_FAKE_BOUND_SESSION_REFRESH_COOKIE_FETCHER_H_
+#define CHROME_BROWSER_SIGNIN_BOUND_SESSION_CREDENTIALS_FAKE_BOUND_SESSION_REFRESH_COOKIE_FETCHER_H_
+
+#include "chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher.h"
+
+#include "base/functional/callback.h"
+#include "base/memory/raw_ptr.h"
+#include "base/time/time.h"
+#include "net/cookies/canonical_cookie.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+class SigninClient;
+
+class FakeBoundSessionRefreshCookieFetcher
+    : public BoundSessionRefreshCookieFetcher {
+ public:
+  FakeBoundSessionRefreshCookieFetcher(
+      SigninClient* client,
+      const GURL& url,
+      const std::string& cookie_name,
+      absl::optional<base::TimeDelta> unlock_automatically_in = absl::nullopt);
+  ~FakeBoundSessionRefreshCookieFetcher() override;
+
+  // BoundSessionRefreshCookieFetcher:
+  void Start(RefreshCookieCompleteCallback callback) override;
+
+  void SimulateCompleteRefreshRequest(
+      absl::optional<base::Time> cookie_expiration);
+
+ protected:
+  std::unique_ptr<net::CanonicalCookie> CreateFakeCookie(
+      base::Time cookie_expiration);
+  void OnRefreshCookieCompleted(std::unique_ptr<net::CanonicalCookie> cookie);
+  void InsertCookieInCookieJar(std::unique_ptr<net::CanonicalCookie> cookie);
+  void OnCookieSet(net::CookieAccessResult access_result);
+
+  const raw_ptr<SigninClient> client_;
+  const GURL url_;
+  const std::string cookie_name_;
+  RefreshCookieCompleteCallback callback_;
+
+  // `this` might be used temporarily for local development until the server
+  // endpoint is fully developed and is stable. In production,
+  // `unlock_automatically_in_` is set to simulate a fake delay, upon completion
+  // the request is completed. If `unlock_automatically_in_` is not set,
+  // `SimulateCompleteRefreshRequest()` must be called manually to complete
+  // the refresh request.
+  absl::optional<base::TimeDelta> unlock_automatically_in_;
+  base::WeakPtrFactory<FakeBoundSessionRefreshCookieFetcher> weak_ptr_factory_{
+      this};
+};
+#endif  // CHROME_BROWSER_SIGNIN_BOUND_SESSION_CREDENTIALS_FAKE_BOUND_SESSION_REFRESH_COOKIE_FETCHER_H_
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_unittest.cc b/chrome/browser/signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher_unittest.cc
similarity index 70%
rename from chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_unittest.cc
rename to chrome/browser/signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher_unittest.cc
index 654b529..9aca7d25 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_unittest.cc
+++ b/chrome/browser/signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher.h"
+#include "chrome/browser/signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher.h"
 
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
@@ -17,9 +17,9 @@
 namespace {
 constexpr char kSIDTSCookieName[] = "__Secure-1PSIDTS";
 
-class BoundSessionRefreshCookieFetcherTest : public testing::Test {
+class FakeBoundSessionRefreshCookieFetcherTest : public testing::Test {
  public:
-  BoundSessionRefreshCookieFetcherTest()
+  FakeBoundSessionRefreshCookieFetcherTest()
       : task_environment_(
             base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME) {
     std::unique_ptr<BoundSessionTestCookieManager> fake_cookie_manager =
@@ -28,21 +28,20 @@
     signin_client_.set_cookie_manager(std::move(fake_cookie_manager));
   }
 
-  ~BoundSessionRefreshCookieFetcherTest() override = default;
+  ~FakeBoundSessionRefreshCookieFetcherTest() override = default;
 
   void InitializeFetcher(base::OnceClosure on_done) {
-    fetcher_ = std::make_unique<BoundSessionRefreshCookieFetcher>(
+    fetcher_ = std::make_unique<FakeBoundSessionRefreshCookieFetcher>(
         &signin_client_, GaiaUrls::GetInstance()->secure_google_url(),
-        kSIDTSCookieName);
+        kSIDTSCookieName, /*unlock_automatically_in=*/base::Milliseconds(100));
 
     fetcher_->Start(
-        base::BindOnce(&BoundSessionRefreshCookieFetcherTest::OnCookieSet,
+        base::BindOnce(&FakeBoundSessionRefreshCookieFetcherTest::OnCookieSet,
                        base::Unretained(this), std::move(on_done)));
   }
 
   void OnCookieSet(base::OnceClosure on_done,
-                   absl::optional<base::Time> result) {
-    expected_expiry_date_ = result.value_or(base::Time());
+                   BoundSessionRefreshCookieFetcher::Result result) {
     std::move(on_done).Run();
   }
 
@@ -52,23 +51,23 @@
 
     net::CanonicalCookie& cookie = cookie_manager_->cookie();
     EXPECT_TRUE(cookie.IsCanonical());
-    EXPECT_EQ(cookie.ExpiryDate(), expected_expiry_date_);
     EXPECT_EQ(cookie.Domain(), ".google.com");
     EXPECT_EQ(cookie.Name(), kSIDTSCookieName);
     EXPECT_EQ(cookie.Value(), kFakeCookieValue);
+    EXPECT_GT(cookie.ExpiryDate(), base::Time::Now());
     EXPECT_TRUE(cookie.IsExpired(base::Time::Now() + base::Minutes(10)));
   }
 
  protected:
-  base::test::SingleThreadTaskEnvironment task_environment_;
-  base::Time expected_expiry_date_;
-  std::unique_ptr<BoundSessionRefreshCookieFetcher> fetcher_;
+  base::test::SingleThreadTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  std::unique_ptr<FakeBoundSessionRefreshCookieFetcher> fetcher_;
   sync_preferences::TestingPrefServiceSyncable prefs_;
   TestSigninClient signin_client_{&prefs_};
   raw_ptr<BoundSessionTestCookieManager> cookie_manager_ = nullptr;
 };
 
-TEST_F(BoundSessionRefreshCookieFetcherTest, SetSIDTSCookie) {
+TEST_F(FakeBoundSessionRefreshCookieFetcherTest, SetSIDTSCookie) {
   base::RunLoop run_loop;
   InitializeFetcher(run_loop.QuitClosure());
   task_environment_.FastForwardBy(base::Milliseconds(100));
diff --git a/chrome/browser/speech/cros_speech_recognition_service_factory.cc b/chrome/browser/speech/cros_speech_recognition_service_factory.cc
index 7e57214..76bf16ba 100644
--- a/chrome/browser/speech/cros_speech_recognition_service_factory.cc
+++ b/chrome/browser/speech/cros_speech_recognition_service_factory.cc
@@ -34,7 +34,12 @@
           "SpeechRecognitionService",
           // Incognito profiles should use their own instance of the browser
           // context.
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 CrosSpeechRecognitionServiceFactory::~CrosSpeechRecognitionServiceFactory() =
     default;
diff --git a/chrome/browser/speech/speech_recognition_client_browser_interface_factory.cc b/chrome/browser/speech/speech_recognition_client_browser_interface_factory.cc
index 92138fd6..58c630d 100644
--- a/chrome/browser/speech/speech_recognition_client_browser_interface_factory.cc
+++ b/chrome/browser/speech/speech_recognition_client_browser_interface_factory.cc
@@ -32,7 +32,12 @@
           "SpeechRecognitionClientBrowserInterface",
           // Incognito profiles should use their own instance of the browser
           // context.
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
 #if !BUILDFLAG(IS_CHROMEOS_LACROS)
   DependsOn(::captions::LiveCaptionControllerFactory::GetInstance());
 #endif  // !BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/speech/speech_recognition_service_factory.cc b/chrome/browser/speech/speech_recognition_service_factory.cc
index f8b79b1..09fdaf4 100644
--- a/chrome/browser/speech/speech_recognition_service_factory.cc
+++ b/chrome/browser/speech/speech_recognition_service_factory.cc
@@ -28,7 +28,12 @@
           "SpeechRecognitionService",
           // Incognito profiles should use their own instance of the browser
           // context.
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 SpeechRecognitionServiceFactory::~SpeechRecognitionServiceFactory() = default;
 
diff --git a/chrome/browser/ssl/sct_reporting_service_factory.cc b/chrome/browser/ssl/sct_reporting_service_factory.cc
index 947ce0c8..fd98609 100644
--- a/chrome/browser/ssl/sct_reporting_service_factory.cc
+++ b/chrome/browser/ssl/sct_reporting_service_factory.cc
@@ -25,7 +25,12 @@
 SCTReportingServiceFactory::SCTReportingServiceFactory()
     : ProfileKeyedServiceFactory(
           "sct_reporting::Factory",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 SCTReportingServiceFactory::~SCTReportingServiceFactory() = default;
 
diff --git a/chrome/browser/ssl/stateful_ssl_host_state_delegate_factory.cc b/chrome/browser/ssl/stateful_ssl_host_state_delegate_factory.cc
index 770edbf9..f8c62d7 100644
--- a/chrome/browser/ssl/stateful_ssl_host_state_delegate_factory.cc
+++ b/chrome/browser/ssl/stateful_ssl_host_state_delegate_factory.cc
@@ -44,7 +44,12 @@
 StatefulSSLHostStateDelegateFactory::StatefulSSLHostStateDelegateFactory()
     : ProfileKeyedServiceFactory(
           "StatefulSSLHostStateDelegate",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
diff --git a/chrome/browser/storage/storage_notification_service_factory.cc b/chrome/browser/storage/storage_notification_service_factory.cc
index b3ac229..cb3921d 100644
--- a/chrome/browser/storage/storage_notification_service_factory.cc
+++ b/chrome/browser/storage/storage_notification_service_factory.cc
@@ -7,7 +7,12 @@
 StorageNotificationServiceFactory::StorageNotificationServiceFactory()
     : ProfileKeyedServiceFactory(
           "StorageNotificationService",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 StorageNotificationServiceFactory::~StorageNotificationServiceFactory() {}
 
 // static
diff --git a/chrome/browser/subresource_filter/subresource_filter_profile_context_factory.cc b/chrome/browser/subresource_filter/subresource_filter_profile_context_factory.cc
index 2380c84..22c78bb 100644
--- a/chrome/browser/subresource_filter/subresource_filter_profile_context_factory.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_profile_context_factory.cc
@@ -28,7 +28,12 @@
 SubresourceFilterProfileContextFactory::SubresourceFilterProfileContextFactory()
     : ProfileKeyedServiceFactory(
           "SubresourceFilterProfileContext",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
   DependsOn(HistoryServiceFactory::GetInstance());
 }
diff --git a/chrome/browser/sync/user_event_service_factory.cc b/chrome/browser/sync/user_event_service_factory.cc
index 9c8cf3c..2e7fac7 100644
--- a/chrome/browser/sync/user_event_service_factory.cc
+++ b/chrome/browser/sync/user_event_service_factory.cc
@@ -39,7 +39,12 @@
 UserEventServiceFactory::UserEventServiceFactory()
     : ProfileKeyedServiceFactory(
           "UserEventService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(ModelTypeStoreServiceFactory::GetInstance());
   DependsOn(SessionSyncServiceFactory::GetInstance());
 }
diff --git a/chrome/browser/translate/translate_model_service_factory.cc b/chrome/browser/translate/translate_model_service_factory.cc
index c39ac6f..a8aca7c6 100644
--- a/chrome/browser/translate/translate_model_service_factory.cc
+++ b/chrome/browser/translate/translate_model_service_factory.cc
@@ -31,7 +31,12 @@
 TranslateModelServiceFactory::TranslateModelServiceFactory()
     : ProfileKeyedServiceFactory(
           "TranslateModelService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   if (translate::IsTFLiteLanguageDetectionEnabled())
     DependsOn(OptimizationGuideKeyedServiceFactory::GetInstance());
 }
diff --git a/chrome/browser/ui/browser_element_identifiers.cc b/chrome/browser/ui/browser_element_identifiers.cc
index 433cd50..bccdb19 100644
--- a/chrome/browser/ui/browser_element_identifiers.cc
+++ b/chrome/browser/ui/browser_element_identifiers.cc
@@ -41,6 +41,7 @@
 DEFINE_ELEMENT_IDENTIFIER_VALUE(kSidePanelElementId);
 DEFINE_ELEMENT_IDENTIFIER_VALUE(kSidePanelCloseButtonElementId);
 DEFINE_ELEMENT_IDENTIFIER_VALUE(kSidePanelComboboxElementId);
+DEFINE_ELEMENT_IDENTIFIER_VALUE(kSidePanelCompanionToolbarButtonElementId);
 DEFINE_ELEMENT_IDENTIFIER_VALUE(kSidePanelOpenInNewTabButtonElementId);
 DEFINE_ELEMENT_IDENTIFIER_VALUE(kSidePanelPinButtonElementId);
 DEFINE_ELEMENT_IDENTIFIER_VALUE(kSidePanelReadingListUnreadElementId);
diff --git a/chrome/browser/ui/browser_element_identifiers.h b/chrome/browser/ui/browser_element_identifiers.h
index 83b3dd0..521a6e9 100644
--- a/chrome/browser/ui/browser_element_identifiers.h
+++ b/chrome/browser/ui/browser_element_identifiers.h
@@ -50,6 +50,7 @@
 DECLARE_ELEMENT_IDENTIFIER_VALUE(kSidePanelElementId);
 DECLARE_ELEMENT_IDENTIFIER_VALUE(kSidePanelCloseButtonElementId);
 DECLARE_ELEMENT_IDENTIFIER_VALUE(kSidePanelComboboxElementId);
+DECLARE_ELEMENT_IDENTIFIER_VALUE(kSidePanelCompanionToolbarButtonElementId);
 DECLARE_ELEMENT_IDENTIFIER_VALUE(kSidePanelOpenInNewTabButtonElementId);
 DECLARE_ELEMENT_IDENTIFIER_VALUE(kSidePanelPinButtonElementId);
 DECLARE_ELEMENT_IDENTIFIER_VALUE(kSidePanelReadingListUnreadElementId);
diff --git a/chrome/browser/ui/cookie_controls/cookie_controls_service_factory.cc b/chrome/browser/ui/cookie_controls/cookie_controls_service_factory.cc
index 9d86b193..a9b0caa 100644
--- a/chrome/browser/ui/cookie_controls/cookie_controls_service_factory.cc
+++ b/chrome/browser/ui/cookie_controls/cookie_controls_service_factory.cc
@@ -30,7 +30,12 @@
           "CookieControlsService",
           // The incognito profile has its own CookieSettings. Therefore, it
           // should get its own CookieControlsService.
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 CookieControlsServiceFactory::~CookieControlsServiceFactory() = default;
 
diff --git a/chrome/browser/ui/find_bar/find_bar_state_factory.cc b/chrome/browser/ui/find_bar/find_bar_state_factory.cc
index 004b6d9..dec67eb 100644
--- a/chrome/browser/ui/find_bar/find_bar_state_factory.cc
+++ b/chrome/browser/ui/find_bar/find_bar_state_factory.cc
@@ -22,7 +22,12 @@
     : ProfileKeyedServiceFactory(
           "FindBarState",
           // Separate instance in incognito.
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 FindBarStateFactory::~FindBarStateFactory() = default;
 
diff --git a/chrome/browser/ui/global_media_controls/media_notification_service_factory.cc b/chrome/browser/ui/global_media_controls/media_notification_service_factory.cc
index 95419787..e4aebea 100644
--- a/chrome/browser/ui/global_media_controls/media_notification_service_factory.cc
+++ b/chrome/browser/ui/global_media_controls/media_notification_service_factory.cc
@@ -14,7 +14,12 @@
 MediaNotificationServiceFactory::MediaNotificationServiceFactory()
     : ProfileKeyedServiceFactory(
           "MediaNotificationService",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 MediaNotificationServiceFactory::~MediaNotificationServiceFactory() {}
 
diff --git a/chrome/browser/ui/media_router/media_router_ui_service_factory.cc b/chrome/browser/ui/media_router/media_router_ui_service_factory.cc
index 689b1d5..baf48cd 100644
--- a/chrome/browser/ui/media_router/media_router_ui_service_factory.cc
+++ b/chrome/browser/ui/media_router/media_router_ui_service_factory.cc
@@ -30,7 +30,12 @@
 MediaRouterUIServiceFactory::MediaRouterUIServiceFactory()
     : ProfileKeyedServiceFactory(
           "MediaRouterUIService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(ChromeMediaRouterFactory::GetInstance());
   // MediaRouterUIService owns a MediaRouterActionController that depends on
   // ToolbarActionsModel.
diff --git a/chrome/browser/ui/prefs/pref_watcher.cc b/chrome/browser/ui/prefs/pref_watcher.cc
index 11a9731..56b578b 100644
--- a/chrome/browser/ui/prefs/pref_watcher.cc
+++ b/chrome/browser/ui/prefs/pref_watcher.cc
@@ -167,7 +167,12 @@
 PrefWatcherFactory::PrefWatcherFactory()
     : ProfileKeyedServiceFactory(
           "PrefWatcher",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 PrefWatcherFactory::~PrefWatcherFactory() = default;
 
diff --git a/chrome/browser/ui/side_panel/companion/companion_tab_helper.cc b/chrome/browser/ui/side_panel/companion/companion_tab_helper.cc
index 7866469..fa9248e6 100644
--- a/chrome/browser/ui/side_panel/companion/companion_tab_helper.cc
+++ b/chrome/browser/ui/side_panel/companion/companion_tab_helper.cc
@@ -116,6 +116,10 @@
   return companion_page_handler_;
 }
 
+content::WebContents* CompanionTabHelper::GetCompanionWebContentsForTesting() {
+  return delegate_->GetCompanionWebContentsForTesting();  // IN-TEST
+}
+
 std::unique_ptr<side_panel::mojom::ImageQuery>
 CompanionTabHelper::GetImageQuery() {
   return std::move(image_query_);
@@ -135,13 +139,16 @@
   }
 }
 
-void CompanionTabHelper::UpdateNewTabButtonState() {
-  delegate_->UpdateNewTabButtonState();
+void CompanionTabHelper::CreateAndRegisterEntry() {
+  delegate_->CreateAndRegisterEntry();
 }
 
-GURL CompanionTabHelper::GetNewTabButtonUrl() {
-  return companion_page_handler_ ? companion_page_handler_->GetNewTabButtonUrl()
-                                 : GURL();
+void CompanionTabHelper::DeregisterEntry() {
+  delegate_->DeregisterEntry();
+}
+
+void CompanionTabHelper::UpdateNewTabButton(GURL url_to_open) {
+  delegate_->UpdateNewTabButton(url_to_open);
 }
 
 std::string CompanionTabHelper::GetTextQueryFromSearchUrl(
diff --git a/chrome/browser/ui/side_panel/companion/companion_tab_helper.h b/chrome/browser/ui/side_panel/companion/companion_tab_helper.h
index 2c6b11a..5a475b8 100644
--- a/chrome/browser/ui/side_panel/companion/companion_tab_helper.h
+++ b/chrome/browser/ui/side_panel/companion/companion_tab_helper.h
@@ -31,10 +31,17 @@
    public:
     virtual ~Delegate() = default;
 
+    // Creates the companion SidePanelEntry and registers it to the contextual
+    // registry.
+    virtual void CreateAndRegisterEntry() = 0;
+    // Deregisters the companion SidePanelEntry.
+    virtual void DeregisterEntry() = 0;
     // Shows the companion side panel.
     virtual void ShowCompanionSidePanel() = 0;
-    // Triggers an update of the 'open in new tab' button
-    virtual void UpdateNewTabButtonState() = 0;
+    // Triggers an update of the 'open in new tab' button.
+    virtual void UpdateNewTabButton(GURL url_to_open) = 0;
+    // Retrieves the web contents for testing purposes.
+    virtual content::WebContents* GetCompanionWebContentsForTesting() = 0;
   };
 
   CompanionTabHelper(const CompanionTabHelper&) = delete;
@@ -68,17 +75,23 @@
   // handler or an empty pointer if none.
   std::unique_ptr<side_panel::mojom::ImageQuery> GetImageQuery();
 
+  // Triggers the companion side panel entry to be created and registered for
+  // the tab.
+  void CreateAndRegisterEntry();
+  // Triggers the companion side panel entry to be deregistered for the tab.
+  void DeregisterEntry();
+
   // Triggers an update for the 'open in new tab' button in the side panel
   // header to make sure the visibility is correct.
-  void UpdateNewTabButtonState();
-  // Returns the latest set url to be used for the 'open in new tab' button in
-  // the side panel header.
-  GURL GetNewTabButtonUrl();
+  void UpdateNewTabButton(GURL url_to_open);
 
   base::WeakPtr<CompanionPageHandler> GetCompanionPageHandler();
   void SetCompanionPageHandler(
       base::WeakPtr<CompanionPageHandler> companion_page_handler);
 
+  // Returns the companion web contents for testing purposes.
+  content::WebContents* GetCompanionWebContentsForTesting();
+
  private:
   explicit CompanionTabHelper(content::WebContents* web_contents);
 
diff --git a/chrome/browser/ui/side_panel/companion/companion_utils.cc b/chrome/browser/ui/side_panel/companion/companion_utils.cc
index 1115116..b413cecb 100644
--- a/chrome/browser/ui/side_panel/companion/companion_utils.cc
+++ b/chrome/browser/ui/side_panel/companion/companion_utils.cc
@@ -9,9 +9,13 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/search.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/common/pref_names.h"
+#include "components/feature_engagement/public/feature_constants.h"
 #include "components/prefs/pref_service.h"
+#include "content/public/browser/web_contents.h"
 
 namespace companion {
 
@@ -56,4 +60,20 @@
       base::Value(companion_should_be_default_pinned));
 }
 
+void MaybeTriggerCompanionFeaturePromo(content::WebContents* web_contents) {
+  if (search::IsNTPURL(web_contents->GetLastCommittedURL())) {
+    return;
+  }
+
+  Browser* const browser = chrome::FindBrowserWithWebContents(web_contents);
+  PrefService* const pref_service = browser->profile()->GetPrefs();
+  if (base::FeatureList::IsEnabled(companion::features::kSidePanelCompanion) &&
+      pref_service &&
+      pref_service->GetBoolean(
+          prefs::kSidePanelCompanionEntryPinnedToToolbar)) {
+    browser->window()->MaybeShowFeaturePromo(
+        feature_engagement::kIPHCompanionSidePanelFeature);
+  }
+}
+
 }  // namespace companion
diff --git a/chrome/browser/ui/side_panel/companion/companion_utils.h b/chrome/browser/ui/side_panel/companion/companion_utils.h
index 88bb452e..472db06 100644
--- a/chrome/browser/ui/side_panel/companion/companion_utils.h
+++ b/chrome/browser/ui/side_panel/companion/companion_utils.h
@@ -8,6 +8,10 @@
 class Browser;
 class PrefService;
 
+namespace content {
+class WebContents;
+}
+
 namespace companion {
 
 // Returns true if the companion feature is enabled.
@@ -29,6 +33,9 @@
 // should be pinned to the toolbar by default.
 void UpdateCompanionDefaultPinnedToToolbarState(PrefService* pref_service);
 
+// Potentially triggers the IPH promo for the companion feature.
+void MaybeTriggerCompanionFeaturePromo(content::WebContents* web_contents);
+
 }  // namespace companion
 
 #endif  // CHROME_BROWSER_UI_SIDE_PANEL_COMPANION_COMPANION_UTILS_H_
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc
index 1aff895..cce31ce 100644
--- a/chrome/browser/ui/tabs/tab_strip_model.cc
+++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -40,6 +40,7 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble.h"
+#include "chrome/browser/ui/side_panel/companion/companion_utils.h"
 #include "chrome/browser/ui/tab_ui_helper.h"
 #include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.h"
 #include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.h"
@@ -660,10 +661,17 @@
 
 void TabStripModel::UpdateWebContentsStateAt(int index,
                                              TabChangeType change_type) {
-  CHECK(ContainsIndex(index));
+  WebContents* const web_contents = GetWebContentsAtImpl(index);
 
-  for (auto& observer : observers_)
-    observer.TabChangedAt(GetWebContentsAtImpl(index), index, change_type);
+  for (auto& observer : observers_) {
+    observer.TabChangedAt(web_contents, index, change_type);
+  }
+
+  // Maybe trigger side panel companion feature IPH if supported.
+  if (companion::IsSearchInCompanionSidePanelSupported(
+          chrome::FindBrowserWithWebContents(web_contents))) {
+    companion::MaybeTriggerCompanionFeaturePromo(web_contents);
+  }
 }
 
 void TabStripModel::SetTabNeedsAttentionAt(int index, bool attention) {
diff --git a/chrome/browser/ui/test/popup_browsertest.cc b/chrome/browser/ui/test/popup_browsertest.cc
index 8d36857..713ed872 100644
--- a/chrome/browser/ui/test/popup_browsertest.cc
+++ b/chrome/browser/ui/test/popup_browsertest.cc
@@ -13,58 +13,12 @@
 #include "content/public/test/browser_test_utils.h"
 #include "ui/display/display.h"
 #include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_observer.h"
 
 namespace {
 
 // Tests of window placement for popup browser windows.
 using PopupTest = PopupTestBase;
 
-// A helper class to wait for the bounds of two widgets to become equal.
-class WidgetBoundsEqualWaiter final : public views::WidgetObserver {
- public:
-  WidgetBoundsEqualWaiter(views::Widget* widget, views::Widget* widget_cmp)
-      : widget_(widget), widget_cmp_(widget_cmp) {
-    widget_->AddObserver(this);
-    widget_cmp_->AddObserver(this);
-  }
-
-  WidgetBoundsEqualWaiter(const WidgetBoundsEqualWaiter&) = delete;
-  WidgetBoundsEqualWaiter& operator=(const WidgetBoundsEqualWaiter&) = delete;
-  ~WidgetBoundsEqualWaiter() final {
-    widget_->RemoveObserver(this);
-    widget_cmp_->RemoveObserver(this);
-  }
-
-  // views::WidgetObserver:
-  void OnWidgetBoundsChanged(views::Widget* widget,
-                             const gfx::Rect& rect) final {
-    if (WidgetsBoundsEqual()) {
-      widget_->RemoveObserver(this);
-      widget_cmp_->RemoveObserver(this);
-      run_loop_.Quit();
-    }
-  }
-
-  // Wait for changes to occur, or return immediately if they already have.
-  void Wait() {
-    if (!WidgetsBoundsEqual()) {
-      run_loop_.Run();
-    }
-  }
-
- private:
-  bool WidgetsBoundsEqual() {
-    return widget_->GetWindowBoundsInScreen() ==
-           widget_cmp_->GetWindowBoundsInScreen();
-  }
-  const raw_ptr<views::Widget> widget_ = nullptr;
-  const raw_ptr<views::Widget> widget_cmp_ = nullptr;
-  base::RunLoop run_loop_;
-};
-
 // Ensure `left=0,top=0` popup window feature coordinates are respected.
 IN_PROC_BROWSER_TEST_F(PopupTest, OpenLeftAndTopZeroCoordinates) {
   // Attempt to open a popup at (0,0). Its bounds should match the request, but
@@ -190,12 +144,6 @@
   Browser* opener_popup =
       OpenPopup(browser(), "open('.', '', `" + std::string(kFeatures) + "`)");
 
-  WidgetBoundsEqualWaiter(views::Widget::GetWidgetForNativeWindow(
-                              noopener_popup->window()->GetNativeWindow()),
-                          views::Widget::GetWidgetForNativeWindow(
-                              opener_popup->window()->GetNativeWindow()))
-      .Wait();
-
   EXPECT_EQ(noopener_popup->window()->GetBounds().ToString(),
             opener_popup->window()->GetBounds().ToString());
 }
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_model_factory.cc b/chrome/browser/ui/toolbar/toolbar_actions_model_factory.cc
index 057674b..74c39e5e 100644
--- a/chrome/browser/ui/toolbar/toolbar_actions_model_factory.cc
+++ b/chrome/browser/ui/toolbar/toolbar_actions_model_factory.cc
@@ -30,7 +30,12 @@
 ToolbarActionsModelFactory::ToolbarActionsModelFactory()
     : ProfileKeyedServiceFactory(
           "ToolbarActionsModel",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(extensions::ExtensionActionAPI::GetFactoryInstance());
   DependsOn(extensions::ExtensionPrefsFactory::GetInstance());
   DependsOn(extensions::ExtensionRegistryFactory::GetInstance());
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc
index 2b1ec68..de521640 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc
@@ -34,6 +34,8 @@
                  : vector_icons::kExtensionIcon;
     case ExtensionsToolbarButton::State::kAllExtensionsBlocked:
       return vector_icons::kExtensionOffIcon;
+    case ExtensionsToolbarButton::State::kAnyExtensionHasAccess:
+      return vector_icons::kExtensionOnIcon;
   }
 }
 
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_button.h b/chrome/browser/ui/views/extensions/extensions_toolbar_button.h
index 26720690b..96ac0c3 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_button.h
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_button.h
@@ -27,8 +27,8 @@
   enum class State {
     // All extensions have blocked access to the current site.
     kAllExtensionsBlocked,
-    // TODO(crbug.com/1239772): Add new icon when 1+ extensions have access to
-    // the current site.
+    // At least one extension has access to the current site.
+    kAnyExtensionHasAccess,
     kDefault,
   };
 
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_controls.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_controls.cc
index 6f361e5..bdc2439 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_controls.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_controls.cc
@@ -36,7 +36,8 @@
     const std::vector<std::unique_ptr<ToolbarActionViewController>>& actions,
     extensions::PermissionsManager::UserSiteSetting site_setting,
     content::WebContents* current_web_contents) {
-  UpdateExtensionsButton(is_restricted_url, site_setting);
+  UpdateExtensionsButton(actions, site_setting, current_web_contents,
+                         is_restricted_url);
   UpdateRequestAccessButton(actions, site_setting, current_web_contents);
 
   // Display background only when multiple buttons are visible. Since
@@ -54,16 +55,23 @@
 }
 
 void ExtensionsToolbarControls::UpdateExtensionsButton(
-    bool is_restricted_url,
-    extensions::PermissionsManager::UserSiteSetting site_setting) {
-  bool extensions_are_blocked =
-      is_restricted_url ||
-      site_setting ==
-          extensions::PermissionsManager::UserSiteSetting::kBlockAllExtensions;
+    const std::vector<std::unique_ptr<ToolbarActionViewController>>& actions,
+    extensions::PermissionsManager::UserSiteSetting site_setting,
+    content::WebContents* web_contents,
+    bool is_restricted_url) {
   ExtensionsToolbarButton::State extensions_button_state =
-      extensions_are_blocked
-          ? ExtensionsToolbarButton::State::kAllExtensionsBlocked
-          : ExtensionsToolbarButton::State::kDefault;
+      ExtensionsToolbarButton::State::kDefault;
+
+  if (is_restricted_url || site_setting ==
+                               extensions::PermissionsManager::UserSiteSetting::
+                                   kBlockAllExtensions) {
+    extensions_button_state =
+        ExtensionsToolbarButton::State::kAllExtensionsBlocked;
+  } else if (ExtensionActionViewController::AnyActionHasCurrentSiteAccess(
+                 actions, web_contents)) {
+    extensions_button_state =
+        ExtensionsToolbarButton::State::kAnyExtensionHasAccess;
+  }
 
   extensions_button_->UpdateState(extensions_button_state);
 }
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_controls.h b/chrome/browser/ui/views/extensions/extensions_toolbar_controls.h
index 637827c..c7fd1d9 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_controls.h
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_controls.h
@@ -52,11 +52,13 @@
   void UpdateAllIcons() override;
 
  private:
-  // Updates `extensions_button_` icon given the user `site_setting` and whether
-  // `is_restricted_url`.
+  // Updates `extensions_button_` icon given `actions`, the user `site_setting`
+  // and whether `is_restricted_url` in `web_contents`.
   void UpdateExtensionsButton(
-      bool is_restricted_url,
-      extensions::PermissionsManager::UserSiteSetting site_setting);
+      const std::vector<std::unique_ptr<ToolbarActionViewController>>& actions,
+      extensions::PermissionsManager::UserSiteSetting site_setting,
+      content::WebContents* web_contents,
+      bool is_restricted_url);
 
   // Updates `request_access_button_` visibility given the user `site_setting`
   // and `actions` in `web_contents`.
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_controls_unittest.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_controls_unittest.cc
index a396801..eef5429 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_controls_unittest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_controls_unittest.cc
@@ -77,11 +77,11 @@
   web_contents_tester_ = AddWebContentsAndGetTester();
 }
 
-TEST_F(ExtensionsToolbarControlsUnitTest, ExtensionsButton_UserSiteSetting) {
-  // Install an extension that requests host permissions, and withhold them.
+TEST_F(ExtensionsToolbarControlsUnitTest,
+       ExtensionsButton_SitePermissionsUpdates) {
+  // Install an extension that requests host permissions.
   auto extension =
       InstallExtensionWithHostPermissions("Extension", {"<all_urls>"});
-  WithholdHostPermissions(extension.get());
 
   const GURL url("http://www.url.com");
   auto url_origin = url::Origin::Create(url);
@@ -100,22 +100,32 @@
   }
 
   {
-    // Extensions button has "default" icon type when it's not
-    // an user restricted site. Even though the extension has site access
-    // withheld, extension is not explicitly blocked on site since it can still
-    // run on click.
+    // Extensions button has "any extension has access" icon type when it's not
+    // an user restricted site and 1+ extensions have
+    // site access granted. Note that by default extensions have granted access.
     extensions::PermissionsManagerWaiter manager_waiter(manager);
     manager->RemoveUserRestrictedSite(url_origin);
     manager_waiter.WaitForUserPermissionsSettingsChange();
     WaitForAnimation();
     EXPECT_EQ(extensions_button()->GetStateForTesting(),
+              ExtensionsToolbarButton::State::kAnyExtensionHasAccess);
+  }
+
+  {
+    // Extension button has "default" icon type when it's not an user restricted
+    // site and no extensions have site access granted.
+    // To achieve this, we withhold host permissions in the only extension
+    // installed.
+    WithholdHostPermissions(extension.get());
+    WaitForAnimation();
+    EXPECT_EQ(extensions_button()->GetStateForTesting(),
               ExtensionsToolbarButton::State::kDefault);
   }
 }
 
 TEST_F(ExtensionsToolbarControlsUnitTest,
        ExtensionsButton_ChromeRestrictedSite) {
-  InstallExtension("Extension");
+  InstallExtensionWithHostPermissions("Extension", {"<all_urls>"});
 
   const GURL restricted_url("chrome://extensions");
   NavigateAndCommit(restricted_url);
@@ -400,8 +410,12 @@
   EXPECT_EQ(permissions->GetUserSiteAccess(*extension, url),
             extensions::PermissionsManager::UserSiteAccess::kOnClick);
 
-  ClickButton(request_access_button());
+  // Extension menu button has default state since extensions are not blocked,
+  // and there is no extension with access to the site.
+  EXPECT_EQ(extensions_button()->GetStateForTesting(),
+            ExtensionsToolbarButton::State::kDefault);
 
+  ClickButton(request_access_button());
   WaitForAnimation();
   LayoutContainerIfNecessary();
 
@@ -412,6 +426,11 @@
   EXPECT_EQ(user_action_tester.GetActionCount(kActivatedUserAction), 1);
   EXPECT_EQ(permissions->GetUserSiteAccess(*extension, url),
             extensions::PermissionsManager::UserSiteAccess::kOnClick);
+
+  // Verify extensions menu button has "any extension  has access" state, since
+  // the extension executed its action.
+  EXPECT_EQ(extensions_button()->GetStateForTesting(),
+            ExtensionsToolbarButton::State::kAnyExtensionHasAccess);
 }
 
 class ExtensionsToolbarControlsWithPermittedSitesUnitTest
diff --git a/chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm b/chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm
index e533e5f..6895f354b 100644
--- a/chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm
+++ b/chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm
@@ -38,8 +38,8 @@
 EyeDropperViewMac::~EyeDropperViewMac() = default;
 
 struct EyeDropperView::PreEventDispatchHandler::ObjCStorage {
-  id click_event_tap_ = nil;
-  id notification_observer_ = nil;
+  id click_event_tap = nil;
+  id notification_observer = nil;
 };
 
 EyeDropperView::PreEventDispatchHandler::PreEventDispatchHandler(
@@ -47,7 +47,7 @@
     gfx::NativeView parent)
     : view_(view), objc_storage_(std::make_unique<ObjCStorage>()) {
   // Ensure that this handler is called before color popup handler.
-  objc_storage_->click_event_tap_ = [NSEvent
+  objc_storage_->click_event_tap = [NSEvent
       addLocalMonitorForEventsMatchingMask:NSEventMaskAny
                                    handler:^NSEvent*(NSEvent* event) {
                                      NSEventType eventType = [event type];
@@ -71,7 +71,7 @@
   // menubar.
   NSNotificationCenter* notificationCenter =
       [NSNotificationCenter defaultCenter];
-  objc_storage_->notification_observer_ =
+  objc_storage_->notification_observer =
       [notificationCenter addObserverForName:NSMenuDidBeginTrackingNotification
                                       object:[NSApp mainMenu]
                                        queue:[NSOperationQueue mainQueue]
@@ -81,16 +81,16 @@
 }
 
 EyeDropperView::PreEventDispatchHandler::~PreEventDispatchHandler() {
-  if (objc_storage_->click_event_tap_) {
-    [NSEvent removeMonitor:objc_storage_->click_event_tap_];
-    objc_storage_->click_event_tap_ = nil;
+  if (objc_storage_->click_event_tap) {
+    [NSEvent removeMonitor:objc_storage_->click_event_tap];
+    objc_storage_->click_event_tap = nil;
   }
 
-  if (objc_storage_->notification_observer_) {
+  if (objc_storage_->notification_observer) {
     NSNotificationCenter* notificationCenter =
         [NSNotificationCenter defaultCenter];
-    [notificationCenter removeObserver:objc_storage_->notification_observer_];
-    objc_storage_->notification_observer_ = nil;
+    [notificationCenter removeObserver:objc_storage_->notification_observer];
+    objc_storage_->notification_observer = nil;
   }
 }
 
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.cc
index 040988a..a8482346 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.cc
@@ -102,6 +102,9 @@
   base::UmaHistogramExactLinear(string_constants::kFontScaleHistogramName,
                                 GetNormalizedFontScale(font_scale),
                                 maximum_font_scale_logging + 1);
+  ReadAnythingFontModel::ReadAnythingFont font =
+      coordinator_->GetModel()->GetFontModel()->GetFontLoggingValue();
+  base::UmaHistogramEnumeration(string_constants::kFontNameHistogramName, font);
   ReadAnythingColorsModel::ColorInfo::ReadAnythingColor color =
       coordinator_->GetModel()->color_logging_value();
   base::UmaHistogramEnumeration(string_constants::kColorHistogramName, color);
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc
index 51ee794..74878723 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc
@@ -6,9 +6,11 @@
 
 #include <vector>
 
+#include "base/metrics/histogram_functions.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.h"
+#include "chrome/common/accessibility/read_anything_constants.h"
 #include "components/prefs/pref_service.h"
 
 ReadAnythingController::ReadAnythingController(ReadAnythingModel* model,
@@ -23,6 +25,8 @@
   if (!model_->GetFontModel()->IsValidFontIndex(new_index))
     return;
 
+  base::UmaHistogramEnumeration(string_constants::kSettingsChangeHistogramName,
+                                ReadAnythingSettingsChange::kFontChange);
   model_->SetSelectedFontByIndex(new_index);
 
   browser_->profile()->GetPrefs()->SetString(
@@ -45,18 +49,25 @@
     model_->DecreaseTextSize();
   }
 
+  base::UmaHistogramEnumeration(string_constants::kSettingsChangeHistogramName,
+                                ReadAnythingSettingsChange::kFontSizeChange);
   browser_->profile()->GetPrefs()->SetDouble(
       prefs::kAccessibilityReadAnythingFontScale, model_->GetFontScale());
 }
 
 void ReadAnythingController::OnColorsChanged(int new_index) {
-  if (!model_->GetColorsModel()->IsValidIndex(new_index))
+  PrefService* prefs = browser_->profile()->GetPrefs();
+  if (!model_->GetColorsModel()->IsValidIndex(new_index) ||
+      prefs->GetInteger(prefs::kAccessibilityReadAnythingColorInfo) ==
+          new_index) {
     return;
+  }
 
+  base::UmaHistogramEnumeration(string_constants::kSettingsChangeHistogramName,
+                                ReadAnythingSettingsChange::kThemeChange);
   model_->SetSelectedColorsByIndex(new_index);
 
-  browser_->profile()->GetPrefs()->SetInteger(
-      prefs::kAccessibilityReadAnythingColorInfo, new_index);
+  prefs->SetInteger(prefs::kAccessibilityReadAnythingColorInfo, new_index);
 }
 
 ReadAnythingMenuModel* ReadAnythingController::GetColorsModel() {
@@ -67,6 +78,8 @@
   if (!model_->GetLineSpacingModel()->IsValidIndex(new_index))
     return;
 
+  base::UmaHistogramEnumeration(string_constants::kSettingsChangeHistogramName,
+                                ReadAnythingSettingsChange::kLineHeightChange);
   model_->SetSelectedLineSpacingByIndex(new_index);
 
   // Saved preferences correspond to LineSpacing. However, since it contains a
@@ -86,6 +99,9 @@
   if (!model_->GetLetterSpacingModel()->IsValidIndex(new_index))
     return;
 
+  base::UmaHistogramEnumeration(
+      string_constants::kSettingsChangeHistogramName,
+      ReadAnythingSettingsChange::kLetterSpacingChange);
   model_->SetSelectedLetterSpacingByIndex(new_index);
 
   // Saved preferences correspond to LetterSpacing. However, since it contains a
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc
index 88ceee4b..0d1ceb5 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc
@@ -75,8 +75,9 @@
 
   // If this profile has previously selected choices that were saved to
   // prefs, check they are still a valid, and then assign if so.
-  if (font_model_->IsValidFontName(font_name)) {
-    font_model_->SetSelectedIndex(font_model_->GetFontNameIndex(font_name));
+  size_t font_index = font_model_->GetFontNameIndex(font_name);
+  if (font_model_->IsValidFontIndex(font_index)) {
+    font_model_->SetSelectedIndex(font_index);
   }
 
   font_scale_ = GetValidFontScale(font_scale);
@@ -217,35 +218,41 @@
 
 void ReadAnythingFontModel::SetDefaultLanguage(const std::string& lang) {
   if (base::Contains(kLanguagesSupportedByPoppins, lang)) {
-    font_choices_.emplace_back(u"Poppins");
+    FontInfo kPoppins = {u"Poppins", ReadAnythingFont::kPoppins};
+    font_choices_.emplace_back(kPoppins);
   }
-  font_choices_.emplace_back(u"Sans-serif");
-  font_choices_.emplace_back(u"Serif");
+  FontInfo kSansSerif = {u"Sans-serif", ReadAnythingFont::kSansSerif};
+  FontInfo kSerif = {u"Serif", ReadAnythingFont::kSerif};
+  font_choices_.emplace_back(kSansSerif);
+  font_choices_.emplace_back(kSerif);
   if (base::Contains(kLanguagesSupportedByComicNeue, lang)) {
-    font_choices_.emplace_back(u"Comic Neue");
+    FontInfo kComicNeue = {u"Comic Neue", ReadAnythingFont::kComicNeue};
+    font_choices_.emplace_back(kComicNeue);
   }
   if (base::Contains(kLanguagesSupportedByLexendDeca, lang)) {
-    font_choices_.emplace_back(u"Lexend Deca");
+    FontInfo kLexendDeca = {u"Lexend Deca", ReadAnythingFont::kLexendDeca};
+    font_choices_.emplace_back(kLexendDeca);
   }
   if (base::Contains(kLanguagesSupportedByEbGaramond, lang)) {
-    font_choices_.emplace_back(u"EB Garamond");
+    FontInfo kEbGaramond = {u"EB Garamond", ReadAnythingFont::kEbGaramond};
+    font_choices_.emplace_back(kEbGaramond);
   }
   if (base::Contains(kLanguagesSupportedByStixTwoText, lang)) {
-    font_choices_.emplace_back(u"STIX Two Text");
+    FontInfo kStixTwoText = {u"STIX Two Text", ReadAnythingFont::kStixTwoText};
+    font_choices_.emplace_back(kStixTwoText);
   }
   font_choices_.shrink_to_fit();
 }
 
-bool ReadAnythingFontModel::IsValidFontName(const std::string& font_name) {
-  return base::Contains(font_choices_, base::UTF8ToUTF16(font_name));
-}
-
 bool ReadAnythingFontModel::IsValidFontIndex(size_t index) {
   return index < GetItemCount();
 }
 
 size_t ReadAnythingFontModel::GetFontNameIndex(std::string font_name) {
-  auto it = base::ranges::find(font_choices_, base::UTF8ToUTF16(font_name));
+  auto it = base::ranges::find_if(
+      font_choices_, [font_name](const FontInfo& font_info) {
+        return base::UTF8ToUTF16(font_name) == font_info.name;
+      });
   return static_cast<size_t>(it - font_choices_.begin());
 }
 
@@ -273,12 +280,12 @@
 
 std::u16string ReadAnythingFontModel::GetDropDownTextAt(size_t index) const {
   DCHECK_LT(index, GetItemCount());
-  return font_choices_[index];
+  return font_choices_[index].name;
 }
 
 std::string ReadAnythingFontModel::GetFontNameAt(size_t index) {
   DCHECK_LT(index, GetItemCount());
-  return base::UTF16ToUTF8(font_choices_[index]);
+  return base::UTF16ToUTF8(font_choices_[index].name);
 }
 
 // This method uses the text from the drop down at |index| and constructs a
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h
index 84bea5c..6bb7ab9 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h
@@ -35,8 +35,30 @@
   ReadAnythingFontModel& operator=(const ReadAnythingFontModel&) = delete;
   ~ReadAnythingFontModel() override;
 
+  // Enum for logging the user-chosen font.
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
+  enum class ReadAnythingFont {
+    kPoppins = 0,
+    kSansSerif = 1,
+    kSerif = 2,
+    kComicNeue = 3,
+    kLexendDeca = 4,
+    kEbGaramond = 5,
+    kStixTwoText = 6,
+    kMaxValue = kStixTwoText,
+  };
+
+  // Simple struct to hold the various fonts to keep code cleaner.
+  struct FontInfo {
+    // The name of the font
+    std::u16string name;
+
+    // The enum value of the font.
+    ReadAnythingFontModel::ReadAnythingFont enum_value;
+  };
+
   std::string GetFontNameAt(size_t index);
-  bool IsValidFontName(const std::string& font_name);
   bool IsValidFontIndex(size_t index);
   void SetDefaultLanguage(const std::string& lang);
   size_t GetFontNameIndex(std::string font_name);
@@ -44,6 +66,9 @@
   std::vector<std::string> GetLabelFontNameAt(size_t index) override;
   absl::optional<int> GetLabelFontSize() override;
   size_t GetSelectedIndex() { return selected_index_; }
+  ReadAnythingFont GetFontLoggingValue() {
+    return font_choices_[selected_index_].enum_value;
+  }
 
   absl::optional<ui::ColorId> GetDropdownForegroundColorIdAt(
       size_t index) const override;
@@ -76,7 +101,7 @@
 
  private:
   // Styled font names for the drop down options in front-end.
-  std::vector<std::u16string> font_choices_;
+  std::vector<FontInfo> font_choices_;
 
   size_t selected_index_ = 0;
 
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc
index 4212ab1..d1ae696 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc
@@ -204,18 +204,6 @@
   EXPECT_NEAR(model_->GetFontScale(), 4.5, 0.01);
 }
 
-TEST_F(ReadAnythingModelTest, FontModelIsValidFontName) {
-  InitModel();
-  EXPECT_TRUE(GetFontModel()->IsValidFontName("Poppins"));
-  EXPECT_TRUE(GetFontModel()->IsValidFontName("Sans-serif"));
-  EXPECT_TRUE(GetFontModel()->IsValidFontName("Serif"));
-  EXPECT_TRUE(GetFontModel()->IsValidFontName("Comic Neue"));
-  EXPECT_TRUE(GetFontModel()->IsValidFontName("Lexend Deca"));
-  EXPECT_TRUE(GetFontModel()->IsValidFontName("EB Garamond"));
-  EXPECT_TRUE(GetFontModel()->IsValidFontName("STIX Two Text"));
-  EXPECT_FALSE(GetFontModel()->IsValidFontName("xxyyzz"));
-}
-
 TEST_F(ReadAnythingModelTest, FontModelGetFontNameEnglishOptions) {
   InitModel();
   EXPECT_EQ("Poppins", GetFontModel()->GetFontNameAt(0));
diff --git a/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc b/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc
index 2237d27..024e69c0 100644
--- a/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc
+++ b/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc
@@ -166,11 +166,9 @@
   }
 
   content::WebContents* GetCompanionWebContents(Browser* browser) {
-    auto* search_companion_side_panel_coordinator =
-        SearchCompanionSidePanelCoordinator::FromBrowser(browser);
-    DCHECK(search_companion_side_panel_coordinator);
-    auto* web_contents =
-        search_companion_side_panel_coordinator->web_contents();
+    auto* companion_helper =
+        companion::CompanionTabHelper::FromWebContents(web_contents());
+    auto* web_contents = companion_helper->GetCompanionWebContentsForTesting();
     DCHECK(web_contents);
     return web_contents;
   }
diff --git a/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.cc b/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.cc
index 3c775e67..a584639 100644
--- a/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.cc
+++ b/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.cc
@@ -4,10 +4,15 @@
 
 #include "chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.h"
 
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/side_panel/search_companion/search_companion_side_panel_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
+#include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
+#include "chrome/browser/ui/views/side_panel/side_panel_web_ui_view.h"
+#include "chrome/browser/ui/webui/side_panel/companion/companion_side_panel_untrusted_ui.h"
+#include "chrome/common/webui_url_constants.h"
 
 namespace companion {
 
@@ -17,6 +22,41 @@
 
 CompanionSidePanelController::~CompanionSidePanelController() = default;
 
+void CompanionSidePanelController::CreateAndRegisterEntry() {
+  auto* registry = SidePanelRegistry::Get(web_contents_);
+  Browser* browser = chrome::FindBrowserWithWebContents(web_contents_);
+  if (!registry || !browser ||
+      registry->GetEntryForKey(
+          SidePanelEntry::Key(SidePanelEntry::Id::kSearchCompanion))) {
+    return;
+  }
+
+  auto* coordinator =
+      SearchCompanionSidePanelCoordinator::GetOrCreateForBrowser(browser);
+
+  auto entry = std::make_unique<SidePanelEntry>(
+      SidePanelEntry::Id::kSearchCompanion, coordinator->name(),
+      ui::ImageModel::FromVectorIcon(coordinator->icon(), ui::kColorIcon,
+                                     /*icon_size=*/16),
+      base::BindRepeating(
+          &companion::CompanionSidePanelController::CreateCompanionWebView,
+          base::Unretained(this)),
+      base::BindRepeating(
+          &companion::CompanionSidePanelController::GetOpenInNewTabUrl,
+          base::Unretained(this)));
+  registry->Register(std::move(entry));
+}
+
+void CompanionSidePanelController::DeregisterEntry() {
+  auto* registry = SidePanelRegistry::Get(web_contents_);
+  if (!registry) {
+    return;
+  }
+
+  registry->Deregister(
+      SidePanelEntry::Key(SidePanelEntry::Id::kSearchCompanion));
+}
+
 void CompanionSidePanelController::ShowCompanionSidePanel() {
   if (Browser* browser = chrome::FindBrowserWithWebContents(web_contents_)) {
     auto* coordinator =
@@ -25,7 +65,8 @@
   }
 }
 
-void CompanionSidePanelController::UpdateNewTabButtonState() {
+void CompanionSidePanelController::UpdateNewTabButton(GURL url_to_open) {
+  open_in_new_tab_url_ = url_to_open;
   Browser* browser = chrome::FindBrowserWithWebContents(web_contents_);
   BrowserView* browser_view =
       browser ? BrowserView::GetBrowserViewForBrowser(browser) : nullptr;
@@ -34,4 +75,66 @@
   }
 }
 
+content::WebContents*
+CompanionSidePanelController::GetCompanionWebContentsForTesting() {
+  return web_contents();
+}
+
+std::unique_ptr<views::View>
+CompanionSidePanelController::CreateCompanionWebView() {
+  auto wrapper =
+      std::make_unique<BubbleContentsWrapperT<CompanionSidePanelUntrustedUI>>(
+          GURL(chrome::kChromeUIUntrustedCompanionSidePanelURL),
+          Profile::FromBrowserContext(web_contents_->GetBrowserContext()),
+          /*webui_resizes_host=*/false,
+          /*esc_closes_ui=*/false);
+  auto companion_web_view =
+      std::make_unique<SidePanelWebUIViewT<CompanionSidePanelUntrustedUI>>(
+          base::RepeatingClosure(), base::RepeatingClosure(),
+          std::move(wrapper));
+
+  // Observe on the webcontents for opening links in new tab.
+  Observe(companion_web_view->GetWebContents());
+
+  return companion_web_view;
+}
+
+GURL CompanionSidePanelController::GetOpenInNewTabUrl() {
+  return open_in_new_tab_url_;
+}
+
+// This method is called when the WebContents wants to open a link in a new
+// tab. This delegate does not override AddNewContents(), so the webcontents
+// is not actually created. Instead it forwards the parameters to the real
+// browser.
+void CompanionSidePanelController::DidOpenRequestedURL(
+    content::WebContents* new_contents,
+    content::RenderFrameHost* source_render_frame_host,
+    const GURL& url,
+    const content::Referrer& referrer,
+    WindowOpenDisposition disposition,
+    ui::PageTransition transition,
+    bool started_from_context_menu,
+    bool renderer_initiated) {
+  content::OpenURLParams params(url, referrer, disposition, transition,
+                                renderer_initiated);
+
+  // If the navigation is initiated by the renderer process, we must set an
+  // initiator origin.
+  if (renderer_initiated) {
+    params.initiator_origin = url::Origin::Create(url);
+  }
+
+  // Open the new tab in the foreground.
+  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
+
+  Browser* browser = chrome::FindBrowserWithWebContents(web_contents_);
+  if (!browser) {
+    return;
+  }
+
+  // Open the url in a new tab.
+  browser->OpenURL(params);
+}
+
 }  // namespace companion
diff --git a/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.h b/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.h
index 0116b7e0..de1c4167 100644
--- a/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.h
+++ b/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.h
@@ -7,15 +7,21 @@
 
 #include "base/memory/raw_ptr.h"
 #include "chrome/browser/ui/side_panel/companion/companion_tab_helper.h"
+#include "content/public/browser/web_contents_observer.h"
 
 namespace content {
 class WebContents;
 }  // namespace content
 
+namespace views {
+class View;
+}  // namespace views
+
 namespace companion {
 
 // Controller for handling views specific logic for the CompanionTabHelper.
-class CompanionSidePanelController : public CompanionTabHelper::Delegate {
+class CompanionSidePanelController : public CompanionTabHelper::Delegate,
+                                     public content::WebContentsObserver {
  public:
   explicit CompanionSidePanelController(content::WebContents* web_contents);
   CompanionSidePanelController(const CompanionSidePanelController&) = delete;
@@ -24,10 +30,27 @@
   ~CompanionSidePanelController() override;
 
   // CompanionTabHelper::Delegate:
+  void CreateAndRegisterEntry() override;
+  void DeregisterEntry() override;
   void ShowCompanionSidePanel() override;
-  void UpdateNewTabButtonState() override;
+  void UpdateNewTabButton(GURL url_to_open) override;
+  content::WebContents* GetCompanionWebContentsForTesting() override;
 
  private:
+  std::unique_ptr<views::View> CreateCompanionWebView();
+  GURL GetOpenInNewTabUrl();
+
+  // content::WebContentsObserver:
+  void DidOpenRequestedURL(content::WebContents* new_contents,
+                           content::RenderFrameHost* source_render_frame_host,
+                           const GURL& url,
+                           const content::Referrer& referrer,
+                           WindowOpenDisposition disposition,
+                           ui::PageTransition transition,
+                           bool started_from_context_menu,
+                           bool renderer_initiated) override;
+
+  GURL open_in_new_tab_url_;
   const raw_ptr<content::WebContents> web_contents_;
 };
 
diff --git a/chrome/browser/ui/views/side_panel/search_companion/search_companion_side_panel_coordinator.cc b/chrome/browser/ui/views/side_panel/search_companion/search_companion_side_panel_coordinator.cc
index e1d55f0..7fdb1f7 100644
--- a/chrome/browser/ui/views/side_panel/search_companion/search_companion_side_panel_coordinator.cc
+++ b/chrome/browser/ui/views/side_panel/search_companion/search_companion_side_panel_coordinator.cc
@@ -14,12 +14,8 @@
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_entry.h"
-#include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_toolbar_container.h"
-#include "chrome/browser/ui/views/side_panel/side_panel_web_ui_view.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
-#include "chrome/browser/ui/webui/side_panel/companion/companion_side_panel_untrusted_ui.h"
-#include "chrome/common/webui_url_constants.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/vector_icons/vector_icons.h"
 
@@ -56,35 +52,6 @@
          (!include_dsp_check || search::DefaultSearchProviderIsGoogle(profile));
 }
 
-std::unique_ptr<views::View>
-SearchCompanionSidePanelCoordinator::CreateCompanionWebView() {
-  auto wrapper =
-      std::make_unique<BubbleContentsWrapperT<CompanionSidePanelUntrustedUI>>(
-          GURL(chrome::kChromeUIUntrustedCompanionSidePanelURL),
-          GetBrowserView()->GetProfile(),
-          /*webui_resizes_host=*/false,
-          /*esc_closes_ui=*/false);
-  auto companion_web_view =
-      std::make_unique<SidePanelWebUIViewT<CompanionSidePanelUntrustedUI>>(
-          base::RepeatingClosure(), base::RepeatingClosure(),
-          std::move(wrapper));
-
-  // Observe on the webcontents for opening links in new tab.
-  Observe(companion_web_view->GetWebContents());
-
-  return companion_web_view;
-}
-
-GURL SearchCompanionSidePanelCoordinator::GetOpenInNewTabUrl() {
-  if (content::WebContents* active_web_contents =
-          browser_->tab_strip_model()->GetActiveWebContents()) {
-    auto* companion_helper =
-        companion::CompanionTabHelper::FromWebContents(active_web_contents);
-    return companion_helper->GetNewTabButtonUrl();
-  }
-  return GURL();
-}
-
 bool SearchCompanionSidePanelCoordinator::Show() {
   auto* browser_view = GetBrowserView();
   if (!browser_view) {
@@ -113,12 +80,8 @@
     const TabStripSelectionChange& selection) {
   if (change.type() == TabStripModelChange::Type::kInserted) {
     for (const auto& inserted_tab : change.GetInsert()->contents) {
-      auto* contextual_registry = SidePanelRegistry::Get(inserted_tab.contents);
-      if (contextual_registry &&
-          !contextual_registry->GetEntryForKey(
-              SidePanelEntry::Key(SidePanelEntry::Id::kSearchCompanion))) {
-        contextual_registry->Register(CreateCompanionEntry());
-      }
+      companion::CompanionTabHelper::FromWebContents(inserted_tab.contents)
+          ->CreateAndRegisterEntry();
     }
   }
 }
@@ -127,70 +90,21 @@
     CreateAndRegisterEntriesForExistingWebContents(
         TabStripModel* tab_strip_model) {
   for (int index = 0; index < tab_strip_model->GetTabCount(); index++) {
-    auto* contextual_registry =
-        SidePanelRegistry::Get(tab_strip_model->GetWebContentsAt(index));
-    contextual_registry->Register(CreateCompanionEntry());
+    companion::CompanionTabHelper::FromWebContents(
+        tab_strip_model->GetWebContentsAt(index))
+        ->CreateAndRegisterEntry();
   }
 }
 
 void SearchCompanionSidePanelCoordinator::
     DeregisterEntriesForExistingWebContents(TabStripModel* tab_strip_model) {
   for (int index = 0; index < tab_strip_model->GetTabCount(); index++) {
-    auto* contextual_registry =
-        SidePanelRegistry::Get(tab_strip_model->GetWebContentsAt(index));
-    contextual_registry->Deregister(
-        SidePanelEntry::Key(SidePanelEntry::Id::kSearchCompanion));
+    companion::CompanionTabHelper::FromWebContents(
+        tab_strip_model->GetWebContentsAt(index))
+        ->DeregisterEntry();
   }
 }
 
-std::unique_ptr<SidePanelEntry>
-SearchCompanionSidePanelCoordinator::CreateCompanionEntry() {
-  return std::make_unique<SidePanelEntry>(
-      SidePanelEntry::Id::kSearchCompanion, name(),
-      ui::ImageModel::FromVectorIcon(icon(), ui::kColorIcon,
-                                     /*icon_size=*/16),
-      base::BindRepeating(
-          &SearchCompanionSidePanelCoordinator::CreateCompanionWebView,
-          base::Unretained(this)),
-      base::BindRepeating(
-          &SearchCompanionSidePanelCoordinator::GetOpenInNewTabUrl,
-          base::Unretained(this)));
-}
-
-// This method is called when the WebContents wants to open a link in a new
-// tab. This delegate does not override AddNewContents(), so the webcontents
-// is not actually created. Instead it forwards the parameters to the real
-// browser.
-void SearchCompanionSidePanelCoordinator::DidOpenRequestedURL(
-    content::WebContents* new_contents,
-    content::RenderFrameHost* source_render_frame_host,
-    const GURL& url,
-    const content::Referrer& referrer,
-    WindowOpenDisposition disposition,
-    ui::PageTransition transition,
-    bool started_from_context_menu,
-    bool renderer_initiated) {
-  content::OpenURLParams params(url, referrer, disposition, transition,
-                                renderer_initiated);
-
-  // If the navigation is initiated by the renderer process, we must set an
-  // initiator origin.
-  if (renderer_initiated) {
-    params.initiator_origin = url::Origin::Create(url);
-  }
-
-  // Open the new tab in the foreground.
-  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
-
-  auto* browser_view = GetBrowserView();
-  if (!browser_view) {
-    return;
-  }
-
-  // Open the url in a new tab.
-  browser_view->browser()->OpenURL(params);
-}
-
 void SearchCompanionSidePanelCoordinator::OnTemplateURLServiceChanged() {
   BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_);
   if (!browser_view) {
diff --git a/chrome/browser/ui/views/side_panel/search_companion/search_companion_side_panel_coordinator.h b/chrome/browser/ui/views/side_panel/search_companion/search_companion_side_panel_coordinator.h
index 24b434a..45272535 100644
--- a/chrome/browser/ui/views/side_panel/search_companion/search_companion_side_panel_coordinator.h
+++ b/chrome/browser/ui/views/side_panel/search_companion/search_companion_side_panel_coordinator.h
@@ -16,20 +16,14 @@
 #include "chrome/browser/ui/views/side_panel/side_panel_entry.h"
 #include "components/search_engines/template_url_service.h"
 #include "components/search_engines/template_url_service_observer.h"
-#include "content/public/browser/web_contents_observer.h"
 
 class Browser;
 class Profile;
 
-namespace views {
-class View;
-}  // namespace views
-
 // SearchCompanionSidePanelCoordinator handles the creation and registration of
 // the search companion SidePanelEntry.
 class SearchCompanionSidePanelCoordinator
     : public BrowserUserData<SearchCompanionSidePanelCoordinator>,
-      public content::WebContentsObserver,
       public TabStripModelObserver,
       public TemplateURLServiceObserver {
  public:
@@ -62,22 +56,6 @@
       TabStripModel* tab_strip_model);
   void DeregisterEntriesForExistingWebContents(TabStripModel* tab_strip_model);
 
-  std::unique_ptr<SidePanelEntry> CreateCompanionEntry();
-
-  std::unique_ptr<views::View> CreateCompanionWebView();
-
-  GURL GetOpenInNewTabUrl();
-
-  // content::WebContentsObserver:
-  void DidOpenRequestedURL(content::WebContents* new_contents,
-                           content::RenderFrameHost* source_render_frame_host,
-                           const GURL& url,
-                           const content::Referrer& referrer,
-                           WindowOpenDisposition disposition,
-                           ui::PageTransition transition,
-                           bool started_from_context_menu,
-                           bool renderer_initiated) override;
-
   // TemplateURLServiceObserver:
   void OnTemplateURLServiceChanged() override;
   void OnTemplateURLServiceShuttingDown() override;
diff --git a/chrome/browser/ui/views/side_panel/side_panel_toolbar_container.cc b/chrome/browser/ui/views/side_panel/side_panel_toolbar_container.cc
index 065519a6..53d09a12 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_toolbar_container.cc
+++ b/chrome/browser/ui/views/side_panel/side_panel_toolbar_container.cc
@@ -10,8 +10,10 @@
 #include "base/memory/raw_ptr.h"
 #include "base/metrics/user_metrics.h"
 #include "chrome/app/vector_icons/vector_icons.h"
+#include "chrome/browser/feature_engagement/tracker_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_element_identifiers.h"
 #include "chrome/browser/ui/side_panel/companion/companion_utils.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
@@ -23,6 +25,7 @@
 #include "chrome/browser/ui/views/toolbar/side_panel_toolbar_button.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/feature_engagement/public/feature_constants.h"
 #include "components/prefs/pref_service.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/models/dialog_model_menu_model_adapter.h"
@@ -68,6 +71,11 @@
     coordinator->Show(
         id_, SidePanelUtil::SidePanelOpenTrigger::kPinnedEntryToolbarButton);
   }
+  // Close IPH for companion if shown and record usage for side panel promo.
+  browser_view_->NotifyFeatureEngagementEvent(
+      "companion_side_panel_accessed_via_toolbar_button");
+  browser_view_->CloseFeaturePromo(
+      feature_engagement::kIPHCompanionSidePanelFeature);
 }
 
 void SidePanelToolbarContainer::PinnedSidePanelToolbarButton::
@@ -196,6 +204,8 @@
   }
   auto button = std::make_unique<PinnedSidePanelToolbarButton>(browser_view_,
                                                                id, name, icon);
+  button->SetProperty(views::kElementIdentifierKey,
+                      kSidePanelCompanionToolbarButtonElementId);
   button->SetVisible(false);
   ObserveButton(button.get());
   pinned_button_visibility_change_subscription_ =
diff --git a/chrome/browser/ui/views/user_education/browser_user_education_service.cc b/chrome/browser/ui/views/user_education/browser_user_education_service.cc
index 66ae8d8..6b5dd3b92 100644
--- a/chrome/browser/ui/views/user_education/browser_user_education_service.cc
+++ b/chrome/browser/ui/views/user_education/browser_user_education_service.cc
@@ -354,6 +354,12 @@
       feature_engagement::kIPHPowerBookmarksSidePanelFeature,
       kSidePanelButtonElementId, IDS_POWER_BOOKMARKS_SIDE_PANEL_PROMO));
 
+  // kIPHCompanionSidePanelFeature:
+  registry.RegisterFeature(FeaturePromoSpecification::CreateForSnoozePromo(
+      feature_engagement::kIPHCompanionSidePanelFeature,
+      kSidePanelCompanionToolbarButtonElementId,
+      IDS_SIDE_PANEL_COMPANION_PROMO));
+
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
   // kIPHSwitchProfileFeature:
   registry.RegisterFeature(FeaturePromoSpecification::CreateForToastPromo(
diff --git a/chrome/browser/ui/views/user_education/browser_user_education_service_browsertest.cc b/chrome/browser/ui/views/user_education/browser_user_education_service_browsertest.cc
new file mode 100644
index 0000000..057170f
--- /dev/null
+++ b/chrome/browser/ui/views/user_education/browser_user_education_service_browsertest.cc
@@ -0,0 +1,377 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cstdint>
+#include <map>
+#include <ostream>
+#include <sstream>
+#include <vector>
+
+#include "base/feature_list.h"
+#include "base/functional/bind.h"
+#include "base/run_loop.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/feature_engagement/tracker_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/user_education/user_education_service.h"
+#include "chrome/browser/ui/user_education/user_education_service_factory.h"
+#include "chrome/browser/ui/views/user_education/browser_user_education_service.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "components/feature_engagement/public/configuration.h"
+#include "components/feature_engagement/public/feature_configurations.h"
+#include "components/feature_engagement/public/feature_constants.h"
+#include "components/feature_engagement/public/tracker.h"
+#include "components/feature_engagement/test/scoped_iph_feature_list.h"
+#include "components/user_education/common/feature_promo_registry.h"
+#include "components/user_education/common/feature_promo_specification.h"
+#include "content/public/test/browser_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/abseil-cpp/absl/types/variant.h"
+
+namespace {
+
+enum class IPHFailureReason {
+  kNone,
+  kNotConfigured,
+  kWrongSessionRate,
+  kWrongSessionImpact,
+  kLegacyPromoNoScreenReader,
+};
+
+struct IPHException {
+  IPHException() = default;
+  IPHException(const base::Feature* feature_,
+               absl::optional<IPHFailureReason> reason_,
+               const char* description_)
+      : feature(feature_), reason(reason_), description(description_) {}
+  IPHException(const IPHException& other) = default;
+  IPHException& operator=(const IPHException& other) = default;
+  ~IPHException() = default;
+
+  base::raw_ptr<const base::Feature> feature = nullptr;
+  absl::optional<IPHFailureReason> reason;
+  const char* description = nullptr;
+};
+
+struct IPHFailure {
+  IPHFailure() = default;
+  IPHFailure(const base::Feature* feature_,
+             IPHFailureReason reason_,
+             const feature_engagement::FeatureConfig* config_)
+      : feature(feature_), reason(reason_), config(config_) {}
+  IPHFailure(const IPHFailure& other) = default;
+  IPHFailure& operator=(const IPHFailure& other) = default;
+
+  base::raw_ptr<const base::Feature> feature = nullptr;
+  IPHFailureReason reason = IPHFailureReason::kNone;
+  base::raw_ptr<const feature_engagement::FeatureConfig> config = nullptr;
+};
+
+std::ostream& operator<<(std::ostream& os,
+                         feature_engagement::ComparatorType type) {
+  switch (type) {
+    case feature_engagement::ANY:
+      os << "ANY";
+      break;
+    case feature_engagement::LESS_THAN:
+      os << "LESS_THAN";
+      break;
+    case feature_engagement::GREATER_THAN:
+      os << "GREATER_THAN";
+      break;
+    case feature_engagement::LESS_THAN_OR_EQUAL:
+      os << "LESS_THAN_OR_EQUAL";
+      break;
+    case feature_engagement::GREATER_THAN_OR_EQUAL:
+      os << "GREATER_THAN_OR_EQUAL";
+      break;
+    case feature_engagement::EQUAL:
+      os << "EQUAL";
+      break;
+    case feature_engagement::NOT_EQUAL:
+      os << "NOT_EQUAL";
+      break;
+  }
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         feature_engagement::SessionRateImpact::Type type) {
+  switch (type) {
+    case feature_engagement::SessionRateImpact::Type::ALL:
+      os << "ALL";
+      break;
+    case feature_engagement::SessionRateImpact::Type::EXPLICIT:
+      os << "EXPLICIT";
+      break;
+    case feature_engagement::SessionRateImpact::Type::NONE:
+      os << "NONE";
+      break;
+  }
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const IPHFailure& failure) {
+  os << failure.feature->name;
+  switch (failure.reason) {
+    case IPHFailureReason::kNone:
+      NOTREACHED();
+      break;
+    case IPHFailureReason::kNotConfigured:
+      os << " is not configured. Please add a configuration to "
+            "feature_configurations.cc (preferred) or "
+            "fieldtrial_testing_config.json.";
+      break;
+    case IPHFailureReason::kWrongSessionRate:
+      os << " has unexpected session rate: "
+         << failure.config->session_rate.type << ", "
+         << failure.config->session_rate.value
+         << ". Non-toast IPH should have limited session_rate - typically "
+            "EQUALS, 0 - to prevent other IPH from running in the same "
+            "session.";
+      break;
+    case IPHFailureReason::kWrongSessionImpact:
+      os << " has unexpected session rate impact: "
+         << failure.config->session_rate_impact.type
+         << ". An IPH which runs once per session should also prevent other "
+            "similar IPH from running (session rate impact ALL); an IPH which "
+            "is not limited should not (session rate impact NONE).";
+      break;
+    case IPHFailureReason::kLegacyPromoNoScreenReader:
+      os << " is a legacy promo with inadequate screen reader support. Use a "
+            "toast promo instead.";
+      break;
+  }
+  return os;
+}
+
+template <typename T, typename U>
+void MaybeAddFailure(T& failures,
+                     const U& exceptions,
+                     const base::Feature* feature,
+                     IPHFailureReason reason,
+                     const feature_engagement::FeatureConfig* feature_config) {
+  IPHFailure failure(feature, reason, feature_config);
+  for (const auto& exception : exceptions) {
+    if (exception.feature == feature) {
+      if ((exception.reason.has_value() &&
+           exception.reason.value() == reason) ||
+          (reason != IPHFailureReason::kNotConfigured &&
+           !exception.reason.has_value())) {
+        LOG(WARNING) << "Allowed by exception or currently being worked - "
+                     << exception.description << ":\n"
+                     << failure;
+      }
+      return;
+    }
+  }
+  failures.push_back(failure);
+}
+
+template <typename T>
+std::string FailuresToString(const T& failures) {
+  std::ostringstream oss;
+  oss << "Errors found during IPH configuration validation.";
+  for (auto& failure : failures) {
+    oss << "\n" << failure;
+  }
+  return oss.str();
+}
+
+bool IsComparatorLimited(const feature_engagement::Comparator& comparator,
+                         uint32_t max_count) {
+  switch (comparator.type) {
+    case feature_engagement::ANY:
+    case feature_engagement::GREATER_THAN:
+    case feature_engagement::GREATER_THAN_OR_EQUAL:
+    case feature_engagement::NOT_EQUAL:
+      return false;
+    case feature_engagement::LESS_THAN:
+      return comparator.value <= max_count;
+    case feature_engagement::LESS_THAN_OR_EQUAL:
+    case feature_engagement::EQUAL:
+      return comparator.value < max_count;
+  }
+}
+
+}  // namespace
+
+using BrowserUserEducationServiceBrowserTest = InProcessBrowserTest;
+
+IN_PROC_BROWSER_TEST_F(BrowserUserEducationServiceBrowserTest,
+                       FeatureConfigurationConsistencyCheck) {
+  // Exceptions to the consistency checks. All of those with crbug.com IDs
+  // should ideally be fixed. See tracking bug at crbug.com/1442977
+  const std::vector<IPHException> exceptions({
+      // Known weird/old/test-only IPH.
+      {&feature_engagement::kIPHAutofillExternalAccountProfileSuggestionFeature,
+       IPHFailureReason::kLegacyPromoNoScreenReader, "Known legacy promo."},
+      {&feature_engagement::kIPHAutofillVirtualCardSuggestionFeature,
+       IPHFailureReason::kLegacyPromoNoScreenReader, "Known legacy promo."},
+      {&feature_engagement::kIPHGMCCastStartStopFeature,
+       IPHFailureReason::kLegacyPromoNoScreenReader, "Known legacy promo."},
+      {&feature_engagement::kIPHWebUiHelpBubbleTestFeature,
+       IPHFailureReason::kNotConfigured, "For testing purposes only."},
+
+      // Toast IPH that probably need session impact updated.
+      {&feature_engagement::kIPHPasswordsManagementBubbleAfterSaveFeature,
+       IPHFailureReason::kWrongSessionImpact, "crbug.com/1442979"},
+      {&feature_engagement::kIPHPasswordsManagementBubbleDuringSigninFeature,
+       IPHFailureReason::kWrongSessionImpact, "crbug.com/1442979"},
+      {&feature_engagement::kIPHPasswordsWebAppProfileSwitchFeature,
+       IPHFailureReason::kWrongSessionImpact, "crbug.com/1442979"},
+      {&feature_engagement::kIPHProfileSwitchFeature,
+       IPHFailureReason::kWrongSessionImpact, "crbug.com/1442979"},
+      {&feature_engagement::kIPHTabAudioMutingFeature,
+       IPHFailureReason::kWrongSessionImpact, "crbug.com/1442979"},
+
+      // IPH that limit session rate in other ways. These should probably be
+      // revisited in the future.
+      {&feature_engagement::kIPHDesktopCustomizeChromeFeature,
+       IPHFailureReason::kWrongSessionRate, "crbug.com/1443063"},
+      {&feature_engagement::kIPHDesktopTabGroupsNewGroupFeature,
+       IPHFailureReason::kWrongSessionRate, "crbug.com/1443063"},
+      {&feature_engagement::kIPHSideSearchFeature,
+       IPHFailureReason::kWrongSessionRate, "crbug.com/1443063"},
+      {&feature_engagement::kIPHHighEfficiencyModeFeature,
+       IPHFailureReason::kWrongSessionRate, "crbug.com/1443063"},
+      {&feature_engagement::kIPHPriceTrackingChipFeature, absl::nullopt,
+       "crbug.com/1443063"},
+      {&feature_engagement::kIPHPriceTrackingInSidePanelFeature, absl::nullopt,
+       "crbug.com/1443063"},
+      {&feature_engagement::kIPHPowerBookmarksSidePanelFeature,
+       IPHFailureReason::kWrongSessionRate,
+       "crbug.com/1443067, crbug.com/1443063"},
+      {&feature_engagement::kIPHPasswordsAccountStorageFeature,
+       IPHFailureReason::kWrongSessionRate, "crbug.com/1443075"},
+
+      // Deprecated; should probably be removed.
+      {&feature_engagement::kIPHReopenTabFeature,
+       IPHFailureReason::kNotConfigured, "crbug.com/1442978"},
+      {&feature_engagement::kIPHReadingListDiscoveryFeature,
+       IPHFailureReason::kNotConfigured, "crbug.com/1443020"},
+      {&feature_engagement::kIPHReadingListEntryPointFeature,
+       IPHFailureReason::kNotConfigured, "crbug.com/1443020"},
+      {&feature_engagement::kIPHDesktopSharedHighlightingFeature,
+       IPHFailureReason::kNotConfigured, "crbug.com/1443071"},
+      {&feature_engagement::kIPHReadingListInSidePanelFeature, absl::nullopt,
+       "crbug.com/1443078"},
+      {&feature_engagement::kIPHTabSearchFeature, absl::nullopt,
+       "crbug.com/1443079"},
+      {&feature_engagement::kIPHWebUITabStripFeature, absl::nullopt,
+       "crbug.com/1443082"},
+
+      // Needs configuration.
+      {&feature_engagement::kIPHLiveCaptionFeature,
+       IPHFailureReason::kNotConfigured, "crbug.com/1443002"},
+      {&feature_engagement::kIPHBackNavigationMenuFeature,
+       IPHFailureReason::kNotConfigured, "crbug.com/1443013"},
+      {&feature_engagement::kIPHDesktopPwaInstallFeature,
+       IPHFailureReason::kNotConfigured, "crbug.com/1443016"},
+  });
+
+  // Fetch the tracker and ensure that it is properly initialized.
+  auto* const tracker =
+      feature_engagement::TrackerFactory::GetForBrowserContext(
+          browser()->profile());
+  base::RunLoop run_loop;
+  tracker->AddOnInitializedCallback(base::BindOnce(
+      [](base::OnceClosure callback, bool success) {
+        ASSERT_TRUE(success);
+        std::move(callback).Run();
+      },
+      run_loop.QuitClosure()));
+  run_loop.Run();
+
+  // Get the configuration from the tracker.
+  const feature_engagement::Configuration* const configuration =
+      tracker->GetConfigurationForTesting();
+  ASSERT_NE(nullptr, configuration);
+
+  // Get the associated feature promo registry.
+  const user_education::FeaturePromoRegistry& registry =
+      UserEducationServiceFactory::GetForProfile(browser()->profile())
+          ->feature_promo_registry();
+
+  std::vector<IPHFailure> failures;
+
+  // Iterate through registered IPH and ensure that the configurations are
+  // consistent.
+  for (const auto& [feature, spec] :
+       registry.GetRegisteredFeaturePromoSpecifications()) {
+    const feature_engagement::FeatureConfig* feature_config =
+        &configuration->GetFeatureConfig(*feature);
+
+    // Fetch the configuration for the given feature.
+    absl::optional<feature_engagement::FeatureConfig> client_config;
+    if (!feature_config->valid) {
+      // Disabled features don't read from feature_configurations.cc by default;
+      // we have to do it manually to ensure that if Finch enables the feature
+      // the configuration we read will be correct.
+      client_config = feature_engagement::GetClientSideFeatureConfig(feature);
+      if (client_config) {
+        feature_config = &client_config.value();
+      } else {
+        // This is a feature that can only be configured through Finch; current
+        // best practice is to also include a fieldtrial or (better) a config
+        // in feature_configurations.cc.
+        MaybeAddFailure(failures, exceptions, feature,
+                        IPHFailureReason::kNotConfigured, feature_config);
+        continue;
+      }
+    }
+
+    const bool limits_other_iph =
+        feature_config->session_rate_impact.type ==
+        feature_engagement::SessionRateImpact::Type::ALL;
+    const bool is_session_limited =
+        IsComparatorLimited(feature_config->session_rate, 1);
+
+    switch (spec.promo_type()) {
+      case user_education::FeaturePromoSpecification::PromoType::kToast:
+        // Toast promos are allowed to bypass session exclusivity. However, they
+        // should not limit other IPH.
+        if (limits_other_iph) {
+          MaybeAddFailure(failures, exceptions, feature,
+                          IPHFailureReason::kWrongSessionImpact,
+                          feature_config);
+        }
+        break;
+      case user_education::FeaturePromoSpecification::PromoType::kTutorial:
+      case user_education::FeaturePromoSpecification::PromoType::kCustomAction:
+      case user_education::FeaturePromoSpecification::PromoType::kSnooze:
+        // Standard promos should be session-limited and should limit other IPH.
+        if (!is_session_limited) {
+          MaybeAddFailure(failures, exceptions, feature,
+                          IPHFailureReason::kWrongSessionRate, feature_config);
+        }
+        if (!limits_other_iph) {
+          MaybeAddFailure(failures, exceptions, feature,
+                          IPHFailureReason::kWrongSessionImpact,
+                          feature_config);
+        }
+        break;
+      case user_education::FeaturePromoSpecification::PromoType::kLegacy:
+      case user_education::FeaturePromoSpecification::PromoType::kUnspecified:
+        // Legacy promos are inherently bad. Use toast or snooze instead.
+        if (!spec.screen_reader_string_id()) {
+          MaybeAddFailure(failures, exceptions, feature,
+                          IPHFailureReason::kLegacyPromoNoScreenReader,
+                          feature_config);
+        }
+        // Legacy promos should pattern as snooze or toast promos.
+        if (is_session_limited != limits_other_iph) {
+          MaybeAddFailure(failures, exceptions, feature,
+                          IPHFailureReason::kWrongSessionImpact,
+                          feature_config);
+        }
+        break;
+    }
+  }
+
+  EXPECT_TRUE(failures.empty()) << FailuresToString(failures);
+}
diff --git a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc
index d9c2fb3d..575da5e 100644
--- a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc
+++ b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc
@@ -33,8 +33,8 @@
   // As only a single brand icon is selected and the user can have monitors with
   // different screen densities, make the ideal size be the size which works
   // with a high density display (if the OS supports high density displays).
-  float max_supported_scale = ui::GetScaleForResourceScaleFactor(
-      ui::GetMaxSupportedResourceScaleFactor());
+  const float max_supported_scale =
+      ui::GetScaleForMaxSupportedResourceScaleFactor();
   return round(GetBrandIconMinimumSize() * max_supported_scale);
 }
 
diff --git a/chrome/browser/ui/webui/management/management_ui_handler.cc b/chrome/browser/ui/webui/management/management_ui_handler.cc
index b3ead9d4..b216de7 100644
--- a/chrome/browser/ui/webui/management/management_ui_handler.cc
+++ b/chrome/browser/ui/webui/management/management_ui_handler.cc
@@ -974,8 +974,7 @@
   }
 
 #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
-  if (capture_policy::IsGetDisplayMediaSetSelectAllScreensAllowedForAnySite(
-          profile)) {
+  if (capture_policy::IsGetAllScreensMediaAllowedForAnySite(profile)) {
     AddThreatProtectionPermission(kManagementScreenCaptureEvent,
                                   kManagementScreenCaptureData, &info);
   }
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
index 27e796b9..c3e05d7 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
@@ -8,6 +8,7 @@
 #include <string>
 #include <utility>
 
+#include "base/base64.h"
 #include "base/containers/unique_ptr_adapters.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
@@ -70,33 +71,7 @@
   return resolved_addresses_list;
 }
 
-// This function converts net::ConnectionEndpointMetadata to base::Value::Dict.
-base::Value::Dict ConnectionEndpointMetadataToBaseDict(
-    const net::ConnectionEndpointMetadata& metadata) {
-  base::Value::Dict connection_endpoint_metadata;
-
-  base::Value::List supported_protocol_alpns;
-  base::Value::List ech_config_list;
-  for (const std::string& supported_protocol_alpn :
-       metadata.supported_protocol_alpns) {
-    supported_protocol_alpns.Append(supported_protocol_alpn);
-  }
-
-  for (uint8_t ech_config : metadata.ech_config_list) {
-    ech_config_list.Append(ech_config);
-  }
-
-  connection_endpoint_metadata.Set("supported_protocol_alpns",
-                                   std::move(supported_protocol_alpns));
-  connection_endpoint_metadata.Set("ech_config_list",
-                                   std::move(ech_config_list));
-  connection_endpoint_metadata.Set("target_name", metadata.target_name);
-
-  return connection_endpoint_metadata;
-}
-
-// This function converts
-// absl::optional<net::HostResolverEndpointResults> to
+// This function converts absl::optional<net::HostResolverEndpointResults> to
 // base::Value::List.
 base::Value::List HostResolverEndpointResultsToBaseList(
     const absl::optional<net::HostResolverEndpointResults>& endpoint_results) {
@@ -106,13 +81,22 @@
     return endpoint_results_list;
   }
 
-  for (const auto& endpoint_result : *endpoint_results) {
-    base::Value::Dict endpoint_results_dict;
-    endpoint_results_dict.Set(
-        "ip_endpoints", IPEndpointsToBaseList(endpoint_result.ip_endpoints));
-    endpoint_results_dict.Set("metadata", ConnectionEndpointMetadataToBaseDict(
-                                              endpoint_result.metadata));
-    endpoint_results_list.Append(std::move(endpoint_results_dict));
+  for (const auto& endpoint : *endpoint_results) {
+    base::Value::Dict dict;
+    dict.Set("ip_endpoints", IPEndpointsToBaseList(endpoint.ip_endpoints));
+
+    base::Value::List alpns;
+    for (const std::string& alpn : endpoint.metadata.supported_protocol_alpns) {
+      alpns.Append(alpn);
+    }
+    dict.Set("alpns", std::move(alpns));
+
+    if (!endpoint.metadata.ech_config_list.empty()) {
+      dict.Set("ech_config_list",
+               base::Base64Encode(endpoint.metadata.ech_config_list));
+    }
+
+    endpoint_results_list.Append(std::move(dict));
   }
   return endpoint_results_list;
 }
@@ -389,10 +373,12 @@
       IPEndpointsToBaseList(resolved_addresses->endpoints());
   result.Set("resolved_addresses", std::move(resolved_addresses_list));
 
-  base::Value::List endpoint_result_with_metadata =
+  // TODO(crbug.com/1416410): Rename `endpoint_results_with_metadata` in the
+  // Mojo API to `alternative_endpoints`, to match the terminology used in the
+  // specification.
+  base::Value::List alternative_endpoints_list =
       HostResolverEndpointResultsToBaseList(endpoint_results_with_metadata);
-  result.Set("endpoint_results_with_metadata",
-             std::move(endpoint_result_with_metadata));
+  result.Set("alternative_endpoints", std::move(alternative_endpoints_list));
 
   ResolveJavascriptCallback(base::Value(callback_id), std::move(result));
 }
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
index 696db282..2baafbe 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
@@ -140,6 +140,9 @@
       first_endpoint_metadata.supported_protocol_alpns = {"http/1.1", "h2"};
       second_endpoint_metadata.supported_protocol_alpns = {"http/1.1", "h2",
                                                            "h3"};
+    } else if (hostname == "ech.com") {
+      first_endpoint_metadata.supported_protocol_alpns = {"http/1.1", "h2"};
+      first_endpoint_metadata.ech_config_list = {0x01, 0x02, 0x03, 0x04};
     } else {
       response_client->OnComplete(
           0, net::ResolveErrorInfo(net::OK),
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
index 8e9f4a04..d644ce66 100644
--- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
+++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
@@ -368,9 +368,6 @@
       enterprise_info = l10n_util::GetStringFUTF16(
           IDS_ASH_ENTERPRISE_DEVICE_MANAGED_BY, ui::GetChromeOSDeviceName(),
           base::UTF8ToUTF16(enterprise_domain_manager));
-    } else if (connector->IsActiveDirectoryManaged()) {
-      enterprise_info = l10n_util::GetStringFUTF16(
-          IDS_ASH_ENTERPRISE_DEVICE_MANAGED, ui::GetChromeOSDeviceName());
     } else {
       NOTREACHED() << "Unknown management type";
     }
diff --git a/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc b/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc
index b2288b4..9aecc0ef 100644
--- a/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc
+++ b/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc
@@ -147,10 +147,6 @@
       base::BindRepeating(&MultideviceHandler::HandleSetUpAndroidSms,
                           base::Unretained(this)));
   web_ui()->RegisterMessageCallback(
-      "getSmartLockSignInAllowed",
-      base::BindRepeating(&MultideviceHandler::HandleGetSmartLockSignInAllowed,
-                          base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
       "getAndroidSmsInfo",
       base::BindRepeating(&MultideviceHandler::HandleGetAndroidSmsInfo,
                           base::Unretained(this)));
@@ -250,11 +246,6 @@
         browser_tabs_model_provider_.get());
   }
 
-  pref_change_registrar_.Add(
-      multidevice_setup::kSmartLockSigninAllowedPrefName,
-      base::BindRepeating(
-          &MultideviceHandler::NotifySmartLockSignInAllowedChanged,
-          base::Unretained(this)));
   if (NearbySharingServiceFactory::IsNearbyShareSupportedForBrowserContext(
           Profile::FromWebUI(web_ui()))) {
     pref_change_registrar_.Add(
@@ -473,16 +464,6 @@
   android_sms_app_manager_->SetUpAndLaunchAndroidSmsApp();
 }
 
-void MultideviceHandler::HandleGetSmartLockSignInAllowed(
-    const base::Value::List& args) {
-  const base::Value& callback_id = args[0];
-  CHECK(callback_id.is_string());
-
-  bool sign_in_allowed =
-      prefs_->GetBoolean(multidevice_setup::kSmartLockSigninAllowedPrefName);
-  ResolveJavascriptCallback(callback_id, base::Value(sign_in_allowed));
-}
-
 base::Value::Dict MultideviceHandler::GenerateAndroidSmsInfo() {
   absl::optional<GURL> app_url;
   if (android_sms_app_manager_) {
@@ -885,13 +866,6 @@
   return page_content_dictionary;
 }
 
-void MultideviceHandler::NotifySmartLockSignInAllowedChanged() {
-  bool sign_in_allowed =
-      prefs_->GetBoolean(multidevice_setup::kSmartLockSigninAllowedPrefName);
-  FireWebUIListener("smart-lock-signin-allowed-changed",
-                    base::Value(sign_in_allowed));
-}
-
 bool MultideviceHandler::IsAuthTokenValid(const std::string& auth_token) {
   Profile* profile = Profile::FromWebUI(web_ui());
   quick_unlock::QuickUnlockStorage* quick_unlock_storage =
diff --git a/chrome/browser/ui/webui/settings/ash/multidevice_handler.h b/chrome/browser/ui/webui/settings/ash/multidevice_handler.h
index 017b8f3..cfca0a8 100644
--- a/chrome/browser/ui/webui/settings/ash/multidevice_handler.h
+++ b/chrome/browser/ui/webui/settings/ash/multidevice_handler.h
@@ -142,9 +142,6 @@
   void HandleRemoveHostDevice(const base::Value::List& args);
   void HandleRetryPendingHostSetup(const base::Value::List& args);
   void HandleSetUpAndroidSms(const base::Value::List& args);
-  // TODO(b/227674947):Now that Sign in with Smart Lock is deprecated, delete
-  // this method.
-  void HandleGetSmartLockSignInAllowed(const base::Value::List& args);
   void HandleGetAndroidSmsInfo(const base::Value::List& args);
   void HandleAttemptNotificationSetup(const base::Value::List& args);
   void HandleCancelNotificationSetup(const base::Value::List& args);
@@ -160,10 +157,6 @@
   void OnSetFeatureStateEnabledResult(const std::string& js_callback_id,
                                       bool success);
 
-  // TODO(b/227674947):Now that Sign in with Smart Lock is deprecated, delete
-  // this methods.
-  void NotifySmartLockSignInAllowedChanged();
-
   // Generate android sms info dictionary containing the messages for web
   // content settings origin url and messages feature state.
   base::Value::Dict GenerateAndroidSmsInfo();
diff --git a/chrome/browser/ui/webui/settings/ash/os_settings_hats_manager_factory.cc b/chrome/browser/ui/webui/settings/ash/os_settings_hats_manager_factory.cc
index 02bb0dd3..cc219c9b 100644
--- a/chrome/browser/ui/webui/settings/ash/os_settings_hats_manager_factory.cc
+++ b/chrome/browser/ui/webui/settings/ash/os_settings_hats_manager_factory.cc
@@ -26,7 +26,12 @@
 OsSettingsHatsManagerFactory::OsSettingsHatsManagerFactory()
     : ProfileKeyedServiceFactory(
           "OsSettingsHatsManager",
-          ProfileSelections::BuildForRegularAndIncognito()) {}
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {}
 
 OsSettingsHatsManagerFactory::~OsSettingsHatsManagerFactory() = default;
 
diff --git a/chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.cc b/chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.cc
index cf9a4dbd..6cd6eefa 100644
--- a/chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.cc
+++ b/chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.cc
@@ -36,7 +36,12 @@
 OsSettingsManagerFactory::OsSettingsManagerFactory()
     : ProfileKeyedServiceFactory(
           "OsSettingsManager",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(
       local_search_service::LocalSearchServiceProxyFactory::GetInstance());
   DependsOn(multidevice_setup::MultiDeviceSetupClientFactory::GetInstance());
diff --git a/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc b/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc
index 3453b134..0462b1e 100644
--- a/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc
+++ b/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc
@@ -135,10 +135,6 @@
   page_->OnImageQuery(image_query.Clone());
 }
 
-GURL CompanionPageHandler::GetNewTabButtonUrl() {
-  return open_in_new_tab_url_;
-}
-
 void CompanionPageHandler::OnPromoAction(
     side_panel::mojom::PromoType promo_type,
     side_panel::mojom::PromoAction promo_action) {
@@ -167,8 +163,7 @@
   auto* companion_helper =
       companion::CompanionTabHelper::FromWebContents(web_contents());
   DCHECK(companion_helper);
-  open_in_new_tab_url_ = url_to_open;
-  companion_helper->UpdateNewTabButtonState();
+  companion_helper->UpdateNewTabButton(url_to_open);
 }
 
 void CompanionPageHandler::RecordUiSurfaceShown(
diff --git a/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.h b/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.h
index fe41fb69..ef4d7cf 100644
--- a/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.h
+++ b/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.h
@@ -62,10 +62,6 @@
   void OnSearchTextQuery(const std::string& text_query);
   void OnImageQuery(side_panel::mojom::ImageQuery image_query);
 
-  // Returns the latest set url to be used for the 'open in new tab' button in
-  // the side panel header.
-  GURL GetNewTabButtonUrl();
-
  private:
   // MsbbDelegate overrides.
   void EnableMsbb(bool enable_msbb) override;
@@ -93,7 +89,6 @@
   std::unique_ptr<SigninDelegate> signin_delegate_;
   std::unique_ptr<CompanionUrlBuilder> url_builder_;
   std::unique_ptr<PromoHandler> promo_handler_;
-  GURL open_in_new_tab_url_;
 
   // Logs metrics for companion page. Reset when there is a new navigation.
   std::unique_ptr<CompanionMetricsLogger> metrics_logger_;
diff --git a/chrome/browser/updates/announcement_notification/announcement_notification_service_factory.cc b/chrome/browser/updates/announcement_notification/announcement_notification_service_factory.cc
index bd494eb..670484ea 100644
--- a/chrome/browser/updates/announcement_notification/announcement_notification_service_factory.cc
+++ b/chrome/browser/updates/announcement_notification/announcement_notification_service_factory.cc
@@ -58,7 +58,12 @@
 AnnouncementNotificationServiceFactory::AnnouncementNotificationServiceFactory()
     : ProfileKeyedServiceFactory(
           "AnnouncementNotificationService",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(NotificationDisplayServiceFactory::GetInstance());
 }
 
diff --git a/chrome/browser/usb/usb_chooser_context_factory.cc b/chrome/browser/usb/usb_chooser_context_factory.cc
index 5174e85e..8dfe968a 100644
--- a/chrome/browser/usb/usb_chooser_context_factory.cc
+++ b/chrome/browser/usb/usb_chooser_context_factory.cc
@@ -11,7 +11,12 @@
 UsbChooserContextFactory::UsbChooserContextFactory()
     : ProfileKeyedServiceFactory(
           "UsbChooserContext",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
diff --git a/chrome/browser/web_applications/commands/update_protocol_handler_approval_command_browsertest.cc b/chrome/browser/web_applications/commands/update_protocol_handler_approval_command_browsertest.cc
index 5c8506b5..50eedf32 100644
--- a/chrome/browser/web_applications/commands/update_protocol_handler_approval_command_browsertest.cc
+++ b/chrome/browser/web_applications/commands/update_protocol_handler_approval_command_browsertest.cc
@@ -32,13 +32,31 @@
 namespace {
 const char16_t kAppName[] = u"Test App";
 
+// A few tests have Windows specific assertions because Windows is the only
+// OS where protocols are registered on the OS differently compared to
+// other OSes where protocols are bundled into the shortcut
+// registration/update/unregistration flow.
 class UpdateProtocolHandlerApprovalCommandTest
     : public WebAppControllerBrowserTest,
       public ::testing::WithParamInterface<OsIntegrationSubManagersState> {
  public:
   const GURL kTestAppUrl = GURL("https://example.com");
 
-  UpdateProtocolHandlerApprovalCommandTest() = default;
+  UpdateProtocolHandlerApprovalCommandTest() {
+    if (GetParam() == OsIntegrationSubManagersState::kSaveStateToDB) {
+      scoped_feature_list_.InitAndEnableFeatureWithParameters(
+          features::kOsIntegrationSubManagers, {{"stage", "write_config"}});
+    } else if (GetParam() ==
+               OsIntegrationSubManagersState::kSaveStateAndExecute) {
+      scoped_feature_list_.InitAndEnableFeatureWithParameters(
+          features::kOsIntegrationSubManagers,
+          {{"stage", "execute_and_write_config"}});
+    } else {
+      scoped_feature_list_.InitWithFeatures(
+          /*enabled_features=*/{},
+          /*disabled_features=*/{features::kOsIntegrationSubManagers});
+    }
+  }
   ~UpdateProtocolHandlerApprovalCommandTest() override = default;
 
   void SetUpOnMainThread() override {
@@ -51,18 +69,6 @@
     WebAppControllerBrowserTest::SetUpOnMainThread();
   }
 
-  void SetUp() override {
-    WebAppControllerBrowserTest::SetUp();
-    if (EnableOsIntegrationSubManager()) {
-      scoped_feature_list_.InitAndEnableFeatureWithParameters(
-          features::kOsIntegrationSubManagers, {{"stage", "write_config"}});
-    } else {
-      scoped_feature_list_.InitWithFeatures(
-          /*enabled_features=*/{},
-          /*disabled_features=*/{features::kOsIntegrationSubManagers});
-    }
-  }
-
   void TearDownOnMainThread() override {
     // Uninstallation of all apps is required for the shortcut override
     // destruction.
@@ -122,10 +128,6 @@
 #endif
   }
 
-  bool EnableOsIntegrationSubManager() {
-    return GetParam() == OsIntegrationSubManagersState::kSaveStateToDB;
-  }
-
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
   std::unique_ptr<OsIntegrationTestOverrideImpl::BlockingRegistration>
@@ -267,12 +269,18 @@
 #endif
 
   if (AreProtocolsRegisteredWithOs()) {
-    // They should be registered on first install, then removed on disallow.
+#if BUILDFLAG(IS_WIN)
     EXPECT_THAT(
         OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
         testing::ElementsAre(
             std::make_tuple(app_id, std::vector({protocol_handler.protocol})),
             std::make_tuple(app_id, std::vector<std::string>())));
+#else
+    EXPECT_THAT(
+        OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
+        testing::ElementsAre(
+            std::make_tuple(app_id, std::vector({protocol_handler.protocol}))));
+#endif  // BUILDFLAG(IS_WIN)
   }
 }
 
@@ -308,14 +316,18 @@
 #endif
 
   if (AreProtocolsRegisteredWithOs()) {
-    // They should be registered on first install, then removed on disallow. On
-    // the 2nd command run with the same inputs, this should not change because
-    // OS integration does not re-run again.
+#if BUILDFLAG(IS_WIN)
     EXPECT_THAT(
         OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
         testing::ElementsAre(
             std::make_tuple(app_id, std::vector({protocol_handler.protocol})),
             std::make_tuple(app_id, std::vector<std::string>())));
+#else
+    EXPECT_THAT(
+        OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
+        testing::ElementsAre(
+            std::make_tuple(app_id, std::vector({protocol_handler.protocol}))));
+#endif  // BUILDFLAG(IS_WIN)
   }
 }
 
@@ -354,12 +366,18 @@
 #endif
 
   if (AreProtocolsRegisteredWithOs()) {
-    // They should be registered on first install, then removed on disallow.
+#if BUILDFLAG(IS_WIN)
     EXPECT_THAT(
         OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
         testing::ElementsAre(
             std::make_tuple(app_id, std::vector({protocol_handler.protocol})),
             std::make_tuple(app_id, std::vector<std::string>())));
+#else
+    EXPECT_THAT(
+        OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
+        testing::ElementsAre(
+            std::make_tuple(app_id, std::vector({protocol_handler.protocol}))));
+#endif  // BUILDFLAG(IS_WIN)
   }
 }
 
@@ -400,12 +418,38 @@
 #endif
 
   if (AreProtocolsRegisteredWithOs()) {
+#if BUILDFLAG(IS_WIN)
+    if (AreSubManagersExecuteEnabled()) {
+      // The sub managers first add a protocol, then remove it on being
+      // disallowed and then adds it again.
+      EXPECT_THAT(
+          OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
+          testing::ElementsAre(
+              std::make_tuple(app_id, std::vector({protocol_handler.protocol})),
+              std::make_tuple(app_id, std::vector<std::string>()),
+              std::make_tuple(app_id,
+                              std::vector({protocol_handler.protocol}))));
+    } else {
+      // The old OS integration code first adds a protocol, and then does an
+      // update with no approved protocols (hence an unregistration but no
+      // registration). The last update call performs an unregistration and a
+      // re-addition of the protocol, so there are four entries.
+      EXPECT_THAT(
+          OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
+          testing::ElementsAre(
+              std::make_tuple(app_id, std::vector({protocol_handler.protocol})),
+              std::make_tuple(app_id, std::vector<std::string>()),
+              std::make_tuple(app_id, std::vector<std::string>()),
+              std::make_tuple(app_id,
+                              std::vector({protocol_handler.protocol}))));
+    }
+#else
     EXPECT_THAT(
         OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
         testing::ElementsAre(
             std::make_tuple(app_id, std::vector({protocol_handler.protocol})),
-            std::make_tuple(app_id, std::vector<std::string>()),
             std::make_tuple(app_id, std::vector({protocol_handler.protocol}))));
+#endif  // BUILDFLAG(IS_WIN)
   }
 }
 
@@ -446,15 +490,39 @@
               testing::ElementsAre(protocol_handler.protocol));
 #endif
 
-  // They should be registered on first install, removed on Disallow and then
-  // added back when removed from the disallowed list.
   if (AreProtocolsRegisteredWithOs()) {
+#if BUILDFLAG(IS_WIN)
+    if (AreSubManagersExecuteEnabled()) {
+      // The sub managers first add a protocol, then remove it on being
+      // disallowed and then adds it again.
+      EXPECT_THAT(
+          OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
+          testing::ElementsAre(
+              std::make_tuple(app_id, std::vector({protocol_handler.protocol})),
+              std::make_tuple(app_id, std::vector<std::string>()),
+              std::make_tuple(app_id,
+                              std::vector({protocol_handler.protocol}))));
+    } else {
+      // The old OS integration code first adds a protocol, and then does an
+      // update with no approved protocols (hence an unregistration but no
+      // registration). The last update call performs an unregistration and a
+      // re-addition of the protocol, so there are four entries.
+      EXPECT_THAT(
+          OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
+          testing::ElementsAre(
+              std::make_tuple(app_id, std::vector({protocol_handler.protocol})),
+              std::make_tuple(app_id, std::vector<std::string>()),
+              std::make_tuple(app_id, std::vector<std::string>()),
+              std::make_tuple(app_id,
+                              std::vector({protocol_handler.protocol}))));
+    }
+#else
     EXPECT_THAT(
         OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
         testing::ElementsAre(
             std::make_tuple(app_id, std::vector({protocol_handler.protocol})),
-            std::make_tuple(app_id, std::vector<std::string>()),
             std::make_tuple(app_id, std::vector({protocol_handler.protocol}))));
+#endif  // BUILDFLAG(IS_WIN)
   }
 }
 
@@ -509,6 +577,7 @@
     All,
     UpdateProtocolHandlerApprovalCommandTest,
     ::testing::Values(OsIntegrationSubManagersState::kSaveStateToDB,
+                      OsIntegrationSubManagersState::kSaveStateAndExecute,
                       OsIntegrationSubManagersState::kDisabled),
     test::GetOsIntegrationSubManagersTestName);
 
diff --git a/chrome/browser/web_applications/os_integration/protocol_handling_sub_manager_unittest.cc b/chrome/browser/web_applications/os_integration/protocol_handling_sub_manager_unittest.cc
index edd1ebbd..cb7d1a0 100644
--- a/chrome/browser/web_applications/os_integration/protocol_handling_sub_manager_unittest.cc
+++ b/chrome/browser/web_applications/os_integration/protocol_handling_sub_manager_unittest.cc
@@ -345,17 +345,17 @@
 #endif
 
   if (AreProtocolsRegisteredWithOs()) {
-    // TODO(crbug.com/1404819): Update tests to verify protocol handling
-    // unregistration as part of update.
-    // There should only be a single value for registration, as unregistration
-    // is a no-op for OsIntegrationTestOverrideImpl::Get().
     ASSERT_THAT(
         OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
         testing::ElementsAre(
-            std::make_tuple(app_id, std::vector({protocol_handler.protocol}))));
+            std::make_tuple(app_id, std::vector({protocol_handler.protocol})),
+            std::make_tuple(app_id, std::vector<std::string>())));
   }
 }
 
+// This test has extra assertions since Windows registers protocol handlers
+// differently than Mac/Linux where protocol handlers are bundled as part
+// of the shortcuts OS integration process.
 TEST_P(ProtocolHandlingExecuteTest, UpdateHandlers) {
   apps::ProtocolHandlerInfo protocol_handler_approved;
   const std::string handler_url1 =
@@ -400,8 +400,17 @@
                 testing::ElementsAre(protocol_handler_approved.protocol));
 #endif
     if (AreProtocolsRegisteredWithOs()) {
-      // TODO(crbug.com/1404819): Update tests to verify protocol handling
-      // unregistration as part of update.
+#if BUILDFLAG(IS_WIN)
+      ASSERT_THAT(
+          OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
+          testing::ElementsAre(
+              std::make_tuple(
+                  app_id, std::vector({protocol_handler_approved.protocol,
+                                       protocol_handler_disapproved.protocol})),
+              std::make_tuple(app_id, std::vector<std::string>()),
+              std::make_tuple(
+                  app_id, std::vector({protocol_handler_approved.protocol}))));
+#else
       ASSERT_THAT(
           OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
           testing::ElementsAre(
@@ -410,6 +419,7 @@
                                        protocol_handler_disapproved.protocol})),
               std::make_tuple(
                   app_id, std::vector({protocol_handler_approved.protocol}))));
+#endif  // BUILDFLAG(IS_WIN)
     }
   } else {
     ASSERT_FALSE(os_integration_state.has_protocols_handled());
@@ -483,20 +493,9 @@
                 testing::IsEmpty());
 #endif
     if (AreProtocolsRegisteredWithOs()) {
-      // TODO(crbug.com/1404819): Update tests to streamline proper
-      // representation of protocols registered, independent of OSes.
-      // These values are set by the ShortcutHandlingSubManager.
-#if BUILDFLAG(IS_WIN)
       ASSERT_THAT(
           OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
           testing::IsEmpty());
-#else
-      ASSERT_THAT(
-          OsIntegrationTestOverrideImpl::Get()->protocol_scheme_registrations(),
-          testing::ElementsAre(
-              std::make_tuple(app_id1, std::vector<std::string>()),
-              std::make_tuple(app_id1, std::vector<std::string>())));
-#endif
     }
   } else {
     ASSERT_FALSE(os_integration_state.has_protocols_handled());
diff --git a/chrome/browser/web_applications/os_integration/web_app_protocol_handler_registration_win.cc b/chrome/browser/web_applications/os_integration/web_app_protocol_handler_registration_win.cc
index eeb76af..717030b0 100644
--- a/chrome/browser/web_applications/os_integration/web_app_protocol_handler_registration_win.cc
+++ b/chrome/browser/web_applications/os_integration/web_app_protocol_handler_registration_win.cc
@@ -102,11 +102,11 @@
     const base::FilePath& profile_path) {
   base::AssertLongCPUWorkAllowed();
 
-  if (OsIntegrationTestOverride::Get()) {
+  scoped_refptr<OsIntegrationTestOverride> os_override =
+      OsIntegrationTestOverride::Get();
+  if (os_override) {
     CHECK_IS_TEST();
-    // The unregistration is not tested due to complication in the
-    // implementation of other OS's. Instead, we check if the updated
-    // registrations are empty / don't have the offending protocol.
+    os_override->RegisterProtocolSchemes(app_id, std::vector<std::string>());
     return;
   }
 
@@ -138,13 +138,9 @@
     const base::FilePath profile_path,
     std::vector<apps::ProtocolHandlerInfo> protocol_handlers,
     ResultCallback callback) {
+  scoped_refptr<OsIntegrationTestOverride> os_override =
+      OsIntegrationTestOverride::Get();
   if (protocol_handlers.empty()) {
-    scoped_refptr<OsIntegrationTestOverride> os_override =
-        OsIntegrationTestOverride::Get();
-    if (os_override) {
-      CHECK_IS_TEST();
-      os_override->RegisterProtocolSchemes(app_id, std::vector<std::string>());
-    }
     std::move(callback).Run(Result::kOk);
     return;
   }
@@ -165,6 +161,8 @@
 void UnregisterProtocolHandlersWithOs(const AppId& app_id,
                                       const base::FilePath profile_path,
                                       ResultCallback callback) {
+  scoped_refptr<OsIntegrationTestOverride> os_override =
+      OsIntegrationTestOverride::Get();
   base::ThreadPool::PostTaskAndReply(
       FROM_HERE,
       {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut_linux.cc b/chrome/browser/web_applications/os_integration/web_app_shortcut_linux.cc
index 18fb861..aa7a389 100644
--- a/chrome/browser/web_applications/os_integration/web_app_shortcut_linux.cc
+++ b/chrome/browser/web_applications/os_integration/web_app_shortcut_linux.cc
@@ -502,7 +502,7 @@
         CreateShortcutInAutoStart(env, shortcut_filename, contents) && success;
   }
 
-  if (test_override) {
+  if (test_override && !shortcut_info.protocol_handlers.empty()) {
     CHECK_IS_TEST();
     std::vector<std::string> protocol_handler(
         shortcut_info.protocol_handlers.begin(),
@@ -626,6 +626,12 @@
     deleted_from_autostart = DeleteShortcutInAutoStart(env, shortcut_filename);
   }
 
+  if (test_override) {
+    CHECK_IS_TEST();
+    test_override->RegisterProtocolSchemes(extension_id,
+                                           std::vector<std::string>());
+  }
+
   bool deleted_from_application_menu = true;
   if (!test_override) {
     deleted_from_application_menu = DeleteShortcutInApplicationsMenu(
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm b/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm
index 915c27e2..bdb27ef 100644
--- a/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm
+++ b/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #import "chrome/browser/web_applications/os_integration/web_app_shortcut_mac.h"
-#include "base/check_is_test.h"
 
 #import <Cocoa/Cocoa.h>
 #include <stdint.h>
@@ -15,6 +14,7 @@
 #include <utility>
 
 #include "base/base_switches.h"
+#include "base/check_is_test.h"
 #include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/files/file_enumerator.h"
@@ -1500,6 +1500,18 @@
   }
 
   if (!protocol_handlers.empty()) {
+    scoped_refptr<OsIntegrationTestOverride> os_override =
+        OsIntegrationTestOverride::Get();
+    if (os_override) {
+      CHECK_IS_TEST();
+      std::vector<std::string> protocol_handlers_vec;
+      protocol_handlers_vec.insert(protocol_handlers_vec.end(),
+                                   protocol_handlers.begin(),
+                                   protocol_handlers.end());
+      os_override->RegisterProtocolSchemes(info_->app_id,
+                                           std::move(protocol_handlers_vec));
+    }
+
     base::scoped_nsobject<NSMutableArray> handlers(
         [[NSMutableArray alloc] init]);
     for (const auto& protocol_handler : protocol_handlers)
@@ -1511,17 +1523,6 @@
       app_mode::kCFBundleURLSchemesKey : handlers
     } ];
   }
-  scoped_refptr<OsIntegrationTestOverride> os_override =
-      OsIntegrationTestOverride::Get();
-  if (os_override) {
-    CHECK_IS_TEST();
-    std::vector<std::string> protocol_handlers_vec;
-    protocol_handlers_vec.insert(protocol_handlers_vec.end(),
-                                 protocol_handlers.begin(),
-                                 protocol_handlers.end());
-    os_override->RegisterProtocolSchemes(info_->app_id,
-                                         std::move(protocol_handlers_vec));
-  }
 
   // TODO(crbug.com/1273526): If we decide to rename app bundles on app title
   // changes, instead of relying on localization, then this will need to change
@@ -1825,6 +1826,12 @@
   // `GetChromeAppsFolder()`).
   scoped_refptr<OsIntegrationTestOverride> test_override =
       web_app::OsIntegrationTestOverride::Get();
+
+  if (test_override) {
+    CHECK_IS_TEST();
+    test_override->RegisterProtocolSchemes(shortcut_info.app_id,
+                                           std::vector<std::string>());
+  }
   const std::string bundle_id =
       GetBundleIdentifier(shortcut_info.app_id, shortcut_info.profile_path);
   auto bundle_infos = SearchForBundlesById(bundle_id);
diff --git a/chrome/browser/webid/federated_identity_api_permission_context_factory.cc b/chrome/browser/webid/federated_identity_api_permission_context_factory.cc
index fbf96c8..ec71daa 100644
--- a/chrome/browser/webid/federated_identity_api_permission_context_factory.cc
+++ b/chrome/browser/webid/federated_identity_api_permission_context_factory.cc
@@ -29,7 +29,12 @@
     FederatedIdentityApiPermissionContextFactory()
     : ProfileKeyedServiceFactory(
           "FederatedIdentityApiPermissionContext",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
diff --git a/chrome/browser/webid/federated_identity_auto_reauthn_permission_context_factory.cc b/chrome/browser/webid/federated_identity_auto_reauthn_permission_context_factory.cc
index ddaac21..3f6fe37b 100644
--- a/chrome/browser/webid/federated_identity_auto_reauthn_permission_context_factory.cc
+++ b/chrome/browser/webid/federated_identity_auto_reauthn_permission_context_factory.cc
@@ -30,7 +30,12 @@
     FederatedIdentityAutoReauthnPermissionContextFactory()
     : ProfileKeyedServiceFactory(
           "FederatedIdentityAutoReauthnPermissionContext",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
diff --git a/chrome/browser/webid/federated_identity_permission_context_factory.cc b/chrome/browser/webid/federated_identity_permission_context_factory.cc
index c9144b9..44999151 100644
--- a/chrome/browser/webid/federated_identity_permission_context_factory.cc
+++ b/chrome/browser/webid/federated_identity_permission_context_factory.cc
@@ -36,7 +36,12 @@
     FederatedIdentityPermissionContextFactory()
     : ProfileKeyedServiceFactory(
           "FederatedIdentityPermissionContext",
-          ProfileSelections::BuildForRegularAndIncognito()) {
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kOwnInstance)
+              // TODO(crbug.com/1418376): Check if this service is needed in
+              // Guest mode.
+              .WithGuest(ProfileSelection::kOwnInstance)
+              .Build()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
diff --git a/chrome/browser/win/jumplist.cc b/chrome/browser/win/jumplist.cc
index e132cca..61c3d722 100644
--- a/chrome/browser/win/jumplist.cc
+++ b/chrome/browser/win/jumplist.cc
@@ -51,6 +51,7 @@
 #include "components/sessions/core/session_types.h"
 #include "components/strings/grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_scale_factor.h"
 #include "ui/gfx/codec/png_codec.h"
 #include "ui/gfx/favicon_size.h"
 #include "ui/gfx/icon_util.h"
@@ -135,9 +136,11 @@
   // save it as the temporary file.
   gfx::ImageFamily image_family;
   if (!image_skia.isNull()) {
-    std::vector<float> supported_scales = image_skia.GetSupportedScales();
-    for (auto& scale : supported_scales) {
-      gfx::ImageSkiaRep image_skia_rep = image_skia.GetRepresentation(scale);
+    const std::vector<ui::ResourceScaleFactor> supported_scales =
+        ui::GetSupportedResourceScaleFactors();
+    for (const auto scale : supported_scales) {
+      gfx::ImageSkiaRep image_skia_rep = image_skia.GetRepresentation(
+          ui::GetScaleForResourceScaleFactor(scale));
       if (!image_skia_rep.is_null()) {
         image_family.Add(
             gfx::Image::CreateFrom1xBitmap(image_skia_rep.GetBitmap()));
diff --git a/chrome/build/lacros-arm.pgo.txt b/chrome/build/lacros-arm.pgo.txt
index a22376d..b6283abb 100644
--- a/chrome/build/lacros-arm.pgo.txt
+++ b/chrome/build/lacros-arm.pgo.txt
@@ -1 +1 @@
-chrome-chromeos-arm-generic-main-1683590337-1642c75848c8942b7568ed245d41780e1ff3b02b.profdata
+chrome-chromeos-arm-generic-main-1683633544-85191843369fd535ab18bf3f8ffa255eb4fcf016.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index f2079be..696c702 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1683640633-57bf6337728fbacd57bed8821568b45d465d916f.profdata
+chrome-mac-arm-main-1683647964-caae149fce7222704d5c4bd322b53b3018b4845a.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index c9da4f6a..b69c4174 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1683633544-8759a51acb1e502a9a16a70f0da0061383a78033.profdata
+chrome-win32-main-1683643909-d802b791b85dfd8668c833fa2bcd15534de906c6.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index e043343..f12de18b 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1683633544-e7ef505d4a715bfb26b1769c392e0efb9f619fed.profdata
+chrome-win64-main-1683643909-1841c9e87e8a01b7f1ef6f5fd64d08900665c0c3.profdata
diff --git a/chrome/common/accessibility/read_anything_constants.cc b/chrome/common/accessibility/read_anything_constants.cc
index 390b105..d22e830 100644
--- a/chrome/common/accessibility/read_anything_constants.cc
+++ b/chrome/common/accessibility/read_anything_constants.cc
@@ -16,7 +16,10 @@
 const char kLineSpacingHistogramName[] =
     "Accessibility.ReadAnything.LineSpacing";
 const char kColorHistogramName[] = "Accessibility.ReadAnything.Color";
+const char kFontNameHistogramName[] = "Accessibility.ReadAnything.FontName";
 const char kFontScaleHistogramName[] = "Accessibility.ReadAnything.FontScale";
+const char kSettingsChangeHistogramName[] =
+    "Accessibility.ReadAnything.SettingsChange";
 
 const std::set<std::string> GetNonSelectableUrls() {
   return {
diff --git a/chrome/common/accessibility/read_anything_constants.h b/chrome/common/accessibility/read_anything_constants.h
index 31228c91..5a92562 100644
--- a/chrome/common/accessibility/read_anything_constants.h
+++ b/chrome/common/accessibility/read_anything_constants.h
@@ -17,7 +17,9 @@
 extern const char kLetterSpacingHistogramName[];
 extern const char kLineSpacingHistogramName[];
 extern const char kColorHistogramName[];
+extern const char kFontNameHistogramName[];
 extern const char kFontScaleHistogramName[];
+extern const char kSettingsChangeHistogramName[];
 
 extern const std::set<std::string> GetNonSelectableUrls();
 
@@ -50,6 +52,18 @@
 const double kReadAnythingMaximumFontScale = 4.5;
 const double kReadAnythingFontScaleIncrement = 0.25;
 
+// Enum for logging when a text style setting is changed.
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum class ReadAnythingSettingsChange {
+  kFontChange = 0,
+  kFontSizeChange = 1,
+  kThemeChange = 2,
+  kLineHeightChange = 3,
+  kLetterSpacingChange = 4,
+  kMaxValue = kLetterSpacingChange,
+};
+
 }  // namespace
 
 #endif  // CHROME_COMMON_ACCESSIBILITY_READ_ANYTHING_CONSTANTS_H_
diff --git a/chrome/renderer/extensions/api/notifications_native_handler.cc b/chrome/renderer/extensions/api/notifications_native_handler.cc
index 1ad27615..75d2c1454 100644
--- a/chrome/renderer/extensions/api/notifications_native_handler.cc
+++ b/chrome/renderer/extensions/api/notifications_native_handler.cc
@@ -31,8 +31,7 @@
     const v8::FunctionCallbackInfo<v8::Value>& args) {
   NotificationBitmapSizes bitmap_sizes = GetNotificationBitmapSizes();
 
-  const float scale_factor = ui::GetScaleForResourceScaleFactor(
-      ui::GetMaxSupportedResourceScaleFactor());
+  const float scale_factor = ui::GetScaleForMaxSupportedResourceScaleFactor();
 
   v8::Isolate* isolate = GetIsolate();
   v8::HandleScope handle_scope(isolate);
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 03e86a55..191936e 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2355,6 +2355,7 @@
       "../browser/ui/views/toolbar/avatar_toolbar_button_browsertest.cc",
       "../browser/ui/views/toolbar/chrome_labs_browsertest.cc",
       "../browser/ui/views/toolbar/home_button_browsertest.cc",
+      "../browser/ui/views/user_education/browser_user_education_service_browsertest.cc",
       "../browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc",
       "../browser/ui/views/web_apps/frame_toolbar/web_app_minimal_ui_test.cc",
       "../browser/ui/views/web_apps/protocol_handler_launch_dialog_browsertest.cc",
@@ -3876,6 +3877,7 @@
         "../browser/ash/logging_browsertest.cc",
         "../browser/ash/login/accessibility_browsertest.cc",
         "../browser/ash/login/app_mode/test/auto_launched_kiosk_browsertest.cc",
+        "../browser/ash/login/app_mode/test/chome_app_kiosk_lacros_browsertest.cc",
         "../browser/ash/login/app_mode/test/kiosk_accelerator_browsertest.cc",
         "../browser/ash/login/app_mode/test/kiosk_accelerator_lacros_browsertest.cc",
         "../browser/ash/login/app_mode/test/kiosk_apps_mixin.cc",
@@ -6649,10 +6651,10 @@
       "../browser/signin/bound_session_credentials/bound_session_cookie_controller_impl_unittest.cc",
       "../browser/signin/bound_session_credentials/bound_session_cookie_observer_unittest.cc",
       "../browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl_unittest.cc",
-      "../browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_unittest.cc",
       "../browser/signin/bound_session_credentials/bound_session_request_throttled_listener_browser_impl_unittest.cc",
       "../browser/signin/bound_session_credentials/bound_session_test_cookie_manager.cc",
       "../browser/signin/bound_session_credentials/bound_session_test_cookie_manager.h",
+      "../browser/signin/bound_session_credentials/fake_bound_session_refresh_cookie_fetcher_unittest.cc",
       "../browser/signin/bound_session_credentials/registration_token_helper_unittest.cc",
       "../renderer/bound_session_credentials/bound_session_request_throttled_in_renderer_manager_unittest.cc",
       "../renderer/bound_session_credentials/bound_session_request_throttled_listener_renderer_impl_unittest.cc",
diff --git a/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/app_main.html b/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/app_main.html
new file mode 100644
index 0000000..d83b005
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/app_main.html
@@ -0,0 +1,10 @@
+<html>
+<!--
+Copyright 2023 The Chromium Authors
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+<body>
+<h1>Kiosk Base Test App!!!</h1>
+</body>
+<hmtl>
\ No newline at end of file
diff --git a/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/icon-128.png b/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/icon-128.png
new file mode 100644
index 0000000..03bb3b6
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/icon-128.png
Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/icon-16.png b/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/icon-16.png
new file mode 100644
index 0000000..345479b
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/icon-16.png
Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/main.js b/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/main.js
new file mode 100644
index 0000000..db5513c
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/main.js
@@ -0,0 +1,7 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+chrome.app.runtime.onLaunched.addListener(function(launchData) {
+  chrome.app.window.create('app_main.html');
+});
\ No newline at end of file
diff --git a/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/manifest.json b/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/manifest.json
new file mode 100644
index 0000000..aa96a53
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/kiosk_base_test_app/src/manifest.json
@@ -0,0 +1,15 @@
+{
+  "manifest_version": 3,
+  "name": "Kiosk Base Test App",
+  "version": "1.0.0",
+  "icons": {
+    "128": "icon-128.png",
+    "16": "icon-16.png"
+  },
+  "app": {
+    "background": {
+      "scripts": ["main.js"]
+    }
+  },
+  "kiosk_enabled": true
+}
\ No newline at end of file
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/epancfbahpnkphlhpeefecinmgclhjlj.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/epancfbahpnkphlhpeefecinmgclhjlj.crx
new file mode 100644
index 0000000..0f580a79
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/webstore/downloads/epancfbahpnkphlhpeefecinmgclhjlj.crx
Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/epancfbahpnkphlhpeefecinmgclhjlj.pem b/chrome/test/data/chromeos/app_mode/webstore/downloads/epancfbahpnkphlhpeefecinmgclhjlj.pem
new file mode 100644
index 0000000..4219a20
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/webstore/downloads/epancfbahpnkphlhpeefecinmgclhjlj.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPJp1zBu3fdrer
+X0a8YSvXhtZYEjXMTNeTIsd+gjxeyt48TwCE1K4BEyITPakG5Rso0NZs2XtZnUCG
+v2iNCzhZQpmVega0IoXm5a2c3bK7ZX95IC8QVRgw+UjB5fOJMgXd1QPRZAxAsVKG
+ZNtxpys1yG39CqB+tvTmLHpp2XUKyMd7101PxVUWkMxZKD4id1E2uEXr7F3LDlhS
+tguHpHX0+VKhP+SbZsKPfMHo45E18DH+qpaxY5HlinwikNEqnl0LIvYpG5/40YAW
+iEO1JLXFKCw1k1mqpUx8DxYHmq6uskJ/LuwvSlJkvohaS/oe3cYLjpgtt0HyKnwi
+rjdff05RAgMBAAECggEABNbXGMfRqMXCNqusIFx4xLkuqrIKNbKZ2qMWW/s449ID
+bQ8/aNr7EaVbx21KVJHnl4WBbNuLySUmS7+O9rSLZXJr2hUWsQCZdjJpYt++/Ce7
+2Z2J2+zQ+tvn+jef/9V+U5dVVn/q1VwPHHqgscAA/2mmQCIOa8dkYzgox+4/kLfj
+P1uAZkqT8laEClr9TvwGU4xqLwrGP8N1pKbOZNLSredrU5TAPvcT2wGQtYQgYeYo
+dm1bMAuyvvIczcMJicqTzliU7+g+6lPz5OSoV2c0XfbmxvHEoAy4NBeNWDibvBLh
+dvjeVorSDg+YBtjnsuI0G60jmKp1JN4/WxUOPd8z/QKBgQD3vASpAJs6uOWQp0Tx
+tBmeN4e4zO6310PzC/6EfSmg1aYhLhrTCnMotUXfr7NnRmXLIY30REpeyRkoCMhZ
+0KTKa+PF02F8WC7oBnnfNffs176K6TafhKUE8D/N73aRPeENdfAEgMoIW3VhtOTB
+ZqI1n0OxfcZ8O0XprzKKEfnv4wKBgQDWD/V2XGC9vr269sYXw5Z/vAOdxAj4TCBw
+9mFoAGkw94Mk6K5gtFigXBEkQhPsEDk+d8/y9GQlH/pQ8diisBG37EQoZOmoIT4Q
+JV3yHUPl/mxZQZHOE7eq5qVn5v0piHVRfJDJWQehVxj6w1hqaqnB8AN02WZaekwJ
+yNvvspv3OwKBgQCqiqi6n0w9dKO0nTH9InqwTJIGSi3cKTkBzDP+iRtrOSkQlmio
+9/ym/YOIpa/fXLsex46tpYV9EvtacBFcoyGOqA85VHc73okL+clUPBbc2Pi3MC0G
+S44+hBWocz0wZ2TSm2oL740li7CW/qyr5zerqmQzf95wD23lnVIxcoaY+QKBgQCB
+KkYJ8nnpZIPloewsALf6QX/JHbXv5TeaEgD6mWzfwCohBknaTlhAAu3Q/BI7WhrA
+h9kxl6gqAp6vYw8+M5GtcmI6IZIgAlcJtRJ3+pKy4A+O2BLbz2f/NodOJ8JQ4mcw
+EULoS9Ff2EdZYLAkHlJqlKHxSxEIvUzOhqW3gAW+awKBgBzgmXBwNraoUDnxcMQw
+dbx2BQlDHZ5Ju/pZHQXvTj/MP9ylRKf4OplmJZqTGU/525YAoyBHwhDRoI9ZoKS9
+DUcBMTKIfYzRJTMcc6VFSxIrIZwwzmDDiS5ZIhyhRAiaTBTmK80ce+6QmcMmt9tT
+nJ97nhf3G7pq1sfgPMX4/ERZ
+-----END PRIVATE KEY-----
diff --git a/chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/epancfbahpnkphlhpeefecinmgclhjlj b/chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/epancfbahpnkphlhpeefecinmgclhjlj
new file mode 100644
index 0000000..1c2d232b
--- /dev/null
+++ b/chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/epancfbahpnkphlhpeefecinmgclhjlj
@@ -0,0 +1,11 @@
+{
+  "id": "epancfbahpnkphlhpeefecinmgclhjlj",
+  "users": "1234",
+  "average_rating": 1.0,
+  "rating_count": 999,
+  "verified_site": "chrome.google.com",
+  "localized_name": "Name of Kiosk Base Test App",
+  "localized_description": "Description of Kiosk Base Test App",
+  "icon_url": "kiosk_base_test_app/src/icon-16.png",
+  "manifest":"{ \"manifest_version\": 3, \"name\": \"Kiosk Base Test App\", \"version\": \"1.0.0\", \"icons\": { \"128\": \"icon-128.png\", \"16\": \"icon-16.png\"}, \"app\": { \"background\": { \"scripts\": [\"main.js\"] } }, \"kiosk_enabled\": true }"
+}
diff --git a/chrome/test/data/extensions/api_test/tab_groups/background.js b/chrome/test/data/extensions/api_test/tab_groups/background.js
index 4745602..e7e6374 100644
--- a/chrome/test/data/extensions/api_test/tab_groups/background.js
+++ b/chrome/test/data/extensions/api_test/tab_groups/background.js
@@ -28,17 +28,24 @@
     });
   },
   function testCreateEventDispatched() {
-    let createdGroupId = -1;
-
-    chrome.tabGroups.onCreated.addListener((group) => {
-      chrome.test.assertEq(group.id, createdGroupId);
-      chrome.test.succeed();
+    let onCreatedPromise = new Promise((resolve) => {
+      chrome.tabGroups.onCreated.addListener((group) => {
+        resolve(group.id);
+      });
     });
 
-    chrome.tabs.create({}, (tab) => {
-      chrome.tabs.group({tabIds: tab.id}, (groupId) => {
-        createdGroupId = groupId;
+    let createPromise = new Promise((resolve) => {
+      chrome.tabs.create({}, (tab) => {
+        chrome.tabs.group({tabIds: tab.id}, (groupId) => {
+          resolve(groupId);
+        });
       });
     });
+
+    Promise.allSettled([onCreatedPromise, createPromise]).then((results) => {
+      chrome.test.assertEq(results.length, 2);
+      chrome.test.assertEq(results[0], results[1]);
+      chrome.test.succeed();
+    });
   }
 ]);
diff --git a/chrome/test/data/updater/Keystone.legacy.ticketstore b/chrome/test/data/updater/Keystone.legacy.ticketstore
index 515d0b55..e7fb725 100644
--- a/chrome/test/data/updater/Keystone.legacy.ticketstore
+++ b/chrome/test/data/updater/Keystone.legacy.ticketstore
Binary files differ
diff --git a/chrome/test/data/updater/Keystone.legacy.ticketstore.plist b/chrome/test/data/updater/Keystone.legacy.ticketstore.plist
new file mode 100644
index 0000000..73234111
--- /dev/null
+++ b/chrome/test/data/updater/Keystone.legacy.ticketstore.plist
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+
+<!-- This manually crafted file is feeded to chrome/updater/tool:keystone_ticket_tool
+     to generate Keystone.legacy.ticketstore.
+
+     All value fields are in type<string>, except the `CreationDate` which is <date>.
+
+     Supported keys:
+       ProductID
+       Version
+       VersionPath
+       VersionKey
+       ExistenceChecker
+       Tag
+       TagPath
+       TagKey
+       BrandCode
+       BrandPath
+       BrandKey
+       Cohort
+       CohortHint
+       CohortName
+       CreationDate
+-->
+
+<plist version="1.0">
+<dict>
+  <key>com.chromium.corruptedapp</key>  <!-- Main key must be in lower case -->
+  <dict>
+    <key>ProductID</key><string>com.chromium.CorruptedApp</string>
+    <key>Version</key><string>1.2.1</string>
+    <key>ExistenceChecker</key><string>/</string>
+    <key>Tag</key><string>canary</string>
+    <key>CreationDate</key><date>2023-03-24T18:20:51Z</date>
+  </dict>
+
+  <key>com.chromium.popularapp</key>  <!-- Main key must be in lower case -->
+  <dict>
+    <key>ProductID</key><string>com.chromium.PopularApp</string>
+    <key>Version</key><string>101.100.1000.9999</string>
+    <key>ExistenceChecker</key><string>/</string>
+    <key>Tag</key><string>GOOG</string>
+    <key>TagPath</key><string>/Application/PopularApp.app</string>
+    <key>TagKey</key><string>KSTag</string>
+    <key>BrandPath</key><string>/</string>
+    <key>BrandKey</key><string>KSBrandID</string>
+    <key>Cohort</key><string>TestCohort</string>
+    <key>CohortHint</key><string>TestCohortHint</string>
+    <key>CohortName</key><string>TestCohortName</string>
+    <key>CreationDate</key><date>2023-03-24T18:20:51Z</date>
+  </dict>
+
+  <key>com.chromium.kipple</key>  <!-- Main key must be in lower case -->
+  <dict>
+    <key>ProductID</key><string>com.chromium.kipple</string>
+    <key>Version</key><string>1.2.3.4</string>
+    <key>ExistenceChecker</key><string>/</string>
+    <key>BrandPath</key><string>/</string>
+    <key>BrandKey</key><string>UnrecognizedBrandKey</string>
+    <key>CreationDate</key><date>2023-03-24T18:20:51Z</date>
+  </dict>
+
+  <key>com.chromium.nonexistapp</key>  <!-- Main key must be in lower case -->
+  <dict>
+    <key>ProductID</key><string>com.chromium.NonExistApp</string>
+    <key>Version</key><string>1.0.0.0</string>
+    <key>ExistenceChecker</key><string>/Applications/NoSuchDirectory.app</string>
+    <key>BrandPath</key><string>/</string>
+    <key>BrandKey</key><string>foo</string>
+    <key>CreationDate</key><date>2023-03-24T18:20:51Z</date>
+  </dict>
+
+  <key>com.google.keystone</key>  <!-- Main key must be in lower case -->
+  <dict>
+    <key>ProductID</key><string>com.google.Keystone</string>
+    <key>Version</key><string>1.100.18.0</string>
+    <key>ExistenceChecker</key>
+    <string>
+     /Users/CoolUser/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle
+    </string>
+    <key>Cohort</key><string>1:1lax:1lb3@5.4000000000000005E-5</string>
+    <key>CohortName</key><string>Omaha 4 Migration (Rollout)</string>
+    <key>CreationDate</key><date>2023-03-24T18:20:51Z</date>
+  </dict>
+</dict>
+</plist>
diff --git a/chrome/test/data/webui/net_internals/dns_view_test.js b/chrome/test/data/webui/net_internals/dns_view_test.js
index abbea6084..0c20cce 100644
--- a/chrome/test/data/webui/net_internals/dns_view_test.js
+++ b/chrome/test/data/webui/net_internals/dns_view_test.js
@@ -14,11 +14,14 @@
 dns_view_test.suiteName = 'NetInternalsDnsViewTests';
 /** @enum {string} */
 dns_view_test.TestNames = {
-  ResolveSingleHostWithoutMetadata: 'resolve single host without metadata',
-  ResolveSingleHostWithHTTP2Alpn: 'resolve single host with http2 alpn',
-  ResolveSingleHostWithHTTP3Alpn: 'resolve single host with http3 alpn',
-  ResolveMultipleHostWithMultipleAlpns:
-      'resolve multiple host with multiple alpns',
+  ResolveHostWithoutAlternative: 'resolve host with no alternative endpoints',
+  ResolveHostWithHTTP2Alternative:
+      'resolve host with http2 alternative endpoint',
+  ResolveHostWithHTTP3Alternative:
+      'resolve host with http3 alternative endpoint',
+  ResolveHostWithECHAlternative: 'resolve host with ECH alternative endpoint',
+  ResolveHostWithMultipleAlternatives:
+      'resolve host with multiple alternative endpoints',
   ErrorNameNotResolved: 'error name not resolved',
   ClearCache: 'clear cache',
 };
@@ -93,72 +96,81 @@
   }
 
   /**
-   * Checks a single host resolve without metadata.
+   * Checks a host resolve without alternative endpoints.
    */
-  test(dns_view_test.TestNames.ResolveSingleHostWithoutMetadata, function() {
+  test(dns_view_test.TestNames.ResolveHostWithoutAlternative, function() {
     switchToView('dns');
     const taskQueue = new TaskQueue(true);
-
-    // Make sure a successful lookup of single address without metadata.
     taskQueue.addTask(new ResolveHostTask('somewhere.com'));
     taskQueue.addFunctionTask(assertEquals.bind(
         null,
         'Resolved IP addresses of "somewhere.com": ["127.0.0.1"].' +
-            'No data on which protocols are supported.'));
+            'No alternative endpoints.'));
     return taskQueue.run();
   });
 
   /**
-   * Checks a single host resolve with supported protocol alpns {"http/1.1",
-   * "h2"}.
+   * Checks a host resolve with an alternative endpoint that supports "http/1.1"
+   * and "h2".
    */
-  test(dns_view_test.TestNames.ResolveSingleHostWithHTTP2Alpn, function() {
+  test(dns_view_test.TestNames.ResolveHostWithHTTP2Alternative, function() {
     switchToView('dns');
     const taskQueue = new TaskQueue(true);
-
-    // Make sure a successful lookup of single address with supported protocol
-    // alpns {"http/1.1","h2"}.
     taskQueue.addTask(new ResolveHostTask('http2.com'));
     taskQueue.addFunctionTask(assertEquals.bind(
         null,
         'Resolved IP addresses of "http2.com": ["127.0.0.1"].' +
-            'Supported protocol alpns of "["127.0.0.1"]": ["http/1.1","h2"].'));
+            'Alternative endpoint: ' +
+            '{"alpns":["http/1.1","h2"],"ip_endpoints":["127.0.0.1"]}.'));
     return taskQueue.run();
   });
 
   /**
-   * Checks a single host resolve with supported protocol alpns {"http/1.1",
-   * "h2", "h3"}.
+   * Checks a host resolve with an alternative endpoint that supports
+   * "http/1.1", "h2", and "h3".
    */
-  test(dns_view_test.TestNames.ResolveSingleHostWithHTTP3Alpn, function() {
+  test(dns_view_test.TestNames.ResolveHostWithHTTP3Alternative, function() {
     switchToView('dns');
     const taskQueue = new TaskQueue(true);
-
-    // Make sure a successful lookup of single address with supported protocol
-    // alpns {"http/1.1","h2","h3"}.
     taskQueue.addTask(new ResolveHostTask('http3.com'));
     taskQueue.addFunctionTask(assertEquals.bind(
         null,
         'Resolved IP addresses of "http3.com": ["127.0.0.1"].' +
-            'Supported protocol alpns of "["127.0.0.1"]": ["http/1.1","h2","h3"].'));
+            'Alternative endpoint: ' +
+            '{"alpns":["http/1.1","h2","h3"],"ip_endpoints":["127.0.0.1"]}.'));
     return taskQueue.run();
   });
 
   /**
-   * Checks a multiple host resolve with multiple supported protocol alpns.
+   * Checks a host resolve with an alternative endpoint that supports ECH.
    */
-  test(dns_view_test.TestNames.ResolveMultipleHostWithMultipleAlpns, function() {
+  test(dns_view_test.TestNames.ResolveHostWithECHAlternative, function() {
     switchToView('dns');
     const taskQueue = new TaskQueue(true);
+    taskQueue.addTask(new ResolveHostTask('ech.com'));
+    taskQueue.addFunctionTask(assertEquals.bind(
+        null,
+        'Resolved IP addresses of "ech.com": ["127.0.0.1"].' +
+            'Alternative endpoint: ' +
+            '{"alpns":["http/1.1","h2"],"ech_config_list":"AQIDBA==",' +
+            '"ip_endpoints":["127.0.0.1"]}.'));
+    return taskQueue.run();
+  });
 
-    // Make sure a successful lookup of multiple addresses with multiple
-    // supported protocol alpns.
+  /**
+   * Checks a host resolve with multiple alternative endpoints.
+   */
+  test(dns_view_test.TestNames.ResolveHostWithMultipleAlternatives, function() {
+    switchToView('dns');
+    const taskQueue = new TaskQueue(true);
     taskQueue.addTask(new ResolveHostTask('multihost.com'));
     taskQueue.addFunctionTask(assertEquals.bind(
         null,
         'Resolved IP addresses of "multihost.com": ["127.0.0.1","127.0.0.2"].' +
-            'Supported protocol alpns of "["127.0.0.1"]": ["http/1.1","h2"].' +
-            'Supported protocol alpns of "["127.0.0.2"]": ["http/1.1","h2","h3"].'));
+            'Alternative endpoint: ' +
+            '{"alpns":["http/1.1","h2"],"ip_endpoints":["127.0.0.1"]}.' +
+            'Alternative endpoint: ' +
+            '{"alpns":["http/1.1","h2","h3"],"ip_endpoints":["127.0.0.2"]}.'));
     return taskQueue.run();
   });
 
diff --git a/chrome/test/data/webui/net_internals/net_internals_browsertest.js b/chrome/test/data/webui/net_internals/net_internals_browsertest.js
index f723d2a..988869e 100644
--- a/chrome/test/data/webui/net_internals/net_internals_browsertest.js
+++ b/chrome/test/data/webui/net_internals/net_internals_browsertest.js
@@ -66,29 +66,31 @@
   },
 };
 
+TEST_F('NetInternalsDnsViewTest', 'ResolveHostWithoutAlternative', function() {
+  this.runMochaTest(dns_view_test.TestNames.ResolveHostWithoutAlternative);
+});
+
 TEST_F(
-    'NetInternalsDnsViewTest', 'ResolveSingleHostWithoutMetadata', function() {
+    'NetInternalsDnsViewTest', 'ResolveHostWithHTTP2Alternative', function() {
       this.runMochaTest(
-          dns_view_test.TestNames.ResolveSingleHostWithoutMetadata);
+          dns_view_test.TestNames.ResolveHostWithHTTP2Alternative);
     });
 
 TEST_F(
-    'NetInternalsDnsViewTest', 'ResolveSingleHostWithHTTP2Metadata',
-    function() {
-      this.runMochaTest(dns_view_test.TestNames.ResolveSingleHostWithHTTP2Alpn);
+    'NetInternalsDnsViewTest', 'ResolveHostWithHTTP3Alternative', function() {
+      this.runMochaTest(
+          dns_view_test.TestNames.ResolveHostWithHTTP3Alternative);
     });
 
-TEST_F(
-    'NetInternalsDnsViewTest', 'ResolveSingleHostWithHTTP3Metadata',
-    function() {
-      this.runMochaTest(dns_view_test.TestNames.ResolveSingleHostWithHTTP3Alpn);
-    });
+TEST_F('NetInternalsDnsViewTest', 'ResolveHostWithECHAlternative', function() {
+  this.runMochaTest(dns_view_test.TestNames.ResolveHostWithECHAlternative);
+});
 
 TEST_F(
-    'NetInternalsDnsViewTest', 'ResolveMultipleHostWithMultipleAlpns',
+    'NetInternalsDnsViewTest', 'ResolveHostWithMultipleAlternatives',
     function() {
       this.runMochaTest(
-          dns_view_test.TestNames.ResolveMultipleHostWithMultipleAlpns);
+          dns_view_test.TestNames.ResolveHostWithMultipleAlternatives);
     });
 
 TEST_F('NetInternalsDnsViewTest', 'ErrorNameNotResolved', function() {
diff --git a/chrome/test/data/webui/settings/chromeos/multidevice_page/multidevice_smartlock_item_test.ts b/chrome/test/data/webui/settings/chromeos/multidevice_page/multidevice_smartlock_item_test.ts
index 69f82011..f80177be9 100644
--- a/chrome/test/data/webui/settings/chromeos/multidevice_page/multidevice_smartlock_item_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/multidevice_page/multidevice_smartlock_item_test.ts
@@ -8,7 +8,6 @@
 import {MultiDeviceBrowserProxyImpl, MultiDeviceFeature, MultiDeviceFeatureState, MultiDevicePageContentData, MultiDeviceSettingsMode, Router} from 'chrome://os-settings/chromeos/os_settings.js';
 import {assert} from 'chrome://resources/js/assert_ts.js';
 import {webUIListenerCallback} from 'chrome://resources/js/cr.js';
-import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals} from 'chrome://webui-test/chai_assert.js';
 
@@ -83,16 +82,7 @@
     browserProxy.resetResolver('setFeatureEnabledState');
   }
 
-  /**
-   * @param isSmartLockSignInRemoved Whether to enable or disable the
-   *     isSmartLockSignInRemoved flag.
-   * TODO(b/227674947): When Sign in with Smart Lock is removed, this function
-   * can be replaced with a normal setup() function that will automatically run
-   * before each test and not require a param.
-   */
-  function initializeElement(isSmartLockSignInRemoved: boolean = false) {
-    loadTimeData.overrideValues(
-        {'isSmartLockSignInRemoved': isSmartLockSignInRemoved});
+  setup(() => {
     browserProxy = new TestMultideviceBrowserProxy();
     MultiDeviceBrowserProxyImpl.setInstanceForTesting(browserProxy);
 
@@ -107,7 +97,7 @@
     setSmartLockState(MultiDeviceFeatureState.ENABLED_BY_USER);
 
     return browserProxy.whenCalled('getPageContentData');
-  }
+  });
 
   teardown(() => {
     smartLockItem.remove();
@@ -115,7 +105,6 @@
   });
 
   test('settings row visibile only if host is verified', () => {
-    initializeElement();
     for (const mode of Object.values(MultiDeviceSettingsMode)) {
       setHostData(mode as MultiDeviceSettingsMode);
       setBetterTogetherState(MultiDeviceFeatureState.ENABLED_BY_USER);
@@ -131,7 +120,6 @@
   });
 
   test('settings row visibile only if feature is supported', () => {
-    initializeElement();
     let featureItem = smartLockItem.shadowRoot!.querySelector('#smartLockItem');
     assert(featureItem);
 
@@ -147,7 +135,6 @@
   });
 
   test('settings row visibile only if better together suite is enabled', () => {
-    initializeElement();
     let featureItem = smartLockItem.shadowRoot!.querySelector('#smartLockItem');
     assert(featureItem);
     setBetterTogetherState(MultiDeviceFeatureState.DISABLED_BY_USER);
@@ -156,16 +143,8 @@
   });
 
   test('feature toggle click event handled', async () => {
-    initializeElement();
     await simulateFeatureStateChangeRequest(false);
     await simulateFeatureStateChangeRequest(true);
   });
 
-  test('SmartLockSignInRemoved flag removes subpage', async () => {
-    initializeElement(/*isSmartLockSignInRemoved=*/ true);
-    const featureItem = smartLockItem.shadowRoot!.querySelector(
-        'settings-multidevice-feature-item');
-    assert(featureItem);
-    assertEquals(undefined, featureItem.subpageRoute);
-  });
 });
diff --git a/chrome/test/data/webui/settings/chromeos/multidevice_page/test_multidevice_browser_proxy.ts b/chrome/test/data/webui/settings/chromeos/multidevice_page/test_multidevice_browser_proxy.ts
index 82f2b08d..6a59bead 100644
--- a/chrome/test/data/webui/settings/chromeos/multidevice_page/test_multidevice_browser_proxy.ts
+++ b/chrome/test/data/webui/settings/chromeos/multidevice_page/test_multidevice_browser_proxy.ts
@@ -47,7 +47,6 @@
       createFakePageContentData(MultiDeviceSettingsMode.NO_HOST_SET);
   private androidSmsInfo_:
       AndroidSmsInfo = {origin: TEST_ANDROID_SMS_ORIGIN, enabled: true};
-  private smartLockSignInAllowed_: boolean = true;
 
   constructor() {
     super([
@@ -55,7 +54,6 @@
       'getPageContentData',
       'setFeatureEnabledState',
       'setUpAndroidSms',
-      'getSmartLockSignInAllowed',
       'getAndroidSmsInfo',
       'attemptNotificationSetup',
       'cancelNotificationSetup',
@@ -97,12 +95,6 @@
     this.methodCalled('setUpAndroidSms');
   }
 
-  /** @override */
-  getSmartLockSignInAllowed() {
-    this.methodCalled('getSmartLockSignInAllowed');
-    return Promise.resolve(this.smartLockSignInAllowed_);
-  }
-
   getAndroidSmsInfo(): Promise<AndroidSmsInfo> {
     this.methodCalled('getAndroidSmsInfo');
     return Promise.resolve(this.androidSmsInfo_);
diff --git a/chrome/updater/mac/setup/keystone_unittest.cc b/chrome/updater/mac/setup/keystone_unittest.cc
index 8a135df2d..fbae707 100644
--- a/chrome/updater/mac/setup/keystone_unittest.cc
+++ b/chrome/updater/mac/setup/keystone_unittest.cc
@@ -56,7 +56,7 @@
 
   EXPECT_EQ(registration_requests.size(), 4u);
 
-  EXPECT_EQ(registration_requests[0].app_id, "com.chromium.CorruptedApp");
+  EXPECT_EQ(registration_requests[0].app_id, "com.chromium.corruptedapp");
   EXPECT_TRUE(registration_requests[0].brand_code.empty());
   EXPECT_TRUE(registration_requests[0].brand_path.empty());
   EXPECT_EQ(registration_requests[0].ap, "canary");
@@ -66,7 +66,7 @@
   EXPECT_FALSE(registration_requests[0].dla);   // Value is too big.
   EXPECT_FALSE(registration_requests[0].dlrc);  // Value is too small.
 
-  EXPECT_EQ(registration_requests[1].app_id, "com.chromium.PopularApp");
+  EXPECT_EQ(registration_requests[1].app_id, "com.chromium.popularapp");
   EXPECT_TRUE(registration_requests[1].brand_code.empty());
   EXPECT_EQ(registration_requests[1].brand_path, base::FilePath("/"));
   EXPECT_EQ(registration_requests[1].ap, "GOOG");
@@ -74,6 +74,9 @@
             base::Version("101.100.1000.9999"));
   EXPECT_EQ(registration_requests[1].existence_checker_path,
             base::FilePath("/"));
+  EXPECT_EQ(registration_requests[1].cohort, "TestCohort");
+  EXPECT_EQ(registration_requests[1].cohort_hint, "TestCohortHint");
+  EXPECT_EQ(registration_requests[1].cohort_name, "TestCohortName");
   EXPECT_EQ(registration_requests[1].dla.value(), 5921);
   EXPECT_EQ(registration_requests[1].dlrc.value(), 5922);
 
@@ -84,7 +87,7 @@
   EXPECT_FALSE(registration_requests[2].dla);   // No data.
   EXPECT_FALSE(registration_requests[2].dlrc);  // String value is ignored.
 
-  EXPECT_EQ(registration_requests[3].app_id, "com.chromium.NonExistApp");
+  EXPECT_EQ(registration_requests[3].app_id, "com.chromium.nonexistapp");
   EXPECT_TRUE(registration_requests[3].brand_path.empty());
 }
 
diff --git a/chrome/updater/mac/setup/ks_tickets.h b/chrome/updater/mac/setup/ks_tickets.h
index 7786e36..a203fed9 100644
--- a/chrome/updater/mac/setup/ks_tickets.h
+++ b/chrome/updater/mac/setup/ks_tickets.h
@@ -16,9 +16,30 @@
 
 @interface KSPathExistenceChecker : NSObject <NSSecureCoding>
 @property(nonnull, readonly) NSString* path;
+
+- (nullable instancetype)initWithFilePath:(const base::FilePath&)filePath;
 @end
 
-@interface KSTicket : NSObject <NSSecureCoding>
+@interface KSTicket : NSObject <NSSecureCoding> {
+  NSString* productID_;
+  NSString* version_;
+  NSString* brandCode_;
+  KSPathExistenceChecker* existenceChecker_;
+  NSURL* serverURL_;
+  NSString* serverType_;
+  NSDate* creationDate_;
+  NSString* tag_;
+  NSString* tagPath_;
+  NSString* tagKey_;
+  NSString* brandPath_;
+  NSString* brandKey_;
+  NSString* versionPath_;
+  NSString* versionKey_;
+  NSString* cohort_;
+  NSString* cohortHint_;
+  NSString* cohortName_;
+  int32_t ticketVersion_;
+}
 
 @property(nonnull, nonatomic, readonly) NSString* productID;
 @property(nullable, nonatomic, readonly)
diff --git a/chrome/updater/mac/setup/ks_tickets.mm b/chrome/updater/mac/setup/ks_tickets.mm
index f1528999a..f6d159a 100644
--- a/chrome/updater/mac/setup/ks_tickets.mm
+++ b/chrome/updater/mac/setup/ks_tickets.mm
@@ -125,7 +125,7 @@
 }
 
 - (void)encodeWithCoder:(NSCoder*)coder {
-  NOTREACHED() << "KSPathExistenceChecker::encodeWithCoder not implemented.";
+  [coder encodeObject:path_ forKey:@"path"];
 }
 
 - (NSString*)description {
@@ -202,15 +202,26 @@
 
 @end
 
+// All these keys must be same as those from Keystone.
+NSString* const kKSTicketBrandKeyKey = @"brandKey";
+NSString* const kKSTicketBrandPathKey = @"brandPath";
 NSString* const kKSTicketCohortKey = @"Cohort";
 NSString* const kKSTicketCohortHintKey = @"CohortHint";
 NSString* const kKSTicketCohortNameKey = @"CohortName";
+NSString* const kKSTicketCreationDateKey = @"creation_date";
+NSString* const kKSTicketExistenceCheckerKey = @"existence_checker";
+NSString* const kKSTicketProductIDKey = @"product_id";
+NSString* const kKSTicketServerTypeKey = @"serverType";
+NSString* const kKSTicketServerURLKey = @"server_url";
+NSString* const kKSTicketTagKey = @"tag";
+NSString* const kKSTicketTagKeyKey = @"tagKey";
+NSString* const kKSTicketTagPathKey = @"tagPath";
+NSString* const kKSTicketTicketVersionKey = @"ticketVersion";
+NSString* const kKSTicketVersionKey = @"version";
+NSString* const kKSTicketVersionPathKey = @"versionPath";
+NSString* const kKSTicketVersionKeyKey = @"versionKey";
 
-@implementation KSTicket {
-  NSString* tag_;
-  NSString* version_;
-  NSString* brandCode_;
-}
+@implementation KSTicket
 
 @synthesize productID = productID_;
 @synthesize version = version_;
@@ -242,7 +253,7 @@
                             [NSString class],
                             [NSURL class],
                           ]]
-                                         forKey:@"server_url"];
+                                         forKey:kKSTicketServerURLKey];
   if (!serverURL)
     return nil;
   if ([serverURL isKindOfClass:[NSString class]]) {
@@ -254,40 +265,42 @@
 - (instancetype)initWithCoder:(NSCoder*)coder {
   if ((self = [super init])) {
     productID_ = [[coder decodeObjectOfClass:[NSString class]
-                                      forKey:@"product_id"] retain];
+                                      forKey:kKSTicketProductIDKey] retain];
     version_ = [[coder decodeObjectOfClass:[NSString class]
-                                    forKey:@"version"] retain];
-    if ([[coder decodeObjectForKey:@"existence_checker"]
+                                    forKey:kKSTicketVersionKey] retain];
+    if ([[coder decodeObjectForKey:kKSTicketExistenceCheckerKey]
             isKindOfClass:[KSPathExistenceChecker class]]) {
       existenceChecker_ =
           [[coder decodeObjectOfClass:[KSPathExistenceChecker class]
-                               forKey:@"existence_checker"] retain];
+                               forKey:kKSTicketExistenceCheckerKey] retain];
     }
     serverURL_ = [[self decodeServerURL:coder] retain];
-    creationDate_ = [[coder decodeObjectOfClass:[NSDate class]
-                                         forKey:@"creation_date"] retain];
+    creationDate_ =
+        [[coder decodeObjectOfClass:[NSDate class]
+                             forKey:kKSTicketCreationDateKey] retain];
     serverType_ = [[coder decodeObjectOfClass:[NSString class]
-                                       forKey:@"serverType"] retain];
-    tag_ = [[coder decodeObjectOfClass:[NSString class] forKey:@"tag"] retain];
+                                       forKey:kKSTicketServerTypeKey] retain];
+    tag_ = [[coder decodeObjectOfClass:[NSString class]
+                                forKey:kKSTicketTagKey] retain];
     tagPath_ = [[coder decodeObjectOfClass:[NSString class]
-                                    forKey:@"tagPath"] retain];
+                                    forKey:kKSTicketTagPathKey] retain];
     tagKey_ = [[coder decodeObjectOfClass:[NSString class]
-                                   forKey:@"tagKey"] retain];
+                                   forKey:kKSTicketTagKeyKey] retain];
     brandPath_ = [[coder decodeObjectOfClass:[NSString class]
-                                      forKey:@"brandPath"] retain];
+                                      forKey:kKSTicketBrandPathKey] retain];
     brandKey_ = [[coder decodeObjectOfClass:[NSString class]
-                                     forKey:@"brandKey"] retain];
+                                     forKey:kKSTicketBrandKeyKey] retain];
     versionPath_ = [[coder decodeObjectOfClass:[NSString class]
-                                        forKey:@"versionPath"] retain];
+                                        forKey:kKSTicketVersionPathKey] retain];
     versionKey_ = [[coder decodeObjectOfClass:[NSString class]
-                                       forKey:@"versionKey"] retain];
+                                       forKey:kKSTicketVersionKeyKey] retain];
     cohort_ = [[coder decodeObjectOfClass:[NSString class]
                                    forKey:kKSTicketCohortKey] retain];
     cohortHint_ = [[coder decodeObjectOfClass:[NSString class]
                                        forKey:kKSTicketCohortHintKey] retain];
     cohortName_ = [[coder decodeObjectOfClass:[NSString class]
                                        forKey:kKSTicketCohortNameKey] retain];
-    ticketVersion_ = [coder decodeInt32ForKey:@"ticketVersion"];
+    ticketVersion_ = [coder decodeInt32ForKey:kKSTicketTicketVersionKey];
   }
   return self;
 }
@@ -347,7 +360,45 @@
 }
 
 - (void)encodeWithCoder:(NSCoder*)coder {
-  NOTREACHED() << "KSTicket::encodeWithCoder not implemented.";
+  [coder encodeObject:productID_ forKey:kKSTicketProductIDKey];
+  [coder encodeObject:version_ forKey:kKSTicketVersionKey];
+  [coder encodeObject:existenceChecker_ forKey:kKSTicketExistenceCheckerKey];
+  [coder encodeObject:serverURL_ forKey:kKSTicketServerURLKey];
+  [coder encodeObject:creationDate_ forKey:kKSTicketCreationDateKey];
+  if (serverType_.length) {
+    [coder encodeObject:serverType_ forKey:kKSTicketServerTypeKey];
+  }
+  if (tag_.length) {
+    [coder encodeObject:tag_ forKey:kKSTicketTagKey];
+  }
+  if (tagPath_.length) {
+    [coder encodeObject:tagPath_ forKey:kKSTicketTagPathKey];
+  }
+  if (tagKey_.length) {
+    [coder encodeObject:tagKey_ forKey:kKSTicketTagKeyKey];
+  }
+  if (brandPath_.length) {
+    [coder encodeObject:brandPath_ forKey:kKSTicketBrandPathKey];
+  }
+  if (brandKey_.length) {
+    [coder encodeObject:brandKey_ forKey:kKSTicketBrandKeyKey];
+  }
+  if (versionPath_.length) {
+    [coder encodeObject:versionPath_ forKey:kKSTicketVersionPathKey];
+  }
+  if (versionKey_.length) {
+    [coder encodeObject:versionKey_ forKey:kKSTicketVersionKeyKey];
+  }
+  if (cohort_.length) {
+    [coder encodeObject:cohort_ forKey:kKSTicketCohortKey];
+  }
+  if (cohortHint_.length) {
+    [coder encodeObject:cohortHint_ forKey:kKSTicketCohortHintKey];
+  }
+  if (cohortName_.length) {
+    [coder encodeObject:cohortName_ forKey:kKSTicketCohortNameKey];
+  }
+  [coder encodeInt32:ticketVersion_ forKey:kKSTicketTicketVersionKey];
 }
 
 - (NSUInteger)hash {
diff --git a/chrome/updater/test/integration_tests_mac.mm b/chrome/updater/test/integration_tests_mac.mm
index 238670f..7674c18 100644
--- a/chrome/updater/test/integration_tests_mac.mm
+++ b/chrome/updater/test/integration_tests_mac.mm
@@ -321,13 +321,11 @@
   EXPECT_EQ(persisted_data->GetDateLastActive(kPopularApp).value(), 5921);
   EXPECT_EQ(persisted_data->GetDateLastRollcall(kPopularApp).value(), 5922);
 
-// TODO(crbug.com/1442695): Enable this after updating the `ticketstore` under
-// chrome/test/data/updater/Keystone.legacy.ticketstore.
-#if 0
+  // TODO(crbug.com/1442695): Enable this after updating the `ticketstore` under
+  // chrome/test/data/updater/Keystone.legacy.ticketstore.
   EXPECT_EQ(persisted_data->GetCohort(kPopularApp), "TestCohort");
   EXPECT_EQ(persisted_data->GetCohortName(kPopularApp), "TestCohortName");
   EXPECT_EQ(persisted_data->GetCohortHint(kPopularApp), "TestCohortHint");
-#endif
 
   // App CorruptedApp (client-regulated counting data is corrupted).
   const std::string kCorruptedApp = "com.chromium.CorruptedApp";
diff --git a/chrome/updater/tools/BUILD.gn b/chrome/updater/tools/BUILD.gn
index eba89fa2..2d9bd9f8 100644
--- a/chrome/updater/tools/BUILD.gn
+++ b/chrome/updater/tools/BUILD.gn
@@ -46,8 +46,8 @@
 }
 
 if (is_mac) {
-  executable("keystone_ticketstore_reader") {
-    sources = [ "keystone_ticketstore_reader.mm" ]
+  executable("keystone_ticketstore_tool") {
+    sources = [ "keystone_ticketstore_tool.mm" ]
     deps = [
       "//base",
       "//chrome/updater:ks_ticket",
diff --git a/chrome/updater/tools/keystone_ticketstore_reader.mm b/chrome/updater/tools/keystone_ticketstore_reader.mm
deleted file mode 100644
index b2da68ea..0000000
--- a/chrome/updater/tools/keystone_ticketstore_reader.mm
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-
-#include "base/strings/sys_string_conversions.h"
-#import "chrome/updater/mac/setup/ks_tickets.h"
-
-namespace updater {
-namespace {
-
-int ReadTicketStore(char* path) {
-  @autoreleasepool {
-    NSDictionary<NSString*, KSTicket*>* store =
-        [KSTicketStore readStoreWithPath:[NSString stringWithUTF8String:path]];
-    for (NSString* key in store) {
-      std::cout << "------ Key " << base::SysNSStringToUTF8(key) << "\n"
-                << base::SysNSStringToUTF8(
-                       [[store objectForKey:key] description])
-                << "\n\n";
-    }
-  }
-  return 0;
-}
-
-}  // namespace
-}  // namespace updater
-
-int main(int argc, char* argv[]) {
-  if (argc != 2) {
-    std::cerr << "Usage: keystone_ticket_reader path/to/Keystone.ticketstore\n";
-    return 1;
-  }
-  return updater::ReadTicketStore(argv[1]);
-}
diff --git a/chrome/updater/tools/keystone_ticketstore_tool.mm b/chrome/updater/tools/keystone_ticketstore_tool.mm
new file mode 100644
index 0000000..248a272
--- /dev/null
+++ b/chrome/updater/tools/keystone_ticketstore_tool.mm
@@ -0,0 +1,187 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Foundation/Foundation.h>
+
+#include <iostream>
+
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/mac/foundation_util.h"
+#include "base/strings/sys_string_conversions.h"
+#import "chrome/updater/mac/setup/ks_tickets.h"
+
+@interface KSTicket (TestingTool)
+@end
+
+@implementation KSTicket (TestingTool)
+- (instancetype)initWithAppId:(NSString*)appId
+                      version:(NSString*)version
+                  versionPath:(NSString*)versionPath
+                   versionKey:(NSString*)versionKey
+                          ecp:(NSString*)ecp
+                          tag:(NSString*)tag
+                      tagPath:(NSString*)tagPath
+                       tagKey:(NSString*)tagKey
+                    brandCode:(NSString*)brandCode
+                    brandPath:(NSString*)brandPath
+                     brandKey:(NSString*)brandKey
+                       cohort:(NSString*)cohort
+                   cohortHint:(NSString*)cohortHint
+                   cohortName:(NSString*)cohortName
+                 creationDate:(NSDate*)creationData {
+  if ((self = [super init])) {
+    productID_ = [appId retain];
+    version_ = [version retain];
+    if (ecp.length) {
+      existenceChecker_ = [[KSPathExistenceChecker alloc]
+          initWithFilePath:base::mac::NSStringToFilePath(ecp)];
+    }
+    tag_ = [tag retain];
+    if (tagPath.length) {
+      tagPath_ = [tagPath retain];
+    }
+    if (tagKey.length) {
+      tagKey_ = [tagKey retain];
+    }
+    brandCode_ = [brandCode retain];
+    if (brandPath.length) {
+      brandPath_ = [brandPath retain];
+    }
+    if (brandKey.length) {
+      brandKey_ = [brandKey retain];
+    }
+    serverURL_ = [[NSURL
+        URLWithString:@"https://tools.google.com/service/update2"] retain];
+    serverType_ = [@"Omaha" retain];
+    versionPath_ = [versionPath retain];
+    versionKey_ = [versionKey retain];
+    cohort_ = [cohort retain];
+    cohortHint_ = [cohortHint retain];
+    cohortName_ = [cohortName retain];
+    creationDate_ = [creationData retain];
+    ticketVersion_ = 1;
+  }
+  return self;
+}
+@end
+
+namespace updater {
+namespace {
+constexpr char kPlistPathSwtich[] = "plist";
+constexpr char kStorePathSwitch[] = "store";
+
+void Usage() {
+  std::cerr
+      << "Usage:" << std::endl
+      << "    Read Keystone ticket store: " << std::endl
+      << "        keystone_ticket_tool --store=<path/to/Keystone.ticketstore>"
+      << std::endl
+      << std::endl
+      << "    Convert plist ticket store to Keystone ticket store: "
+      << std::endl
+      << "        keystone_ticket_tool --plist=<path/to/ticketstore.plist> "
+      << "--store=<path/to/Keystone.ticketstore>" << std::endl
+      << std::endl;
+}
+
+int ReadTicketStore(const base::FilePath& path) {
+  @autoreleasepool {
+    NSDictionary<NSString*, KSTicket*>* store =
+        [KSTicketStore readStoreWithPath:base::mac::FilePathToNSString(path)];
+    for (NSString* key in store) {
+      std::cout << "------ Key " << base::SysNSStringToUTF8(key) << std::endl
+                << base::SysNSStringToUTF8(
+                       [[store objectForKey:key] description])
+                << std::endl
+                << std::endl;
+    }
+  }
+  return 0;
+}
+
+NSDictionary<NSString*, KSTicket*>* ReadPlistTicketStore(
+    const base::FilePath& input) {
+  NSError* error = nil;
+  NSDictionary<NSString*, NSDictionary<NSString*, id>*>* tickets_data =
+      [NSDictionary
+          dictionaryWithContentsOfURL:base::mac::FilePathToNSURL(input)
+                                error:&error];
+  if (error) {
+    std::cerr << "Error read store: " << error << "\n";
+    return nil;
+  }
+
+  NSMutableDictionary* tickets = [NSMutableDictionary dictionary];
+  [tickets_data
+      enumerateKeysAndObjectsUsingBlock:^(id key, id ticket_data, BOOL* stop) {
+        tickets[key] =
+            [[KSTicket alloc] initWithAppId:key
+                                    version:ticket_data[@"Version"]
+                                versionPath:ticket_data[@"VersionPath"]
+                                 versionKey:ticket_data[@"VersionKey"]
+                                        ecp:ticket_data[@"ExistenceChecker"]
+                                        tag:ticket_data[@"Tag"]
+                                    tagPath:ticket_data[@"TagPath"]
+                                     tagKey:ticket_data[@"TagKey"]
+                                  brandCode:ticket_data[@"BrandCode"]
+                                  brandPath:ticket_data[@"BrandPath"]
+                                   brandKey:ticket_data[@"BrandKey"]
+                                     cohort:ticket_data[@"Cohort"]
+                                 cohortHint:ticket_data[@"CohortHint"]
+                                 cohortName:ticket_data[@"CohortName"]
+                               creationDate:ticket_data[@"CreationDate"]];
+      }];
+  return tickets;
+}
+
+int ConvertTicketStore(const base::FilePath& input,
+                       const base::FilePath& output) {
+  @autoreleasepool {
+    NSDictionary<NSString*, KSTicket*>* store = ReadPlistTicketStore(input);
+    if (!store) {
+      std::cerr << "Failed to read input ticket store, is it a valid plist?"
+                << std::endl;
+      return 1;
+    }
+
+    NSData* storeData = [NSKeyedArchiver archivedDataWithRootObject:store];
+    if (!storeData) {
+      std::cerr << "Input ticket store data is invalid." << std::endl;
+      return 1;
+    }
+
+    NSError* error = nil;
+    if (![storeData writeToFile:base::mac::FilePathToNSString(output)
+                        options:NSAtomicWrite
+                          error:&error]) {
+      std::cerr << "Failed to write output: " << error << std::endl;
+      return 1;
+    }
+    return 0;
+  }
+}
+
+}  // namespace
+}  // namespace updater
+
+int main(int argc, char* argv[]) {
+  base::CommandLine::Init(argc, argv);
+  const base::CommandLine* command_line =
+      base::CommandLine::ForCurrentProcess();
+
+  if (!command_line->HasSwitch(updater::kStorePathSwitch)) {
+    updater::Usage();
+    return 1;
+  }
+
+  if (command_line->HasSwitch(updater::kPlistPathSwtich)) {
+    return updater::ConvertTicketStore(
+        command_line->GetSwitchValuePath(updater::kPlistPathSwtich),
+        command_line->GetSwitchValuePath(updater::kStorePathSwitch));
+  } else {
+    return updater::ReadTicketStore(
+        command_line->GetSwitchValuePath(updater::kStorePathSwitch));
+  }
+}
diff --git a/chromeos/ash/services/multidevice_setup/public/cpp/prefs.cc b/chromeos/ash/services/multidevice_setup/public/cpp/prefs.cc
index 6ba9ec3..fbdb5ae 100644
--- a/chromeos/ash/services/multidevice_setup/public/cpp/prefs.cc
+++ b/chromeos/ash/services/multidevice_setup/public/cpp/prefs.cc
@@ -19,7 +19,6 @@
 const char kInstantTetheringAllowedPrefName[] = "tether.allowed";
 const char kMessagesAllowedPrefName[] = "multidevice.sms_connect_allowed";
 const char kSmartLockAllowedPrefName[] = "easy_unlock.allowed";
-const char kSmartLockSigninAllowedPrefName[] = "smart_lock_signin.allowed";
 const char kPhoneHubAllowedPrefName[] = "phone_hub.allowed";
 const char kPhoneHubCameraRollAllowedPrefName[] =
     "phone_hub_camera_roll.allowed";
@@ -53,7 +52,6 @@
   registry->RegisterBooleanPref(kInstantTetheringAllowedPrefName, true);
   registry->RegisterBooleanPref(kMessagesAllowedPrefName, true);
   registry->RegisterBooleanPref(kSmartLockAllowedPrefName, true);
-  registry->RegisterBooleanPref(kSmartLockSigninAllowedPrefName, true);
   registry->RegisterBooleanPref(kPhoneHubAllowedPrefName, true);
   registry->RegisterBooleanPref(kPhoneHubCameraRollAllowedPrefName, true);
   registry->RegisterBooleanPref(kPhoneHubNotificationsAllowedPrefName, true);
diff --git a/chromeos/ash/services/multidevice_setup/public/cpp/prefs.h b/chromeos/ash/services/multidevice_setup/public/cpp/prefs.h
index 5bde211..a8de9d59 100644
--- a/chromeos/ash/services/multidevice_setup/public/cpp/prefs.h
+++ b/chromeos/ash/services/multidevice_setup/public/cpp/prefs.h
@@ -29,9 +29,6 @@
 extern const char kInstantTetheringAllowedPrefName[];
 extern const char kMessagesAllowedPrefName[];
 extern const char kSmartLockAllowedPrefName[];
-// TODO(b/227674947): Deprecate kSmartLockSigninAllowedPrefName and its
-// corresponding policy.
-extern const char kSmartLockSigninAllowedPrefName[];
 extern const char kPhoneHubAllowedPrefName[];
 extern const char kPhoneHubCameraRollAllowedPrefName[];
 extern const char kPhoneHubNotificationsAllowedPrefName[];
diff --git a/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc b/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc
index e8303e6..416c38b 100644
--- a/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc
+++ b/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc
@@ -757,10 +757,6 @@
     auto input = std::make_unique<apps::IconValue>();
     input->icon_type = apps::IconType::kUnknown;
 
-    std::vector<float> scales;
-    scales.push_back(1.0f);
-    gfx::ImageSkia::SetSupportedScales(scales);
-
     gfx::ImageSkia image = gfx::test::CreateImageSkia(1, 2);
     input->uncompressed = image;
 
@@ -782,10 +778,6 @@
     auto input = std::make_unique<apps::IconValue>();
     input->icon_type = apps::IconType::kUncompressed;
 
-    std::vector<float> scales;
-    scales.push_back(1.0f);
-    gfx::ImageSkia::SetSupportedScales(scales);
-
     gfx::ImageSkia image = gfx::test::CreateImageSkia(3, 4);
     input->uncompressed = image;
     input->is_placeholder_icon = false;
diff --git a/components/autofill/content/browser/form_forest_unittest.cc b/components/autofill/content/browser/form_forest_unittest.cc
index 2acd21b..c48b0a2 100644
--- a/components/autofill/content/browser/form_forest_unittest.cc
+++ b/components/autofill/content/browser/form_forest_unittest.cc
@@ -16,11 +16,17 @@
 #include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_feature_list.h"
+#include "components/autofill/content/browser/content_autofill_driver.h"
+#include "components/autofill/content/browser/content_autofill_driver_factory.h"
 #include "components/autofill/content/browser/form_forest.h"
 #include "components/autofill/content/browser/form_forest_test_api.h"
 #include "components/autofill/content/browser/form_forest_util_inl.h"
+#include "components/autofill/content/browser/test_autofill_client_injector.h"
+#include "components/autofill/content/browser/test_autofill_driver_injector.h"
+#include "components/autofill/content/browser/test_content_autofill_client.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/common/autofill_features.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/test/navigation_simulator.h"
 #include "content/public/test/test_renderer_host.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -271,8 +277,7 @@
 
 class MockContentAutofillDriver : public ContentAutofillDriver {
  public:
-  explicit MockContentAutofillDriver(content::RenderFrameHost* rfh)
-      : ContentAutofillDriver(rfh, /*autofill_router=*/nullptr) {}
+  using ContentAutofillDriver::ContentAutofillDriver;
 
   LocalFrameToken token() { return Token(render_frame_host()); }
 
@@ -325,10 +330,7 @@
     CHECK(kOpaqueOrigin.opaque());
   }
 
-  void TearDown() override {
-    autofill_drivers_.clear();
-    RenderViewHostTestHarness::TearDown();
-  }
+  void TearDown() override { RenderViewHostTestHarness::TearDown(); }
 
  protected:
   MockContentAutofillDriver* NavigateMainFrame(
@@ -347,7 +349,7 @@
         break;
     }
     simulator->Commit();
-    return GetOrCreateDriver(main_rfh());
+    return autofill_driver_injector_[main_rfh()];
   }
 
   // Creates a fresh child frame of |parent| with permissions |policy| and
@@ -373,7 +375,30 @@
         content::RenderFrameHostTester::For(parent->render_frame_host())
             ->AppendChildWithPolicy(static_cast<std::string>(name),
                                     declared_policy);
-    return NavigateFrame(rfh, url);
+    // ContentAutofillDriverFactory::DidFinishNavigation() creates a driver for
+    // subframes only if
+    // `NavigationHandle::HasSubframeNavigationEntryCommitted()` is true. This
+    // is not the case for the first navigation. (In non-unit-tests, the first
+    // navigation creates a driver in
+    // ContentAutofillDriverFactory::BindAutofillDriver().) Therefore,
+    // we simulate *two* navigations here, and explicitly set the transition
+    // type for the second navigation.
+    std::unique_ptr<content::NavigationSimulator> simulator;
+    // First navigation: `HasSubframeNavigationEntryCommitted() == false`.
+    // Must be a different URL from the second navigation.
+    GURL about_blank("about:blank");
+    CHECK_NE(about_blank, url);
+    simulator =
+        content::NavigationSimulator::CreateRendererInitiated(about_blank, rfh);
+    simulator->Commit();
+    rfh = simulator->GetFinalRenderFrameHost();
+    // Second navigation: `HasSubframeNavigationEntryCommitted() == true`.
+    // Must set the transition type to ui::PAGE_TRANSITION_MANUAL_SUBFRAME.
+    simulator = content::NavigationSimulator::CreateRendererInitiated(url, rfh);
+    simulator->SetTransition(ui::PAGE_TRANSITION_MANUAL_SUBFRAME);
+    simulator->Commit();
+    rfh = simulator->GetFinalRenderFrameHost();
+    return autofill_driver_injector_[rfh];
   }
 
  private:
@@ -398,27 +423,12 @@
         /*matches_opaque_src=*/false)};
   }
 
-  MockContentAutofillDriver* NavigateFrame(content::RenderFrameHost* rfh,
-                                           const GURL& url) {
-    rfh = content::NavigationSimulator::NavigateAndCommitFromDocument(url, rfh);
-    return GetOrCreateDriver(rfh);
-  }
-
-  MockContentAutofillDriver* GetOrCreateDriver(content::RenderFrameHost* rfh) {
-    auto it = autofill_drivers_.find(rfh);
-    if (it == autofill_drivers_.end()) {
-      it = autofill_drivers_
-               .emplace(rfh, std::make_unique<MockContentAutofillDriver>(rfh))
-               .first;
-    }
-    return it->second.get();
-  }
-
   base::test::ScopedFeatureList feature_list_;
   test::AutofillUnitTestEnvironment autofill_test_environment_;
-  std::map<content::RenderFrameHost*,
-           std::unique_ptr<MockContentAutofillDriver>>
-      autofill_drivers_;
+  TestAutofillClientInjector<TestContentAutofillClient>
+      autofill_client_injector_;
+  TestAutofillDriverInjector<MockContentAutofillDriver>
+      autofill_driver_injector_;
 };
 
 // Test fixture with a mocked frame/form tree.
diff --git a/components/cronet/android/fake/java/org/chromium/net/test/FakeUrlRequest.java b/components/cronet/android/fake/java/org/chromium/net/test/FakeUrlRequest.java
index 1482c6e..d4515a7 100644
--- a/components/cronet/android/fake/java/org/chromium/net/test/FakeUrlRequest.java
+++ b/components/cronet/android/fake/java/org/chromium/net/test/FakeUrlRequest.java
@@ -678,13 +678,10 @@
      */
     private void enterUploadErrorState(final Throwable error) {
         synchronized (mLock) {
-            mUserExecutor.execute(new Runnable() {
-                @Override
-                public void run() {
-                    tryToFailWithException(new CronetExceptionImpl(
-                            "Exception received from UploadDataProvider", error));
-                }
-            });
+            executeCheckedRunnable(
+                    ()
+                            -> tryToFailWithException(new CronetExceptionImpl(
+                                    "Exception received from UploadDataProvider", error)));
         }
     }
 
diff --git a/components/cronet/android/fake/javatests/org/chromium/net/test/FakeUrlRequestTest.java b/components/cronet/android/fake/javatests/org/chromium/net/test/FakeUrlRequestTest.java
index 5c4f75e..966d8616 100644
--- a/components/cronet/android/fake/javatests/org/chromium/net/test/FakeUrlRequestTest.java
+++ b/components/cronet/android/fake/javatests/org/chromium/net/test/FakeUrlRequestTest.java
@@ -22,7 +22,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.test.util.DisabledTest;
 import org.chromium.net.CronetEngine;
 import org.chromium.net.CronetException;
 import org.chromium.net.InlineExecutionProhibitedException;
@@ -476,7 +475,7 @@
 
         request.start();
         callback.waitForNextStep();
-        assertEquals(callback.mResponseStep, ResponseStep.ON_RECEIVED_REDIRECT);
+        assertEquals(ResponseStep.ON_RECEIVED_REDIRECT, callback.mResponseStep);
         checkStatus(request, Status.IDLE);
         callback.setAutoAdvance(true);
         request.followRedirect();
@@ -507,7 +506,7 @@
         request.start();
         callback.blockForDone();
 
-        assertEquals(callback.mResponseStep, ResponseStep.ON_SUCCEEDED);
+        assertEquals(ResponseStep.ON_SUCCEEDED, callback.mResponseStep);
         assertTrue(request.isDone());
     }
 
@@ -687,7 +686,7 @@
         request.start();
         callback.blockForDone();
 
-        assertEquals(callback.mResponseStep, ResponseStep.ON_FAILED);
+        assertEquals(ResponseStep.ON_FAILED, callback.mResponseStep);
         // Checks that the exception from {@link DirectPreventingExecutor} was successfully returned
         // to the callabck in the onFailed method.
         assertTrue(callback.mError.getCause() instanceof InlineExecutionProhibitedException);
@@ -808,7 +807,7 @@
             assertEquals("Invalid state transition - expected 4 but was 3", e.getMessage());
         }
         callback.waitForNextStep();
-        assertEquals(callback.mResponseStep, ResponseStep.ON_RECEIVED_REDIRECT);
+        assertEquals(ResponseStep.ON_RECEIVED_REDIRECT, callback.mResponseStep);
         callback.setAutoAdvance(true);
         request.followRedirect();
         callback.blockForDone();
@@ -1422,12 +1421,13 @@
     }
 
     /** This test uses a direct executor for callbacks, and non direct for upload */
-    @DisabledTest(message = "crbug/1412467")
     @Test
     @SmallTest
     public void testDirectExecutorProhibitedByDefault() throws Exception {
         TestUrlRequestCallback callback = new TestUrlRequestCallback();
-        Executor myExecutor = new Executor() {
+        // Everything submitted to this executor will be executed immediately on the thread
+        // that submitted the Runnable (blocking it until the runnable completes)
+        Executor directExecutor = new Executor() {
             @Override
             public void execute(Runnable command) {
                 command.run();
@@ -1436,7 +1436,7 @@
         String url = "url";
         FakeUrlRequest.Builder builder =
                 (FakeUrlRequest.Builder) mFakeCronetEngine.newUrlRequestBuilder(
-                        url, callback, myExecutor);
+                        url, callback, directExecutor);
         mFakeCronetController.addResponseMatcher(new EchoBodyResponseMatcher());
 
         TestUploadDataProvider dataProvider = new TestUploadDataProvider(
@@ -1448,10 +1448,8 @@
         builder.addHeader("Content-Type", "useless/string");
         builder.build().start();
         callback.blockForDone();
-
         assertEquals(1, dataProvider.getNumReadCalls());
         assertEquals(0, dataProvider.getNumRewindCalls());
-
         assertContains("Exception posting task to executor", callback.mError.getMessage());
         assertContains("Inline execution is prohibited for this request",
                 callback.mError.getCause().getMessage());
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
index a347c7a..5212a1e 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
@@ -685,6 +685,55 @@
 
     @Test
     @SmallTest
+    // TODO: the Java implementation currently fails this test - it incorrectly
+    // increments the count on the second start.
+    @OnlyRunNativeCronet
+    public void testGetActiveRequestCountOnDoubleStart() throws Exception {
+        CronetEngine cronetEngine = mTestRule.startCronetTestFramework().mCronetEngine;
+        TestUrlRequestCallback callback = new TestUrlRequestCallback();
+        callback.setAutoAdvance(false);
+        UrlRequest request =
+                cronetEngine.newUrlRequestBuilder(mUrl, callback, callback.getExecutor()).build();
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+        request.start();
+        assertEquals(1, cronetEngine.getActiveRequestCount());
+        boolean threwException = false;
+        try {
+            request.start();
+        } catch (Exception e) {
+            threwException = true;
+        }
+        assertTrue(threwException);
+        assertEquals(1, cronetEngine.getActiveRequestCount());
+        callback.setAutoAdvance(true);
+        callback.blockForDone();
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+    }
+
+    @Test
+    @SmallTest
+    // Only native Cronet has code paths that throw exceptions directly from start() on invalid
+    // requests.
+    @OnlyRunNativeCronet
+    public void testGetActiveRequestCountOnInvalidRequest() throws Exception {
+        CronetEngine cronetEngine = mTestRule.startCronetTestFramework().mCronetEngine;
+        TestUrlRequestCallback callback = new TestUrlRequestCallback();
+        UrlRequest request = cronetEngine.newUrlRequestBuilder("", callback, callback.getExecutor())
+                                     .setHttpMethod("")
+                                     .build();
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+        boolean threwException = false;
+        try {
+            request.start();
+        } catch (Exception e) {
+            threwException = true;
+        }
+        assertTrue(threwException);
+        assertEquals(0, cronetEngine.getActiveRequestCount());
+    }
+
+    @Test
+    @SmallTest
     public void testGetActiveRequestCountWithCancel() throws Exception {
         final CronetTestFramework testFramework = mTestRule.startCronetTestFramework();
         CronetEngine cronetEngine = testFramework.mCronetEngine;
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java
index 3bb925c4..2dc32de 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java
@@ -139,7 +139,6 @@
         cronetEngine.shutdown();
     }
 
-    @DisabledTest(message = "crbug.com/1021941")
     @Test
     @MediumTest
     @OnlyRunNativeCronet
@@ -161,7 +160,7 @@
         assertEquals(200, callback.mResponseInfo.getHttpStatusCode());
         assertEquals("GET", callback.mResponseAsString);
 
-        assertFileContainsString(file, "CLIENT_RANDOM");
+        assertFileContainsString(file, "CLIENT_HANDSHAKE_TRAFFIC_SECRET");
         assertTrue(file.delete());
         assertFalse(file.exists());
         cronetEngine.shutdown();
diff --git a/components/cronet/tools/generate_javadoc.py b/components/cronet/tools/generate_javadoc.py
index 3cf42635..6a00f330 100755
--- a/components/cronet/tools/generate_javadoc.py
+++ b/components/cronet/tools/generate_javadoc.py
@@ -28,9 +28,9 @@
 SDK_DIR = os.path.join(REPOSITORY_ROOT, 'third_party', 'android_sdk', 'public')
 # TODO(b/260694901) Remove this usage of Java 11 as soon as Doclava supports it.
 # Doclava support for JDK17 was actively being worked on as of Jan 2023.
-JAVADOC_PATH = os.path.join(build_utils.JAVA_11_HOME_DEPRECATED, 'bin',
-                            'javadoc')
-JAR_PATH = os.path.join(build_utils.JAVA_11_HOME_DEPRECATED, 'bin', 'jar')
+JAVA_11_HOME = os.path.join(REPOSITORY_ROOT, 'third_party', 'jdk11', 'current')
+JAVADOC_PATH = os.path.join(JAVA_11_HOME, 'bin', 'javadoc')
+JAR_PATH = os.path.join(JAVA_11_HOME, 'bin', 'jar')
 
 JAVADOC_WARNING = """\
 javadoc: warning - The old Doclet and Taglet APIs in the packages
diff --git a/components/embedder_support/user_agent_utils_unittest.cc b/components/embedder_support/user_agent_utils_unittest.cc
index a36d3ea..a845de07 100644
--- a/components/embedder_support/user_agent_utils_unittest.cc
+++ b/components/embedder_support/user_agent_utils_unittest.cc
@@ -220,10 +220,16 @@
   }
 
   if (!model.empty()) {
-    if (base::SysInfo::GetAndroidBuildCodename() == "REL")
-      ASSERT_EQ(base::SysInfo::HardwareModelName(), model);
-    else
+    if (base::SysInfo::GetAndroidBuildCodename() == "REL") {
+      // In UA reduction Phase 6, we change the deviceModel token to "K".
+      ASSERT_EQ(base::FeatureList::IsEnabled(
+                    blink::features::kReduceUserAgentAndroidVersionDeviceModel)
+                    ? "K"
+                    : base::SysInfo::HardwareModelName(),
+                model);
+    } else {
       ASSERT_EQ("", model);
+    }
   }
 #elif BUILDFLAG(IS_FUCHSIA)
   // X11; Fuchsia
diff --git a/components/exo/wayland/BUILD.gn b/components/exo/wayland/BUILD.gn
index 05299dc9..bb82103e 100644
--- a/components/exo/wayland/BUILD.gn
+++ b/components/exo/wayland/BUILD.gn
@@ -69,6 +69,8 @@
     "wl_subcompositor.h",
     "wp_presentation.cc",
     "wp_presentation.h",
+    "wp_single_pixel_buffer.cc",
+    "wp_single_pixel_buffer.h",
     "wp_viewporter.cc",
     "wp_viewporter.h",
     "xdg_shell.cc",
@@ -177,6 +179,7 @@
     "//third_party/wayland-protocols:relative_pointer_protocol",
     "//third_party/wayland-protocols:remote_shell_protocol",
     "//third_party/wayland-protocols:secure_output_protocol",
+    "//third_party/wayland-protocols:single_pixel_buffer",
     "//third_party/wayland-protocols:stylus_protocol",
     "//third_party/wayland-protocols:stylus_tools_protocol",
     "//third_party/wayland-protocols:text_input_extension_protocol",
@@ -404,6 +407,7 @@
     "//third_party/wayland-protocols:relative_pointer_protocol",
     "//third_party/wayland-protocols:remote_shell_protocol",
     "//third_party/wayland-protocols:secure_output_protocol",
+    "//third_party/wayland-protocols:single_pixel_buffer",
     "//third_party/wayland-protocols:stylus_protocol",
     "//third_party/wayland-protocols:stylus_tools_protocol",
     "//third_party/wayland-protocols:text_input_extension_protocol",
diff --git a/components/exo/wayland/clients/client_helper.cc b/components/exo/wayland/clients/client_helper.cc
index 1dffd0e..573dc98 100644
--- a/components/exo/wayland/clients/client_helper.cc
+++ b/components/exo/wayland/clients/client_helper.cc
@@ -10,6 +10,7 @@
 #include <linux-dmabuf-unstable-v1-client-protocol.h>
 #include <linux-explicit-synchronization-unstable-v1-client-protocol.h>
 #include <presentation-time-client-protocol.h>
+#include <single-pixel-buffer-v1-client-protocol.h>
 #include <wayland-client-core.h>
 #include <wayland-client-protocol.h>
 
@@ -82,6 +83,8 @@
 DEFAULT_DELETER(wl_data_device_manager, wl_data_device_manager_destroy)
 DEFAULT_DELETER(wp_content_type_manager_v1, wp_content_type_manager_v1_destroy)
 DEFAULT_DELETER(wp_content_type_v1, wp_content_type_v1_destroy)
+DEFAULT_DELETER(wp_single_pixel_buffer_manager_v1,
+                wp_single_pixel_buffer_manager_v1_destroy)
 DEFAULT_DELETER(wp_viewporter, wp_viewporter_destroy)
 DEFAULT_DELETER(zxdg_shell_v6, zxdg_shell_v6_destroy)
 DEFAULT_DELETER(xdg_wm_base, xdg_wm_base_destroy)
diff --git a/components/exo/wayland/clients/client_helper.h b/components/exo/wayland/clients/client_helper.h
index c8c719f..92c2279 100644
--- a/components/exo/wayland/clients/client_helper.h
+++ b/components/exo/wayland/clients/client_helper.h
@@ -29,6 +29,7 @@
 #include <remote-shell-unstable-v1-client-protocol.h>
 #include <remote-shell-unstable-v2-client-protocol.h>
 #include <secure-output-unstable-v1-client-protocol.h>
+#include <single-pixel-buffer-v1-client-protocol.h>
 #include <stylus-tools-unstable-v1-client-protocol.h>
 #include <stylus-unstable-v2-client-protocol.h>
 #include <surface-augmenter-client-protocol.h>
@@ -100,6 +101,7 @@
 DEFAULT_DELETER_FDECL(zwp_linux_dmabuf_v1)
 DEFAULT_DELETER_FDECL(zwp_linux_explicit_synchronization_v1)
 DEFAULT_DELETER_FDECL(zwp_linux_surface_synchronization_v1)
+DEFAULT_DELETER_FDECL(wp_single_pixel_buffer_manager_v1)
 DEFAULT_DELETER_FDECL(zcr_vsync_feedback_v1)
 DEFAULT_DELETER_FDECL(zcr_vsync_timing_v1)
 DEFAULT_DELETER_FDECL(wl_data_device_manager)
diff --git a/components/exo/wayland/clients/globals.cc b/components/exo/wayland/clients/globals.cc
index a26ed207..98bfed9 100644
--- a/components/exo/wayland/clients/globals.cc
+++ b/components/exo/wayland/clients/globals.cc
@@ -71,6 +71,8 @@
   BIND(zcr_remote_shell_v1, cr_remote_shell_v1)
   BIND(zcr_remote_shell_v2, cr_remote_shell_v2)
   BIND(surface_augmenter, surface_augmenter)
+  BIND(wp_single_pixel_buffer_manager_v1, wp_single_pixel_buffer_manager_v1)
+  BIND(wp_viewporter, wp_viewporter)
 
 #undef BIND
 #undef BIND_VECTOR
diff --git a/components/exo/wayland/clients/globals.h b/components/exo/wayland/clients/globals.h
index aa9c91bf..d395d1d1 100644
--- a/components/exo/wayland/clients/globals.h
+++ b/components/exo/wayland/clients/globals.h
@@ -73,6 +73,8 @@
   Object<zcr_remote_shell_v1> cr_remote_shell_v1;
   Object<zcr_remote_shell_v2> cr_remote_shell_v2;
   Object<surface_augmenter> surface_augmenter;
+  Object<wp_single_pixel_buffer_manager_v1> wp_single_pixel_buffer_manager_v1;
+  Object<wp_viewporter> wp_viewporter;
 
   base::flat_map<std::string, uint32_t> requested_versions;
 };
diff --git a/components/exo/wayland/clients/perftests.cc b/components/exo/wayland/clients/perftests.cc
index d4ca122..d4e3ba08 100644
--- a/components/exo/wayland/clients/perftests.cc
+++ b/components/exo/wayland/clients/perftests.cc
@@ -55,11 +55,13 @@
   exo::wayland::clients::Simple client;
   EXPECT_TRUE(client.Init(params));
 
-  client.Run(kWarmUpFrames, false, nullptr);
+  const exo::wayland::clients::Simple::RunParam run_params = {false, false};
+
+  client.Run(kWarmUpFrames, run_params, nullptr);
 
   exo::wayland::clients::Simple::PresentationFeedback feedback;
   auto start_time = base::Time::Now();
-  client.Run(kTestFrames, false, &feedback);
+  client.Run(kTestFrames, run_params, &feedback);
   auto time_delta = base::Time::Now() - start_time;
   float fps = kTestFrames / time_delta.InSecondsF();
   auto reporter = SetUpReporter(kStorySimple);
diff --git a/components/exo/wayland/clients/simple.cc b/components/exo/wayland/clients/simple.cc
index 40131d8..3261e66 100644
--- a/components/exo/wayland/clients/simple.cc
+++ b/components/exo/wayland/clients/simple.cc
@@ -5,7 +5,10 @@
 #include "components/exo/wayland/clients/simple.h"
 
 #include <presentation-time-client-protocol.h>
+#include <single-pixel-buffer-v1-client-protocol.h>
 
+#include <climits>
+#include <cstdint>
 #include <iostream>
 
 #include "base/command_line.h"
@@ -95,7 +98,7 @@
 Simple::Simple() = default;
 
 void Simple::Run(int frames,
-                 const bool log_vsync_timing_updates,
+                 const RunParam& run_param,
                  PresentationFeedback* feedback) {
   wl_display_roundtrip(display_.get());
   // We always send this bug fix ID as a sanity check.
@@ -106,7 +109,7 @@
       FeedbackSyncOutput, FeedbackPresented, FeedbackDiscarded};
 
   std::unique_ptr<zcr_vsync_timing_v1> vsync_timing;
-  if (log_vsync_timing_updates) {
+  if (run_param.log_vsync_timing_updates) {
     if (globals_.vsync_feedback) {
       vsync_timing.reset(zcr_vsync_feedback_v1_get_vsync_timing(
           globals_.vsync_feedback.get(), globals_.outputs.back().get()));
@@ -127,6 +130,8 @@
 
   std::unique_ptr<wl_callback> frame_callback;
   bool frame_callback_pending = false;
+  wp_viewport* viewport =
+      wp_viewporter_get_viewport(globals_.wp_viewporter.get(), surface_.get());
   do {
     if (frame_callback_pending)
       continue;
@@ -134,14 +139,35 @@
     if (frame_count == frames)
       break;
 
-    Buffer* buffer = DequeueBuffer();
-    if (!buffer)
-      continue;
-
-    SkCanvas* canvas = buffer->sk_surface->getCanvas();
-
+    wl_buffer* buffer;
     static const SkColor kColors[] = {SK_ColorRED, SK_ColorBLACK};
-    canvas->clear(kColors[++frame_count % std::size(kColors)]);
+    SkColor color = kColors[++frame_count % std::size(kColors)];
+    if (run_param.single_pixel_buffer) {
+      SkColor4f precise_color = SkColor4f::FromColor(color);
+      // Single Pixel Buffer protocol uses premultiplied color.
+      uint32_t red =
+          UINT_MAX * (double)precise_color.fR * (double)precise_color.fA;
+      uint32_t green =
+          UINT_MAX * (double)precise_color.fG * (double)precise_color.fA;
+      uint32_t blue =
+          UINT_MAX * (double)precise_color.fB * (double)precise_color.fA;
+      uint32_t alpha = UINT_MAX * (double)precise_color.fA;
+      buffer = wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer(
+          globals_.wp_single_pixel_buffer_manager_v1.get(), red, green, blue,
+          alpha);
+      wp_viewport_set_destination(viewport, surface_size_.width(),
+                                  surface_size_.height());
+    } else {
+      Buffer* dequeued_buffer = DequeueBuffer();
+      if (!dequeued_buffer) {
+        continue;
+      }
+
+      SkCanvas* canvas = dequeued_buffer->sk_surface->getCanvas();
+
+      canvas->clear(color);
+      buffer = dequeued_buffer->buffer.get();
+    }
 
     if (gr_context_) {
       gr_context_->flushAndSubmit();
@@ -152,7 +178,8 @@
     wl_surface_set_buffer_transform(surface_.get(), transform_);
     wl_surface_damage(surface_.get(), 0, 0, surface_size_.width(),
                       surface_size_.height());
-    wl_surface_attach(surface_.get(), buffer->buffer.get(), 0, 0);
+
+    wl_surface_attach(surface_.get(), buffer, 0, 0);
 
     // Set up the frame callback.
     frame_callback_pending = true;
diff --git a/components/exo/wayland/clients/simple.h b/components/exo/wayland/clients/simple.h
index 22e79b7..e344914f 100644
--- a/components/exo/wayland/clients/simple.h
+++ b/components/exo/wayland/clients/simple.h
@@ -26,9 +26,16 @@
     // Number of presented frames.
     uint32_t num_frames_presented = 0;
   };
+  struct RunParam {
+    // Whether the client should log vsync.
+    bool log_vsync_timing_updates = false;
+
+    // Whether the client should use single pixel buffer.
+    bool single_pixel_buffer = false;
+  };
 
   void Run(int frames,
-           const bool log_vsync_timing_updates = false,
+           const RunParam& run_param,
            PresentationFeedback* feedback = nullptr);
 };
 
diff --git a/components/exo/wayland/clients/simple_main.cc b/components/exo/wayland/clients/simple_main.cc
index 9a8d86e..44c0c48 100644
--- a/components/exo/wayland/clients/simple_main.cc
+++ b/components/exo/wayland/clients/simple_main.cc
@@ -14,6 +14,8 @@
 namespace switches {
 // Specifies if VSync timing updates should be logged on the output.
 const char kLogVSyncTimingUpdates[] = "log-vsync-timing-updates";
+
+const char kSinglePixelBuffer[] = "single-pixel-buffer";
 }  // namespace switches
 
 int main(int argc, char* argv[]) {
@@ -29,10 +31,11 @@
   if (!client.Init(params))
     return 1;
 
-  bool log_vsync_timing_updates =
-      command_line->HasSwitch(switches::kLogVSyncTimingUpdates);
+  const exo::wayland::clients::Simple::RunParam run_params = {
+      command_line->HasSwitch(switches::kLogVSyncTimingUpdates),
+      command_line->HasSwitch(switches::kSinglePixelBuffer)};
 
-  client.Run(std::numeric_limits<int>::max(), log_vsync_timing_updates);
+  client.Run(std::numeric_limits<int>::max(), run_params);
 
   return 0;
 }
diff --git a/components/exo/wayland/clients/test/client_version_test.cc b/components/exo/wayland/clients/test/client_version_test.cc
index e8c3f52..ae70c1a7 100644
--- a/components/exo/wayland/clients/test/client_version_test.cc
+++ b/components/exo/wayland/clients/test/client_version_test.cc
@@ -109,6 +109,8 @@
   std::unique_ptr<zxdg_output_manager_v1> zxdg_output_manager_v1;
   std::unique_ptr<weston_test> weston_test;
   std::unique_ptr<zwp_idle_inhibit_manager_v1> zwp_idle_inhibit_manager_v1;
+  std::unique_ptr<wp_single_pixel_buffer_manager_v1>
+      wp_single_pixel_buffer_manager_v1;
 };
 
 typedef void (*InterfaceRegistryCallback)(Globals*,
@@ -175,6 +177,8 @@
           REGISTRY_CALLBACK(wl_data_device_manager, wl_data_device_manager),
           REGISTRY_CALLBACK(wp_content_type_manager_v1,
                             wp_content_type_manager_v1),
+          REGISTRY_CALLBACK(wp_single_pixel_buffer_manager_v1,
+                            wp_single_pixel_buffer_manager_v1),
           REGISTRY_CALLBACK(wp_viewporter, wp_viewporter),
           REGISTRY_CALLBACK(zxdg_shell_v6, zxdg_shell_v6),
           REGISTRY_CALLBACK(xdg_wm_base, xdg_wm_base),
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc
index e382e79..cf2e99d3 100644
--- a/components/exo/wayland/server.cc
+++ b/components/exo/wayland/server.cc
@@ -27,6 +27,7 @@
 #include <remote-shell-unstable-v1-server-protocol.h>
 #include <remote-shell-unstable-v2-server-protocol.h>
 #include <secure-output-unstable-v1-server-protocol.h>
+#include <single-pixel-buffer-v1-server-protocol.h>
 #include <stylus-tools-unstable-v1-server-protocol.h>
 #include <stylus-unstable-v2-server-protocol.h>
 #include <surface-augmenter-server-protocol.h>
@@ -76,6 +77,7 @@
 #include "components/exo/wayland/wl_shm.h"
 #include "components/exo/wayland/wl_subcompositor.h"
 #include "components/exo/wayland/wp_presentation.h"
+#include "components/exo/wayland/wp_single_pixel_buffer.h"
 #include "components/exo/wayland/wp_viewporter.h"
 #include "components/exo/wayland/xdg_shell.h"
 #include "components/exo/wayland/zaura_output_manager.h"
@@ -282,6 +284,9 @@
 
   wl_global_create(wl_display_.get(), &surface_augmenter_interface,
                    kSurfaceAugmenterVersion, display_, bind_surface_augmenter);
+  wl_global_create(
+      wl_display_.get(), &wp_single_pixel_buffer_manager_v1_interface,
+      kSinglePixelBufferVersion, display_, bind_single_pixel_buffer);
   wl_global_create(wl_display_.get(), &overlay_prioritizer_interface, 1,
                    display_, bind_overlay_prioritizer);
   wl_global_create(wl_display_.get(), &wp_viewporter_interface, 1, display_,
diff --git a/components/exo/wayland/wp_single_pixel_buffer.cc b/components/exo/wayland/wp_single_pixel_buffer.cc
new file mode 100644
index 0000000..ac8e241
--- /dev/null
+++ b/components/exo/wayland/wp_single_pixel_buffer.cc
@@ -0,0 +1,92 @@
+// Copyright 2021 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/wayland/wp_single_pixel_buffer.h"
+
+#include <single-pixel-buffer-v1-server-protocol.h>
+
+#include <cstdint>
+#include <memory>
+
+#include "components/exo/buffer.h"
+#include "components/exo/sub_surface.h"
+#include "components/exo/sub_surface_observer.h"
+#include "components/exo/surface.h"
+#include "components/exo/surface_observer.h"
+#include "components/exo/wayland/server_util.h"
+#include "ui/gfx/geometry/rounded_corners_f.h"
+#include "ui/gfx/geometry/rrect_f.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace exo::wayland {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+// wl_buffer_interface:
+
+void buffer_destroy(wl_client* client, wl_resource* resource) {
+  wl_resource_destroy(resource);
+}
+
+const struct wl_buffer_interface buffer_implementation = {buffer_destroy};
+
+////////////////////////////////////////////////////////////////////////////////
+// single_pixel_buffer_interface:
+
+void single_pixel_buffer_destroy_manager(wl_client* client,
+                                         wl_resource* resource) {
+  wl_resource_destroy(resource);
+}
+
+void HandleBufferReleaseCallback(wl_resource* resource) {
+  wl_buffer_send_release(resource);
+  wl_client_flush(wl_resource_get_client(resource));
+}
+
+void create_u32_rgba_buffer(wl_client* client,
+                            wl_resource* resource,
+                            uint32_t id,
+                            uint32_t r,
+                            uint32_t g,
+                            uint32_t b,
+                            uint32_t a) {
+  double dividor = UINT32_MAX;
+  // TODO: consider moving SolidColorBuffer to use premultiplied instead.
+  float alpha = static_cast<float>(a / dividor);
+  if (alpha != 0) {
+    dividor /= alpha;
+  }
+  SkColor4f color = {static_cast<float>(r / dividor),
+                     static_cast<float>(g / dividor),
+                     static_cast<float>(b / dividor), alpha};
+  std::unique_ptr<SolidColorBuffer> buffer =
+      std::make_unique<SolidColorBuffer>(color, gfx::Size(1, 1));
+  wl_resource* buffer_resource = wl_resource_create(
+      client, &wl_buffer_interface, wl_resource_get_version(resource), id);
+
+  buffer->set_release_callback(base::BindRepeating(
+      &HandleBufferReleaseCallback, base::Unretained(buffer_resource)));
+
+  SetImplementation(buffer_resource, &buffer_implementation, std::move(buffer));
+}
+
+const struct wp_single_pixel_buffer_manager_v1_interface
+    single_pixel_buffer_implementation = {single_pixel_buffer_destroy_manager,
+                                          create_u32_rgba_buffer};
+
+}  // namespace
+
+void bind_single_pixel_buffer(wl_client* client,
+                              void* data,
+                              uint32_t version,
+                              uint32_t id) {
+  wl_resource* resource =
+      wl_resource_create(client, &wp_single_pixel_buffer_manager_v1_interface,
+                         std::min(version, kSinglePixelBufferVersion), id);
+
+  wl_resource_set_implementation(resource, &single_pixel_buffer_implementation,
+                                 data, nullptr);
+}
+
+}  // namespace exo::wayland
diff --git a/components/exo/wayland/wp_single_pixel_buffer.h b/components/exo/wayland/wp_single_pixel_buffer.h
new file mode 100644
index 0000000..ef7c0c3d
--- /dev/null
+++ b/components/exo/wayland/wp_single_pixel_buffer.h
@@ -0,0 +1,23 @@
+// Copyright 2021 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_EXO_WAYLAND_WP_SINGLE_PIXEL_BUFFER_H_
+#define COMPONENTS_EXO_WAYLAND_WP_SINGLE_PIXEL_BUFFER_H_
+
+#include <stdint.h>
+
+struct wl_client;
+
+namespace exo::wayland {
+
+constexpr uint32_t kSinglePixelBufferVersion = 1;
+
+void bind_single_pixel_buffer(wl_client* client,
+                              void* data,
+                              uint32_t version,
+                              uint32_t id);
+
+}  // namespace exo::wayland
+
+#endif  // COMPONENTS_EXO_WAYLAND_WP_SINGLE_PIXEL_BUFFER_H_
diff --git a/components/feature_engagement/internal/tracker_impl.cc b/components/feature_engagement/internal/tracker_impl.cc
index 05091e6..137e84a 100644
--- a/components/feature_engagement/internal/tracker_impl.cc
+++ b/components/feature_engagement/internal/tracker_impl.cc
@@ -370,6 +370,10 @@
   priority_notification_handlers_.erase(feature.name);
 }
 
+const Configuration* TrackerImpl::GetConfigurationForTesting() const {
+  return configuration_.get();
+}
+
 bool TrackerImpl::IsInitialized() const {
   return event_model_->IsReady() && availability_model_->IsReady();
 }
diff --git a/components/feature_engagement/internal/tracker_impl.h b/components/feature_engagement/internal/tracker_impl.h
index f9fdee05..ed756333 100644
--- a/components/feature_engagement/internal/tracker_impl.h
+++ b/components/feature_engagement/internal/tracker_impl.h
@@ -67,6 +67,7 @@
                                            base::OnceClosure callback) override;
   void UnregisterPriorityNotificationHandler(
       const base::Feature& feature) override;
+  const Configuration* GetConfigurationForTesting() const override;
 
  private:
   friend test::ScopedIphFeatureList;
diff --git a/components/feature_engagement/public/android/wrapping_test_tracker.cc b/components/feature_engagement/public/android/wrapping_test_tracker.cc
index 78416231..34121a8 100644
--- a/components/feature_engagement/public/android/wrapping_test_tracker.cc
+++ b/components/feature_engagement/public/android/wrapping_test_tracker.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/android/jni_string.h"
+#include "base/notreached.h"
 #include "base/task/single_thread_task_runner.h"
 #include "components/feature_engagement/public/jni_headers/CppWrappedTestTracker_jni.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -118,4 +119,9 @@
       FROM_HERE, base::BindOnce(std::move(callback), IsInitialized()));
 }
 
+const Configuration* WrappingTestTracker::GetConfigurationForTesting() const {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
 }  // namespace feature_engagement
diff --git a/components/feature_engagement/public/android/wrapping_test_tracker.h b/components/feature_engagement/public/android/wrapping_test_tracker.h
index eca6ad1..6404a2e 100644
--- a/components/feature_engagement/public/android/wrapping_test_tracker.h
+++ b/components/feature_engagement/public/android/wrapping_test_tracker.h
@@ -46,6 +46,7 @@
       const base::Feature& feature) override;
   bool IsInitialized() const override;
   void AddOnInitializedCallback(OnInitializedCallback callback) override;
+  const Configuration* GetConfigurationForTesting() const override;
 
  private:
   base::android::ScopedJavaGlobalRef<jobject> java_tracker_;
diff --git a/components/feature_engagement/public/feature_configurations.cc b/components/feature_engagement/public/feature_configurations.cc
index 6c8b694..ae141f3 100644
--- a/components/feature_engagement/public/feature_configurations.cc
+++ b/components/feature_engagement/public/feature_configurations.cc
@@ -238,6 +238,20 @@
     return config;
   }
 
+  if (kIPHCompanionSidePanelFeature.name == feature->name) {
+    absl::optional<FeatureConfig> config = FeatureConfig();
+    config->valid = true;
+    config->availability = Comparator(ANY, 0);
+    config->session_rate = Comparator(EQUAL, 0);
+    // Show the promo up to 3 times a year.
+    config->trigger = EventConfig("iph_companion_side_panel_trigger",
+                                  Comparator(LESS_THAN, 3), 360, 360);
+    config->used =
+        EventConfig("companion_side_panel_accessed_via_toolbar_button",
+                    Comparator(EQUAL, 0), 360, 360);
+    return config;
+  }
+
   if (kIPHDesktopCustomizeChromeFeature.name == feature->name) {
     absl::optional<FeatureConfig> config = FeatureConfig();
     config->valid = true;
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc
index 14eebbe..9fc2ce6 100644
--- a/components/feature_engagement/public/feature_constants.cc
+++ b/components/feature_engagement/public/feature_constants.cc
@@ -27,6 +27,9 @@
 BASE_FEATURE(kIPHBatterySaverModeFeature,
              "IPH_BatterySaverMode",
              base::FEATURE_ENABLED_BY_DEFAULT);
+BASE_FEATURE(kIPHCompanionSidePanelFeature,
+             "IPH_CompanionSidePanel",
+             base::FEATURE_DISABLED_BY_DEFAULT);
 BASE_FEATURE(kIPHDesktopSharedHighlightingFeature,
              "IPH_DesktopSharedHighlighting",
              base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h
index 4e00a93..8e0ac25e 100644
--- a/components/feature_engagement/public/feature_constants.h
+++ b/components/feature_engagement/public/feature_constants.h
@@ -25,6 +25,7 @@
     BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA)
 BASE_DECLARE_FEATURE(kIPHAutofillFeedbackNewBadgeFeature);
 BASE_DECLARE_FEATURE(kIPHBatterySaverModeFeature);
+BASE_DECLARE_FEATURE(kIPHCompanionSidePanelFeature);
 BASE_DECLARE_FEATURE(kIPHDesktopSharedHighlightingFeature);
 BASE_DECLARE_FEATURE(kIPHDesktopTabGroupsNewGroupFeature);
 BASE_DECLARE_FEATURE(kIPHDesktopCustomizeChromeFeature);
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc
index 818814e..7ee2198 100644
--- a/components/feature_engagement/public/feature_list.cc
+++ b/components/feature_engagement/public/feature_list.cc
@@ -141,6 +141,7 @@
     BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA)
     &kIPHAutofillFeedbackNewBadgeFeature,
     &kIPHBatterySaverModeFeature,
+    &kIPHCompanionSidePanelFeature,
     &kIPHDesktopTabGroupsNewGroupFeature,
     &kIPHDesktopCustomizeChromeFeature,
     &kIPHDownloadToolbarButtonFeature,
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h
index bd9531e..9a65e60 100644
--- a/components/feature_engagement/public/feature_list.h
+++ b/components/feature_engagement/public/feature_list.h
@@ -258,6 +258,7 @@
 DEFINE_VARIATION_PARAM(kIPHAutofillFeedbackNewBadgeFeature,
                        "IPH_AutofillFeedbackNewBadge");
 DEFINE_VARIATION_PARAM(kIPHBatterySaverModeFeature, "IPH_BatterySaverMode");
+DEFINE_VARIATION_PARAM(kIPHCompanionSidePanelFeature, "IPH_CompanionSidePanel");
 DEFINE_VARIATION_PARAM(kIPHDesktopCustomizeChromeFeature,
                        "IPH_DesktopCustomizeChrome");
 DEFINE_VARIATION_PARAM(kIPHDesktopTabGroupsNewGroupFeature,
@@ -452,6 +453,7 @@
     BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA)
         VARIATION_ENTRY(kIPHAutofillFeedbackNewBadgeFeature),
         VARIATION_ENTRY(kIPHBatterySaverModeFeature),
+        VARIATION_ENTRY(kIPHCompanionSidePanelFeature),
         VARIATION_ENTRY(kIPHDesktopCustomizeChromeFeature),
         VARIATION_ENTRY(kIPHDesktopTabGroupsNewGroupFeature),
         VARIATION_ENTRY(kIPHDownloadToolbarButtonFeature),
diff --git a/components/feature_engagement/public/tracker.h b/components/feature_engagement/public/tracker.h
index 6abb0be..03e1ccd 100644
--- a/components/feature_engagement/public/tracker.h
+++ b/components/feature_engagement/public/tracker.h
@@ -28,6 +28,8 @@
 
 namespace feature_engagement {
 
+class Configuration;
+
 // A handle for the display lock. While this is unreleased, no in-product help
 // can be displayed.
 class DisplayLockHandle {
@@ -257,6 +259,9 @@
   // invoked exactly one time.
   virtual void AddOnInitializedCallback(OnInitializedCallback callback) = 0;
 
+  // Returns the configuration associated with the tracker for testing purposes.
+  virtual const Configuration* GetConfigurationForTesting() const = 0;
+
  protected:
   Tracker() = default;
 };
diff --git a/components/feature_engagement/test/mock_tracker.h b/components/feature_engagement/test/mock_tracker.h
index c4f38245..b336155a 100644
--- a/components/feature_engagement/test/mock_tracker.h
+++ b/components/feature_engagement/test/mock_tracker.h
@@ -47,6 +47,7 @@
   MOCK_METHOD1(UnregisterPriorityNotificationHandler,
                void(const base::Feature&));
   MOCK_METHOD1(AddOnInitializedCallback, void(OnInitializedCallback callback));
+  MOCK_CONST_METHOD0(GetConfigurationForTesting, const Configuration*());
 };
 
 }  // namespace test
diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc
index 2b8a27b7..5c6c056f 100644
--- a/components/omnibox/browser/autocomplete_controller.cc
+++ b/components/omnibox/browser/autocomplete_controller.cc
@@ -1128,6 +1128,7 @@
                                  provider_client_->GetPrefs(), result_);
 #endif
   }
+  result_.TrimOmniboxActions();
 }
 
 void AutocompleteController::UpdateAssociatedKeywords(
diff --git a/components/omnibox/browser/autocomplete_result.cc b/components/omnibox/browser/autocomplete_result.cc
index 65bcc57..8f8cd5f 100644
--- a/components/omnibox/browser/autocomplete_result.cc
+++ b/components/omnibox/browser/autocomplete_result.cc
@@ -530,8 +530,6 @@
         << debug_info;
   }
 #endif
-
-  TrimOmniboxActions();
 }
 
 void AutocompleteResult::TrimOmniboxActions() {
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/SmartLockSigninAllowed.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/SmartLockSigninAllowed.yaml
index e1d9d33d..1d428964 100644
--- a/components/policy/resources/templates/policy_definitions/Miscellaneous/SmartLockSigninAllowed.yaml
+++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/SmartLockSigninAllowed.yaml
@@ -21,7 +21,8 @@
 schema:
   type: boolean
 supported_on:
-- chrome_os:71-
+- chrome_os:71-103
+deprecated: true
 tags:
 - local-data-access
 - google-sharing
diff --git a/components/policy/test/data/policy_test_cases.json b/components/policy/test/data/policy_test_cases.json
index 6db74d6f..93ebbc8 100644
--- a/components/policy/test/data/policy_test_cases.json
+++ b/components/policy/test/data/policy_test_cases.json
@@ -12132,39 +12132,7 @@
     ]
   },
   "SmartLockSigninAllowed": {
-    "os": [
-      "chromeos_ash"
-    ],
-    "policy_pref_mapping_tests": [
-      {
-        "policies": {},
-        "prefs": {
-          "smart_lock_signin.allowed": {
-            "value": false
-          }
-        }
-      },
-      {
-        "policies": {
-          "SmartLockSigninAllowed": false
-        },
-        "prefs": {
-          "smart_lock_signin.allowed": {
-            "value": false
-          }
-        }
-      },
-      {
-        "policies": {
-          "SmartLockSigninAllowed": true
-        },
-        "prefs": {
-          "smart_lock_signin.allowed": {
-            "value": true
-          }
-        }
-      }
-    ]
+    "reason_for_missing_test": "Policy was removed"
   },
   "InstantTetheringAllowed": {
     "os": [
diff --git a/components/services/screen_ai/screen_ai_service_impl.cc b/components/services/screen_ai/screen_ai_service_impl.cc
index c363862..fbb0bf7 100644
--- a/components/services/screen_ai/screen_ai_service_impl.cc
+++ b/components/services/screen_ai/screen_ai_service_impl.cc
@@ -269,9 +269,14 @@
   RecordMetrics(ukm_source_id, ukm::UkmRecorder::Get(), elapsed_time,
                 /* success= */ content_node_ids.has_value());
 
-  VLOG(2) << "Screen2x returned " << content_node_ids->size() << " node ids.";
+  if (content_node_ids.has_value()) {
+    VLOG(2) << "Screen2x returned " << content_node_ids->size() << " node ids.";
+    std::move(callback).Run(*content_node_ids);
+    return;
+  }
 
-  std::move(callback).Run(*content_node_ids);
+  VLOG(0) << "Screen2x returned no results.";
+  std::move(callback).Run(std::vector<int32_t>());
 }
 
 // static
diff --git a/components/user_education/common/feature_promo_registry.h b/components/user_education/common/feature_promo_registry.h
index f81f531..e6940e85 100644
--- a/components/user_education/common/feature_promo_registry.h
+++ b/components/user_education/common/feature_promo_registry.h
@@ -41,7 +41,7 @@
   void RegisterFeature(FeaturePromoSpecification spec);
 
   const std::map<const base::Feature*, FeaturePromoSpecification>&
-  GetRegisteredFeaturePromoSpecifications() {
+  GetRegisteredFeaturePromoSpecifications() const {
     return feature_promo_data_;
   }
 
diff --git a/components/user_education/common/help_bubble_params.cc b/components/user_education/common/help_bubble_params.cc
index b3c226a8..07556e6 100644
--- a/components/user_education/common/help_bubble_params.cc
+++ b/components/user_education/common/help_bubble_params.cc
@@ -13,6 +13,41 @@
 HelpBubbleButtonParams& HelpBubbleButtonParams::operator=(
     HelpBubbleButtonParams&&) = default;
 
+HelpBubbleParams::ExtendedProperties::ExtendedProperties() = default;
+
+HelpBubbleParams::ExtendedProperties::ExtendedProperties(
+    const ExtendedProperties& other)
+    : dict_(other.dict_.Clone()) {}
+
+HelpBubbleParams::ExtendedProperties::ExtendedProperties(
+    ExtendedProperties&& other)
+    : dict_(std::move(other.dict_)) {}
+
+HelpBubbleParams::ExtendedProperties&
+HelpBubbleParams::ExtendedProperties::operator=(
+    const ExtendedProperties& other) {
+  dict_ = other.dict_.Clone();
+  return *this;
+}
+
+HelpBubbleParams::ExtendedProperties&
+HelpBubbleParams::ExtendedProperties::operator=(ExtendedProperties&& other) {
+  dict_ = std::move(other.dict_);
+  return *this;
+}
+
+HelpBubbleParams::ExtendedProperties::~ExtendedProperties() = default;
+
+bool HelpBubbleParams::ExtendedProperties::operator==(
+    const ExtendedProperties& other) const {
+  return dict_ == other.dict_;
+}
+
+bool HelpBubbleParams::ExtendedProperties::operator!=(
+    const ExtendedProperties& other) const {
+  return dict_ != other.dict_;
+}
+
 HelpBubbleParams::HelpBubbleParams() = default;
 HelpBubbleParams::HelpBubbleParams(HelpBubbleParams&&) = default;
 HelpBubbleParams::~HelpBubbleParams() = default;
diff --git a/components/user_education/common/help_bubble_params.h b/components/user_education/common/help_bubble_params.h
index 7d7e7f16..5b1445c 100644
--- a/components/user_education/common/help_bubble_params.h
+++ b/components/user_education/common/help_bubble_params.h
@@ -12,6 +12,7 @@
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/time/time.h"
+#include "base/values.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/interaction/element_tracker.h"
 #include "ui/gfx/vector_icon_types.h"
@@ -53,6 +54,28 @@
 };
 
 struct HelpBubbleParams {
+  // Platform-specific properties that can be set for a help bubble. If an
+  // extended property evolves to warrant cross-platform support, it should be
+  // promoted out of extended properties.
+  class ExtendedProperties {
+   public:
+    ExtendedProperties();
+    ExtendedProperties(const ExtendedProperties&);
+    ExtendedProperties(ExtendedProperties&&);
+    ExtendedProperties& operator=(const ExtendedProperties&);
+    ExtendedProperties& operator=(ExtendedProperties&&);
+    ~ExtendedProperties();
+
+    bool operator==(const ExtendedProperties&) const;
+    bool operator!=(const ExtendedProperties&) const;
+
+    base::Value::Dict& values() { return dict_; }
+    const base::Value::Dict& values() const { return dict_; }
+
+   private:
+    base::Value::Dict dict_;
+  };
+
   HelpBubbleParams();
   HelpBubbleParams(HelpBubbleParams&&);
   ~HelpBubbleParams();
@@ -93,6 +116,11 @@
 
   // Called when the bubble times out.
   base::OnceClosure timeout_callback = base::DoNothing();
+
+  // Platform-specific properties that can be set for a help bubble. If an
+  // extended property evolves to warrant cross-platform support, it should be
+  // promoted out of extended properties.
+  ExtendedProperties extended_properties;
 };
 
 }  // namespace user_education
diff --git a/components/user_education/common/tutorial.cc b/components/user_education/common/tutorial.cc
index 3880e8e0..0389031d 100644
--- a/components/user_education/common/tutorial.cc
+++ b/components/user_education/common/tutorial.cc
@@ -210,12 +210,14 @@
          absl::optional<std::pair<int, int>> progress_, bool is_last_step_,
          bool can_be_restarted_,
          TutorialDescription::NextButtonCallback next_button_callback,
+         HelpBubbleParams::ExtendedProperties extended_properties,
          ui::InteractionSequence* sequence, ui::TrackedElement* element) {
         DCHECK(tutorial_service);
 
         tutorial_service->HideCurrentBubbleIfShowing();
 
         HelpBubbleParams params;
+        params.extended_properties = std::move(extended_properties);
         params.title_text = title_text_;
         params.body_text = body_text_;
         params.progress = progress_;
@@ -286,7 +288,8 @@
         tutorial_service->SetCurrentBubble(std::move(bubble), is_last_step_);
       },
       base::Unretained(tutorial_service), title_text, body_text, step_.arrow,
-      progress, is_last_step, can_be_restarted, step_.next_button_callback);
+      progress, is_last_step, can_be_restarted, step_.next_button_callback,
+      step_.extended_properties);
 }
 
 ui::InteractionSequence::StepEndCallback
diff --git a/components/user_education/common/tutorial_description.h b/components/user_education/common/tutorial_description.h
index aa5b651..76b8e7b 100644
--- a/components/user_education/common/tutorial_description.h
+++ b/components/user_education/common/tutorial_description.h
@@ -219,6 +219,11 @@
     // 2. if this step is the last step of a tutorial
     NextButtonCallback next_button_callback = NextButtonCallback();
 
+    // Platform-specific properties that can be set for a bubble step. If an
+    // extended property evolves to warrant cross-platform support, it should be
+    // promoted out of extended properties.
+    HelpBubbleParams::ExtendedProperties extended_properties;
+
     // returns true iff all of the required parameters exist to display a
     // bubble.
     bool ShouldShowBubble() const;
@@ -286,6 +291,12 @@
       return *this;
     }
 
+    BubbleStep& SetExtendedProperties(
+        HelpBubbleParams::ExtendedProperties extended_properties_) {
+      extended_properties = std::move(extended_properties_);
+      return *this;
+    }
+
     BubbleStep& AddDefaultNextButton() {
       return AddCustomNextButton(
           base::BindRepeating([](ui::TrackedElement* current_anchor) {
diff --git a/components/user_education/common/tutorial_unittest.cc b/components/user_education/common/tutorial_unittest.cc
index 77402aea..5d3e0ba 100644
--- a/components/user_education/common/tutorial_unittest.cc
+++ b/components/user_education/common/tutorial_unittest.cc
@@ -538,6 +538,46 @@
       ClickCloseButton(service.currently_displayed_bubble_for_testing()));
 }
 
+TEST_F(TutorialTest, TutorialWithExtendedProperties) {
+  UNCALLED_MOCK_CALLBACK(TutorialService::CompletedCallback, completed);
+
+  const auto bubble_factory_registry =
+      CreateTestTutorialBubbleFactoryRegistry();
+  TutorialRegistry registry;
+  TestTutorialService service(&registry, bubble_factory_registry.get());
+
+  // Build and show test element.
+  ui::test::TestElement element_1(kTestIdentifier1, kTestContext1);
+  element_1.Show();
+
+  // Configure extended properties.
+  HelpBubbleParams::ExtendedProperties extended_properties;
+  extended_properties.values().Set("string", "v1");
+  extended_properties.values().Set("bool", true);
+  extended_properties.values().Set("int", 1);
+
+  // Build the tutorial `description`.
+  TutorialDescription description;
+  description.steps.emplace_back(
+      TutorialDescription::BubbleStep(kTestIdentifier1)
+          .SetBubbleBodyText(IDS_OK)
+          .SetExtendedProperties(extended_properties));
+
+  // Register and start the tutorial.
+  registry.AddTutorial(kTestTutorial1, std::move(description));
+  service.StartTutorial(kTestTutorial1, element_1.context(), completed.Get());
+
+  // Verify the bubble has been forwarded the extended properties.
+  auto* bubble = service.currently_displayed_bubble_for_testing();
+  ASSERT_TRUE(bubble);
+  EXPECT_THAT(
+      static_cast<test::TestHelpBubble*>(bubble)->params().extended_properties,
+      extended_properties);
+
+  // Close the bubble to complete the tutorial.
+  EXPECT_CALL_IN_SCOPE(completed, Run, ClickCloseButton(bubble));
+}
+
 TEST_F(TutorialTest, SingleStepRestartTutorial) {
   UNCALLED_MOCK_CALLBACK(TutorialService::CompletedCallback, completed);
 
diff --git a/components/vector_icons/BUILD.gn b/components/vector_icons/BUILD.gn
index db8b9bf..8109abc 100644
--- a/components/vector_icons/BUILD.gn
+++ b/components/vector_icons/BUILD.gn
@@ -56,6 +56,7 @@
     "extension.icon",
     "extension_chrome_refresh.icon",
     "extension_off.icon",
+    "extension_on.icon",
     "feed.icon",
     "file_download.icon",
     "file_download_off.icon",
diff --git a/components/vector_icons/extension_on.icon b/components/vector_icons/extension_on.icon
new file mode 100644
index 0000000..9fc3db475
--- /dev/null
+++ b/components/vector_icons/extension_on.icon
@@ -0,0 +1,47 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+CANVAS_DIMENSIONS, 20,
+MOVE_TO, 19.2f, 11,
+R_CUBIC_TO, 0, 0.57f, -0.19f, 1.06f, -0.58f, 1.47f,
+R_CUBIC_TO, -0.39f, 0.41f, -0.88f, 0.64f, -1.45f, 0.68f,
+R_V_LINE_TO, 3.35f,
+R_CUBIC_TO, 0, 0.46f, -0.16f, 0.85f, -0.49f, 1.18f,
+R_CUBIC_TO, -0.31f, 0.32f, -0.74f, 0.5f, -1.18f, 0.49f,
+H_LINE_TO, 5.53f,
+R_LINE_TO, 0.32f, -0.32f,
+R_LINE_TO, 1.41f, -1.41f,
+H_LINE_TO, 15.44f,
+V_LINE_TO, 5.56f,
+H_LINE_TO, 4.56f,
+R_V_LINE_TO, 2.26f,
+R_CUBIC_TO, 0.57f, 0.31f, 1.05f, 0.77f, 1.37f, 1.33f,
+R_CUBIC_TO, 0.07f, 0.12f, 0.13f, 0.25f, 0.18f, 0.38f,
+R_LINE_TO, -0.6f, 0.59f,
+R_LINE_TO, -0.83f, 0.82f,
+R_CUBIC_TO, -0.01f, -0.49f, -0.19f, -0.9f, -0.53f, -1.26f,
+R_CUBIC_TO, -0.35f, -0.36f, -0.82f, -0.57f, -1.32f, -0.59f,
+R_V_LINE_TO, -3.59f,
+R_CUBIC_TO, 0, -0.46f, 0.16f, -0.86f, 0.49f, -1.18f,
+R_CUBIC_TO, 0.31f, -0.32f, 0.74f, -0.5f, 1.18f, -0.49f,
+R_H_LINE_TO, 3.36f,
+R_CUBIC_TO, 0.02f, -0.55f, 0.26f, -1.07f, 0.66f, -1.44f,
+R_CUBIC_TO, 0.41f, -0.4f, 0.91f, -0.59f, 1.48f, -0.59f,
+R_CUBIC_TO, 0.57f, 0, 1.06f, 0.19f, 1.47f, 0.58f,
+R_CUBIC_TO, 0.41f, 0.39f, 0.64f, 0.88f, 0.68f, 1.45f,
+R_H_LINE_TO, 3.35f,
+R_CUBIC_TO, 0.46f, 0, 0.85f, 0.16f, 1.18f, 0.49f,
+R_CUBIC_TO, 0.33f, 0.33f, 0.49f, 0.72f, 0.49f, 1.18f,
+R_V_LINE_TO, 3.36f,
+R_CUBIC_TO, 0.55f, 0.02f, 1.07f, 0.26f, 1.44f, 0.66f,
+R_CUBIC_TO, 0.4f, 0.41f, 0.59f, 0.91f, 0.59f, 1.48f,
+CLOSE,
+R_MOVE_TO, -11.59f, -0.52f,
+R_LINE_TO, -3.83f, 3.81f,
+R_LINE_TO, -1.71f, -1.71f,
+R_LINE_TO, -1.18f, 1.2f,
+R_LINE_TO, 2.89f, 2.91f,
+R_LINE_TO, 5.03f, -5.04f,
+R_LINE_TO, -1.2f, -1.17f,
+CLOSE
diff --git a/components/webapps/browser/banners/app_banner_manager.cc b/components/webapps/browser/banners/app_banner_manager.cc
index e55a6518..403784f 100644
--- a/components/webapps/browser/banners/app_banner_manager.cc
+++ b/components/webapps/browser/banners/app_banner_manager.cc
@@ -177,11 +177,6 @@
   gTimeDeltaInDaysForTesting = days;
 }
 
-// static
-void AppBannerManager::SetTotalEngagementToTrigger(double engagement) {
-  AppBannerSettingsHelper::SetTotalEngagementToTrigger(engagement);
-}
-
 void AppBannerManager::RequestAppBanner(const GURL& validated_url) {
   DCHECK_EQ(State::INACTIVE, state_);
 
diff --git a/components/webapps/browser/banners/app_banner_manager.h b/components/webapps/browser/banners/app_banner_manager.h
index cb8c262..1d349f4 100644
--- a/components/webapps/browser/banners/app_banner_manager.h
+++ b/components/webapps/browser/banners/app_banner_manager.h
@@ -137,9 +137,6 @@
   // Fast-forwards the current time for testing.
   static void SetTimeDeltaForTesting(int days);
 
-  // Sets the total engagement required for triggering the banner in testing.
-  static void SetTotalEngagementToTrigger(double engagement);
-
   // TODO(https://crbug.com/930612): Move |GetInstallableAppName| and
   // |IsExternallyInstalledWebApp| out into a more general purpose
   // installability check class.
diff --git a/components/webapps/browser/banners/app_banner_settings_helper.cc b/components/webapps/browser/banners/app_banner_settings_helper.cc
index b5a58e3..e08489f 100644
--- a/components/webapps/browser/banners/app_banner_settings_helper.cc
+++ b/components/webapps/browser/banners/app_banner_settings_helper.cc
@@ -389,8 +389,9 @@
   gTotalEngagementToTrigger = total_engagement;
 }
 
-void AppBannerSettingsHelper::SetDefaultParameters() {
-  SetTotalEngagementToTrigger(kDefaultTotalEngagementToTrigger);
+base::AutoReset<double> AppBannerSettingsHelper::ScopeTotalEngagementForTesting(
+    double total_engagement) {
+  return base::AutoReset<double>(&gTotalEngagementToTrigger, total_engagement);
 }
 
 void AppBannerSettingsHelper::UpdateFromFieldTrial() {
diff --git a/components/webapps/browser/banners/app_banner_settings_helper.h b/components/webapps/browser/banners/app_banner_settings_helper.h
index 51f9a30..3ceda79f 100644
--- a/components/webapps/browser/banners/app_banner_settings_helper.h
+++ b/components/webapps/browser/banners/app_banner_settings_helper.h
@@ -8,6 +8,7 @@
 #include <set>
 #include <string>
 
+#include "base/auto_reset.h"
 #include "base/time/time.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -158,9 +159,8 @@
   // Set the total engagement weight required to trigger a banner.
   static void SetTotalEngagementToTrigger(double total_engagement);
 
-  // Resets the engagement weights, minimum minutes, and total engagement to
-  // trigger to their default values.
-  static void SetDefaultParameters();
+  static base::AutoReset<double> ScopeTotalEngagementForTesting(
+      double total_engagement);
 
   // Updates all values from field trial.
   static void UpdateFromFieldTrial();
diff --git a/components/webapps/browser/banners/app_banner_settings_helper_unittest.cc b/components/webapps/browser/banners/app_banner_settings_helper_unittest.cc
index 6814ffe8..e9d1d0e 100644
--- a/components/webapps/browser/banners/app_banner_settings_helper_unittest.cc
+++ b/components/webapps/browser/banners/app_banner_settings_helper_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "components/webapps/browser/banners/app_banner_settings_helper.h"
 
+#include "base/auto_reset.h"
 #include "base/time/time.h"
 #include "components/permissions/test/test_permissions_client.h"
 #include "components/prefs/testing_pref_service.h"
@@ -52,7 +53,6 @@
     site_engagement::SiteEngagementService::RegisterProfilePrefs(
         prefs_.registry());
     site_engagement::SiteEngagementService::SetServiceProvider(this);
-    AppBannerSettingsHelper::SetDefaultParameters();
   }
 
   void TearDown() override {
@@ -261,7 +261,8 @@
 }
 
 TEST_F(AppBannerSettingsHelperTest, ShouldShowWithHigherTotal) {
-  AppBannerSettingsHelper::SetTotalEngagementToTrigger(10);
+  base::AutoReset<double> total_engagement =
+      AppBannerSettingsHelper::ScopeTotalEngagementForTesting(10);
   GURL url(kTestURL);
   site_engagement::SiteEngagementService* service =
       site_engagement::SiteEngagementService::Get(browser_context());
diff --git a/content/browser/attribution_reporting/attribution_os_level_manager_android.cc b/content/browser/attribution_reporting/attribution_os_level_manager_android.cc
index b03c52b..920e879 100644
--- a/content/browser/attribution_reporting/attribution_os_level_manager_android.cc
+++ b/content/browser/attribution_reporting/attribution_os_level_manager_android.cc
@@ -146,45 +146,6 @@
 
   JNIEnv* env = base::android::AttachCurrentThread();
 
-  // Currently Android and Chromium have different matching behaviors when both
-  // `origins` and `domains` are empty.
-  // Chromium: Delete -> Delete nothing; Preserve -> Delete all.
-  // Android: Delete -> Delete all; Preserve -> Delete nothing.
-  // Android may fix the behavior in the future. As a workaround, Chromium will
-  // not call Android if it's to delete nothing (no-op), and call Android with
-  // both Delete and Preserve modes if it's to delete all. These two modes will
-  // be one no-op and one delete all in Android releases with and without the
-  // fix. See crbug.com/1442967.
-  if (origins.empty() && domains.empty()) {
-    switch (mode) {
-      case BrowsingDataFilterBuilder::Mode::kDelete:
-        // No-op.
-        std::move(done).Run();
-        return;
-      case BrowsingDataFilterBuilder::Mode::kPreserve: {
-        // Delete everything.
-        auto barrier = base::BarrierClosure(2, std::move(done));
-
-        auto empty_origins = url::GURLAndroid::ToJavaArrayOfGURLs(env, {});
-        auto empty_domains = base::android::ToJavaArrayOfStrings(
-            env, std::vector<std::string>());
-
-        for (auto match_mode : {BrowsingDataFilterBuilder::Mode::kDelete,
-                                BrowsingDataFilterBuilder::Mode::kPreserve}) {
-          int request_id = next_callback_id_++;
-          pending_data_deletion_callbacks_.emplace(request_id, barrier);
-          Java_AttributionOsLevelManager_deleteRegistrations(
-              env, jobj_, request_id, delete_begin.ToJavaTime(),
-              delete_end.ToJavaTime(), empty_origins, empty_domains,
-              GetDeletionMode(delete_rate_limit_data),
-              GetMatchBehavior(match_mode));
-        }
-
-        return;
-      }
-    }
-  }
-
   std::vector<base::android::ScopedJavaLocalRef<jobject>> j_origins;
   base::ranges::transform(
       origins, std::back_inserter(j_origins), [env](const url::Origin& origin) {
diff --git a/content/browser/gpu/browser_child_process_backgrounded_bridge.mm b/content/browser/gpu/browser_child_process_backgrounded_bridge.mm
index 759e9f2d..045c4ed 100644
--- a/content/browser/gpu/browser_child_process_backgrounded_bridge.mm
+++ b/content/browser/gpu/browser_child_process_backgrounded_bridge.mm
@@ -24,8 +24,8 @@
 struct BrowserChildProcessBackgroundedBridge::ObjCStorage {
   // Registration IDs for NSApplicationDidBecomeActiveNotification and
   // NSApplicationDidResignActiveNotification.
-  id did_become_active_observer_ = nil;
-  id did_resign_active_observer_ = nil;
+  id did_become_active_observer = nil;
+  id did_resign_active_observer = nil;
 };
 
 BrowserChildProcessBackgroundedBridge::BrowserChildProcessBackgroundedBridge(
@@ -45,13 +45,13 @@
 
 BrowserChildProcessBackgroundedBridge::
     ~BrowserChildProcessBackgroundedBridge() {
-  if (objc_storage_->did_become_active_observer_) {
+  if (objc_storage_->did_become_active_observer) {
     [NSNotificationCenter.defaultCenter
-        removeObserver:objc_storage_->did_become_active_observer_];
+        removeObserver:objc_storage_->did_become_active_observer];
   }
-  if (objc_storage_->did_resign_active_observer_) {
+  if (objc_storage_->did_resign_active_observer) {
     [NSNotificationCenter.defaultCenter
-        removeObserver:objc_storage_->did_resign_active_observer_];
+        removeObserver:objc_storage_->did_resign_active_observer];
   }
 }
 
@@ -87,7 +87,7 @@
   // process becomes foreground and background, respectively. The blocks
   // implicity captures `this`. It is safe to do so since the subscriptions are
   // removed in the destructor
-  objc_storage_->did_become_active_observer_ =
+  objc_storage_->did_become_active_observer =
       [NSNotificationCenter.defaultCenter
           addObserverForName:NSApplicationDidBecomeActiveNotification
                       object:nil
@@ -95,7 +95,7 @@
                   usingBlock:^(NSNotification* notification) {
                     OnBrowserProcessForegrounded();
                   }];
-  objc_storage_->did_resign_active_observer_ =
+  objc_storage_->did_resign_active_observer =
       [NSNotificationCenter.defaultCenter
           addObserverForName:NSApplicationDidResignActiveNotification
                       object:nil
diff --git a/content/browser/lock_screen/lock_screen_storage_impl.h b/content/browser/lock_screen/lock_screen_storage_impl.h
index 231341b..d1390b8 100644
--- a/content/browser/lock_screen/lock_screen_storage_impl.h
+++ b/content/browser/lock_screen/lock_screen_storage_impl.h
@@ -62,7 +62,8 @@
   void InitForTesting(content::BrowserContext* browser_context,
                       const base::FilePath& base_path);
 
-  raw_ptr<content::BrowserContext> browser_context_ = nullptr;
+  raw_ptr<content::BrowserContext, DanglingUntriaged> browser_context_ =
+      nullptr;
   base::SequenceBound<LockScreenStorageHelper> helper_;
 
   base::WeakPtrFactory<LockScreenStorageImpl> weak_factory_{this};
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 bf4edfb..08d5276 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -350,7 +350,7 @@
     return false;
   }
   ContentBrowserClient* browser_client = GetContentClient()->browser();
-  return browser_client->IsGetDisplayMediaSetSelectAllScreensAllowed(
+  return browser_client->IsGetAllScreensMediaAllowed(
       render_frame_host->GetBrowserContext(),
       render_frame_host->GetMainFrame()->GetLastCommittedOrigin());
 }
@@ -434,10 +434,7 @@
   // TODO(crbug/1379794): Move into ValidateControlsForGenerateStreams().
   if (controls.video.stream_type ==
           blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE_SET &&
-      (!base::FeatureList::IsEnabled(features::kGetDisplayMediaSet) ||
-       !base::FeatureList::IsEnabled(
-           features::kGetDisplayMediaSetAutoSelectAllScreens)) &&
-      (!base::FeatureList::IsEnabled(blink::features::kGetAllScreensMedia))) {
+      !base::FeatureList::IsEnabled(blink::features::kGetAllScreensMedia)) {
     mojo::ReportBadMessage("This API has not been enabled");
     return;
   }
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
index 61ca5243c..10bd7a37 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -314,8 +314,7 @@
         origin_(url::Origin::Create(GURL("https://test.com"))) {
     scoped_feature_list_
         .InitFromCommandLine(/*enable_features=*/
-                             "UserMediaCaptureOnFocus,GetDisplayMediaSet,"
-                             "GetDisplayMediaSetAutoSelectAllScreens",
+                             "UserMediaCaptureOnFocus,GetAllScreensMedia",
                              /*disable_features=*/"");
     audio_manager_ = std::make_unique<media::MockAudioManager>(
         std::make_unique<media::TestAudioThread>());
@@ -1298,8 +1297,7 @@
   scoped_feature_list_.Reset();
   scoped_feature_list_
       .InitFromCommandLine(/*enable_features=*/
-                           "UserMediaCaptureOnFocus,GetDisplayMediaSet,"
-                           "GetDisplayMediaSetAutoSelectAllScreens,"
+                           "UserMediaCaptureOnFocus,GetAllScreensMedia,"
                            "MediaStreamTrackTransfer",
                            /*disable_features=*/"");
   base::RunLoop loop;
@@ -1426,7 +1424,7 @@
 class MockContentBrowserClient : public ContentBrowserClient {
  public:
   MOCK_METHOD(bool,
-              IsGetDisplayMediaSetSelectAllScreensAllowed,
+              IsGetAllScreensMediaAllowed,
               (content::BrowserContext * context, const url::Origin& origin),
               (override));
 };
@@ -1477,8 +1475,7 @@
   GlobalRenderFrameHostId main_rfh_global_id = global_rfh_id();
   int main_render_process_id = main_rfh_global_id.child_id;
   int render_frame_id = main_rfh_global_id.frame_routing_id;
-  EXPECT_CALL(content_browser_client_,
-              IsGetDisplayMediaSetSelectAllScreensAllowed(_, _))
+  EXPECT_CALL(content_browser_client_, IsGetAllScreensMediaAllowed(_, _))
       .WillOnce(Return(true));
 
   EXPECT_TRUE(MediaStreamDispatcherHost::CheckRequestAllScreensAllowed(
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
index f45a84e..7da1a40b 100644
--- a/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -947,8 +947,8 @@
                                               video_type_, is_secure);
   }
 
-  // This function checks if the request is for the getDisplayMediaSet API.
-  bool IsGetDisplayMediaSet() const {
+  // This function checks if the request is for the getAllScreensMedia API.
+  bool IsGetAllScreensMedia() const {
     return stream_controls_.video.stream_type ==
            blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE_SET;
   }
@@ -1078,7 +1078,7 @@
   }
 
   void NotifyMultiCaptureStateChanged(MediaRequestState new_state) {
-    if (!IsGetDisplayMediaSet()) {
+    if (!IsGetAllScreensMedia()) {
       return;
     }
     switch (new_state) {
@@ -2535,7 +2535,7 @@
   SendLogMessage(base::StringPrintf("DeleteRequest([label=%s])",
                                     request_it->first.c_str()));
 #if BUILDFLAG(IS_CHROMEOS)
-  if (request_it->second->IsGetDisplayMediaSet()) {
+  if (request_it->second->IsGetAllScreensMedia()) {
     GetUIThreadTaskRunner({})->PostTask(
         FROM_HERE,
         base::BindOnce(NotifyMultiCaptureStopped, request_it->first));
@@ -3000,7 +3000,7 @@
   blink::mojom::StreamDevicesSetPtr stream_devices_set =
       request->stream_devices_set.Clone();
 
-  if (request->IsGetDisplayMediaSet()) {
+  if (request->IsGetAllScreensMedia()) {
     PanTiltZoomPermissionChecked(label, MediaStreamDevice(),
                                  /*pan_tilt_zoom_allowed=*/false);
     return;
@@ -3078,7 +3078,7 @@
 
   request->PanTiltZoomPermissionChecked(label, pan_tilt_zoom_allowed);
 
-  if (request->IsGetDisplayMediaSet()) {
+  if (request->IsGetAllScreensMedia()) {
     return;
   }
 
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h
index 335ca7f3..ad699c8 100644
--- a/content/browser/renderer_host/navigation_request.h
+++ b/content/browser/renderer_host/navigation_request.h
@@ -1127,7 +1127,10 @@
 
   // For subframe NavigationRequests, these set and return the main frame's
   // NavigationRequest token, in the case that the main frame returns it from
-  // GetNavigationTokenForDeferringSubframes().
+  // GetNavigationTokenForDeferringSubframes(). Note that by the time
+  // `main_frame_same_document_history_token()` is called, the NavigationRequest
+  // represented by that token may have already finished and been deleted, so
+  // any attempt to lookup based on this token must null-check the request.
   void set_main_frame_same_document_history_token(
       absl::optional<base::UnguessableToken> token) {
     main_frame_same_document_navigation_token_ = token;
diff --git a/content/browser/renderer_host/subframe_history_navigation_throttle.cc b/content/browser/renderer_host/subframe_history_navigation_throttle.cc
index fc5881d..e112b12 100644
--- a/content/browser/renderer_host/subframe_history_navigation_throttle.cc
+++ b/content/browser/renderer_host/subframe_history_navigation_throttle.cc
@@ -63,7 +63,12 @@
       request->frame_tree_node()->frame_tree().root()->current_frame_host();
   NavigationRequest* root_frame_navigation_request =
       root_frame_host->GetSameDocumentNavigationRequest(*main_frame_token);
-  DCHECK(root_frame_navigation_request);
+  // If the main-frame same-document history navigation already completed, the
+  // throttle is no longer necessary. This can happen when `request` is
+  // cross-document and had to wait on a slow beforeunload handler.
+  if (!root_frame_navigation_request) {
+    return nullptr;
+  }
   auto throttle = std::make_unique<SubframeHistoryNavigationThrottle>(request);
   root_frame_navigation_request->AddDeferredSubframeNavigationThrottle(
       throttle->weak_factory_.GetWeakPtr());
diff --git a/content/browser/speech/speech_recognition_manager_impl.cc b/content/browser/speech/speech_recognition_manager_impl.cc
index a310158..441745a7 100644
--- a/content/browser/speech/speech_recognition_manager_impl.cc
+++ b/content/browser/speech/speech_recognition_manager_impl.cc
@@ -303,7 +303,7 @@
     return;
 
   // The SpeechRecognictionManager is not used with multiple streams
-  // which is only supported in combination with the getDisplayMediaSet API.
+  // which is only supported in combination with the getAllScreensMedia API.
   // The |stream_devices| vector can be empty e.g. if the permission
   // was denied.
   DCHECK_LE(stream_devices_set.stream_devices.size(), 1u);
diff --git a/content/browser/theme_helper_mac.mm b/content/browser/theme_helper_mac.mm
index 479566b..869f193 100644
--- a/content/browser/theme_helper_mac.mm
+++ b/content/browser/theme_helper_mac.mm
@@ -256,7 +256,7 @@
 
 struct ThemeHelperMac::ObjCStorage {
   // ObjC object that observes notifications from the system.
-  base::scoped_nsobject<SystemThemeObserver> theme_observer_;
+  base::scoped_nsobject<SystemThemeObserver> theme_observer;
 };
 
 // static
@@ -286,7 +286,7 @@
   LoadSystemColors();
 
   // Start observing for changes.
-  objc_storage_->theme_observer_.reset([[SystemThemeObserver alloc]
+  objc_storage_->theme_observer.reset([[SystemThemeObserver alloc]
       initWithColorsChangedCallback:base::BindRepeating(
                                         &ThemeHelperMac::LoadSystemColors,
                                         base::Unretained(this))]);
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index 57c7d87..030b84c 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -323,9 +323,6 @@
 #endif
     {wf::EnableRemoveMobileViewportDoubleTap,
      raw_ref(features::kRemoveMobileViewportDoubleTap)},
-    {wf::EnableGetDisplayMediaSet, raw_ref(features::kGetDisplayMediaSet)},
-    {wf::EnableGetDisplayMediaSetAutoSelectAllScreens,
-     raw_ref(features::kGetDisplayMediaSetAutoSelectAllScreens)},
     {wf::EnableServiceWorkerBypassFetchHandler,
      raw_ref(features::kServiceWorkerBypassFetchHandler)},
   };
diff --git a/content/public/android/java/src/org/chromium/content/browser/AttributionOsLevelManager.java b/content/public/android/java/src/org/chromium/content/browser/AttributionOsLevelManager.java
index 446e2994..e566b17 100644
--- a/content/public/android/java/src/org/chromium/content/browser/AttributionOsLevelManager.java
+++ b/content/public/android/java/src/org/chromium/content/browser/AttributionOsLevelManager.java
@@ -17,6 +17,7 @@
 import androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams;
 import androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -154,6 +155,37 @@
             onDataDeletionCompleted(requestId);
             return;
         }
+
+        // Currently Android and Chromium have different matching behaviors when both
+        // `origins` and `domains` are empty.
+        // Chromium: Delete -> Delete nothing; Preserve -> Delete all.
+        // Android: Delete -> Delete all; Preserve -> Delete nothing.
+        // Android may fix the behavior in the future. As a workaround, Chromium will
+        // not call Android if it's to delete nothing (no-op), and call Android with
+        // both Delete and Preserve modes if it's to delete all. These two modes will
+        // be one no-op and one delete all in Android releases with and without the
+        // fix. See crbug.com/1442967.
+
+        ImmutableList<Integer> matchBehaviors = null;
+
+        if (origins.length == 0 && domains.length == 0) {
+            switch (matchBehavior) {
+                case DeletionRequest.MATCH_BEHAVIOR_DELETE:
+                    onDataDeletionCompleted(requestId);
+                    return;
+                case DeletionRequest.MATCH_BEHAVIOR_PRESERVE:
+                    matchBehaviors = ImmutableList.of(DeletionRequest.MATCH_BEHAVIOR_DELETE,
+                            DeletionRequest.MATCH_BEHAVIOR_PRESERVE);
+                    break;
+                default:
+                    Log.e(TAG, "Received invalid match behavior: ", matchBehavior);
+                    onDataDeletionCompleted(requestId);
+                    return;
+            }
+        } else {
+            matchBehaviors = ImmutableList.of(matchBehavior);
+        }
+
         ArrayList<Uri> originUris = new ArrayList<Uri>(origins.length);
         for (GURL origin : origins) {
             originUris.add(Uri.parse(origin.getSpec()));
@@ -164,21 +196,36 @@
             domainUris.add(Uri.parse(domain));
         }
 
-        ListenableFuture<?> future = mm.deleteRegistrationsAsync(
-                new DeletionRequest(deletionMode, matchBehavior, Instant.ofEpochMilli(startMs),
-                        Instant.ofEpochMilli(endMs), originUris, domainUris));
+        int numCalls = matchBehaviors.size();
 
-        Futures.addCallback(future, new FutureCallback<Object>() {
+        FutureCallback<Object> callback = new FutureCallback<Object>() {
+            private int mNumPendingCalls = numCalls;
+
+            private void onCall() {
+                if (--mNumPendingCalls == 0) {
+                    onDataDeletionCompleted(requestId);
+                }
+            }
+
             @Override
             public void onSuccess(Object result) {
-                onDataDeletionCompleted(requestId);
+                onCall();
             }
             @Override
             public void onFailure(Throwable thrown) {
                 Log.w(TAG, "Failed to delete measurement API data", thrown);
-                onDataDeletionCompleted(requestId);
+                onCall();
             }
-        }, ContextUtils.getApplicationContext().getMainExecutor());
+        };
+
+        for (int currMatchBehavior : matchBehaviors) {
+            ListenableFuture<?> future = mm.deleteRegistrationsAsync(new DeletionRequest(
+                    deletionMode, currMatchBehavior, Instant.ofEpochMilli(startMs),
+                    Instant.ofEpochMilli(endMs), originUris, domainUris));
+
+            Futures.addCallback(
+                    future, callback, ContextUtils.getApplicationContext().getMainExecutor());
+        }
     }
 
     /**
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 24baf87..a689ed3 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -354,7 +354,7 @@
   return false;
 }
 
-bool ContentBrowserClient::IsGetDisplayMediaSetSelectAllScreensAllowed(
+bool ContentBrowserClient::IsGetAllScreensMediaAllowed(
     content::BrowserContext* context,
     const url::Origin& origin) {
   return false;
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 90fc10e..059024e8 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -670,10 +670,9 @@
 
   // Check if applications whose origin is |origin| are allowed to perform
   // all-screens-auto-selection, which allows automatic capturing of all
-  // screens with the getDisplayMediaSet API.
-  virtual bool IsGetDisplayMediaSetSelectAllScreensAllowed(
-      content::BrowserContext* context,
-      const url::Origin& origin);
+  // screens with the getAllScreensMedia API.
+  virtual bool IsGetAllScreensMediaAllowed(content::BrowserContext* context,
+                                           const url::Origin& origin);
 
   // Allow the embedder to control the maximum renderer process count. Only
   // applies if it is set to a non-zero value.  Once this limit is exceeded,
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 8bdccda..efc55c11 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -533,17 +533,6 @@
              "NetworkQualityEstimatorWebHoldback",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// Enables the getDisplayMediaSet API for capturing multiple screens at once.
-BASE_FEATURE(kGetDisplayMediaSet,
-             "GetDisplayMediaSet",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-// Enables auto selection of all screens in combination with the
-// getDisplayMediaSet API.
-BASE_FEATURE(kGetDisplayMediaSetAutoSelectAllScreens,
-             "GetDisplayMediaSetAutoSelectAllScreens",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 // Determines if an extra brand version pair containing possibly escaped double
 // quotes and escaped backslashed should be added to the Sec-CH-UA header
 // (activated by kUserAgentClientHint)
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 4cb16451..ec429b7 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -114,8 +114,6 @@
 CONTENT_EXPORT extern const base::FeatureParam<int>
     kFledgeLimitNumAuctionsParam;
 CONTENT_EXPORT BASE_DECLARE_FEATURE(kFractionalScrollOffsets);
-CONTENT_EXPORT BASE_DECLARE_FEATURE(kGetDisplayMediaSet);
-CONTENT_EXPORT BASE_DECLARE_FEATURE(kGetDisplayMediaSetAutoSelectAllScreens);
 CONTENT_EXPORT BASE_DECLARE_FEATURE(kGreaseUACH);
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 CONTENT_EXPORT BASE_DECLARE_FEATURE(kHandleRendererThreadTypeChangesInBrowser);
diff --git a/content/test/gpu/gpu_tests/javascript/webgl_conformance_harness_script.js b/content/test/gpu/gpu_tests/javascript/webgl_conformance_harness_script.js
index f892b3f..c1d36a1 100644
--- a/content/test/gpu/gpu_tests/javascript/webgl_conformance_harness_script.js
+++ b/content/test/gpu/gpu_tests/javascript/webgl_conformance_harness_script.js
@@ -10,7 +10,6 @@
     this.throttle_timer = null;
     this.last_heartbeat = null;
     this.socket = null;
-    this.eat_messages = false;
 
     this._sendDelayedHeartbeat = this._sendDelayedHeartbeat.bind(this);
   }
@@ -23,14 +22,7 @@
     }
   }
 
-  eatWebsocketMessages() {
-    this.eat_messages = true;
-  }
-
   _sendMessage(message) {
-    if (this.eat_messages) {
-      return;
-    }
     if (this.socket === null) {
       this.queued_messages.push(message);
     } else {
@@ -112,12 +104,6 @@
   });
 }
 
-// TODO(crbug.com/1432592): Remove this once Android is back to using the
-// heartbeat mechanism.
-function eatWebsocketMessages() {
-  wrapper.eatWebsocketMessages();
-}
-
 function wrapFunctionInHeartbeat(prototype, key) {
   const old = prototype[key];
   // Some functions are specific to a WebGL version, so don't try to wrap
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_integration_test_base.py b/content/test/gpu/gpu_tests/webgl_conformance_integration_test_base.py
index 8342495..ffc2c9f3 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_integration_test_base.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_integration_test_base.py
@@ -282,21 +282,15 @@
       url = self.UrlOfStaticFilePath(TEST_PAGE_RELPATH)
       self.tab.Navigate(url, script_to_evaluate_on_commit=harness_script)
       self.tab.WaitForDocumentReadyStateToBeComplete(timeout=5)
-      # TODO(crbug.com/1432592): Remove this special casing once the flaky adb
-      # issues are investigated/resolved.
-      if self.browser.platform.GetOSName() != 'android':
-        self.tab.action_runner.EvaluateJavaScript(
-            'connectWebsocket("%d")' %
-            self.__class__.websocket_server.server_port,
-            timeout=WEBSOCKET_JAVASCRIPT_TIMEOUT_S)
-        self.__class__.websocket_server.WaitForConnection()
-        response = self.__class__.websocket_server.Receive(
-            WEBSOCKET_JAVASCRIPT_TIMEOUT_S)
-        response = json.loads(response)
-        assert response['type'] == 'CONNECTION_ACK'
-      else:
-        self.tab.action_runner.EvaluateJavaScript(
-            'eatWebsocketMessages()', timeout=WEBSOCKET_JAVASCRIPT_TIMEOUT_S)
+      self.tab.action_runner.EvaluateJavaScript(
+          'connectWebsocket("%d")' %
+          self.__class__.websocket_server.server_port,
+          timeout=WEBSOCKET_JAVASCRIPT_TIMEOUT_S)
+      self.__class__.websocket_server.WaitForConnection()
+      response = self.__class__.websocket_server.Receive(
+          WEBSOCKET_JAVASCRIPT_TIMEOUT_S)
+      response = json.loads(response)
+      assert response['type'] == 'CONNECTION_ACK'
       self.__class__.page_loaded = True
 
     gpu_info = self.browser.GetSystemInfo().gpu
@@ -311,13 +305,6 @@
     self.tab.action_runner.EvaluateJavaScript('runTest("%s")' % url)
 
   def _HandleMessageLoop(self, test_timeout: float) -> None:
-    # TODO(crbug.com/1432592): Remove this special casing once the flaky adb
-    # issues are investigated/resolved.
-    if self.browser.platform.GetOSName() == 'android':
-      self.tab.action_runner.WaitForJavaScriptCondition(
-          'webglTestHarness._finished', timeout=test_timeout)
-      return
-
     got_test_started = False
     start_time = time.time()
     try:
diff --git a/device/fido/mac/credential_store.mm b/device/fido/mac/credential_store.mm
index cd5c1783..5cc0aa1 100644
--- a/device/fido/mac/credential_store.mm
+++ b/device/fido/mac/credential_store.mm
@@ -202,7 +202,7 @@
 }
 
 struct TouchIdCredentialStore::ObjCStorage {
-  LAContext* __strong authentication_context_;
+  LAContext* __strong authentication_context;
 };
 
 TouchIdCredentialStore::TouchIdCredentialStore(AuthenticatorConfig config)
@@ -212,7 +212,7 @@
 
 void TouchIdCredentialStore::SetAuthenticationContext(
     LAContext* authentication_context) {
-  objc_storage_->authentication_context_ = authentication_context;
+  objc_storage_->authentication_context = authentication_context;
 }
 
 absl::optional<std::pair<Credential, base::ScopedCFTypeRef<SecKeyRef>>>
@@ -269,10 +269,10 @@
           flags, /*error=*/nullptr));
   CFDictionarySetValue(private_key_params, kSecAttrAccessControl,
                        access_control);
-  if (objc_storage_->authentication_context_) {
+  if (objc_storage_->authentication_context) {
     CFDictionarySetValue(
         private_key_params, kSecUseAuthenticationContext,
-        (__bridge CFTypeRef)objc_storage_->authentication_context_);
+        (__bridge CFTypeRef)objc_storage_->authentication_context);
   }
   base::ScopedCFTypeRef<CFErrorRef> cferr;
   base::ScopedCFTypeRef<SecKeyRef> private_key =
@@ -353,10 +353,10 @@
           /*error=*/nullptr));
   CFDictionarySetValue(private_key_params, kSecAttrAccessControl,
                        access_control);
-  if (objc_storage_->authentication_context_) {
+  if (objc_storage_->authentication_context) {
     CFDictionarySetValue(
         private_key_params, kSecUseAuthenticationContext,
-        (__bridge CFTypeRef)objc_storage_->authentication_context_);
+        (__bridge CFTypeRef)objc_storage_->authentication_context);
   }
   base::ScopedCFTypeRef<CFErrorRef> cferr;
   base::ScopedCFTypeRef<SecKeyRef> private_key =
@@ -517,10 +517,10 @@
   // `kSecAttrLabel` attribute wouldn't match the encoded RP ID.
   base::ScopedCFTypeRef<CFMutableDictionaryRef> query =
       DefaultKeychainQuery(config_, rp_id);
-  if (objc_storage_->authentication_context_) {
+  if (objc_storage_->authentication_context) {
     CFDictionarySetValue(
         query, kSecUseAuthenticationContext,
-        (__bridge CFTypeRef)objc_storage_->authentication_context_);
+        (__bridge CFTypeRef)objc_storage_->authentication_context);
   }
   CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue);
   CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue);
diff --git a/docs/git_tips.md b/docs/git_tips.md
index 30b7488..23cfe0f 100644
--- a/docs/git_tips.md
+++ b/docs/git_tips.md
@@ -23,7 +23,7 @@
     explaining the main purpose of Git operations.
 *   [Git User's Manual](http://schacon.github.com/git/user-manual.html) -- a
     great resource to learn more about ho to use Git properly.
-*   [A Visual Git Reference](http://marklodato.github.com/visual-git-guide/index-en.html)
+*   [A Visual Git Reference](https://marklodato.github.io/visual-git-guide/index-en.html)
     -- a resource that explains various Git operations for visual learners.
 *   [Git Cheat Sheet](http://cheat.errtheblog.com/s/git) -- now that you
     understand Git, here's a cheat sheet to quickly remind you of all the
diff --git a/docs/mac/mixing_cpp_and_objc.md b/docs/mac/mixing_cpp_and_objc.md
index da13269ba..143d08fb 100644
--- a/docs/mac/mixing_cpp_and_objc.md
+++ b/docs/mac/mixing_cpp_and_objc.md
@@ -44,13 +44,13 @@
 
 ```cpp
 struct UtilityObjectMac::ObjCStorage {
-  id appkit_token_;
-  NSWindow* window_;
+  id appkit_token;
+  NSWindow* window;
 };
 
 UtilityObjectMac::UtilityObjectMac()
     : objc_storage_(std::make_unique<ObjCStorage>()) {
-  objc_storage_->appkit_token_ = [NSFramework registerTheThing: //...
+  objc_storage_->appkit_token = [NSFramework registerTheThing: //...
   // ...
 ```
 
diff --git a/extensions/browser/api/sockets_udp/udp_socket_event_dispatcher.h b/extensions/browser/api/sockets_udp/udp_socket_event_dispatcher.h
index 2a3f9c9..f0a3810 100644
--- a/extensions/browser/api/sockets_udp/udp_socket_event_dispatcher.h
+++ b/extensions/browser/api/sockets_udp/udp_socket_event_dispatcher.h
@@ -62,7 +62,7 @@
     ~ReceiveParams();
 
     content::BrowserThread::ID thread_id;
-    raw_ptr<void> browser_context_id;
+    raw_ptr<void, DanglingUntriaged> browser_context_id;
     std::string extension_id;
     scoped_refptr<SocketData> sockets;
     int socket_id;
diff --git a/google_apis/tasks/tasks_api_response_types.cc b/google_apis/tasks/tasks_api_response_types.cc
index aff18a5..d25e4d1 100644
--- a/google_apis/tasks/tasks_api_response_types.cc
+++ b/google_apis/tasks/tasks_api_response_types.cc
@@ -31,6 +31,10 @@
 constexpr char kApiResponseStatusKey[] = "status";
 constexpr char kApiResponseTitleKey[] = "title";
 constexpr char kApiResponseUpdatedKey[] = "updated";
+constexpr char kApiResponseLinksKey[] = "links";
+constexpr char kApiResponseLinkTypeKey[] = "type";
+
+constexpr char kLinkTypeEmail[] = "email";
 
 constexpr char kTaskStatusCompleted[] = "completed";
 constexpr char kTaskStatusNeedsAction[] = "needsAction";
@@ -55,6 +59,12 @@
   return true;
 }
 
+bool ConvertTaskLinkType(base::StringPiece input, TaskLink::Type* output) {
+  *output = input == kLinkTypeEmail ? TaskLink::Type::kEmail
+                                    : TaskLink::Type::kUnknown;
+  return true;
+}
+
 }  // namespace
 
 // ----- TaskList -----
@@ -96,6 +106,14 @@
   return task_lists;
 }
 
+// ----- TaskLink -----
+
+// static
+void TaskLink::RegisterJSONConverter(JSONValueConverter<TaskLink>* converter) {
+  converter->RegisterCustomField<Type>(kApiResponseLinkTypeKey,
+                                       &TaskLink::type_, &ConvertTaskLinkType);
+}
+
 // ----- Task -----
 
 Task::Task() = default;
@@ -110,6 +128,8 @@
   converter->RegisterStringField(kApiResponseParentKey, &Task::parent_id_);
   converter->RegisterCustomField<absl::optional<base::Time>>(
       kApiResponseDueKey, &Task::due_, &ConvertTaskDueDate);
+  converter->RegisterRepeatedMessage<TaskLink>(kApiResponseLinksKey,
+                                               &Task::links_);
 }
 
 // static
diff --git a/google_apis/tasks/tasks_api_response_types.h b/google_apis/tasks/tasks_api_response_types.h
index 119212f..9f7a6ee 100644
--- a/google_apis/tasks/tasks_api_response_types.h
+++ b/google_apis/tasks/tasks_api_response_types.h
@@ -76,6 +76,32 @@
   std::vector<std::unique_ptr<TaskList>> items_;
 };
 
+// https://developers.google.com/tasks/reference/rest/v1/tasks (see "links[]*").
+class TaskLink {
+ public:
+  // Type of the link.
+  enum class Type {
+    kEmail,  // is the only supported right now.
+    kUnknown,
+  };
+
+  TaskLink() = default;
+  TaskLink(const TaskLink&) = delete;
+  TaskLink& operator=(const TaskLink&) = delete;
+  ~TaskLink() = default;
+
+  // Registers the mapping between JSON field names and the members in this
+  // class.
+  static void RegisterJSONConverter(
+      base::JSONValueConverter<TaskLink>* converter);
+
+  Type type() const { return type_; }
+
+ private:
+  // Type of the link.
+  Type type_ = Type::kUnknown;
+};
+
 // https://developers.google.com/tasks/reference/rest/v1/tasks
 class Task {
  public:
@@ -103,6 +129,7 @@
   Status status() const { return status_; }
   const std::string& parent_id() const { return parent_id_; }
   const absl::optional<base::Time>& due() const { return due_; }
+  const std::vector<std::unique_ptr<TaskLink>>& links() const { return links_; }
 
  private:
   // Task identifier.
@@ -121,6 +148,9 @@
   // `base::Time`). The due date only records date information. Not all tasks
   // have a due date.
   absl::optional<base::Time> due_ = absl::nullopt;
+
+  // Collection of links related to this task.
+  std::vector<std::unique_ptr<TaskLink>> links_;
 };
 
 // Container for multiple `Task`s.
diff --git a/google_apis/tasks/tasks_api_response_types_unittest.cc b/google_apis/tasks/tasks_api_response_types_unittest.cc
index dd3c479e..1465fb3 100644
--- a/google_apis/tasks/tasks_api_response_types_unittest.cc
+++ b/google_apis/tasks/tasks_api_response_types_unittest.cc
@@ -6,18 +6,34 @@
 
 #include <memory>
 
-#include "base/values.h"
-#include "google_apis/common/parser_util.h"
-#include "google_apis/common/test_util.h"
+#include "base/json/json_reader.h"
 #include "google_apis/common/time_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace google_apis::tasks {
 
+using ::base::JSONReader;
+
 TEST(TasksApiResponseTypesTest, CreatesTaskListsFromResponse) {
-  const auto raw_task_lists = test_util::LoadJSONFile("tasks/task_lists.json");
-  ASSERT_TRUE(raw_task_lists.get());
-  ASSERT_EQ(raw_task_lists->type(), base::Value::Type::DICT);
+  const auto raw_task_lists = JSONReader::Read(R"(
+      {
+        "kind": "tasks#taskLists",
+        "items": [
+          {
+            "kind": "tasks#taskList",
+            "id": "qwerty",
+            "title": "My Tasks 1",
+            "updated": "2023-01-30T22:19:22.812Z"
+          },
+          {
+            "kind": "tasks#taskList",
+            "id": "asdfgh",
+            "title": "My Tasks 2",
+            "updated": "2022-12-21T23:38:22.590Z"
+          }
+        ]
+      })");
+  ASSERT_TRUE(raw_task_lists);
 
   const auto task_lists = TaskLists::CreateFrom(*raw_task_lists);
   ASSERT_TRUE(task_lists);
@@ -36,11 +52,13 @@
 }
 
 TEST(TasksApiResponseTypesTest, CreatesTaskListsWithNextPageTokenFromResponse) {
-  const auto raw_task_lists = test_util::LoadJSONFile("tasks/task_lists.json");
-  ASSERT_TRUE(raw_task_lists.get());
-  ASSERT_EQ(raw_task_lists->type(), base::Value::Type::DICT);
-
-  raw_task_lists->SetStringKey("nextPageToken", "qwerty");
+  const auto raw_task_lists = JSONReader::Read(R"(
+      {
+        "kind": "tasks#taskLists",
+        "items": [],
+        "nextPageToken": "qwerty"
+      })");
+  ASSERT_TRUE(raw_task_lists);
 
   const auto task_lists = TaskLists::CreateFrom(*raw_task_lists);
   ASSERT_TRUE(task_lists);
@@ -48,20 +66,37 @@
 }
 
 TEST(TasksApiResponseTypesTest, FailsToCreateTaskListsFromInvalidResponse) {
-  const auto raw_task_lists = test_util::LoadJSONFile("tasks/task_lists.json");
-  ASSERT_TRUE(raw_task_lists.get());
-  ASSERT_EQ(raw_task_lists->type(), base::Value::Type::DICT);
-
-  raw_task_lists->SetStringKey(kApiResponseKindKey, "invalid_kind");
+  const auto raw_task_lists = JSONReader::Read(R"(
+      {
+        "kind": "invalid_kind",
+        "items": true
+      })");
+  ASSERT_TRUE(raw_task_lists);
 
   const auto task_lists = TaskLists::CreateFrom(*raw_task_lists);
   ASSERT_FALSE(task_lists);
 }
 
 TEST(TasksApiResponseTypesTest, CreatesTasksFromResponse) {
-  const auto raw_tasks = test_util::LoadJSONFile("tasks/tasks.json");
-  ASSERT_TRUE(raw_tasks.get());
-  ASSERT_EQ(raw_tasks->type(), base::Value::Type::DICT);
+  const auto raw_tasks = JSONReader::Read(R"(
+      {
+        "kind": "tasks#tasks",
+        "items": [
+          {
+            "id": "qwe",
+            "title": "Completed child task",
+            "parent": "asd",
+            "status": "completed"
+          },
+          {
+            "id": "asd",
+            "title": "Parent task",
+            "status": "needsAction",
+            "due": "2023-04-19T00:00:00.000Z"
+          }
+        ]
+      })");
+  ASSERT_TRUE(raw_tasks);
 
   const auto tasks = Tasks::CreateFrom(*raw_tasks);
   ASSERT_TRUE(tasks);
@@ -83,11 +118,13 @@
 }
 
 TEST(TasksApiResponseTypesTest, CreatesTasksWithNextPageTokenFromResponse) {
-  const auto raw_tasks = test_util::LoadJSONFile("tasks/tasks.json");
-  ASSERT_TRUE(raw_tasks.get());
-  ASSERT_EQ(raw_tasks->type(), base::Value::Type::DICT);
-
-  raw_tasks->SetStringKey("nextPageToken", "qwerty");
+  const auto raw_tasks = JSONReader::Read(R"(
+      {
+        "kind": "tasks#tasks",
+        "items": [],
+        "nextPageToken": "qwerty"
+      })");
+  ASSERT_TRUE(raw_tasks);
 
   const auto tasks = Tasks::CreateFrom(*raw_tasks);
   ASSERT_TRUE(tasks);
@@ -99,12 +136,41 @@
   EXPECT_EQ(Task::StatusToString(Task::Status::kNeedsAction), "needsAction");
 }
 
-TEST(TasksApiResponseTypesTest, FailsToCreateTasksFromInvalidResponse) {
-  const auto raw_tasks = test_util::LoadJSONFile("tasks/tasks.json");
-  ASSERT_TRUE(raw_tasks.get());
-  ASSERT_EQ(raw_tasks->type(), base::Value::Type::DICT);
+TEST(TasksApiResponseTypesTest, ConvertsTaskLinks) {
+  const auto raw_tasks = JSONReader::Read(R"(
+      {
+        "kind": "tasks#tasks",
+        "items": [
+          {
+            "id": "qwerty",
+            "links": [
+              {"type": "email"},
+              {"type": "something unsupported yet"}
+            ]
+          }
+        ]
+      })");
+  ASSERT_TRUE(raw_tasks);
 
-  raw_tasks->SetStringKey(kApiResponseKindKey, "invalid_kind");
+  const auto tasks = Tasks::CreateFrom(*raw_tasks);
+  ASSERT_TRUE(tasks);
+  ASSERT_EQ(tasks->items().size(), 1u);
+
+  EXPECT_EQ(tasks->items().at(0)->id(), "qwerty");
+
+  const auto& links = tasks->items().at(0)->links();
+  ASSERT_EQ(links.size(), 2u);
+  EXPECT_EQ(links.at(0)->type(), TaskLink::Type::kEmail);
+  EXPECT_EQ(links.at(1)->type(), TaskLink::Type::kUnknown);
+}
+
+TEST(TasksApiResponseTypesTest, FailsToCreateTasksFromInvalidResponse) {
+  const auto raw_tasks = JSONReader::Read(R"(
+      {
+        "kind": "invalid_kind",
+        "items": true
+      })");
+  ASSERT_TRUE(raw_tasks);
 
   const auto tasks = Tasks::CreateFrom(*raw_tasks);
   ASSERT_FALSE(tasks);
diff --git a/google_apis/tasks/tasks_api_url_generator_utils.cc b/google_apis/tasks/tasks_api_url_generator_utils.cc
index 1f7d28a..4e495d2d 100644
--- a/google_apis/tasks/tasks_api_url_generator_utils.cc
+++ b/google_apis/tasks/tasks_api_url_generator_utils.cc
@@ -28,7 +28,7 @@
 
 constexpr char kTasksListUrlTemplate[] = "tasks/v1/lists/$1/tasks";
 constexpr char kTasksListRequestedFields[] =
-    "kind,items(id,title,status,parent,due),nextPageToken";
+    "kind,items(id,title,status,parent,due,links(type)),nextPageToken";
 
 constexpr char kTaskUrlTemplate[] = "tasks/v1/lists/$1/tasks/$2";
 
diff --git a/google_apis/tasks/tasks_api_url_generator_utils_unittest.cc b/google_apis/tasks/tasks_api_url_generator_utils_unittest.cc
index 622c630..209a1c5 100644
--- a/google_apis/tasks/tasks_api_url_generator_utils_unittest.cc
+++ b/google_apis/tasks/tasks_api_url_generator_utils_unittest.cc
@@ -27,25 +27,25 @@
 }
 
 TEST(TasksApiUrlGeneratorUtilsTest, ReturnsListTasksUrl) {
-  EXPECT_EQ(
-      GetListTasksUrl("task-list-id", /*include_completed=*/false,
-                      /*max_results=*/absl::nullopt,
-                      /*page_token=*/""),
-      "https://tasks.googleapis.com/tasks/v1/lists/task-list-id/tasks"
-      "?fields=kind%2Citems(id%2Ctitle%2Cstatus%2Cparent%2Cdue)%2CnextPageToken"
-      "&showCompleted=false");
+  EXPECT_EQ(GetListTasksUrl("task-list-id", /*include_completed=*/false,
+                            /*max_results=*/absl::nullopt,
+                            /*page_token=*/""),
+            "https://tasks.googleapis.com/tasks/v1/lists/task-list-id/tasks"
+            "?fields=kind%2Citems(id%2Ctitle%2Cstatus%2Cparent%2Cdue%2Clinks("
+            "type))%2CnextPageToken"
+            "&showCompleted=false");
 }
 
 TEST(TasksApiUrlGeneratorUtilsTest, ReturnsListTasksUrlWithOptionalArgs) {
-  EXPECT_EQ(
-      GetListTasksUrl("task-list-id", /*include_completed=*/true,
-                      /*max_results=*/100,
-                      /*page_token=*/"qwerty"),
-      "https://tasks.googleapis.com/tasks/v1/lists/task-list-id/tasks"
-      "?fields=kind%2Citems(id%2Ctitle%2Cstatus%2Cparent%2Cdue)%2CnextPageToken"
-      "&showCompleted=true"
-      "&maxResults=100"
-      "&pageToken=qwerty");
+  EXPECT_EQ(GetListTasksUrl("task-list-id", /*include_completed=*/true,
+                            /*max_results=*/100,
+                            /*page_token=*/"qwerty"),
+            "https://tasks.googleapis.com/tasks/v1/lists/task-list-id/tasks"
+            "?fields=kind%2Citems(id%2Ctitle%2Cstatus%2Cparent%2Cdue%2Clinks("
+            "type))%2CnextPageToken"
+            "&showCompleted=true"
+            "&maxResults=100"
+            "&pageToken=qwerty");
 }
 
 TEST(TasksApiUrlGeneratorUtilsTest, ReturnsPatchTaskUrl) {
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing.h b/gpu/command_buffer/service/shared_image/iosurface_image_backing.h
index 7b3abf1f..4efd52a 100644
--- a/gpu/command_buffer/service/shared_image/iosurface_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing.h
@@ -309,7 +309,7 @@
 
   // Updates the read and write accesses tracker variables on BeginAccess and
   // waits on `release_fence_` if fence is not null.
-  void HandleBeginAccessSync(bool readonly);
+  bool HandleBeginAccessSync(bool readonly);
   // Updates the read and write accesses tracker variables on EndAccess.
   void HandleEndAccessSync(bool readonly);
 
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
index 6ed5c47..656b645c 100644
--- a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
+++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
@@ -396,7 +396,9 @@
   std::vector<sk_sp<SkSurface>> BeginWriteAccess(
       const SkSurfaceProps& surface_props,
       const gfx::Rect& update_rect) override {
-    backing_impl()->HandleBeginAccessSync(/*readonly=*/false);
+    if (!backing_impl()->HandleBeginAccessSync(/*readonly=*/false)) {
+      return {};
+    }
     if (!write_surfaces_.empty()) {
       // Write access is already in progress.
       return {};
@@ -426,7 +428,9 @@
   }
 
   std::vector<skgpu::graphite::BackendTexture> BeginWriteAccess() override {
-    backing_impl()->HandleBeginAccessSync(/*readonly=*/false);
+    if (!backing_impl()->HandleBeginAccessSync(/*readonly=*/false)) {
+      return {};
+    }
     return CreateGraphiteMetalTextures(mtl_textures_, format(), size());
   }
 
@@ -439,7 +443,9 @@
   }
 
   std::vector<skgpu::graphite::BackendTexture> BeginReadAccess() override {
-    backing_impl()->HandleBeginAccessSync(/*readonly=*/true);
+    if (!backing_impl()->HandleBeginAccessSync(/*readonly=*/true)) {
+      return {};
+    }
     return CreateGraphiteMetalTextures(mtl_textures_, format(), size());
   }
 
@@ -1079,14 +1085,29 @@
   }
 }
 
-void IOSurfaceImageBacking::HandleBeginAccessSync(bool readonly) {
-  CHECK(!ongoing_write_access_);
+bool IOSurfaceImageBacking::HandleBeginAccessSync(bool readonly) {
+  if (!readonly && ongoing_write_access_) {
+    DLOG(ERROR) << "Unable to begin write access because another "
+                   "write access is in progress";
+    return false;
+  }
+  // Track reads and writes if not being used for concurrent read/writes.
+  if (!(usage() & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE)) {
+    if (readonly && ongoing_write_access_) {
+      DLOG(ERROR) << "Unable to begin read access because another "
+                     "write access is in progress";
+      return false;
+    }
+    if (!readonly && num_ongoing_read_accesses_) {
+      DLOG(ERROR) << "Unable to begin write access because a read access is in "
+                     "progress";
+      return false;
+    }
+  }
+
   if (readonly) {
     num_ongoing_read_accesses_++;
   } else {
-    if (!(usage() & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE)) {
-      CHECK_EQ(num_ongoing_read_accesses_, 0u);
-    }
     ongoing_write_access_ = true;
   }
 
@@ -1098,6 +1119,8 @@
       fence.Wait();
     }
   }
+
+  return true;
 }
 
 void IOSurfaceImageBacking::HandleEndAccessSync(bool readonly) {
@@ -1121,7 +1144,9 @@
     bool readonly) {
   // It is in error to read or write an IOSurface while it is purgeable.
   CHECK(!purgeable_);
-  HandleBeginAccessSync(readonly);
+  if (!HandleBeginAccessSync(readonly)) {
+    return false;
+  }
 
   // If the GL texture is already bound (the bind is not marked as pending),
   // then early-out.
diff --git a/gpu/config/software_rendering_list.json b/gpu/config/software_rendering_list.json
index 82d2485..31e2acae 100644
--- a/gpu/config/software_rendering_list.json
+++ b/gpu/config/software_rendering_list.json
@@ -1628,7 +1628,7 @@
         "type": "chromeos"
       },
       "vendor_id": "0x8086",
-      "device_id": ["0x0a16", "0x0a1e", "0x0d26", "0x0a06"],
+      "device_id": ["0x0a16", "0x0a1e", "0x0d26", "0x0a06", "0x0a26"],
       "features": [
         "accelerated_2d_canvas"
       ]
diff --git a/infra/config/PRESUBMIT.py b/infra/config/PRESUBMIT.py
index 1f86a86..9671aa3 100644
--- a/infra/config/PRESUBMIT.py
+++ b/infra/config/PRESUBMIT.py
@@ -119,7 +119,7 @@
       tb_gn_isolate_map = f.read()
     if ic_gn_isolate_map != tb_gn_isolate_map:
       sync_script_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
-                                                'scripts/sync-isolate-map.pyl')
+                                                'scripts/sync-isolate-map.py')
       return [
           output_api.PresubmitError(
               '//testing/buildbot/gn_isolate_map.pyl must be kept in sync with'
diff --git a/infra/config/generated/builders/ci/GPU FYI Mac arm64 Builder/properties.json b/infra/config/generated/builders/ci/GPU FYI Mac arm64 Builder/properties.json
index 8bf6ef3..02358b43 100644
--- a/infra/config/generated/builders/ci/GPU FYI Mac arm64 Builder/properties.json
+++ b/infra/config/generated/builders/ci/GPU FYI Mac arm64 Builder/properties.json
@@ -86,6 +86,36 @@
               },
               "run_tests_serially": true
             }
+          },
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "Mac FYI Retina Release (Apple M2)",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "builder_group": "chromium.gpu.fyi",
+              "execution_mode": "TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_arch": "arm",
+                "target_bits": 64,
+                "target_platform": "mac"
+              },
+              "legacy_gclient_config": {
+                "config": "chromium"
+              },
+              "parent": {
+                "bucket": "ci",
+                "builder": "GPU FYI Mac arm64 Builder",
+                "project": "chromium"
+              },
+              "run_tests_serially": true
+            }
           }
         ]
       },
@@ -106,6 +136,11 @@
           "bucket": "ci",
           "builder": "Mac FYI Release (Apple M1)",
           "project": "chromium"
+        },
+        {
+          "bucket": "ci",
+          "builder": "Mac FYI Retina Release (Apple M2)",
+          "project": "chromium"
         }
       ],
       "mirroring_builder_group_and_names": [
@@ -116,6 +151,10 @@
         {
           "builder": "gpu-fyi-try-mac-arm64-apple-m1-rel",
           "group": "tryserver.chromium.mac"
+        },
+        {
+          "builder": "gpu-fyi-try-mac-arm64-apple-m2-retina-rel",
+          "group": "tryserver.chromium.mac"
         }
       ]
     }
diff --git "a/infra/config/generated/builders/ci/Mac FYI Retina Release \050Apple M2\051/properties.json" "b/infra/config/generated/builders/ci/Mac FYI Retina Release \050Apple M2\051/properties.json"
new file mode 100644
index 0000000..5d9e78d
--- /dev/null
+++ "b/infra/config/generated/builders/ci/Mac FYI Retina Release \050Apple M2\051/properties.json"
@@ -0,0 +1,90 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "GPU FYI Mac arm64 Builder",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "builder_group": "chromium.gpu.fyi",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_arch": "arm",
+                "target_bits": 64,
+                "target_platform": "mac"
+              },
+              "legacy_gclient_config": {
+                "config": "chromium"
+              }
+            }
+          },
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "Mac FYI Retina Release (Apple M2)",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "builder_group": "chromium.gpu.fyi",
+              "execution_mode": "TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_arch": "arm",
+                "target_bits": 64,
+                "target_platform": "mac"
+              },
+              "legacy_gclient_config": {
+                "config": "chromium"
+              },
+              "parent": {
+                "bucket": "ci",
+                "builder": "GPU FYI Mac arm64 Builder",
+                "project": "chromium"
+              },
+              "run_tests_serially": true
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "Mac FYI Retina Release (Apple M2)",
+          "project": "chromium"
+        }
+      ],
+      "mirroring_builder_group_and_names": [
+        {
+          "builder": "gpu-fyi-try-mac-arm64-apple-m2-retina-rel",
+          "group": "tryserver.chromium.mac"
+        }
+      ]
+    }
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "chromium.gpu.fyi",
+  "perf_dashboard_machine_group": "ChromiumGPUFYI",
+  "recipe": "chromium",
+  "sheriff_rotations": [
+    "chromium.gpu"
+  ]
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/fuchsia-arm64-rel-compilator/properties.json b/infra/config/generated/builders/try/fuchsia-arm64-rel-compilator/properties.json
deleted file mode 100644
index 5419689..0000000
--- a/infra/config/generated/builders/try/fuchsia-arm64-rel-compilator/properties.json
+++ /dev/null
@@ -1,60 +0,0 @@
-{
-  "$build/chromium_tests_builder_config": {
-    "builder_config": {
-      "builder_db": {
-        "entries": [
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "fuchsia-arm64-rel",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "build_gs_bucket": "chromium-linux-archive",
-              "builder_group": "chromium.fuchsia",
-              "execution_mode": "COMPILE_AND_TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_arch": "arm",
-                "target_bits": 64,
-                "target_platform": "fuchsia"
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "fuchsia_arm64",
-                  "fuchsia_arm64_host"
-                ],
-                "config": "chromium"
-              }
-            }
-          }
-        ]
-      },
-      "builder_ids": [
-        {
-          "bucket": "ci",
-          "builder": "fuchsia-arm64-rel",
-          "project": "chromium"
-        }
-      ]
-    }
-  },
-  "$build/reclient": {
-    "instance": "rbe-chromium-untrusted",
-    "jobs": 300,
-    "metrics_project": "chromium-reclient-metrics"
-  },
-  "$recipe_engine/resultdb/test_presentation": {
-    "column_keys": [],
-    "grouping_keys": [
-      "status",
-      "v.test_suite"
-    ]
-  },
-  "builder_group": "tryserver.chromium.fuchsia",
-  "recipe": "chromium/compilator"
-}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/fuchsia-arm64-rel/properties.json b/infra/config/generated/builders/try/fuchsia-arm64-rel/properties.json
index 36f73479..ada7bc61 100644
--- a/infra/config/generated/builders/try/fuchsia-arm64-rel/properties.json
+++ b/infra/config/generated/builders/try/fuchsia-arm64-rel/properties.json
@@ -1,8 +1,4 @@
 {
-  "$build/chromium_orchestrator": {
-    "compilator": "fuchsia-arm64-rel-compilator",
-    "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23"
-  },
   "$build/chromium_tests_builder_config": {
     "builder_config": {
       "builder_db": {
@@ -47,6 +43,11 @@
       ]
     }
   },
+  "$build/reclient": {
+    "instance": "rbe-chromium-untrusted",
+    "jobs": 300,
+    "metrics_project": "chromium-reclient-metrics"
+  },
   "$recipe_engine/resultdb/test_presentation": {
     "column_keys": [],
     "grouping_keys": [
@@ -56,5 +57,5 @@
   },
   "builder_group": "tryserver.chromium.fuchsia",
   "cq": "path-based",
-  "recipe": "chromium/orchestrator"
+  "recipe": "chromium_trybot"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/gpu-fyi-try-mac-arm64-apple-m2-retina-rel/properties.json b/infra/config/generated/builders/try/gpu-fyi-try-mac-arm64-apple-m2-retina-rel/properties.json
new file mode 100644
index 0000000..1742a8f
--- /dev/null
+++ b/infra/config/generated/builders/try/gpu-fyi-try-mac-arm64-apple-m2-retina-rel/properties.json
@@ -0,0 +1,92 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "GPU FYI Mac arm64 Builder",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "builder_group": "chromium.gpu.fyi",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_arch": "arm",
+                "target_bits": 64,
+                "target_platform": "mac"
+              },
+              "legacy_gclient_config": {
+                "config": "chromium"
+              }
+            }
+          },
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "Mac FYI Retina Release (Apple M2)",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "builder_group": "chromium.gpu.fyi",
+              "execution_mode": "TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_arch": "arm",
+                "target_bits": 64,
+                "target_platform": "mac"
+              },
+              "legacy_gclient_config": {
+                "config": "chromium"
+              },
+              "parent": {
+                "bucket": "ci",
+                "builder": "GPU FYI Mac arm64 Builder",
+                "project": "chromium"
+              },
+              "run_tests_serially": true
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "GPU FYI Mac arm64 Builder",
+          "project": "chromium"
+        }
+      ],
+      "builder_ids_in_scope_for_testing": [
+        {
+          "bucket": "ci",
+          "builder": "Mac FYI Retina Release (Apple M2)",
+          "project": "chromium"
+        }
+      ]
+    }
+  },
+  "$build/reclient": {
+    "instance": "rbe-chromium-untrusted",
+    "metrics_project": "chromium-reclient-metrics",
+    "scandeps_server": true
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "tryserver.chromium.mac",
+  "recipe": "chromium_trybot"
+}
\ No newline at end of file
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg
index 416cc70..155e912 100644
--- a/infra/config/generated/luci/commit-queue.cfg
+++ b/infra/config/generated/luci/commit-queue.cfg
@@ -1733,10 +1733,6 @@
         }
       }
       builders {
-        name: "chromium/try/fuchsia-arm64-rel-compilator"
-        includable_only: true
-      }
-      builders {
         name: "chromium/try/fuchsia-binary-size"
         location_filters {
           gerrit_host_regexp: ".*"
@@ -2125,6 +2121,10 @@
         includable_only: true
       }
       builders {
+        name: "chromium/try/gpu-fyi-try-mac-arm64-apple-m2-retina-rel"
+        includable_only: true
+      }
+      builders {
         name: "chromium/try/gpu-fyi-try-mac-intel-asan"
         includable_only: true
       }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index f8b9aeb..a2104247 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -15886,6 +15886,93 @@
       }
     }
     builders {
+      name: "Mac FYI Retina Release (Apple M2)"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cores:2"
+      dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
+      dimensions: "os:Ubuntu-18.04"
+      dimensions: "pool:luci.chromium.gpu.ci"
+      dimensions: "ssd:0"
+      exe {
+        cipd_package: "infra/chromium/bootstrapper/${platform}"
+        cipd_version: "latest"
+        cmd: "bootstrapper"
+      }
+      properties:
+        '{'
+        '  "$bootstrap/exe": {'
+        '    "exe": {'
+        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
+        '      "cipd_version": "refs/heads/main",'
+        '      "cmd": ['
+        '        "luciexe"'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$bootstrap/properties": {'
+        '    "properties_file": "infra/config/generated/builders/ci/Mac FYI Retina Release (Apple M2)/properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "chromium.gpu.fyi",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium",'
+        '  "sheriff_rotations": ['
+        '    "chromium.gpu"'
+        '  ]'
+        '}'
+      execution_timeout_secs: 21600
+      build_numbers: YES
+      service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
       name: "Mac FYI Retina Release (NVIDIA)"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -65010,11 +65097,12 @@
     builders {
       name: "fuchsia-arm64-rel"
       swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:fuchsia-arm64-rel"
-      dimensions: "cores:2"
+      dimensions: "builderless:1"
+      dimensions: "cores:8"
       dimensions: "cpu:x86-64"
       dimensions: "os:Ubuntu-22.04"
       dimensions: "pool:luci.chromium.try"
+      dimensions: "ssd:0"
       exe {
         cipd_package: "infra/chromium/bootstrapper/${platform}"
         cipd_version: "latest"
@@ -65044,7 +65132,7 @@
         '  "builder_group": "tryserver.chromium.fuchsia",'
         '  "cq": "path-based",'
         '  "led_builder_is_bootstrapped": true,'
-        '  "recipe": "chromium/orchestrator"'
+        '  "recipe": "chromium_trybot"'
         '}'
       execution_timeout_secs: 14400
       expiration_secs: 7200
@@ -65108,97 +65196,6 @@
           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/fuchsia-arm64-rel-compilator\">fuchsia-arm64-rel-compilator</a>."
-    }
-    builders {
-      name: "fuchsia-arm64-rel-compilator"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:fuchsia-arm64-rel-compilator"
-      dimensions: "cores:8"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-22.04"
-      dimensions: "pool:luci.chromium.try"
-      exe {
-        cipd_package: "infra/chromium/bootstrapper/${platform}"
-        cipd_version: "latest"
-        cmd: "bootstrapper"
-      }
-      properties:
-        '{'
-        '  "$bootstrap/exe": {'
-        '    "exe": {'
-        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
-        '      "cipd_version": "refs/heads/main",'
-        '      "cmd": ['
-        '        "luciexe"'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$bootstrap/properties": {'
-        '    "properties_file": "infra/config/generated/builders/try/fuchsia-arm64-rel-compilator/properties.json",'
-        '    "top_level_project": {'
-        '      "ref": "refs/heads/main",'
-        '      "repo": {'
-        '        "host": "chromium.googlesource.com",'
-        '        "project": "chromium/src"'
-        '      }'
-        '    }'
-        '  },'
-        '  "builder_group": "tryserver.chromium.fuchsia",'
-        '  "led_builder_is_bootstrapped": true,'
-        '  "recipe": "chromium/compilator"'
-        '}'
-      execution_timeout_secs: 14400
-      expiration_secs: 7200
-      grace_period {
-        seconds: 120
-      }
-      build_numbers: YES
-      service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-      task_template_canary_percentage {
-        value: 5
-      }
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "try_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_try_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_try_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          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/fuchsia-arm64-rel\">fuchsia-arm64-rel</a>."
     }
     builders {
       name: "fuchsia-binary-size"
@@ -68440,6 +68437,91 @@
       }
     }
     builders {
+      name: "gpu-fyi-try-mac-arm64-apple-m2-retina-rel"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cpu:x86-64"
+      dimensions: "os:Mac"
+      dimensions: "pool:luci.chromium.gpu.mac.arm64.apple.m1.try"
+      exe {
+        cipd_package: "infra/chromium/bootstrapper/${platform}"
+        cipd_version: "latest"
+        cmd: "bootstrapper"
+      }
+      properties:
+        '{'
+        '  "$bootstrap/exe": {'
+        '    "exe": {'
+        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
+        '      "cipd_version": "refs/heads/main",'
+        '      "cmd": ['
+        '        "luciexe"'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$bootstrap/properties": {'
+        '    "properties_file": "infra/config/generated/builders/try/gpu-fyi-try-mac-arm64-apple-m2-retina-rel/properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "tryserver.chromium.mac",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium_trybot"'
+        '}'
+      execution_timeout_secs: 21600
+      expiration_secs: 7200
+      build_numbers: YES
+      service_account: "chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
+      task_template_canary_percentage {
+        value: 5
+      }
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "try_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
       name: "gpu-fyi-try-mac-intel-asan"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index 0d3eb67..761e4bd 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -3039,9 +3039,6 @@
     name: "buildbucket/luci.chromium.try/fuchsia-arm64-rel"
   }
   builders {
-    name: "buildbucket/luci.chromium.try/fuchsia-arm64-rel-compilator"
-  }
-  builders {
     name: "buildbucket/luci.chromium.try/fuchsia-x64-cast-receiver-rel"
   }
   builders {
@@ -11305,7 +11302,12 @@
   builders {
     name: "buildbucket/luci.chromium.ci/Mac FYI Release (Apple M1)"
     category: "Mac|Apple"
-    short_name: "rel"
+    short_name: "m1"
+  }
+  builders {
+    name: "buildbucket/luci.chromium.ci/Mac FYI Retina Release (Apple M2)"
+    category: "Mac|Apple"
+    short_name: "m2"
   }
   builders {
     name: "buildbucket/luci.chromium.ci/Mac FYI Release (Intel)"
@@ -17707,9 +17709,6 @@
     name: "buildbucket/luci.chromium.try/fuchsia-arm64-rel"
   }
   builders {
-    name: "buildbucket/luci.chromium.try/fuchsia-arm64-rel-compilator"
-  }
-  builders {
     name: "buildbucket/luci.chromium.try/fuchsia-binary-size"
   }
   builders {
@@ -17821,6 +17820,9 @@
     name: "buildbucket/luci.chromium.try/gpu-fyi-try-mac-arm64-apple-m1-rel"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/gpu-fyi-try-mac-arm64-apple-m2-retina-rel"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/gpu-fyi-try-mac-intel-asan"
   }
   builders {
@@ -19086,9 +19088,6 @@
     name: "buildbucket/luci.chromium.try/fuchsia-arm64-rel"
   }
   builders {
-    name: "buildbucket/luci.chromium.try/fuchsia-arm64-rel-compilator"
-  }
-  builders {
     name: "buildbucket/luci.chromium.try/fuchsia-binary-size"
   }
   builders {
@@ -19395,6 +19394,9 @@
     name: "buildbucket/luci.chromium.try/gpu-fyi-try-mac-arm64-apple-m1-rel"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/gpu-fyi-try-mac-arm64-apple-m2-retina-rel"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/gpu-fyi-try-mac-intel-asan"
   }
   builders {
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg
index 60b8512..0c81294 100644
--- a/infra/config/generated/luci/luci-scheduler.cfg
+++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -2129,6 +2129,15 @@
   }
 }
 job {
+  id: "Mac FYI Retina Release (Apple M2)"
+  realm: "ci"
+  buildbucket {
+    server: "cr-buildbucket.appspot.com"
+    bucket: "ci"
+    builder: "Mac FYI Retina Release (Apple M2)"
+  }
+}
+job {
   id: "Mac FYI Retina Release (NVIDIA)"
   realm: "ci"
   buildbucket {
diff --git a/infra/config/generated/luci/realms.cfg b/infra/config/generated/luci/realms.cfg
index 567ffe3..fbe37cf7 100644
--- a/infra/config/generated/luci/realms.cfg
+++ b/infra/config/generated/luci/realms.cfg
@@ -244,6 +244,7 @@
         values: "Mac FYI Retina ASAN (AMD)"
         values: "Mac FYI Retina Debug (AMD)"
         values: "Mac FYI Retina Release (AMD)"
+        values: "Mac FYI Retina Release (Apple M2)"
         values: "Mac FYI Retina Release (NVIDIA)"
         values: "Mac Pro FYI Release (AMD)"
         values: "Win10 FYI x64 DX12 Vulkan Debug (NVIDIA)"
diff --git a/infra/config/generated/sheriff-rotations/chromium.gpu.txt b/infra/config/generated/sheriff-rotations/chromium.gpu.txt
index 93aed63..c72e5899 100644
--- a/infra/config/generated/sheriff-rotations/chromium.gpu.txt
+++ b/infra/config/generated/sheriff-rotations/chromium.gpu.txt
@@ -49,6 +49,7 @@
 ci/Mac FYI Retina ASAN (AMD)
 ci/Mac FYI Retina Debug (AMD)
 ci/Mac FYI Retina Release (AMD)
+ci/Mac FYI Retina Release (Apple M2)
 ci/Mac FYI Retina Release (NVIDIA)
 ci/Mac Pro FYI Release (AMD)
 ci/Mac Release (Intel)
diff --git a/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star b/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star
index aad41b6c..6adf2c7 100644
--- a/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star
+++ b/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star
@@ -971,7 +971,33 @@
     ),
     console_view_entry = consoles.console_view_entry(
         category = "Mac|Apple",
-        short_name = "rel",
+        short_name = "m1",
+    ),
+)
+
+ci.thin_tester(
+    name = "Mac FYI Retina Release (Apple M2)",
+    triggered_by = ["GPU FYI Mac arm64 Builder"],
+    builder_spec = builder_config.builder_spec(
+        execution_mode = builder_config.execution_mode.TEST,
+        gclient_config = builder_config.gclient_config(
+            config = "chromium",
+        ),
+        chromium_config = builder_config.chromium_config(
+            config = "chromium",
+            apply_configs = [
+                "mb",
+            ],
+            build_config = builder_config.build_config.RELEASE,
+            target_arch = builder_config.target_arch.ARM,
+            target_bits = 64,
+            target_platform = builder_config.target_platform.MAC,
+        ),
+        run_tests_serially = True,
+    ),
+    console_view_entry = consoles.console_view_entry(
+        category = "Mac|Apple",
+        short_name = "m2",
     ),
 )
 
diff --git a/infra/config/subprojects/chromium/gpu.try.star b/infra/config/subprojects/chromium/gpu.try.star
index 10476ea..ae143839 100644
--- a/infra/config/subprojects/chromium/gpu.try.star
+++ b/infra/config/subprojects/chromium/gpu.try.star
@@ -317,6 +317,17 @@
 )
 
 gpu_mac_builder(
+    name = "gpu-fyi-try-mac-arm64-apple-m2-retina-rel",
+    mirrors = [
+        "ci/GPU FYI Mac arm64 Builder",
+        "ci/Mac FYI Retina Release (Apple M2)",
+    ],
+    # TODO(crbug.com/1435476): Switch to a dedicated M2 pool once we have
+    # allocated machines.
+    pool = "luci.chromium.gpu.mac.arm64.apple.m1.try",
+)
+
+gpu_mac_builder(
     name = "gpu-fyi-try-mac-intel-asan",
     mirrors = [
         "ci/GPU FYI Mac Builder (asan)",
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star b/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star
index 816c88b8..d8c37103 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star
@@ -46,20 +46,18 @@
     ),
 )
 
-try_.orchestrator_builder(
+try_.builder(
     name = "fuchsia-arm64-rel",
     branch_selector = branches.selector.FUCHSIA_BRANCHES,
     mirrors = [
         "ci/fuchsia-arm64-rel",
     ],
-    compilator = "fuchsia-arm64-rel-compilator",
     experiments = {
         "enable_weetbix_queries": 100,
         "weetbix.retry_weak_exonerations": 100,
         "weetbix.enable_weetbix_exonerations": 100,
     },
     main_list_view = "try",
-    service_account = try_.DEFAULT_SERVICE_ACCOUNT,
     tryjob = try_.job(
         location_filters = [
             # Covers //fuchsia_web and //fuchsia changes, including
@@ -76,14 +74,6 @@
     ),
 )
 
-try_.compilator_builder(
-    name = "fuchsia-arm64-rel-compilator",
-    branch_selector = branches.selector.FUCHSIA_BRANCHES,
-    # TODO(crbug.com/1298110): Set to True once compilator bots are moved
-    ssd = None,
-    main_list_view = "try",
-)
-
 try_.builder(
     name = "fuchsia-binary-size",
     branch_selector = branches.selector.FUCHSIA_BRANCHES,
diff --git a/ios/chrome/app/application_delegate/app_state+private.h b/ios/chrome/app/application_delegate/app_state+private.h
index f7589d62..c14b8568 100644
--- a/ios/chrome/app/application_delegate/app_state+private.h
+++ b/ios/chrome/app/application_delegate/app_state+private.h
@@ -7,18 +7,12 @@
 
 #include "ios/chrome/app/application_delegate/app_state.h"
 
-@class SafeModeCoordinator;
-
 // Class extension exposing private methods of AppState for testing.
 @interface AppState () <AppStateObserver>
 
-@property(nonatomic, retain) SafeModeCoordinator* safeModeCoordinator;
-
 // Redefined internally as readwrite.
 @property(nonatomic, assign) InitStage initStage;
 
-- (void)queueTransitionToFirstInitStage;
-
 - (void)completeUIInitialization;
 
 @end
diff --git a/ios/chrome/app/application_delegate/app_state.h b/ios/chrome/app/application_delegate/app_state.h
index adc5cba..eb89412 100644
--- a/ios/chrome/app/application_delegate/app_state.h
+++ b/ios/chrome/app/application_delegate/app_state.h
@@ -118,14 +118,6 @@
 // YES if the application is getting terminated.
 @property(nonatomic, readonly) BOOL appIsTerminating;
 
-// Saves the launchOptions to be used from -newTabFromLaunchOptions. If the
-// application is in background, initialize the browser to basic. If not, launch
-// the browser.
-// Returns whether additional delegate handling should be performed (call to
-// -performActionForShortcutItem or -openURL by the system for example)
-- (BOOL)requiresHandlingAfterLaunchWithOptions:(NSDictionary*)launchOptions
-                               stateBackground:(BOOL)stateBackground;
-
 // Logs duration of the session and records that chrome is no longer in cold
 // start.
 - (void)willResignActive;
@@ -187,6 +179,10 @@
 // transition at once.
 - (void)queueTransitionToNextInitStage;
 
+// Queue the transition (as defined above) to the very first initialization
+// stage.
+- (void)startInitialization;
+
 @end
 
 #endif  // IOS_CHROME_APP_APPLICATION_DELEGATE_APP_STATE_H_
diff --git a/ios/chrome/app/application_delegate/app_state.mm b/ios/chrome/app/application_delegate/app_state.mm
index d2d80e1..1f90f13 100644
--- a/ios/chrome/app/application_delegate/app_state.mm
+++ b/ios/chrome/app/application_delegate/app_state.mm
@@ -303,17 +303,8 @@
   // Fully initialize the browser objects for the browser UI if it is not
   // already the case. This is especially needed for scene startup.
   if (self.initStage < InitStageBrowserObjectsForUI) {
-    // Start the initialization in the case it wasn't already done before
-    // foregrounding the app. `initStage` will be greater than InitStageStart if
-    // the initialization was already started.
-    if (self.initStage == InitStageStart) {
-      // TODO(crbug.com/1346512): Remove this code path after some time in
-      // canary. This is meant to be easy to revert. Initialization is always
-      // started at application:didFinishLaunchingWithOptions: and transitions
-      // past InitStageStart before returning to the runloop.
-      NOTREACHED();
-      [self queueTransitionToFirstInitStage];
-    }
+    // Invariant: The app has passed InitStageStart.
+    CHECK(self.initStage != InitStageStart);
     // TODO(crbug.com/1197330): This function should only be called once
     // during a specific stage, but this requires non-trivial refactoring, so
     // for now #initializeUIPreSafeMode will just return early if called more
@@ -455,25 +446,6 @@
   }
 }
 
-- (BOOL)requiresHandlingAfterLaunchWithOptions:(NSDictionary*)launchOptions
-                               stateBackground:(BOOL)stateBackground {
-  [_browserLauncher setLaunchOptions:launchOptions];
-
-  [self queueTransitionToFirstInitStage];
-
-  // `stateBackground` is wrongly always YES, even in regular foreground
-  // launches. This variable is a legacy before we started supporting
-  // multi-scene.
-  // TODO(crbug.com/1346512): Remove this code path after some time in
-  // canary. This is meant to be easy to revert.
-  DCHECK(stateBackground);
-  if (!stateBackground) {
-    [self initializeUIPreSafeMode];
-  }
-
-  return YES;
-}
-
 - (void)addObserver:(id<AppStateObserver>)observer {
   [self.observers addObserver:observer];
 
@@ -508,31 +480,10 @@
   [self queueTransitionToInitStage:nextInitStage];
 }
 
-- (void)queueTransitionToFirstInitStage {
+- (void)startInitialization {
   [self queueTransitionToInitStage:InitStageStart];
 }
 
-- (void)queueTransitionToInitStage:(InitStage)initStage {
-  if (self.isIncrementingInitStage) {
-    // It is an error to queue more than one transition at once.
-    DCHECK(!self.needsIncrementInitStage);
-
-    // Set a flag to increment after the observers are notified of the current
-    // change.
-    self.needsIncrementInitStage = YES;
-    return;
-  }
-
-  self.isIncrementingInitStage = YES;
-  self.initStage = initStage;
-  self.isIncrementingInitStage = NO;
-
-  if (self.needsIncrementInitStage) {
-    self.needsIncrementInitStage = NO;
-    [self queueTransitionToNextInitStage];
-  }
-}
-
 #pragma mark - Multiwindow-related
 
 - (SceneState*)foregroundActiveScene {
@@ -619,6 +570,27 @@
   [[PreviousSessionInfo sharedInstance] beginRecordingCurrentSession];
 }
 
+- (void)queueTransitionToInitStage:(InitStage)initStage {
+  if (self.isIncrementingInitStage) {
+    // It is an error to queue more than one transition at once.
+    DCHECK(!self.needsIncrementInitStage);
+
+    // Set a flag to increment after the observers are notified of the current
+    // change.
+    self.needsIncrementInitStage = YES;
+    return;
+  }
+
+  self.isIncrementingInitStage = YES;
+  self.initStage = initStage;
+  self.isIncrementingInitStage = NO;
+
+  if (self.needsIncrementInitStage) {
+    self.needsIncrementInitStage = NO;
+    [self queueTransitionToNextInitStage];
+  }
+}
+
 #pragma mark - UIBlockerManager
 
 - (void)incrementBlockingUICounterForTarget:(id<UIBlockerTarget>)target {
diff --git a/ios/chrome/app/application_delegate/app_state_unittest.mm b/ios/chrome/app/application_delegate/app_state_unittest.mm
index efa5ded..b8216d0 100644
--- a/ios/chrome/app/application_delegate/app_state_unittest.mm
+++ b/ios/chrome/app/application_delegate/app_state_unittest.mm
@@ -154,31 +154,6 @@
 // A block ths returns values of AppState connectedScenes.
 typedef NSArray<SceneState*>* (^ScenesBlock)(id self);
 
-// Sets init stage expected transition calls from `start` to `end`.
-void SetInitStageTransitionExpectations(id mock,
-                                        AppState* app_state,
-                                        InitStage start,
-                                        InitStage end) {
-  ASSERT_LE(end, InitStageFinal);
-  ASSERT_GE(end, InitStageStart);
-
-  InitStage current_stage = start;
-
-  // Handle the particular case of InitStageStart.
-  if (current_stage == InitStageStart) {
-    [[mock expect] appState:app_state willTransitionToInitStage:InitStageStart];
-    [[mock expect] appState:app_state
-        didTransitionFromInitStage:InitStageStart];
-  }
-
-  while (current_stage != end) {
-    InitStage next_stage = static_cast<InitStage>(current_stage + 1);
-    [[mock expect] appState:app_state willTransitionToInitStage:next_stage];
-    [[mock expect] appState:app_state didTransitionFromInitStage:current_stage];
-    current_stage = next_stage;
-  }
-}
-
 }  // namespace
 
 // An app state observer that will call [AppState
@@ -466,136 +441,6 @@
 
 #pragma mark - Tests.
 
-// Tests that if the application is in background
-// -requiresHandlingAfterLaunchWithOptions saves the launchOptions and returns
-// YES (to handle the launch options later).
-TEST_F(AppStateTest, requiresHandlingAfterLaunchWithOptionsBackground) {
-  // Setup.
-  NSString* sourceApplication = @"com.apple.mobilesafari";
-  NSDictionary* launchOptions =
-      @{UIApplicationLaunchOptionsSourceApplicationKey : sourceApplication};
-
-  AppState* appState = getAppStateWithMock();
-
-  id browserLauncherMock = getBrowserLauncherMock();
-  [[browserLauncherMock expect] setLaunchOptions:launchOptions];
-
-  // Action.
-  BOOL result = [appState requiresHandlingAfterLaunchWithOptions:launchOptions
-                                                 stateBackground:YES];
-
-  // Test.
-  EXPECT_TRUE(result);
-  EXPECT_OCMOCK_VERIFY(browserLauncherMock);
-
-  // Verify the launch stage is still at the point of initializing the browser
-  // basics when the app is backgrounded.
-  EXPECT_EQ(InitStageBrowserBasic, appState.initStage);
-}
-
-// Tests that if the application is active and Safe Mode should be activated
-// -requiresHandlingAfterLaunchWithOptions save the launch options and activate
-// the Safe Mode.
-TEST_F(AppStateTest, requiresHandlingAfterLaunchWithOptionsForegroundSafeMode) {
-  // Setup.
-  NSString* sourceApplication = @"com.apple.mobilesafari";
-  NSDictionary* launchOptions =
-      @{UIApplicationLaunchOptionsSourceApplicationKey : sourceApplication};
-
-  base::TimeTicks now = base::TimeTicks::Now();
-  [[[getStartupInformationMock() stub] andReturnValue:@YES] isColdStart];
-  [[getStartupInformationMock() stub] setIsFirstRun:YES];
-  [[[getStartupInformationMock() stub] andReturnValue:@YES] isFirstRun];
-  [[[getStartupInformationMock() stub] andDo:^(NSInvocation* invocation) {
-    [invocation setReturnValue:(void*)&now];
-  }] appLaunchTime];
-
-  id windowMock = getWindowMock();
-  [[[windowMock stub] andReturn:nil] rootViewController];
-  [[windowMock expect] setRootViewController:[OCMArg any]];
-  [[windowMock expect] makeKeyAndVisible];
-
-  AppState* appState = getAppStateWithMock();
-  ASSERT_EQ(InitStageStart, appState.initStage);
-
-  id appStateObserverMock = getAppStateObserverMock();
-  SetInitStageTransitionExpectations(appStateObserverMock, appState,
-                                     InitStageStart, InitStageFinal);
-  [appState addObserver:appStateObserverMock];
-  id browserLauncherMock = getBrowserLauncherMock();
-  [[browserLauncherMock expect] setLaunchOptions:launchOptions];
-
-  swizzleSafeModeShouldStart(YES);
-
-  // Action.
-  BOOL result = [appState requiresHandlingAfterLaunchWithOptions:launchOptions
-                                                 stateBackground:YES];
-
-  [appState queueTransitionToNextInitStage];
-
-  // Start the safe mode by transitioning the scene to foreground again after
-  // #requiresHandlingAfterLaunchWithOptions which starts the safe mode.
-  SceneState* sceneState = appState.connectedScenes.firstObject;
-  sceneState.activationLevel = SceneActivationLevelForegroundActive;
-
-  EXPECT_TRUE(result);
-  EXPECT_EQ(appState.initStage, InitStageSafeMode);
-
-  // Transition out of safe mode.
-  [appState queueTransitionToNextInitStage];
-
-  // Verify that the dependencies are called properly during the app journey.
-  EXPECT_OCMOCK_VERIFY(windowMock);
-  EXPECT_OCMOCK_VERIFY(browserLauncherMock);
-  EXPECT_OCMOCK_VERIFY(appStateObserverMock);
-
-  EXPECT_EQ(InitStageFinal, appState.initStage);
-}
-
-// Tests that if the application is active
-// -requiresHandlingAfterLaunchWithOptions saves the launchOptions and start the
-// application in foreground.
-TEST_F(AppStateTest, requiresHandlingAfterLaunchWithOptionsForeground) {
-  // Setup.
-  NSString* sourceApplication = @"com.apple.mobilesafari";
-  NSDictionary* launchOptions =
-      @{UIApplicationLaunchOptionsSourceApplicationKey : sourceApplication};
-
-  [[[getStartupInformationMock() stub] andReturnValue:@YES] isColdStart];
-  [[getStartupInformationMock() stub] setIsFirstRun:YES];
-  [[[getStartupInformationMock() stub] andReturnValue:@YES] isFirstRun];
-
-  [[[getWindowMock() stub] andReturn:nil] rootViewController];
-
-  AppState* appState = getAppStateWithMock();
-  ASSERT_EQ(appState.initStage, InitStageStart);
-
-  id appStateObserverMock = getAppStateObserverMock();
-  SetInitStageTransitionExpectations(appStateObserverMock, appState,
-                                     InitStageStart, InitStageFinal);
-
-  [appState addObserver:appStateObserverMock];
-
-  id browserLauncherMock = getBrowserLauncherMock();
-  [[browserLauncherMock expect] setLaunchOptions:launchOptions];
-
-  swizzleSafeModeShouldStart(NO);
-
-  // Action.
-  BOOL result = [appState requiresHandlingAfterLaunchWithOptions:launchOptions
-                                                 stateBackground:YES];
-
-  [appState queueTransitionToNextInitStage];
-
-  // Test.
-  EXPECT_TRUE(result);
-  EXPECT_EQ(InitStageFinal, appState.initStage);
-
-  // Verify that the dependencies were called properly.
-  EXPECT_OCMOCK_VERIFY(browserLauncherMock);
-  EXPECT_OCMOCK_VERIFY(appStateObserverMock);
-}
-
 using AppStateNoFixtureTest = PlatformTest;
 
 // Test that -willResignActive set cold start to NO and launch record.
@@ -634,7 +479,7 @@
   [appState addObserver:observer];
 
   // Start init stages.
-  [appState queueTransitionToFirstInitStage];
+  [appState startInitialization];
   [appState queueTransitionToNextInitStage];
   [appState queueTransitionToNextInitStage];
 
@@ -676,7 +521,7 @@
   [appState addObserver:observer];
 
   // Start init stages.
-  [appState queueTransitionToFirstInitStage];
+  [appState startInitialization];
   [appState queueTransitionToNextInitStage];
 
   id application = [OCMockObject mockForClass:[UIApplication class]];
@@ -724,7 +569,7 @@
   [[appStateMock expect] completeUIInitialization];
 
   // Simulate finishing the initialization before going to background.
-  [getAppStateWithMock() queueTransitionToFirstInitStage];
+  [getAppStateWithMock() startInitialization];
   [getAppStateWithMock() queueTransitionToNextInitStage];
 
   // Simulate background before going to foreground.
@@ -767,7 +612,7 @@
   [[[getStartupInformationMock() stub] andReturnValue:@YES] isFirstRun];
 
   // Simulate finishing the initialization before going to background.
-  [getAppStateWithMock() queueTransitionToFirstInitStage];
+  [getAppStateWithMock() startInitialization];
   [getAppStateWithMock() queueTransitionToNextInitStage];
 
   // Actions.
diff --git a/ios/chrome/app/application_delegate/browser_launcher.h b/ios/chrome/app/application_delegate/browser_launcher.h
index 8b444921..81eaf53 100644
--- a/ios/chrome/app/application_delegate/browser_launcher.h
+++ b/ios/chrome/app/application_delegate/browser_launcher.h
@@ -10,9 +10,6 @@
 // This protocol defines the startup method for the application.
 @protocol BrowserLauncher<NSObject>
 
-// Cached launchOptions from AppState's -didFinishLaunchingWithOptions.
-@property(nonatomic, retain) NSDictionary* launchOptions;
-
 // Browser view information created during startup.
 @property(nonatomic, readonly) id<BrowserProviderInterface>
     browserProviderInterface;
diff --git a/ios/chrome/app/application_delegate/fake_startup_information.mm b/ios/chrome/app/application_delegate/fake_startup_information.mm
index 686a298..5bf29cf 100644
--- a/ios/chrome/app/application_delegate/fake_startup_information.mm
+++ b/ios/chrome/app/application_delegate/fake_startup_information.mm
@@ -53,9 +53,4 @@
   // Stub.
 }
 
-- (NSDictionary*)launchOptions {
-  // Stub.
-  return @{};
-}
-
 @end
diff --git a/ios/chrome/app/application_delegate/mock_tab_opener.mm b/ios/chrome/app/application_delegate/mock_tab_opener.mm
index 5cb7a98..902de306 100644
--- a/ios/chrome/app/application_delegate/mock_tab_opener.mm
+++ b/ios/chrome/app/application_delegate/mock_tab_opener.mm
@@ -47,7 +47,7 @@
   _urlLoadParams.web_params.url = _urlLoadParams.web_params.url.EmptyGURL();
 }
 
-- (void)openTabFromLaunchWithParams:(NSDictionary*)launchOptions
+- (void)openTabFromLaunchWithParams:(URLOpenerParams*)params
                  startupInformation:(id<StartupInformation>)startupInformation
                            appState:(AppState*)appState {
   // Stub.
diff --git a/ios/chrome/app/application_delegate/startup_information.h b/ios/chrome/app/application_delegate/startup_information.h
index 7119e73..9e51a193 100644
--- a/ios/chrome/app/application_delegate/startup_information.h
+++ b/ios/chrome/app/application_delegate/startup_information.h
@@ -28,9 +28,6 @@
 // Tick of the first scene connection, used for UMA.
 @property(nonatomic, assign) base::TimeTicks firstSceneConnectionTime;
 
-// Only for iOS 12 compat.
-- (NSDictionary*)launchOptions;
-
 // Disables the FirstUserActionRecorder.
 - (void)resetFirstUserActionRecorder;
 
diff --git a/ios/chrome/app/main_application_delegate.mm b/ios/chrome/app/main_application_delegate.mm
index b3a68801..3aac648 100644
--- a/ios/chrome/app/main_application_delegate.mm
+++ b/ios/chrome/app/main_application_delegate.mm
@@ -121,15 +121,8 @@
                                    kAppDidFinishLaunchingConsecutiveCallsKey] +
                  1
           forKey:metrics_mediator::kAppDidFinishLaunchingConsecutiveCallsKey];
-  BOOL inBackground =
-      [application applicationState] == UIApplicationStateBackground;
-  // `inBackground` is wrongly always YES, even in regular foreground launches.
-  // TODO(crbug.com/1346512): Remove this code path after some time in canary.
-  // This is meant to be easy to revert.
-  DCHECK(inBackground);
-  BOOL requiresHandling =
-      [_appState requiresHandlingAfterLaunchWithOptions:launchOptions
-                                        stateBackground:inBackground];
+
+  [_appState startInitialization];
   [[NSNotificationCenter defaultCenter]
       addObserver:self
          selector:@selector(sceneWillConnect:)
@@ -157,7 +150,7 @@
              name:UIApplicationWillEnterForegroundNotification
            object:nil];
 
-  return requiresHandling;
+  return YES;
 }
 
 - (void)applicationWillTerminate:(UIApplication*)application {
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm
index b94e80e..27742dd5 100644
--- a/ios/chrome/app/main_controller.mm
+++ b/ios/chrome/app/main_controller.mm
@@ -310,9 +310,6 @@
   // in system Spotlight index.
   SpotlightManager* _spotlightManager;
 
-  // Cached launchOptions from -didFinishLaunchingWithOptions.
-  NSDictionary* _launchOptions;
-
   // Variable backing metricsMediator property.
   __weak MetricsMediator* _metricsMediator;
 
@@ -380,8 +377,6 @@
 @implementation MainController
 
 // Defined by public protocols.
-// - BrowserLauncher
-@synthesize launchOptions = _launchOptions;
 // - StartupInformation
 @synthesize isColdStart = _isColdStart;
 @synthesize appLaunchTime = _appLaunchTime;
@@ -586,8 +581,6 @@
   [_startupTasks registerForApplicationWillResignActiveNotification];
   [self registerForOrientationChangeNotifications];
 
-  _launchOptions = nil;
-
   [self scheduleTasksRequiringBVCWithBrowserState];
 
   CustomizeUIAppearance();
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.h b/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.h
index f614aeb..4e899c6 100644
--- a/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.h
+++ b/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.h
@@ -54,12 +54,10 @@
                          web::WebState* new_web_state);
 
   // Called when the Browser which the user is primarily interacting with has
-  // changed. The `active_web_state` is the active tab of the browser's
-  // webStateList. If the user began interacting with `active_web_state`,
+  // changed. If the user began interacting with `active_web_state`,
   // `primary_browser` should be true. If the user stopped interacting with
   // `active_web_state`, `primary_browser` should be false.
-  void RecordPrimaryBrowserChange(bool primary_browser,
-                                  web::WebState* active_web_state);
+  void RecordPrimaryBrowserChange(bool primary_browser);
 
   // Called when a page load begins, to keep track of how many page loads
   // happen before an evicted tab is seen.
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.mm b/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.mm
index 2de728f..4d656f6 100644
--- a/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.mm
+++ b/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.mm
@@ -179,8 +179,9 @@
 }
 
 void TabUsageRecorderBrowserAgent::RecordPrimaryBrowserChange(
-    bool primary_browser,
-    web::WebState* active_web_state) {
+    bool primary_browser) {
+  web::WebState* active_web_state =
+      web_state_list_ ? web_state_list_->GetActiveWebState() : nullptr;
   if (primary_browser) {
     // User just came back to this tab model, so record a tab selection even
     // though the current tab was reselected.
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent_unittest.mm b/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent_unittest.mm
index eea9db0..463f1c5c 100644
--- a/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent_unittest.mm
+++ b/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent_unittest.mm
@@ -222,7 +222,7 @@
   web::FakeWebState* mock_tab_a = InsertFakeWebState(kURL, NOT_IN_MEMORY);
   web::FakeWebState* mock_tab_b = InsertFakeWebState(kURL, NOT_IN_MEMORY);
   web::FakeWebState* mock_tab_c = InsertFakeWebState(kURL, NOT_IN_MEMORY);
-  tab_usage_recorder_->RecordPrimaryBrowserChange(false, nullptr);
+  tab_usage_recorder_->RecordPrimaryBrowserChange(false);
 
   // Switch from A (incognito evicted) to B (incognito evicted).
   tab_usage_recorder_->RecordTabSwitched(mock_tab_a, mock_tab_b);
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn b/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn
index d2200a4c8..e9f4d20 100644
--- a/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn
+++ b/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn
@@ -47,7 +47,6 @@
     "//ios/chrome/browser/permissions:infobar_delegate",
     "//ios/chrome/browser/safe_browsing/tailored_security:infobar_delegates",
     "//ios/chrome/browser/ui/authentication",
-    "//ios/chrome/browser/ui/resources:password_key",
     "//ios/chrome/browser/ui/settings/sync/utils",
     "//ios/chrome/browser/web/",
     "//ios/web/public/permissions",
diff --git a/ios/chrome/browser/shared/ui/symbols/symbol_names.h b/ios/chrome/browser/shared/ui/symbols/symbol_names.h
index 04fde00..39d692a 100644
--- a/ios/chrome/browser/shared/ui/symbols/symbol_names.h
+++ b/ios/chrome/browser/shared/ui/symbols/symbol_names.h
@@ -154,6 +154,7 @@
 extern NSString* const kSquareOnSquareDashedSymbol;
 extern NSString* const kDocPlaintext;
 extern NSString* const kFlagSymbol;
+extern NSString* const kKeyboardSymbol;
 
 // Names of the default symbol being non-monochrome by default. When using them,
 // you probably want to set their color to monochrome.
diff --git a/ios/chrome/browser/shared/ui/symbols/symbol_names.mm b/ios/chrome/browser/shared/ui/symbols/symbol_names.mm
index e3e7dda..7977701 100644
--- a/ios/chrome/browser/shared/ui/symbols/symbol_names.mm
+++ b/ios/chrome/browser/shared/ui/symbols/symbol_names.mm
@@ -147,6 +147,7 @@
 NSString* const kSquareOnSquareDashedSymbol = @"square.on.square.dashed";
 NSString* const kDocPlaintext = @"doc.plaintext";
 NSString* const kFlagSymbol = @"flag";
+NSString* const kKeyboardSymbol = @"keyboard";
 
 // Names of the default symbol being non-monochrome by default. When using them,
 // you probably want to set their color to monochrome.
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
index 138bb80..930185f 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
+++ b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
@@ -125,10 +125,9 @@
     "//ios/chrome/browser/shared/model/application_context",
     "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/shared/ui/list_model:list_model",
+    "//ios/chrome/browser/shared/ui/symbols",
     "//ios/chrome/browser/shared/ui/table_view:styler",
     "//ios/chrome/browser/shared/ui/table_view:table_view",
-    "//ios/chrome/browser/ui/autofill/manual_fill/resources:mf_keyboard",
-    "//ios/chrome/browser/ui/resources:password_key",
     "//ios/chrome/browser/ui/settings/password:title_view",
     "//ios/chrome/common:button_config",
     "//ios/chrome/common:string_util",
@@ -136,8 +135,6 @@
     "//ios/chrome/common/ui/util",
     "//ios/third_party/material_components_ios",
     "//net:net",
-    "//third_party/material_design_icons:ic_credit_card",
-    "//third_party/material_design_icons:ic_place",
     "//ui/base:base",
   ]
   frameworks = [ "UIKit.framework" ]
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.mm
index 3a2e73e..47aceab 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.mm
@@ -7,6 +7,7 @@
 #import "base/ios/ios_util.h"
 #import "base/metrics/user_metrics.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
+#import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/common/button_configuration_util.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
@@ -48,6 +49,9 @@
 // iPad override for the icons' spacing.
 constexpr CGFloat ManualFillIconsIPadSpacing = 15;
 
+// Size of the symbols.
+constexpr CGFloat kSymbolSize = 18;
+
 // Color to use for the buttons while enabled.
 UIColor* IconActiveTintColor() {
   return [UIColor colorNamed:kToolbarButtonColor];
@@ -146,12 +150,19 @@
 // Helper to create a system button with the passed data and `self` as the
 // target. Such button has been configured to have some preset properties
 - (UIButton*)manualFillButtonWithAction:(SEL)selector
-                             ImageNamed:(NSString*)imageName
+                            symbolNamed:(NSString*)symbolName
+                          defaultSymbol:(BOOL)defaultSymbol
                 accessibilityIdentifier:(NSString*)accessibilityIdentifier
                      accessibilityLabel:(NSString*)accessibilityLabel {
   UIButton* button = [UIButton buttonWithType:UIButtonTypeSystem];
-  UIImage* image = [[UIImage imageNamed:imageName]
-      imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
+  UIImageConfiguration* imageConfiguration = [UIImageSymbolConfiguration
+      configurationWithPointSize:kSymbolSize
+                          weight:UIImageSymbolWeightBold
+                           scale:UIImageSymbolScaleMedium];
+  UIImage* image =
+      defaultSymbol
+          ? DefaultSymbolWithConfiguration(symbolName, imageConfiguration)
+          : CustomSymbolWithConfiguration(symbolName, imageConfiguration);
   [button setImage:image forState:UIControlStateNormal];
   button.tintColor = IconActiveTintColor();
   button.translatesAutoresizingMaskIntoConstraints = NO;
@@ -173,7 +184,8 @@
   if (ui::GetDeviceFormFactor() != ui::DEVICE_FORM_FACTOR_TABLET) {
     self.keyboardButton = [self
         manualFillButtonWithAction:@selector(keyboardButtonPressed)
-                        ImageNamed:@"mf_keyboard"
+                       symbolNamed:kKeyboardSymbol
+                     defaultSymbol:YES
            accessibilityIdentifier:manual_fill::
                                        AccessoryKeyboardAccessibilityIdentifier
                 accessibilityLabel:l10n_util::GetNSString(
@@ -185,7 +197,8 @@
 
   self.passwordButton = [self
       manualFillButtonWithAction:@selector(passwordButtonPressed:)
-                      ImageNamed:@"password_key"
+                     symbolNamed:kPasswordSymbol
+                   defaultSymbol:NO
          accessibilityIdentifier:manual_fill::
                                      AccessoryPasswordAccessibilityIdentifier
               accessibilityLabel:l10n_util::GetNSString(
@@ -213,7 +226,8 @@
 
   self.cardsButton =
       [self manualFillButtonWithAction:@selector(cardButtonPressed:)
-                            ImageNamed:@"ic_credit_card"
+                           symbolNamed:kCreditCardSymbol
+                         defaultSymbol:YES
                accessibilityIdentifier:
                    manual_fill::AccessoryCreditCardAccessibilityIdentifier
                     accessibilityLabel:
@@ -224,7 +238,8 @@
 
   self.accountButton = [self
       manualFillButtonWithAction:@selector(accountButtonPressed:)
-                      ImageNamed:@"ic_place"
+                     symbolNamed:kLocationSymbol
+                   defaultSymbol:NO
          accessibilityIdentifier:manual_fill::
                                      AccessoryAddressAccessibilityIdentifier
               accessibilityLabel:l10n_util::GetNSString(
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/resources/BUILD.gn b/ios/chrome/browser/ui/autofill/manual_fill/resources/BUILD.gn
deleted file mode 100644
index 5e9f2006..0000000
--- a/ios/chrome/browser/ui/autofill/manual_fill/resources/BUILD.gn
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2018 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/ios/asset_catalog.gni")
-
-imageset("mf_keyboard") {
-  sources = [
-    "mf_keyboard.imageset/Contents.json",
-    "mf_keyboard.imageset/mf_keyboard.png",
-    "mf_keyboard.imageset/mf_keyboard@2x.png",
-    "mf_keyboard.imageset/mf_keyboard@3x.png",
-  ]
-}
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/resources/mf_keyboard.imageset/Contents.json b/ios/chrome/browser/ui/autofill/manual_fill/resources/mf_keyboard.imageset/Contents.json
deleted file mode 100644
index 42f99fd..0000000
--- a/ios/chrome/browser/ui/autofill/manual_fill/resources/mf_keyboard.imageset/Contents.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-    "images": [
-        {
-            "idiom": "universal",
-            "scale": "1x",
-            "filename": "mf_keyboard.png"
-        },
-        {
-            "idiom": "universal",
-            "scale": "2x",
-            "filename": "mf_keyboard@2x.png"
-        },
-        {
-            "idiom": "universal",
-            "scale": "3x",
-            "filename": "mf_keyboard@3x.png"
-        }
-    ],
-    "info": {
-        "version": 1,
-        "author": "xcode"
-    }
-}
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/resources/mf_keyboard.imageset/mf_keyboard.png b/ios/chrome/browser/ui/autofill/manual_fill/resources/mf_keyboard.imageset/mf_keyboard.png
deleted file mode 100644
index 20be7858..0000000
--- a/ios/chrome/browser/ui/autofill/manual_fill/resources/mf_keyboard.imageset/mf_keyboard.png
+++ /dev/null
Binary files differ
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/resources/mf_keyboard.imageset/mf_keyboard@2x.png b/ios/chrome/browser/ui/autofill/manual_fill/resources/mf_keyboard.imageset/mf_keyboard@2x.png
deleted file mode 100644
index 45ef1be..0000000
--- a/ios/chrome/browser/ui/autofill/manual_fill/resources/mf_keyboard.imageset/mf_keyboard@2x.png
+++ /dev/null
Binary files differ
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/resources/mf_keyboard.imageset/mf_keyboard@3x.png b/ios/chrome/browser/ui/autofill/manual_fill/resources/mf_keyboard.imageset/mf_keyboard@3x.png
deleted file mode 100644
index c24e960..0000000
--- a/ios/chrome/browser/ui/autofill/manual_fill/resources/mf_keyboard.imageset/mf_keyboard@3x.png
+++ /dev/null
Binary files differ
diff --git a/ios/chrome/browser/ui/badges/BUILD.gn b/ios/chrome/browser/ui/badges/BUILD.gn
index 77f01f9c..95c3b88 100644
--- a/ios/chrome/browser/ui/badges/BUILD.gn
+++ b/ios/chrome/browser/ui/badges/BUILD.gn
@@ -79,7 +79,6 @@
     "//ios/chrome/browser/shared/ui/symbols",
     "//ios/chrome/browser/shared/ui/util",
     "//ios/chrome/browser/ui/fullscreen:ui",
-    "//ios/chrome/browser/ui/resources:password_key",
     "//ios/chrome/browser/web",
     "//ios/chrome/common:timing",
     "//ios/chrome/common/ui/colors",
diff --git a/ios/chrome/browser/ui/bookmarks/folder_editor/bookmarks_folder_editor_view_controller.mm b/ios/chrome/browser/ui/bookmarks/folder_editor/bookmarks_folder_editor_view_controller.mm
index 6e1d2ed8..e9e0216 100644
--- a/ios/chrome/browser/ui/bookmarks/folder_editor/bookmarks_folder_editor_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/folder_editor/bookmarks_folder_editor_view_controller.mm
@@ -20,6 +20,7 @@
 #import "components/bookmarks/common/bookmark_features.h"
 #import "components/bookmarks/common/bookmark_metrics.h"
 #import "ios/chrome/browser/bookmarks/bookmark_model_bridge_observer.h"
+#import "ios/chrome/browser/bookmarks/bookmarks_utils.h"
 #import "ios/chrome/browser/shared/coordinator/alert/action_sheet_coordinator.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
@@ -100,6 +101,9 @@
   __strong BookmarkParentFolderItem* _parentFolderItem;
   // The action sheet coordinator, if one is currently being shown.
   __strong ActionSheetCoordinator* _actionSheetCoordinator;
+  // Whether the user manually changed the folder. In which case it must be
+  // saved as last used folder on "save".
+  BOOL _manuallyChangedTheFolder;
 }
 
 #pragma mark - Initialization
@@ -218,6 +222,7 @@
 - (void)updateParentFolder:(const BookmarkNode*)parent {
   DCHECK(parent);
   _parentFolder = parent;
+  _manuallyChangedTheFolder = YES;
   [self updateParentFolderState];
 }
 
@@ -344,6 +349,12 @@
     _folder = modelForParentFolder->AddFolder(
         _parentFolder, _parentFolder->children().size(), folderTitle);
   }
+
+  if (_manuallyChangedTheFolder) {
+    bookmarks::StorageType type = bookmark_utils_ios::GetBookmarkModelType(
+        _folder, _profileBookmarkModel.get(), _accountBookmarkModel.get());
+    SetLastUsedBookmarkFolder(_browserState->GetPrefs(), _folder, type);
+  }
   [self.view endEditing:YES];
   [self.delegate bookmarksFolderEditor:self didFinishEditingFolder:_folder];
 }
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 89b68e9..6d07d26 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -678,8 +678,7 @@
 
 - (void)setPrimary:(BOOL)primary {
   if (_tabUsageRecorderBrowserAgent) {
-    _tabUsageRecorderBrowserAgent->RecordPrimaryBrowserChange(
-        primary, self.currentWebState);
+    _tabUsageRecorderBrowserAgent->RecordPrimaryBrowserChange(primary);
   }
   if (primary) {
     [self updateBroadcastState];
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_pedal_egtest.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_pedal_egtest.mm
index a2bc6bb0..1d4184b 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_pedal_egtest.mm
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_pedal_egtest.mm
@@ -213,6 +213,41 @@
   [ChromeEarlGrey closeCurrentTab];
 }
 
+// Tests that manage settings pedal is present and it opens the manage settings
+// page.
+- (void)testManageSettingsPedal {
+  // Focus omnibox from Web.
+  [ChromeEarlGrey loadURL:GURL("about:blank")];
+  [ChromeEarlGreyUI focusOmniboxAndType:@"pedalsettings"];
+
+  NSString* manageSettingsPedalString = l10n_util::GetNSString(
+      IDS_IOS_OMNIBOX_PEDAL_SUBTITLE_MANAGE_CHROME_SETTINGS);
+
+  // Matcher for the manage settings pedal suggestion.
+  id<GREYMatcher> manageSettingsPedal =
+      popupRowWithString(manageSettingsPedalString);
+
+  // Manage settings pedal should be visible.
+  [ChromeEarlGrey waitForUIElementToAppearWithMatcher:manageSettingsPedal];
+
+  // Tap on manage settings pedal.
+  [[EarlGrey selectElementWithMatcher:manageSettingsPedal]
+      performAction:grey_tap()];
+
+  // Manage settings page should be displayed.
+  [ChromeEarlGrey waitForUIElementToAppearWithMatcher:
+                      chrome_test_util::SettingsCollectionView()];
+
+  // Close the Manage settings page.
+  [[EarlGrey
+      selectElementWithMatcher:chrome_test_util::NavigationBarDoneButton()]
+      performAction:grey_tap()];
+  [ChromeEarlGrey waitForUIElementToDisappearWithMatcher:
+                      chrome_test_util::SettingsCollectionView()];
+
+  [ChromeEarlGrey closeCurrentTab];
+}
+
 // Tests that the dino pedal does not appear when the search suggestion is below
 // the top 3.
 - (void)testNoPedal {
diff --git a/ios/chrome/browser/ui/resources/BUILD.gn b/ios/chrome/browser/ui/resources/BUILD.gn
index 53db362..bdbe28fd 100644
--- a/ios/chrome/browser/ui/resources/BUILD.gn
+++ b/ios/chrome/browser/ui/resources/BUILD.gn
@@ -21,11 +21,3 @@
     "module_shadow.imageset/module_shadow@3x.png",
   ]
 }
-
-imageset("password_key") {
-  sources = [
-    "password_key.imageset/Contents.json",
-    "password_key.imageset/password_key@2x.png",
-    "password_key.imageset/password_key@3x.png",
-  ]
-}
diff --git a/ios/chrome/browser/ui/resources/password_key.imageset/Contents.json b/ios/chrome/browser/ui/resources/password_key.imageset/Contents.json
deleted file mode 100644
index fc983739..0000000
--- a/ios/chrome/browser/ui/resources/password_key.imageset/Contents.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-    "images": [
-        {
-            "idiom": "universal",
-            "scale": "2x",
-            "filename": "password_key@2x.png"
-        },
-        {
-            "idiom": "universal",
-            "scale": "3x",
-            "filename": "password_key@3x.png"
-        }
-    ],
-    "info": {
-        "version": 1,
-        "author": "xcode"
-    }
-}
diff --git a/ios/chrome/browser/ui/resources/password_key.imageset/password_key@2x.png b/ios/chrome/browser/ui/resources/password_key.imageset/password_key@2x.png
deleted file mode 100644
index a7cc0e5..0000000
--- a/ios/chrome/browser/ui/resources/password_key.imageset/password_key@2x.png
+++ /dev/null
Binary files differ
diff --git a/ios/chrome/browser/ui/resources/password_key.imageset/password_key@3x.png b/ios/chrome/browser/ui/resources/password_key.imageset/password_key@3x.png
deleted file mode 100644
index 77fb4a8b..0000000
--- a/ios/chrome/browser/ui/resources/password_key.imageset/password_key@3x.png
+++ /dev/null
Binary files differ
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn
index dd97824..2e67b92 100644
--- a/ios/chrome/browser/ui/settings/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -167,7 +167,6 @@
     "//ios/chrome/browser/ui/first_run:field_trial",
     "//ios/chrome/browser/ui/keyboard",
     "//ios/chrome/browser/ui/ntp:feature_flags",
-    "//ios/chrome/browser/ui/resources:password_key",
     "//ios/chrome/browser/ui/settings/autofill",
     "//ios/chrome/browser/ui/settings/bandwidth",
     "//ios/chrome/browser/ui/settings/cells",
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/BUILD.gn b/ios/chrome/browser/ui/settings/clear_browsing_data/BUILD.gn
index acf3cc4..ceae84f 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/BUILD.gn
@@ -58,7 +58,6 @@
     "//ios/chrome/browser/sync",
     "//ios/chrome/browser/ui/authentication",
     "//ios/chrome/browser/ui/keyboard",
-    "//ios/chrome/browser/ui/resources:password_key",
     "//ios/chrome/browser/ui/settings:settings_root",
     "//ios/chrome/browser/ui/settings/cells",
     "//ios/chrome/browser/url:constants",
diff --git a/ios/chrome/browser/ui/settings/safety_check/BUILD.gn b/ios/chrome/browser/ui/settings/safety_check/BUILD.gn
index abd7071..5ac860be 100644
--- a/ios/chrome/browser/ui/settings/safety_check/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/safety_check/BUILD.gn
@@ -80,7 +80,6 @@
     "//ios/chrome/browser/shared/ui/util",
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/sync",
-    "//ios/chrome/browser/ui/resources:password_key",
     "//ios/chrome/browser/ui/settings:settings_root",
     "//ios/chrome/browser/ui/settings/cells",
     "//ios/chrome/browser/ui/settings/cells:public",
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator_unittest.mm b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator_unittest.mm
index f07bf653..a1208f7 100644
--- a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator_unittest.mm
@@ -11,9 +11,11 @@
 #import "base/strings/string_util.h"
 #import "base/strings/sys_string_conversions.h"
 #import "base/strings/utf_string_conversions.h"
+#import "base/test/bind.h"
 #import "base/test/ios/wait_util.h"
 #import "base/test/scoped_feature_list.h"
 #import "components/keyed_service/core/service_access_type.h"
+#import "components/password_manager/core/browser/affiliation/fake_affiliation_service.h"
 #import "components/password_manager/core/browser/password_form.h"
 #import "components/password_manager/core/browser/password_manager_test_utils.h"
 #import "components/password_manager/core/browser/test_password_store.h"
@@ -24,6 +26,7 @@
 #import "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #import "components/strings/grit/components_strings.h"
 #import "components/sync_preferences/pref_service_mock_factory.h"
+#import "ios/chrome/browser/passwords/ios_chrome_affiliation_service_factory.h"
 #import "ios/chrome/browser/passwords/ios_chrome_password_check_manager.h"
 #import "ios/chrome/browser/passwords/ios_chrome_password_check_manager_factory.h"
 #import "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
@@ -126,6 +129,8 @@
 class SafetyCheckMediatorTest : public PlatformTest {
  public:
   SafetyCheckMediatorTest() {
+    feature_list_.InitAndEnableFeature(
+        password_manager::features::kPasswordsGrouping);
     TestChromeBrowserState::Builder test_cbs_builder;
     test_cbs_builder.AddTestingFactory(
         AuthenticationServiceFactory::GetInstance(),
@@ -138,6 +143,12 @@
         base::BindRepeating(
             &password_manager::BuildPasswordStore<web::BrowserState,
                                                   TestPasswordStore>));
+    test_cbs_builder.AddTestingFactory(
+        IOSChromeAffiliationServiceFactory::GetInstance(),
+        base::BindRepeating(base::BindLambdaForTesting([](web::BrowserState*) {
+          return std::unique_ptr<KeyedService>(
+              std::make_unique<password_manager::FakeAffiliationService>());
+        })));
     browser_state_ = test_cbs_builder.Build();
     AuthenticationServiceFactory::CreateAndInitializeForBrowserState(
         browser_state_.get(),
@@ -229,6 +240,7 @@
   }
 
  protected:
+  base::test::ScopedFeatureList feature_list_;
   web::WebTaskEnvironment environment_;
   IOSChromeScopedTestingLocalState scoped_testing_local_state_;
   std::unique_ptr<TestChromeBrowserState> browser_state_;
diff --git a/ios/chrome/test/data/omnibox/fake_suggestions_pedal.json b/ios/chrome/test/data/omnibox/fake_suggestions_pedal.json
index c603daaa..5a0bbc2 100644
--- a/ios/chrome/test/data/omnibox/fake_suggestions_pedal.json
+++ b/ios/chrome/test/data/omnibox/fake_suggestions_pedal.json
@@ -251,5 +251,46 @@
     "google:verbatimrelevance": 1300
   }
   ],
+  [
+  "pedalsettings",
+  [
+    "Manage Settings",
+    "nopedal1",
+    "nopedal2"
+  ],
+  [
+    "",
+    "",
+    "",
+  ],
+  [],
+  {
+    "google:clientdata": {
+      "bpc": false,
+      "tlw": false
+    },
+    "google:suggestdetail": [
+      {},
+      {},
+      {},
+    ],
+    "google:suggestrelevance": [
+      1253,
+      1252,
+      1251,
+    ],
+    "google:suggestsubtypes": [
+      [],
+      [],
+      [],
+    ],
+    "google:suggesttype": [
+      "QUERY",
+      "QUERY",
+      "QUERY",
+    ],
+    "google:verbatimrelevance": 1300
+  }
+  ],
 ]
 
diff --git a/services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h b/services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h
index 1695464..d72100f3 100644
--- a/services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h
+++ b/services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h
@@ -53,7 +53,7 @@
   base::OnceCallback<mojom::URLLoaderFactory*()> make_factory_ptr_;
 
   // Not owned.
-  raw_ptr<mojom::URLLoaderFactory> factory_ptr_ = nullptr;
+  raw_ptr<mojom::URLLoaderFactory, DanglingUntriaged> factory_ptr_ = nullptr;
 };
 
 }  // namespace network
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 1d9e72d..8469277 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -14773,6 +14773,44 @@
       }
     ]
   },
+  "Mac FYI Retina Release (Apple M2)": {
+    "isolated_scripts": [
+      {
+        "args": [
+          "noop_sleep",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "noop_sleep_tests",
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "hidpi": "1",
+              "mac_model": "Mac14,7",
+              "os": "Mac-13.3.1",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      }
+    ]
+  },
   "Mac FYI Retina Release (NVIDIA)": {
     "gtest_tests": [
       {
diff --git a/testing/buildbot/filters/linux-chromeos.browser_tests.require_lacros.filter b/testing/buildbot/filters/linux-chromeos.browser_tests.require_lacros.filter
index 42931fe..9948a383 100644
--- a/testing/buildbot/filters/linux-chromeos.browser_tests.require_lacros.filter
+++ b/testing/buildbot/filters/linux-chromeos.browser_tests.require_lacros.filter
@@ -6,6 +6,7 @@
 Autoclick*
 AshTtsApiTest*
 BrowserAppShelfControllerBrowserTest*
+ChromeAppKioskLacrosTest*
 ChromeVox*
 DemoAshRequiresLacrosTest*
 DesksTemplatesClientLacrosTest*
diff --git a/testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter b/testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter
index 1e9c9a55..b16c86f 100644
--- a/testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter
+++ b/testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter
@@ -30,8 +30,10 @@
 -SameSiteSubframe/DragAndDropBrowserTest.DragSameOriginImageBetweenFrames/0
 -SitePerProcessInteractiveBrowserTest.TabAndMouseFocusNavigation
 # The following tests are flaky.
+-CrossSiteSubframe/DragAndDropBrowserTest.CrossSiteDrag/0
 -MenuItemViewTestInsertWithSubmenu1.InsertItemWithSubmenu1
 -MenuViewDragAndDropTestNestedDrag.MenuViewDragAndDropNestedDrag
+-SameSiteSubframe/DragAndDropBrowserTest.CrossSiteDrag/0
 -TouchMode/InteractionTestUtilMouseUiTest.Drag/0
 
 # TODO(crbug.com/1195712): Implement the feature for Wayland.
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl
index a9a4b70..58ca5b4 100644
--- a/testing/buildbot/mixins.pyl
+++ b/testing/buildbot/mixins.pyl
@@ -904,6 +904,18 @@
       },
     },
   },
+  'mac_arm64_apple_m2_retina_gpu_stable': {
+    'swarming': {
+      'dimensions': {
+        'cpu': 'arm64',
+        'mac_model': 'Mac14,7',
+        'os': 'Mac-13.3.1',
+        'pool': 'chromium.tests.gpu',
+        'display_attached': '1',
+        'hidpi': '1',
+      },
+    },
+  },
   'mac_beta_arm64': {
     'swarming': {
       'dimensions': {
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 200b9309..de56650 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -4762,6 +4762,16 @@
           'gpu_telemetry_tests': 'gpu_fyi_mac_release_telemetry_tests',
         },
       },
+      'Mac FYI Retina Release (Apple M2)': {
+        'os_type': 'mac',
+        'browser_config': 'release',
+        'mixins': [
+          'mac_arm64_apple_m2_retina_gpu_stable',
+        ],
+        'test_suites': {
+          'gpu_telemetry_tests': 'gpu_noop_sleep_telemetry_test',
+        },
+      },
       'Mac FYI Retina Release (NVIDIA)': {
         'os_type': 'mac',
         'browser_config': 'release',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 64a1c5b6..98c08eb 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -7047,6 +7047,24 @@
             ]
         }
     ],
+    "IOSPinnedTabs": [
+        {
+            "platforms": [
+                "ios"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "params": {
+                        "overflow_param": "true"
+                    },
+                    "enable_features": [
+                        "EnablePinnedTabs"
+                    ]
+                }
+            ]
+        }
+    ],
     "IOSRestoreSessionFromCache": [
         {
             "platforms": [
@@ -7370,23 +7388,6 @@
             ]
         }
     ],
-    "InputIpcDirect": [
-        {
-            "platforms": [
-                "android",
-                "android_webview",
-                "linux"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "InputIpcDirect"
-                    ]
-                }
-            ]
-        }
-    ],
     "InstallAmbientBadgeEngagement": [
         {
             "platforms": [
@@ -10163,24 +10164,6 @@
             ]
         }
     ],
-    "PinnedTabsIOS": [
-        {
-            "platforms": [
-                "ios"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "params": {
-                        "overflow_param": "true"
-                    },
-                    "enable_features": [
-                        "EnablePinnedTabs"
-                    ]
-                }
-            ]
-        }
-    ],
     "PolicyLogsPageIOS": [
         {
             "platforms": [
diff --git a/third_party/blink/public/mojom/mediastream/media_stream.mojom b/third_party/blink/public/mojom/mediastream/media_stream.mojom
index e59b09e4..a54e27d8 100644
--- a/third_party/blink/public/mojom/mediastream/media_stream.mojom
+++ b/third_party/blink/public/mojom/mediastream/media_stream.mojom
@@ -44,7 +44,7 @@
   DISPLAY_VIDEO_CAPTURE_THIS_TAB,
 
   // Enables the capture of multiple display surfaces at the same time,
-  // generated by a getDisplayMediaSet() call.
+  // generated by a getAllScreensMedia() call.
   DISPLAY_VIDEO_CAPTURE_SET,
 
   // TODO(crbug.com/971228): Remove NUM_MEDIA_TYPES, as per the conventions
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
index 911d6bd..0a99f27 100644
--- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
+++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -1768,7 +1768,6 @@
   // is re-applied, it needs to remove clip from canvas and restore it after the
   // image is drawn.
   canvas->restoreToCount(1);
-  canvas->save();
 
   // TODO(jochin): Consider using ResourceProvider()->RestoreBackBuffer() here
   // to avoid all of this clip stack manipulation.
diff --git a/third_party/blink/renderer/core/html/forms/html_form_control_element.cc b/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
index 4e59be1e..c74670fc 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
@@ -370,11 +370,11 @@
     auto popover = popoverTargetElement();
     if (popover.popover) {
       auto& document = GetDocument();
-      DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
+      CHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
           document.GetExecutionContext()));
       auto trigger_support = SupportsPopoverTriggering();
-      DCHECK_NE(popover.action, PopoverTriggerAction::kNone);
-      DCHECK_NE(trigger_support, PopoverTriggerSupport::kNone);
+      CHECK_NE(popover.action, PopoverTriggerAction::kNone);
+      CHECK_NE(trigger_support, PopoverTriggerSupport::kNone);
       // Note that the order is: `mousedown` which runs popover light dismiss
       // code, then (for clicked elements) focus is set to the clicked
       // element, then |DOMActivate| runs here. Also note that the light
@@ -443,7 +443,7 @@
     }
     float hover_delay_seconds = computed_style->PopoverShowDelay();
     // If the value is infinite or NaN, don't queue a task at all.
-    DCHECK_GE(hover_delay_seconds, 0);
+    CHECK_GE(hover_delay_seconds, 0);
     if (!std::isfinite(hover_delay_seconds)) {
       return;
     }
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc
index 741a85f..5590d91b 100644
--- a/third_party/blink/renderer/core/html/html_element.cc
+++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -1259,8 +1259,8 @@
     case PopoverValueType::kNone:
       NOTREACHED();
   }
-  DCHECK_EQ(type, GetPopoverTypeFromAttributeValue(
-                      FastGetAttribute(html_names::kPopoverAttr)));
+  CHECK_EQ(type, GetPopoverTypeFromAttributeValue(
+                     FastGetAttribute(html_names::kPopoverAttr)));
   EnsurePopoverData()->setType(type);
 }
 
@@ -1295,7 +1295,7 @@
 
 // This should be true when `:popover-open` should match.
 bool HTMLElement::popoverOpen() const {
-  DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
+  CHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
       GetDocument().GetExecutionContext()));
   if (auto* popover_data = GetPopoverData())
     return popover_data->visibilityState() == PopoverVisibilityState::kShowing;
@@ -1306,10 +1306,10 @@
                                  ExceptionState* exception_state,
                                  bool include_event_handler_text,
                                  Document* expected_document) const {
-  DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
+  CHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
       GetDocument().GetExecutionContext()));
-  DCHECK_NE(action, PopoverTriggerAction::kNone);
-  DCHECK_NE(action, PopoverTriggerAction::kToggle);
+  CHECK_NE(action, PopoverTriggerAction::kNone);
+  CHECK_NE(action, PopoverTriggerAction::kToggle);
 
   auto maybe_throw_exception = [&exception_state, &include_event_handler_text](
                                    DOMExceptionCode code, const char* msg) {
@@ -1379,7 +1379,7 @@
 // We have to mark *all* invokers for the given popover dirty in the
 // ax tree, since they all should now have an updated expanded state.
 void MarkPopoverInvokersDirty(const HTMLElement& popover) {
-  DCHECK(popover.HasPopoverAttribute());
+  CHECK(popover.HasPopoverAttribute());
   auto& document = popover.GetDocument();
   AXObjectCache* cache = document.ExistingAXObjectCache();
   if (!cache) {
@@ -1396,7 +1396,7 @@
 }  // namespace
 
 void HTMLElement::togglePopover(ExceptionState& exception_state) {
-  DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
+  CHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
       GetDocument().GetExecutionContext()));
   if (popoverOpen()) {
     hidePopover(exception_state);
@@ -1406,7 +1406,7 @@
 }
 
 void HTMLElement::togglePopover(bool force, ExceptionState& exception_state) {
-  DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
+  CHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
       GetDocument().GetExecutionContext()));
   if (!force && popoverOpen()) {
     hidePopover(exception_state);
@@ -1422,7 +1422,7 @@
 void HTMLElement::ShowPopoverInternal(Element* invoker,
                                       ExceptionState* exception_state) {
   auto& original_document = GetDocument();
-  DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
+  CHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
       original_document.GetExecutionContext()));
 
   if (GetPopoverData()) {
@@ -1431,7 +1431,7 @@
   if (!IsPopoverReady(PopoverTriggerAction::kShow, exception_state,
                       /*include_event_handler_text=*/false,
                       &original_document)) {
-    DCHECK(exception_state)
+    CHECK(exception_state)
         << " Callers which aren't supposed to throw exceptions should not call "
            "ShowPopoverInternal when the Popover isn't in a valid state to be "
            "shown.";
@@ -1449,10 +1449,10 @@
   auto* event = ToggleEvent::Create(
       event_type_names::kBeforetoggle, Event::Cancelable::kYes,
       /*old_state*/ "closed", /*new_state*/ "open");
-  DCHECK(!event->bubbles());
-  DCHECK(event->cancelable());
-  DCHECK_EQ(event->oldState(), "closed");
-  DCHECK_EQ(event->newState(), "open");
+  CHECK(!event->bubbles());
+  CHECK(event->cancelable());
+  CHECK_EQ(event->oldState(), "closed");
+  CHECK_EQ(event->newState(), "open");
   event->SetTarget(this);
   if (DispatchEvent(*event) != DispatchEventResult::kNotCanceled)
     return;
@@ -1472,7 +1472,7 @@
       original_type == PopoverValueType::kHint) {
     const auto* ancestor = FindTopmostPopoverAncestor(*this);
     if (original_type == PopoverValueType::kHint) {
-      DCHECK(RuntimeEnabledFeatures::HTMLPopoverHintEnabled());
+      CHECK(RuntimeEnabledFeatures::HTMLPopoverHintEnabled());
       // If the new popover is popover=hint, hide other hints first.
       if (original_document.PopoverHintShowing()) {
         original_document.PopoverHintShowing()->HidePopoverInternal(
@@ -1518,10 +1518,10 @@
     // Add this popover to the popover stack.
     if (original_type == PopoverValueType::kAuto) {
       auto& stack = original_document.PopoverStack();
-      DCHECK(!stack.Contains(this));
+      CHECK(!stack.Contains(this));
       stack.push_back(this);
     } else {
-      DCHECK(RuntimeEnabledFeatures::HTMLPopoverHintEnabled());
+      CHECK(RuntimeEnabledFeatures::HTMLPopoverHintEnabled());
       original_document.SetPopoverHintShowing(this);
     }
   }
@@ -1571,17 +1571,17 @@
   after_event = ToggleEvent::Create(event_type_names::kToggle,
                                     Event::Cancelable::kNo, old_state,
                                     /*new_state*/ "open");
-  DCHECK_EQ(after_event->newState(), "open");
-  DCHECK_EQ(after_event->oldState(), old_state);
-  DCHECK(!after_event->bubbles());
-  DCHECK(!after_event->cancelable());
+  CHECK_EQ(after_event->newState(), "open");
+  CHECK_EQ(after_event->oldState(), old_state);
+  CHECK(!after_event->bubbles());
+  CHECK(!after_event->cancelable());
   after_event->SetTarget(this);
   GetPopoverData()->setPendingToggleEventTask(PostCancellableTask(
       *original_document.GetTaskRunner(TaskType::kDOMManipulation), FROM_HERE,
       WTF::BindOnce(
           [](HTMLElement* element, ToggleEvent* event) {
-            DCHECK(element);
-            DCHECK(event);
+            CHECK(element);
+            CHECK(event);
             element->DispatchEvent(*event);
           },
           WrapPersistent(this), WrapPersistent(after_event))));
@@ -1598,11 +1598,11 @@
     HidePopoverFocusBehavior focus_behavior,
     HidePopoverTransitionBehavior transition_behavior,
     HidePopoverIndependence popover_independence) {
-  DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
+  CHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
       document.GetExecutionContext()));
-  DCHECK(!endpoint || endpoint->HasPopoverAttribute());
-  DCHECK(endpoint ||
-         popover_independence == HidePopoverIndependence::kHideUnrelated);
+  CHECK(!endpoint || endpoint->HasPopoverAttribute());
+  CHECK(endpoint ||
+        popover_independence == HidePopoverIndependence::kHideUnrelated);
   // We never throw exceptions from HideAllPopoversUntil, since it is always
   // used to close other popovers that are already showing.
   ExceptionState* exception_state = nullptr;
@@ -1619,7 +1619,7 @@
 
   auto& stack = document.PopoverStack();
   if (endpoint->PopoverType() == PopoverValueType::kHint) {
-    DCHECK(RuntimeEnabledFeatures::HTMLPopoverHintEnabled());
+    CHECK(RuntimeEnabledFeatures::HTMLPopoverHintEnabled());
     if (popover_independence == HidePopoverIndependence::kHideUnrelated) {
       if (document.PopoverHintShowing() &&
           document.PopoverHintShowing() != endpoint) {
@@ -1633,7 +1633,7 @@
       }
     }
   } else {
-    DCHECK_EQ(endpoint->PopoverType(), PopoverValueType::kAuto);
+    CHECK_EQ(endpoint->PopoverType(), PopoverValueType::kAuto);
 
     bool repeating_hide = false;
     do {
@@ -1667,7 +1667,7 @@
       }
       if (!last_to_hide && document.PopoverHintShowing() &&
           hint_ancestor == endpoint) {
-        DCHECK(RuntimeEnabledFeatures::HTMLPopoverHintEnabled());
+        CHECK(RuntimeEnabledFeatures::HTMLPopoverHintEnabled());
         // endpoint is the top of the popover stack, and there's a nested hint.
         document.PopoverHintShowing()->HidePopoverInternal(
             focus_behavior, transition_behavior, exception_state);
@@ -1676,7 +1676,7 @@
         // We never throw exceptions from HideAllPopoversUntil, since it is
         // always used to close other popovers that are already showing.
         if (stack.back() == hint_ancestor) {
-          DCHECK(RuntimeEnabledFeatures::HTMLPopoverHintEnabled());
+          CHECK(RuntimeEnabledFeatures::HTMLPopoverHintEnabled());
           document.PopoverHintShowing()->HidePopoverInternal(
               focus_behavior, transition_behavior, exception_state);
         }
@@ -1700,7 +1700,7 @@
 }
 
 void HTMLElement::hidePopover(ExceptionState& exception_state) {
-  DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
+  CHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
       GetDocument().GetExecutionContext()));
   HidePopoverInternal(
       HidePopoverFocusBehavior::kFocusPreviousElement,
@@ -1712,7 +1712,7 @@
     HidePopoverFocusBehavior focus_behavior,
     HidePopoverTransitionBehavior transition_behavior,
     ExceptionState* exception_state) {
-  DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
+  CHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
       GetDocument().GetExecutionContext()));
 
   auto& document = GetDocument();
@@ -1754,13 +1754,13 @@
     auto* event = ToggleEvent::Create(
         event_type_names::kBeforetoggle, Event::Cancelable::kNo,
         /*old_state*/ "open", /*new_state*/ "closed");
-    DCHECK(!event->bubbles());
-    DCHECK(!event->cancelable());
-    DCHECK_EQ(event->oldState(), "open");
-    DCHECK_EQ(event->newState(), "closed");
+    CHECK(!event->bubbles());
+    CHECK(!event->cancelable());
+    CHECK_EQ(event->oldState(), "open");
+    CHECK_EQ(event->newState(), "closed");
     event->SetTarget(this);
     auto result = DispatchEvent(*event);
-    DCHECK_EQ(result, DispatchEventResult::kNotCanceled);
+    CHECK_EQ(result, DispatchEventResult::kNotCanceled);
 
     // The 'beforetoggle' event handler could have changed this popover, e.g. by
     // changing its type, removing it from the document, or calling
@@ -1785,17 +1785,17 @@
     after_event = ToggleEvent::Create(event_type_names::kToggle,
                                       Event::Cancelable::kNo, old_state,
                                       /*new_state*/ "closed");
-    DCHECK_EQ(after_event->newState(), "closed");
-    DCHECK_EQ(after_event->oldState(), old_state);
-    DCHECK(!after_event->bubbles());
-    DCHECK(!after_event->cancelable());
+    CHECK_EQ(after_event->newState(), "closed");
+    CHECK_EQ(after_event->oldState(), old_state);
+    CHECK(!after_event->bubbles());
+    CHECK(!after_event->cancelable());
     after_event->SetTarget(this);
     GetPopoverData()->setPendingToggleEventTask(PostCancellableTask(
         *document.GetTaskRunner(TaskType::kDOMManipulation), FROM_HERE,
         WTF::BindOnce(
             [](HTMLElement* element, ToggleEvent* event) {
-              DCHECK(element);
-              DCHECK(event);
+              CHECK(element);
+              CHECK(event);
               element->DispatchEvent(*event);
             },
             WrapPersistent(this), WrapPersistent(after_event))));
@@ -1808,12 +1808,12 @@
   // Remove this popover from the stack.
   if (PopoverType() == PopoverValueType::kAuto) {
     auto& stack = document.PopoverStack();
-    DCHECK(!stack.empty());
-    DCHECK_EQ(stack.back(), this);
+    CHECK(!stack.empty());
+    CHECK_EQ(stack.back(), this);
     stack.pop_back();
   } else if (PopoverType() == PopoverValueType::kHint) {
-    DCHECK(RuntimeEnabledFeatures::HTMLPopoverHintEnabled());
-    DCHECK_EQ(document.TopmostPopoverOrHint(), this);
+    CHECK(RuntimeEnabledFeatures::HTMLPopoverHintEnabled());
+    CHECK_EQ(document.TopmostPopoverOrHint(), this);
     document.SetPopoverHintShowing(nullptr);
   }
 
@@ -1843,7 +1843,7 @@
 }
 
 void HTMLElement::SetPopoverFocusOnShow() {
-  DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
+  CHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
       GetDocument().GetExecutionContext()));
   // The layout must be updated here because we call Element::isFocusable,
   // which requires an up-to-date layout.
@@ -1963,10 +1963,10 @@
 // can *have* ancestors.
 const HTMLElement* HTMLElement::FindTopmostPopoverAncestor(
     HTMLElement& new_popover) {
-  DCHECK(new_popover.HasPopoverAttribute());
-  DCHECK_NE(new_popover.PopoverType(), PopoverValueType::kManual);
+  CHECK(new_popover.HasPopoverAttribute());
+  CHECK_NE(new_popover.PopoverType(), PopoverValueType::kManual);
   auto& document = new_popover.GetDocument();
-  DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
+  CHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
       document.GetExecutionContext()));
 
   // Build a map from each open popover to its position in the stack.
@@ -1982,11 +1982,8 @@
 
   const HTMLElement* topmost_popover_ancestor = nullptr;
   auto check_ancestor = [&topmost_popover_ancestor,
-                         &popover_positions](const Element* candidate) {
-    if (!candidate)
-      return;
-    auto* candidate_ancestor =
-        NearestOpenPopover(candidate, /*inclusive*/ true);
+                         &popover_positions](const Element* to_check) {
+    auto* candidate_ancestor = NearestOpenPopover(to_check, /*inclusive*/ true);
     if (!candidate_ancestor ||
         candidate_ancestor->PopoverType() != PopoverValueType::kAuto) {
       return;
@@ -1999,8 +1996,7 @@
   };
   // Add the three types of ancestor relationships to the map:
   // 1. DOM tree ancestor.
-  check_ancestor(NearestOpenPopover(
-      FlatTreeTraversal::ParentElement(new_popover), /*inclusive*/ true));
+  check_ancestor(FlatTreeTraversal::ParentElement(new_popover));
   // 2. Anchor attribute.
   check_ancestor(new_popover.anchorElement());
   // 3. Invoker to popover
@@ -2017,7 +2013,7 @@
 // stack) is returned.
 const HTMLElement* FindTopmostRelatedPopover(const Node& node, bool inclusive) {
   auto& document = node.GetDocument();
-  DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
+  CHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
       document.GetExecutionContext()));
   // Check if we're in an invoking element or a popover, and choose
   // the higher popover on the stack.
@@ -2039,7 +2035,7 @@
 // static
 void HTMLElement::HandlePopoverLightDismiss(const Event& event,
                                             const Node& target_node) {
-  DCHECK(event.isTrusted());
+  CHECK(event.isTrusted());
   auto& document = target_node.GetDocument();
   if (!RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
           document.GetExecutionContext())) {
@@ -2053,8 +2049,8 @@
   if (IsA<PointerEvent>(event)) {
     // PointerEventManager will call this function before actually dispatching
     // the event.
-    DCHECK(!event.HasEventPath());
-    DCHECK_EQ(Event::PhaseType::kNone, event.eventPhase());
+    CHECK(!event.HasEventPath());
+    CHECK_EQ(Event::PhaseType::kNone, event.eventPhase());
 
     if (event_type == event_type_names::kPointerdown) {
       document.SetPopoverPointerdownTarget(
@@ -2085,8 +2081,8 @@
   } else if (event_type == event_type_names::kKeydown) {
     const KeyboardEvent* key_event = DynamicTo<KeyboardEvent>(event);
     if (key_event && key_event->key() == "Escape") {
-      DCHECK(!event.GetEventPath().IsEmpty());
-      DCHECK_EQ(Event::PhaseType::kNone, event.eventPhase());
+      CHECK(!event.GetEventPath().IsEmpty());
+      CHECK_EQ(Event::PhaseType::kNone, event.eventPhase());
       // Escape key just pops the topmost popover=auto/hint off the stack.
       document.TopmostPopoverOrHint()->HidePopoverInternal(
           HidePopoverFocusBehavior::kFocusPreviousElement,
@@ -2097,10 +2093,10 @@
 }
 
 void HTMLElement::InvokePopover(Element* invoker) {
-  DCHECK(invoker);
-  DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
+  CHECK(invoker);
+  CHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
       GetDocument().GetExecutionContext()));
-  DCHECK(HasPopoverAttribute());
+  CHECK(HasPopoverAttribute());
   ShowPopoverInternal(invoker, /*exception_state=*/nullptr);
 }
 
@@ -2221,10 +2217,10 @@
 }
 
 void HTMLElement::SetOwnerSelectMenuElement(HTMLSelectMenuElement* element) {
-  DCHECK(RuntimeEnabledFeatures::HTMLSelectMenuElementEnabled());
-  DCHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
+  CHECK(RuntimeEnabledFeatures::HTMLSelectMenuElementEnabled());
+  CHECK(RuntimeEnabledFeatures::HTMLPopoverAttributeEnabled(
       GetDocument().GetExecutionContext()));
-  DCHECK(HasPopoverAttribute());
+  CHECK(HasPopoverAttribute());
   GetPopoverData()->setOwnerSelectMenuElement(element);
 }
 
diff --git a/third_party/blink/renderer/core/timing/performance_resource_timing.cc b/third_party/blink/renderer/core/timing/performance_resource_timing.cc
index 628450c..3eb6e2b 100644
--- a/third_party/blink/renderer/core/timing/performance_resource_timing.cc
+++ b/third_party/blink/renderer/core/timing/performance_resource_timing.cc
@@ -330,8 +330,10 @@
     return 0;
   }
 
-  base::TimeTicks response_start = info_->timing->first_early_hints_time;
-  if (response_start.is_null()) {
+  base::TimeTicks response_start = info_->timing->receive_headers_start;
+  if (response_start.is_null() ||
+      response_start ==
+          info_->timing->receive_non_informational_headers_start) {
     return 0;
   }
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index 431cf97..3819cef 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -7182,11 +7182,7 @@
   String string_builder = InternalRoleName(RoleValue()).EncodeForDebugging();
 
   if (IsDetached()) {
-    string_builder = string_builder + " (detached)";
-  }
-
-  if (AXObjectCache().HasBeenDisposed()) {
-    return string_builder + " (doc shutdown) #" + String::Number(AXObjectID());
+    return string_builder + " (detached)";
   }
 
   if (verbose) {
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
index df41fc6..c3164fe1 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -353,12 +353,11 @@
   if (!c)
     return;
   for (Member<CanvasRenderingContext2DState> curr_state : state_stack_) {
+    c->save();
     c->setMatrix(SkM44());
     curr_state->PlaybackClips(c);
     c->setMatrix(AffineTransformToSkM44(curr_state->GetTransform()));
-    c->save();
   }
-  c->restore();
   ValidateStateStackWithCanvas(c);
 }
 
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.cc b/third_party/blink/renderer/modules/mediastream/media_devices.cc
index fe34370..b447e18 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_devices.cc
@@ -80,8 +80,8 @@
 
   void OnSuccess(const MediaStreamVector& streams,
                  CaptureController* capture_controller) override {
-    if (media_type_ == UserMediaRequestType::kDisplayMediaSet) {
-      OnSuccessGetDisplayMediaSet(streams);
+    if (media_type_ == UserMediaRequestType::kAllScreensMedia) {
+      OnSuccessGetAllScreensMedia(streams);
       return;
     }
 
@@ -127,9 +127,9 @@
   }
 
  private:
-  void OnSuccessGetDisplayMediaSet(const MediaStreamVector& streams) {
+  void OnSuccessGetAllScreensMedia(const MediaStreamVector& streams) {
     DCHECK(!streams.empty());
-    DCHECK_EQ(UserMediaRequestType::kDisplayMediaSet, media_type_);
+    DCHECK_EQ(UserMediaRequestType::kAllScreensMedia, media_type_);
     resolver_->Resolve(streams);
   }
 
@@ -528,35 +528,10 @@
   constraints->setVideo(
       MakeGarbageCollected<V8UnionBooleanOrMediaTrackConstraints>(true));
   constraints->setAutoSelectAllScreens(true);
-  return SendUserMediaRequest(UserMediaRequestType::kDisplayMediaSet, resolver,
+  return SendUserMediaRequest(UserMediaRequestType::kAllScreensMedia, resolver,
                               constraints, exception_state);
 }
 
-ScriptPromise MediaDevices::getDisplayMediaSet(
-    ScriptState* script_state,
-    const DisplayMediaStreamOptions* options,
-    ExceptionState& exception_state) {
-  // This timeout of base::Seconds(6) is an initial value and based on the data
-  // in Media.MediaDevices.GetDisplayMediaSet.Latency, it should be iterated
-  // upon.
-  auto* resolver = MakeGarbageCollected<
-      ScriptPromiseResolverWithTracker<UserMediaRequestResult>>(
-      script_state, "Media.MediaDevices.GetDisplayMediaSet", base::Seconds(6));
-
-  ExecutionContext* const context = GetExecutionContext();
-  if (!context) {
-    resolver->RecordAndThrowDOMException(
-        exception_state, DOMExceptionCode::kInvalidStateError,
-        "No media device client available; is this a detached window?",
-        UserMediaRequestResult::kContextDestroyed);
-    return ScriptPromise();
-  }
-
-  return SendUserMediaRequest(UserMediaRequestType::kDisplayMediaSet, resolver,
-                              ToMediaStreamConstraints(options),
-                              exception_state);
-}
-
 ScriptPromise MediaDevices::getDisplayMedia(
     ScriptState* script_state,
     const DisplayMediaStreamOptions* options,
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.h b/third_party/blink/renderer/modules/mediastream/media_devices.h
index 8aca2511..cc06d76f 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices.h
+++ b/third_party/blink/renderer/modules/mediastream/media_devices.h
@@ -78,10 +78,6 @@
 
   ScriptPromise getAllScreensMedia(ScriptState*, ExceptionState&);
 
-  ScriptPromise getDisplayMediaSet(ScriptState*,
-                                   const DisplayMediaStreamOptions*,
-                                   ExceptionState&);
-
   ScriptPromise getDisplayMedia(ScriptState*,
                                 const DisplayMediaStreamOptions*,
                                 ExceptionState&);
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.idl b/third_party/blink/renderer/modules/mediastream/media_devices.idl
index 239f25c..94b86e8c 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices.idl
+++ b/third_party/blink/renderer/modules/mediastream/media_devices.idl
@@ -30,11 +30,6 @@
     getDisplayMedia(optional DisplayMediaStreamOptions constraints = {});
 
     [
-      RuntimeEnabled = GetDisplayMediaSet, CallWith = ScriptState, RaisesException
-    ] Promise<sequence<MediaStream>>
-    getDisplayMediaSet(optional DisplayMediaStreamOptions constraints = {});
-
-    [
       RuntimeEnabled = GetAllScreensMedia, CallWith = ScriptState, RaisesException
     ] Promise<sequence<MediaStream>>
     getAllScreensMedia();
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints.idl b/third_party/blink/renderer/modules/mediastream/media_stream_constraints.idl
index abb7710d..1e09839 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints.idl
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints.idl
@@ -39,7 +39,7 @@
     // https://wicg.github.io/prefer-current-tab/#prefer-current-tab
     boolean preferCurrentTab = false;
     [
-      RuntimeEnabled = GetDisplayMediaSetAutoSelectAllScreens
+      RuntimeEnabled = GetAllScreensMedia
     ] boolean autoSelectAllScreens = false;
 
     // https://w3c.github.io/mediacapture-screen-share/#dom-displaymediastreamoptions-controller
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc b/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc
index 0715b727..0861ab96 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc
@@ -117,7 +117,7 @@
     // time as the underlying media device is unplugged from the system.
     return;
   }
-  // OnDeviceChanged cannot only happen in combination with getDisplayMediaSet,
+  // OnDeviceChanged cannot only happen in combination with getAllScreensMedia,
   // which is the only API that handles multiple streams at once.
   DCHECK_EQ(1u, it->value.size());
 
@@ -197,7 +197,7 @@
     return;
   }
   // OnDeviceCaptureHandleChange cannot only happen in combination with
-  // getDisplayMediaSet, which is the only API that handles multiple streams
+  // getAllScreensMedia, which is the only API that handles multiple streams
   // at once.
   DCHECK_EQ(1u, it->value.size());
 
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_set.cc b/third_party/blink/renderer/modules/mediastream/media_stream_set.cc
index 92bf898..372b4557 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_set.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_set.cc
@@ -61,8 +61,8 @@
       media_streams_initialized_callback_(std::move(callback)) {
   DCHECK(IsMainThread());
 
-  if (request_type == UserMediaRequestType::kDisplayMediaSet) {
-    InitializeGetDisplayMediaSetStreams(context, stream_descriptors);
+  if (request_type == UserMediaRequestType::kAllScreensMedia) {
+    InitializeGetAllScreensMediaStreams(context, stream_descriptors);
     return;
   }
 
@@ -93,7 +93,7 @@
   ExecutionContextClient::Trace(visitor);
 }
 
-void MediaStreamSet::InitializeGetDisplayMediaSetStreams(
+void MediaStreamSet::InitializeGetAllScreensMediaStreams(
     ExecutionContext* context,
     const MediaStreamDescriptorVector& stream_descriptors) {
   DCHECK(IsMainThread());
@@ -103,7 +103,7 @@
 
   // TODO(crbug.com/1358949): Move the generation of the |ScreenDetails| object
   // next to the generation of the descriptors and store them as members to
-  // avoid race conditions. Further, match the getDisplayMediaSet API and the
+  // avoid race conditions. Further, match the getAllScreensMedia API and the
   // window placement API by unique IDs instead of assuming the same order.
   ScreenDetails* const screen_details =
       MakeGarbageCollected<ScreenDetails>(window);
@@ -140,7 +140,7 @@
 }
 
 // TODO(crbug.com/1300883): Clean up other streams if one stream capture
-// results in an error. This is only required for getDisplayMediaSet.
+// results in an error. This is only required for getAllScreensMedia.
 // Currently existing functionality generates only one stream which is not
 // affected by this change.
 void MediaStreamSet::OnMediaStreamInitialized(
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_set.h b/third_party/blink/renderer/modules/mediastream/media_stream_set.h
index e2cd896..4c802128 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_set.h
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_set.h
@@ -36,7 +36,7 @@
   void Trace(Visitor*) const override;
 
  private:
-  void InitializeGetDisplayMediaSetStreams(
+  void InitializeGetAllScreensMediaStreams(
       ExecutionContext* context,
       const MediaStreamDescriptorVector& stream_descriptors);
   void OnMediaStreamInitialized(MediaStream*);
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_set_test.cc b/third_party/blink/renderer/modules/mediastream/media_stream_set_test.cc
index e549d8f8..ac30b095 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_set_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_set_test.cc
@@ -78,9 +78,9 @@
 }
 
 // This test checks if |MediaStreamSet| calls the initialized callback if used
-// for getDisplayMediaSet with a single stream requested, i.e. one descriptor
+// for getAllScreensMedia with a single stream requested, i.e. one descriptor
 // with one video source passed in the constructor.
-TEST_F(MediaStreamSetTest, GetDisplayMediaSetSingleMediaStreamInitialized) {
+TEST_F(MediaStreamSetTest, GetAllScreensMediaSingleMediaStreamInitialized) {
   V8TestingScope v8_scope;
   MediaStreamComponentVector audio_component_vector;
   MediaStreamComponentVector video_component_vector = {
@@ -92,7 +92,7 @@
   base::RunLoop run_loop;
   media_stream_set_ = MakeGarbageCollected<MediaStreamSet>(
       v8_scope.GetExecutionContext(), descriptors,
-      UserMediaRequestType::kDisplayMediaSet,
+      UserMediaRequestType::kAllScreensMedia,
       base::BindLambdaForTesting([&run_loop](MediaStreamVector streams) {
         EXPECT_EQ(streams.size(), 1u);
         run_loop.Quit();
@@ -101,9 +101,9 @@
 }
 
 // This test checks if |MediaStreamSet| calls the initialized callback if used
-// for getDisplayMediaSet with a multiple streams requested, i.e.
+// for getAllScreensMedia with a multiple streams requested, i.e.
 // multiple descriptors with one video source each passed in the constructor.
-TEST_F(MediaStreamSetTest, GetDisplayMediaSetMultipleMediaStreamsInitialized) {
+TEST_F(MediaStreamSetTest, GetAllScreensMediaMultipleMediaStreamsInitialized) {
   V8TestingScope v8_scope;
   MediaStreamComponentVector audio_component_vector;
   MediaStreamComponentVector video_component_vector = {
@@ -116,7 +116,7 @@
   base::RunLoop run_loop;
   media_stream_set_ = MakeGarbageCollected<MediaStreamSet>(
       v8_scope.GetExecutionContext(), descriptors,
-      UserMediaRequestType::kDisplayMediaSet,
+      UserMediaRequestType::kAllScreensMedia,
       base::BindLambdaForTesting([&run_loop](MediaStreamVector streams) {
         EXPECT_EQ(streams.size(), 4u);
         run_loop.Quit();
@@ -125,15 +125,15 @@
 }
 
 // This test checks if |MediaStreamSet| calls the initialized callback if used
-// for getDisplayMediaSet with a no streams requested, i.e.
+// for getAllScreensMedia with a no streams requested, i.e.
 // an empty descriptors list.
-TEST_F(MediaStreamSetTest, GetDisplayMediaSetNoMediaStreamInitialized) {
+TEST_F(MediaStreamSetTest, GetAllScreensMediaNoMediaStreamInitialized) {
   V8TestingScope v8_scope;
   MediaStreamDescriptorVector descriptors;
   base::RunLoop run_loop;
   media_stream_set_ = MakeGarbageCollected<MediaStreamSet>(
       v8_scope.GetExecutionContext(), descriptors,
-      UserMediaRequestType::kDisplayMediaSet,
+      UserMediaRequestType::kAllScreensMedia,
       base::BindLambdaForTesting([&run_loop](MediaStreamVector streams) {
         EXPECT_TRUE(streams.empty());
         run_loop.Quit();
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_client.cc b/third_party/blink/renderer/modules/mediastream/user_media_client.cc
index 81ee1367..384a460 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_client.cc
+++ b/third_party/blink/renderer/modules/mediastream/user_media_client.cc
@@ -41,8 +41,8 @@
     case UserMediaRequestType::kDisplayMedia:
       api_name = RTCAPIName::kGetDisplayMedia;
       break;
-    case UserMediaRequestType::kDisplayMediaSet:
-      api_name = RTCAPIName::kGetDisplayMediaSet;
+    case UserMediaRequestType::kAllScreensMedia:
+      api_name = RTCAPIName::kGetAllScreensMedia;
       break;
   }
   UpdateWebRTCMethodCount(api_name);
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
index 096ccfd..11b935c 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
+++ b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
@@ -620,7 +620,7 @@
 
   TrackControls& audio_controls = stream_controls->audio;
   audio_controls.stream_type =
-      (request->MediaRequestType() == UserMediaRequestType::kDisplayMediaSet)
+      (request->MediaRequestType() == UserMediaRequestType::kAllScreensMedia)
           ? MediaStreamType::NO_SERVICE
           : request->AudioMediaStreamType();
 
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_request.cc b/third_party/blink/renderer/modules/mediastream/user_media_request.cc
index 72d5449d..34ef5a091 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_request.cc
+++ b/third_party/blink/renderer/modules/mediastream/user_media_request.cc
@@ -448,7 +448,7 @@
       }
     }
   } else if (media_type == UserMediaRequestType::kDisplayMedia ||
-             media_type == UserMediaRequestType::kDisplayMediaSet) {
+             media_type == UserMediaRequestType::kAllScreensMedia) {
     // https://w3c.github.io/mediacapture-screen-share/#mediadevices-additions
     // MediaDevices Additions
     // The user agent MUST reject audio-only requests.
@@ -462,7 +462,7 @@
     //   newly created TypeError.
     // 3. Let requestedMediaTypes be the set of media types in constraints with
     // either a dictionary value or a value of true.
-    if (media_type == UserMediaRequestType::kDisplayMediaSet) {
+    if (media_type == UserMediaRequestType::kAllScreensMedia) {
       if (!audio.IsNull()) {
         exception_state.ThrowTypeError("Audio requests are not supported");
         return nullptr;
@@ -640,7 +640,7 @@
   if (MediaRequestType() == UserMediaRequestType::kDisplayMedia) {
     return MediaStreamType::DISPLAY_AUDIO_CAPTURE;
   }
-  if (MediaRequestType() == UserMediaRequestType::kDisplayMediaSet) {
+  if (MediaRequestType() == UserMediaRequestType::kAllScreensMedia) {
     return MediaStreamType::NO_SERVICE;
   }
   DCHECK_EQ(UserMediaRequestType::kUserMedia, MediaRequestType());
@@ -674,7 +674,7 @@
                ? MediaStreamType::DISPLAY_VIDEO_CAPTURE_THIS_TAB
                : MediaStreamType::DISPLAY_VIDEO_CAPTURE;
   }
-  if (MediaRequestType() == UserMediaRequestType::kDisplayMediaSet) {
+  if (MediaRequestType() == UserMediaRequestType::kAllScreensMedia) {
     DCHECK(!should_prefer_current_tab());
     return MediaStreamType::DISPLAY_VIDEO_CAPTURE_SET;
   }
@@ -788,7 +788,7 @@
         PeerConnectionTracker::From(*window).TrackGetUserMediaSuccess(this,
                                                                       stream);
       } else if (media_type_ == UserMediaRequestType::kDisplayMedia ||
-                 media_type_ == UserMediaRequestType::kDisplayMediaSet) {
+                 media_type_ == UserMediaRequestType::kAllScreensMedia) {
         PeerConnectionTracker::From(*window).TrackGetDisplayMediaSuccess(
             this, stream);
       } else {
@@ -814,7 +814,7 @@
       PeerConnectionTracker::From(*window).TrackGetUserMediaFailure(
           this, "OverConstrainedError", message);
     } else if (media_type_ == UserMediaRequestType::kDisplayMedia ||
-               media_type_ == UserMediaRequestType::kDisplayMediaSet) {
+               media_type_ == UserMediaRequestType::kAllScreensMedia) {
       PeerConnectionTracker::From(*window).TrackGetDisplayMediaFailure(
           this, "OverConstrainedError", message);
     } else {
@@ -882,7 +882,7 @@
       PeerConnectionTracker::From(*window).TrackGetUserMediaFailure(
           this, DOMException::GetErrorName(exception_code), message);
     } else if (media_type_ == UserMediaRequestType::kDisplayMedia ||
-               media_type_ == UserMediaRequestType::kDisplayMediaSet) {
+               media_type_ == UserMediaRequestType::kAllScreensMedia) {
       PeerConnectionTracker::From(*window).TrackGetDisplayMediaFailure(
           this, DOMException::GetErrorName(exception_code), message);
     } else {
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_request.h b/third_party/blink/renderer/modules/mediastream/user_media_request.h
index 8bff462..6164a8b 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_request.h
+++ b/third_party/blink/renderer/modules/mediastream/user_media_request.h
@@ -50,7 +50,7 @@
 class TransferredMediaStreamTrack;
 class UserMediaClient;
 
-enum class UserMediaRequestType { kUserMedia, kDisplayMedia, kDisplayMediaSet };
+enum class UserMediaRequestType { kUserMedia, kDisplayMedia, kAllScreensMedia };
 
 enum class UserMediaRequestResult {
   kOk = 0,
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
index 460c2b8..5b5f2098 100644
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
@@ -636,10 +636,7 @@
         if (!member->is_defined() || member->name() == track_id_str) {
           continue;
         }
-        // Non-standardized / provisional stats which are not exposed
-        // to Javascript are postfixed with an asterisk.
-        std::string postfix = member->is_standardized() ? "" : "*";
-        name_value_pairs.Append(member->name() + postfix);
+        name_value_pairs.Append(member->name());
         name_value_pairs.Append(MemberToValue(*member));
       }
       stats_subdictionary.Set("values", std::move(name_value_pairs));
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
index 8c90ac8..33cbca6 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
@@ -1036,12 +1036,14 @@
                                                    &release_callback2));
   EXPECT_FALSE(release_callback2);
 }
+
 class CustomFakeCanvasResourceHost : public FakeCanvasResourceHost {
  public:
   explicit CustomFakeCanvasResourceHost(const gfx::Size& size)
       : FakeCanvasResourceHost(size) {}
   void RestoreCanvasMatrixClipStack(cc::PaintCanvas* canvas) const override {
-    // Alter canvas' matrix to emulate a restore
+    // Restore the canvas stack to hold a simple matrix transform.
+    canvas->save();
     canvas->translate(5, 0);
   }
 };
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_host.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_host.cc
index f635b9a..bc8962d0 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_resource_host.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_resource_host.cc
@@ -42,7 +42,6 @@
 }
 
 void CanvasResourceHost::InitializeForRecording(cc::PaintCanvas* canvas) {
-  canvas->save();
   RestoreCanvasMatrixClipStack(canvas);
 }
 
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_api_name.h b/third_party/blink/renderer/platform/peerconnection/rtc_api_name.h
index 498e221..d16a1817 100644
--- a/third_party/blink/renderer/platform/peerconnection/rtc_api_name.h
+++ b/third_party/blink/renderer/platform/peerconnection/rtc_api_name.h
@@ -21,7 +21,8 @@
   kVideoCaptureStream,
   kGetDisplayMedia,
   kGetCurrentBrowsingContextMedia,  // Deprecated.
-  kGetDisplayMediaSet,
+  kGetDisplayMediaSet,              // Deprecated.
+  kGetAllScreensMedia,
   kInvalidName
 };
 
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 317117f2..7dba4f53 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1868,26 +1868,6 @@
       status: "experimental",
     },
     {
-      // Enables the getDisplayMediaSet API for multi surface capture.
-      name: "GetDisplayMediaSet",
-      depends_on: ["GetDisplayMedia"],
-      public: true,
-      status: "test",
-      base_feature: "none",
-    },
-    {
-      name: "GetDisplayMediaSetAutoSelectAllScreens",
-      depends_on: ["GetDisplayMediaSet"],
-      public: true,
-      status: {
-        "ChromeOS_Ash": "test",
-        "ChromeOS_Lacros": "test",
-        "Linux": "test",
-        "default": "",
-      },
-      base_feature: "none",
-    },
-    {
       name: "GroupEffect",
       status: "test",
       base_feature: "none",
@@ -2832,7 +2812,7 @@
       // User-Agent string.
       name: "ReduceUserAgentAndroidVersionDeviceModel",
       depends_on: ["ReduceUserAgentMinorVersion"],
-      status: {"Android": "experimental"},
+      status: {"Android": "stable"},
     },
     // If enabled, the minor version of the User-Agent string will be reduced.
     // This User-Agent Reduction feature has been enabled starting from M101,
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_uploader.py b/third_party/blink/tools/blinkpy/w3c/wpt_uploader.py
index 104b5d0..b2e5316 100644
--- a/third_party/blink/tools/blinkpy/w3c/wpt_uploader.py
+++ b/third_party/blink/tools/blinkpy/w3c/wpt_uploader.py
@@ -147,6 +147,7 @@
         url = "https://%s/api/results/upload" % fqdn
 
         with open(path_to_report, 'rb') as fp:
+            params = {'labels': 'master'}
             files = {'result_file': fp}
             if self._dry_run:
                 _log.info("Dry run, no report uploaded.")
@@ -154,7 +155,7 @@
             session = requests.Session()
             password = self.get_password()
             session.auth = (username, password)
-            res = session.post(url=url, files=files)
+            res = session.post(url=url, params=params, files=files)
             if res.status_code == 200:
                 _log.info("Successfully uploaded wpt report with response: " + res.text.strip())
                 report_id = res.text.split()[1]
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests
index 26bd2a2..e24753d 100644
--- a/third_party/blink/web_tests/SlowTests
+++ b/third_party/blink/web_tests/SlowTests
@@ -1532,7 +1532,6 @@
 
 crbug.com/1376679 [ Mac12 Release ] virtual/threaded/external/wpt/scroll-animations/css/scroll-timeline-dynamic.tentative.html [ Slow ]
 
-crbug.com/1366717 http/tests/inspector-protocol/storage/indexed-db-storage-key-track-untrack.js [ Slow ]
 crbug.com/1366717 http/tests/inspector-protocol/storage/indexed-db-set-items-by-storage-key.js [ Slow ]
 
 crbug.com/1412278 http/tests/inspector-protocol/issues/third-party-cookie-blocking-first-party-set-enabled.js [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 68e1f48..f0a7cc6 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -5930,9 +5930,6 @@
 crbug.com/1360691 [ Debug Linux ] fast/canvas/disconnected-canvas-lost-gpu-context.html [ Failure ]
 
 
-# Investigate timeouts on bots
-crbug.com/1366717 http/tests/inspector-protocol/storage/indexed-db-storage-key-track-untrack.js [ Failure Pass Timeout ]
-
 crbug.com/1367113 fast/dom/shadow/event-path-load.html [ Crash Failure Pass Timeout ]
 crbug.com/1367113 http/tests/security/cors-check-for-cached-image.html [ Crash Failure Pass Timeout ]
 crbug.com/1367113 paint/images/animated-gif-last-frame-crash.html [ Crash Failure Pass Timeout ]
diff --git a/third_party/blink/web_tests/external/wpt/fullscreen/api/fullscreen-reordering.html b/third_party/blink/web_tests/external/wpt/fullscreen/api/fullscreen-reordering.html
new file mode 100644
index 0000000..1a286c3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fullscreen/api/fullscreen-reordering.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<title>Re-requesting fullscreen doesn't fail but doesn't change order</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="../../html/semantics/popovers/resources/popover-utils.js"></script>
+
+<div class="elements">
+  <div id="A">Element A</div>
+  <div id="B">Element B</div>
+</div>
+
+<style>
+  .elements>div {
+    width:200px;
+    height:200px;
+  }
+  #A { background: blue; }
+  #B { background: green; }
+</style>
+
+<script>
+promise_test(async (t) => {
+  t.add_cleanup(async () => {
+    while (document.fullscreenElement)
+      await document.exitFullscreen();
+  });
+  document.onfullscreenerror = () => assert_unreached('fullscreenerror should not happen');
+  const A = document.getElementById('A');
+  const B = document.getElementById('B');
+  assert_true(!isTopLayer(A) && !isTopLayer(B));
+  await blessTopLayer(document.body);
+  await A.requestFullscreen();
+  assert_equals(document.fullscreenElement,A,'first A request');
+  assert_true(isTopLayer(A),'A top layer');
+  await blessTopLayer(A);
+  try {
+    await B.requestFullscreen();
+  } catch (error) {
+    assert_unreached('The second call to requestFullscreen rejected - it should be possible to put siblings into fullscreen together');
+  }
+  assert_equals(document.fullscreenElement,B,'B request');
+  assert_true(isTopLayer(B),'B top layer');
+  assert_true(isTopLayer(A),'A still top layer');
+  await blessTopLayer(B);
+  await A.requestFullscreen();
+  assert_true(isTopLayer(A),'A is still top layer');
+  assert_true(isTopLayer(B),'B is still top layer');
+  assert_equals(document.fullscreenElement,A,'A is moved back to the top of the top layer stack');
+  assert_equals(document.elementFromPoint(10,10),A,'A should be topmost');
+
+  await document.exitFullscreen();
+  assert_equals(document.fullscreenElement,B,'B goes back to being the fullscreen element');
+  assert_true(isTopLayer(B),'B is still top layer');
+  assert_false(isTopLayer(A),'A is no longer top layer');
+  await document.exitFullscreen();
+  assert_equals(document.fullscreenElement,null,'Both closed');
+  assert_false(isTopLayer(A),'A is no longer top layer');
+  assert_false(isTopLayer(B),'B is no longer top layer');
+}, 'Requesting fullscreen on A, then B, then A');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-compositing-change.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-compositing-change.html
index 592720a8..658c2ad 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-compositing-change.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-compositing-change.html
@@ -2,6 +2,7 @@
 <html class="reftest-wait">
 <title>Composited images correctly re-raster when the image and bounds change</title>
 <meta charset="utf-8">
+<meta name=fuzzy content="maxDifference=150;totalPixels=296">
 <link rel="match" href="image-compositing-change-ref.html"/>
 <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-img-element">
 <style>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-compositing-change.html.ini b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-compositing-change.html.ini
deleted file mode 100644
index 30b696b..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-compositing-change.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[image-compositing-change.html]
-  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/popovers/resources/popover-utils.js b/third_party/blink/web_tests/external/wpt/html/semantics/popovers/resources/popover-utils.js
index 39de6aa9..aa69b7d4 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/popovers/resources/popover-utils.js
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/popovers/resources/popover-utils.js
@@ -47,6 +47,22 @@
 function isElementVisible(el) {
   return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
 }
+function isTopLayer(el) {
+  // A bit of a hack. Just test a few properties of the ::backdrop pseudo
+  // element that change when in the top layer.
+  const properties = ['right','background'];
+  const testEl = document.createElement('div');
+  document.body.appendChild(testEl);
+  const computedStyle = getComputedStyle(testEl, '::backdrop');
+  const nonTopLayerValues = properties.map(p => computedStyle[p]);
+  testEl.remove();
+  for(let i=0;i<properties.length;++i) {
+    if (getComputedStyle(el,'::backdrop')[properties[i]] !== nonTopLayerValues[i]) {
+      return true;
+    }
+  }
+  return false;
+}
 async function finishAnimations(popover) {
   popover.getAnimations({subtree: true}).forEach(animation => animation.finish());
   await waitForRender();
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/interim-response-times.h2.html b/third_party/blink/web_tests/external/wpt/resource-timing/interim-response-times.h2.html
index 850ee7cb..4b1ca93f 100644
--- a/third_party/blink/web_tests/external/wpt/resource-timing/interim-response-times.h2.html
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/interim-response-times.h2.html
@@ -2,6 +2,7 @@
 <html>
 <head>
 <meta charset="utf-8" />
+<meta name="timeout" content="long">
 <title>Resource Timing: PerformanceResourceTiming interim resource times</title>
 <link rel="author" title="Google" href="http://www.google.com/" />
 <script src="/common/utils.js"></script>
@@ -10,55 +11,64 @@
 <script src="/resources/testharnessreport.js"></script>
 <script>
   const {REMOTE_HOST} = get_host_info();
-  function interim_response_time_test({origin, tao, with103, expected}) {
+  function interim_response_time_test({origin, with100, with103}) {
     promise_test(async t => {
-      const delay = 100;
+      const delay = 500;
       const url = new URL('/resource-timing/resources/header-delay.h2.py',
-        origin == "same-origin" ?
+      origin == "same-origin" ?
           location.href :
           `${location.protocol}//${REMOTE_HOST}:${location.port}`);
       url.searchParams.set("delay", delay);
-      if (tao)
+      if (origin === "cross-origin-with-TAO")
         url.searchParams.set("tao", "*");
+      if (with100)
+        url.searchParams.set("with100", "true");
       if (with103)
         url.searchParams.set("with103", "true");
       const response = await fetch(url.toString(), {mode: "cors"});
       assert_equals(response.status, 200)
       await response.text();
       const [entry] = performance.getEntriesByName(url.toString());
-      if (expected) {
-        assert_greater_than(entry.firstInterimResponseStart,
-                            entry.requestStart + delay * 2,
-                            "firstInterimResponseStart");
-        assert_greater_than(entry.responseStart,
-                            entry.firstInterimResponseStart + delay,
-                            "responseStart");
-      } else {
+      if (origin === "cross-origin") {
         assert_equals(entry.firstInterimResponseStart, 0);
+        return;
+      }
+      let total_delay = entry.requestStart;
+      if (with100) {
+        total_delay += delay;
+        assert_greater_than(entry.firstInterimResponseStart,
+        total_delay,
+                            "firstInterimResponseStart > 100 response");
       }
 
-      assert_equals(entry.toJSON().firstInterimResponseStart,
-                    entry.firstInterimResponseStart);
+      if (with103) {
+        total_delay += delay;
+        if (with100) {
+          assert_less_than_equal(entry.firstInterimResponseStart,
+          total_delay,  "firstInterimResponseStart > 100 response");
+        } else {
+          assert_greater_than(entry.firstInterimResponseStart,
+          delay, "firstInterimResponseStart > 100 response");
+        }
+      }
+
+      total_delay += delay;
+      if (!with100 && !with103)
+        assert_equals(entry.firstInterimResponseStart, 0);
+
+      assert_greater_than(entry.responseStart, total_delay,
+                        "responseStart");
     }, `Fetch from ${origin} ${with103 ? "with" : "without"} early hints, ${
-        tao ? "with" : "without"} Timing-Allow-Origin should ${
-        expected ? "expose" : "not expose"} interim response times`);
+        with100 ? "with" : "without"} 100 response`);
   }
 
-  interim_response_time_test(
-    {origin: "same-origin", tao: false, with103: true, expected: true});
-
-  // TAO should protect firstInterimResponseStart
-  interim_response_time_test(
-    {origin: "cross-origin", tao: true, with103: true, expected: true});
-  interim_response_time_test(
-    {origin: "cross-origin", tao: false, with103: true, expected: false});
-
-  // Without early hints, firstInterimResponseStart should be 0 regalrdss of protections.
-  interim_response_time_test(
-    {origin: "same-origin", tao: false, with103: false, expected: false});
-  interim_response_time_test(
-    {origin: "cross-origin", tao: true, with103: false, expected: false});
-
+  for (const with103 of [true, false]) {
+    for (const with100 of [true, false]) {
+      for (origin of ['same-origin', 'cross-origin', 'cross-origin-with-TAO']) {
+        interim_response_time_test({with100, with103, origin});
+      }
+    }
+  }
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/interim-response-times.html b/third_party/blink/web_tests/external/wpt/resource-timing/interim-response-times.html
index b922590..a4d03f5 100644
--- a/third_party/blink/web_tests/external/wpt/resource-timing/interim-response-times.html
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/interim-response-times.html
@@ -2,6 +2,7 @@
 <html>
 <head>
 <meta charset="utf-8" />
+<meta name="timeout" content="long">
 <title>Resource Timing: PerformanceResourceTiming interim resource times</title>
 <link rel="author" title="Google" href="http://www.google.com/" />
 <script src="/common/utils.js"></script>
@@ -10,53 +11,62 @@
 <script src="/resources/testharnessreport.js"></script>
 <script>
   const {REMOTE_ORIGIN} = get_host_info();
-  function interim_response_time_test({origin, tao, with103, expected}) {
+  function interim_response_time_test({origin, with100, with103}) {
     promise_test(async t => {
-      const delay = 100;
+      const delay = 500;
       const url = new URL('/resource-timing/resources/header-delay.py',
         origin == "same-origin" ? location.href : REMOTE_ORIGIN);
       url.searchParams.set("delay", delay);
-      if (tao)
+      if (origin === "cross-origin-with-TAO")
         url.searchParams.set("tao", "*");
+      if (with100)
+        url.searchParams.set("with100", "true");
       if (with103)
         url.searchParams.set("with103", "true");
       const response = await fetch(url.toString(), {mode: "cors"});
       assert_equals(response.status, 200)
       await response.text();
       const [entry] = performance.getEntriesByName(url.toString());
-      if (expected) {
-        assert_greater_than(entry.firstInterimResponseStart,
-                            entry.requestStart + delay * 2,
-                            "firstInterimResponseStart");
-        assert_greater_than(entry.responseStart,
-                            entry.firstInterimResponseStart + delay,
-                            "responseStart");
-      } else {
+      if (origin === "cross-origin") {
         assert_equals(entry.firstInterimResponseStart, 0);
+        return;
+      }
+      let total_delay = entry.requestStart;
+      if (with100) {
+        total_delay += delay;
+        assert_greater_than(entry.firstInterimResponseStart,
+        total_delay,
+                            "firstInterimResponseStart > 100 response");
       }
 
-      assert_equals(entry.toJSON().firstInterimResponseStart,
-                    entry.firstInterimResponseStart);
+      if (with103) {
+        total_delay += delay;
+        if (with100) {
+          assert_less_than_equal(entry.firstInterimResponseStart,
+          total_delay,  "firstInterimResponseStart > 100 response");
+        } else {
+          assert_greater_than(entry.firstInterimResponseStart,
+          delay, "firstInterimResponseStart > 100 response");
+        }
+      }
+
+      total_delay += delay;
+      if (!with100 && !with103)
+        assert_equals(entry.firstInterimResponseStart, 0);
+
+      assert_greater_than(entry.responseStart, total_delay,
+                        "responseStart");
     }, `Fetch from ${origin} ${with103 ? "with" : "without"} early hints, ${
-        tao ? "with" : "without"} Timing-Allow-Origin should ${
-        expected ? "expose" : "not expose"} interim response times`);
+        with100 ? "with" : "without"} 100 response`);
   }
 
-  interim_response_time_test(
-    {origin: "same-origin", tao: false, with103: true, expected: true});
-
-  // TAO should protect firstInterimResponseStart
-  interim_response_time_test(
-    {origin: "cross-origin", tao: true, with103: true, expected: true});
-  interim_response_time_test(
-    {origin: "cross-origin", tao: false, with103: true, expected: false});
-
-  // Without early hints, firstInterimResponseStart should be 0 regalrdss of protections.
-  interim_response_time_test(
-    {origin: "same-origin", tao: false, with103: false, expected: false});
-  interim_response_time_test(
-    {origin: "cross-origin", tao: true, with103: false, expected: false});
-
+  for (const with103 of [true, false]) {
+    for (const with100 of [true, false]) {
+      for (origin of ['same-origin', 'cross-origin', 'cross-origin-with-TAO']) {
+        interim_response_time_test({with100, with103, origin});
+      }
+    }
+  }
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/resources/header-delay.h2.py b/third_party/blink/web_tests/external/wpt/resource-timing/resources/header-delay.h2.py
index be29e52..27b6fd5 100644
--- a/third_party/blink/web_tests/external/wpt/resource-timing/resources/header-delay.h2.py
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/resources/header-delay.h2.py
@@ -2,14 +2,16 @@
 
 def handle_headers(frame, request, response):
     delay = int(request.GET.first(b"delay")) / 1000
-    sleep(delay)
-    response.writer.write_raw_header_frame(headers=[(b":status", b"100")], end_headers=True)
-    sleep(delay)
+
+    if b"with100" in request.GET:
+        sleep(delay)
+        response.writer.write_raw_header_frame(headers=[(b":status", b"103")], end_headers=True)
 
     if b"with103" in request.GET:
-        response.writer.write_raw_header_frame(headers=[(b":status", b"103")], end_headers=True)
         sleep(delay)
+        response.writer.write_raw_header_frame(headers=[(b":status", b"103")], end_headers=True)
 
+    sleep(delay)
     response.status = 200
 
     if b"tao" in request.GET:
diff --git a/third_party/blink/web_tests/external/wpt/resource-timing/resources/header-delay.py b/third_party/blink/web_tests/external/wpt/resource-timing/resources/header-delay.py
index a47a63e..631f785 100644
--- a/third_party/blink/web_tests/external/wpt/resource-timing/resources/header-delay.py
+++ b/third_party/blink/web_tests/external/wpt/resource-timing/resources/header-delay.py
@@ -5,16 +5,18 @@
 
     # TODO: make this exported from ResponseWriter
     handler = response.writer._handler
-    sleep(delay)
-    handler.send_response(100)
-    handler.end_headers()
-    sleep(delay)
+    if b"with100" in request.GET:
+        sleep(delay)
+        handler.send_response(100)
+        handler.end_headers()
 
     if b"with103" in request.GET:
+        sleep(delay)
         handler.send_response(103)
         handler.send_header("Link", "<resources/empty.js>;rel=preload;as=script")
         handler.end_headers()
-        sleep(delay)
+
+    sleep(delay)
 
     handler.send_response(200)
 
diff --git a/third_party/blink/web_tests/fast/loader/slow-back-beforeunload-in-iframe.html b/third_party/blink/web_tests/fast/loader/slow-back-beforeunload-in-iframe.html
new file mode 100644
index 0000000..64c8c07
--- /dev/null
+++ b/third_party/blink/web_tests/fast/loader/slow-back-beforeunload-in-iframe.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<iframe id="i" src="resources/empty.html"></iframe>
+<script>
+promise_test(async t => {
+  // Wait for onload so push navigations don't get converted to replace.
+  await new Promise(r => window.onload = () => t.step_timeout(r, 0));
+
+  await navigation.navigate("#forward").finished;
+  i.contentWindow.navigation.navigate("empty.html?forward");
+  await new Promise(r => i.onload = r);
+
+  navigation.onnavigate = () => {
+    // Dummy so that the browser process knows there's a navigate event handler.
+  }
+  // Now navigate both windows back. The main frame will navigate
+  // same-document quickly, but the cross-document iframe navigation will
+  // stall on this slow beforeunload handler. The browser process shouldn't
+  // crash when the iframe cross-document navigation returns to the browser
+  // when beforeunload completes.
+  i.contentWindow.onbeforeunload = () => {
+    let end = performance.now() + 20;
+    let dummy = 0;
+    while (performance.now() < end) {
+      dummy++;
+    }
+  }
+  let main_frame_finished_promise = navigation.back().finished;
+
+  // Both windows should successfully navigate.
+  await new Promise(r => i.onload = r);
+  await main_frame_finished_promise;
+});
+</script>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/storage/indexed-db-storage-key-track-untrack.js b/third_party/blink/web_tests/http/tests/inspector-protocol/storage/indexed-db-storage-key-track-untrack.js
index bd09d25..72e9a98 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/storage/indexed-db-storage-key-track-untrack.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/storage/indexed-db-storage-key-track-untrack.js
@@ -50,6 +50,7 @@
         const objectStore = db.createObjectStore("test-store");
         objectStore.add("test-data", "test-key");
         resolve('key-value pair added successfully');
+        db.close();
       };
     })
   `);
@@ -84,6 +85,7 @@
         const store = db.transaction(['test-store'],'readwrite').objectStore('test-store');
         store.add("one-more-test-data", "one-more-test-key");
         resolve("one more key-value pair added");
+        db.close();
       };
     })
   `);
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index e06e4b06..d7c346f0 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -5803,7 +5803,6 @@
     method enumerateDevices
     method getAllScreensMedia
     method getDisplayMedia
-    method getDisplayMediaSet
     method getSupportedConstraints
     method getUserMedia
     method setCaptureHandleConfig
diff --git a/third_party/wayland-protocols/BUILD.gn b/third_party/wayland-protocols/BUILD.gn
index 77bf224..ec97e7b 100644
--- a/third_party/wayland-protocols/BUILD.gn
+++ b/third_party/wayland-protocols/BUILD.gn
@@ -116,6 +116,10 @@
   sources = [ "unstable/secure-output/secure-output-unstable-v1.xml" ]
 }
 
+wayland_protocol("single_pixel_buffer") {
+  sources = [ "src/staging/single-pixel-buffer/single-pixel-buffer-v1.xml" ]
+}
+
 wayland_protocol("stylus_protocol") {
   sources = [ "unstable/stylus/stylus-unstable-v2.xml" ]
 }
diff --git a/tools/cygprofile/symbol_extractor.py b/tools/cygprofile/symbol_extractor.py
index cdb74a4..048d4436 100644
--- a/tools/cygprofile/symbol_extractor.py
+++ b/tools/cygprofile/symbol_extractor.py
@@ -5,6 +5,7 @@
 """Utilities to get and manipulate symbols from a binary."""
 
 import collections
+import json
 import logging
 import os
 import re
@@ -26,139 +27,76 @@
                                                    'section'))
 
 
-# Regular expression to match lines printed by 'objdump -t -w'. An example of
-# such line looks like this:
-# 018db2de l     F .text  00000060              .hidden _ZN8SkBitmapC2ERKS_
-#
-# The regex intentionally allows matching more than valid inputs. This gives
-# more protection against potentially incorrectly silently ignoring unmatched
-# input lines. Instead a few assertions early in _FromObjdumpLine() check the
-# validity of a few parts matched as groups.
-_OBJDUMP_LINE_RE = re.compile(
-    r'''
-  # The offset of the function, as hex.
-  (?P<offset>^[0-9a-f]+)
-
-  # The space character.
-  [ ]
-
-  # The 7 groups of flag characters, one character each.
-  (
-    (?P<assert_scope>.)           # Global, local, unique local, etc.
-    (?P<assert_weak_or_strong>.)
-    (?P<assert_4spaces>.{4})      # Constructor, warning, indirect ref,
-                                  # debugger symbol.
-    (?P<symbol_type>.)            # Function, object, file or normal.
-  )
-
-  [ ]
-
-  # The section name should start with ".text", can be ".text.foo". With LLD,
-  # and especially LTO the traces of input sections are not preserved. Support
-  # ".text.foo" for a little longer time because it is easy.
-  (?P<section>.text[^0-9a-f]*)
-
-  (?P<assert_tab> \s+)
-
-  # The size of the symbol, as hex.
-  (?P<size>[0-9a-f]+)
-
-  [ ]+
-
-  # Hidden symbols should be treated as usual.
-  (.hidden [ ])?
-
-  # The symbol name.
-  (?P<name>.*)
-
-  $
-  ''', re.VERBOSE)
-
-
-def _FromObjdumpLine(line):
-  """Create a SymbolInfo by parsing a properly formatted objdump output line.
+def _SymbolInfosFromStream(input_file):
+  """Parses the output of llvm-readelf, and gets all the symbols from a binary.
 
   Args:
-    line: line from objdump
-
-  Returns:
-    An instance of SymbolInfo if the line represents a symbol, None otherwise.
-  """
-  m = _OBJDUMP_LINE_RE.match(line)
-  if not m:
-    return None
-
-  # A symbol can be (g)lobal, (l)ocal, or neither (a space). Per objdump's
-  # manpage, "A symbol can be neither local or global for a variety of reasons".
-  assert m.group('assert_scope') in set(['g', 'l', ' ']), line
-  assert m.group('assert_weak_or_strong') in set(['w', ' ']), line
-  assert m.group('assert_tab') == '\t', line
-  assert m.group('assert_4spaces') == ' ' * 4, line
-  name = m.group('name')
-  offset = int(m.group('offset'), 16)
-
-  # Output the label that contains the earliest offset. It is needed later for
-  # translating offsets from the profile dumps.
-  if name == START_OF_TEXT_SYMBOL:
-    return SymbolInfo(name=name, offset=offset, section='.text', size=0)
-
-  # Check symbol type for validity and ignore some types.
-  # From objdump manual page: The symbol is the name of a function (F) or a file
-  # (f) or an object (O) or just a normal symbol (a space). The 'normal' symbols
-  # seens so far has been function-local labels.
-  symbol_type = m.group('symbol_type')
-  if symbol_type == ' ':
-    # Ignore local goto labels. Unfortunately, v8 builtins (like 'Builtins_.*')
-    # are indistinguishable from labels of size 0 other than by name.
-    return None
-  # Guard against file symbols, since they are normally not seen in the
-  # binaries we parse.
-  assert symbol_type != 'f', line
-
-  # Extract the size from the ELF field. This value sometimes does not reflect
-  # the real size of the function. One reason for that is the '.size' directive
-  # in the assembler. As a result, a few functions in .S files have the size 0.
-  # They are not instrumented (yet), but maintaining their order in the
-  # orderfile may be important in some cases.
-  size = int(m.group('size'), 16)
-
-  # Forbid ARM mapping symbols and other unexpected symbol names, but allow $
-  # characters in a non-initial position, which can appear as a component of a
-  # mangled name, e.g. Clang can mangle a lambda function to:
-  # 02cd61e0 l     F .text  000000c0 _ZZL11get_globalsvENK3$_1clEv
-  # The equivalent objdump line from GCC is:
-  # 0325c58c l     F .text  000000d0 _ZZL11get_globalsvENKUlvE_clEv
-  #
-  # Also disallow .internal and .protected symbols (as well as other flags),
-  # those have not appeared in the binaries we parse. Rejecting these extra
-  # prefixes is done by disallowing spaces in symbol names.
-  assert re.match('^[a-zA-Z0-9_.][a-zA-Z0-9_.$]*$', name), name
-
-  return SymbolInfo(name=name, offset=offset, section=m.group('section'),
-                    size=size)
-
-
-def _SymbolInfosFromStream(objdump_lines):
-  """Parses the output of objdump, and get all the symbols from a binary.
-
-  Args:
-    objdump_lines: An iterable of lines
+    input_file: a .json file handle containing the readelf output.
 
   Returns:
     A list of SymbolInfo.
   """
+  # Load the JSON output
+  raw_symbols = json.load(input_file)
+  # The file is structured as a list containing dictionaries, one per input
+  # file.
+  assert len(raw_symbols) == 1
+  raw_symbols = raw_symbols[0]
+  # Next have two sections: FileSummary and Symbols
+  assert 'Symbols' in raw_symbols
+  raw_symbols = raw_symbols['Symbols']
+
   name_to_offsets = collections.defaultdict(list)
   symbol_infos = []
-  for line in objdump_lines:
-    symbol_info = _FromObjdumpLine(line.rstrip('\n'))
-    if symbol_info is not None:
-      # On ARM the LLD linker inserts pseudo-functions (thunks) that allow
-      # jumping distances farther than 16 MiB. Such thunks are known to often
-      # reside on multiple offsets, they are not instrumented and hence they do
-      # not reach the orderfiles. Exclude the thunk symbols from the warning.
-      if not symbol_info.name.startswith('__ThumbV7PILongThunk_'):
-        name_to_offsets[symbol_info.name].append(symbol_info.offset)
-      symbol_infos.append(symbol_info)
+
+  for symbol in raw_symbols:
+    symbol = symbol['Symbol']
+    name = symbol['Name']['Name']
+    offset = symbol['Value']
+    size = symbol['Size']
+    section = symbol['Section']['Name']
+    scope = symbol['Binding']['Name']
+    # Output the label that contains the earliest offset. It is needed later for
+    # translating offsets from the profile dumps.
+    if name == START_OF_TEXT_SYMBOL:
+      symbol_infos.append(
+          SymbolInfo(name=name, offset=offset, section='.text', size=0))
+      continue
+    # Check symbol type for validity and ignore some types.
+    symbol_type = symbol['Type']['Name']
+    if symbol_type == 'None':
+      # Ignore local goto labels. Unfortunately, v8 builtins (like
+      # 'Builtins_.*') are indistinguishable from labels of size 0 other than
+      # by name.
+      continue
+    if section != '.text':
+      # Ignore anything that's outside the primary .text section
+      continue
+    assert symbol_type in ['Object', 'Function', 'File', 'GNU_IFunc']
+    assert scope in ['Local', 'Global', 'Weak']
+    # Forbid ARM mapping symbols and other unexpected symbol names, but allow $
+    # characters in a non-initial position, which can appear as a component of a
+    # mangled name, e.g. Clang can mangle a lambda function to:
+    # 02cd61e0 l     F .text  000000c0 _ZZL11get_globalsvENK3$_1clEv
+    # The equivalent objdump line from GCC is:
+    # 0325c58c l     F .text  000000d0 _ZZL11get_globalsvENKUlvE_clEv
+    #
+    # Also disallow .internal and .protected symbols (as well as other flags),
+    # those have not appeared in the binaries we parse. Rejecting these extra
+    # prefixes is done by disallowing spaces in symbol names.
+    assert re.match('^[a-zA-Z0-9_.][a-zA-Z0-9_.$]*$', name), name
+
+    symbol_info = SymbolInfo(name=name,
+                             offset=offset,
+                             section=section,
+                             size=size)
+    # On ARM the LLD linker inserts pseudo-functions (thunks) that allow
+    # jumping distances farther than 16 MiB. Such thunks are known to often
+    # reside on multiple offsets, they are not instrumented and hence they do
+    # not reach the orderfiles. Exclude the thunk symbols from the warning.
+    if not symbol_info.name.startswith('__ThumbV7PILongThunk_'):
+      name_to_offsets[symbol_info.name].append(symbol_info.offset)
+    symbol_infos.append(symbol_info)
 
   # Outlined functions are known to be repeated often, so ignore them in the
   # repeated symbol count.
@@ -178,7 +116,7 @@
 
 
 def SymbolInfosFromBinary(binary_filename):
-  """Runs objdump to get all the symbols from a binary.
+  """Runs llvm-readelf to get all the symbols from a binary.
 
   Args:
     binary_filename: path to the binary.
@@ -186,20 +124,22 @@
   Returns:
     A list of SymbolInfo from the binary.
   """
-  command = [_TOOL_PREFIX + 'objdump', '-t', '-w', binary_filename]
+  command = [
+      _TOOL_PREFIX + 'readelf', '--syms', '--elf-output-style=JSON',
+      '--pretty-print', binary_filename
+  ]
   try:
     p = subprocess.Popen(command,
                          stdout=subprocess.PIPE,
                          universal_newlines=True)
   except OSError as error:
-    logging.error("Failed to execute the command: path=%s, binary_filename=%s",
+    logging.error('Failed to execute the command: path=%s, binary_filename=%s',
                   command[0], binary_filename)
     raise error
 
   try:
     return _SymbolInfosFromStream(p.stdout)
   finally:
-    p.stdout.close()
     p.wait()
 
 
diff --git a/tools/cygprofile/symbol_extractor_unittest.py b/tools/cygprofile/symbol_extractor_unittest.py
index abb350e..a69963e 100755
--- a/tools/cygprofile/symbol_extractor_unittest.py
+++ b/tools/cygprofile/symbol_extractor_unittest.py
@@ -3,6 +3,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import tempfile
 import unittest
 
 import symbol_extractor
@@ -11,161 +12,169 @@
 # The number of spaces that objdump prefixes each symbol with.
 SPACES = ' ' * 14
 
-
-class TestLlvmBitcodeSymbolExtractor(unittest.TestCase):
-
-  def testBasicParsing(self):
-    data = '''-------- T _ZN4base11GetFileSizeERKNS_8FilePathEPx
-aaaaaaaa W _ZNKSt3__19basic_iosIcNS_11char_traitsIcEEE5widenEc
--------- T _ZN4base13ContentsEqualERKNS_8FilePathES2_
----------------- T _SymbolWithA64BitAddress_
-00000000 W _ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv'''
-    lines = data.split('\n')
-
-    symbol_names = symbol_extractor._SymbolInfosFromLlvmNm(lines)
-    self.assertEqual(5, len(symbol_names))
-    self.assertListEqual(
-        ['_ZN4base11GetFileSizeERKNS_8FilePathEPx',
-         '_ZNKSt3__19basic_iosIcNS_11char_traitsIcEEE5widenEc',
-         '_ZN4base13ContentsEqualERKNS_8FilePathES2_',
-         '_SymbolWithA64BitAddress_',
-         '_ZNSt3__113basic_filebufIcNS_11char_traitsIcEEE11__read_modeEv'],
-        symbol_names)
-
-
-class TestSymbolInfo(unittest.TestCase):
-
-  def testIgnoresBlankLine(self):
-    symbol_info = symbol_extractor._FromObjdumpLine('')
-    self.assertIsNone(symbol_info)
-
-  def testIgnoresMalformedLine(self):
-    # This line is too short: only 6 flags.
-    line = ('00c1b228      F .text\t00000060' + SPACES + '_ZN20trace_event')
-    symbol_info = symbol_extractor._FromObjdumpLine(line)
-    self.assertIsNone(symbol_info)
-
-  def testWrongSymbolType(self):
-    # This line has unsupported 'f' as symbol type.
-    line = '00c1b228 l     f .text\t00000060' + SPACES + '_ZN20trace_event'
-    self.assertRaises(AssertionError, symbol_extractor._FromObjdumpLine, line)
-
-  def testAssertionErrorOnInvalidLines(self):
-    # This line has an invalid scope.
-    line = ('00c1b228 z     F .text\t00000060' + SPACES + '_ZN20trace_event')
-    self.assertRaises(AssertionError, symbol_extractor._FromObjdumpLine, line)
-    # This line has the symbol name with spaces in it.
-    line = ('00c1b228 l     F .text\t00000060' + SPACES +
-            '_ZN20trace_event too many')
-    self.assertRaises(AssertionError, symbol_extractor._FromObjdumpLine, line)
-    # This line has invalid characters in the symbol name.
-    line = ('00c1b228 l     F .text\t00000060' + SPACES + '_ZN20trace_?bad')
-    self.assertRaises(AssertionError, symbol_extractor._FromObjdumpLine, line)
-    # This line has an invalid character at the start of the symbol name.
-    line = ('00c1b228 l     F .text\t00000060' + SPACES + '$_ZN20trace_bad')
-    self.assertRaises(AssertionError, symbol_extractor._FromObjdumpLine, line)
-
-  def testSymbolTypeObject(self):
-    # Builds with ThinLTO produce symbols of type 'O'.
-    line = ('009faf60 l     O .text\t00000500' + SPACES + 'AES_Td')
-    symbol_info = symbol_extractor._FromObjdumpLine(line)
-    self.assertIsNotNone(symbol_info)
-    self.assertEquals(0x009faf60, symbol_info.offset)
-    self.assertEquals('.text', symbol_info.section)
-    self.assertEquals(0x500, symbol_info.size)
-    self.assertEquals('AES_Td', symbol_info.name)
-
-  def testSymbolFromLocalLabel(self):
-    line = ('00f64b80 l       .text\t00000000' + SPACES + 'Builtins_Abort')
-    symbol_info = symbol_extractor._FromObjdumpLine(line)
-    self.assertIsNone(symbol_info)
-
-  def testStartOfText(self):
-    line = ('00918000 l       .text\t00000000' + SPACES +
-            '.hidden linker_script_start_of_text')
-    symbol_info = symbol_extractor._FromObjdumpLine(line)
-    self.assertIsNotNone(symbol_info)
-    self.assertEquals(0x00918000, symbol_info.offset)
-    self.assertEquals('linker_script_start_of_text', symbol_info.name)
-
-  def testSymbolInfo(self):
-    line = ('00c1c05c l     F .text\t0000002c' + SPACES +
-            '_GLOBAL__sub_I_chrome_main_delegate.cc')
-    test_name = '_GLOBAL__sub_I_chrome_main_delegate.cc'
-    test_offset = 0x00c1c05c
-    test_size = 0x2c
-    test_section = '.text'
-    symbol_info = symbol_extractor._FromObjdumpLine(line)
-    self.assertIsNotNone(symbol_info)
-    self.assertEquals(test_offset, symbol_info.offset)
-    self.assertEquals(test_size, symbol_info.size)
-    self.assertEquals(test_name, symbol_info.name)
-    self.assertEquals(test_section, symbol_info.section)
-
-  def testHiddenSymbol(self):
-    line = ('00c1c05c l     F .text\t0000002c' + SPACES +
-            '.hidden _GLOBAL__sub_I_chrome_main_delegate.cc')
-    test_name = '_GLOBAL__sub_I_chrome_main_delegate.cc'
-    test_offset = 0x00c1c05c
-    test_size = 0x2c
-    test_section = '.text'
-    symbol_info = symbol_extractor._FromObjdumpLine(line)
-    self.assertIsNotNone(symbol_info)
-    self.assertEquals(test_offset, symbol_info.offset)
-    self.assertEquals(test_size, symbol_info.size)
-    self.assertEquals(test_name, symbol_info.name)
-    self.assertEquals(test_section, symbol_info.section)
-
-  def testDollarInSymbolName(self):
-    # A $ character elsewhere in the symbol name is fine.
-    # This is an example of a lambda function name from Clang.
-    line = ('00c1b228 l     F .text\t00000060' + SPACES +
-            '_ZZL11get_globalsvENK3$_1clEv')
-    symbol_info = symbol_extractor._FromObjdumpLine(line)
-    self.assertIsNotNone(symbol_info)
-    self.assertEquals(0xc1b228, symbol_info.offset)
-    self.assertEquals(0x60, symbol_info.size)
-    self.assertEquals('_ZZL11get_globalsvENK3$_1clEv', symbol_info.name)
-    self.assertEquals('.text', symbol_info.section)
-
-  def testOutlinedFunction(self):
-    # Test that an outlined function is reported normally. Also note that
-    # outlined functions are in 64 bit builds which have longer addresses.
-    line = ('00000000020fab4c l     F .text\t0000000000000014' + SPACES +
-            'OUTLINED_FUNCTION_4')
-    symbol_info = symbol_extractor._FromObjdumpLine(line)
-    self.assertIsNotNone(symbol_info)
-    self.assertEquals(0x20fab4c, symbol_info.offset)
-    self.assertEquals(0x14, symbol_info.size)
-    self.assertEquals('OUTLINED_FUNCTION_4', symbol_info.name)
-    self.assertEquals('.text', symbol_info.section)
-
-  def testNeitherLocalNorGlobalSymbol(self):
-    # This happens, see crbug.com/992884.
-    # Symbol which is neither local nor global.
-    line = '0287ae50  w    F .text\t000001e8              log2l'
-    symbol_info = symbol_extractor._FromObjdumpLine(line)
-    self.assertIsNotNone(symbol_info)
-    self.assertEquals(0x287ae50, symbol_info.offset)
-    self.assertEquals(0x1e8, symbol_info.size)
-    self.assertEquals('log2l', symbol_info.name)
-    self.assertEquals('.text', symbol_info.section)
-
 class TestSymbolInfosFromStream(unittest.TestCase):
 
+  SYMBOL_INFO_DUMP = r"""[
+  {
+    "FileSummary": {
+      "File": "./exe.unstripped/chrome_crashpad_handler",
+      "Format": "elf64-littleaarch64",
+      "Arch": "aarch64",
+      "AddressSize": "64bit",
+      "LoadName": "<Not found>"
+    },
+    "Symbols": [
+      {
+        "Symbol": {
+          "Name": {
+            "Name": "",
+            "Value": 0
+          },
+          "Value": 0,
+          "Size": 0,
+          "Binding": {
+            "Name": "Local",
+            "Value": 0
+          },
+          "Type": {
+            "Name": "None",
+            "Value": 0
+          },
+          "Other": {
+            "Value": 0,
+            "Flags": []
+          },
+          "Section": {
+            "Name": "Undefined",
+            "Value": 0
+          }
+        }
+      },
+      {
+        "Symbol": {
+          "Name": {
+            "Name": "first",
+            "Value": 42
+          },
+          "Value": 12697692,
+          "Size": 44,
+          "Binding": {
+            "Name": "Local",
+            "Value": 2
+          },
+          "Type": {
+            "Name": "Function",
+            "Value": 4
+          },
+          "Other": {
+            "Value": 0,
+            "Flags": []
+          },
+          "Section": {
+            "Name": ".text",
+            "Value": 65521
+          }
+        }
+      },
+      {
+        "Symbol": {
+          "Name": {
+            "Name": "second",
+            "Value": 42
+          },
+          "Value": 341,
+          "Size": 18,
+          "Binding": {
+            "Name": "Global",
+            "Value": 2
+          },
+          "Type": {
+            "Name": "Function",
+            "Value": 4
+          },
+          "Other": {
+            "Value": 0,
+            "Flags": []
+          },
+          "Section": {
+            "Name": ".text",
+            "Value": 65521
+          }
+        }
+      },
+      {
+        "Symbol": {
+          "Name": {
+            "Name": "third",
+            "Value": 53234419
+          },
+          "Value": 83614392,
+          "Size": 80,
+          "Binding": {
+            "Name": "Local",
+            "Value": 0
+          },
+          "Type": {
+            "Name": "GNU_IFunc",
+            "Value": 10
+          },
+          "Other": {
+            "Value": 2,
+            "Flags": [
+              {
+                "Name": "STV_HIDDEN",
+                "Value": 2
+              }
+            ]
+          },
+          "Section": {
+            "Name": ".text",
+            "Value": 16
+          }
+        }
+      },
+      {
+        "Symbol": {
+          "Name": {
+            "Name": "do_not_parse",
+            "Value": 1216
+          },
+          "Value": 39499768,
+          "Size": 80,
+          "Binding": {
+            "Name": "Local",
+            "Value": 0
+          },
+          "Type": {
+            "Name": "None",
+            "Value": 0
+          },
+          "Other": {
+            "Value": 0,
+            "Flags": []
+          },
+          "Section": {
+            "Name": ".text",
+            "Value": 16
+          }
+        }
+      }
+    ]
+  }
+]"""
+
   def testSymbolInfosFromStream(self):
-    lines = ['Garbage',
-             '',
-             '00c1c05c l     F .text\t0000002c' + SPACES + 'first',
-             ''
-             'more garbage',
-             '00155 g     F .text\t00000012' + SPACES + 'second']
-    symbol_infos = symbol_extractor._SymbolInfosFromStream(lines)
-    self.assertEquals(len(symbol_infos), 2)
-    first = symbol_extractor.SymbolInfo('first', 0x00c1c05c, 0x2c, '.text')
-    self.assertEquals(first, symbol_infos[0])
-    second = symbol_extractor.SymbolInfo('second', 0x00155, 0x12, '.text')
-    self.assertEquals(second, symbol_infos[1])
+    with tempfile.TemporaryFile(suffix='.json') as fp:
+      fp.write(self.SYMBOL_INFO_DUMP.encode('utf8'))
+      fp.seek(0)
+      symbol_infos = symbol_extractor._SymbolInfosFromStream(fp)
+      self.assertEquals(len(symbol_infos), 3)
+      first = symbol_extractor.SymbolInfo('first', 0x00c1c05c, 0x2c, '.text')
+      self.assertEquals(first, symbol_infos[0])
+      second = symbol_extractor.SymbolInfo('second', 0x00155, 0x12, '.text')
+      self.assertEquals(second, symbol_infos[1])
+      third = symbol_extractor.SymbolInfo('third', 0x4fbdab8, 0x50, '.text')
+      self.assertEquals(third, symbol_infos[2])
 
 
 class TestSymbolInfoMappings(unittest.TestCase):
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 81fb64b..1750f9d 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -923,7 +923,7 @@
 
     # Internal codesearch builders.
     'luci.infra-internal.codesearch': {
-      'codesearch-gen-chrome-internal-linux': 'codesearch_gen_chromium_bot',
+      'codesearch-gen-chrome-internal-linux': 'codesearch_gen_chromium_bot_reclient',
     },
 
     'official.chrome': {
@@ -1283,6 +1283,7 @@
       'gpu-fyi-try-mac-amd-retina-rel': 'gpu_fyi_tests_release_trybot_reclient',
       'gpu-fyi-try-mac-arm64-apple-m1-exp': 'gpu_fyi_tests_release_trybot_arm64_reclient',
       'gpu-fyi-try-mac-arm64-apple-m1-rel': 'gpu_fyi_tests_release_trybot_arm64_reclient',
+      'gpu-fyi-try-mac-arm64-apple-m2-retina-rel': 'gpu_fyi_tests_release_trybot_arm64_reclient',
       'gpu-fyi-try-mac-intel-asan': 'gpu_fyi_tests_release_trybot_asan_reclient',
       'gpu-fyi-try-mac-intel-dbg': 'gpu_fyi_tests_debug_trybot_reclient',
       'gpu-fyi-try-mac-intel-exp': 'gpu_fyi_tests_release_trybot_reclient',
@@ -2463,10 +2464,6 @@
       'codesearch_reclient', 'android_without_codecs', 'static',
     ],
 
-    'codesearch_gen_chromium_bot': [
-      'codesearch',
-    ],
-
     'codesearch_gen_chromium_bot_reclient': [
       'codesearch_reclient',
     ],
@@ -4016,13 +4013,6 @@
       'mixins': ['clang'],
     },
 
-    # Settings used by the codesearch builders to generate cross-references.
-    'codesearch': {
-      'gn_args': 'clang_use_chrome_plugins=false enable_kythe_annotations=true',
-      'mixins': ['goma', 'clang', 'shared', 'debug', 'minimal_symbols',
-                 'blink_enable_generated_code_formatting'],
-    },
-
     # Same as regular codesearch except ios does not allow component builds
     'codesearch_ios_reclient': {
       'gn_args': 'clang_use_chrome_plugins=false enable_kythe_annotations=true',
diff --git a/tools/mb/mb_config_expectations/luci.infra-internal.codesearch.json b/tools/mb/mb_config_expectations/luci.infra-internal.codesearch.json
index 4b6ee91b..e3fd964 100644
--- a/tools/mb/mb_config_expectations/luci.infra-internal.codesearch.json
+++ b/tools/mb/mb_config_expectations/luci.infra-internal.codesearch.json
@@ -8,7 +8,7 @@
       "is_component_build": true,
       "is_debug": true,
       "symbol_level": 1,
-      "use_goma": true
+      "use_remoteexec": true
     }
   }
 }
\ No newline at end of file
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.mac.json b/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
index cb37c742..15c4a6d 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
@@ -85,6 +85,19 @@
       "use_remoteexec": true
     }
   },
+  "gpu-fyi-try-mac-arm64-apple-m2-retina-rel": {
+    "gn_args": {
+      "dcheck_always_on": true,
+      "enable_nacl": false,
+      "ffmpeg_branding": "Chrome",
+      "is_component_build": false,
+      "is_debug": false,
+      "proprietary_codecs": true,
+      "symbol_level": 1,
+      "target_cpu": "arm64",
+      "use_remoteexec": true
+    }
+  },
   "gpu-fyi-try-mac-intel-asan": {
     "gn_args": {
       "dcheck_always_on": true,
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index d422369..97de090 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -37443,6 +37443,7 @@
       label="For ChromeReengagementNotification2 feature."/>
   <suffix name="ChromeReengagementNotification3"
       label="For ChromeReengagementNotification3 feature."/>
+  <suffix name="CompanionSidePanel" label="For companion side panel feature."/>
   <suffix name="ContextualPageActions_PriceTracking"
       label="For Contextual page actions price tracking feature."/>
   <suffix name="ContextualPageActions_PriceTrackingActionChip"
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 9fd474112..d49c9ee 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -16290,6 +16290,7 @@
   <int value="7" label="kDiskReadError"/>
   <int value="8" label="kDiskWriteError"/>
   <int value="9" label="kRootPartitionUnexpectedSize"/>
+  <int value="10" label="kMigrationNotAllowed"/>
 </enum>
 
 <enum name="ChromeOSSamlApiUsed">
@@ -88760,6 +88761,16 @@
   <int value="4" label="Blue"/>
 </enum>
 
+<enum name="ReadAnythingFontName">
+  <int value="0" label="Poppins"/>
+  <int value="1" label="Sans-serif"/>
+  <int value="2" label="Serif"/>
+  <int value="3" label="Comic Neue"/>
+  <int value="4" label="Lexend Deca"/>
+  <int value="5" label="EB Garamond"/>
+  <int value="6" label="STIX Two Text"/>
+</enum>
+
 <enum name="ReadAnythingLetterSpacing">
   <int value="0" label="Tight (Deprecated)"/>
   <int value="1" label="Standard"/>
@@ -88774,6 +88785,14 @@
   <int value="3" label="Very Loose"/>
 </enum>
 
+<enum name="ReadAnythingSettingsChange">
+  <int value="0" label="Font change"/>
+  <int value="1" label="Font size change"/>
+  <int value="2" label="Theme change"/>
+  <int value="3" label="Line height change"/>
+  <int value="4" label="Letter spacing change"/>
+</enum>
+
 <enum name="ReadDynamicRulesJSONStatus">
   <int value="0" label="kSuccess"/>
   <int value="1" label="kFileDoesNotExist"/>
@@ -90920,7 +90939,8 @@
   <int value="7" label="VideoCaptureStream"/>
   <int value="8" label="GetDisplayMedia"/>
   <int value="9" label="OBSOLETE_GetCurrentBrowsingContextMedia"/>
-  <int value="10" label="GetDisplayMediaSet"/>
+  <int value="10" label="OBSOLETE_GetDisplayMediaSet"/>
+  <int value="11" label="GetAllScreensMedia"/>
 </enum>
 
 <enum name="RTCQuicStreamReadIntoResult">
diff --git a/tools/metrics/histograms/metadata/accessibility/histograms.xml b/tools/metrics/histograms/metadata/accessibility/histograms.xml
index cc7ace8..8e53b897 100644
--- a/tools/metrics/histograms/metadata/accessibility/histograms.xml
+++ b/tools/metrics/histograms/metadata/accessibility/histograms.xml
@@ -1752,6 +1752,15 @@
   </summary>
 </histogram>
 
+<histogram name="Accessibility.ReadAnything.FontName"
+    enum="ReadAnythingFontName" expires_after="2023-11-30">
+  <owner>abigailbklein@google.com</owner>
+  <owner>chrome-a11y-core@google.com</owner>
+  <summary>
+    Records the user-chosen font name for the Read Anything panel.
+  </summary>
+</histogram>
+
 <histogram name="Accessibility.ReadAnything.FontScale" units="em"
     expires_after="2023-11-30">
   <owner>abigailbklein@google.com</owner>
@@ -1779,6 +1788,16 @@
   </summary>
 </histogram>
 
+<histogram name="Accessibility.ReadAnything.SettingsChange"
+    enum="ReadAnythingSettingsChange" expires_after="2023-11-30">
+  <owner>abigailbklein@google.com</owner>
+  <owner>chrome-a11y-core@google.com</owner>
+  <summary>
+    Records when the user changes a text style setting in the Read Anything
+    panel.
+  </summary>
+</histogram>
+
 <histogram name="Accessibility.Reliability.Tree.UnserializeError"
     enum="AccessibilityTreeUnserializeError" expires_after="2023-11-30">
   <owner>aleventhal@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml
index 1adb629e..03b1b86e 100644
--- a/tools/metrics/histograms/metadata/android/histograms.xml
+++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -1586,6 +1586,17 @@
   <token key="ActivityType" variants="ActivityType"/>
 </histogram>
 
+<histogram name="Android.GridTabSwitcher.ThumbnailFetchingResult"
+    enum="GridTabSwitcherThumbnailFetchingResult" expires_after="2023-10-01">
+  <owner>ckitagawa@chromium.org</owner>
+  <owner>clank-isochron-team@google.com</owner>
+  <summary>
+    This histogram records the result of thumbnail fetching in the Grid Tab
+    Switcher on Android. This is recorded once per thumbnail fetch when a Tab
+    card with a thumbnail is shown onscreen.
+  </summary>
+</histogram>
+
 <histogram name="Android.HistoryPage.ClearBrowsingData.PerProfileType"
     enum="BrowserProfileType" expires_after="2023-10-08">
   <owner>roagarwal@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
index 868f48a..da4f081 100644
--- a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
+++ b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
@@ -82,6 +82,9 @@
       summary="Chrome Home shown on cold start"/>
   <variant name="IPH_ChromeHomePullToRefresh"
       summary="Chrome Home shown after a pull-to-refresh"/>
+  <variant name="IPH_CompanionSidePanel"
+      summary="prompting users to view the companion feature in the side
+               panel"/>
   <variant name="IPH_ContextualPageActions_PriceTracking"
       summary="contextual page price tracking action in the top toolbar"/>
   <variant name="IPH_ContextualPageActions_PriceTrackingActionChip"
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index c14c4bf..9307190 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -6690,6 +6690,10 @@
 
 <histogram name="GridTabSwitcher.ThumbnailFetchingResult"
     enum="GridTabSwitcherThumbnailFetchingResult" expires_after="2021-02-14">
+  <obsolete>
+    Expired 2021-02-14 replaced superceded by
+    Android.GridTabSwitcher.ThumbnailFetchingResult.
+  </obsolete>
   <owner>yusufo@chromium.org</owner>
   <owner>wychen@chromium.org</owner>
   <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 16e38a8..b4b67c83 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -21,8 +21,8 @@
             "full_remote_path": "perfetto-luci-artifacts/v34.0/mac-arm64/trace_processor_shell"
         },
         "linux": {
-            "hash": "3c83c160e7c9e9d35e4ee8be48cf4b143f18a0ef",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/fadc3ec879d63b8f2a8166d31674fb1856469d2a/trace_processor_shell"
+            "hash": "c82d914dc4e3a1a40667be1c49acec957dfe7508",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/5bab1b7d3f12c1fd5c9ff12abd93a7c672fa2ab5/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/android/resources/resource_manager.h b/ui/android/resources/resource_manager.h
index 80fa5d5..bff2565 100644
--- a/ui/android/resources/resource_manager.h
+++ b/ui/android/resources/resource_manager.h
@@ -62,8 +62,6 @@
                                                : 0;
   }
 
-  virtual void MarkTintNonDiscardable(SkColor tint_color) = 0;
-
   // A notification that all updates have finished for the current frame.
   virtual void OnFrameUpdatesFinished() = 0;
 
diff --git a/ui/android/resources/resource_manager_impl.cc b/ui/android/resources/resource_manager_impl.cc
index d9b11df..ac65593 100644
--- a/ui/android/resources/resource_manager_impl.cc
+++ b/ui/android/resources/resource_manager_impl.cc
@@ -27,7 +27,6 @@
 #include "ui/android/resources/ui_resource_provider.h"
 #include "ui/android/ui_android_jni_headers/ResourceManager_jni.h"
 #include "ui/android/window_android.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/gfx/android/java_bitmap.h"
 #include "ui/gfx/geometry/rect.h"
 
@@ -119,10 +118,6 @@
 }
 
 void ResourceManagerImpl::RemoveUnusedTints() {
-  if (base::FeatureList::IsEnabled(features::kKeepAndroidTintedResources)) {
-    return;
-  }
-
   // Iterate over the currently cached tints and remove ones that were not
   // used as defined in |used_tints|.
   for (auto it = tinted_resources_.cbegin(); it != tinted_resources_.cend();) {
@@ -134,10 +129,6 @@
   }
 }
 
-void ResourceManagerImpl::MarkTintNonDiscardable(SkColor tint_color) {
-  used_tints_.insert(tint_color);
-}
-
 void ResourceManagerImpl::OnFrameUpdatesFinished() {
   RemoveUnusedTints();
   used_tints_.clear();
diff --git a/ui/android/resources/resource_manager_impl.h b/ui/android/resources/resource_manager_impl.h
index 30eba34..b632a03 100644
--- a/ui/android/resources/resource_manager_impl.h
+++ b/ui/android/resources/resource_manager_impl.h
@@ -49,7 +49,6 @@
                                       SkColor tint_color,
                                       bool preserve_color_alpha) override;
   void PreloadResource(AndroidResourceType res_type, int res_id) override;
-  void MarkTintNonDiscardable(SkColor tint_color) override;
   void OnFrameUpdatesFinished() override;
 
   // Called from Java
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index cd69e24..1e2047cc 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -39,12 +39,14 @@
 # should be kept minimal to not have to build too many targets with multiple
 # toolchains.
 #
-# Any other target should depend on //ui/base instead.
+# Any other target should depend on //ui/base instead, except when needed to
+# avoid circular dependencies.
 component("ui_data_pack") {
   visibility = [
     ":base",
     "//chromeos/crosapi/mojom",  # This target requires minimal dependencies.
     "//ios/chrome/tools/strings:generate_localizable_strings",
+    "//ui/gfx:*",
   ]
 
   sources = [
diff --git a/ui/base/cocoa/bubble_closer.mm b/ui/base/cocoa/bubble_closer.mm
index e3b05d9..bed62408 100644
--- a/ui/base/cocoa/bubble_closer.mm
+++ b/ui/base/cocoa/bubble_closer.mm
@@ -13,7 +13,7 @@
 namespace ui {
 
 struct BubbleCloser::ObjCStorage {
-  id event_tap_ = nil;  // Weak. Owned by AppKit.
+  id event_tap = nil;  // Weak. Owned by AppKit.
 };
 
 BubbleCloser::BubbleCloser(NSWindow* window,
@@ -52,14 +52,14 @@
 
     return event;
   };
-  objc_storage_->event_tap_ =
+  objc_storage_->event_tap =
       [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskLeftMouseDown |
                                                     NSEventMaskRightMouseDown
                                             handler:block];
 }
 
 BubbleCloser::~BubbleCloser() {
-  [NSEvent removeMonitor:objc_storage_->event_tap_];
+  [NSEvent removeMonitor:objc_storage_->event_tap];
 }
 
 void BubbleCloser::OnClickOutside() {
diff --git a/ui/base/layout.cc b/ui/base/layout.cc
index 9b1a348..2fec3d5 100644
--- a/ui/base/layout.cc
+++ b/ui/base/layout.cc
@@ -4,126 +4,11 @@
 
 #include "ui/base/layout.h"
 
-#include <stddef.h>
-
-#include <algorithm>
-#include <cmath>
-#include <limits>
-
-#include "base/check.h"
-#include "base/check_op.h"
-#include "build/build_config.h"
-#include "ui/base/pointer/pointer_device.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
-#include "ui/gfx/image/image_skia.h"
 
 namespace ui {
 
-namespace {
-
-std::vector<ResourceScaleFactor>* g_supported_resource_scale_factors = nullptr;
-
-}  // namespace
-
-void SetSupportedResourceScaleFactors(
-    const std::vector<ResourceScaleFactor>& scale_factors) {
-  CHECK(!scale_factors.empty());
-
-  if (g_supported_resource_scale_factors != nullptr) {
-    delete g_supported_resource_scale_factors;
-  }
-
-  g_supported_resource_scale_factors =
-      new std::vector<ResourceScaleFactor>(scale_factors);
-  std::sort(g_supported_resource_scale_factors->begin(),
-            g_supported_resource_scale_factors->end(),
-            [](ResourceScaleFactor lhs, ResourceScaleFactor rhs) {
-              return GetScaleForResourceScaleFactor(lhs) <
-                     GetScaleForResourceScaleFactor(rhs);
-            });
-
-  // Set ImageSkia's supported scales.
-  std::vector<float> scales;
-  for (std::vector<ResourceScaleFactor>::const_iterator it =
-           g_supported_resource_scale_factors->begin();
-       it != g_supported_resource_scale_factors->end(); ++it) {
-    scales.push_back(GetScaleForResourceScaleFactor(*it));
-  }
-  gfx::ImageSkia::SetSupportedScales(scales);
-}
-
-const std::vector<ResourceScaleFactor>& GetSupportedResourceScaleFactors() {
-  CHECK_NE(g_supported_resource_scale_factors, nullptr)
-      << "ResourceBundle needs to be intialized.";
-
-  return *g_supported_resource_scale_factors;
-}
-
-ResourceScaleFactor GetSupportedResourceScaleFactor(float scale) {
-  CHECK_NE(g_supported_resource_scale_factors, nullptr)
-      << "ResourceBundle needs to be intialized.";
-
-  ResourceScaleFactor closest_match = k100Percent;
-  float smallest_diff = std::numeric_limits<float>::max();
-  for (const auto scale_factor : *g_supported_resource_scale_factors) {
-    const float diff =
-        std::abs(GetScaleForResourceScaleFactor(scale_factor) - scale);
-    if (diff < smallest_diff) {
-      closest_match = scale_factor;
-      smallest_diff = diff;
-    } else {
-      break;
-    }
-  }
-
-  CHECK_NE(closest_match, kScaleFactorNone);
-  return closest_match;
-}
-
-ResourceScaleFactor GetMaxSupportedResourceScaleFactor() {
-  CHECK_NE(g_supported_resource_scale_factors, nullptr)
-      << "ResourceBundle needs to be intialized.";
-
-  return g_supported_resource_scale_factors->back();
-}
-
-bool IsSupportedScale(float scale) {
-  CHECK_NE(g_supported_resource_scale_factors, nullptr)
-      << "ResourceBundle needs to be intialized.";
-
-  for (const auto scale_factor_idx : *g_supported_resource_scale_factors) {
-    if (GetScaleForResourceScaleFactor(scale_factor_idx) == scale) {
-      return true;
-    }
-  }
-  return false;
-}
-
-namespace test {
-
-ScopedSetSupportedResourceScaleFactors::ScopedSetSupportedResourceScaleFactors(
-    const std::vector<ResourceScaleFactor>& new_scale_factors) {
-  if (g_supported_resource_scale_factors) {
-    original_scale_factors_ =
-        std::make_unique<std::vector<ResourceScaleFactor>>(
-            *g_supported_resource_scale_factors);
-  }
-  SetSupportedResourceScaleFactors(new_scale_factors);
-}
-
-ScopedSetSupportedResourceScaleFactors::
-    ~ScopedSetSupportedResourceScaleFactors() {
-  if (original_scale_factors_) {
-    SetSupportedResourceScaleFactors(*original_scale_factors_);
-  } else {
-    delete g_supported_resource_scale_factors;
-    g_supported_resource_scale_factors = nullptr;
-  }
-}
-
-}  // namespace test
-
 float GetScaleFactorForNativeView(gfx::NativeView view) {
   // A number of unit tests do not setup the screen.
   if (!display::Screen::GetScreen())
diff --git a/ui/base/layout.h b/ui/base/layout.h
index 9251363..50b364f7 100644
--- a/ui/base/layout.h
+++ b/ui/base/layout.h
@@ -5,64 +5,16 @@
 #ifndef UI_BASE_LAYOUT_H_
 #define UI_BASE_LAYOUT_H_
 
-#include <memory>
-#include <vector>
-
 #include "base/component_export.h"
-#include "build/build_config.h"
 #include "ui/base/resource/resource_scale_factor.h"
 #include "ui/gfx/native_widget_types.h"
 
 namespace ui {
 
-// Changes the value of GetSupportedScaleFactors() to |scale_factors|.
-// Use ScopedSetSupportedScaleFactors for unit tests as not to affect the
-// state of other tests.
-COMPONENT_EXPORT(UI_BASE)
-void SetSupportedResourceScaleFactors(
-    const std::vector<ResourceScaleFactor>& scale_factors);
-
-// Returns a vector with the scale factors which are supported by this
-// platform, in ascending order.
-COMPONENT_EXPORT(UI_BASE)
-const std::vector<ResourceScaleFactor>& GetSupportedResourceScaleFactors();
-
-// Returns the supported ResourceScaleFactor which most closely matches |scale|.
-COMPONENT_EXPORT(UI_BASE)
-ResourceScaleFactor GetSupportedResourceScaleFactor(float image_scale);
-
-// Returns the maximum supported ResourceScaleFactor.
-COMPONENT_EXPORT(UI_BASE)
-ResourceScaleFactor GetMaxSupportedResourceScaleFactor();
-
-// Returns the ResourceScaleFactor used by |view|.
+// Returns the ResourceScaleFactor used by `view`.
 COMPONENT_EXPORT(UI_BASE)
 float GetScaleFactorForNativeView(gfx::NativeView view);
 
-// Returns true if the scale passed in is the list of supported scales for
-// the platform.
-// TODO(oshima): Deprecate this.
-COMPONENT_EXPORT(UI_BASE) bool IsSupportedScale(float scale);
-
-namespace test {
-// Class which changes the value of GetSupportedResourceScaleFactors() to
-// |new_scale_factors| for the duration of its lifetime.
-class COMPONENT_EXPORT(UI_BASE) ScopedSetSupportedResourceScaleFactors {
- public:
-  explicit ScopedSetSupportedResourceScaleFactors(
-      const std::vector<ResourceScaleFactor>& new_scale_factors);
-  ScopedSetSupportedResourceScaleFactors(
-      const ScopedSetSupportedResourceScaleFactors&) = delete;
-  ScopedSetSupportedResourceScaleFactors& operator=(
-      const ScopedSetSupportedResourceScaleFactors&) = delete;
-  ~ScopedSetSupportedResourceScaleFactors();
-
- private:
-  std::unique_ptr<std::vector<ResourceScaleFactor>> original_scale_factors_;
-};
-
-}  // namespace test
-
 }  // namespace ui
 
 #endif  // UI_BASE_LAYOUT_H_
diff --git a/ui/base/resource/resource_scale_factor.cc b/ui/base/resource/resource_scale_factor.cc
index 5e07a18..022ed84 100644
--- a/ui/base/resource/resource_scale_factor.cc
+++ b/ui/base/resource/resource_scale_factor.cc
@@ -4,15 +4,31 @@
 
 #include "ui/base/resource/resource_scale_factor.h"
 
+#include <algorithm>
+#include <cmath>
 #include <iterator>
+#include <limits>
+#include <memory>
+#include <vector>
+
+#include "base/check.h"
+#include "base/check_op.h"
 
 namespace ui {
 
 namespace {
 
+std::vector<ResourceScaleFactor>* g_supported_resource_scale_factors = nullptr;
+
 const float kResourceScaleFactorScales[] = {1.0f, 1.0f, 2.0f, 3.0f};
 static_assert(NUM_SCALE_FACTORS == std::size(kResourceScaleFactorScales),
-              "kScaleFactorScales has incorrect size");
+              "kResourceScaleFactorScales has incorrect size");
+
+// The difference to fall back to the smaller scale factor rather than the
+// larger one. For example, assume 1.20 is requested but only 1.0 and 2.0 are
+// supported. In that case, not fall back to 2.0 but 1.0, and then expand
+// the image to 1.20.
+const float kFallbackToSmallerScaleDiff = 0.20f;
 
 }  // namespace
 
@@ -20,4 +36,117 @@
   return kResourceScaleFactorScales[scale_factor];
 }
 
+void SetSupportedResourceScaleFactors(
+    const std::vector<ResourceScaleFactor>& scale_factors) {
+  CHECK(!scale_factors.empty());
+
+  if (g_supported_resource_scale_factors != nullptr) {
+    delete g_supported_resource_scale_factors;
+  }
+
+  g_supported_resource_scale_factors =
+      new std::vector<ResourceScaleFactor>(scale_factors);
+  std::sort(g_supported_resource_scale_factors->begin(),
+            g_supported_resource_scale_factors->end(),
+            [](ResourceScaleFactor lhs, ResourceScaleFactor rhs) {
+              return kResourceScaleFactorScales[lhs] <
+                     kResourceScaleFactorScales[rhs];
+            });
+}
+
+const std::vector<ResourceScaleFactor>& GetSupportedResourceScaleFactors() {
+  CHECK_NE(g_supported_resource_scale_factors, nullptr)
+      << "ResourceBundle needs to be intialized.";
+
+  return *g_supported_resource_scale_factors;
+}
+
+ResourceScaleFactor GetSupportedResourceScaleFactor(float scale) {
+  CHECK_NE(g_supported_resource_scale_factors, nullptr)
+      << "ResourceBundle needs to be intialized.";
+
+  ResourceScaleFactor closest_match = k100Percent;
+  float smallest_diff = std::numeric_limits<float>::max();
+  for (const auto scale_factor : *g_supported_resource_scale_factors) {
+    const float diff =
+        std::abs(kResourceScaleFactorScales[scale_factor] - scale);
+    if (diff < smallest_diff) {
+      closest_match = scale_factor;
+      smallest_diff = diff;
+    } else {
+      break;
+    }
+  }
+
+  CHECK_NE(closest_match, kScaleFactorNone);
+  return closest_match;
+}
+
+ResourceScaleFactor GetSupportedResourceScaleFactorForRescale(float scale) {
+  CHECK_NE(g_supported_resource_scale_factors, nullptr)
+      << "ResourceBundle needs to be intialized.";
+
+  // Returns an exact match, a smaller scale within
+  // `kFallbackToSmallerScaleDiff` units, the nearest larger scale, or the max
+  // supported scale.
+  for (auto supported_scale : *g_supported_resource_scale_factors) {
+    if (kResourceScaleFactorScales[supported_scale] +
+            kFallbackToSmallerScaleDiff >=
+        scale) {
+      return supported_scale;
+    }
+  }
+
+  return GetMaxSupportedResourceScaleFactor();
+}
+
+ResourceScaleFactor GetMaxSupportedResourceScaleFactor() {
+  CHECK_NE(g_supported_resource_scale_factors, nullptr)
+      << "ResourceBundle needs to be intialized.";
+
+  ResourceScaleFactor max_scale = g_supported_resource_scale_factors->back();
+  CHECK_NE(max_scale, kScaleFactorNone);
+  return max_scale;
+}
+
+float GetScaleForMaxSupportedResourceScaleFactor() {
+  return kResourceScaleFactorScales[GetMaxSupportedResourceScaleFactor()];
+}
+
+bool IsSupportedScale(float scale) {
+  CHECK_NE(g_supported_resource_scale_factors, nullptr)
+      << "ResourceBundle needs to be intialized.";
+
+  for (const auto scale_factor_idx : *g_supported_resource_scale_factors) {
+    if (kResourceScaleFactorScales[scale_factor_idx] == scale) {
+      return true;
+    }
+  }
+  return false;
+}
+
+namespace test {
+
+ScopedSetSupportedResourceScaleFactors::ScopedSetSupportedResourceScaleFactors(
+    const std::vector<ResourceScaleFactor>& new_scale_factors) {
+  if (g_supported_resource_scale_factors) {
+    original_scale_factors_ =
+        std::make_unique<std::vector<ResourceScaleFactor>>(
+            *g_supported_resource_scale_factors);
+  }
+  SetSupportedResourceScaleFactors(new_scale_factors);
+}
+
+ScopedSetSupportedResourceScaleFactors::
+    ~ScopedSetSupportedResourceScaleFactors() {
+  if (original_scale_factors_) {
+    SetSupportedResourceScaleFactors(*original_scale_factors_);
+  } else {
+    delete g_supported_resource_scale_factors;
+    g_supported_resource_scale_factors = nullptr;
+  }
+}
+
+}  // namespace test
+
 }  // namespace ui
diff --git a/ui/base/resource/resource_scale_factor.h b/ui/base/resource/resource_scale_factor.h
index cc9f735..73f3f6c 100644
--- a/ui/base/resource/resource_scale_factor.h
+++ b/ui/base/resource/resource_scale_factor.h
@@ -5,13 +5,16 @@
 #ifndef UI_BASE_RESOURCE_RESOURCE_SCALE_FACTOR_H_
 #define UI_BASE_RESOURCE_RESOURCE_SCALE_FACTOR_H_
 
+#include <memory>
+#include <vector>
+
 #include "base/component_export.h"
 
 namespace ui {
 
 // Supported resource scale factors for the platform. This is used as an index
-// into the array |kScaleFactorScales| which maps the enum value to a float.
-// kScaleFactorNone is used for density independent resources such as
+// into the array `kResourceScaleFactorScales` which maps the enum value to a
+// float. `kScaleFactorNone` is used for density independent resources such as
 // string, html/js files or an image that can be used for any scale factors
 // (such as wallpapers).
 enum ResourceScaleFactor : int {
@@ -27,6 +30,62 @@
 COMPONENT_EXPORT(UI_DATA_PACK)
 float GetScaleForResourceScaleFactor(ResourceScaleFactor scale_factor);
 
+// Changes the value of `GetSupportedScaleFactors` to `scale_factors`. Use
+// `ScopedSetSupportedResourceScaleFactors` for unit tests to avoid affecting
+// the state of other tests.
+COMPONENT_EXPORT(UI_DATA_PACK)
+void SetSupportedResourceScaleFactors(
+    const std::vector<ResourceScaleFactor>& scale_factors);
+
+// Returns a vector with the scale factors which are supported by this
+// platform, in ascending order.
+COMPONENT_EXPORT(UI_DATA_PACK)
+const std::vector<ResourceScaleFactor>& GetSupportedResourceScaleFactors();
+
+// Returns the supported ResourceScaleFactor which most closely matches `scale`.
+COMPONENT_EXPORT(UI_DATA_PACK)
+ResourceScaleFactor GetSupportedResourceScaleFactor(float scale);
+
+// Returns a resource scale factor value that can be used to load a resource
+// that will later be scaled to `scale` minimizing quality loss. This means
+// that, instead of the closest resource scale factor, it might return a
+// resource meant for a bigger scale factor.
+COMPONENT_EXPORT(UI_DATA_PACK)
+ResourceScaleFactor GetSupportedResourceScaleFactorForRescale(float scale);
+
+// Returns the maximum supported ResourceScaleFactor.
+COMPONENT_EXPORT(UI_DATA_PACK)
+ResourceScaleFactor GetMaxSupportedResourceScaleFactor();
+
+// Returns the maximum supported ResourceScaleFactor as a float.
+COMPONENT_EXPORT(UI_DATA_PACK)
+float GetScaleForMaxSupportedResourceScaleFactor();
+
+// Returns true if the scale passed in is the list of supported scales for
+// the platform.
+// TODO(oshima): Deprecate this.
+COMPONENT_EXPORT(UI_DATA_PACK) bool IsSupportedScale(float scale);
+
+namespace test {
+
+// Class which changes the value of GetSupportedResourceScaleFactors() to
+// `new_scale_factors` for the duration of its lifetime.
+class COMPONENT_EXPORT(UI_DATA_PACK) ScopedSetSupportedResourceScaleFactors {
+ public:
+  explicit ScopedSetSupportedResourceScaleFactors(
+      const std::vector<ResourceScaleFactor>& new_scale_factors);
+  ScopedSetSupportedResourceScaleFactors(
+      const ScopedSetSupportedResourceScaleFactors&) = delete;
+  ScopedSetSupportedResourceScaleFactors& operator=(
+      const ScopedSetSupportedResourceScaleFactors&) = delete;
+  ~ScopedSetSupportedResourceScaleFactors();
+
+ private:
+  std::unique_ptr<std::vector<ResourceScaleFactor>> original_scale_factors_;
+};
+
+}  // namespace test
+
 }  // namespace ui
 
 #endif  // UI_BASE_RESOURCE_RESOURCE_SCALE_FACTOR_H_
diff --git a/ui/base/ui_base_features.cc b/ui/base/ui_base_features.cc
index c5e220a..61542de 100644
--- a/ui/base/ui_base_features.cc
+++ b/ui/base/ui_base_features.cc
@@ -424,10 +424,6 @@
 bool UseToastManager() {
   return base::FeatureList::IsEnabled(kUseToastManager);
 }
-
-BASE_FEATURE(kKeepAndroidTintedResources,
-             "KeepAndroidTintedResources",
-             base::FEATURE_DISABLED_BY_DEFAULT);
 #endif  // BUILDFLAG(IS_ANDROID)
 
 BASE_FEATURE(kEnableVariableRefreshRate,
diff --git a/ui/base/ui_base_features.h b/ui/base/ui_base_features.h
index 5a08b60..8ef4c4d 100644
--- a/ui/base/ui_base_features.h
+++ b/ui/base/ui_base_features.h
@@ -41,11 +41,6 @@
 
 #if BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(UI_BASE_FEATURES) BASE_DECLARE_FEATURE(kUseToastManager);
-
-// Causes the Tinted Resource cache to only be cleared when Chrome goes to the
-// background.
-COMPONENT_EXPORT(UI_BASE_FEATURES)
-BASE_DECLARE_FEATURE(kKeepAndroidTintedResources);
 #endif  // BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_WIN)
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
index 1182831..6b4ef22b 100644
--- a/ui/gfx/BUILD.gn
+++ b/ui/gfx/BUILD.gn
@@ -314,6 +314,7 @@
     "//mojo/public/cpp/bindings:struct_traits",
     "//skia",
     "//third_party/zlib",
+    "//ui/base:ui_data_pack",
   ]
 
   if (!is_apple) {
@@ -699,6 +700,7 @@
     "//base/test:test_support",
     "//skia",
     "//testing/gtest",
+    "//ui/base:ui_data_pack",
     "//ui/gfx/animation",
     "//ui/gfx/animation/keyframe",
     "//ui/gfx/geometry",
diff --git a/ui/gfx/DEPS b/ui/gfx/DEPS
index 75bd0583..f4b8917 100644
--- a/ui/gfx/DEPS
+++ b/ui/gfx/DEPS
@@ -7,6 +7,7 @@
   "+third_party/harfbuzz-ng",
   "+third_party/skia",
   "+third_party/test_fonts",
+  "+ui/base/resource/resource_scale_factor.h",
   "+ui/base/ui_base_features.h",
   "+ui/ios",
   "+ui/linux",
diff --git a/ui/gfx/image/image_ios.mm b/ui/gfx/image/image_ios.mm
index 685bf67..f7ce1f4 100644
--- a/ui/gfx/image/image_ios.mm
+++ b/ui/gfx/image/image_ios.mm
@@ -13,6 +13,7 @@
 #include "base/logging.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/mac/scoped_nsobject.h"
+#include "ui/base/resource/resource_scale_factor.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/image/image_internal.h"
 #include "ui/gfx/image/image_png_rep.h"
@@ -117,7 +118,7 @@
 }
 
 UIImage* UIImageFromPNG(const std::vector<gfx::ImagePNGRep>& image_png_reps) {
-  float ideal_scale = ImageSkia::GetMaxSupportedScale();
+  const float ideal_scale = ui::GetScaleForMaxSupportedResourceScaleFactor();
 
   if (image_png_reps.empty())
     return CreateErrorUIImage(ideal_scale);
@@ -126,8 +127,8 @@
   float smallest_diff = std::numeric_limits<float>::max();
   size_t closest_index = 0u;
   for (size_t i = 0; i < image_png_reps.size(); ++i) {
-    float scale = image_png_reps[i].scale;
-    float diff = std::abs(ideal_scale - scale);
+    const float scale = image_png_reps[i].scale;
+    const float diff = std::abs(ideal_scale - scale);
     if (diff < smallest_diff) {
       smallest_diff = diff;
       closest_index = i;
diff --git a/ui/gfx/image/image_ios_unittest.mm b/ui/gfx/image/image_ios_unittest.mm
index f7d8c49..0510c364 100644
--- a/ui/gfx/image/image_ios_unittest.mm
+++ b/ui/gfx/image/image_ios_unittest.mm
@@ -11,6 +11,7 @@
 #include "base/mac/scoped_cftyperef.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/resource/resource_scale_factor.h"
 #include "ui/gfx/image/image_skia.h"
 
 namespace {
@@ -44,24 +45,10 @@
 
 class ImageIOSTest : public testing::Test {
  public:
-  ImageIOSTest() {}
-
+  ImageIOSTest() = default;
   ImageIOSTest(const ImageIOSTest&) = delete;
   ImageIOSTest& operator=(const ImageIOSTest&) = delete;
-
-  ~ImageIOSTest() override {}
-
-  void SetUp() override {
-    original_scale_factors_ = gfx::ImageSkia::GetSupportedScales();
-  }
-
-  void TearDown() override {
-    gfx::ImageSkia::SetSupportedScales(original_scale_factors_);
-  }
-
- private:
-  // Used to save and restore the scale factors in effect before this test.
-  std::vector<float> original_scale_factors_;
+  ~ImageIOSTest() override = default;
 };
 
 // Tests image conversion when the scale factor of the source image is not in
@@ -69,17 +56,17 @@
 TEST_F(ImageIOSTest, ImageConversionWithUnsupportedScaleFactor) {
   const CGFloat kWidth = 200;
   const CGFloat kHeight = 100;
-  const CGFloat kTestScales[3] = { 1.0f, 2.0f, 3.0f };
+  const ui::ResourceScaleFactor kTestScales[3] = {
+      ui::k100Percent, ui::k200Percent, ui::k300Percent};
 
   for (size_t i = 0; i < std::size(kTestScales); ++i) {
     for (size_t j = 0; j < std::size(kTestScales); ++j) {
       const CGFloat source_scale = kTestScales[i];
-      const CGFloat supported_scale = kTestScales[j];
+      const ui::ResourceScaleFactor supported_scale = kTestScales[j];
 
       // Set the supported scale for testing.
-      std::vector<float> supported_scales;
-      supported_scales.push_back(supported_scale);
-      gfx::ImageSkia::SetSupportedScales(supported_scales);
+      ui::test::ScopedSetSupportedResourceScaleFactors scoped_scale_factors(
+          {supported_scale});
 
       // Create an UIImage with the appropriate source_scale.
       UIImage* ui_image =
@@ -92,8 +79,10 @@
       gfx::Image to_skbitmap([ui_image retain]);
       const SkBitmap* bitmap = to_skbitmap.ToSkBitmap();
       ASSERT_TRUE(bitmap != NULL);
-      EXPECT_EQ(kWidth * supported_scale, bitmap->width());
-      EXPECT_EQ(kHeight * supported_scale, bitmap->height());
+      EXPECT_EQ(kWidth * ui::GetScaleForResourceScaleFactor(supported_scale),
+                bitmap->width());
+      EXPECT_EQ(kHeight * ui::GetScaleForResourceScaleFactor(supported_scale),
+                bitmap->height());
 
       // Convert to ImageSkia and test its size.
       gfx::Image to_imageskia([ui_image retain]);
diff --git a/ui/gfx/image/image_mac_unittest.mm b/ui/gfx/image/image_mac_unittest.mm
index e6b0e8b..de023825 100644
--- a/ui/gfx/image/image_mac_unittest.mm
+++ b/ui/gfx/image/image_mac_unittest.mm
@@ -7,6 +7,7 @@
 
 #include "base/mac/scoped_nsobject.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/resource/resource_scale_factor.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_png_rep.h"
 #include "ui/gfx/image/image_skia.h"
@@ -75,12 +76,14 @@
 
 class ImageMacTest : public testing::Test {
  public:
-  ImageMacTest() {
-    gfx::ImageSkia::SetSupportedScales(gfx::test::Get1xAnd2xScales());
-  }
-
+  ImageMacTest() = default;
   ImageMacTest(const ImageMacTest&) = delete;
   ImageMacTest& operator=(const ImageMacTest&) = delete;
+  ~ImageMacTest() override = default;
+
+ private:
+  ui::test::ScopedSetSupportedResourceScaleFactors supported_scale_factors_{
+      {ui::k100Percent, ui::k200Percent}};
 };
 
 namespace gt = gfx::test;
diff --git a/ui/gfx/image/image_skia.cc b/ui/gfx/image/image_skia.cc
index d1b8637..7608fc74 100644
--- a/ui/gfx/image/image_skia.cc
+++ b/ui/gfx/image/image_skia.cc
@@ -20,6 +20,7 @@
 #include "base/sequence_checker.h"
 #include "build/build_config.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/resource/resource_scale_factor.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/geometry/size_conversions.h"
@@ -38,14 +39,6 @@
   return *null_image_rep;
 }
 
-std::vector<float>* g_supported_scales = NULL;
-
-// The difference to fall back to the smaller scale factor rather than the
-// larger one. For example, assume 1.20 is requested but only 1.0 and 2.0 are
-// supported. In that case, not fall back to 2.0 but 1.0, and then expand
-// the image to 1.20.
-const float kFallbackToSmallerScaleDiff = 0.20f;
-
 }  // namespace
 
 namespace internal {
@@ -239,7 +232,7 @@
     ImageSkiaRep image;
     float resource_scale = scale;
     if (!HasRepresentationAtAllScales()) {
-      resource_scale = ImageSkia::MapToResourceScale(scale);
+      resource_scale = ui::GetSupportedResourceScaleFactorForRescale(scale);
     }
     if (scale != resource_scale) {
       auto iter = FindRepresentation(resource_scale, fetch_new_image);
@@ -313,39 +306,6 @@
 }
 
 // static
-void ImageSkia::SetSupportedScales(const std::vector<float>& supported_scales) {
-  if (g_supported_scales != NULL)
-    delete g_supported_scales;
-  g_supported_scales = new std::vector<float>(supported_scales);
-  std::sort(g_supported_scales->begin(), g_supported_scales->end());
-}
-
-// static
-const std::vector<float>& ImageSkia::GetSupportedScales() {
-  CHECK_NE(g_supported_scales, nullptr);
-  return *g_supported_scales;
-}
-
-// static
-float ImageSkia::GetMaxSupportedScale() {
-  CHECK_NE(g_supported_scales, nullptr);
-  return g_supported_scales->back();
-}
-
-// static
-float ImageSkia::MapToResourceScale(float scale) {
-  CHECK_NE(g_supported_scales, nullptr);
-  // Returns an exact match, a smaller scale within 0.2 units, the nearest
-  // larger scale, or the min/max supported scale.
-  for (float supported_scale : *g_supported_scales) {
-    if (supported_scale + kFallbackToSmallerScaleDiff >= scale) {
-      return supported_scale;
-    }
-  }
-  return g_supported_scales->back();
-}
-
-// static
 ImageSkia ImageSkia::CreateFromBitmap(const SkBitmap& bitmap, float scale) {
   // An uninitialized/empty/null bitmap makes a null ImageSkia.
   if (bitmap.drawsNothing())
@@ -497,14 +457,17 @@
 }
 
 void ImageSkia::EnsureRepsForSupportedScales() const {
-  DCHECK(g_supported_scales != NULL);
+  const std::vector<ui::ResourceScaleFactor>& supported_scales =
+      ui::GetSupportedResourceScaleFactors();
+
   // Don't check ReadOnly because the source may generate images even for read
   // only ImageSkia. Concurrent access will be protected by
-  // |DCHECK(sequence_checker_.CalledOnValidSequence())| in FindRepresentation.
+  // `DCHECK(sequence_checker_.CalledOnValidSequence())` in FindRepresentation.
   if (storage_.get() && storage_->has_source()) {
-    for (std::vector<float>::const_iterator it = g_supported_scales->begin();
-         it != g_supported_scales->end(); ++it)
-      storage_->FindRepresentation(*it, true);
+    for (const auto scale : supported_scales) {
+      storage_->FindRepresentation(ui::GetScaleForResourceScaleFactor(scale),
+                                   true);
+    }
   }
 }
 
@@ -512,7 +475,9 @@
   for (const ImageSkiaRep& image_rep_to_test : image_reps()) {
     const float test_scale = image_rep_to_test.scale();
     if (test_scale != scale &&
-        ImageSkia::MapToResourceScale(test_scale) == scale) {
+        ui::GetScaleForResourceScaleFactor(
+            ui::GetSupportedResourceScaleFactorForRescale(test_scale)) ==
+            scale) {
       RemoveRepresentation(test_scale);
     }
   }
@@ -521,7 +486,7 @@
 void ImageSkia::Init(const ImageSkiaRep& image_rep) {
   DCHECK(!image_rep.is_null());
   storage_ = new internal::ImageSkiaStorage(
-      NULL, gfx::Size(image_rep.GetWidth(), image_rep.GetHeight()));
+      nullptr, gfx::Size(image_rep.GetWidth(), image_rep.GetHeight()));
   storage_->image_reps().push_back(image_rep);
 }
 
diff --git a/ui/gfx/image/image_skia.h b/ui/gfx/image/image_skia.h
index 1e8bf4a..15e93b9 100644
--- a/ui/gfx/image/image_skia.h
+++ b/ui/gfx/image/image_skia.h
@@ -69,20 +69,6 @@
 
   ~ImageSkia();
 
-  // Changes the value of GetSupportedScales() to |scales|.
-  static void SetSupportedScales(const std::vector<float>& scales);
-
-  // Returns a vector with the scale factors which are supported by this
-  // platform, in ascending order.
-  static const std::vector<float>& GetSupportedScales();
-
-  // Returns the maximum scale supported by this platform.
-  static float GetMaxSupportedScale();
-
-  // Returns the resource scale factor value that ImageSkia uses when
-  // looking for the resource for a given device scale factor.
-  static float MapToResourceScale(float device_scale_factor);
-
   // Creates an image from the passed in bitmap, which is designed for display
   // at the device scale factor given in `scale`. The DIP width and height will
   // be based on that scale factor. A scale factor of 0 is equivalent to
diff --git a/ui/gfx/image/image_skia_unittest.cc b/ui/gfx/image/image_skia_unittest.cc
index 46e8eb0f..9984e28 100644
--- a/ui/gfx/image/image_skia_unittest.cc
+++ b/ui/gfx/image/image_skia_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/threading/simple_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/resource/resource_scale_factor.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/image/image_skia_rep.h"
 #include "ui/gfx/image/image_skia_source.h"
@@ -140,24 +141,14 @@
 
 class ImageSkiaTest : public testing::Test {
  public:
-  ImageSkiaTest() {
-    // In the test, we assume that we support 1.0f and 2.0f DSFs.
-    old_scales_ = ImageSkia::GetSupportedScales();
-
-    // Sets the list of scale factors supported by resource bundle.
-    std::vector<float> supported_scales;
-    supported_scales.push_back(1.0f);
-    supported_scales.push_back(2.0f);
-    ImageSkia::SetSupportedScales(supported_scales);
-  }
-
+  ImageSkiaTest() = default;
   ImageSkiaTest(const ImageSkiaTest&) = delete;
   ImageSkiaTest& operator=(const ImageSkiaTest&) = delete;
-
-  ~ImageSkiaTest() override { ImageSkia::SetSupportedScales(old_scales_); }
+  ~ImageSkiaTest() override = default;
 
  private:
-  std::vector<float> old_scales_;
+  ui::test::ScopedSetSupportedResourceScaleFactors
+      scoped_set_supported_scale_factors_{{ui::k100Percent, ui::k200Percent}};
 };
 
 TEST_F(ImageSkiaTest, FixedSource) {
@@ -478,8 +469,8 @@
   image.MakeThreadSafe();
   EXPECT_TRUE(image.IsThreadSafe());
   // Check if image reps are generated for supported scale factors.
-  EXPECT_EQ(ImageSkia::GetSupportedScales().size(),
-           image.image_reps().size());
+  EXPECT_EQ(ui::GetSupportedResourceScaleFactors().size(),
+            image.image_reps().size());
   test::TestOnThread threadsafe_on_thread(&image);
   threadsafe_on_thread.StartAndJoin();
   EXPECT_TRUE(threadsafe_on_thread.can_read());
diff --git a/ui/gfx/image/image_skia_util_ios.mm b/ui/gfx/image/image_skia_util_ios.mm
index 0732567..0aba33e 100644
--- a/ui/gfx/image/image_skia_util_ios.mm
+++ b/ui/gfx/image/image_skia_util_ios.mm
@@ -9,6 +9,7 @@
 #include "base/mac/scoped_cftyperef.h"
 #include "skia/ext/skia_utils_ios.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/resource/resource_scale_factor.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_skia_rep.h"
 
@@ -16,7 +17,7 @@
 
 gfx::ImageSkia ImageSkiaFromUIImage(UIImage* image) {
   gfx::ImageSkia image_skia;
-  float max_scale = ImageSkia::GetSupportedScales().back();
+  const float max_scale = ui::GetScaleForMaxSupportedResourceScaleFactor();
   gfx::ImageSkiaRep image_skia_rep = ImageSkiaRepOfScaleFromUIImage(
       image, max_scale);
   if (!image_skia_rep.is_null())
@@ -38,8 +39,8 @@
 }
 
 UIImage* UIImageFromImageSkia(const gfx::ImageSkia& image_skia) {
-  return UIImageFromImageSkiaRep(
-      image_skia.GetRepresentation(ImageSkia::GetSupportedScales().back()));
+  const float max_scale = ui::GetScaleForMaxSupportedResourceScaleFactor();
+  return UIImageFromImageSkiaRep(image_skia.GetRepresentation(max_scale));
 }
 
 UIImage* UIImageFromImageSkiaRep(const gfx::ImageSkiaRep& image_skia_rep) {
diff --git a/ui/gfx/image/image_skia_util_mac.mm b/ui/gfx/image/image_skia_util_mac.mm
index 57cb0e4..8e02387 100644
--- a/ui/gfx/image/image_skia_util_mac.mm
+++ b/ui/gfx/image/image_skia_util_mac.mm
@@ -15,6 +15,7 @@
 #include "base/mac/scoped_nsobject.h"
 #include "skia/ext/skia_utils_mac.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/resource/resource_scale_factor.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_skia_rep.h"
 
@@ -59,10 +60,11 @@
   if (IsNSImageEmpty(image))
     return gfx::ImageSkia();
 
-  std::vector<float> supported_scales = ImageSkia::GetSupportedScales();
-
   gfx::ImageSkia image_skia;
-  for (float scale : supported_scales) {
+  const std::vector<ui::ResourceScaleFactor>& supported_scales =
+      ui::GetSupportedResourceScaleFactors();
+  for (const auto resource_scale : supported_scales) {
+    const float scale = ui::GetScaleForResourceScaleFactor(resource_scale);
     NSSize desired_size_for_scale =
         NSMakeSize(desired_size.width * scale, desired_size.height * scale);
     NSImageRep* ns_image_rep = GetNSImageRepWithPixelSize(image,
diff --git a/ui/gfx/image/image_unittest.cc b/ui/gfx/image/image_unittest.cc
index 64ba931..3785663 100644
--- a/ui/gfx/image/image_unittest.cc
+++ b/ui/gfx/image/image_unittest.cc
@@ -5,11 +5,13 @@
 #include <stddef.h>
 
 #include <utility>
+#include <vector>
 
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkPaint.h"
+#include "ui/base/resource/resource_scale_factor.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_png_rep.h"
@@ -48,14 +50,18 @@
 
 class ImageTest : public testing::Test {
  public:
-  ImageTest() {
-    std::vector<float> scales;
-    scales.push_back(1.0f);
+  ImageTest() = default;
+  ImageTest(const ImageTest&) = delete;
+  ImageTest& operator=(const ImageTest&) = delete;
+  ~ImageTest() override = default;
+
+ private:
+  ui::test::ScopedSetSupportedResourceScaleFactors
+      scoped_set_supported_scale_factors_{{ui::k100Percent,
 #if !BUILDFLAG(IS_IOS)
-    scales.push_back(2.0f);
+                                           ui::k200Percent
 #endif
-    gfx::ImageSkia::SetSupportedScales(scales);
-  }
+      }};
 };
 
 namespace gt = gfx::test;
@@ -280,18 +286,20 @@
   gfx::Image from_platform(gt::CopyViaPlatformType(from_png));
 #if BUILDFLAG(IS_IOS)
   // On iOS the platform type (UIImage) only supports one resolution.
-  std::vector<float> scales = gfx::ImageSkia::GetSupportedScales();
+  const std::vector<ui::ResourceScaleFactor>& scales =
+      ui::GetSupportedResourceScaleFactors();
   EXPECT_EQ(scales.size(), 1U);
-  if (scales[0] == 1.0f)
+  if (scales[0] == ui::k100Percent) {
     EXPECT_TRUE(
         gt::ArePNGBytesCloseToBitmap(*bytes1x, from_platform.AsBitmap(),
                                      gt::MaxColorSpaceConversionColorShift()));
-  else if (scales[0] == 2.0f)
+  } else if (scales[0] == ui::k200Percent) {
     EXPECT_TRUE(
         gt::ArePNGBytesCloseToBitmap(*bytes2x, from_platform.AsBitmap(),
                                      gt::MaxColorSpaceConversionColorShift()));
-  else
+  } else {
     ADD_FAILURE() << "Unexpected platform scale factor.";
+  }
 #else
   EXPECT_TRUE(
       gt::ArePNGBytesCloseToBitmap(*bytes1x, from_platform.AsBitmap(),
diff --git a/ui/gfx/image/image_unittest_util.cc b/ui/gfx/image/image_unittest_util.cc
index 49988e9..c94b5bd 100644
--- a/ui/gfx/image/image_unittest_util.cc
+++ b/ui/gfx/image/image_unittest_util.cc
@@ -24,6 +24,7 @@
 #if BUILDFLAG(IS_IOS)
 #include "base/mac/scoped_cftyperef.h"
 #include "skia/ext/skia_utils_ios.h"
+#include "ui/base/resource/resource_scale_factor.h"
 #elif BUILDFLAG(IS_MAC)
 #include "base/mac/mac_util.h"
 #include "skia/ext/skia_utils_mac.h"
@@ -42,13 +43,6 @@
 
 }  // namespace
 
-std::vector<float> Get1xAnd2xScales() {
-  std::vector<float> scales;
-  scales.push_back(1.0f);
-  scales.push_back(2.0f);
-  return scales;
-}
-
 const SkBitmap CreateBitmap(int width, int height) {
   SkBitmap bitmap;
   bitmap.allocN32Pixels(width, height);
@@ -189,11 +183,11 @@
 PlatformImage CreatePlatformImage() {
   SkBitmap bitmap(CreateBitmap(25, 25));
 #if BUILDFLAG(IS_IOS)
-  float scale = ImageSkia::GetMaxSupportedScale();
+  const float scale = ui::GetScaleForMaxSupportedResourceScaleFactor();
 
   if (scale > 1.0) {
     // Always create a 25pt x 25pt image.
-    int size = static_cast<int>(25 * scale);
+    const int size = static_cast<int>(25 * scale);
     bitmap = CreateBitmap(size, size);
   }
 
diff --git a/ui/gfx/image/image_unittest_util.h b/ui/gfx/image/image_unittest_util.h
index d9e9606..71e9442 100644
--- a/ui/gfx/image/image_unittest_util.h
+++ b/ui/gfx/image/image_unittest_util.h
@@ -26,8 +26,6 @@
 typedef gfx::ImageSkia PlatformImage;
 #endif
 
-std::vector<float> Get1xAnd2xScales();
-
 // Create a bitmap of |width|x|height|.
 const SkBitmap CreateBitmap(int width, int height);
 
diff --git a/ui/gfx/scoped_ns_graphics_context_save_gstate_mac.mm b/ui/gfx/scoped_ns_graphics_context_save_gstate_mac.mm
index ee94ca71..950b4a0 100644
--- a/ui/gfx/scoped_ns_graphics_context_save_gstate_mac.mm
+++ b/ui/gfx/scoped_ns_graphics_context_save_gstate_mac.mm
@@ -11,18 +11,18 @@
 namespace gfx {
 
 struct ScopedNSGraphicsContextSaveGState::ObjCStorage {
-  NSGraphicsContext* context_;  // weak
+  NSGraphicsContext* context;  // weak
 };
 
 ScopedNSGraphicsContextSaveGState::ScopedNSGraphicsContextSaveGState()
     : objc_storage_(std::make_unique<ObjCStorage>()) {
-  objc_storage_->context_ = NSGraphicsContext.currentContext;
+  objc_storage_->context = NSGraphicsContext.currentContext;
   [NSGraphicsContext saveGraphicsState];
 }
 
 ScopedNSGraphicsContextSaveGState::~ScopedNSGraphicsContextSaveGState() {
   [NSGraphicsContext restoreGraphicsState];
-  DCHECK_EQ(objc_storage_->context_, NSGraphicsContext.currentContext);
+  DCHECK_EQ(objc_storage_->context, NSGraphicsContext.currentContext);
 }
 
 }  // namespace gfx
diff --git a/ui/shell_dialogs/fake_select_file_dialog.h b/ui/shell_dialogs/fake_select_file_dialog.h
index 2fdc7d8..994f3300 100644
--- a/ui/shell_dialogs/fake_select_file_dialog.h
+++ b/ui/shell_dialogs/fake_select_file_dialog.h
@@ -109,8 +109,8 @@
   std::u16string title_;
   FileTypeInfo file_types_;
   std::string default_extension_;
-  raw_ptr<void> params_;
-  raw_ptr<const GURL> caller_;
+  raw_ptr<void, DanglingUntriaged> params_;
+  raw_ptr<const GURL, DanglingUntriaged> caller_;
   base::WeakPtrFactory<FakeSelectFileDialog> weak_ptr_factory_{this};
 };
 
diff --git a/ui/views/controls/menu/menu_cocoa_watcher_mac.mm b/ui/views/controls/menu/menu_cocoa_watcher_mac.mm
index 5f236f2b..581c5fa 100644
--- a/ui/views/controls/menu/menu_cocoa_watcher_mac.mm
+++ b/ui/views/controls/menu/menu_cocoa_watcher_mac.mm
@@ -39,15 +39,15 @@
 
 struct MenuCocoaWatcherMac::ObjCStorage {
   // Tokens representing the notification observers.
-  id observer_token_other_menu_ = nil;
-  id observer_token_new_window_focus_ = nil;
-  id observer_token_app_change_ = nil;
+  id observer_token_other_menu = nil;
+  id observer_token_new_window_focus = nil;
+  id observer_token_app_change = nil;
 };
 
 MenuCocoaWatcherMac::MenuCocoaWatcherMac(base::OnceClosure callback)
     : callback_(std::move(callback)),
       objc_storage_(std::make_unique<ObjCStorage>()) {
-  objc_storage_->observer_token_other_menu_ =
+  objc_storage_->observer_token_other_menu =
       [[NSNotificationCenter defaultCenter]
           addObserverForName:NSMenuDidBeginTrackingNotification
                       object:nil
@@ -59,7 +59,7 @@
 
                     ExecuteCallback();
                   }];
-  objc_storage_->observer_token_new_window_focus_ =
+  objc_storage_->observer_token_new_window_focus =
       [[NSNotificationCenter defaultCenter]
           addObserverForName:NSWindowDidBecomeKeyNotification
                       object:nil
@@ -71,7 +71,7 @@
 
                     ExecuteCallback();
                   }];
-  objc_storage_->observer_token_app_change_ =
+  objc_storage_->observer_token_app_change =
       [[[NSWorkspace sharedWorkspace] notificationCenter]
           addObserverForName:NSWorkspaceDidActivateApplicationNotification
                       object:nil
@@ -92,11 +92,11 @@
 
 MenuCocoaWatcherMac::~MenuCocoaWatcherMac() {
   [[NSNotificationCenter defaultCenter]
-      removeObserver:objc_storage_->observer_token_other_menu_];
+      removeObserver:objc_storage_->observer_token_other_menu];
   [[NSNotificationCenter defaultCenter]
-      removeObserver:objc_storage_->observer_token_new_window_focus_];
+      removeObserver:objc_storage_->observer_token_new_window_focus];
   [[[NSWorkspace sharedWorkspace] notificationCenter]
-      removeObserver:objc_storage_->observer_token_app_change_];
+      removeObserver:objc_storage_->observer_token_app_change];
 }
 
 void MenuCocoaWatcherMac::SetNotificationFilterForTesting(
diff --git a/ui/views/event_monitor_mac.mm b/ui/views/event_monitor_mac.mm
index 4ee546af..1ecf19a 100644
--- a/ui/views/event_monitor_mac.mm
+++ b/ui/views/event_monitor_mac.mm
@@ -37,7 +37,7 @@
 }
 
 struct EventMonitorMac::ObjCStorage {
-  id monitor_ = nil;
+  id monitor = nil;
 };
 
 EventMonitorMac::EventMonitorMac(ui::EventObserver* event_observer,
@@ -65,13 +65,13 @@
     return event;
   };
 
-  objc_storage_->monitor_ =
+  objc_storage_->monitor =
       [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskAny
                                             handler:block];
 }
 
 EventMonitorMac::~EventMonitorMac() {
-  [NSEvent removeMonitor:objc_storage_->monitor_];
+  [NSEvent removeMonitor:objc_storage_->monitor];
 }
 
 gfx::Point EventMonitorMac::GetLastMouseLocation() {
diff --git a/ui/wm/core/cursor_util.cc b/ui/wm/core/cursor_util.cc
index d2e2a8a5..6140aa61 100644
--- a/ui/wm/core/cursor_util.cc
+++ b/ui/wm/core/cursor_util.cc
@@ -13,6 +13,7 @@
 #include "ui/base/cursor/cursor_size.h"
 #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "ui/base/resource/resource_scale_factor.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/image/image_skia.h"
@@ -321,7 +322,8 @@
   std::vector<SkBitmap> bitmaps;
   const gfx::ImageSkia* image =
       ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
-  const float resource_scale = gfx::ImageSkia::MapToResourceScale(scale);
+  const float resource_scale = ui::GetScaleForResourceScaleFactor(
+      ui::GetSupportedResourceScaleFactorForRescale(scale));
   const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(resource_scale);
   CHECK_EQ(image_rep.scale(), resource_scale);
   SkBitmap bitmap = image_rep.GetBitmap();
@@ -453,7 +455,8 @@
   DCHECK_EQ(resource->type, t);
   *resource_id = resource->id;
   *point = resource->hotspot_1x;
-  if (gfx::ImageSkia::MapToResourceScale(scale_factor) == 2.0f) {
+  if (ui::GetSupportedResourceScaleFactorForRescale(scale_factor) ==
+      ui::k200Percent) {
     *point = resource->hotspot_2x;
   }
   return true;
diff --git a/ui/wm/core/cursor_util_unittest.cc b/ui/wm/core/cursor_util_unittest.cc
index 0b3c5af7..c8e37dd 100644
--- a/ui/wm/core/cursor_util_unittest.cc
+++ b/ui/wm/core/cursor_util_unittest.cc
@@ -17,7 +17,6 @@
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/geometry/skia_conversions.h"
-#include "ui/gfx/image/image_skia.h"
 
 namespace wm {
 namespace {
@@ -111,7 +110,8 @@
         EXPECT_EQ(gfx::SkISizeToSize(pointer_data->bitmaps[0].dimensions()),
                   gfx::ScaleToFlooredSize(
                       test.size[base::checked_cast<int>(size)], scale));
-        const float resource_scale = gfx::ImageSkia::MapToResourceScale(scale);
+        const float resource_scale = ui::GetScaleForResourceScaleFactor(
+            ui::GetSupportedResourceScaleFactorForRescale(scale));
         EXPECT_EQ(pointer_data->hotspot,
                   gfx::ScaleToFlooredPoint(
                       test.hotspot[base::checked_cast<int>(size)]