diff --git a/DEPS b/DEPS
index f0ec547e..88f1e10b 100644
--- a/DEPS
+++ b/DEPS
@@ -254,7 +254,7 @@
   # luci-go CIPD package version.
   # Make sure the revision is uploaded by infra-packagers builder.
   # https://ci.chromium.org/p/infra-internal/g/infra-packagers/console
-  'luci_go': 'git_revision:8b73cff3b780a7136c4904103f19124d2be3dee1',
+  'luci_go': 'git_revision:3e49653ac027a003d9ef6cf89068acbf28f5bd9e',
 
   # This can be overridden, e.g. with custom_vars, to build clang from HEAD
   # instead of downloading the prebuilt pinned revision.
@@ -310,11 +310,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'src_internal_revision': 'c62e1f4b248dcad36232a1a959455b2bbc9cd7f3',
+  'src_internal_revision': '66c70f7165712e360b0cd864b15a4875fff95137',
   # 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': '31ceb1669d1cf6a82be0d7ec63aaaf14cce1a4d6',
+  'skia_revision': 'b961fc35371508346c7552cb8f79651f154f10c3',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -322,7 +322,7 @@
   # 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': '29d0fe5143aaf475602925483f774f134910beaf',
+  'angle_revision': 'c9955641bcc2323ea2c92f9ff3d827466ac0a2db',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -385,11 +385,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '3c4b5cf37f825a7e13c9fc65f18551f49791399c',
+  'catapult_revision': '7c462e0d55cd87448af2c1ba66ce223e5294fe0c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling chromium_variations
   # and whatever else without interference from each other.
-  'chromium_variations_revision': 'ca0c802ac159ed51ed640cabeb3b67e953c40aec',
+  'chromium_variations_revision': '3869a87d4512536dcce862b55f2274b8c5e9f438',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling CrossBench
   # and whatever else without interference from each other.
@@ -449,7 +449,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'quiche_revision': '4c9b668a0bbd6e5a5e0be3423213b20ae54ca0ac',
+  'quiche_revision': '8c88ebfbe42f3e19a33b0c5db67c52970549389a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ios_webkit
   # and whatever else without interference from each other.
@@ -845,7 +845,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    '340aed4c542ac53f950fd007ee452c3f1099739f',
+    'da219a17d5eabce16b35e68f276e7d265377236b',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -1051,7 +1051,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'DqV7MfoS-OdweHanUQqLvihUZG2azL412tGbq3_z7K8C',
+          'version': 'a9CGOell056bhQij2JhATC4nOCgZpeDXqqwWjr1_ewAC',
       },
     ],
     'condition': 'checkout_android',
@@ -1295,7 +1295,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'f936d540e1811967bd3cc819089b498b98b1e1be',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '0827dd28f1c4d25f3cd90776f7e221cba6243c2f',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1576,7 +1576,7 @@
     Var('chromium_git') + '/external/libaddressinput.git' + '@' + 'e8712e415627f22d0b00ebee8db99547077f39bd',
 
   'src/third_party/libaom/source/libaom':
-    Var('aomedia_git') + '/aom.git' + '@' +  '5f8db64abce68a3698fb732697ae50880bc9cac4',
+    Var('aomedia_git') + '/aom.git' + '@' +  '82018abee6cb2c4cb8b26cd83eff569e766f1722',
 
   'src/third_party/libavif/src':
     Var('chromium_git') + '/external/github.com/AOMediaCodec/libavif.git' + '@' + Var('libavif_revision'),
@@ -1790,7 +1790,7 @@
     Var('pdfium_git') + '/pdfium.git' + '@' +  Var('pdfium_revision'),
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '43ee4b90e33bcc0c9191d569b74e6f76585d314a',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'c478eb8ffb74aa961c2320efb2c901a5d1d69cba',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1824,7 +1824,7 @@
   },
 
   'src/third_party/re2/src':
-    Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + '09de536bb7c77c2e0869a001f012d49560f56cbe',
+    Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + '26f7d889e1f7e75e95e65490086538edf9f5275c',
 
   'src/third_party/r8': {
       'packages': [
@@ -1868,7 +1868,7 @@
   },
 
   'src/third_party/ruy/src':
-    Var('chromium_git') + '/external/github.com/google/ruy.git' + '@' + 'c04e5e52ae6b144f74ac032652e3c538bda15c9b',
+    Var('chromium_git') + '/external/github.com/google/ruy.git' + '@' + '6ffa93a89376555b09134c59b84d8f5e9cfc6ce6',
 
   'src/third_party/skia':
     Var('skia_git') + '/skia.git' + '@' +  Var('skia_revision'),
@@ -1922,7 +1922,7 @@
     Var('chromium_git') + '/external/github.com/GoogleChromeLabs/text-fragments-polyfill.git' + '@' + 'c036420683f672d685e27415de0a5f5e85bdc23f',
 
   'src/third_party/tflite/src':
-    Var('chromium_git') + '/external/github.com/tensorflow/tensorflow.git' + '@' + 'bc6d7a48432f1c7e1fd9b34ee3e90c919982ab8c',
+    Var('chromium_git') + '/external/github.com/tensorflow/tensorflow.git' + '@' + 'edf7215123c67d76199d099779137b974b6e1293',
 
   'src/third_party/turbine': {
       'packages': [
@@ -1972,7 +1972,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'f4bf599a8b575df685c31d9c4729a70a04e377ed',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '0447990a43973392ca18aec8a0422f67e5b6776e',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'a50d0906eedac478595363ad1342787a581f9e2e',
 
   'src/third_party/webrtc':
     Var('webrtc_git') + '/src.git' + '@' + '7892f05411d93fe9a2b876daccd817286ca43182',
@@ -2000,7 +2000,7 @@
   },
 
   'src/third_party/xnnpack/src':
-    Var('chromium_git') + '/external/github.com/google/XNNPACK.git' + '@' + '60c997b99b3d98b8d146d267072cd4edb68535bd',
+    Var('chromium_git') + '/external/github.com/google/XNNPACK.git' + '@' + 'bbbaa7352a3ea729987d3e654d37be93e8009691',
 
   'src/tools/page_cycler/acid3':
     Var('chromium_git') + '/chromium/deps/acid3.git' + '@' + 'a926d0a32e02c4c03ae95bb798e6c780e0e184ba',
@@ -2109,7 +2109,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'QGRgA1kRHsKZGh5PYGL82JRNyzgftrF1z9j7CnlpNG4C',
+        'version': 'JYbJ1yh6mny09UbGObAmaZfVoAFQhCtUaGI0n099Je8C',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/docs/developer-ui.md b/android_webview/docs/developer-ui.md
index 546ea8a..5eb72965 100644
--- a/android_webview/docs/developer-ui.md
+++ b/android_webview/docs/developer-ui.md
@@ -158,13 +158,32 @@
 Finch experiment), we **highly encourage** you to [add to
 ProductionSupportedFlagList](/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java):
 
-1. You can list the feature flag name directly. This will be autochecked when
-   sending a Finch change to ensure it's not misspelt.
-2. See
+1. Add your feature to ProductionSupportedFlagList.java. You can list the
+   feature name as a string (This will be autochecked when sending a Finch
+   change to ensure it's not misspelt) or you can use a Java constant (e.g.,
+   `BlinkFeatures.NAME_OF_FEATURE`).
+   * If you're adding a feature which doesn't have an autogenerated constant,
+     you can either add the name as a string or you can follow instructions for
+     how to autogenerate the Java constants:
+     [instructions for switches](/docs/android_accessing_cpp_switches_in_java.md),
+     [instructions for features](/docs/android_accessing_cpp_features_in_java.md#generating-foo-feature-list-java)
+     (skip the "Checking if a Feature is enabled" section, start at the
+     "Auto-generating FooFeatureList.java" section).
+2. **Optional:** you can write a user-visible description of what the flag does.
+   This is completely optional and you may land a flag without a
+   description.
+3. **Optional:** See
    [this doc](/tools/metrics/histograms/README.md#Flag-Histograms) for more info
    about flag labels if you want histogram data about usage. This involves
    updating the "LoginCustomFlags" field in
    `/tools/metrics/histograms/enums.xml`.
+4. Create a CL. Any chromium committer can approve changes to
+   ProductionSupportedFlagList.java.
+5. If you've also made a Finch change, you can remove `WEBVIEW_FLAG_EXEMPT` from
+   that change. You don't need a flag exemption if you've exposed the flag in
+   ProductionSupportedFlagList.java. Alternatively, you may link to the CL which
+   updated ProductionSupportedFlagList.java:
+   `WEBVIEW_FLAG_EXEMPT=https://crrev.com/c/YOUR_CL_NUMBER`.
 
 Exposing your feature this way has several benefits:
 
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc
index 12de229a..5c6ed2f 100644
--- a/ash/app_list/app_list_controller_impl.cc
+++ b/ash/app_list/app_list_controller_impl.cc
@@ -1508,7 +1508,7 @@
 }
 
 int AppListControllerImpl::GetSystemShelfInsetsInTabletMode() {
-  return ShelfConfig::Get()->GetSystemShelfInsetsInTabletMode();
+  return ShelfConfig::Get()->GetTabletModeShelfInsetsAndRecordUMA();
 }
 
 bool AppListControllerImpl::IsInTabletMode() {
diff --git a/ash/components/arc/BUILD.gn b/ash/components/arc/BUILD.gn
index 3f5d7ba..0d6073e1 100644
--- a/ash/components/arc/BUILD.gn
+++ b/ash/components/arc/BUILD.gn
@@ -74,6 +74,8 @@
     "metrics/arc_metrics_anr.h",
     "metrics/arc_metrics_service.cc",
     "metrics/arc_metrics_service.h",
+    "metrics/arc_wm_metrics.cc",
+    "metrics/arc_wm_metrics.h",
     "metrics/stability_metrics_manager.cc",
     "metrics/stability_metrics_manager.h",
     "midis/arc_midis_bridge.cc",
@@ -436,6 +438,7 @@
     "memory_pressure/arc_memory_pressure_bridge_unittest.cc",
     "metrics/arc_metrics_anr_unittest.cc",
     "metrics/arc_metrics_service_unittest.cc",
+    "metrics/arc_wm_metrics_unittest.cc",
     "metrics/stability_metrics_manager_unittest.cc",
     "midis/arc_midis_bridge_unittest.cc",
     "net/always_on_vpn_manager_unittest.cc",
diff --git a/ash/components/arc/metrics/arc_metrics_service.cc b/ash/components/arc/metrics/arc_metrics_service.cc
index 562e0785..42cbf3a 100644
--- a/ash/components/arc/metrics/arc_metrics_service.cc
+++ b/ash/components/arc/metrics/arc_metrics_service.cc
@@ -13,6 +13,7 @@
 #include "ash/components/arc/arc_prefs.h"
 #include "ash/components/arc/arc_util.h"
 #include "ash/components/arc/metrics/arc_metrics_anr.h"
+#include "ash/components/arc/metrics/arc_wm_metrics.h"
 #include "ash/components/arc/metrics/stability_metrics_manager.h"
 #include "ash/components/arc/session/arc_bridge_service.h"
 #include "ash/public/cpp/app_types_util.h"
@@ -226,6 +227,8 @@
     psi_parser_ = std::make_unique<metrics::PSIMemoryParser>(
         kVmMemoryPSIReportsPeriod.Get());
   }
+
+  arc_wm_metrics_ = std::make_unique<ArcWmMetrics>();
 }
 
 ArcMetricsService::~ArcMetricsService() {
diff --git a/ash/components/arc/metrics/arc_metrics_service.h b/ash/components/arc/metrics/arc_metrics_service.h
index fdf7b0e..c092befc 100644
--- a/ash/components/arc/metrics/arc_metrics_service.h
+++ b/ash/components/arc/metrics/arc_metrics_service.h
@@ -14,6 +14,7 @@
 #include "ash/components/arc/arc_browser_context_keyed_service_factory_base.h"
 #include "ash/components/arc/metrics/arc_daily_metrics.h"
 #include "ash/components/arc/metrics/arc_metrics_constants.h"
+#include "ash/components/arc/metrics/arc_wm_metrics.h"
 #include "ash/components/arc/mojom/anr.mojom.h"
 #include "ash/components/arc/mojom/metrics.mojom.h"
 #include "ash/components/arc/mojom/process.mojom.h"
@@ -389,6 +390,9 @@
   raw_ptr<PrefService, ExperimentalAsh> prefs_ = nullptr;
   std::unique_ptr<ArcMetricsAnr> metrics_anr_;
 
+  // Tracks window management related metrics.
+  std::unique_ptr<ArcWmMetrics> arc_wm_metrics_;
+
   // For reporting Arc.Provisioning.PreSignInTimeDelta.
   absl::optional<base::TimeTicks> arc_provisioning_start_time_;
   absl::optional<std::string> arc_provisioning_account_type_suffix_;
diff --git a/ash/components/arc/metrics/arc_wm_metrics.cc b/ash/components/arc/metrics/arc_wm_metrics.cc
new file mode 100644
index 0000000..7eebad6
--- /dev/null
+++ b/ash/components/arc/metrics/arc_wm_metrics.cc
@@ -0,0 +1,181 @@
+// 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 "ash/components/arc/metrics/arc_wm_metrics.h"
+
+#include "ash/constants/app_types.h"
+#include "ash/public/cpp/app_types_util.h"
+#include "ash/wm/window_state.h"
+#include "ash/wm/window_state_observer.h"
+#include "base/functional/callback_forward.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/strings/strcat.h"
+#include "base/timer/elapsed_timer.h"
+#include "chromeos/ui/base/window_state_type.h"
+#include "ui/aura/client/aura_constants.h"
+#include "ui/base/ui_base_types.h"
+
+namespace arc {
+
+namespace {
+
+// Histogram of the delay for window maximizing operation.
+constexpr char kWindowMaximizedTimeHistogramPrefix[] =
+    "Arc.WM.WindowMaximizedDelayTime.";
+
+constexpr char kArcHistogramName[] = "ArcApp";
+constexpr char kBrowserHistogramName[] = "Browser";
+constexpr char kChromeAppHistogramName[] = "ChromeApp";
+constexpr char kSystemAppHistogramName[] = "SystemApp";
+constexpr char kCrostiniAppHistogramName[] = "CrostiniApp";
+
+std::string GetAppTypeName(ash::AppType app_type) {
+  switch (app_type) {
+    case ash::AppType::ARC_APP:
+      return kArcHistogramName;
+    case ash::AppType::BROWSER:
+      return kBrowserHistogramName;
+    case ash::AppType::CHROME_APP:
+      return kChromeAppHistogramName;
+    case ash::AppType::SYSTEM_APP:
+      return kSystemAppHistogramName;
+    case ash::AppType::CROSTINI_APP:
+      return kCrostiniAppHistogramName;
+    default:
+      return "Others";
+  }
+}
+
+}  // namespace
+
+// A window state observer that records the delay of window maximizing
+// operation.
+class ArcWmMetrics::WindowStateChangeObserver
+    : public ash::WindowStateObserver {
+ public:
+  WindowStateChangeObserver(aura::Window* window,
+                            ui::WindowShowState old_window_show_state,
+                            base::OnceClosure callback)
+      : window_(window),
+        old_window_show_state_(old_window_show_state),
+        window_operation_completed_callback_(std::move(callback)) {
+    auto* window_state = ash::WindowState::Get(window);
+    CHECK(window_state);
+    window_state_observation_.Observe(window_state);
+  }
+
+  WindowStateChangeObserver(const WindowStateChangeObserver&) = delete;
+  WindowStateChangeObserver& operator=(const WindowStateChangeObserver) =
+      delete;
+  ~WindowStateChangeObserver() override = default;
+
+  // ash::WindowStateObserver:
+  void OnPostWindowStateTypeChange(
+      ash::WindowState* new_window_state,
+      chromeos::WindowStateType old_window_state_type) override {
+    if (old_window_state_type ==
+        chromeos::ToWindowStateType(old_window_show_state_)) {
+      RecordWindowStateChangeDelay(new_window_state);
+    }
+
+    std::move(window_operation_completed_callback_).Run();
+  }
+
+ private:
+  void RecordWindowStateChangeDelay(ash::WindowState* state) {
+    const ash::AppType app_type =
+        static_cast<ash::AppType>(window_->GetProperty(aura::client::kAppType));
+    if (state->IsMaximized()) {
+      base::UmaHistogramCustomTimes(
+          ArcWmMetrics::GetWindowMaximizedTimeHistogramName(app_type),
+          window_operation_elapsed_timer_.Elapsed(),
+          /*minimum=*/base::Milliseconds(1),
+          /*maximum=*/base::Seconds(2), 100);
+    }
+  }
+
+  const raw_ptr<aura::Window, ExperimentalAsh> window_;
+  const ui::WindowShowState old_window_show_state_;
+
+  // Tracks the elapsed time from the window maximizing operation happens until
+  // the window state is changed.
+  base::ElapsedTimer window_operation_elapsed_timer_;
+
+  base::ScopedObservation<ash::WindowState, ash::WindowStateObserver>
+      window_state_observation_{this};
+
+  base::OnceClosure window_operation_completed_callback_;
+};
+
+ArcWmMetrics::ArcWmMetrics() {
+  if (aura::Env::HasInstance()) {
+    env_observation_.Observe(aura::Env::GetInstance());
+  }
+}
+
+ArcWmMetrics::~ArcWmMetrics() = default;
+
+// static
+std::string ArcWmMetrics::GetWindowMaximizedTimeHistogramName(
+    ash::AppType app_type) {
+  const std::string app_type_str = GetAppTypeName(app_type);
+  return base::StrCat({kWindowMaximizedTimeHistogramPrefix, app_type_str});
+}
+
+void ArcWmMetrics::OnWindowInitialized(aura::Window* new_window) {
+  if (static_cast<ash::AppType>(new_window->GetProperty(
+          aura::client::kAppType)) == ash::AppType::NON_APP) {
+    return;
+  }
+
+  if (window_observations_.IsObservingSource(new_window)) {
+    return;
+  }
+
+  window_observations_.AddObservation(new_window);
+}
+
+void ArcWmMetrics::OnWindowPropertyChanged(aura::Window* window,
+                                           const void* key,
+                                           intptr_t old) {
+  if (key != aura::client::kShowStateKey) {
+    return;
+  }
+
+  if (state_change_observing_windows_.contains(window)) {
+    return;
+  }
+
+  const auto new_window_show_state =
+      window->GetProperty(aura::client::kShowStateKey);
+  const auto old_window_show_state = static_cast<ui::WindowShowState>(old);
+
+  // We do not measure the case that window state is maximized on the app is
+  // launched.
+  if (new_window_show_state == old_window_show_state ||
+      old_window_show_state == ui::WindowShowState::SHOW_STATE_DEFAULT) {
+    return;
+  }
+
+  if (new_window_show_state == ui::WindowShowState::SHOW_STATE_MAXIMIZED) {
+    state_change_observing_windows_.emplace(
+        window, std::make_unique<WindowStateChangeObserver>(
+                    window, old_window_show_state,
+                    base::BindOnce(&ArcWmMetrics::OnOperationCompleted,
+                                   base::Unretained(this), window)));
+  }
+}
+
+void ArcWmMetrics::OnWindowDestroying(aura::Window* window) {
+  state_change_observing_windows_.erase(window);
+  if (window_observations_.IsObservingSource(window)) {
+    window_observations_.RemoveObservation(window);
+  }
+}
+
+void ArcWmMetrics::OnOperationCompleted(aura::Window* window) {
+  state_change_observing_windows_.erase(window);
+}
+
+}  // namespace arc
diff --git a/ash/components/arc/metrics/arc_wm_metrics.h b/ash/components/arc/metrics/arc_wm_metrics.h
new file mode 100644
index 0000000..d1250af
--- /dev/null
+++ b/ash/components/arc/metrics/arc_wm_metrics.h
@@ -0,0 +1,57 @@
+// 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 ASH_COMPONENTS_ARC_METRICS_ARC_WM_METRICS_H_
+#define ASH_COMPONENTS_ARC_METRICS_ARC_WM_METRICS_H_
+
+#include <memory>
+#include <string>
+
+#include "ash/constants/app_types.h"
+#include "base/scoped_multi_source_observation.h"
+#include "base/scoped_observation.h"
+#include "ui/aura/env.h"
+#include "ui/aura/env_observer.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_observer.h"
+
+namespace arc {
+
+class ArcWmMetrics : public aura::EnvObserver, public aura::WindowObserver {
+ public:
+  ArcWmMetrics();
+  ArcWmMetrics(const ArcWmMetrics&) = delete;
+  ArcWmMetrics& operator=(const ArcWmMetrics&) = delete;
+  ~ArcWmMetrics() override;
+
+  static std::string GetWindowMaximizedTimeHistogramName(ash::AppType app_type);
+
+  // aura::EnvObserver
+  void OnWindowInitialized(aura::Window* new_window) override;
+
+  // aura::WindowObserver:
+  void OnWindowPropertyChanged(aura::Window* window,
+                               const void* key,
+                               intptr_t old) override;
+  void OnWindowDestroying(aura::Window* window) override;
+
+ private:
+  class WindowStateChangeObserver;
+
+  void OnOperationCompleted(aura::Window* window);
+
+  // The map of windows that being observed by WindowStateChangeObserver and
+  // their corresponding observers.
+  base::flat_map<aura::Window*, std::unique_ptr<WindowStateChangeObserver>>
+      state_change_observing_windows_;
+
+  base::ScopedObservation<aura::Env, aura::EnvObserver> env_observation_{this};
+
+  base::ScopedMultiSourceObservation<aura::Window, aura::WindowObserver>
+      window_observations_{this};
+};
+
+}  // namespace arc
+
+#endif  // ASH_COMPONENTS_ARC_METRICS_ARC_WM_METRICS_H_
diff --git a/ash/components/arc/metrics/arc_wm_metrics_unittest.cc b/ash/components/arc/metrics/arc_wm_metrics_unittest.cc
new file mode 100644
index 0000000..d2edff7
--- /dev/null
+++ b/ash/components/arc/metrics/arc_wm_metrics_unittest.cc
@@ -0,0 +1,53 @@
+// 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 "ash/components/arc/metrics/arc_wm_metrics.h"
+
+#include <memory>
+
+#include "ash/constants/app_types.h"
+#include "ash/test/ash_test_base.h"
+#include "ash/wm/wm_event.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/window.h"
+
+namespace arc {
+
+class ArcWmMetricsTest : public ash::AshTestBase {
+ public:
+  ArcWmMetricsTest() = default;
+  ArcWmMetricsTest(const ArcWmMetricsTest&) = delete;
+  ArcWmMetricsTest& operator=(const ArcWmMetricsTest&) = delete;
+  ~ArcWmMetricsTest() override = default;
+
+  void SetUp() override {
+    ash::AshTestBase::SetUp();
+    arc_wm_metrics_ = std::make_unique<ArcWmMetrics>();
+  }
+
+ private:
+  std::unique_ptr<ArcWmMetrics> arc_wm_metrics_;
+};
+
+TEST_F(ArcWmMetricsTest, TestWindowMaximizeDelayMetrics) {
+  ash::AppType app_type = ash::AppType::ARC_APP;
+  auto window = CreateAppWindow(gfx::Rect(0, 0, 100, 100), app_type);
+  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
+  window->SetProperty(aura::client::kResizeBehaviorKey,
+                      aura::client::kResizeBehaviorCanMaximize);
+  window->Show();
+
+  base::HistogramTester histogram_tester;
+  const auto histogram_name =
+      ArcWmMetrics::GetWindowMaximizedTimeHistogramName(app_type);
+  histogram_tester.ExpectTotalCount(histogram_name, 0);
+
+  auto maximize_event = std::make_unique<ash::WMEvent>(ash::WM_EVENT_MAXIMIZE);
+  ash::WindowState::Get(window.get())->OnWMEvent(maximize_event.get());
+  histogram_tester.ExpectTotalCount(histogram_name, 1);
+}
+
+}  // namespace arc
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index b83f55e1b..13843fc9 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -879,6 +879,11 @@
              "EnterpriseReportingUI",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+// Controls whether ephemeral network configuration policies are respected.
+BASE_FEATURE(kEphemeralNetworkPolicies,
+             "kEphemeralNetworkPolicies",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 // Enables Device End Of Lifetime warning notifications.
 BASE_FEATURE(kEolWarningNotifications,
              "EolWarningNotifications",
@@ -3644,6 +3649,10 @@
   return base::FeatureList::IsEnabled(kEcheShorterScanningDutyCycle);
 }
 
+bool AreEphemeralNetworkPoliciesEnabled() {
+  return base::FeatureList::IsEnabled(kEphemeralNetworkPolicies);
+}
+
 bool IsNearbyKeepAliveFixEnabled() {
   return base::FeatureList::IsEnabled(kNearbyKeepAliveFix);
 }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index 495299f..22058e7 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -302,6 +302,8 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kFastPairLowPower);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kEnterpriseReportingUI);
 COMPONENT_EXPORT(ASH_CONSTANTS)
+BASE_DECLARE_FEATURE(kEphemeralNetworkPolicies);
+COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::FeatureParam<double> kFastPairLowPowerActiveSeconds;
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::FeatureParam<double> kFastPairLowPowerInactiveSeconds;
@@ -957,6 +959,8 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsEcheNetworkConnectionStateEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS)
 bool IsEcheShorterScanningDutyCycleEnabled();
+COMPONENT_EXPORT(ASH_CONSTANTS)
+bool AreEphemeralNetworkPoliciesEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFullscreenAfterUnlockAllowed();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFullscreenAlertBubbleEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsBlockFwupdClientEnabled();
diff --git a/ash/public/cpp/shelf_config.h b/ash/public/cpp/shelf_config.h
index dceea4f..760a42b0 100644
--- a/ash/public/cpp/shelf_config.h
+++ b/ash/public/cpp/shelf_config.h
@@ -242,8 +242,9 @@
   // Size of the shelf in tablet mode.
   int GetSystemShelfSizeInTabletMode() const;
 
-  // Size of the insets used in tablet mode to allocate space to the shelf.
-  int GetSystemShelfInsetsInTabletMode() const;
+  // Records the UMA of showing the stacked hotseat app bar and returns the size
+  // of the insets used in tablet mode to allocate space to the shelf.
+  int GetTabletModeShelfInsetsAndRecordUMA();
 
   // Minimum size for the inline app bar.
   int GetMinimumInlineAppBarSize() const;
@@ -281,6 +282,10 @@
   bool CalculateIsInApp(bool app_list_visible,
                         bool virtual_keyboard_shown) const;
 
+  // Whether an elevated app bar has been rendered (stacked hotseat). This
+  // boolean is used for logging UMA metrics.
+  absl::optional<bool> has_shown_elevated_app_bar_;
+
   // Whether tablet mode homecher should use elevated app bar.
   bool elevate_tablet_mode_app_bar_ = false;
 
diff --git a/ash/shelf/hotseat_widget_unittest.cc b/ash/shelf/hotseat_widget_unittest.cc
index cf7f036..98cd421 100644
--- a/ash/shelf/hotseat_widget_unittest.cc
+++ b/ash/shelf/hotseat_widget_unittest.cc
@@ -361,6 +361,10 @@
 // TODO(b:270757104) Set status are widget sizes.
 TEST_P(StackedHotseatWidgetTest, StackedHotseatShownOnSmallScreens) {
   UpdateDisplay("475x350");
+  base::HistogramTester histogram_tester;
+  // Nothing logged before entering the tablet mode.
+  histogram_tester.ExpectTotalCount("Ash.Shelf.ShowStackedHotseat", 0);
+
   TabletModeControllerTestApi().EnterTabletMode();
   GetAppListTestHelper()->CheckVisibility(true);
   const gfx::Rect hotseat_bounds = GetPrimaryShelf()
@@ -370,11 +374,20 @@
   ASSERT_EQ(hotseat_bounds.bottom(),
             350 - ShelfConfig::Get()->hotseat_bottom_padding() * 2 -
                 ShelfConfig::Get()->shelf_size());
+
+  // Showed stacked hostseat.
+  histogram_tester.ExpectBucketCount("Ash.Shelf.ShowStackedHotseat", true, 1);
+  histogram_tester.ExpectBucketCount("Ash.Shelf.ShowStackedHotseat", false, 0);
 }
 
 // TODO(b:270757104) Set status are widget sizes.
 TEST_P(StackedHotseatWidgetTest, StackedHotseatNotShownOnLargeScreens) {
   UpdateDisplay("800x600");
+
+  base::HistogramTester histogram_tester;
+  // Nothing logged before entering the tablet mode.
+  histogram_tester.ExpectTotalCount("Ash.Shelf.ShowStackedHotseat", 0);
+
   TabletModeControllerTestApi().EnterTabletMode();
   GetAppListTestHelper()->CheckVisibility(true);
   const gfx::Rect hotseat_bounds = GetPrimaryShelf()
@@ -383,6 +396,10 @@
                                        ->GetWindowBoundsInScreen();
   ASSERT_EQ(hotseat_bounds.bottom(),
             600 - ShelfConfig::Get()->hotseat_bottom_padding());
+
+  // Showed regular hotseat.
+  histogram_tester.ExpectBucketCount("Ash.Shelf.ShowStackedHotseat", true, 0);
+  histogram_tester.ExpectBucketCount("Ash.Shelf.ShowStackedHotseat", false, 1);
 }
 
 TEST_P(HotseatWidgetTest, LongPressHomeWithoutAppWindow) {
diff --git a/ash/shelf/shelf_config.cc b/ash/shelf/shelf_config.cc
index 7cc397e..d7104ad 100644
--- a/ash/shelf/shelf_config.cc
+++ b/ash/shelf/shelf_config.cc
@@ -19,6 +19,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/scoped_observation.h"
 #include "chromeos/constants/chromeos_features.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/chromeos/styles/cros_tokens_color_mappings.h"
 
 namespace ash {
@@ -230,6 +231,8 @@
   in_tablet_mode_ = false;
 
   UpdateConfig(is_app_list_visible_, /*tablet_mode_changed=*/true);
+
+  has_shown_elevated_app_bar_ = absl::nullopt;
 }
 
 void ShelfConfig::OnDisplayMetricsChanged(const display::Display& display,
@@ -516,12 +519,18 @@
                                    : kSystemShelfSizeTabletModeNormal;
 }
 
-int ShelfConfig::GetSystemShelfInsetsInTabletMode() const {
-  if (elevate_tablet_mode_app_bar_) {
-    return kElevatedSystemShelfSizeTabletMode;
-  } else {
-    return GetSystemShelfSizeInTabletMode();
+int ShelfConfig::GetTabletModeShelfInsetsAndRecordUMA() {
+  if (!has_shown_elevated_app_bar_.has_value() ||
+      has_shown_elevated_app_bar_.value() != elevate_tablet_mode_app_bar_) {
+    has_shown_elevated_app_bar_ = elevate_tablet_mode_app_bar_;
+    // This method can be called more than once during the app bar rendering.
+    // Records only once when `elevate_tablet_mode_app_bar_` changes.
+    base::UmaHistogramBoolean("Ash.Shelf.ShowStackedHotseat",
+                              elevate_tablet_mode_app_bar_);
   }
+
+  return elevate_tablet_mode_app_bar_ ? kElevatedSystemShelfSizeTabletMode
+                                      : GetSystemShelfSizeInTabletMode();
 }
 
 int ShelfConfig::GetMinimumInlineAppBarSize() const {
diff --git a/ash/system/focus_mode/focus_mode_detailed_view.cc b/ash/system/focus_mode/focus_mode_detailed_view.cc
index 8c2f615b..8ae29f2 100644
--- a/ash/system/focus_mode/focus_mode_detailed_view.cc
+++ b/ash/system/focus_mode/focus_mode_detailed_view.cc
@@ -75,7 +75,7 @@
     const base::Time end_time = now + session_duration_remaining;
     return l10n_util::GetStringFUTF16(
         IDS_ASH_STATUS_TRAY_FOCUS_MODE_TOGGLE_TIME_SUBLABEL, time_string,
-        base::TimeFormatTimeOfDay(end_time));
+        focus_mode_util::GetFormattedClockString(end_time));
   }
 
   return base::NumberToString16(
diff --git a/ash/system/focus_mode/focus_mode_detailed_view_unittest.cc b/ash/system/focus_mode/focus_mode_detailed_view_unittest.cc
index 25f3452..3f36936 100644
--- a/ash/system/focus_mode/focus_mode_detailed_view_unittest.cc
+++ b/ash/system/focus_mode/focus_mode_detailed_view_unittest.cc
@@ -7,9 +7,12 @@
 #include <memory>
 
 #include "ash/constants/ash_features.h"
+#include "ash/shell.h"
 #include "ash/style/pill_button.h"
 #include "ash/style/switch.h"
 #include "ash/system/focus_mode/focus_mode_controller.h"
+#include "ash/system/focus_mode/focus_mode_util.h"
+#include "ash/system/model/system_tray_model.h"
 #include "ash/system/tray/fake_detailed_view_delegate.h"
 #include "ash/system/tray/hover_highlight_view.h"
 #include "ash/test/ash_test_base.h"
@@ -146,17 +149,17 @@
     EXPECT_EQ(active, focus_mode_controller->in_focus_session());
     EXPECT_EQ(active ? u"Focusing" : u"Focus", label->GetText());
 
+    const base::Time now = base::Time::Now();
     const base::TimeDelta session_duration =
         focus_mode_controller->session_duration();
     const int remaining_minutes =
-        active ? (focus_mode_controller->end_time() - base::Time::Now())
-                     .InMinutes()
+        active ? (focus_mode_controller->end_time() - now).InMinutes()
                : session_duration.InMinutes();
 
     EXPECT_EQ(base::UTF8ToUTF16(base::StringPrintf(
                   "%d min ⋅ Until %s", remaining_minutes,
-                  base::UTF16ToUTF8(base::TimeFormatTimeOfDay(
-                                        base::Time::Now() + session_duration))
+                  base::UTF16ToUTF8(focus_mode_util::GetFormattedClockString(
+                                        now + session_duration))
                       .c_str())),
               sub_label->GetText());
     EXPECT_EQ(active ? u"End" : u"Start", toggle_button->GetText());
@@ -172,6 +175,18 @@
 
   LeftClickOn(toggle_button);
   validate_labels(/*active=*/false);
+
+  // Verify that the time displays correctly in the 24-hour clock format.
+  Shell::Get()->system_tray_model()->SetUse24HourClock(true);
+
+  LeftClickOn(toggle_button);
+  // Wait a second to avoid the time remaining being either 1500 seconds or
+  // 1499.99 seconds.
+  task_environment()->FastForwardBy(base::Seconds(1));
+  validate_labels(/*active=*/true);
+
+  LeftClickOn(toggle_button);
+  validate_labels(/*active=*/false);
 }
 
 }  // namespace ash
diff --git a/ash/system/focus_mode/focus_mode_util.cc b/ash/system/focus_mode/focus_mode_util.cc
index f1f9348..3bb93da 100644
--- a/ash/system/focus_mode/focus_mode_util.cc
+++ b/ash/system/focus_mode/focus_mode_util.cc
@@ -92,13 +92,16 @@
   return U_SUCCESS(status);
 }
 
-std::u16string GetNotificationTitleForFocusSession(const base::Time& end_time) {
-  const std::u16string time_str = base::TimeFormatTimeOfDayWithHourClockType(
+std::u16string GetFormattedClockString(const base::Time end_time) {
+  return base::TimeFormatTimeOfDayWithHourClockType(
       end_time, Shell::Get()->system_tray_model()->clock()->hour_clock_type(),
       base::kKeepAmPm);
+}
 
+std::u16string GetNotificationTitleForFocusSession(const base::Time end_time) {
   return l10n_util::GetStringFUTF16(
-      IDS_ASH_DO_NOT_DISTURB_NOTIFICATION_IN_FOCUS_MODE_TITLE, time_str);
+      IDS_ASH_DO_NOT_DISTURB_NOTIFICATION_IN_FOCUS_MODE_TITLE,
+      GetFormattedClockString(end_time));
 }
 
 }  // namespace ash::focus_mode_util
diff --git a/ash/system/focus_mode/focus_mode_util.h b/ash/system/focus_mode/focus_mode_util.h
index 17ebbc5..6941426 100644
--- a/ash/system/focus_mode/focus_mode_util.h
+++ b/ash/system/focus_mode/focus_mode_util.h
@@ -48,10 +48,14 @@
     TimeFormatType format_type,
     std::u16string& out_duration_string);
 
+// Returns a string of `end_time` formatted with the correct clock type. For
+// example: "5:10 PM" for 12-hour clock, "17:10" for 24-hour clock.
+ASH_EXPORT std::u16string GetFormattedClockString(const base::Time end_time);
+
 // Returns a string indicating that do not disturb will be turned off when the
 // focus session ends at `end_time`.
 ASH_EXPORT std::u16string GetNotificationTitleForFocusSession(
-    const base::Time& end_time);
+    const base::Time end_time);
 
 }  // namespace ash::focus_mode_util
 
diff --git a/ash/system/input_device_settings/input_device_settings_controller_impl.cc b/ash/system/input_device_settings/input_device_settings_controller_impl.cc
index 292ba5f..a3e85d8 100644
--- a/ash/system/input_device_settings/input_device_settings_controller_impl.cc
+++ b/ash/system/input_device_settings/input_device_settings_controller_impl.cc
@@ -1115,9 +1115,12 @@
     return;
   }
 
+  const auto old_settings = std::move(found_graphics_tablet.settings);
   found_graphics_tablet.settings = settings.Clone();
   graphics_tablet_pref_handler_->UpdateGraphicsTabletSettings(
       active_pref_service_, found_graphics_tablet);
+  metrics_manager_->RecordGraphicsTabletChangedMetrics(found_graphics_tablet,
+                                                       *old_settings);
   DispatchGraphicsTabletSettingsChanged(id);
 
   UpdateDuplicateDeviceSettings(
@@ -1494,6 +1497,7 @@
   if (active_pref_service_) {
     graphics_tablet_pref_handler_->InitializeGraphicsTabletSettings(
         active_pref_service_, graphics_tablet);
+    metrics_manager_->RecordGraphicsTabletInitialMetrics(*graphics_tablet);
     return;
   }
 
diff --git a/ash/system/input_device_settings/input_device_settings_metrics_manager.cc b/ash/system/input_device_settings/input_device_settings_metrics_manager.cc
index 3b46750..f7b63a6 100644
--- a/ash/system/input_device_settings/input_device_settings_metrics_manager.cc
+++ b/ash/system/input_device_settings/input_device_settings_metrics_manager.cc
@@ -639,6 +639,28 @@
   }
 }
 
+void InputDeviceSettingsMetricsManager::RecordGraphicsTabletInitialMetrics(
+    const mojom::GraphicsTablet& graphics_tablet) {
+  // Only record the metrics once for each graphics tablet.
+  const auto account_id =
+      Shell::Get()->session_controller()->GetActiveAccountId();
+  auto iter = recorded_graphics_tablets_.find(account_id);
+
+  if (iter != recorded_graphics_tablets_.end() &&
+      base::Contains(iter->second, graphics_tablet.device_key)) {
+    return;
+  }
+  recorded_graphics_tablets_[account_id].insert(graphics_tablet.device_key);
+
+  // TODO(cambickel): Add graphics tablet initial metrics logging.
+}
+
+void InputDeviceSettingsMetricsManager::RecordGraphicsTabletChangedMetrics(
+    const mojom::GraphicsTablet& graphics_tablet,
+    const mojom::GraphicsTabletSettings& old_settings) {
+  // TODO(cambickel): Add graphics tablet changed metrics logging.
+}
+
 void InputDeviceSettingsMetricsManager::RecordModifierRemappingHash(
     const mojom::Keyboard& keyboard) {
   // Compute hash by left-shifting by `kModifierHashWidth` and then inserting
diff --git a/ash/system/input_device_settings/input_device_settings_metrics_manager.h b/ash/system/input_device_settings/input_device_settings_metrics_manager.h
index a5fe8eee..a6a334d 100644
--- a/ash/system/input_device_settings/input_device_settings_metrics_manager.h
+++ b/ash/system/input_device_settings/input_device_settings_metrics_manager.h
@@ -46,6 +46,11 @@
   void RecordTouchpadChangedMetrics(
       const mojom::Touchpad& touchpad,
       const mojom::TouchpadSettings& old_settings);
+  void RecordGraphicsTabletInitialMetrics(
+      const mojom::GraphicsTablet& graphics_tablet);
+  void RecordGraphicsTabletChangedMetrics(
+      const mojom::GraphicsTablet& graphics_tablet,
+      const mojom::GraphicsTabletSettings& old_settings);
   void RecordKeyboardMouseComboDeviceMetric(const mojom::Keyboard& keyboard,
                                             const mojom::Mouse& mouse);
 
@@ -55,6 +60,8 @@
   base::flat_map<AccountId, base::flat_set<std::string>>
       recorded_pointing_sticks_;
   base::flat_map<AccountId, base::flat_set<std::string>> recorded_touchpads_;
+  base::flat_map<AccountId, base::flat_set<std::string>>
+      recorded_graphics_tablets_;
 };
 
 }  // namespace ash
diff --git a/ash/webui/shortcut_customization_ui/resources/css/shortcut_customization_shared.css b/ash/webui/shortcut_customization_ui/resources/css/shortcut_customization_shared.css
index 959dbc7..3d5ece2 100644
--- a/ash/webui/shortcut_customization_ui/resources/css/shortcut_customization_shared.css
+++ b/ash/webui/shortcut_customization_ui/resources/css/shortcut_customization_shared.css
@@ -52,7 +52,6 @@
   align-items: center;
   display: flex;
   margin-inline-start: 8px;
-  padding-inline-end: 10px;
 }
 
 .lock-icon-container[hidden] {
@@ -63,7 +62,6 @@
   align-items: center;
   display: flex;
   margin-inline-start: 8px;
-  padding-inline-end: 10px;
 }
 
 .edit-icon-container[hidden] {
diff --git a/ash/webui/shortcut_customization_ui/resources/js/accelerator_row.html b/ash/webui/shortcut_customization_ui/resources/js/accelerator_row.html
index 3d7e91a2a..5d10a82 100644
--- a/ash/webui/shortcut_customization_ui/resources/js/accelerator_row.html
+++ b/ash/webui/shortcut_customization_ui/resources/js/accelerator_row.html
@@ -5,6 +5,7 @@
     display: grid;
     grid-auto-rows: minmax(52px, auto);
     grid-template-columns: minmax(min-content, 286px) 50%;
+    padding: 0 20px;
   }
 
   /* Show edit-button when user hover on the row container. */
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc
index 402869c5..aa9b8881 100644
--- a/base/allocator/partition_allocator/partition_alloc_unittest.cc
+++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -351,6 +351,10 @@
   }
 
   void InitializeMainTestAllocators() {
+#if BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
+    PartitionOptions::EnableToggle enable_backup_ref_ptr =
+        PartitionOptions::kEnabled;
+#endif
 #if BUILDFLAG(ENABLE_PKEYS)
     int pkey = PkeyAlloc(UseThreadIsolatedPool() ? 0 : PKEY_DISABLE_WRITE);
     if (pkey != -1) {
@@ -371,6 +375,11 @@
     ThreadIsolationOption thread_isolation_opt;
     if (UseThreadIsolatedPool() && pkey_ != kInvalidPkey) {
       thread_isolation_opt = ThreadIsolationOption(pkey_);
+#if BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
+      // BRP and thread isolated mode use different pools, so they can't be
+      // enabled at the same time.
+      enable_backup_ref_ptr = PartitionOptions::kDisabled;
+#endif
     }
 #endif  // BUILDFLAG(ENABLE_PKEYS)
     InitializeTestRoot(
@@ -384,7 +393,7 @@
           .aligned_alloc = PartitionOptions::kAllowed,
 #endif
 #if BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
-          .backup_ref_ptr = PartitionOptions::kEnabled,
+          .backup_ref_ptr = enable_backup_ref_ptr,
 #endif
           .ref_count_size = GetParam().ref_count_size,
 #if BUILDFLAG(ENABLE_PKEYS)
diff --git a/chrome/VERSION b/chrome/VERSION
index f18b288..3225b4c 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=119
 MINOR=0
-BUILD=6031
+BUILD=6032
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index fe92eab..b9d64871 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -248,6 +248,7 @@
   java_group("delegate_public_impl_java") {
     deps = [
       ":app_hooks_java",
+      "//chrome/android/modules/readaloud/public:provider_public_java",
       "//chrome/browser/accessibility/hierarchysnapshotter/android:delegate_public_impl_java",
       "//chrome/browser/auxiliary_search:delegate_public_impl_java",
       "//chrome/browser/feedback/android:delegate_public_impl_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragment.java
index a7a8004..701bbd1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragment.java
@@ -25,6 +25,7 @@
 import androidx.preference.PreferenceScreen;
 
 import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.base.BuildInfo;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.autofill.AutofillEditorBase;
@@ -155,39 +156,16 @@
         }
 
         // TODO(crbug.com/1427216): Confirm with Product on the order of the toggles.
-        if (ChromeFeatureList.isEnabled(
-                    ChromeFeatureList.AUTOFILL_ENABLE_PAYMENTS_MANDATORY_REAUTH)) {
-            if (mReauthenticatorBridge == null) {
-                mReauthenticatorBridge = ReauthenticatorBridge.create(DeviceAuthSource.AUTOFILL);
-            }
-            ChromeSwitchPreference mandatoryReauthSwitch =
-                    new ChromeSwitchPreference(getStyledContext(), null);
-            mandatoryReauthSwitch.setTitle(
-                    R.string.autofill_settings_page_enable_payment_method_mandatory_reauth_label);
-            mandatoryReauthSwitch.setSummary(
-                    R.string.autofill_settings_page_enable_payment_method_mandatory_reauth_sublabel);
-            mandatoryReauthSwitch.setKey(PREF_MANDATORY_REAUTH);
-            // We always display the toggle, but the toggle is only enabled when Autofill credit
-            // card is enabled AND the device supports biometric auth or screen lock. If either of
-            // these is not met, we will grey out the toggle.
-            boolean enableReauthSwitch = PersonalDataManager.isAutofillCreditCardEnabled()
-                    && mReauthenticatorBridge.canUseAuthenticationWithBiometricOrScreenLock();
-            mandatoryReauthSwitch.setEnabled(enableReauthSwitch);
-            mandatoryReauthSwitch.setOnPreferenceChangeListener(
-                    this::onMandatoryReauthSwitchToggled);
-            getPreferenceScreen().addPreference(mandatoryReauthSwitch);
-
-            // Every {@link SwitchPreferenceCompat} on a {@link PreferenceScreen} has a pref that is
-            // automatically added to the {@link SharedPreferences}. When a switch is added, by
-            // default its checked state is reset to the saved pref value irrespective of whether or
-            // not the switch's checked state was set before adding the switch. Setting the checked
-            // state after adding the switch updates the underlying pref as well.
-            // If a user opts in to mandatory reauth during the checkout flow, since the switch's
-            // underlying pref is still false, the switch does not reflect the opt-in. Set switch's
-            // checked state after adding it to the screen so the underlying pref value is also
-            // updated and is in sync with the mandatory reauth user pref.
-            mandatoryReauthSwitch.setChecked(
-                    PersonalDataManager.isPaymentMethodsMandatoryReauthEnabled());
+        // Don't show the toggle to enable mandatory reauth on automotive,
+        // as the feature is always enabled for automotive builds.
+        if (BuildInfo.getInstance().isAutomotive) {
+            // The ReauthenticatorBridge is still needed for reauthentication to view/edit
+            // payment methods.
+            createReauthenticatorBridge();
+        } else if (ChromeFeatureList.isEnabled(
+                           ChromeFeatureList.AUTOFILL_ENABLE_PAYMENTS_MANDATORY_REAUTH)) {
+            createReauthenticatorBridge();
+            createMandatoryReauthSwitch();
         }
 
         if (ChromeFeatureList.isEnabled(ChromeFeatureList.AUTOFILL_ENABLE_CVC_STORAGE)) {
@@ -283,6 +261,42 @@
         refreshPaymentAppsPrefForAndroidPaymentApps(payment_apps_pref);
     }
 
+    private void createReauthenticatorBridge() {
+        if (mReauthenticatorBridge == null) {
+            mReauthenticatorBridge = ReauthenticatorBridge.create(DeviceAuthSource.AUTOFILL);
+        }
+    }
+
+    private void createMandatoryReauthSwitch() {
+        ChromeSwitchPreference mandatoryReauthSwitch =
+                new ChromeSwitchPreference(getStyledContext(), null);
+        mandatoryReauthSwitch.setTitle(
+                R.string.autofill_settings_page_enable_payment_method_mandatory_reauth_label);
+        mandatoryReauthSwitch.setSummary(
+                R.string.autofill_settings_page_enable_payment_method_mandatory_reauth_sublabel);
+        mandatoryReauthSwitch.setKey(PREF_MANDATORY_REAUTH);
+        // We always display the toggle, but the toggle is only enabled when Autofill credit
+        // card is enabled AND the device supports biometric auth or screen lock. If either of
+        // these is not met, we will grey out the toggle.
+        boolean enableReauthSwitch = PersonalDataManager.isAutofillCreditCardEnabled()
+                && mReauthenticatorBridge.canUseAuthenticationWithBiometricOrScreenLock();
+        mandatoryReauthSwitch.setEnabled(enableReauthSwitch);
+        mandatoryReauthSwitch.setOnPreferenceChangeListener(this::onMandatoryReauthSwitchToggled);
+        getPreferenceScreen().addPreference(mandatoryReauthSwitch);
+
+        // Every {@link SwitchPreferenceCompat} on a {@link PreferenceScreen} has a pref that is
+        // automatically added to the {@link SharedPreferences}. When a switch is added, by
+        // default its checked state is reset to the saved pref value irrespective of whether or
+        // not the switch's checked state was set before adding the switch. Setting the checked
+        // state after adding the switch updates the underlying pref as well.
+        // If a user opts in to mandatory reauth during the checkout flow, since the switch's
+        // underlying pref is still false, the switch does not reflect the opt-in. Set switch's
+        // checked state after adding it to the screen so the underlying pref value is also
+        // updated and is in sync with the mandatory reauth user pref.
+        mandatoryReauthSwitch.setChecked(
+                PersonalDataManager.isPaymentMethodsMandatoryReauthEnabled());
+    }
+
     private Context getStyledContext() {
         return getPreferenceManager().getContext();
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/SettingsLauncherHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/SettingsLauncherHelper.java
index f2bc3f38..1f05a78 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/SettingsLauncherHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/SettingsLauncherHelper.java
@@ -9,14 +9,11 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
-import org.chromium.base.BuildInfo;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.metrics.RecordUserAction;
-import org.chromium.chrome.browser.device_lock.DeviceLockActivityLauncherImpl;
 import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
 import org.chromium.components.browser_ui.settings.SettingsLauncher;
 import org.chromium.content_public.browser.WebContents;
-import org.chromium.ui.base.WindowAndroid;
 
 /** Launches autofill settings subpages. */
 public class SettingsLauncherHelper {
@@ -41,28 +38,15 @@
      * Tries showing the settings page for Payments.
      *
      * @param context The {@link Context} required to start the settings page. Noop without it.
-     * @param windowAndroid The {@link WindowAndroid} required to start the settings page on
-     *        automotive devices. Noop without it.
      * @return True iff the context is valid and `launchSettingsActivity` was called.
      */
-    public static boolean showAutofillCreditCardSettings(
-            @Nullable Context context, @Nullable WindowAndroid windowAndroid) {
+    public static boolean showAutofillCreditCardSettings(@Nullable Context context) {
         if (context == null) {
             return false;
         }
-        if (BuildInfo.getInstance().isAutomotive) {
-            DeviceLockActivityLauncherImpl.get().presentDeviceLockChallenge(context,
-                    /* requireDeviceLockReauthentication */ true, windowAndroid,
-                    () -> launchSettingsActivity(context));
-        } else {
-            launchSettingsActivity(context);
-        }
-        return true;
-    }
-
-    private static void launchSettingsActivity(Context context) {
         RecordUserAction.record("AutofillCreditCardsViewed");
         getLauncher().launchSettingsActivity(context, AutofillPaymentMethodsFragment.class);
+        return true;
     }
 
     @CalledByNative
@@ -72,8 +56,7 @@
 
     @CalledByNative
     private static void showAutofillCreditCardSettings(WebContents webContents) {
-        showAutofillCreditCardSettings(webContents.getTopLevelNativeWindow().getActivity().get(),
-                webContents.getTopLevelNativeWindow());
+        showAutofillCreditCardSettings(webContents.getTopLevelNativeWindow().getActivity().get());
     }
 
     private static SettingsLauncher getLauncher() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/device_lock/DeviceLockActivityLauncherImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/device_lock/DeviceLockActivityLauncherImpl.java
index b0da1fe..6b59c3f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/device_lock/DeviceLockActivityLauncherImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/device_lock/DeviceLockActivityLauncherImpl.java
@@ -4,16 +4,12 @@
 
 package org.chromium.chrome.browser.device_lock;
 
-import android.app.Activity;
-import android.app.KeyguardManager;
 import android.content.Context;
 import android.content.Intent;
 
 import androidx.annotation.Nullable;
 
-import org.chromium.chrome.browser.ui.device_lock.DeviceLockCoordinator;
 import org.chromium.components.browser_ui.device_lock.DeviceLockActivityLauncher;
-import org.chromium.components.browser_ui.device_lock.DeviceLockBridge;
 import org.chromium.ui.base.WindowAndroid;
 
 /**
@@ -33,24 +29,6 @@
         return sLauncher;
     }
 
-    /**
-     * Set the shared instance for testing.
-     *
-     * @param deviceLockActivityLauncherImpl The {@link DeviceLockActivityLauncherImpl} instance to
-     *        use for testing.
-     */
-    public static void setInstanceForTesting(
-            DeviceLockActivityLauncherImpl deviceLockActivityLauncherImpl) {
-        sLauncher = deviceLockActivityLauncherImpl;
-    }
-
-    /**
-     * Resets the shared instance used for testing.
-     */
-    public static void resetInstanceForTesting() {
-        sLauncher = null;
-    }
-
     private DeviceLockActivityLauncherImpl() {}
 
     @Override
@@ -61,34 +39,4 @@
                 context, selectedAccount, requireDeviceLockReauthentication);
         windowAndroid.showIntent(intent, callback, null);
     }
-
-    // TODO(crbug.com/1482534)
-    // Refactor to use DeviceLockDialogController rather than #launchDeviceLockActivity.
-    @Override
-    public void presentDeviceLockChallenge(Context context,
-            boolean requireDeviceLockReauthentication, WindowAndroid windowAndroid,
-            Runnable callback) {
-        if (shouldShowDeviceLockPage(context)) {
-            launchDeviceLockActivity(context, null, requireDeviceLockReauthentication,
-                    windowAndroid, (int resultCode, Intent data) -> {
-                        if (resultCode == Activity.RESULT_OK) {
-                            callback.run();
-                        }
-                    });
-        } else {
-            DeviceLockCoordinator.createDeviceLockAuthenticatorBridge().reauthenticate(
-                    (authSucceeded) -> {
-                        if (authSucceeded) {
-                            callback.run();
-                        }
-                    });
-        }
-    }
-
-    private static boolean shouldShowDeviceLockPage(Context context) {
-        boolean deviceLockIsPresent =
-                ((KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE))
-                        .isDeviceSecure();
-        return !DeviceLockBridge.deviceLockPageHasBeenPassed() || !deviceLockIsPresent;
-    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
index 9345bc4..16b5cd3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
@@ -59,7 +59,6 @@
 import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.components.sync.SyncService;
 import org.chromium.components.user_prefs.UserPrefs;
-import org.chromium.ui.base.WindowAndroid;
 import org.chromium.ui.modaldialog.ModalDialogManager;
 
 import java.util.HashMap;
@@ -97,7 +96,6 @@
     private ChromeBasePreference mManageSync;
     private @Nullable PasswordCheck mPasswordCheck;
     private ObservableSupplier<ModalDialogManager> mModalDialogManagerSupplier;
-    private WindowAndroid mWindowAndroid;
 
     public MainSettings() {
         setHasOptionsMenu(true);
@@ -369,8 +367,7 @@
         }
         findPreference(PREF_AUTOFILL_PAYMENTS)
                 .setOnPreferenceClickListener(preference
-                        -> SettingsLauncherHelper.showAutofillCreditCardSettings(
-                                getActivity(), mWindowAndroid));
+                        -> SettingsLauncherHelper.showAutofillCreditCardSettings(getActivity()));
         findPreference(PREF_AUTOFILL_ADDRESSES)
                 .setOnPreferenceClickListener(preference
                         -> SettingsLauncherHelper.showAutofillProfileSettings(getActivity()));
@@ -450,8 +447,4 @@
             ObservableSupplier<ModalDialogManager> modalDialogManagerSupplier) {
         mModalDialogManagerSupplier = modalDialogManagerSupplier;
     }
-
-    public void setWindowAndroid(WindowAndroid windowAndroid) {
-        mWindowAndroid = windowAndroid;
-    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
index 2bc58ae..16ab004 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
@@ -22,7 +22,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 
-import androidx.annotation.CallSuper;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.widget.Toolbar;
@@ -97,10 +96,7 @@
 import org.chromium.components.privacy_sandbox.TrackingProtectionSettings;
 import org.chromium.ui.KeyboardVisibilityDelegate;
 import org.chromium.ui.UiUtils;
-import org.chromium.ui.base.ActivityWindowAndroid;
 import org.chromium.ui.base.DeviceFormFactor;
-import org.chromium.ui.base.IntentRequestTracker;
-import org.chromium.ui.base.WindowAndroid;
 import org.chromium.ui.modaldialog.ModalDialogManager;
 import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType;
 
@@ -138,9 +134,6 @@
     private OneshotSupplierImpl<BottomSheetController> mBottomSheetControllerSupplier =
             new OneshotSupplierImpl<>();
 
-    private IntentRequestTracker mIntentRequestTracker;
-    private WindowAndroid mWindowAndroid;
-
     @Nullable
     private UiConfig mUiConfig;
 
@@ -200,12 +193,6 @@
 
         setStatusBarColor();
         initBottomSheet();
-
-        if (BuildInfo.getInstance().isAutomotive) {
-            mIntentRequestTracker = IntentRequestTracker.createFromActivity(this);
-            mWindowAndroid = new ActivityWindowAndroid(
-                    this, /* listenToActivityState= */ true, mIntentRequestTracker);
-        }
     }
 
     @Override
@@ -368,17 +355,6 @@
         checkForMissingDeviceLockOnAutomotive();
     }
 
-    @CallSuper
-    @Override
-    protected void onDestroy() {
-        if (mWindowAndroid != null) {
-            mWindowAndroid.destroy();
-            mWindowAndroid = null;
-        }
-
-        super.onDestroy();
-    }
-
     private void checkForMissingDeviceLockOnAutomotive() {
         if (BuildInfo.getInstance().isAutomotive) {
             if (mMissingDeviceLockLauncher == null) {
@@ -507,9 +483,8 @@
 
         // Settings screen specific attachments.
         if (fragment instanceof MainSettings) {
-            MainSettings mainSettings = ((MainSettings) fragment);
-            mainSettings.setModalDialogManagerSupplier(getModalDialogManagerSupplier());
-            mainSettings.setWindowAndroid(mWindowAndroid);
+            ((MainSettings) fragment)
+                    .setModalDialogManagerSupplier(getModalDialogManagerSupplier());
         }
         if (fragment instanceof SiteSettingsPreferenceFragment) {
             ((SiteSettingsPreferenceFragment) fragment)
@@ -613,26 +588,6 @@
     }
 
     @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (mIntentRequestTracker != null) {
-            mIntentRequestTracker.onActivityResult(requestCode, resultCode, data);
-        }
-        super.onActivityResult(requestCode, resultCode, data);
-    }
-
-    /** Get the tracker of this activity's intents. May be null if one was not created. */
-    public @Nullable IntentRequestTracker getIntentRequestTracker() {
-        return mIntentRequestTracker;
-    }
-
-    /**
-     * @return A {@link ActivityWindowAndroid} instance. May be null if one was not created.
-     */
-    public @Nullable WindowAndroid getWindowAndroid() {
-        return mWindowAndroid;
-    }
-
-    @Override
     public SnackbarManager getSnackbarManager() {
         return mSnackbarManager;
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragmentTest.java
index cf97b33..0d000a7 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragmentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsFragmentTest.java
@@ -30,9 +30,11 @@
 import org.mockito.junit.MockitoRule;
 import org.mockito.quality.Strictness;
 
+import org.chromium.base.BuildInfo;
 import org.chromium.base.Callback;
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.HistogramWatcher;
+import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.autofill.AutofillTestHelper;
 import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard;
 import org.chromium.chrome.browser.device_reauth.ReauthenticatorBridge;
@@ -53,6 +55,7 @@
 import org.chromium.components.prefs.PrefService;
 import org.chromium.components.user_prefs.UserPrefs;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.test.util.DeviceRestriction;
 
 import java.util.concurrent.TimeoutException;
 
@@ -68,7 +71,7 @@
     @Rule
     public final AutofillTestRule rule = new AutofillTestRule();
     @Rule
-    public final MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.LENIENT);
     @Rule
     public final SettingsActivityTestRule<AutofillPaymentMethodsFragment>
             mSettingsActivityTestRule =
@@ -145,6 +148,7 @@
 
     @Test
     @MediumTest
+    @Restriction(DeviceRestriction.RESTRICTION_TYPE_NON_AUTO)
     public void testTwoCreditCards_displaysTwoServerCards() throws Exception {
         mAutofillTestHelper.addServerCreditCard(SAMPLE_CARD_VISA);
         mAutofillTestHelper.addServerCreditCard(SAMPLE_CARD_MASTERCARD);
@@ -158,12 +162,27 @@
 
     @Test
     @MediumTest
+    @Restriction(DeviceRestriction.RESTRICTION_TYPE_AUTO)
+    public void testTwoCreditCards_displaysTwoServerCards_mandatoryReauthNotShownOnAutomotive()
+            throws Exception {
+        mAutofillTestHelper.addServerCreditCard(SAMPLE_CARD_VISA);
+        mAutofillTestHelper.addServerCreditCard(SAMPLE_CARD_MASTERCARD);
+
+        SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity();
+
+        // Verify that the preferences on the initial screen map to Save and Fill toggle + 2 Cards
+        // + Add Card button + Payment Apps.
+        Assert.assertEquals(5, getPreferenceScreen(activity).getPreferenceCount());
+    }
+
+    @Test
+    @MediumTest
     public void testCreditCardWithoutNickname_displayNetworkAndLastFourAsTitle() throws Exception {
         mAutofillTestHelper.addServerCreditCard(SAMPLE_CARD_VISA);
 
         SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity();
 
-        Preference cardPreference = getPreferenceScreen(activity).getPreference(2);
+        Preference cardPreference = getFirstPaymentMethodPreference(activity);
         String title = cardPreference.getTitle().toString();
         assertThat(title).contains("Visa");
         assertThat(title).contains("1111");
@@ -177,7 +196,7 @@
 
         SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity();
 
-        Preference cardPreference = getPreferenceScreen(activity).getPreference(2);
+        Preference cardPreference = getFirstPaymentMethodPreference(activity);
         String title = cardPreference.getTitle().toString();
         assertThat(title).contains("Test nickname");
         assertThat(title).contains("1111");
@@ -192,7 +211,7 @@
 
         SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity();
 
-        Preference cardPreference = getPreferenceScreen(activity).getPreference(2);
+        Preference cardPreference = getFirstPaymentMethodPreference(activity);
         String title = cardPreference.getTitle().toString();
         assertThat(title).contains("This is a long nickname");
         assertThat(title).contains("1111");
@@ -206,7 +225,7 @@
 
         SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity();
 
-        Preference cardPreference = getPreferenceScreen(activity).getPreference(2);
+        Preference cardPreference = getFirstPaymentMethodPreference(activity);
         String summary = cardPreference.getSummary().toString();
         assertThat(summary).isEqualTo(
                 activity.getString(R.string.autofill_virtual_card_enrolled_text));
@@ -220,7 +239,7 @@
 
         SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity();
 
-        Preference cardPreference = getPreferenceScreen(activity).getPreference(2);
+        Preference cardPreference = getFirstPaymentMethodPreference(activity);
         String summary = cardPreference.getSummary().toString();
         // Verify that the summary (line below the card name and number) contains the expiration
         // date.
@@ -235,7 +254,7 @@
 
         SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity();
 
-        Preference cardPreference = getPreferenceScreen(activity).getPreference(2);
+        Preference cardPreference = getFirstPaymentMethodPreference(activity);
         String summary = cardPreference.getSummary().toString();
         assertThat(summary).contains(String.format("05/%s", AutofillTestHelper.twoDigitNextYear()));
     }
@@ -249,7 +268,7 @@
 
         SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity();
 
-        Preference cardPreference = getPreferenceScreen(activity).getPreference(2);
+        Preference cardPreference = getFirstPaymentMethodPreference(activity);
         String summary = cardPreference.getSummary().toString();
         assertThat(summary).contains(String.format("05/%s", AutofillTestHelper.twoDigitNextYear()));
     }
@@ -301,6 +320,7 @@
     @MediumTest
     // Use the policy to simulate AutofillCreditCard is disabled.
     @Policies.Add({ @Policies.Item(key = "AutofillCreditCardEnabled", string = "false") })
+    @Restriction(DeviceRestriction.RESTRICTION_TYPE_NON_AUTO)
     public void testMandatoryReauthToggle_disabledWhenAutofillDisabled() throws Exception {
         SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity();
 
@@ -310,6 +330,7 @@
 
     @Test
     @MediumTest
+    @Restriction(DeviceRestriction.RESTRICTION_TYPE_NON_AUTO)
     public void testMandatoryReauthToggle_disabledWhenBothBiometricAndScreenLockAreDisabled()
             throws Exception {
         // Simulate the user can't authenticate with neither biometric nor screen lock.
@@ -323,6 +344,7 @@
 
     @Test
     @MediumTest
+    @Restriction(DeviceRestriction.RESTRICTION_TYPE_NON_AUTO)
     public void testMandatoryReauthToggle_disabledWithCorrespondingPrefValue() throws Exception {
         // Simulate the pref was enabled previously, to ensure the toggle value is set
         // correspondingly.
@@ -343,6 +365,7 @@
 
     @Test
     @MediumTest
+    @Restriction(DeviceRestriction.RESTRICTION_TYPE_NON_AUTO)
     public void testMandatoryReauthToggle_displayToggle() throws Exception {
         // Simulate the pref was enabled previously, to ensure the toggle value is set
         // correspondingly.
@@ -368,6 +391,7 @@
 
     @Test
     @MediumTest
+    @Restriction(DeviceRestriction.RESTRICTION_TYPE_NON_AUTO)
     public void testMandatoryReauthToggle_switchValueOnClicked() throws Exception {
         var optInHistogram =
                 HistogramWatcher.newBuilder()
@@ -402,6 +426,7 @@
 
     @Test
     @MediumTest
+    @Restriction(DeviceRestriction.RESTRICTION_TYPE_NON_AUTO)
     public void testMandatoryReauthToggle_stayAtOldValueIfBiometricAuthFails() throws Exception {
         var optOutHistogram =
                 HistogramWatcher.newBuilder()
@@ -465,9 +490,12 @@
 
         SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity();
 
-        // Verify that the Reauth preference is checked.
-        Assert.assertTrue(getMandatoryReauthPreference(activity).isChecked());
-        Preference cardPreference = getPreferenceScreen(activity).getPreference(2);
+        // Verify that the Reauth preference is checked on non-automotive devices.
+        if (!BuildInfo.getInstance().isAutomotive) {
+            Assert.assertTrue(getMandatoryReauthPreference(activity).isChecked());
+        }
+
+        Preference cardPreference = getFirstPaymentMethodPreference(activity);
         String title = cardPreference.getTitle().toString();
         assertThat(title).contains("Visa");
         assertThat(title).contains("1111");
@@ -506,9 +534,12 @@
 
         SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity();
 
-        // Verify that the Reauth preference is checked.
-        Assert.assertTrue(getMandatoryReauthPreference(activity).isChecked());
-        Preference cardPreference = getPreferenceScreen(activity).getPreference(2);
+        // Verify that the Reauth preference is checked on non-automotive devices.
+        if (!BuildInfo.getInstance().isAutomotive) {
+            Assert.assertTrue(getMandatoryReauthPreference(activity).isChecked());
+        }
+
+        Preference cardPreference = getFirstPaymentMethodPreference(activity);
         String title = cardPreference.getTitle().toString();
         assertThat(title).contains("Visa");
         assertThat(title).contains("1111");
@@ -539,7 +570,7 @@
         SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity();
 
         // Get the local card widget.
-        Preference cardPreference = getPreferenceScreen(activity).getPreference(1);
+        Preference cardPreference = getFirstPaymentMethodPreference(activity);
         String title = cardPreference.getTitle().toString();
         assertThat(title).contains("Visa");
         assertThat(title).contains("1111");
@@ -557,6 +588,7 @@
 
     @Test
     @MediumTest
+    @Restriction(DeviceRestriction.RESTRICTION_TYPE_NON_AUTO)
     public void testLocalCardEditWithReauth_noReauthWhenReauthIsDisabled() throws Exception {
         mAutofillTestHelper.setCreditCard(SAMPLE_LOCAL_CARD);
         // Simulate Reauth pref is disabled.
@@ -570,7 +602,7 @@
 
         // Verify that the Reauth preference is not checked.
         Assert.assertFalse(getMandatoryReauthPreference(activity).isChecked());
-        Preference cardPreference = getPreferenceScreen(activity).getPreference(2);
+        Preference cardPreference = getFirstPaymentMethodPreference(activity);
         String title = cardPreference.getTitle().toString();
         assertThat(title).contains("Visa");
         assertThat(title).contains("1111");
@@ -588,6 +620,7 @@
 
     @Test
     @MediumTest
+    @Restriction(DeviceRestriction.RESTRICTION_TYPE_NON_AUTO)
     public void testLocalCardEditWithReauth_turnOnReauthAndVerifyReauthOnClick() throws Exception {
         mAutofillTestHelper.setCreditCard(SAMPLE_LOCAL_CARD);
 
@@ -607,7 +640,7 @@
         TestThreadUtils.runOnUiThreadBlocking(getMandatoryReauthPreference(activity)::performClick);
 
         // Get the local card's widget.
-        Preference cardPreference = getPreferenceScreen(activity).getPreference(2);
+        Preference cardPreference = getFirstPaymentMethodPreference(activity);
         String title = cardPreference.getTitle().toString();
         assertThat(title).contains("Visa");
         assertThat(title).contains("1111");
@@ -627,6 +660,7 @@
 
     @Test
     @MediumTest
+    @Restriction(DeviceRestriction.RESTRICTION_TYPE_NON_AUTO)
     public void testLocalCardEditWithReauth_turnOffReauthAndVerifyNoReauthOnClick()
             throws Exception {
         mAutofillTestHelper.setCreditCard(SAMPLE_LOCAL_CARD);
@@ -647,7 +681,7 @@
         TestThreadUtils.runOnUiThreadBlocking(getMandatoryReauthPreference(activity)::performClick);
 
         // Get the local card's widget.
-        Preference cardPreference = getPreferenceScreen(activity).getPreference(2);
+        Preference cardPreference = getFirstPaymentMethodPreference(activity);
         String title = cardPreference.getTitle().toString();
         assertThat(title).contains("Visa");
         assertThat(title).contains("1111");
@@ -766,4 +800,16 @@
     private static PrefService getPrefService() {
         return UserPrefs.get(Profile.getLastUsedRegularProfile());
     }
+
+    private static Preference getFirstPaymentMethodPreference(SettingsActivity activity) {
+        boolean mandatoryReauthToggleShown =
+                ChromeFeatureList.isEnabled(
+                        ChromeFeatureList.AUTOFILL_ENABLE_PAYMENTS_MANDATORY_REAUTH)
+                && !BuildInfo.getInstance().isAutomotive;
+        if (mandatoryReauthToggleShown) {
+            return getPreferenceScreen(activity).getPreference(2);
+        } else {
+            return getPreferenceScreen(activity).getPreference(1);
+        }
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/device_lock/DeviceLockActivityLauncherImplTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/device_lock/DeviceLockActivityLauncherImplTest.java
index 5d9247f1..5f416705 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/device_lock/DeviceLockActivityLauncherImplTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/device_lock/DeviceLockActivityLauncherImplTest.java
@@ -4,50 +4,32 @@
 package org.chromium.chrome.browser.device_lock;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import static org.chromium.components.browser_ui.device_lock.DeviceLockBridge.DEVICE_LOCK_PAGE_HAS_BEEN_PASSED;
-
-import android.app.Activity;
-import android.app.KeyguardManager;
 import android.content.Context;
 import android.content.Intent;
-import android.content.SharedPreferences;
 
 import androidx.test.filters.MediumTest;
 
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
-import org.chromium.base.Callback;
-import org.chromium.base.ContextUtils;
-import org.chromium.base.test.util.DoNotBatch;
-import org.chromium.chrome.browser.device_reauth.ReauthenticatorBridge;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.ui.base.WindowAndroid;
 
-import java.util.concurrent.atomic.AtomicBoolean;
-
 /**
  * Tests for the {@link DeviceLockActivity}.
  */
 @RunWith(ChromeJUnit4ClassRunner.class)
-@DoNotBatch(reason = "Uses static launcher.")
 public class DeviceLockActivityLauncherImplTest {
     @Rule
     public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@@ -58,27 +40,6 @@
     private WindowAndroid mWindowAndroid;
     @Mock
     private WindowAndroid.IntentCallback mIntentCallback;
-    @Mock
-    private KeyguardManager mKeyguardManager;
-    @Mock
-    private ReauthenticatorBridge mReauthenticatorBridge;
-
-    private final AtomicBoolean mCallbackCalled = new AtomicBoolean();
-
-    @Before
-    public void setup() {
-        mContext = Mockito.mock(Context.class);
-        mKeyguardManager = Mockito.mock(KeyguardManager.class);
-        mReauthenticatorBridge = Mockito.mock(ReauthenticatorBridge.class);
-
-        mCallbackCalled.set(false);
-        SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
-        prefs.edit().remove(DEVICE_LOCK_PAGE_HAS_BEEN_PASSED).apply();
-        ReauthenticatorBridge.setInstanceForTesting(mReauthenticatorBridge);
-
-        doReturn(mKeyguardManager).when(mContext).getSystemService(eq(Context.KEYGUARD_SERVICE));
-        doReturn(true).when(mKeyguardManager).isDeviceSecure();
-    }
 
     @Test
     @MediumTest
@@ -102,106 +63,4 @@
         DeviceLockActivityLauncherImpl.get().launchDeviceLockActivity(
                 mContext, "testSelectedAccount", true, mWindowAndroid, mIntentCallback);
     }
-
-    @Test
-    @MediumTest
-    public void
-    testEnsureDeviceLockSecureForSignedOutFlow_launchesDeviceLockActivity_callbackCalled() {
-        SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
-        prefs.edit().putBoolean(DEVICE_LOCK_PAGE_HAS_BEEN_PASSED, false).apply();
-
-        doAnswer((invocation) -> {
-            Intent intent = invocation.getArgument(0);
-            assertEquals(DeviceLockActivity.class.getName(), intent.getComponent().getClassName());
-
-            WindowAndroid.IntentCallback callback = invocation.getArgument(1);
-            callback.onIntentCompleted(Activity.RESULT_OK, null);
-            return null;
-        })
-                .when(mWindowAndroid)
-                .showIntent(any(Intent.class), any(WindowAndroid.IntentCallback.class), any());
-
-        DeviceLockActivityLauncherImpl.get().presentDeviceLockChallenge(
-                mContext, true, mWindowAndroid, () -> mCallbackCalled.set(true));
-        verify(mWindowAndroid, times(1)).showIntent(any(Intent.class), any(), any());
-        verify(mReauthenticatorBridge, never()).reauthenticate(any());
-        assertTrue("The callback should have been called if the activity ends with RESULT_OK.",
-                mCallbackCalled.get());
-    }
-
-    @Test
-    @MediumTest
-    public void
-    testEnsureDeviceLockSecureForSignedOutFlow_launchesDeviceLockActivity_callbackNotCalled() {
-        SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
-        prefs.edit().putBoolean(DEVICE_LOCK_PAGE_HAS_BEEN_PASSED, false).apply();
-
-        doAnswer((invocation) -> {
-            Intent intent = invocation.getArgument(0);
-            assertEquals(DeviceLockActivity.class.getName(), intent.getComponent().getClassName());
-
-            WindowAndroid.IntentCallback callback = invocation.getArgument(1);
-            callback.onIntentCompleted(Activity.RESULT_CANCELED, null);
-            return null;
-        })
-                .when(mWindowAndroid)
-                .showIntent(any(Intent.class), any(WindowAndroid.IntentCallback.class), any());
-
-        DeviceLockActivityLauncherImpl.get().presentDeviceLockChallenge(
-                mContext, true, mWindowAndroid, () -> mCallbackCalled.set(true));
-        verify(mWindowAndroid, times(1)).showIntent(any(Intent.class), any(), any());
-        verify(mReauthenticatorBridge, never()).reauthenticate(any());
-        assertFalse("The callback should not have been called if the activity ends with "
-                        + "RESULT_CANCELED.",
-                mCallbackCalled.get());
-    }
-
-    @Test
-    @MediumTest
-    public void
-    testEnsureDeviceLockSecureForSignedOutFlow_reauthenticationChallenge_authSucceeded() {
-        SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
-        prefs.edit().putBoolean(DEVICE_LOCK_PAGE_HAS_BEEN_PASSED, true).apply();
-        doReturn(mKeyguardManager).when(mContext).getSystemService(eq(Context.KEYGUARD_SERVICE));
-        doReturn(true).when(mKeyguardManager).isDeviceSecure();
-
-        doAnswer((invocation) -> {
-            Callback<Boolean> callback = invocation.getArgument(0);
-            callback.onResult(true);
-            return null;
-        })
-                .when(mReauthenticatorBridge)
-                .reauthenticate(any());
-
-        DeviceLockActivityLauncherImpl.get().presentDeviceLockChallenge(
-                mContext, true, mWindowAndroid, () -> mCallbackCalled.set(true));
-        verify(mWindowAndroid, never()).showIntent(any(Intent.class), any(), any());
-        verify(mReauthenticatorBridge, times(1)).reauthenticate(any());
-        assertTrue("The callback should be called after a successful reauthentication.",
-                mCallbackCalled.get());
-    }
-
-    @Test
-    @MediumTest
-    public void testEnsureDeviceLockSecureForSignedOutFlow_reauthenticationChallenge_authFailed() {
-        SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
-        prefs.edit().putBoolean(DEVICE_LOCK_PAGE_HAS_BEEN_PASSED, true).apply();
-        doReturn(mKeyguardManager).when(mContext).getSystemService(eq(Context.KEYGUARD_SERVICE));
-        doReturn(true).when(mKeyguardManager).isDeviceSecure();
-
-        doAnswer((invocation) -> {
-            Callback<Boolean> callback = invocation.getArgument(0);
-            callback.onResult(false);
-            return null;
-        })
-                .when(mReauthenticatorBridge)
-                .reauthenticate(any());
-
-        DeviceLockActivityLauncherImpl.get().presentDeviceLockChallenge(
-                mContext, true, mWindowAndroid, () -> mCallbackCalled.set(true));
-        verify(mWindowAndroid, never()).showIntent(any(Intent.class), any(), any());
-        verify(mReauthenticatorBridge, times(1)).reauthenticate(any());
-        assertFalse("The callback should be not called after a failed reauthentication.",
-                mCallbackCalled.get());
-    }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/SettingsLauncherHelperTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/SettingsLauncherHelperTest.java
index 6876c0a..7e8e0e74 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/SettingsLauncherHelperTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/settings/SettingsLauncherHelperTest.java
@@ -6,12 +6,6 @@
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
 
@@ -21,43 +15,29 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
 
-import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DoNotBatch;
 import org.chromium.base.test.util.UserActionTester;
-import org.chromium.chrome.browser.device_lock.DeviceLockActivityLauncherImpl;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.test.AutomotiveContextWrapperTestRule;
 import org.chromium.components.browser_ui.settings.SettingsLauncher;
-import org.chromium.ui.base.WindowAndroid;
-
-import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Test for {@link SettingsLauncherHelper}.
  */
-@RunWith(BaseRobolectricTestRunner.class)
+@RunWith(RobolectricTestRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
 @DoNotBatch(reason = "Uses static launcher.")
 public class SettingsLauncherHelperTest {
-    @Rule
-    public AutomotiveContextWrapperTestRule mAutomotiveContextWrapperTestRule =
-            new AutomotiveContextWrapperTestRule();
-
     @Mock
     private SettingsLauncher mMockLauncher;
     @Mock
     private Context mMockContext;
-    @Mock
-    private WindowAndroid mWindowAndroid;
-    @Mock
-    private DeviceLockActivityLauncherImpl mDeviceLockActivityLauncherImpl;
 
     private UserActionTester mActionTester = new UserActionTester();
 
@@ -65,7 +45,6 @@
     public void setup() {
         MockitoAnnotations.openMocks(this);
         SettingsLauncherHelper.setLauncher(mMockLauncher);
-        DeviceLockActivityLauncherImpl.setInstanceForTesting(mDeviceLockActivityLauncherImpl);
     }
 
     @After
@@ -77,9 +56,7 @@
     @Test
     @SmallTest
     public void testRecordsActionThenLaunchesPaymentsSettings() {
-        mAutomotiveContextWrapperTestRule.setIsAutomotive(false);
-
-        assertTrue(SettingsLauncherHelper.showAutofillCreditCardSettings(mMockContext, null));
+        assertTrue(SettingsLauncherHelper.showAutofillCreditCardSettings(mMockContext));
         assertTrue(mActionTester.getActions().contains("AutofillCreditCardsViewed"));
         verify(mMockLauncher)
                 .launchSettingsActivity(mMockContext, AutofillPaymentMethodsFragment.class);
@@ -96,9 +73,7 @@
     @Test
     @SmallTest
     public void testDoesntLaunchOrRecordPaymentsSettingsWithoutContext() {
-        mAutomotiveContextWrapperTestRule.setIsAutomotive(false);
-
-        assertFalse(SettingsLauncherHelper.showAutofillCreditCardSettings(null, null));
+        assertFalse(SettingsLauncherHelper.showAutofillCreditCardSettings(null));
         assertFalse(mActionTester.getActions().contains("AutofillCreditCardsViewed"));
         verifyNoInteractions(mMockLauncher);
     }
@@ -106,35 +81,8 @@
     @Test
     @SmallTest
     public void testDoesntLaunchOrRecordAddressesSettingsWithoutContext() {
-        mAutomotiveContextWrapperTestRule.setIsAutomotive(false);
-
-        assertFalse(SettingsLauncherHelper.showAutofillCreditCardSettings(null, null));
+        assertFalse(SettingsLauncherHelper.showAutofillCreditCardSettings(null));
         assertFalse(mActionTester.getActions().contains("AutofillAddressesViewed"));
         verifyNoInteractions(mMockLauncher);
     }
-
-    @Test
-    @SmallTest
-    public void testShowAutofillCreditCardSettings_onAutomotiveDevice_ensuresDeviceLockSecure() {
-        mAutomotiveContextWrapperTestRule.setIsAutomotive(true);
-        AtomicReference<Runnable> callback = new AtomicReference<>();
-
-        doAnswer((invocation) -> {
-            Runnable ensureDeviceLockSecureCallback = invocation.getArgument(3);
-            callback.set(ensureDeviceLockSecureCallback);
-            return null;
-        })
-                .when(mDeviceLockActivityLauncherImpl)
-                .presentDeviceLockChallenge(any(), anyBoolean(), any(), any());
-
-        SettingsLauncherHelper.showAutofillCreditCardSettings(mMockContext, mWindowAndroid);
-        verify(mMockLauncher, never())
-                .launchSettingsActivity(mMockContext, AutofillPaymentMethodsFragment.class);
-        verify(mDeviceLockActivityLauncherImpl, times(1))
-                .presentDeviceLockChallenge(eq(mMockContext), eq(true), eq(mWindowAndroid), any());
-
-        callback.get().run();
-        verify(mMockLauncher, times(1))
-                .launchSettingsActivity(mMockContext, AutofillPaymentMethodsFragment.class);
-    }
 }
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 75e585bd..cfe148a 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -2867,19 +2867,19 @@
     Not allowed to use your microphone
   </message>
   <message name="IDS_SETTINGS_SITE_SETTINGS_MIDI_DESCRIPTION" desc="Description of the MIDI devices content setting.">
-    Sites usually connect to MIDI devices for creating and editing music
+    Sites usually use MIDI devices for features for creating and editing music
   </message>
   <message name="IDS_SETTINGS_SITE_SETTINGS_MIDI_ALLOWED" desc="Label for the enabled option of the MIDI devices content setting.">
-    Sites can ask to connect to MIDI devices
+    Sites can ask to use your MIDI devices
   </message>
   <message name="IDS_SETTINGS_SITE_SETTINGS_MIDI_BLOCKED" desc="Label for the disabled option of the MIDI devices content setting.">
-    Don't allow sites to connect to MIDI devices
+    Don't allow sites to use your MIDI devices
   </message>
   <message name="IDS_SETTINGS_SITE_SETTINGS_MIDI_ALLOWED_EXCEPTIONS" desc="Label for the allowed exceptions site list of the MIDI devices content setting.">
-    Allowed to connect to MIDI devices
+    Allowed to use your MIDI devices
   </message>
   <message name="IDS_SETTINGS_SITE_SETTINGS_MIDI_BLOCKED_EXCEPTIONS" desc="Label for the blocked exceptions site list of the MIDI devices content setting.">
-    Not allowed to connect to MIDI devices
+    Not allowed to use your MIDI devices
   </message>
   <message name="IDS_SETTINGS_SITE_SETTINGS_MOTION_SENSORS_DESCRIPTION" desc="Description of the motion sensors content setting.">
     Sites usually use your device's motion sensors for features like virtual reality or fitness tracking
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_ALLOWED.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_ALLOWED.png.sha1
index ada37b32..8a2179f 100644
--- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_ALLOWED.png.sha1
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_ALLOWED.png.sha1
@@ -1 +1 @@
-093bf5dea2c0ad273bc53ea3ca8688a74bb2549f
\ No newline at end of file
+15c343df6aa67ab938ec6de37c3db9e847c9ce46
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_ALLOWED_EXCEPTIONS.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_ALLOWED_EXCEPTIONS.png.sha1
index a32b063..8a2179f 100644
--- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_ALLOWED_EXCEPTIONS.png.sha1
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_ALLOWED_EXCEPTIONS.png.sha1
@@ -1 +1 @@
-8fa010440ef4e5c899d944ff00ef5ac0ecfdfc98
\ No newline at end of file
+15c343df6aa67ab938ec6de37c3db9e847c9ce46
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_BLOCKED.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_BLOCKED.png.sha1
index a4de750..8a2179f 100644
--- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_BLOCKED.png.sha1
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_BLOCKED.png.sha1
@@ -1 +1 @@
-727eb4dd627395b8cef763cf8c3b2e3d7ac19d78
\ No newline at end of file
+15c343df6aa67ab938ec6de37c3db9e847c9ce46
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_BLOCKED_EXCEPTIONS.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_BLOCKED_EXCEPTIONS.png.sha1
index a32b063..8a2179f 100644
--- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_BLOCKED_EXCEPTIONS.png.sha1
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_BLOCKED_EXCEPTIONS.png.sha1
@@ -1 +1 @@
-8fa010440ef4e5c899d944ff00ef5ac0ecfdfc98
\ No newline at end of file
+15c343df6aa67ab938ec6de37c3db9e847c9ce46
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_DESCRIPTION.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_DESCRIPTION.png.sha1
index 4866b0b6..8a2179f 100644
--- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_DESCRIPTION.png.sha1
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_MIDI_DESCRIPTION.png.sha1
@@ -1 +1 @@
-44547efb08b45918f00fda7e366c178af9d9d926
\ No newline at end of file
+15c343df6aa67ab938ec6de37c3db9e847c9ce46
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 77f6f39..3c9e806 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2242,7 +2242,6 @@
     "//components/lookalikes/core:proto",
     "//components/lookalikes/core:safety_tips",
     "//components/media_device_salt",
-    "//components/media_effects",
     "//components/memory_pressure",
     "//components/metrics:call_stack_profile_collector",
     "//components/metrics:call_stack_profile_params",
@@ -4633,7 +4632,6 @@
       "//components/keep_alive_registry",
       "//components/live_caption",
       "//components/live_caption:live_translate",
-      "//components/media_effects",
       "//components/memory_pressure",
       "//components/omnibox/browser:mojo_bindings",
       "//components/services/app_service",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 939c459..533cfb91 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -196,7 +196,6 @@
   "+components/media_router/browser",
   "+components/history_clusters",
   "+components/history_clusters/history_clusters_internals",
-  "+components/media_effects",
   "+components/memory_pressure",
   "+components/messages/android",
   "+components/metal_util",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 16da370..855c2292 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -11078,6 +11078,10 @@
      flag_descriptions::kCrosSoulDescription, kOsCrOS,
      PLATFORM_FEATURE_NAME_TYPE("CrOSLateBootCrOSSOUL")},
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+    {"use-shared-images-for-pepper-video",
+     flag_descriptions::kUseSharedImagesForPepperVideoName,
+     flag_descriptions::kUseSharedImagesForPepperVideoDescription, kOsAll,
+     FEATURE_VALUE_TYPE(media::kUseSharedImagesForPepperVideo)},
 
 #if BUILDFLAG(IS_ANDROID)
     {"grid-tab-switcher-android-animations",
diff --git a/chrome/browser/apps/app_preload_service/BUILD.gn b/chrome/browser/apps/app_preload_service/BUILD.gn
index a07fe6e0..657175c 100644
--- a/chrome/browser/apps/app_preload_service/BUILD.gn
+++ b/chrome/browser/apps/app_preload_service/BUILD.gn
@@ -39,6 +39,7 @@
     "//components/services/app_service",
     "//components/user_manager",
     "//components/webapps/browser:constants",
+    "//components/webapps/common",
     "//google_apis",
     "//services/network/public/cpp",
   ]
diff --git a/chrome/browser/apps/app_preload_service/web_app_preload_installer.cc b/chrome/browser/apps/app_preload_service/web_app_preload_installer.cc
index c20e54c..1a4f88ea 100644
--- a/chrome/browser/apps/app_preload_service/web_app_preload_installer.cc
+++ b/chrome/browser/apps/app_preload_service/web_app_preload_installer.cc
@@ -244,7 +244,7 @@
 
 void WebAppPreloadInstaller::OnAppInstalled(
     WebAppPreloadInstalledCallback callback,
-    const web_app::AppId& app_id,
+    const webapps::AppId& app_id,
     webapps::InstallResultCode code) {
   bool success = webapps::IsSuccess(code);
   RecordInstallResultMetric(success ? WebAppPreloadResult::kSuccess
diff --git a/chrome/browser/apps/app_preload_service/web_app_preload_installer.h b/chrome/browser/apps/app_preload_service/web_app_preload_installer.h
index 36cba6b..1527ecf7 100644
--- a/chrome/browser/apps/app_preload_service/web_app_preload_installer.h
+++ b/chrome/browser/apps/app_preload_service/web_app_preload_installer.h
@@ -13,8 +13,8 @@
 #include "base/scoped_observation.h"
 #include "chrome/browser/apps/app_preload_service/preload_app_definition.h"
 #include "chrome/browser/ash/crosapi/web_app_service_ash.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "components/webapps/browser/install_result_code.h"
+#include "components/webapps/common/web_app_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 class Profile;
@@ -85,7 +85,7 @@
                            std::unique_ptr<network::SimpleURLLoader> url_loader,
                            std::unique_ptr<std::string> response);
   void OnAppInstalled(WebAppPreloadInstalledCallback callback,
-                      const web_app::AppId& app_id,
+                      const webapps::AppId& app_id,
                       webapps::InstallResultCode code);
   void OnAllAppInstallationFinished(const std::vector<bool>& results);
 
diff --git a/chrome/browser/apps/app_preload_service/web_app_preload_installer_browsertest.cc b/chrome/browser/apps/app_preload_service/web_app_preload_installer_browsertest.cc
index d18d450..0d9a8618 100644
--- a/chrome/browser/apps/app_preload_service/web_app_preload_installer_browsertest.cc
+++ b/chrome/browser/apps/app_preload_service/web_app_preload_installer_browsertest.cc
@@ -95,7 +95,7 @@
     return app;
   }
 
-  void VerifyAppInstalled(web_app::AppId app_id, const std::string& app_name) {
+  void VerifyAppInstalled(webapps::AppId app_id, const std::string& app_name) {
     bool found = app_registry_cache().ForOneApp(
         app_id, [app_name](const AppUpdate& update) {
           EXPECT_EQ(update.Name(), app_name);
diff --git a/chrome/browser/apps/app_service/BUILD.gn b/chrome/browser/apps/app_service/BUILD.gn
index 3e02811..30cdbf6 100644
--- a/chrome/browser/apps/app_service/BUILD.gn
+++ b/chrome/browser/apps/app_service/BUILD.gn
@@ -74,6 +74,7 @@
     "//components/favicon/core",
     "//components/keyed_service/content",
     "//components/services/app_service",
+    "//components/webapps/common",
     "//extensions/browser",
     "//extensions/common",
   ]
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_factory_unittest.cc b/chrome/browser/apps/app_service/app_icon/app_icon_factory_unittest.cc
index c9a7745..b962abf 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_factory_unittest.cc
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_factory_unittest.cc
@@ -426,8 +426,8 @@
                                          const IconKey& icon_key,
                                          IconType icon_type) {
     base::test::TestFuture<apps::IconValuePtr> result;
-    app_service_proxy().LoadIconFromIconKey(
-        AppType::kCrostini, app_id, icon_key, icon_type, kSizeInDip,
+    app_service_proxy().app_icon_loader()->LoadIconFromIconKey(
+        app_id, icon_key, icon_type, kSizeInDip,
         /*allow_placeholder_icon=*/false, result.GetCallback());
     return result.Take();
   }
diff --git a/chrome/browser/apps/app_service/app_icon/arc_apps_icon_unittest.cc b/chrome/browser/apps/app_service/app_icon/arc_apps_icon_unittest.cc
index e99d1f6..0c0f3d6c 100644
--- a/chrome/browser/apps/app_service/app_icon/arc_apps_icon_unittest.cc
+++ b/chrome/browser/apps/app_service/app_icon/arc_apps_icon_unittest.cc
@@ -162,12 +162,12 @@
     return result.Take();
   }
 
-  apps::IconValuePtr LoadIconFromIconKey(const std::string& app_id,
-                                         const IconKey& icon_key,
-                                         IconType icon_type) {
+  apps::IconValuePtr LoadIconWithIconEffects(const std::string& app_id,
+                                             uint32_t icon_effects,
+                                             IconType icon_type) {
     base::test::TestFuture<apps::IconValuePtr> result;
-    app_service_proxy().LoadIconFromIconKey(
-        AppType::kArc, app_id, icon_key, icon_type, kSizeInDip,
+    app_service_proxy().LoadIconWithIconEffects(
+        AppType::kArc, app_id, icon_effects, icon_type, kSizeInDip,
         /*allow_placeholder_icon=*/false, result.GetCallback());
     return result.Take();
   }
@@ -251,9 +251,9 @@
 
   // Verify the icon reading and writing function in AppService for the
   // kStandard icon.
-  IconKey icon_key;
-  icon_key.icon_effects = IconEffects::kCrOsStandardIcon | IconEffects::kPaused;
-  auto ret = LoadIconFromIconKey(app_id, icon_key, IconType::kStandard);
+  auto ret = LoadIconWithIconEffects(
+      app_id, IconEffects::kCrOsStandardIcon | IconEffects::kPaused,
+      IconType::kStandard);
 
   ASSERT_EQ(apps::IconType::kStandard, ret->icon_type);
   VerifyIcon(src_image_skia, ret->uncompressed);
diff --git a/chrome/browser/apps/app_service/app_icon/chrome_apps_icon_unittest.cc b/chrome/browser/apps/app_service/app_icon/chrome_apps_icon_unittest.cc
index 8686c573..21d15f0 100644
--- a/chrome/browser/apps/app_service/app_icon/chrome_apps_icon_unittest.cc
+++ b/chrome/browser/apps/app_service/app_icon/chrome_apps_icon_unittest.cc
@@ -213,32 +213,32 @@
     return result.Take();
   }
 
-  apps::IconValuePtr LoadIconFromIconKey(const std::string& app_id,
-                                         const IconKey& icon_key,
-                                         IconType icon_type) {
+  apps::IconValuePtr LoadIconWithIconEffects(const std::string& app_id,
+                                             uint32_t icon_effects,
+                                             IconType icon_type) {
     base::test::TestFuture<apps::IconValuePtr> result;
-    app_service_proxy().LoadIconFromIconKey(
-        AppType::kChromeApp, app_id, icon_key, icon_type, kSizeInDip,
+    app_service_proxy().LoadIconWithIconEffects(
+        AppType::kChromeApp, app_id, icon_effects, icon_type, kSizeInDip,
         /*allow_placeholder_icon=*/false, result.GetCallback());
     return result.Take();
   }
 
-  // Call LoadIconFromIconKey twice with the same parameters, to verify the icon
-  // loading process can handle the icon loading request multiple times with the
-  // same params.
-  std::vector<apps::IconValuePtr> MultipleLoadIconFromIconKey(
+  // Call LoadIconWithIconEffects twice with the same parameters, to verify the
+  // icon loading process can handle the icon loading request multiple times
+  // with the same params.
+  std::vector<apps::IconValuePtr> MultipleLoadIconWithIconEffects(
       const std::string& app_id,
-      const IconKey& icon_key,
+      uint32_t icon_effects,
       IconType icon_type) {
     base::test::TestFuture<std::vector<apps::IconValuePtr>> result;
     auto barrier_callback =
         base::BarrierCallback<apps::IconValuePtr>(2, result.GetCallback());
 
-    app_service_proxy().LoadIconFromIconKey(
-        AppType::kChromeApp, app_id, icon_key, icon_type, kSizeInDip,
+    app_service_proxy().LoadIconWithIconEffects(
+        AppType::kChromeApp, app_id, icon_effects, icon_type, kSizeInDip,
         /*allow_placeholder_icon=*/false, barrier_callback);
-    app_service_proxy().LoadIconFromIconKey(
-        AppType::kChromeApp, app_id, icon_key, icon_type, kSizeInDip,
+    app_service_proxy().LoadIconWithIconEffects(
+        AppType::kChromeApp, app_id, icon_effects, icon_type, kSizeInDip,
         /*allow_placeholder_icon=*/false, barrier_callback);
 
     return result.Take();
@@ -271,10 +271,8 @@
 
   // Verify the icon reading and writing function in AppService for the
   // kStandard icon.
-  IconKey icon_key;
-  icon_key.icon_effects = IconEffects::kCrOsStandardIcon;
-  auto ret = MultipleLoadIconFromIconKey(kPackagedApp1Id, icon_key,
-                                         IconType::kStandard);
+  auto ret = MultipleLoadIconWithIconEffects(
+      kPackagedApp1Id, IconEffects::kCrOsStandardIcon, IconType::kStandard);
 
   ASSERT_EQ(2U, ret.size());
   ASSERT_EQ(apps::IconType::kStandard, ret[0]->icon_type);
@@ -291,8 +289,8 @@
 
   // Verify the icon reading and writing function in AppService for the
   // kUncompressed icon.
-  auto ret =
-      LoadIconFromIconKey(kPackagedApp1Id, IconKey(), IconType::kUncompressed);
+  auto ret = LoadIconWithIconEffects(kPackagedApp1Id, IconEffects::kNone,
+                                     IconType::kUncompressed);
 
   ASSERT_EQ(apps::IconType::kUncompressed, ret->icon_type);
   VerifyIcon(src_image_skia, ret->uncompressed);
diff --git a/chrome/browser/apps/app_service/app_icon/web_app_icon_unittest.cc b/chrome/browser/apps/app_service/app_icon/web_app_icon_unittest.cc
index c79d16d..ed0b9759 100644
--- a/chrome/browser/apps/app_service/app_icon/web_app_icon_unittest.cc
+++ b/chrome/browser/apps/app_service/app_icon/web_app_icon_unittest.cc
@@ -889,54 +889,54 @@
     return result.Take();
   }
 
-  apps::IconValuePtr LoadIconFromIconKey(const std::string& app_id,
-                                         const IconKey& icon_key,
-                                         IconType icon_type) {
+  apps::IconValuePtr LoadIconWithIconEffects(const std::string& app_id,
+                                             uint32_t icon_effects,
+                                             IconType icon_type) {
     base::test::TestFuture<apps::IconValuePtr> result;
-    app_service_proxy().LoadIconFromIconKey(
-        AppType::kWeb, app_id, icon_key, icon_type, kSizeInDip,
+    app_service_proxy().LoadIconWithIconEffects(
+        AppType::kWeb, app_id, icon_effects, icon_type, kSizeInDip,
         /*allow_placeholder_icon=*/false, result.GetCallback());
     return result.Take();
   }
 
-  // Call LoadIconFromIconKey twice with the same parameters, to verify the icon
-  // loading process can handle the icon loading request multiple times with the
-  // same params.
-  std::vector<apps::IconValuePtr> MultipleLoadIconFromIconKey(
+  // Call LoadIconWithIconEffects twice with the same parameters, to verify the
+  // icon loading process can handle the icon loading request multiple times
+  // with the same params.
+  std::vector<apps::IconValuePtr> MultipleLoadIconWithSameIconEffects(
       const std::string& app_id,
-      const IconKey& icon_key,
+      uint32_t icon_effects,
       IconType icon_type) {
     base::test::TestFuture<std::vector<apps::IconValuePtr>> result;
     auto barrier_callback =
         base::BarrierCallback<apps::IconValuePtr>(2, result.GetCallback());
 
-    app_service_proxy().LoadIconFromIconKey(
-        AppType::kWeb, app_id, icon_key, icon_type, kSizeInDip,
+    app_service_proxy().LoadIconWithIconEffects(
+        AppType::kWeb, app_id, icon_effects, icon_type, kSizeInDip,
         /*allow_placeholder_icon=*/false, barrier_callback);
-    app_service_proxy().LoadIconFromIconKey(
-        AppType::kWeb, app_id, icon_key, icon_type, kSizeInDip,
+    app_service_proxy().LoadIconWithIconEffects(
+        AppType::kWeb, app_id, icon_effects, icon_type, kSizeInDip,
         /*allow_placeholder_icon=*/false, barrier_callback);
 
     return result.Take();
   }
 
-  // Call LoadIconFromIconKey twice with icon_key1 and icon_key2, to verify the
-  // icon loading process can handle the icon loading request multiple times
-  // with the different icon keys.
-  std::vector<apps::IconValuePtr> MultipleLoadIconFromIconKeys(
+  // Call LoadIconWithIconEffects twice with icon_effects1 and icon_effects2, to
+  // verify the icon loading process can handle the icon loading request
+  // multiple times with the different icon effects.
+  std::vector<apps::IconValuePtr> MultipleLoadIconWithIconEffects(
       const std::string& app_id,
-      const IconKey& icon_key1,
-      const IconKey& icon_key2,
+      uint32_t icon_effects1,
+      uint32_t icon_effects2,
       IconType icon_type) {
     base::test::TestFuture<std::vector<apps::IconValuePtr>> result;
     auto barrier_callback =
         base::BarrierCallback<apps::IconValuePtr>(2, result.GetCallback());
 
-    app_service_proxy().LoadIconFromIconKey(
-        AppType::kWeb, app_id, icon_key1, icon_type, kSizeInDip,
+    app_service_proxy().LoadIconWithIconEffects(
+        AppType::kWeb, app_id, icon_effects1, icon_type, kSizeInDip,
         /*allow_placeholder_icon=*/false, barrier_callback);
-    app_service_proxy().LoadIconFromIconKey(
-        AppType::kWeb, app_id, icon_key2, icon_type, kSizeInDip,
+    app_service_proxy().LoadIconWithIconEffects(
+        AppType::kWeb, app_id, icon_effects2, icon_type, kSizeInDip,
         /*allow_placeholder_icon=*/false, barrier_callback);
 
     return result.Take();
@@ -1019,10 +1019,9 @@
 
   // Verify the icon reading and writing function in AppService for the
   // compressed icon with icon effects.
-  IconKey icon_key;
-  icon_key.icon_effects = apps::IconEffects::kRoundCorners;
-  VerifyCompressedIcon(
-      src_data, *LoadIconFromIconKey(app_id, icon_key, IconType::kCompressed));
+  VerifyCompressedIcon(src_data, *LoadIconWithIconEffects(
+                                     app_id, apps::IconEffects::kRoundCorners,
+                                     IconType::kCompressed));
 }
 
 // Verify AppIconWriter when write icon files multiple times for compressed
@@ -1057,15 +1056,15 @@
 
   // Verify the icon reading and writing function in AppService for the
   // compressed icon without icon effects.
-  VerifyCompressedIcon(src_data1, *LoadIconFromIconKey(app_id, IconKey(),
-                                                       IconType::kCompressed));
+  VerifyCompressedIcon(src_data1,
+                       *LoadIconWithIconEffects(app_id, IconEffects::kNone,
+                                                IconType::kCompressed));
 
   // Verify the icon reading and writing function in AppService for the
   // compressed icon with icon effects.
-  IconKey icon_key;
-  icon_key.icon_effects = apps::IconEffects::kRoundCorners;
-  VerifyCompressedIcon(
-      src_data2, *LoadIconFromIconKey(app_id, icon_key, IconType::kCompressed));
+  VerifyCompressedIcon(src_data2, *LoadIconWithIconEffects(
+                                      app_id, apps::IconEffects::kRoundCorners,
+                                      IconType::kCompressed));
 }
 
 // Verify AppIconWriter when write icon files multiple times for compressed
@@ -1100,10 +1099,9 @@
 
   // Verify the icon reading and writing function in AppService at the same time
   // for the compressed icons with and without icon effects.
-  IconKey icon_key;
-  icon_key.icon_effects = apps::IconEffects::kRoundCorners;
-  auto ret = MultipleLoadIconFromIconKeys(app_id, IconKey(), icon_key,
-                                          IconType::kCompressed);
+  auto ret = MultipleLoadIconWithIconEffects(app_id, apps::IconEffects::kNone,
+                                             apps::IconEffects::kRoundCorners,
+                                             IconType::kCompressed);
 
   ASSERT_EQ(2U, ret.size());
   VerifyCompressedIcon(src_data1, *ret[0]);
@@ -1134,11 +1132,10 @@
 
   // Verify the icon reading and writing function in AppService for the
   // kStandard icon.
-  IconKey icon_key;
-  icon_key.icon_effects =
-      apps::IconEffects::kRoundCorners | apps::IconEffects::kCrOsStandardIcon;
-  apps::IconValuePtr iv =
-      LoadIconFromIconKey(app_id, icon_key, IconType::kStandard);
+  apps::IconValuePtr iv = LoadIconWithIconEffects(
+      app_id,
+      apps::IconEffects::kRoundCorners | apps::IconEffects::kCrOsStandardIcon,
+      IconType::kStandard);
 
   ASSERT_EQ(apps::IconType::kStandard, iv->icon_type);
   VerifyIcon(src_image_skia, iv->uncompressed);
@@ -1177,14 +1174,13 @@
       scale_to_size_in_px, scale);
 
   // Verify the icon reading and writing function in AppService for the
-  // compressed icon with icon effects. LoadIconFromIconKey can generate the
+  // compressed icon with icon effects. LoadIconWithIconEffects can generate the
   // ImageSkia(size_in_dip=64) with icon files(96px and 256px) after resizing
   // them, then apply the icon effect, and encode the ImageSkiaRep(scale=1.0) to
   // generate the compressed icon data.
-  IconKey icon_key;
-  icon_key.icon_effects = apps::IconEffects::kRoundCorners;
-  VerifyCompressedIcon(
-      src_data, *LoadIconFromIconKey(app_id, icon_key, IconType::kCompressed));
+  VerifyCompressedIcon(src_data, *LoadIconWithIconEffects(
+                                     app_id, apps::IconEffects::kRoundCorners,
+                                     IconType::kCompressed));
 
   gfx::ImageSkia src_image_skia = GenerateWebAppIcon(
       app_id, IconPurpose::ANY, sizes_px, scale_to_size_in_px,
@@ -1226,10 +1222,10 @@
 
   // Verify the icon reading and writing function in AppService for the
   // kStandard icon.
-  IconKey icon_key;
-  icon_key.icon_effects =
-      apps::IconEffects::kRoundCorners | apps::IconEffects::kCrOsStandardIcon;
-  auto ret = MultipleLoadIconFromIconKey(app_id, icon_key, IconType::kStandard);
+  auto ret = MultipleLoadIconWithSameIconEffects(
+      app_id,
+      apps::IconEffects::kRoundCorners | apps::IconEffects::kCrOsStandardIcon,
+      IconType::kStandard);
 
   ASSERT_EQ(2U, ret.size());
   ASSERT_EQ(apps::IconType::kStandard, ret[0]->icon_type);
@@ -1372,10 +1368,10 @@
   // Set the icon effects kCrOsStandardIcon. AppIconReader should convert the
   // icon effects to kCrOsStandardBackground and kCrOsStandardMask for the
   // maskable icon.
-  IconKey icon_key;
-  icon_key.icon_effects =
-      apps::IconEffects::kRoundCorners | apps::IconEffects::kCrOsStandardIcon;
-  auto ret = MultipleLoadIconFromIconKey(app_id, icon_key, IconType::kStandard);
+  auto ret = MultipleLoadIconWithSameIconEffects(
+      app_id,
+      apps::IconEffects::kRoundCorners | apps::IconEffects::kCrOsStandardIcon,
+      IconType::kStandard);
 
   ASSERT_EQ(2U, ret.size());
   ASSERT_EQ(apps::IconType::kStandard, ret[0]->icon_type);
@@ -1409,11 +1405,10 @@
 
   // Load the kStandard icon to generate the icon file in the AppService
   // directory.
-  IconKey icon_key;
-  icon_key.icon_effects =
+  uint32_t icon_effects =
       apps::IconEffects::kRoundCorners | apps::IconEffects::kCrOsStandardIcon;
   apps::IconValuePtr iv1 =
-      LoadIconFromIconKey(app_id, icon_key, IconType::kStandard);
+      LoadIconWithIconEffects(app_id, icon_effects, IconType::kStandard);
 
   ASSERT_EQ(apps::IconType::kStandard, iv1->icon_type);
   VerifyIcon(src_image_skia1, iv1->uncompressed);
@@ -1424,11 +1419,13 @@
   gfx::ImageSkia src_image_skia2 = GenerateWebAppIcon(
       app_id, IconPurpose::ANY, sizes_px, scale_to_size_in_px);
 
+  IconKey icon_key;
+  icon_key.icon_effects = icon_effects;
   UpdateIcon(app_id, icon_key);
 
   // Load the kStandard icon again after updating the icon.
   apps::IconValuePtr iv2 =
-      LoadIconFromIconKey(app_id, icon_key, IconType::kStandard);
+      LoadIconWithIconEffects(app_id, icon_effects, IconType::kStandard);
 
   ASSERT_EQ(apps::IconType::kStandard, iv2->icon_type);
   VerifyIcon(src_image_skia2, iv2->uncompressed);
@@ -1472,13 +1469,12 @@
 
   // Load the kStandard icon to generate the icon files in the AppService
   // directory.
-  IconKey icon_key;
-  icon_key.icon_effects =
+  uint32_t icon_effects =
       apps::IconEffects::kRoundCorners | apps::IconEffects::kCrOsStandardIcon;
   apps::IconValuePtr iv1 =
-      LoadIconFromIconKey(app_id1, icon_key, IconType::kStandard);
+      LoadIconWithIconEffects(app_id1, icon_effects, IconType::kStandard);
   apps::IconValuePtr iv2 =
-      LoadIconFromIconKey(app_id2, icon_key, IconType::kStandard);
+      LoadIconWithIconEffects(app_id2, icon_effects, IconType::kStandard);
 
   ASSERT_EQ(apps::IconType::kStandard, iv1->icon_type);
   VerifyIcon(src_image_skia1, iv1->uncompressed);
@@ -1500,9 +1496,9 @@
 
   // Load the kStandard icons again after reinstall apps.
   apps::IconValuePtr iv3 =
-      LoadIconFromIconKey(app_id1, icon_key, IconType::kStandard);
+      LoadIconWithIconEffects(app_id1, icon_effects, IconType::kStandard);
   apps::IconValuePtr iv4 =
-      LoadIconFromIconKey(app_id2, icon_key, IconType::kStandard);
+      LoadIconWithIconEffects(app_id2, icon_effects, IconType::kStandard);
 
   ASSERT_EQ(apps::IconType::kStandard, iv3->icon_type);
   VerifyIcon(src_image_skia3, iv3->uncompressed);
diff --git a/chrome/browser/apps/app_service/app_service_proxy_ash.cc b/chrome/browser/apps/app_service/app_service_proxy_ash.cc
index 1eb4ce8..9e2429d 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_ash.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_ash.cc
@@ -825,7 +825,6 @@
 
 void AppServiceProxyAsh::LoadIconForDialog(const apps::AppUpdate& update,
                                            apps::LoadIconCallback callback) {
-  auto icon_key = update.IconKey();
   constexpr bool kAllowPlaceholderIcon = false;
   auto icon_type = IconType::kStandard;
 
@@ -835,13 +834,8 @@
   // For non_child profile, load the app icon, because the app is blocked by
   // admin.
   if (!dialog_created_callback_.is_null() || !profile_->IsChild()) {
-    if (!icon_key.has_value()) {
-      std::move(callback).Run(std::make_unique<IconValue>());
-      return;
-    }
-    LoadIconFromIconKey(update.AppType(), update.AppId(), icon_key.value(),
-                        icon_type, kAppDialogIconSize, kAllowPlaceholderIcon,
-                        std::move(callback));
+    LoadIcon(update.AppType(), update.AppId(), icon_type, kAppDialogIconSize,
+             kAllowPlaceholderIcon, std::move(callback));
     return;
   }
 
diff --git a/chrome/browser/apps/app_service/app_service_proxy_base.cc b/chrome/browser/apps/app_service/app_service_proxy_base.cc
index 4e949324..2982759 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_base.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_base.cc
@@ -16,6 +16,7 @@
 #include "base/functional/bind.h"
 #include "base/logging.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_source.h"
+#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/app_launch_params.h"
 #include "chrome/browser/apps/app_service/browser_app_launcher.h"
 #include "chrome/browser/apps/app_service/metrics/app_service_metrics.h"
@@ -221,17 +222,35 @@
                                      std::move(callback));
 }
 
+uint32_t AppServiceProxyBase::GetIconEffects(const std::string& app_id) {
+  absl::optional<apps::IconKey> icon_key =
+      app_icon_loader()->GetIconKey(app_id);
+  if (!icon_key.has_value()) {
+    return IconEffects::kNone;
+  }
+  return icon_key->icon_effects;
+}
+
 std::unique_ptr<apps::IconLoader::Releaser>
-AppServiceProxyBase::LoadIconFromIconKey(AppType app_type,
-                                         const std::string& app_id,
-                                         const IconKey& icon_key,
-                                         IconType icon_type,
-                                         int32_t size_hint_in_dip,
-                                         bool allow_placeholder_icon,
-                                         LoadIconCallback callback) {
+AppServiceProxyBase::LoadIconWithIconEffects(AppType app_type,
+                                             const std::string& app_id,
+                                             uint32_t icon_effects,
+                                             IconType icon_type,
+                                             int32_t size_hint_in_dip,
+                                             bool allow_placeholder_icon,
+                                             LoadIconCallback callback) {
+  absl::optional<apps::IconKey> icon_key =
+      app_icon_loader()->GetIconKey(app_id);
+  if (!icon_key.has_value()) {
+    std::move(callback).Run(std::make_unique<IconValue>());
+    return nullptr;
+  }
+
+  icon_key->icon_effects = icon_effects;
+
   return app_icon_loader()->LoadIconFromIconKey(
-      app_id, icon_key, icon_type, size_hint_in_dip, allow_placeholder_icon,
-      std::move(callback));
+      app_id, icon_key.value(), icon_type, size_hint_in_dip,
+      allow_placeholder_icon, std::move(callback));
 }
 
 void AppServiceProxyBase::Launch(const std::string& app_id,
diff --git a/chrome/browser/apps/app_service/app_service_proxy_base.h b/chrome/browser/apps/app_service/app_service_proxy_base.h
index 6a576389..a96ed8f 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_base.h
+++ b/chrome/browser/apps/app_service/app_service_proxy_base.h
@@ -123,18 +123,20 @@
       bool allow_placeholder_icon,
       apps::LoadIconCallback callback);
 
-  // Load the icon for app represented by `app_id`. `icon_key` can be used to
+  // Get the default icon effects for the app represented by `app_id`,
+  // which will be used when calling `LoadIcon()` for that app.
+  uint32_t GetIconEffects(const std::string& app_id);
+
+  // Load the icon for app represented by `app_id`. `icon_effect` can be used to
   // specify custom icon effect the caller wants to apply on the icon.
   // `allow_placeholder_icon` indicate whether we allow loading placeholder icon
   // from the in memory cache and do not attempt to retry to load the actual
   // icon.
   // TODO(crbug.com/1412708): Remove app_type from interface.
-  // TODO(crbug.com/1412708): Update the interface to load icon with icon
-  // effects instead of icon key.
-  std::unique_ptr<IconLoader::Releaser> LoadIconFromIconKey(
+  std::unique_ptr<IconLoader::Releaser> LoadIconWithIconEffects(
       AppType app_type,
       const std::string& app_id,
-      const IconKey& icon_key,
+      uint32_t icon_effects,
       IconType icon_type,
       int32_t size_hint_in_dip,
       bool allow_placeholder_icon,
diff --git a/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc b/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc
index a60340b1..36c1eac 100644
--- a/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc
+++ b/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc
@@ -22,13 +22,13 @@
 #include "chrome/browser/ui/tabs/tab_enums.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_id_constants.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/webui_url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/browser/page_navigator.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "extensions/common/constants.h"
@@ -288,7 +288,7 @@
                            WindowOpenDisposition::NEW_FOREGROUND_TAB);
   }
 
-  web_app::AppId InstallWebApp(
+  webapps::AppId InstallWebApp(
       const std::string& start_url,
       web_app::mojom::UserDisplayMode user_display_mode) {
     auto info = std::make_unique<web_app::WebAppInstallInfo>();
@@ -299,16 +299,16 @@
     return app_id;
   }
 
-  web_app::AppId InstallWebAppOpeningAsTab(const std::string& start_url) {
+  webapps::AppId InstallWebAppOpeningAsTab(const std::string& start_url) {
     return InstallWebApp(start_url, web_app::mojom::UserDisplayMode::kBrowser);
   }
 
-  web_app::AppId InstallWebAppOpeningAsWindow(const std::string& start_url) {
+  webapps::AppId InstallWebAppOpeningAsWindow(const std::string& start_url) {
     return InstallWebApp(start_url,
                          web_app::mojom::UserDisplayMode::kStandalone);
   }
 
-  void UninstallWebApp(const web_app::AppId& app_id) {
+  void UninstallWebApp(const webapps::AppId& app_id) {
     Profile* profile = ProfileManager::GetPrimaryUserProfile();
     web_app::test::UninstallWebApp(profile, app_id);
   }
diff --git a/chrome/browser/apps/app_service/metrics/app_platform_metrics_browsertest.cc b/chrome/browser/apps/app_service/metrics/app_platform_metrics_browsertest.cc
index 70c02c9..8a3466c 100644
--- a/chrome/browser/apps/app_service/metrics/app_platform_metrics_browsertest.cc
+++ b/chrome/browser/apps/app_service/metrics/app_platform_metrics_browsertest.cc
@@ -23,7 +23,7 @@
 #include "url/gurl.h"
 
 using apps::GetAppTypeName;
-using web_app::AppId;
+using webapps::AppId;
 
 class AppPlatformMetricsBrowserTest : public InProcessBrowserTest {
  public:
diff --git a/chrome/browser/apps/app_service/metrics/website_metrics_browsertest.cc b/chrome/browser/apps/app_service/metrics/website_metrics_browsertest.cc
index 98bfb380..16a5bc0 100644
--- a/chrome/browser/apps/app_service/metrics/website_metrics_browsertest.cc
+++ b/chrome/browser/apps/app_service/metrics/website_metrics_browsertest.cc
@@ -22,7 +22,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_enums.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_id_constants.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chrome/common/chrome_switches.h"
@@ -30,6 +29,7 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/history/core/browser/history_types.h"
 #include "components/ukm/test_ukm_recorder.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/browser/page_navigator.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
@@ -160,7 +160,7 @@
     return website_metrics_browser_test_mixin_.NavigateActiveTab(browser, url);
   }
 
-  web_app::AppId InstallWebApp(
+  webapps::AppId InstallWebApp(
       const std::string& start_url,
       web_app::mojom::UserDisplayMode user_display_mode) {
     auto info = std::make_unique<web_app::WebAppInstallInfo>();
@@ -170,11 +170,11 @@
     return app_id;
   }
 
-  web_app::AppId InstallWebAppOpeningAsTab(const std::string& start_url) {
+  webapps::AppId InstallWebAppOpeningAsTab(const std::string& start_url) {
     return InstallWebApp(start_url, web_app::mojom::UserDisplayMode::kBrowser);
   }
 
-  web_app::AppId InstallWebAppOpeningAsWindow(const std::string& start_url) {
+  webapps::AppId InstallWebAppOpeningAsWindow(const std::string& start_url) {
     return InstallWebApp(start_url,
                          web_app::mojom::UserDisplayMode::kStandalone);
   }
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
index 3cbf9cd..7fc08759 100644
--- a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
+++ b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
@@ -632,7 +632,7 @@
 void ExtensionAppsChromeOs::OnIsCapturingVideoChanged(
     content::WebContents* web_contents,
     bool is_capturing_video) {
-  const web_app::AppId* web_app_id =
+  const webapps::AppId* web_app_id =
       web_app::WebAppTabHelper::GetAppId(web_contents);
   if (web_app_id) {
     // This media access is coming from a web app.
@@ -659,7 +659,7 @@
 void ExtensionAppsChromeOs::OnIsCapturingAudioChanged(
     content::WebContents* web_contents,
     bool is_capturing_audio) {
-  const web_app::AppId* web_app_id =
+  const webapps::AppId* web_app_id =
       web_app::WebAppTabHelper::GetAppId(web_contents);
   if (web_app_id) {
     // This media access is coming from a web app.
diff --git a/chrome/browser/apps/app_service/publishers/web_apps_crosapi_browsertest.cc b/chrome/browser/apps/app_service/publishers/web_apps_crosapi_browsertest.cc
index 72c50a0..06ba7be 100644
--- a/chrome/browser/apps/app_service/publishers/web_apps_crosapi_browsertest.cc
+++ b/chrome/browser/apps/app_service/publishers/web_apps_crosapi_browsertest.cc
@@ -17,10 +17,10 @@
 #include "chrome/browser/ash/crosapi/ash_requires_lacros_browsertestbase.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chromeos/crosapi/mojom/test_controller.mojom.h"
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/instance_registry.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/test/browser_test.h"
 #include "ui/base/models/simple_menu_model.h"
 #include "ui/views/widget/any_widget_observer.h"
@@ -132,7 +132,7 @@
   const size_t kUnpinIndex = 1;
   const size_t kCloseIndex = 2;
 
-  const web_app::AppId app_id =
+  const webapps::AppId app_id =
       InstallWebApp("https://example.org/", apps::WindowMode::kWindow);
 
   EXPECT_EQ(ash::ShelfModel::Get()->ItemIndexByAppID(app_id), -1);
@@ -213,7 +213,7 @@
   const size_t kPinIndex = 1;
   const size_t kUninstallIndex = 3;
 
-  const web_app::AppId app_id =
+  const webapps::AppId app_id =
       InstallWebApp("https://example.org/", apps::WindowMode::kWindow);
 
   {
diff --git a/chrome/browser/apps/app_service/subscriber_crosapi.cc b/chrome/browser/apps/app_service/subscriber_crosapi.cc
index b9e262f..8e2fa77 100644
--- a/chrome/browser/apps/app_service/subscriber_crosapi.cc
+++ b/chrome/browser/apps/app_service/subscriber_crosapi.cc
@@ -149,15 +149,12 @@
                                  IconType icon_type,
                                  int32_t size_hint_in_dip,
                                  apps::LoadIconCallback callback) {
-  if (!icon_key) {
-    std::move(callback).Run(std::make_unique<IconValue>());
-    return;
-  }
-
-  proxy_->LoadIconFromIconKey(proxy_->AppRegistryCache().GetAppType(app_id),
-                              app_id, *icon_key, icon_type, size_hint_in_dip,
-                              /*allow_placeholder_icon=*/false,
-                              std::move(callback));
+  // Currently there is no usage of custom icon_key icon loading from
+  // Lacros. Drop the icon key from the interface here.
+  // TODO(crbug.com/1412708): Update the crosapi interface to match this.
+  proxy_->LoadIcon(proxy_->AppRegistryCache().GetAppType(app_id), app_id,
+                   icon_type, size_hint_in_dip,
+                   /*allow_placeholder_icon=*/false, std::move(callback));
 }
 
 void SubscriberCrosapi::AddPreferredAppDeprecated(
diff --git a/chrome/browser/apps/app_service/web_contents_app_id_utils.cc b/chrome/browser/apps/app_service/web_contents_app_id_utils.cc
index 56be4760..b42a376 100644
--- a/chrome/browser/apps/app_service/web_contents_app_id_utils.cc
+++ b/chrome/browser/apps/app_service/web_contents_app_id_utils.cc
@@ -19,13 +19,13 @@
 #include "chrome/browser/web_applications/user_display_mode.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/browser/web_applications/web_app_tab_helper.h"
 #include "chrome/browser/web_applications/web_app_utils.h"
 #include "components/services/app_service/public/cpp/app_types.h"
 #include "components/services/app_service/public/cpp/app_update.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
@@ -91,7 +91,7 @@
       }
     }
 
-    absl::optional<web_app::AppId> app_id =
+    absl::optional<webapps::AppId> app_id =
         provider->registrar_unsafe().FindAppWithUrlInScope(
             tab->GetVisibleURL());
     if (app_id) {
@@ -121,7 +121,7 @@
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
 std::string GetAppIdForWebContents(content::WebContents* web_contents) {
-  const web_app::AppId* app_id =
+  const webapps::AppId* app_id =
       web_app::WebAppTabHelper::GetAppId(web_contents);
   if (app_id)
     return *app_id;
@@ -153,7 +153,7 @@
   } else {
     bool app_installed = IsAppReady(profile, app_id);
     web_app::WebAppTabHelper::FromWebContents(web_contents)
-        ->SetAppId(app_installed ? absl::optional<web_app::AppId>(app_id)
+        ->SetAppId(app_installed ? absl::optional<webapps::AppId>(app_id)
                                  : absl::nullopt);
     extensions::TabHelper::FromWebContents(web_contents)
         ->SetExtensionAppById(std::string());
diff --git a/chrome/browser/apps/digital_goods/digital_goods_lacros.cc b/chrome/browser/apps/digital_goods/digital_goods_lacros.cc
index 17b059d..e696399 100644
--- a/chrome/browser/apps/digital_goods/digital_goods_lacros.cc
+++ b/chrome/browser/apps/digital_goods/digital_goods_lacros.cc
@@ -20,7 +20,7 @@
 
 namespace {
 
-absl::optional<std::pair<web_app::AppId, GURL>> GetWebAppIdAndScopeForDocument(
+absl::optional<std::pair<webapps::AppId, GURL>> GetWebAppIdAndScopeForDocument(
     content::RenderFrameHost& render_frame_host) {
   web_app::WebAppProvider* provider = web_app::WebAppProvider::GetForWebApps(
       Profile::FromBrowserContext(render_frame_host.GetBrowserContext()));
@@ -29,7 +29,7 @@
   }
 
   const web_app::WebAppRegistrar& registrar = provider->registrar_unsafe();
-  absl::optional<web_app::AppId> app_id = registrar.FindAppWithUrlInScope(
+  absl::optional<webapps::AppId> app_id = registrar.FindAppWithUrlInScope(
       render_frame_host.GetMainFrame()->GetLastCommittedURL());
   if (!app_id) {
     return absl::nullopt;
diff --git a/chrome/browser/apps/digital_goods/util.cc b/chrome/browser/apps/digital_goods/util.cc
index ac4870b..585bce7 100644
--- a/chrome/browser/apps/digital_goods/util.cc
+++ b/chrome/browser/apps/digital_goods/util.cc
@@ -53,7 +53,7 @@
   }
 
   const web_app::WebAppRegistrar& registrar = provider->registrar_unsafe();
-  absl::optional<web_app::AppId> app_id = registrar.FindAppWithUrlInScope(
+  absl::optional<webapps::AppId> app_id = registrar.FindAppWithUrlInScope(
       render_frame_host->GetMainFrame()->GetLastCommittedURL());
   if (!app_id) {
     return std::string();
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index e472889..3a97f27 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -4165,6 +4165,7 @@
     "//components/web_resource",
     "//components/webapps/browser",
     "//components/webapps/browser:constants",
+    "//components/webapps/common",
     "//components/zoom",
     "//content/public/common",
     "//content/public/common:main_function_params",
@@ -4869,6 +4870,7 @@
     "//components/services/filesystem/public/mojom",
     "//components/sync/base",
     "//components/sync/service",
+    "//components/webapps/common",
     "//crypto",
     "//extensions/browser",
     "//extensions/common:common_constants",
@@ -6337,6 +6339,7 @@
     "//components/version_info",
     "//components/webapps/browser",
     "//components/webapps/browser:constants",
+    "//components/webapps/common",
     "//content/public/browser",
     "//content/public/common",
     "//content/test:test_support",
diff --git a/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc b/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
index af0483d6..bb14c45 100644
--- a/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
+++ b/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
@@ -689,7 +689,8 @@
   sm_.Replay();
 }
 
-IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, OpenContextMenu) {
+// TODO(https://crbug.com/1486666): Fix flakiness
+IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, DISABLED_OpenContextMenu) {
   EnableChromeVox();
   StablizeChromeVoxState();
   sm_.Call([this]() { SendKeyPressWithSearch(ui::VKEY_M); });
diff --git a/chrome/browser/ash/app_mode/web_app/web_kiosk_app_update_observer.cc b/chrome/browser/ash/app_mode/web_app/web_kiosk_app_update_observer.cc
index 7d855ad..985094c 100644
--- a/chrome/browser/ash/app_mode/web_app/web_kiosk_app_update_observer.cc
+++ b/chrome/browser/ash/app_mode/web_app/web_kiosk_app_update_observer.cc
@@ -75,11 +75,9 @@
         GURL start_url = GURL(app_info.PublisherId());
 
         if (icon_updated && app_info.IconKey()) {
-          auto icon_key = app_info.IconKey().value();
-          // Remove web app icon effects for Kiosk apps menu.
-          icon_key.icon_effects = apps::IconEffects::kNone;
-          app_service_->LoadIconFromIconKey(
-              apps::AppType::kWeb, app_info.AppId(), icon_key,
+          app_service_->LoadIconWithIconEffects(
+              // Remove web app icon effects for Kiosk apps menu.
+              apps::AppType::kWeb, app_info.AppId(), apps::IconEffects::kNone,
               apps::IconType::kUncompressed, kWebKioskIconSize,
               /*allow_placeholder_icon=*/true,
               base::BindOnce(&WebKioskAppUpdateObserver::OnAppServiceIconLoaded,
diff --git a/chrome/browser/ash/app_restore/full_restore_app_launch_handler_browsertest.cc b/chrome/browser/ash/app_restore/full_restore_app_launch_handler_browsertest.cc
index dfd8583..6ab3c78a 100644
--- a/chrome/browser/ash/app_restore/full_restore_app_launch_handler_browsertest.cc
+++ b/chrome/browser/ash/app_restore/full_restore_app_launch_handler_browsertest.cc
@@ -53,7 +53,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_features.h"
@@ -75,6 +74,7 @@
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/app_types.h"
 #include "components/strings/grit/components_strings.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "content/public/test/test_utils.h"
@@ -290,7 +290,7 @@
   void CreateWebApp() {
     auto web_app_install_info = std::make_unique<web_app::WebAppInstallInfo>();
     web_app_install_info->start_url = GURL("https://example.org");
-    web_app::AppId app_id = web_app::test::InstallWebApp(
+    webapps::AppId app_id = web_app::test::InstallWebApp(
         profile(), std::move(web_app_install_info));
   }
 
diff --git a/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper.cc b/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper.cc
index f2f6681..a0d0e24 100644
--- a/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper.cc
+++ b/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper.cc
@@ -11,6 +11,7 @@
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/unguessable_token.h"
+#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/app_service/launch_utils.h"
@@ -20,7 +21,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/app_update.h"
-#include "components/services/app_service/public/cpp/icon_types.h"
 #include "components/services/app_service/public/cpp/instance_update.h"
 #include "components/services/app_service/public/cpp/types_util.h"
 #include "extensions/browser/extension_registry.h"
@@ -173,8 +173,8 @@
   const std::string app_service_id = AppServiceIdFromAppId(app_id, profile_);
   DCHECK(!app_service_id.empty());
 
-  GetAppProxy()->LoadIconFromIconKey(
-      app_id.app_type(), app_service_id, apps::IconKey(),
+  GetAppProxy()->LoadIconWithIconEffects(
+      app_id.app_type(), app_service_id, apps::IconEffects::kNone,
       apps::IconType::kStandard, size_hint_in_dp,
       /* allow_placeholder_icon */ false,
       base::BindOnce(
diff --git a/chrome/browser/ash/dbus/dlp_files_policy_service_provider_unittest.cc b/chrome/browser/ash/dbus/dlp_files_policy_service_provider_unittest.cc
index bbfa7fde..a0b5e56 100644
--- a/chrome/browser/ash/dbus/dlp_files_policy_service_provider_unittest.cc
+++ b/chrome/browser/ash/dbus/dlp_files_policy_service_provider_unittest.cc
@@ -52,15 +52,13 @@
   void SetUp() override {
     DlpFilesTestBase::SetUp();
 
-    profile_ = TestingProfile::Builder().Build();
-
     EXPECT_CALL(*rules_manager_, IsFilesPolicyEnabled)
         .WillRepeatedly(testing::Return(true));
     EXPECT_CALL(*rules_manager_, GetReportingManager())
         .WillRepeatedly(::testing::Return(nullptr));
     files_controller_ = std::make_unique<
-        testing::StrictMock<policy::MockDlpFilesControllerAsh>>(*rules_manager_,
-                                                                profile_.get());
+        testing::StrictMock<policy::MockDlpFilesControllerAsh>>(
+        *rules_manager_);
     EXPECT_CALL(*rules_manager_, GetDlpFilesController())
         .WillRepeatedly(::testing::Return(files_controller_.get()));
   }
@@ -92,7 +90,7 @@
     return response;
   }
 
-  std::unique_ptr<TestingProfile> profile_;
+
   std::unique_ptr<DlpFilesPolicyServiceProvider> dlp_policy_service_;
   ServiceProviderTestHelper dbus_service_test_helper_;
 
diff --git a/chrome/browser/ash/extensions/file_manager/file_manager_private_apitest.cc b/chrome/browser/ash/extensions/file_manager/file_manager_private_apitest.cc
index b1f20c4..5514415 100644
--- a/chrome/browser/ash/extensions/file_manager/file_manager_private_apitest.cc
+++ b/chrome/browser/ash/extensions/file_manager/file_manager_private_apitest.cc
@@ -771,9 +771,6 @@
   }
 
   void TearDownOnMainThread() override {
-    // The files controller must be destroyed before the profile since it's
-    // holding a pointer to it.
-    files_controller_.reset();
     mock_rules_manager_ = nullptr;
     fpnm_ = nullptr;
     FileManagerPrivateApiTest::TearDownOnMainThread();
@@ -786,8 +783,8 @@
     ON_CALL(*mock_rules_manager_, IsFilesPolicyEnabled)
         .WillByDefault(testing::Return(true));
 
-    files_controller_ = std::make_unique<policy::DlpFilesControllerAsh>(
-        *mock_rules_manager_, Profile::FromBrowserContext(context));
+    files_controller_ =
+        std::make_unique<policy::DlpFilesControllerAsh>(*mock_rules_manager_);
     ON_CALL(*mock_rules_manager_, GetDlpFilesController)
         .WillByDefault(testing::Return(files_controller_.get()));
 
diff --git a/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc b/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc
index cd73046..6f90c20 100644
--- a/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc
+++ b/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc
@@ -955,9 +955,8 @@
  protected:
   class MockFilesController : public policy::DlpFilesControllerAsh {
    public:
-    explicit MockFilesController(const policy::DlpRulesManager& rules_manager,
-                                 Profile* profile)
-        : DlpFilesControllerAsh(rules_manager, profile) {}
+    explicit MockFilesController(const policy::DlpRulesManager& rules_manager)
+        : DlpFilesControllerAsh(rules_manager) {}
     ~MockFilesController() override = default;
 
     MOCK_METHOD(bool,
@@ -1003,7 +1002,7 @@
     ON_CALL(*rules_manager_, IsFilesPolicyEnabled)
         .WillByDefault(testing::Return(true));
     mock_files_controller_ =
-        std::make_unique<MockFilesController>(*rules_manager_, profile_.get());
+        std::make_unique<MockFilesController>(*rules_manager_);
     ON_CALL(*rules_manager_, GetDlpFilesController)
         .WillByDefault(testing::Return(mock_files_controller_.get()));
   }
diff --git a/chrome/browser/ash/file_manager/copy_or_move_io_task_policy_unittest.cc b/chrome/browser/ash/file_manager/copy_or_move_io_task_policy_unittest.cc
index 62f49e3..53f27bf8 100644
--- a/chrome/browser/ash/file_manager/copy_or_move_io_task_policy_unittest.cc
+++ b/chrome/browser/ash/file_manager/copy_or_move_io_task_policy_unittest.cc
@@ -1476,7 +1476,7 @@
 
     files_controller_ = std::make_unique<
         testing::StrictMock<policy::MockDlpFilesControllerAsh>>(
-        *mock_rules_manager_, profile_.get());
+        *mock_rules_manager_);
 
     ON_CALL(*mock_rules_manager_, GetDlpFilesController())
         .WillByDefault(::testing::Return(files_controller_.get()));
@@ -1530,10 +1530,10 @@
   base::test::ScopedFeatureList scoped_feature_list_;
   content::BrowserTaskEnvironment task_environment_;
   ash::disks::FakeDiskMountManager disk_mount_manager_;
-  const std::unique_ptr<TestingProfile> profile_;
   raw_ptr<policy::MockDlpRulesManager, DanglingUntriaged | ExperimentalAsh>
       mock_rules_manager_ = nullptr;
   std::unique_ptr<policy::MockDlpFilesControllerAsh> files_controller_;
+  const std::unique_ptr<TestingProfile> profile_;
   base::ScopedTempDir temp_dir_;
   scoped_refptr<storage::FileSystemContext> file_system_context_;
   raw_ptr<ash::FakeChromeUserManager, DanglingUntriaged | ExperimentalAsh>
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest_base.h b/chrome/browser/ash/file_manager/file_manager_browsertest_base.h
index b681c5f..2711305 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest_base.h
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest_base.h
@@ -20,8 +20,8 @@
 #include "chrome/browser/ash/login/test/logged_in_user_mixin.h"
 #include "chrome/browser/extensions/mixin_based_extension_apitest.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/test/base/devtools_listener.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/browser/devtools_agent_host_observer.h"
 
 class NotificationDisplayServiceTester;
diff --git a/chrome/browser/ash/file_manager/file_manager_policy_browsertest.cc b/chrome/browser/ash/file_manager/file_manager_policy_browsertest.cc
index e11bff2a..a4d9e1c 100644
--- a/chrome/browser/ash/file_manager/file_manager_policy_browsertest.cc
+++ b/chrome/browser/ash/file_manager/file_manager_policy_browsertest.cc
@@ -88,8 +88,8 @@
     ON_CALL(*mock_rules_manager_, IsFilesPolicyEnabled)
         .WillByDefault(testing::Return(true));
 
-    files_controller_ = std::make_unique<policy::DlpFilesControllerAsh>(
-        *mock_rules_manager_, Profile::FromBrowserContext(context));
+    files_controller_ =
+        std::make_unique<policy::DlpFilesControllerAsh>(*mock_rules_manager_);
     ON_CALL(*mock_rules_manager_, GetDlpFilesController)
         .WillByDefault(testing::Return(files_controller_.get()));
 
@@ -303,8 +303,6 @@
   raw_ptr<policy::MockDlpRulesManager, DanglingUntriaged | ExperimentalAsh>
       mock_rules_manager_ = nullptr;
 
-  std::unique_ptr<policy::DlpFilesControllerAsh> files_controller_;
-
   std::unique_ptr<file_access::MockScopedFileAccessDelegate>
       scoped_file_access_delegate_;
 
@@ -346,6 +344,7 @@
     std::move(callback).Run(response);
   }
 
+  std::unique_ptr<policy::DlpFilesControllerAsh> files_controller_;
 };
 
 constexpr char kFileTransferConnectorSettingsForDlp[] = R"(
@@ -798,13 +797,6 @@
                             base::Unretained(this)));
   }
 
-  void TearDownOnMainThread() override {
-    // The files controller must be destroyed before the profile since it's
-    // holding a pointer to it.
-    files_controller_.reset();
-    FileManagerBrowserTestBase::TearDownOnMainThread();
-  }
-
   bool HandleDlpCommands(const std::string& name,
                          const base::Value::Dict& value,
                          std::string* output) override {
diff --git a/chrome/browser/ash/file_manager/file_tasks_browsertest.cc b/chrome/browser/ash/file_manager/file_tasks_browsertest.cc
index c0c9a8a..698b814 100644
--- a/chrome/browser/ash/file_manager/file_tasks_browsertest.cc
+++ b/chrome/browser/ash/file_manager/file_tasks_browsertest.cc
@@ -527,7 +527,7 @@
   TaskDescriptor task_descriptor;
   if (GetParam().crosapi_state == TestProfileParam::CrosapiParam::kDisabled) {
     // Install a PWA in ash.
-    web_app::AppId app_id =
+    webapps::AppId app_id =
         web_app::test::InstallWebApp(profile, std::move(web_app_info));
     task_descriptor = TaskDescriptor(app_id, TaskType::TASK_TYPE_WEB_APP,
                                      "https://www.example.com/handle_file");
@@ -766,14 +766,12 @@
                           base::Unretained(this)));
   ASSERT_TRUE(policy::DlpRulesManagerFactory::GetForPrimaryProfile());
 
-  auto files_controller =
-      std::make_unique<policy::DlpFilesControllerAsh>(*rules_manager_, profile);
-
-  ON_CALL(*rules_manager_, GetDlpFilesController)
-      .WillByDefault(testing::Return(files_controller.get()));
-
   ON_CALL(*rules_manager_, IsFilesPolicyEnabled)
       .WillByDefault(testing::Return(true));
+  std::unique_ptr<policy::DlpFilesControllerAsh> files_controller_ =
+      std::make_unique<policy::DlpFilesControllerAsh>(*rules_manager_);
+  ON_CALL(*rules_manager_, GetDlpFilesController)
+      .WillByDefault(testing::Return(files_controller_.get()));
 
   EXPECT_CALL(*rules_manager_, IsRestrictedDestination)
       .Times(testing::AtLeast(1))
diff --git a/chrome/browser/ash/file_manager/restore_to_destination_io_task_unittest.cc b/chrome/browser/ash/file_manager/restore_to_destination_io_task_unittest.cc
index fcf0568..7e3bcb66 100644
--- a/chrome/browser/ash/file_manager/restore_to_destination_io_task_unittest.cc
+++ b/chrome/browser/ash/file_manager/restore_to_destination_io_task_unittest.cc
@@ -268,7 +268,6 @@
   }
 
   void TearDown() override {
-    files_controller_.reset();
     io_task_controller_ = nullptr;
     mock_rules_manager_ = nullptr;
     RestoreToDestinationIOTaskTest::TearDown();
@@ -289,7 +288,7 @@
         .WillRepeatedly(testing::Return(true));
 
     files_controller_ = std::make_unique<policy::MockDlpFilesControllerAsh>(
-        *mock_rules_manager_, Profile::FromBrowserContext(context));
+        *mock_rules_manager_);
     EXPECT_CALL(*mock_rules_manager_, GetDlpFilesController())
         .WillRepeatedly(::testing::Return(files_controller_.get()));
 
diff --git a/chrome/browser/ash/input_method/editor_mediator.cc b/chrome/browser/ash/input_method/editor_mediator.cc
index 72e9d81..8d82ce2 100644
--- a/chrome/browser/ash/input_method/editor_mediator.cc
+++ b/chrome/browser/ash/input_method/editor_mediator.cc
@@ -4,13 +4,16 @@
 
 #include "chrome/browser/ash/input_method/editor_mediator.h"
 
+#include <string_view>
+
 #include "ash/constants/ash_pref_names.h"
 #include "ash/public/cpp/tablet_mode.h"
 #include "ash/shell.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "base/check_op.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
-#include "chrome/browser/ui/webui/ash/mako/mako_ui.h"
+#include "chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/ime/ash/ime_bridge.h"
 
 namespace ash::input_method {
@@ -103,7 +106,7 @@
 }
 
 void EditorMediator::OnFocus(int context_id) {
-  if (mako_page_handler_.IsVisible()) {
+  if (mako_bubble_coordinator_.IsShowingUI()) {
     return;
   }
 
@@ -120,7 +123,7 @@
 }
 
 void EditorMediator::OnBlur() {
-  if (mako_page_handler_.IsVisible()) {
+  if (mako_bubble_coordinator_.IsShowingUI()) {
     return;
   }
 
@@ -147,7 +150,7 @@
 
 void EditorMediator::OnSurroundingTextChanged(const std::u16string& text,
                                               gfx::Range selection_range) {
-  if (mako_page_handler_.IsVisible()) {
+  if (mako_bubble_coordinator_.IsShowingUI()) {
     return;
   }
 
@@ -159,33 +162,38 @@
 
 void EditorMediator::ProcessConsentAction(ConsentAction consent_action) {
   consent_store_->ProcessConsentAction(consent_action);
-  HandleTrigger();
+  HandleTrigger(/*preset_query_id=*/absl::nullopt,
+                /*freeform_text=*/absl::nullopt);
 }
 
 void EditorMediator::OnPromoCardDeclined() {
   consent_store_->ProcessPromoCardAction(PromoCardAction::kDeclined);
 }
 
-void EditorMediator::HandleTrigger() {
+void EditorMediator::HandleTrigger(
+    absl::optional<std::string_view> preset_query_id,
+    absl::optional<std::string_view> freeform_text) {
   switch (GetEditorMode()) {
     case EditorMode::kRewrite:
-      mako_page_handler_.ShowRewriteUI(profile_);
+      mako_bubble_coordinator_.ShowEditorUI(profile_, MakoEditorMode::kRewrite,
+                                            preset_query_id, freeform_text);
       break;
     case EditorMode::kWrite:
-      mako_page_handler_.ShowWriteUI(profile_);
+      mako_bubble_coordinator_.ShowEditorUI(profile_, MakoEditorMode::kWrite,
+                                            preset_query_id, freeform_text);
       break;
     case EditorMode::kConsentNeeded:
-      mako_page_handler_.ShowConsentUI(profile_);
+      mako_bubble_coordinator_.ShowConsentUI(profile_);
       break;
     case EditorMode::kBlocked:
-      mako_page_handler_.CloseUI();
+      mako_bubble_coordinator_.CloseUI();
   }
 }
 
 void EditorMediator::OnTextInserted() {
   // After queuing the text to be inserted, closing the mako web ui should
   // return the focus back to the original input.
-  mako_page_handler_.CloseUI();
+  mako_bubble_coordinator_.CloseUI();
 }
 
 void EditorMediator::OnTextFieldContextualInfoChanged(
@@ -224,6 +232,7 @@
 void EditorMediator::OnProfileWillBeDestroyed(Profile* profile) {
   profile_observation_.Reset();
 
+  mako_bubble_coordinator_.CloseUI();
   profile_ = nullptr;
   consent_store_ = nullptr;
   editor_switch_ = nullptr;
diff --git a/chrome/browser/ash/input_method/editor_mediator.h b/chrome/browser/ash/input_method/editor_mediator.h
index a8e08d3..4a21a7d 100644
--- a/chrome/browser/ash/input_method/editor_mediator.h
+++ b/chrome/browser/ash/input_method/editor_mediator.h
@@ -22,7 +22,7 @@
 #include "chrome/browser/ash/input_method/mojom/editor.mojom.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_observer.h"
-#include "chrome/browser/ui/webui/ash/mako/mako_ui.h"
+#include "chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
@@ -74,7 +74,11 @@
 
   // EditorPanelManager::Delegate
   void OnPromoCardDeclined() override;
-  void HandleTrigger() override;
+  // TODO(b/301869966): Consider removing default parameters once the context
+  // menu Orca entry is removed.
+  void HandleTrigger(
+      absl::optional<std::string_view> preset_query_id = absl::nullopt,
+      absl::optional<std::string_view> freeform_text = absl::nullopt) override;
   EditorMode GetEditorMode() const override;
 
   // TabletModeObserver:
@@ -113,7 +117,7 @@
 
   EditorInstanceImpl editor_instance_impl_;
   EditorPanelManager panel_manager_;
-  MakoPageHandler mako_page_handler_;
+  MakoBubbleCoordinator mako_bubble_coordinator_;
 
   std::unique_ptr<EditorSwitch> editor_switch_;
   std::unique_ptr<EditorConsentStore> consent_store_;
diff --git a/chrome/browser/ash/input_method/editor_panel_manager.cc b/chrome/browser/ash/input_method/editor_panel_manager.cc
index 62963061..5a12488 100644
--- a/chrome/browser/ash/input_method/editor_panel_manager.cc
+++ b/chrome/browser/ash/input_method/editor_panel_manager.cc
@@ -106,16 +106,19 @@
 }
 
 void EditorPanelManager::StartEditingFlow() {
-  delegate_->HandleTrigger();
+  delegate_->HandleTrigger(/*preset_query_id=*/absl::nullopt,
+                           /*freeform_text=*/absl::nullopt);
 }
 
 void EditorPanelManager::StartEditingFlowWithPreset(
     const std::string& text_query_id) {
-  NOTIMPLEMENTED_LOG_ONCE();
+  delegate_->HandleTrigger(/*preset_query_id=*/text_query_id,
+                           /*freeform_text=*/absl::nullopt);
 }
 
 void EditorPanelManager::StartEditingFlowWithFreeform(const std::string& text) {
-  NOTIMPLEMENTED_LOG_ONCE();
+  delegate_->HandleTrigger(/*preset_query_id=*/absl::nullopt,
+                           /*freeform_text=*/text);
 }
 
 void EditorPanelManager::OnGetPresetTextQueriesResult(
diff --git a/chrome/browser/ash/input_method/editor_panel_manager.h b/chrome/browser/ash/input_method/editor_panel_manager.h
index b106171..b2c9ce9 100644
--- a/chrome/browser/ash/input_method/editor_panel_manager.h
+++ b/chrome/browser/ash/input_method/editor_panel_manager.h
@@ -16,6 +16,7 @@
 #include "chromeos/crosapi/mojom/editor_panel.mojom.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
 #include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash::input_method {
 
@@ -33,7 +34,9 @@
         mojo::PendingReceiver<orca::mojom::EditorClient> pending_receiver) = 0;
 
     virtual void OnPromoCardDeclined() = 0;
-    virtual void HandleTrigger() = 0;
+    virtual void HandleTrigger(
+        absl::optional<std::string_view> preset_query_id,
+        absl::optional<std::string_view> freeform_text) = 0;
     virtual EditorMode GetEditorMode() const = 0;
   };
 
diff --git a/chrome/browser/ash/login/easy_unlock/smartlock_feature_usage_metrics.cc b/chrome/browser/ash/login/easy_unlock/smartlock_feature_usage_metrics.cc
index 07b4edf8..640a56b 100644
--- a/chrome/browser/ash/login/easy_unlock/smartlock_feature_usage_metrics.cc
+++ b/chrome/browser/ash/login/easy_unlock/smartlock_feature_usage_metrics.cc
@@ -52,8 +52,6 @@
       [[fallthrough]];
     case FeatureState::kUnavailableSuiteDisabled:
       [[fallthrough]];
-    case FeatureState::kFurtherSetupRequired:
-      [[fallthrough]];
     case FeatureState::kUnavailableTopLevelFeatureDisabled:
       return true;
   }
diff --git a/chrome/browser/ash/login/easy_unlock/smartlock_feature_usage_metrics_unittest.cc b/chrome/browser/ash/login/easy_unlock/smartlock_feature_usage_metrics_unittest.cc
index a2d5a11..038c378 100644
--- a/chrome/browser/ash/login/easy_unlock/smartlock_feature_usage_metrics_unittest.cc
+++ b/chrome/browser/ash/login/easy_unlock/smartlock_feature_usage_metrics_unittest.cc
@@ -67,9 +67,6 @@
   TestFeatureState(FeatureState::kUnavailableSuiteDisabled,
                    /*expected_eligible_value=*/true,
                    /*expected_enabled_value=*/false);
-  TestFeatureState(FeatureState::kFurtherSetupRequired,
-                   /*expected_eligible_value=*/true,
-                   /*expected_enabled_value=*/false);
   TestFeatureState(FeatureState::kUnavailableTopLevelFeatureDisabled,
                    /*expected_eligible_value=*/true,
                    /*expected_enabled_value=*/false);
diff --git a/chrome/browser/ash/policy/core/device_policy_decoder.cc b/chrome/browser/ash/policy/core/device_policy_decoder.cc
index 270ee9ff..3bbf6f59 100644
--- a/chrome/browser/ash/policy/core/device_policy_decoder.cc
+++ b/chrome/browser/ash/policy/core/device_policy_decoder.cc
@@ -10,13 +10,13 @@
 #include <utility>
 
 #include "ash/system/privacy_hub/privacy_hub_controller.h"
-#include "base/containers/fixed_flat_map.h"
 #include "base/functional/callback.h"
 #include "base/json/json_reader.h"
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/syslog_logging.h"
+#include "base/values.h"
 #include "chrome/browser/ash/policy/core/device_local_account.h"
 #include "chrome/browser/ash/policy/off_hours/off_hours_proto_parser.h"
 #include "chrome/browser/ash/tpm_firmware_update.h"
@@ -32,6 +32,7 @@
 #include "components/policy/core/common/policy_types.h"
 #include "components/policy/core/common/schema.h"
 #include "components/policy/policy_constants.h"
+#include "components/policy/proto/chrome_device_policy.pb.h"
 #include "components/strings/grit/components_strings.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
@@ -76,33 +77,6 @@
   }
 }
 
-base::Value::List ProtoToList(const RepeatedPtrField<std::string>& strings) {
-  base::Value::List result = base::Value::List::with_capacity(strings.size());
-  for (const auto& value : strings) {
-    result.Append(value);
-  }
-  return result;
-}
-
-void SetDeviceDlcPredownloadListPolicy(
-    const RepeatedPtrField<std::string>& raw_policy_value,
-    PolicyMap* policies) {
-  std::string error;
-  absl::optional<base::Value::List> decoded_dlc_list =
-      DecodeDeviceDlcPredownloadListPolicy(raw_policy_value, &error);
-  base::Value::List value_to_set = decoded_dlc_list.has_value()
-                                       ? std::move(decoded_dlc_list.value())
-                                       : ProtoToList(raw_policy_value);
-  policies->Set(key::kDeviceDlcPredownloadList, POLICY_LEVEL_MANDATORY,
-                POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD,
-                base::Value(std::move(value_to_set)), nullptr);
-  if (!error.empty()) {
-    policies->AddMessage(
-        key::kDeviceDlcPredownloadList, PolicyMap::MessageType::kError,
-        IDS_POLICY_PROTO_PARSING_ERROR, {base::UTF8ToUTF16(error)});
-  }
-}
-
 // Returns true and sets |level| to a PolicyLevel if the policy has been set
 // at that level. Returns false if the policy has been set at the level of
 // PolicyOptions::UNSET.
@@ -2308,11 +2282,6 @@
                     nullptr);
     }
   }
-
-  if (policy.has_device_dlc_predownload_list()) {
-    SetDeviceDlcPredownloadListPolicy(
-        policy.device_dlc_predownload_list().value().entries(), policies);
-  }
 }
 
 }  // namespace
@@ -2359,34 +2328,6 @@
   return root;
 }
 
-// TODO (b/297008279): move this function to the class that will manage pre
-// downloading DLCs.
-absl::optional<base::Value::List> DecodeDeviceDlcPredownloadListPolicy(
-    const RepeatedPtrField<std::string>& raw_policy_value,
-    std::string* error) {
-  constexpr auto policy_value_to_dlc_id =
-      base::MakeFixedFlatMap<absl::string_view, absl::string_view>(
-          {{"scanner_drivers", "sane-backends-extras-dlc"}});
-
-  base::Value::List dlcs_to_predownload =
-      base::Value::List::with_capacity(raw_policy_value.size());
-  for (const auto& dlc_to_predownload : raw_policy_value) {
-    // TODO (b/297008279): handle case when there is an invalid value. In this
-    // case we should return an info message and skip this particular DLC
-    // without failing.
-    if (policy_value_to_dlc_id.contains(dlc_to_predownload)) {
-      const absl::string_view& dlc_id =
-          policy_value_to_dlc_id.at(dlc_to_predownload);
-      if (!base::Contains(dlcs_to_predownload, dlc_id)) {
-        // Silently ignore duplicate values.
-        dlcs_to_predownload.Append(dlc_id);
-      }
-    }
-  }
-
-  return dlcs_to_predownload;
-}
-
 void DecodeDevicePolicy(
     const em::ChromeDeviceSettingsProto& policy,
     base::WeakPtr<ExternalDataManager> external_data_manager,
diff --git a/chrome/browser/ash/policy/core/device_policy_decoder.h b/chrome/browser/ash/policy/core/device_policy_decoder.h
index ddbe1897..f5f2769 100644
--- a/chrome/browser/ash/policy/core/device_policy_decoder.h
+++ b/chrome/browser/ash/policy/core/device_policy_decoder.h
@@ -8,9 +8,7 @@
 #include <string>
 
 #include "base/memory/weak_ptr.h"
-#include "base/values.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
-#include "third_party/protobuf/src/google/protobuf/repeated_ptr_field.h"
 
 namespace enterprise_management {
 class ChromeDeviceSettingsProto;
@@ -40,15 +38,6 @@
     const std::string& policy_name,
     std::string* error);
 
-// Decode a list of DLCs that should be pre downloaded to the device from
-// human-readable strings to DLC IDs. Returns nullptr if any string in the list
-// doesn't match with a DLC ID that can be pre downloaded. Any warning or error
-// messages from the decoding and schema validation process are stored in
-// |error|.
-absl::optional<base::Value::List> DecodeDeviceDlcPredownloadListPolicy(
-    const google::protobuf::RepeatedPtrField<std::string>& raw_policy_value,
-    std::string* error);
-
 // Decodes device policy in ChromeDeviceSettingsProto representation into the a
 // PolicyMap.
 void DecodeDevicePolicy(
diff --git a/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller_ash_browsertest.cc b/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller_ash_browsertest.cc
index ba395d3..4dba819 100644
--- a/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller_ash_browsertest.cc
+++ b/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller_ash_browsertest.cc
@@ -150,8 +150,8 @@
 
 class MockDlpRulesManager : public DlpRulesManagerImpl {
  public:
-  explicit MockDlpRulesManager(PrefService* local_state, Profile* profile)
-      : DlpRulesManagerImpl(local_state, profile) {}
+  explicit MockDlpRulesManager(PrefService* local_state)
+      : DlpRulesManagerImpl(local_state) {}
   ~MockDlpRulesManager() override = default;
 
   MOCK_CONST_METHOD0(GetReportingManager, DlpReportingManager*());
@@ -180,6 +180,11 @@
     ON_CALL(*rules_manager_, GetReportingManager)
         .WillByDefault(::testing::Return(reporting_manager_.get()));
 
+    files_controller_ =
+        std::make_unique<DlpFilesControllerAsh>(*rules_manager_);
+    ON_CALL(*rules_manager_, GetDlpFilesController)
+        .WillByDefault(::testing::Return(files_controller_.get()));
+
     dlp_controller_ =
         std::make_unique<FakeDlpController>(*rules_manager_, &helper_);
   }
@@ -188,15 +193,8 @@
       content::BrowserContext* context) {
     auto mock_rules_manager =
         std::make_unique<testing::NiceMock<MockDlpRulesManager>>(
-            g_browser_process->local_state(),
-            Profile::FromBrowserContext(context));
+            g_browser_process->local_state());
     rules_manager_ = mock_rules_manager.get();
-
-    files_controller_ = std::make_unique<DlpFilesControllerAsh>(
-        *rules_manager_, Profile::FromBrowserContext(context));
-    ON_CALL(*rules_manager_, GetDlpFilesController)
-        .WillByDefault(::testing::Return(files_controller_.get()));
-
     return mock_rules_manager;
   }
 
diff --git a/chrome/browser/ash/policy/dlp/dlp_files_controller_ash.cc b/chrome/browser/ash/policy/dlp/dlp_files_controller_ash.cc
index a1436dc..56ef90a6f 100644
--- a/chrome/browser/ash/policy/dlp/dlp_files_controller_ash.cc
+++ b/chrome/browser/ash/policy/dlp/dlp_files_controller_ash.cc
@@ -83,7 +83,8 @@
 storage::FileSystemContext* g_file_system_context_for_testing = nullptr;
 
 // Returns true if `file_path` is in My Files directory.
-bool IsInLocalFileSystem(Profile* profile, const base::FilePath& file_path) {
+bool IsInLocalFileSystem(const base::FilePath& file_path) {
+  Profile* profile = ProfileManager::GetPrimaryUserProfile();
   auto my_files_folder =
       file_manager::util::GetMyFilesFolderForProfile(profile);
   if (my_files_folder == file_path || my_files_folder.IsParent(file_path)) {
@@ -128,12 +129,14 @@
 
 // Returns |g_file_system_context_for_testing| if set, otherwise
 // it returns FileSystemContext* for the primary profile.
-storage::FileSystemContext* GetFileSystemContext(Profile* profile) {
+storage::FileSystemContext* GetFileSystemContext() {
   if (g_file_system_context_for_testing) {
     return g_file_system_context_for_testing;
   }
 
-  return file_manager::util::GetFileManagerFileSystemContext(profile);
+  auto* primary_profile = ProfileManager::GetPrimaryUserProfile();
+  DCHECK(primary_profile);
+  return file_manager::util::GetFileManagerFileSystemContext(primary_profile);
 }
 
 // Gets all files inside |root| recursively and runs |callback_| with the
@@ -267,15 +270,17 @@
 
 // Converts files paths to file system URLs.
 std::vector<storage::FileSystemURL> ConvertFilePathsToFileSystemUrls(
-    Profile* profile,
     const std::vector<base::FilePath>& files_paths) {
   std::vector<storage::FileSystemURL> file_system_urls;
 
-  auto* file_system_context = GetFileSystemContext(profile);
+  auto* file_system_context = GetFileSystemContext();
   if (!file_system_context) {
     return file_system_urls;
   }
 
+  auto* profile = ProfileManager::GetPrimaryUserProfile();
+  DCHECK(profile);
+
   for (const auto& file_path : files_paths) {
     GURL gurl;
     if (file_manager::util::ConvertAbsoluteFilePathToFileSystemUrl(
@@ -319,10 +324,12 @@
 
 // Shows DLP block desktop notification.
 void ShowDlpBlockedFiles(
-    Profile* profile,
     absl::optional<file_manager::io_task::IOTaskId> task_id,
     std::vector<base::FilePath> blocked_files,
     dlp::FileAction action) {
+  auto* profile = ProfileManager::GetPrimaryUserProfile();
+  CHECK(profile);
+
   auto* fpnm =
       FilesPolicyNotificationManagerFactory::GetForBrowserContext(profile);
   if (!fpnm) {
@@ -335,17 +342,22 @@
                             action);
 }
 
-file_manager::VolumeManager* GetVolumeManager(
-    content::BrowserContext* context) {
-  CHECK(context);
+file_manager::VolumeManager* GetVolumeManager() {
+  auto* profile = ProfileManager::GetPrimaryUserProfile();
+  if (!profile) {
+    // May not be available in some tests.
+    CHECK_IS_TEST();
+    return nullptr;
+  }
 
   file_manager::VolumeManager* const volume_manager =
-      file_manager::VolumeManager::Get(context);
+      file_manager::VolumeManager::Get(profile);
   if (!volume_manager) {
     return nullptr;
   }
   return volume_manager;
 }
+
 }  // namespace
 
 // static
@@ -379,15 +391,11 @@
     default;
 
 DlpFilesControllerAsh::DlpFilesControllerAsh(
-    const DlpRulesManager& rules_manager,
-    Profile* profile)
+    const DlpRulesManager& rules_manager)
     : DlpFilesController(rules_manager),
-      profile_(profile),
       event_storage_(std::make_unique<DlpFilesEventStorage>(kCooldownTimeout,
                                                             kEntriesLimit)) {
-  CHECK(profile_);
-
-  auto* volume_manager = GetVolumeManager(profile_);
+  auto* volume_manager = GetVolumeManager();
   if (!volume_manager) {
     LOG(ERROR)
         << "DlpFilesControllerAsh failed to find file_manager::VolumeManager";
@@ -411,7 +419,7 @@
     // If `extract_io_task_observer_` is still alive, it means we are deleting
     // FilesController before VolumeManager, otherwise we would have been
     // notified in `OnShutdownStart`.
-    auto* volume_manager = GetVolumeManager(profile_);
+    auto* volume_manager = GetVolumeManager();
     if (volume_manager) {
       volume_manager->RemoveObserver(this);
     }
@@ -424,7 +432,7 @@
     storage::FileSystemURL destination,
     bool is_move,
     CheckIfTransferAllowedCallback result_callback) {
-  auto* file_system_context = GetFileSystemContext(profile_);
+  auto* file_system_context = GetFileSystemContext();
   if (!file_system_context) {
     std::move(result_callback).Run(std::vector<storage::FileSystemURL>());
     return;
@@ -432,7 +440,7 @@
 
   // If the destination file path is in My Files, all files transfers should be
   // allowed.
-  if (IsInLocalFileSystem(profile_, destination.path())) {
+  if (IsInLocalFileSystem(destination.path())) {
     std::move(result_callback).Run(std::vector<storage::FileSystemURL>());
     return;
   }
@@ -441,7 +449,7 @@
   // If the copied file isn't in the local file system, or the file is in the
   // same file system as the destination, no restrictions should be applied.
   for (const auto& file : transferred_files) {
-    if (!IsInLocalFileSystem(profile_, file.path()) ||
+    if (!IsInLocalFileSystem(file.path()) ||
         file.IsInSameFileSystem(destination)) {
       continue;
     }
@@ -477,7 +485,7 @@
 
   ::dlp::GetFilesSourcesRequest request;
   for (const auto& file : files) {
-    if (IsInLocalFileSystem(profile_, file.path())) {
+    if (IsInLocalFileSystem(file.path())) {
       request.add_files_paths(file.path().value());
     }
   }
@@ -503,14 +511,14 @@
   }
 
   std::vector<storage::FileSystemURL> file_system_urls =
-      ConvertFilePathsToFileSystemUrls(profile_, files_paths);
+      ConvertFilePathsToFileSystemUrls(files_paths);
 
   if (file_system_urls.empty()) {
     std::move(result_callback).Run(std::move(selected_files));
     return;
   }
 
-  auto* file_system_context = GetFileSystemContext(profile_);
+  auto* file_system_context = GetFileSystemContext();
   if (!file_system_context) {
     std::move(result_callback).Run(std::move(selected_files));
     return;
@@ -533,8 +541,11 @@
     const DlpFileDestination& download_src,
     const base::FilePath& file_path,
     CheckIfDlpAllowedCallback result_callback) {
+  auto* profile = ProfileManager::GetPrimaryUserProfile();
+  DCHECK(profile);
+
   auto dst_component =
-      MapFilePathToPolicyComponent(profile_, base::FilePath(file_path));
+      MapFilePathToPolicyComponent(profile, base::FilePath(file_path));
   if (!dst_component.has_value()) {
     // We may block downloads only if saved to external component, otherwise
     // downloads should be allowed.
@@ -553,14 +564,14 @@
                            /*referrer_url=*/"");
 
   absl::optional<data_controls::Component> component =
-      MapFilePathToPolicyComponent(profile_, file_path);
+      MapFilePathToPolicyComponent(profile, file_path);
   DlpFileDestination dlp_destination =
       component ? DlpFileDestination(*component) : DlpFileDestination();
   IsFilesTransferRestricted(
       absl::nullopt, {std::move(file_info)}, dlp_destination,
       dlp::FileAction::kDownload,
       base::BindOnce(
-          [](CheckIfDlpAllowedCallback result_callback, Profile* profile,
+          [](CheckIfDlpAllowedCallback result_callback,
              const std::vector<std::pair<
                  FileDaemonInfo, ::dlp::RestrictionLevel>>& files_levels) {
             bool is_allowed = true;
@@ -574,12 +585,12 @@
               }
             }
             if (!is_allowed) {
-              ShowDlpBlockedFiles(profile, /*task_id=*/absl::nullopt,
-                                  {file_path}, dlp::FileAction::kDownload);
+              ShowDlpBlockedFiles(/*task_id=*/absl::nullopt, {file_path},
+                                  dlp::FileAction::kDownload);
             }
             std::move(result_callback).Run(is_allowed);
           },
-          std::move(result_callback), profile_));
+          std::move(result_callback)));
 }
 
 bool DlpFilesControllerAsh::ShouldPromptBeforeDownload(
@@ -588,8 +599,10 @@
   if (download_src.IsFileSystem()) {
     return false;
   }
+  auto* profile = ProfileManager::GetPrimaryUserProfile();
+  DCHECK(profile);
   auto dst_component =
-      MapFilePathToPolicyComponent(profile_, base::FilePath(file_path));
+      MapFilePathToPolicyComponent(profile, base::FilePath(file_path));
   if (!dst_component.has_value()) {
     // We may block downloads only if saved to external component, otherwise
     // downloads should be allowed.
@@ -612,9 +625,11 @@
     std::move(result_callback).Run(/*is_allowed=*/true);
     return;
   }
+  auto* profile = ProfileManager::GetPrimaryUserProfile();
+  DCHECK(profile);
   ::dlp::CheckFilesTransferRequest request;
   for (const auto& file : intent->files) {
-    auto file_url = apps::GetFileSystemURL(profile_, file->url);
+    auto file_url = apps::GetFileSystemURL(profile, file->url);
     request.add_files_paths(file_url.path().value());
   }
 
@@ -684,6 +699,9 @@
     const DlpFileDestination& destination,
     dlp::FileAction files_action,
     IsFilesTransferRestrictedCallback result_callback) {
+  auto* profile = ProfileManager::GetPrimaryUserProfile();
+  DCHECK(profile);
+
   DlpFileDestination actual_dst = destination;
 
   std::vector<std::pair<FileDaemonInfo, ::dlp::RestrictionLevel>> files_levels;
@@ -746,7 +764,7 @@
   }
 
   auto* fpnm =
-      FilesPolicyNotificationManagerFactory::GetForBrowserContext(profile_);
+      FilesPolicyNotificationManagerFactory::GetForBrowserContext(profile);
   if (!fpnm) {
     LOG(ERROR) << "No FilesPolicyNotificationManager instantiated,"
                   "can't show policy warning UI";
@@ -861,14 +879,14 @@
     CheckIfDlpAllowedCallback result_callback) {
   std::vector<base::FilePath> files_paths;
   for (const auto& file : dropped_files) {
-    if (!IsInLocalFileSystem(profile_, file.path)) {
+    if (!IsInLocalFileSystem(file.path)) {
       continue;
     }
     files_paths.push_back(file.path);
   }
 
   std::vector<storage::FileSystemURL> files_urls =
-      ConvertFilePathsToFileSystemUrls(profile_, files_paths);
+      ConvertFilePathsToFileSystemUrls(files_paths);
   if (files_urls.empty()) {
     std::move(result_callback).Run(/*is_allowed=*/true);
     return;
@@ -876,7 +894,7 @@
 
   DlpFileDestination destination = DTEndpointToFileDestination(data_dst);
 
-  auto* file_system_context = GetFileSystemContext(profile_);
+  auto* file_system_context = GetFileSystemContext();
   if (!file_system_context) {
     std::move(result_callback).Run(/*is_allowed=*/true);
     return;
@@ -1011,8 +1029,8 @@
   if (!restricted_files_paths.empty() &&
       base::FeatureList::IsEnabled(features::kNewFilesPolicyUX) &&
       task_id.has_value()) {
-    ShowDlpBlockedFiles(profile_, std::move(task_id),
-                        std::move(restricted_files_paths), file_action);
+    ShowDlpBlockedFiles(std::move(task_id), std::move(restricted_files_paths),
+                        file_action);
   }
   std::move(result_callback).Run(std::move(restricted_files_urls));
 }
@@ -1043,8 +1061,8 @@
               });
         });
 
-    ShowDlpBlockedFiles(profile_, /*task_id=*/absl::nullopt,
-                        std::move(restricted_files), dlp::FileAction::kUpload);
+    ShowDlpBlockedFiles(/*task_id=*/absl::nullopt, std::move(restricted_files),
+                        dlp::FileAction::kUpload);
   }
 
   std::move(result_callback).Run(std::move(selected_files));
@@ -1071,6 +1089,8 @@
     // Only if it's restricted by any rule and the destination is passed, check
     // if this combination is also blocked or not.
     if (level == DlpRulesManager::Level::kBlock && destination.has_value()) {
+      auto* profile = ProfileManager::GetPrimaryUserProfile();
+      DCHECK(profile);
       absl::optional<data_controls::Component> dst_component =
           destination->component();
       if (dst_component.has_value()) {
@@ -1129,8 +1149,8 @@
 
   std::vector<base::FilePath> blocked_files(response.files_paths().begin(),
                                             response.files_paths().end());
-  ShowDlpBlockedFiles(profile_, /*task_id=*/absl::nullopt,
-                      std::move(blocked_files), action);
+  ShowDlpBlockedFiles(/*task_id=*/absl::nullopt, std::move(blocked_files),
+                      action);
   std::move(result_callback).Run(/*is_allowed=*/false);
 }
 
@@ -1209,8 +1229,9 @@
     return;
   }
 
+  Profile* profile = ProfileManager::GetPrimaryUserProfile();
   absl::optional<data_controls::Component> component =
-      MapFilePathToPolicyComponent(profile_, destination.path());
+      MapFilePathToPolicyComponent(profile, destination.path());
   ::dlp::DlpComponent proto;
   if (component) {
     proto = dlp::MapPolicyComponentToProto(*component);
diff --git a/chrome/browser/ash/policy/dlp/dlp_files_controller_ash.h b/chrome/browser/ash/policy/dlp/dlp_files_controller_ash.h
index 135c57b1..626db6f 100644
--- a/chrome/browser/ash/policy/dlp/dlp_files_controller_ash.h
+++ b/chrome/browser/ash/policy/dlp/dlp_files_controller_ash.h
@@ -111,7 +111,7 @@
   using IsFilesTransferRestrictedCallback = base::OnceCallback<void(
       const std::vector<std::pair<FileDaemonInfo, ::dlp::RestrictionLevel>>&)>;
 
-  DlpFilesControllerAsh(const DlpRulesManager& rules_manager, Profile* profile);
+  explicit DlpFilesControllerAsh(const DlpRulesManager& rules_manager);
   DlpFilesControllerAsh(const DlpFilesControllerAsh& other) = delete;
   DlpFilesControllerAsh& operator=(const DlpFilesControllerAsh& other) = delete;
 
@@ -284,10 +284,6 @@
       CheckIfDlpAllowedCallback result_callback,
       std::vector<storage::FileSystemURL> dropped_files);
 
-  // The profile with which we are associated. Not owned. It's currently always
-  // the main/primary profile.
-  const raw_ptr<Profile> profile_;
-
   // Keeps track of events and detects duplicate ones using time based
   // approach.
   std::unique_ptr<DlpFilesEventStorage> event_storage_;
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 9e88de3..a464deb 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
@@ -90,14 +90,6 @@
     ASSERT_TRUE(DlpRulesManagerFactory::GetForPrimaryProfile());
   }
 
-  void TearDownOnMainThread() override {
-    // The files controller must be destroyed before the profile since it's
-    // holding a pointer to it.
-    files_controller_.reset();
-
-    InProcessBrowserTest::TearDownOnMainThread();
-  }
-
   std::unique_ptr<KeyedService> SetDlpRulesManager(
       content::BrowserContext* context) {
     auto dlp_rules_manager =
@@ -108,8 +100,8 @@
     ON_CALL(*mock_rules_manager_, GetReportingManager)
         .WillByDefault(testing::Return(nullptr));
 
-    files_controller_ = std::make_unique<DlpFilesControllerAsh>(
-        *mock_rules_manager_, Profile::FromBrowserContext(context));
+    files_controller_ =
+        std::make_unique<DlpFilesControllerAsh>(*mock_rules_manager_);
     ON_CALL(*mock_rules_manager_, GetDlpFilesController)
         .WillByDefault(testing::Return(files_controller_.get()));
 
diff --git a/chrome/browser/ash/policy/dlp/files_policy_notification_manager_browsertest.cc b/chrome/browser/ash/policy/dlp/files_policy_notification_manager_browsertest.cc
index 5bacebae..b9d44d9 100644
--- a/chrome/browser/ash/policy/dlp/files_policy_notification_manager_browsertest.cc
+++ b/chrome/browser/ash/policy/dlp/files_policy_notification_manager_browsertest.cc
@@ -783,14 +783,6 @@
               nullptr);
   }
 
-  void TearDownOnMainThread() override {
-    // The files controller must be destroyed before the profile since it's
-    // holding a pointer to it.
-    files_controller_.reset();
-    mock_rules_manager_ = nullptr;
-    FilesPolicyNotificationManagerBrowserTest::TearDownOnMainThread();
-  }
-
   std::unique_ptr<KeyedService> SetDlpRulesManager(
       content::BrowserContext* context) {
     auto dlp_rules_manager =
@@ -801,7 +793,7 @@
 
     files_controller_ =
         std::make_unique<testing::NiceMock<policy::MockDlpFilesControllerAsh>>(
-            *mock_rules_manager_, Profile::FromBrowserContext(context));
+            *mock_rules_manager_);
 
     ON_CALL(*mock_rules_manager_, GetDlpFilesController())
         .WillByDefault(::testing::Return(files_controller_.get()));
@@ -1055,16 +1047,9 @@
   auto notification = bridge_->GetDisplayedNotification(kNotificationId1);
   ASSERT_TRUE(notification.has_value());
 
+  // Show the dialog.
+  ASSERT_TRUE(bridge_->GetDisplayedNotification(kNotificationId1).has_value());
   bridge_->Click(kNotificationId1, NotificationButton::OK);
-
-  // By waiting for the Files app, we make sure that
-  // FilesPolicyNotificationManager::LaunchFilesApp called when the dialog is
-  // show successfully completes before the test ends, since it will at some
-  // point asynchronously call AppServiceProxyAsh::LaunchAppWithIntent and we
-  // need to make sure the files controller is still alive at that point.
-  Browser* first_app = ui_test_utils::WaitForBrowserToOpen();
-  ASSERT_TRUE(first_app);
-  ASSERT_EQ(first_app, FindFilesApp());
 }
 
 // Tests that clicking the OK button on a warning notification shown for copy or
diff --git a/chrome/browser/ash/policy/dlp/test/dlp_files_test_with_mounts.cc b/chrome/browser/ash/policy/dlp/test/dlp_files_test_with_mounts.cc
index 8ea868d..5106737 100644
--- a/chrome/browser/ash/policy/dlp/test/dlp_files_test_with_mounts.cc
+++ b/chrome/browser/ash/policy/dlp/test/dlp_files_test_with_mounts.cc
@@ -82,8 +82,7 @@
 void DlpFilesTestWithMounts::SetUp() {
   DlpFilesTestBase::SetUp();
   ASSERT_TRUE(rules_manager_);
-  files_controller_ =
-      std::make_unique<DlpFilesControllerAsh>(*rules_manager_, profile_.get());
+  files_controller_ = std::make_unique<DlpFilesControllerAsh>(*rules_manager_);
 
   event_storage_ = files_controller_->GetEventStorageForTesting();
   DCHECK(event_storage_);
@@ -131,8 +130,6 @@
 }
 
 void DlpFilesTestWithMounts::TearDown() {
-  event_storage_ = nullptr;
-  files_controller_.reset();
   DlpFilesTestBase::TearDown();
   reporting_manager_.reset();
 
diff --git a/chrome/browser/ash/policy/dlp/test/mock_dlp_files_controller_ash.cc b/chrome/browser/ash/policy/dlp/test/mock_dlp_files_controller_ash.cc
index 9282844..b1947d0 100644
--- a/chrome/browser/ash/policy/dlp/test/mock_dlp_files_controller_ash.cc
+++ b/chrome/browser/ash/policy/dlp/test/mock_dlp_files_controller_ash.cc
@@ -9,9 +9,8 @@
 namespace policy {
 
 MockDlpFilesControllerAsh::MockDlpFilesControllerAsh(
-    const DlpRulesManager& rules_manager,
-    Profile* profile)
-    : DlpFilesControllerAsh(rules_manager, profile) {
+    const DlpRulesManager& rules_manager)
+    : DlpFilesControllerAsh(rules_manager) {
   ON_CALL(*this, CheckIfLaunchAllowed)
       .WillByDefault([](const apps::AppUpdate& app_update,
                         apps::IntentPtr intent,
diff --git a/chrome/browser/ash/policy/dlp/test/mock_dlp_files_controller_ash.h b/chrome/browser/ash/policy/dlp/test/mock_dlp_files_controller_ash.h
index 1dc3384..c1ffc14 100644
--- a/chrome/browser/ash/policy/dlp/test/mock_dlp_files_controller_ash.h
+++ b/chrome/browser/ash/policy/dlp/test/mock_dlp_files_controller_ash.h
@@ -16,8 +16,7 @@
 class MockDlpFilesControllerAsh : public DlpFilesControllerAsh {
  public:
   MockDlpFilesControllerAsh() = delete;
-  explicit MockDlpFilesControllerAsh(const DlpRulesManager& rules_manager,
-                                     Profile* profile);
+  explicit MockDlpFilesControllerAsh(const DlpRulesManager& rules_manager);
   MockDlpFilesControllerAsh(const MockDlpFilesControllerAsh& other) = delete;
   MockDlpFilesControllerAsh& operator=(const MockDlpFilesControllerAsh& other) =
       delete;
diff --git a/chrome/browser/ash/settings/device_settings_provider.cc b/chrome/browser/ash/settings/device_settings_provider.cc
index 5fd810d..e272b82 100644
--- a/chrome/browser/ash/settings/device_settings_provider.cc
+++ b/chrome/browser/ash/settings/device_settings_provider.cc
@@ -82,7 +82,6 @@
     kDeviceDisabled,
     kDeviceDisabledMessage,
     kDeviceDisplayResolution,
-    kDeviceDlcPredownloadList,
     kDeviceDockMacAddressSource,
     kDeviceEncryptedReportingPipelineEnabled,
     kDeviceHindiInscriptLayoutEnabled,
@@ -188,7 +187,7 @@
 constexpr char InvalidCombinationsOfAllowedUsersPoliciesHistogram[] =
     "Login.InvalidCombinationsOfAllowedUsersPolicies";
 
-// Re-use the DecodeJsonStringAndNormalize() from device_policy_decoder.h
+// Re-use the DecodeJsonStringAndNormalize from device_policy_decoder.h
 // here to decode the json string and validate it against |policy_name|'s
 // schema. If the json string is valid, the decoded base::Value will be stored
 // as |setting_name| in |pref_value_map|. The error can be ignored here since it
@@ -205,22 +204,6 @@
   }
 }
 
-// Re-use the DecodeDeviceDlcPredownloadListPolicy() from
-// device_policy_decoder.h here to decode the list of DLCs that should be pre
-// downloaded to the device. The error can be ignored here since it is already
-// reported during decoding in device_policy_decoder.cc.
-void SetDeviceDlcPredownloadListSetting(
-    const RepeatedPtrField<std::string>& raw_policy_value,
-    PrefValueMap* pref_value_map) {
-  std::string error;
-  absl::optional<base::Value::List> decoded_dlc_list =
-      policy::DecodeDeviceDlcPredownloadListPolicy(raw_policy_value, &error);
-  if (decoded_dlc_list.has_value()) {
-    pref_value_map->SetValue(kDeviceDlcPredownloadList,
-                             base::Value(std::move(decoded_dlc_list.value())));
-  }
-}
-
 // Puts the policy value into the settings store if only it matches the regex
 // pattern.
 void SetSettingWithValidatingRegex(const std::string& policy_name,
@@ -1324,12 +1307,6 @@
                                  base::Value(container.enabled()));
     }
   }
-
-  if (policy.has_device_dlc_predownload_list()) {
-    SetDeviceDlcPredownloadListSetting(
-        policy.device_dlc_predownload_list().value().entries(),
-        new_values_cache);
-  }
 }
 
 void DecodeLogUploadPolicies(const em::ChromeDeviceSettingsProto& policy,
diff --git a/chrome/browser/ash/settings/device_settings_provider_unittest.cc b/chrome/browser/ash/settings/device_settings_provider_unittest.cc
index 2ebc4b3..35d281f 100644
--- a/chrome/browser/ash/settings/device_settings_provider_unittest.cc
+++ b/chrome/browser/ash/settings/device_settings_provider_unittest.cc
@@ -222,22 +222,15 @@
   void VerifyPolicyValue(const char* policy_key,
                          const base::Value* ptr_to_expected_value) {
     // The pointer might be null, so check before dereferencing.
-    const base::Value* value = provider_->Get(policy_key);
-    if (ptr_to_expected_value) {
-      // This prevents tests from crashing if provider returns nullptr.
-      ASSERT_TRUE(value);
-      EXPECT_EQ(*ptr_to_expected_value, *value);
-    } else {
-      EXPECT_EQ(nullptr, value);
-    }
+    if (ptr_to_expected_value)
+      EXPECT_EQ(*ptr_to_expected_value, *provider_->Get(policy_key));
+    else
+      EXPECT_EQ(nullptr, provider_->Get(policy_key));
   }
 
   void VerifyPolicyList(const char* policy_key,
                         const base::Value::List& expected_value) {
-    const base::Value* value = provider_->Get(policy_key);
-    // This prevents tests from crashing if provider returns nullptr.
-    ASSERT_TRUE(value);
-    EXPECT_TRUE(value->is_list());
+    EXPECT_TRUE(provider_->Get(policy_key)->is_list());
     EXPECT_EQ(expected_value, provider_->Get(policy_key)->GetList());
   }
 
@@ -1378,62 +1371,4 @@
             *provider_->Get(kDeviceHindiInscriptLayoutEnabled));
 }
 
-TEST_F(DeviceSettingsProviderTest, DeviceDlcPredownloadListUnset) {
-  // Device setting must be unset if the policy is not set.
-  VerifyPolicyValue(kDeviceDlcPredownloadList, nullptr);
-}
-
-TEST_F(DeviceSettingsProviderTest, DeviceDlcPredownloadListEmpty) {
-  // Device setting must be unset if there are no DLCs to pre download.
-  device_policy_->payload().clear_device_dlc_predownload_list();
-  BuildAndInstallDevicePolicy();
-  VerifyPolicyValue(kDeviceDlcPredownloadList, nullptr);
-}
-
-TEST_F(DeviceSettingsProviderTest, DeviceDlcPredownloadListNonempty) {
-  device_policy_->payload()
-      .mutable_device_dlc_predownload_list()
-      ->mutable_value()
-      ->add_entries("scanner_drivers");
-
-  BuildAndInstallDevicePolicy();
-
-  VerifyPolicyList(kDeviceDlcPredownloadList,
-                   base::Value::List().Append("sane-backends-extras-dlc"));
-}
-
-TEST_F(DeviceSettingsProviderTest, DeviceDlcPredownloadListInvalidDlc) {
-  device_policy_->payload()
-      .mutable_device_dlc_predownload_list()
-      ->mutable_value()
-      ->add_entries("scanner_drivers");
-  device_policy_->payload()
-      .mutable_device_dlc_predownload_list()
-      ->mutable_value()
-      ->add_entries("invalid_dlc_name");
-
-  BuildAndInstallDevicePolicy();
-
-  // Device setting must contain only the valid DLCs that can be pre downloaded.
-  VerifyPolicyList(kDeviceDlcPredownloadList,
-                   base::Value::List().Append("sane-backends-extras-dlc"));
-}
-
-TEST_F(DeviceSettingsProviderTest, DeviceDlcPredownloadListDuplicateDlc) {
-  device_policy_->payload()
-      .mutable_device_dlc_predownload_list()
-      ->mutable_value()
-      ->add_entries("scanner_drivers");
-  device_policy_->payload()
-      .mutable_device_dlc_predownload_list()
-      ->mutable_value()
-      ->add_entries("scanner_drivers");
-
-  BuildAndInstallDevicePolicy();
-
-  // Device setting must not contain any duplicate values.
-  VerifyPolicyList(kDeviceDlcPredownloadList,
-                   base::Value::List().Append("sane-backends-extras-dlc"));
-}
-
 }  // namespace ash
diff --git a/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc b/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc
index e2279bd..4272b8ee 100644
--- a/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc
+++ b/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc
@@ -261,7 +261,7 @@
     auto web_app_info = std::make_unique<web_app::WebAppInstallInfo>();
     web_app_info->start_url = start_url;
     web_app_info->user_display_mode = web_app::mojom::UserDisplayMode::kBrowser;
-    const web_app::AppId app_id = web_app::test::InstallWebApp(
+    const webapps::AppId app_id = web_app::test::InstallWebApp(
         browser()->profile(), std::move(web_app_info));
     apps::AppReadinessWaiter(browser()->profile(), app_id).Await();
 
diff --git a/chrome/browser/ash/system_web_apps/BUILD.gn b/chrome/browser/ash/system_web_apps/BUILD.gn
index b28e080..45e747f 100644
--- a/chrome/browser/ash/system_web_apps/BUILD.gn
+++ b/chrome/browser/ash/system_web_apps/BUILD.gn
@@ -48,6 +48,7 @@
     "//components/keyed_service/content",
     "//components/pref_registry:pref_registry",
     "//components/webapps/browser",
+    "//components/webapps/common",
     "//content/public/browser",
     "//ui/base/idle",
     "//ui/chromeos/styles:cros_tokens_color_mappings_generator",
diff --git a/chrome/browser/ash/system_web_apps/apps/help_app/help_app_integration_browsertest.cc b/chrome/browser/ash/system_web_apps/apps/help_app/help_app_integration_browsertest.cc
index 73d4f5bf..9bc1da7a 100644
--- a/chrome/browser/ash/system_web_apps/apps/help_app/help_app_integration_browsertest.cc
+++ b/chrome/browser/ash/system_web_apps/apps/help_app/help_app_integration_browsertest.cc
@@ -207,7 +207,7 @@
 IN_PROC_BROWSER_TEST_P(HelpAppIntegrationTest,
                        HasCorrectThemeAndBackgroundColor) {
   WaitForTestSystemAppInstall();
-  web_app::AppId app_id =
+  webapps::AppId app_id =
       *GetManager().GetAppIdForSystemApp(SystemWebAppType::HELP);
   web_app::WebAppRegistrar& registrar =
       web_app::WebAppProvider::GetForTest(profile())->registrar_unsafe();
diff --git a/chrome/browser/ash/system_web_apps/system_web_app_icon_checker.h b/chrome/browser/ash/system_web_apps/system_web_app_icon_checker.h
index 4f8b34f..60a5b14 100644
--- a/chrome/browser/ash/system_web_apps/system_web_app_icon_checker.h
+++ b/chrome/browser/ash/system_web_apps/system_web_app_icon_checker.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_ASH_SYSTEM_WEB_APPS_SYSTEM_WEB_APP_ICON_CHECKER_H_
 
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/web_app_id.h"
+#include "components/webapps/common/web_app_id.h"
 
 namespace ash {
 
@@ -46,7 +46,7 @@
 
   // Start a check on SWAs identified by `app_ids`. This method shouldn't be
   // called again before `callback` runs.
-  virtual void StartCheck(const std::vector<web_app::AppId>& apps_ids,
+  virtual void StartCheck(const std::vector<webapps::AppId>& apps_ids,
                           base::OnceCallback<void(IconState)> callback) = 0;
 
   // Stop all running checks, `callback` passed into StartCheck() won't be
diff --git a/chrome/browser/ash/system_web_apps/system_web_app_manager.cc b/chrome/browser/ash/system_web_apps/system_web_app_manager.cc
index de861703..55c72fa 100644
--- a/chrome/browser/ash/system_web_apps/system_web_app_manager.cc
+++ b/chrome/browser/ash/system_web_apps/system_web_app_manager.cc
@@ -72,7 +72,6 @@
 #include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
 #include "chrome/browser/web_applications/policy/web_app_policy_manager.h"
 #include "chrome/browser/web_applications/web_app_constants.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/browser/web_applications/web_app_system_web_app_delegate_map_utils.h"
@@ -81,6 +80,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/version_info/version_info.h"
 #include "components/webapps/browser/install_result_code.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/url_data_source.h"
 #include "content/public/common/content_switches.h"
@@ -433,7 +433,7 @@
   run_loop.Run();
 }
 
-absl::optional<web_app::AppId> SystemWebAppManager::GetAppIdForSystemApp(
+absl::optional<webapps::AppId> SystemWebAppManager::GetAppIdForSystemApp(
     SystemWebAppType type) const {
   if (!provider_->is_registry_ready())
     return absl::nullopt;
@@ -442,7 +442,7 @@
 }
 
 absl::optional<SystemWebAppType> SystemWebAppManager::GetSystemAppTypeForAppId(
-    const web_app::AppId& app_id) const {
+    const webapps::AppId& app_id) const {
   if (!provider_->is_registry_ready())
     return absl::nullopt;
   return web_app::GetSystemAppTypeForAppId(provider_->registrar_unsafe(),
@@ -454,10 +454,10 @@
   return GetSystemWebApp(system_app_delegates_, type);
 }
 
-std::vector<web_app::AppId> SystemWebAppManager::GetAppIds() const {
-  std::vector<web_app::AppId> app_ids;
+std::vector<webapps::AppId> SystemWebAppManager::GetAppIds() const {
+  std::vector<webapps::AppId> app_ids;
   for (const auto& app_type_to_app_info : system_app_delegates_) {
-    absl::optional<web_app::AppId> app_id =
+    absl::optional<webapps::AppId> app_id =
         GetAppIdForSystemApp(app_type_to_app_info.first);
     if (app_id.has_value()) {
       app_ids.push_back(app_id.value());
@@ -466,7 +466,7 @@
   return app_ids;
 }
 
-bool SystemWebAppManager::IsSystemWebApp(const web_app::AppId& app_id) const {
+bool SystemWebAppManager::IsSystemWebApp(const webapps::AppId& app_id) const {
   DCHECK(provider_->is_registry_ready());
   return web_app::IsSystemWebApp(provider_->registrar_unsafe(),
                                  system_app_delegates_, app_id);
@@ -486,7 +486,7 @@
 }
 
 void SystemWebAppManager::OnReadyToCommitNavigation(
-    const web_app::AppId& app_id,
+    const webapps::AppId& app_id,
     content::NavigationHandle* navigation_handle) {
   // Perform tab-specific setup when a navigation in a System Web App is about
   // to be committed.
@@ -521,7 +521,7 @@
   if (!provider_->is_registry_ready())
     return absl::nullopt;
 
-  absl::optional<web_app::AppId> app_id =
+  absl::optional<webapps::AppId> app_id =
       provider_->registrar_unsafe().FindAppWithUrlInScope(url);
   if (!app_id.has_value())
     return absl::nullopt;
diff --git a/chrome/browser/ash/system_web_apps/system_web_app_manager.h b/chrome/browser/ash/system_web_apps/system_web_app_manager.h
index ceaeae4..56ae5af 100644
--- a/chrome/browser/ash/system_web_apps/system_web_app_manager.h
+++ b/chrome/browser/ash/system_web_apps/system_web_app_manager.h
@@ -20,9 +20,9 @@
 #include "chrome/browser/ash/system_web_apps/types/system_web_app_delegate.h"
 #include "chrome/browser/ash/system_web_apps/types/system_web_app_delegate_map.h"
 #include "chrome/browser/web_applications/externally_managed_app_manager.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_ui_manager.h"
 #include "components/keyed_service/core/keyed_service.h"
+#include "components/webapps/common/web_app_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
@@ -109,21 +109,21 @@
   void InstallSystemAppsForTesting();
 
   // Returns the app id for the given System App |type|.
-  absl::optional<web_app::AppId> GetAppIdForSystemApp(
+  absl::optional<webapps::AppId> GetAppIdForSystemApp(
       SystemWebAppType type) const;
 
   // Returns the System App Type for the given |app_id|.
   absl::optional<SystemWebAppType> GetSystemAppTypeForAppId(
-      const web_app::AppId& app_id) const;
+      const webapps::AppId& app_id) const;
 
   // Returns the System App Delegate for the given App |type|.
   const SystemWebAppDelegate* GetSystemApp(SystemWebAppType type) const;
 
   // Returns the App Ids for all installed System Web Apps.
-  std::vector<web_app::AppId> GetAppIds() const;
+  std::vector<webapps::AppId> GetAppIds() const;
 
   // Returns whether |app_id| points to an installed System App.
-  bool IsSystemWebApp(const web_app::AppId& app_id) const;
+  bool IsSystemWebApp(const webapps::AppId& app_id) const;
 
   // Returns the SystemWebAppType that should handle |url|.
   //
@@ -213,7 +213,7 @@
 
   // web_app::WebAppUiManagerObserver:
   void OnReadyToCommitNavigation(
-      const web_app::AppId& app_id,
+      const webapps::AppId& app_id,
       content::NavigationHandle* navigation_handle) override;
   void OnWebAppUiManagerDestroyed() override;
 
diff --git a/chrome/browser/ash/system_web_apps/system_web_app_manager_browsertest.cc b/chrome/browser/ash/system_web_apps/system_web_app_manager_browsertest.cc
index 78682746..ab083382 100644
--- a/chrome/browser/ash/system_web_apps/system_web_app_manager_browsertest.cc
+++ b/chrome/browser/ash/system_web_apps/system_web_app_manager_browsertest.cc
@@ -119,7 +119,7 @@
   Browser* app_browser;
   LaunchAppWithoutWaiting(GetAppType(), &app_browser);
 
-  web_app::AppId app_id = app_browser->app_controller()->app_id();
+  webapps::AppId app_id = app_browser->app_controller()->app_id();
   EXPECT_EQ(GetManager().GetAppIdForSystemApp(GetAppType()), app_id);
   EXPECT_TRUE(GetManager().IsSystemWebApp(app_id));
 
@@ -802,7 +802,7 @@
                        NotShownInLauncher) {
   WaitForTestSystemAppInstall();
 
-  web_app::AppId app_id =
+  webapps::AppId app_id =
       GetManager().GetAppIdForSystemApp(GetAppType()).value();
 
   GetAppServiceProxy(browser()->profile())
@@ -833,7 +833,7 @@
 IN_PROC_BROWSER_TEST_P(SystemWebAppManagerNotShownInSearchTest,
                        NotShownInSearch) {
   WaitForTestSystemAppInstall();
-  web_app::AppId app_id =
+  webapps::AppId app_id =
       GetManager().GetAppIdForSystemApp(GetAppType()).value();
 
   GetAppServiceProxy(browser()->profile())
@@ -855,7 +855,7 @@
 IN_PROC_BROWSER_TEST_P(SystemWebAppManagerHandlesFileOpenIntentsTest,
                        HandlesFileOpenIntents) {
   WaitForTestSystemAppInstall();
-  web_app::AppId app_id =
+  webapps::AppId app_id =
       GetManager().GetAppIdForSystemApp(GetAppType()).value();
 
   GetAppServiceProxy(browser()->profile())
@@ -877,7 +877,7 @@
 IN_PROC_BROWSER_TEST_P(SystemWebAppManagerAdditionalSearchTermsTest,
                        AdditionalSearchTerms) {
   WaitForTestSystemAppInstall();
-  web_app::AppId app_id =
+  webapps::AppId app_id =
       GetManager().GetAppIdForSystemApp(GetAppType()).value();
 
   // AdditionalSearchTerms is flaky on Windows as it's a Chrome OS feature.
@@ -1148,7 +1148,7 @@
   Browser* app_browser;
   LaunchAppWithoutWaiting(GetAppType(), &app_browser);
 
-  web_app::AppId app_id =
+  webapps::AppId app_id =
       GetManager().GetAppIdForSystemApp(GetAppType()).value();
   EXPECT_EQ(app_id, app_browser->app_controller()->app_id());
   EXPECT_TRUE(GetManager().IsSystemWebApp(app_id));
@@ -1328,7 +1328,7 @@
  public:
   SystemWebAppManagerAppSuspensionBrowserTest() = default;
 
-  apps::Readiness GetAppReadiness(const web_app::AppId& app_id) {
+  apps::Readiness GetAppReadiness(const webapps::AppId& app_id) {
     apps::Readiness readiness;
     bool app_found =
         GetAppServiceProxy(browser()->profile())
@@ -1340,7 +1340,7 @@
     return readiness;
   }
 
-  absl::optional<apps::IconKey> GetAppIconKey(const web_app::AppId& app_id) {
+  absl::optional<apps::IconKey> GetAppIconKey(const webapps::AppId& app_id) {
     absl::optional<apps::IconKey> icon_key;
     bool app_found =
         GetAppServiceProxy(browser()->profile())
@@ -1367,7 +1367,7 @@
     update->Append(static_cast<int>(policy::SystemFeature::kOsSettings));
   }
   WaitForTestSystemAppInstall();
-  absl::optional<web_app::AppId> settings_id =
+  absl::optional<webapps::AppId> settings_id =
       GetManager().GetAppIdForSystemApp(SystemWebAppType::SETTINGS);
   DCHECK(settings_id.has_value());
 
@@ -1397,7 +1397,7 @@
       "screenplay-44570758-2d0f-4ed9-8172-102244523249");
 
   WaitForTestSystemAppInstall();
-  absl::optional<web_app::AppId> settings_id =
+  absl::optional<webapps::AppId> settings_id =
       GetManager().GetAppIdForSystemApp(SystemWebAppType::SETTINGS);
   DCHECK(settings_id.has_value());
   EXPECT_EQ(apps::Readiness::kReady, GetAppReadiness(*settings_id));
@@ -1443,7 +1443,7 @@
 
 IN_PROC_BROWSER_TEST_P(SystemWebAppManagerShortcutTest, ShortcutUrl) {
   WaitForTestSystemAppInstall();
-  web_app::AppId app_id =
+  webapps::AppId app_id =
       GetManager()
           .GetAppIdForSystemApp(SystemWebAppType::SHORTCUT_CUSTOMIZATION)
           .value();
diff --git a/chrome/browser/ash/system_web_apps/system_web_app_manager_unittest.cc b/chrome/browser/ash/system_web_apps/system_web_app_manager_unittest.cc
index 00d7a9d..9de7d575 100644
--- a/chrome/browser/ash/system_web_apps/system_web_app_manager_unittest.cc
+++ b/chrome/browser/ash/system_web_apps/system_web_app_manager_unittest.cc
@@ -110,7 +110,7 @@
   }
 
   using ReadyToCommitNavigationCallback = base::RepeatingCallback<void(
-      const web_app::AppId& app_id,
+      const webapps::AppId& app_id,
       content::NavigationHandle* navigation_handle)>;
 
   void SetReadyToCommitNavigationCallback(
@@ -119,7 +119,7 @@
   }
 
   void OnReadyToCommitNavigation(
-      const web_app::AppId& app_id,
+      const webapps::AppId& app_id,
       content::NavigationHandle* navigation_handle) override {
     if (ready_to_commit_navigation_callback_)
       ready_to_commit_navigation_callback_.Run(app_id, navigation_handle);
@@ -193,7 +193,7 @@
     for (const SystemAppData& data : system_app_data_list) {
       std::unique_ptr<web_app::WebApp> web_app = web_app::test::CreateWebApp(
           data.url, web_app::WebAppManagement::Type::kSystem);
-      const web_app::AppId app_id = web_app->app_id();
+      const webapps::AppId app_id = web_app->app_id();
       {
         web_app::ScopedRegistryUpdate update =
             provider().sync_bridge_unsafe().BeginUpdate();
diff --git a/chrome/browser/ash/system_web_apps/test_support/system_web_app_browsertest_base.cc b/chrome/browser/ash/system_web_apps/test_support/system_web_app_browsertest_base.cc
index 4f3abb3..5ca9c95 100644
--- a/chrome/browser/ash/system_web_apps/test_support/system_web_app_browsertest_base.cc
+++ b/chrome/browser/ash/system_web_apps/test_support/system_web_app_browsertest_base.cc
@@ -52,7 +52,7 @@
 
 apps::AppLaunchParams SystemWebAppBrowserTestBase::LaunchParamsForApp(
     SystemWebAppType system_app_type) {
-  absl::optional<web_app::AppId> app_id =
+  absl::optional<webapps::AppId> app_id =
       GetManager().GetAppIdForSystemApp(system_app_type);
 
   CHECK(app_id.has_value());
diff --git a/chrome/browser/ash/system_web_apps/test_support/system_web_app_integration_test.cc b/chrome/browser/ash/system_web_apps/test_support/system_web_app_integration_test.cc
index 5925e5b..5206b85 100644
--- a/chrome/browser/ash/system_web_apps/test_support/system_web_app_integration_test.cc
+++ b/chrome/browser/ash/system_web_apps/test_support/system_web_app_integration_test.cc
@@ -42,7 +42,7 @@
   Browser* app_browser;
   LaunchAppWithoutWaiting(app_type, &app_browser);
 
-  web_app::AppId app_id = app_browser->app_controller()->app_id();
+  webapps::AppId app_id = app_browser->app_controller()->app_id();
   EXPECT_EQ(GetManager().GetAppIdForSystemApp(app_type), app_id);
   EXPECT_TRUE(GetManager().IsSystemWebApp(app_id));
 
diff --git a/chrome/browser/ash/system_web_apps/test_support/test_system_web_app_installation.cc b/chrome/browser/ash/system_web_apps/test_support/test_system_web_app_installation.cc
index dbc3f903..93de984 100644
--- a/chrome/browser/ash/system_web_apps/test_support/test_system_web_app_installation.cc
+++ b/chrome/browser/ash/system_web_apps/test_support/test_system_web_app_installation.cc
@@ -212,7 +212,7 @@
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
 void UnittestingSystemAppDelegate::SetAppIdsToUninstallAndReplace(
-    const std::vector<web_app::AppId>& ids) {
+    const std::vector<webapps::AppId>& ids) {
   uninstall_and_replace_ = ids;
 }
 void UnittestingSystemAppDelegate::SetMinimumWindowSize(const gfx::Size& size) {
@@ -912,7 +912,7 @@
   run_loop.Run();
 }
 
-web_app::AppId TestSystemWebAppInstallation::GetAppId() {
+webapps::AppId TestSystemWebAppInstallation::GetAppId() {
   return SystemWebAppManager::GetForTest(profile_)
       ->GetAppIdForSystemApp(type_.value())
       .value();
diff --git a/chrome/browser/ash/system_web_apps/test_support/test_system_web_app_installation.h b/chrome/browser/ash/system_web_apps/test_support/test_system_web_app_installation.h
index 6a62010..d0a1687 100644
--- a/chrome/browser/ash/system_web_apps/test_support/test_system_web_app_installation.h
+++ b/chrome/browser/ash/system_web_apps/test_support/test_system_web_app_installation.h
@@ -70,7 +70,7 @@
   bool ShouldAnimateThemeChanges() const override;
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
-  void SetAppIdsToUninstallAndReplace(const std::vector<web_app::AppId>&);
+  void SetAppIdsToUninstallAndReplace(const std::vector<webapps::AppId>&);
   void SetMinimumWindowSize(const gfx::Size&);
   void SetShouldReuseExistingWindow(bool);
   void SetShouldShowNewWindowMenuOption(bool);
@@ -100,7 +100,7 @@
  private:
   web_app::WebAppInstallInfoFactory info_factory_;
 
-  std::vector<web_app::AppId> uninstall_and_replace_;
+  std::vector<webapps::AppId> uninstall_and_replace_;
   gfx::Size minimum_window_size_;
   bool single_window_ = true;
   bool show_new_window_menu_option_ = false;
@@ -225,7 +225,7 @@
 
   void WaitForAppInstall();
 
-  web_app::AppId GetAppId();
+  webapps::AppId GetAppId();
   const GURL& GetAppUrl();
   SystemWebAppDelegate* GetDelegate();
   SystemWebAppType GetType();
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index fb416f3..23bff565 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -534,7 +534,6 @@
 #include "chrome/browser/webauthn/chrome_authenticator_request_delegate.h"
 #include "chrome/grit/chrome_unscaled_resources.h"  // nogncheck crbug.com/1125897
 #include "components/commerce/core/commerce_feature_list.h"
-#include "components/media_effects/media_effects_manager_binder.h"
 #include "components/password_manager/content/common/web_ui_constants.h"
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom.h"
@@ -8122,14 +8121,3 @@
 void ChromeContentBrowserClient::SetIsMinimalMode(bool minimal) {
   is_minimal_mode_ = minimal;
 }
-
-#if !BUILDFLAG(IS_ANDROID)
-void ChromeContentBrowserClient::BindVideoEffectsManager(
-    const std::string& device_id,
-    content::BrowserContext* browser_context,
-    mojo::PendingReceiver<video_capture::mojom::VideoEffectsManager>
-        video_effects_manager) {
-  media_effects::BindVideoEffectsManager(device_id, browser_context,
-                                         std::move(video_effects_manager));
-}
-#endif  // !BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index d5258126..f7d2397 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -941,14 +941,6 @@
 
   void SetIsMinimalMode(bool minimal) override;
 
-#if !BUILDFLAG(IS_ANDROID)
-  void BindVideoEffectsManager(
-      const std::string& device_id,
-      content::BrowserContext* browser_context,
-      mojo::PendingReceiver<video_capture::mojom::VideoEffectsManager>
-          video_effects_manager) override;
-#endif  // !BUILDFLAG(IS_ANDROID)
-
  protected:
   static bool HandleWebUI(GURL* url, content::BrowserContext* browser_context);
   static bool HandleWebUIReverse(GURL* url,
diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc
index dfdf65e..5bdef219 100644
--- a/chrome/browser/chrome_content_browser_client_unittest.cc
+++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -68,7 +68,6 @@
 #include "url/origin.h"
 
 #if !BUILDFLAG(IS_ANDROID)
-#include "base/test/test_future.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -616,23 +615,6 @@
 
 #endif
 
-#if !BUILDFLAG(IS_ANDROID)
-TEST_F(ChromeContentBrowserClientTest, BindVideoEffectsManager) {
-  TestChromeContentBrowserClient test_content_browser_client;
-  mojo::Remote<video_capture::mojom::VideoEffectsManager> video_effects_manager;
-  test_content_browser_client.BindVideoEffectsManager(
-      "test_device_id", &profile_,
-      video_effects_manager.BindNewPipeAndPassReceiver());
-
-  base::test::TestFuture<video_capture::mojom::VideoEffectsConfigurationPtr>
-      configuration_future;
-  video_effects_manager->GetConfiguration(configuration_future.GetCallback());
-  // The actual value isn't that important here. What matters is that getting a
-  // result means that the plumbing worked.
-  EXPECT_FALSE(configuration_future.Get().is_null());
-}
-#endif  // !BUILDFLAG(IS_ANDROID)
-
 #if BUILDFLAG(IS_CHROMEOS)
 class ChromeContentSettingsRedirectTest
     : public ChromeContentBrowserClientTest {
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 659df5b74..fd0d0d6 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -295,6 +295,7 @@
     "//components/sync_device_info",
     "//components/ukm",
     "//components/vector_icons",
+    "//components/webapps/common",
     "//content/public/common",
     "//crypto",
     "//extensions/browser/updater",
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
index 00ec76a7..81101c65 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
@@ -27,7 +27,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
-#include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/policy/core/common/policy_pref_names.h"
 #include "components/policy/policy_constants.h"
@@ -171,8 +170,8 @@
 
 class MockDlpRulesManager : public DlpRulesManagerImpl {
  public:
-  explicit MockDlpRulesManager(PrefService* local_state, Profile* profile)
-      : DlpRulesManagerImpl(local_state, profile) {}
+  explicit MockDlpRulesManager(PrefService* local_state)
+      : DlpRulesManagerImpl(local_state) {}
   ~MockDlpRulesManager() override = default;
 
   MOCK_CONST_METHOD0(GetReportingManager, DlpReportingManager*());
@@ -229,8 +228,7 @@
       content::BrowserContext* context) {
     auto mock_rules_manager =
         std::make_unique<testing::NiceMock<MockDlpRulesManager>>(
-            g_browser_process->local_state(),
-            Profile::FromBrowserContext(context));
+            g_browser_process->local_state());
     rules_manager_ = mock_rules_manager.get();
     return mock_rules_manager;
   }
@@ -491,14 +489,8 @@
   void SetUpOnMainThread() override {
     InProcessBrowserTest::SetUpOnMainThread();
 
-    TestingProfile::Builder builder;
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-    builder.SetIsMainProfile(true);
-#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
-    profile_ = builder.Build();
-
     rules_manager_ = std::make_unique<::testing::NiceMock<MockDlpRulesManager>>(
-        g_browser_process->local_state(), profile_.get());
+        g_browser_process->local_state());
 
     reporting_manager_ = std::make_unique<DlpReportingManager>();
     auto reporting_queue = std::unique_ptr<::reporting::MockReportQueue,
@@ -520,7 +512,6 @@
     dlp_controller_.reset();
     reporting_manager_.reset();
     rules_manager_.reset();
-    profile_.reset();
   }
 
   content::WebContents* GetActiveWebContents() {
@@ -555,7 +546,6 @@
             });
   }
 
-  std::unique_ptr<TestingProfile> profile_;
   std::unique_ptr<::testing::NiceMock<MockDlpRulesManager>> rules_manager_;
   std::unique_ptr<DlpReportingManager> reporting_manager_;
   raw_ptr<reporting::MockReportQueue> reporting_queue_;
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
index d40cf5a..74e293a 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
@@ -315,9 +315,8 @@
 
 class MockFilesController : public policy::DlpFilesControllerAsh {
  public:
-  explicit MockFilesController(const policy::DlpRulesManager& rules_manager,
-                               Profile* profile)
-      : DlpFilesControllerAsh(rules_manager, profile) {}
+  explicit MockFilesController(const policy::DlpRulesManager& rules_manager)
+      : DlpFilesControllerAsh(rules_manager) {}
   ~MockFilesController() override = default;
 
   MOCK_METHOD(void,
@@ -336,10 +335,7 @@
                          extension_misc::kFilesManagerAppId}))));
   ui::DataTransferEndpoint data_dst((GURL(kExample1Url)));
 
-  std::unique_ptr<TestingProfile> testing_profile =
-      TestingProfile::Builder().Build();
-
-  MockFilesController files_controller(rules_manager_, testing_profile.get());
+  MockFilesController files_controller(rules_manager_);
   std::vector<ui::FileInfo> file_names;
   ASSERT_TRUE(drag_data.GetFilenames(&file_names));
 
@@ -366,10 +362,7 @@
                          extension_misc::kFilesManagerAppId}))));
   ui::DataTransferEndpoint data_dst((GURL(kExample1Url)));
 
-  std::unique_ptr<TestingProfile> testing_profile =
-      TestingProfile::Builder().Build();
-
-  MockFilesController files_controller(rules_manager_, testing_profile.get());
+  MockFilesController files_controller(rules_manager_);
   std::vector<ui::FileInfo> file_names;
   ASSERT_TRUE(drag_data.GetFilenames(&file_names));
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_restriction_set_browsertest.cc b/chrome/browser/chromeos/policy/dlp/dlp_content_restriction_set_browsertest.cc
index bc06c54..8ba185651 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_content_restriction_set_browsertest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_content_restriction_set_browsertest.cc
@@ -23,8 +23,8 @@
 
 class FakeDlpRulesManager : public DlpRulesManagerImpl {
  public:
-  explicit FakeDlpRulesManager(PrefService* local_state, Profile* profile)
-      : DlpRulesManagerImpl(local_state, profile) {}
+  explicit FakeDlpRulesManager(PrefService* local_state)
+      : DlpRulesManagerImpl(local_state) {}
   ~FakeDlpRulesManager() override = default;
 };
 
@@ -66,7 +66,7 @@
   std::unique_ptr<KeyedService> SetDlpRulesManager(
       content::BrowserContext* context) {
     return std::make_unique<FakeDlpRulesManager>(
-        g_browser_process->local_state(), Profile::FromBrowserContext(context));
+        g_browser_process->local_state());
   }
 };
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.cc
index 61e047e..626c8e4a 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.cc
@@ -110,6 +110,6 @@
   if (!local_state)
     return nullptr;
 
-  return new DlpRulesManagerImpl(local_state, profile);
+  return new DlpRulesManagerImpl(local_state);
 }
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
index 79b3d23..cec078e 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
@@ -307,9 +307,7 @@
   return result;
 }
 
-DlpRulesManagerImpl::DlpRulesManagerImpl(PrefService* local_state,
-                                         Profile* profile)
-    : profile_(profile) {
+DlpRulesManagerImpl::DlpRulesManagerImpl(PrefService* local_state) {
   pref_change_registrar_.Init(local_state);
   pref_change_registrar_.Add(
       policy_prefs::kDlpRulesList,
@@ -531,8 +529,7 @@
           request_to_daemon, base::BindOnce(&OnSetDlpFilesPolicy));
 #if BUILDFLAG(IS_CHROMEOS_ASH)
       if (!files_controller_) {
-        files_controller_ =
-            std::make_unique<DlpFilesControllerAsh>(*this, profile_);
+        files_controller_ = std::make_unique<DlpFilesControllerAsh>(*this);
       }
 #elif BUILDFLAG(IS_CHROMEOS_LACROS)
       if (!files_controller_) {
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h
index 57718de..ee71ff4 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h
@@ -12,7 +12,6 @@
 #include <set>
 
 #include "base/scoped_observation.h"
-#include "chrome/browser/profiles/profile.h"
 #include "chromeos/dbus/dlp/dlp_client.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/url_matcher/url_matcher.h"
@@ -61,7 +60,7 @@
  protected:
   friend class DlpRulesManagerFactory;
 
-  DlpRulesManagerImpl(PrefService* local_state, Profile* profile);
+  explicit DlpRulesManagerImpl(PrefService* local_state);
 
  private:
   void OnPolicyUpdate() override;
@@ -84,10 +83,6 @@
   // System-wide singleton instantiated when there are rules involving files.
   std::unique_ptr<DlpFilesController> files_controller_;
 
-  // The profile with which we are associated. Not owned. It's currently always
-  // the main/primary profile.
-  const raw_ptr<Profile> profile_;
-
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // Observe to re-notify DLP daemon in case of restart.
   base::ScopedObservation<chromeos::DlpClient, chromeos::DlpClient::Observer>
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_browsertest.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_browsertest.cc
index f09828e..a361172 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_browsertest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_browsertest.cc
@@ -26,8 +26,8 @@
 
 class FakeDlpRulesManager : public DlpRulesManagerImpl {
  public:
-  explicit FakeDlpRulesManager(PrefService* local_state, Profile* profile)
-      : DlpRulesManagerImpl(local_state, profile) {}
+  explicit FakeDlpRulesManager(PrefService* local_state)
+      : DlpRulesManagerImpl(local_state) {}
   ~FakeDlpRulesManager() override = default;
 };
 }  // namespace
@@ -46,8 +46,8 @@
 
   std::unique_ptr<KeyedService> SetDlpRulesManager(
       content::BrowserContext* context) {
-    auto new_rules_manager = std::make_unique<FakeDlpRulesManager>(
-        g_browser_process->local_state(), Profile::FromBrowserContext(context));
+    auto new_rules_manager =
+        std::make_unique<FakeDlpRulesManager>(g_browser_process->local_state());
     rules_manager_ = new_rules_manager.get();
     return new_rules_manager;
   }
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
index 9d62471..b6202aa 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h"
 
-#include <memory>
 #include <string>
 #include <utility>
 #include <vector>
@@ -24,7 +23,6 @@
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
-#include "chrome/test/base/testing_profile.h"
 #include "chromeos/dbus/dlp/dlp_client.h"
 #include "components/policy/core/common/policy_pref_names.h"
 #include "components/prefs/scoped_user_pref_update.h"
@@ -68,8 +66,8 @@
 constexpr char kRuleName3[] = "rule #3";
 class MockDlpRulesManager : public DlpRulesManagerImpl {
  public:
-  explicit MockDlpRulesManager(PrefService* local_state, Profile* profile)
-      : DlpRulesManagerImpl(local_state, profile) {}
+  explicit MockDlpRulesManager(PrefService* local_state)
+      : DlpRulesManagerImpl(local_state) {}
 
   ~MockDlpRulesManager() override { Shutdown(); }
 };
@@ -79,23 +77,8 @@
 class DlpRulesManagerImplTest : public testing::Test {
  protected:
   DlpRulesManagerImplTest()
-      : testing_local_state_(TestingBrowserProcess::GetGlobal()) {}
-
-  void SetUp() override {
-    TestingProfile::Builder builder;
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-    builder.SetIsMainProfile(true);
-#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
-    profile_ = builder.Build();
-
-    dlp_rules_manager_ = std::make_unique<MockDlpRulesManager>(
-        testing_local_state_.Get(), profile_.get());
-
-    // THe histogram tester should be created after the rules manager, since the
-    // rules manager constructor call OnPolicyUpdate, and we would then record
-    // that additional call.
-    histogram_tester_ = std::make_unique<base::HistogramTester>();
-  }
+      : testing_local_state_(TestingBrowserProcess::GetGlobal()),
+        dlp_rules_manager_(testing_local_state_.Get()) {}
 
   void UpdatePolicyPref(const std::vector<dlp_test_util::DlpRule>& rules) {
     base::Value::List policy_rules;
@@ -115,7 +98,7 @@
       const DlpRulesManager::RuleMetadata& expected_rule_metadata) {
     std::string src_pattern;
     DlpRulesManager::RuleMetadata rule_metadata;
-    EXPECT_EQ(expected_level, dlp_rules_manager_->IsRestrictedComponent(
+    EXPECT_EQ(expected_level, dlp_rules_manager_.IsRestrictedComponent(
                                   GURL(src_url), dst_component, restriction,
                                   &src_pattern, &rule_metadata));
     EXPECT_EQ(src_pattern, expected_src_pattern);
@@ -135,7 +118,7 @@
     std::string src_pattern;
     std::string dst_pattern;
     DlpRulesManager::RuleMetadata rule_metadata;
-    EXPECT_EQ(expected_level, dlp_rules_manager_->IsRestrictedDestination(
+    EXPECT_EQ(expected_level, dlp_rules_manager_.IsRestrictedDestination(
                                   GURL(src_url), GURL(dst_url), restriction,
                                   &src_pattern, &dst_pattern, &rule_metadata));
     EXPECT_EQ(src_pattern, expected_src_pattern);
@@ -154,7 +137,7 @@
     std::string src_pattern;
     DlpRulesManager::RuleMetadata rule_metadata;
     EXPECT_EQ(expected_level,
-              dlp_rules_manager_->IsRestrictedByAnyRule(
+              dlp_rules_manager_.IsRestrictedByAnyRule(
                   GURL(src_url), restriction, &src_pattern, &rule_metadata));
     EXPECT_EQ(src_pattern, expected_src_pattern);
     EXPECT_EQ(rule_metadata.name, expected_rule_metadata.name);
@@ -170,8 +153,8 @@
       const DlpRulesManager::RuleMetadata& expected_rule_metadata) {
     DlpRulesManager::RuleMetadata rule_metadata;
     EXPECT_EQ(expected_pattern,
-              dlp_rules_manager_->GetSourceUrlPattern(
-                  GURL(src_url), restriction, level, &rule_metadata));
+              dlp_rules_manager_.GetSourceUrlPattern(GURL(src_url), restriction,
+                                                     level, &rule_metadata));
     EXPECT_EQ(rule_metadata.name, expected_rule_metadata.name);
     EXPECT_EQ(rule_metadata.obfuscated_id,
               expected_rule_metadata.obfuscated_id);
@@ -179,9 +162,8 @@
 
   content::BrowserTaskEnvironment task_environment_;
   ScopedTestingLocalState testing_local_state_;
-  std::unique_ptr<TestingProfile> profile_;
-  std::unique_ptr<MockDlpRulesManager> dlp_rules_manager_;
-  std::unique_ptr<base::HistogramTester> histogram_tester_;
+  MockDlpRulesManager dlp_rules_manager_;
+  base::HistogramTester histogram_tester_;
   base::RunLoop run_loop_;
 };
 
@@ -189,7 +171,7 @@
   UpdatePolicyPref({});
 
   EXPECT_EQ(DlpRulesManager::Level::kAllow,
-            dlp_rules_manager_->IsRestricted(
+            dlp_rules_manager_.IsRestricted(
                 GURL(kExampleUrl), DlpRulesManager::Restriction::kPrinting));
 
   CheckIsRestrictedDestination(
@@ -198,7 +180,7 @@
       /*expected_dst_pattern=*/"",
       DlpRulesManager::RuleMetadata(/*name=*/"", /*obfuscated_id=*/""));
 
-  histogram_tester_->ExpectUniqueSample(
+  histogram_tester_.ExpectUniqueSample(
       GetDlpHistogramPrefix() + dlp::kDlpPolicyPresentUMA, false, 1);
 }
 
@@ -210,7 +192,7 @@
 
   UpdatePolicyPref({rule});
 
-  histogram_tester_->ExpectBucketCount(
+  histogram_tester_.ExpectBucketCount(
       "Enterprise.Dlp.RestrictionConfigured",
       DlpRulesManager::Restriction::kUnknownRestriction, 0);
 }
@@ -224,9 +206,9 @@
 
   UpdatePolicyPref({rule});
 
-  histogram_tester_->ExpectBucketCount("Enterprise.Dlp.RestrictionConfigured",
-                                       DlpRulesManager::Restriction::kClipboard,
-                                       1);
+  histogram_tester_.ExpectBucketCount("Enterprise.Dlp.RestrictionConfigured",
+                                      DlpRulesManager::Restriction::kClipboard,
+                                      1);
 
   CheckIsRestrictedComponent(
       kExampleUrl, data_controls::Component::kUnknownComponent,
@@ -243,9 +225,9 @@
 
   UpdatePolicyPref({rule});
 
-  histogram_tester_->ExpectBucketCount("Enterprise.Dlp.RestrictionConfigured",
-                                       DlpRulesManager::Restriction::kClipboard,
-                                       0);
+  histogram_tester_.ExpectBucketCount("Enterprise.Dlp.RestrictionConfigured",
+                                      DlpRulesManager::Restriction::kClipboard,
+                                      0);
 }
 
 TEST_F(DlpRulesManagerImplTest, BlockPriority) {
@@ -273,7 +255,7 @@
       DlpRulesManager::RuleMetadata(kRuleName1, kRuleId1));
 
   EXPECT_EQ(DlpRulesManager::Level::kBlock,
-            dlp_rules_manager_->IsRestricted(
+            dlp_rules_manager_.IsRestricted(
                 GURL(kExampleUrl), DlpRulesManager::Restriction::kScreenshot));
 
   CheckIsRestrictedByAnyRule(
@@ -281,14 +263,14 @@
       DlpRulesManager::Level::kBlock, kExampleUrl,
       DlpRulesManager::RuleMetadata(kRuleName1, kRuleId1));
 
-  histogram_tester_->ExpectUniqueSample(
+  histogram_tester_.ExpectUniqueSample(
       GetDlpHistogramPrefix() + dlp::kDlpPolicyPresentUMA, true, 1);
-  histogram_tester_->ExpectBucketCount("Enterprise.Dlp.RestrictionConfigured",
-                                       DlpRulesManager::Restriction::kClipboard,
-                                       2);
-  histogram_tester_->ExpectBucketCount(
-      "Enterprise.Dlp.RestrictionConfigured",
-      DlpRulesManager::Restriction::kScreenshot, 1);
+  histogram_tester_.ExpectBucketCount("Enterprise.Dlp.RestrictionConfigured",
+                                      DlpRulesManager::Restriction::kClipboard,
+                                      2);
+  histogram_tester_.ExpectBucketCount("Enterprise.Dlp.RestrictionConfigured",
+                                      DlpRulesManager::Restriction::kScreenshot,
+                                      1);
 
   // Clear pref
   UpdatePolicyPref({});
@@ -306,7 +288,7 @@
       DlpRulesManager::RuleMetadata(/*name=*/"", /*obfuscated_id=*/""));
 
   EXPECT_EQ(DlpRulesManager::Level::kAllow,
-            dlp_rules_manager_->IsRestricted(
+            dlp_rules_manager_.IsRestricted(
                 GURL(kExampleUrl), DlpRulesManager::Restriction::kScreenshot));
 }
 
@@ -318,7 +300,7 @@
   UpdatePolicyPref({rule1});
 
   EXPECT_EQ(DlpRulesManager::Level::kBlock,
-            dlp_rules_manager_->IsRestricted(
+            dlp_rules_manager_.IsRestricted(
                 GURL(kExampleUrl), DlpRulesManager::Restriction::kScreenshot));
 
   dlp_test_util::DlpRule rule2(kRuleName2, "Exceptional allow", kRuleId2);
@@ -328,10 +310,10 @@
   UpdatePolicyPref({rule2});
 
   EXPECT_EQ(DlpRulesManager::Level::kAllow,
-            dlp_rules_manager_->IsRestricted(
+            dlp_rules_manager_.IsRestricted(
                 GURL(kExampleUrl), DlpRulesManager::Restriction::kScreenshot));
   EXPECT_EQ(DlpRulesManager::Level::kBlock,
-            dlp_rules_manager_->IsRestricted(
+            dlp_rules_manager_.IsRestricted(
                 GURL(kGoogleUrl), DlpRulesManager::Restriction::kScreenshot));
 }
 
@@ -529,7 +511,7 @@
       DlpRulesManager::RuleMetadata(kRuleName1, kRuleId1));
 
   EXPECT_EQ(DlpRulesManager::Level::kBlock,
-            dlp_rules_manager_->IsRestricted(
+            dlp_rules_manager_.IsRestricted(
                 GURL(kExampleUrl), DlpRulesManager::Restriction::kScreenshot));
 
   // Disable feature
@@ -623,9 +605,9 @@
   EXPECT_EQ(1, chromeos::DlpClient::Get()
                    ->GetTestInterface()
                    ->GetSetDlpFilesPolicyCount());
-  EXPECT_TRUE(dlp_rules_manager_->IsFilesPolicyEnabled());
+  EXPECT_TRUE(dlp_rules_manager_.IsFilesPolicyEnabled());
 
-  dlp_rules_manager_->DlpDaemonRestarted();
+  dlp_rules_manager_.DlpDaemonRestarted();
 
   // The above call to DlpRulesManagerImpl::DlpDaemonRestarted posts a task to
   // the same task runner as the one used here. Doing this ensures that the call
@@ -664,7 +646,7 @@
   EXPECT_EQ(0, chromeos::DlpClient::Get()
                    ->GetTestInterface()
                    ->GetSetDlpFilesPolicyCount());
-  EXPECT_FALSE(dlp_rules_manager_->IsFilesPolicyEnabled());
+  EXPECT_FALSE(dlp_rules_manager_.IsFilesPolicyEnabled());
   chromeos::DlpClient::Shutdown();
 }
 
@@ -739,35 +721,35 @@
 
   // Screensharing from chat.google should be allowed.
   EXPECT_EQ(DlpRulesManager::Level::kAllow,
-            dlp_rules_manager_->IsRestricted(
+            dlp_rules_manager_.IsRestricted(
                 GURL(base::StrCat({kHttpsPrefix, kChatPattern})),
                 DlpRulesManager::Restriction::kScreenShare));
 
   // Screensharing from docs/drive urls should be blocked.
   EXPECT_EQ(DlpRulesManager::Level::kBlock,
-            dlp_rules_manager_->IsRestricted(
+            dlp_rules_manager_.IsRestricted(
                 GURL(base::StrCat({kHttpsPrefix, kDocsPattern})),
                 DlpRulesManager::Restriction::kScreenShare));
   EXPECT_EQ(DlpRulesManager::Level::kBlock,
-            dlp_rules_manager_->IsRestricted(
+            dlp_rules_manager_.IsRestricted(
                 GURL(base::StrCat({kHttpsPrefix, kDrivePattern})),
                 DlpRulesManager::Restriction::kScreenShare));
 
   // Screensharing from gmail/example/Salesforce urls should be reported.
   EXPECT_EQ(DlpRulesManager::Level::kReport,
-            dlp_rules_manager_->IsRestricted(
+            dlp_rules_manager_.IsRestricted(
                 GURL(kGmailUrl), DlpRulesManager::Restriction::kScreenShare));
   EXPECT_EQ(DlpRulesManager::Level::kReport,
-            dlp_rules_manager_->IsRestricted(
+            dlp_rules_manager_.IsRestricted(
                 GURL(kExampleUrl), DlpRulesManager::Restriction::kScreenShare));
   EXPECT_EQ(DlpRulesManager::Level::kReport,
-            dlp_rules_manager_->IsRestricted(
+            dlp_rules_manager_.IsRestricted(
                 GURL(base::StrCat({kHttpsPrefix, kSalesforcePattern})),
                 DlpRulesManager::Restriction::kScreenShare));
 }
 
 TEST_F(DlpRulesManagerImplTest, GetAggregatedDestinations_NoMatch) {
-  auto result = dlp_rules_manager_->GetAggregatedDestinations(
+  auto result = dlp_rules_manager_.GetAggregatedDestinations(
       GURL(kExampleUrl), DlpRulesManager::Restriction::kClipboard);
 
   EXPECT_TRUE(result.empty());
@@ -800,9 +782,9 @@
       FROM_HERE, run_loop_.QuitClosure());
   run_loop_.Run();
 
-  EXPECT_TRUE(dlp_rules_manager_->IsFilesPolicyEnabled());
+  EXPECT_TRUE(dlp_rules_manager_.IsFilesPolicyEnabled());
 
-  auto result = dlp_rules_manager_->GetAggregatedDestinations(
+  auto result = dlp_rules_manager_.GetAggregatedDestinations(
       GURL(kExampleUrl), DlpRulesManager::Restriction::kFiles);
   std::map<DlpRulesManager::Level, std::set<std::string>> expected;
   expected[DlpRulesManager::Level::kBlock].insert(kGoogleUrl);
@@ -836,9 +818,9 @@
       FROM_HERE, run_loop_.QuitClosure());
   run_loop_.Run();
 
-  EXPECT_TRUE(dlp_rules_manager_->IsFilesPolicyEnabled());
+  EXPECT_TRUE(dlp_rules_manager_.IsFilesPolicyEnabled());
 
-  auto result = dlp_rules_manager_->GetAggregatedDestinations(
+  auto result = dlp_rules_manager_.GetAggregatedDestinations(
       GURL(kExampleUrl), DlpRulesManager::Restriction::kFiles);
   std::map<DlpRulesManager::Level, std::set<std::string>> expected;
   expected[DlpRulesManager::Level::kBlock].insert(kWildCardMatching);
@@ -868,7 +850,7 @@
 
   UpdatePolicyPref({rule1, rule2, rule3});
 
-  auto result = dlp_rules_manager_->GetAggregatedDestinations(
+  auto result = dlp_rules_manager_.GetAggregatedDestinations(
       GURL(kExampleUrl), DlpRulesManager::Restriction::kClipboard);
   std::map<DlpRulesManager::Level, std::set<std::string>> expected;
   expected[DlpRulesManager::Level::kBlock].insert(kCompanyUrl);
@@ -897,7 +879,7 @@
 
   UpdatePolicyPref({rule1, rule2, rule3});
 
-  auto result = dlp_rules_manager_->GetAggregatedDestinations(
+  auto result = dlp_rules_manager_.GetAggregatedDestinations(
       GURL(kExampleUrl), DlpRulesManager::Restriction::kClipboard);
   std::map<DlpRulesManager::Level, std::set<std::string>> expected;
   expected[DlpRulesManager::Level::kBlock].insert(kCompanyUrl);
@@ -907,7 +889,7 @@
 }
 
 TEST_F(DlpRulesManagerImplTest, GetAggregatedComponents_NoMatch) {
-  auto result = dlp_rules_manager_->GetAggregatedComponents(
+  auto result = dlp_rules_manager_.GetAggregatedComponents(
       GURL(kExampleUrl), DlpRulesManager::Restriction::kClipboard);
   std::map<DlpRulesManager::Level, std::set<data_controls::Component>> expected;
   for (auto component : data_controls::kAllComponents) {
@@ -936,9 +918,9 @@
       FROM_HERE, run_loop_.QuitClosure());
   run_loop_.Run();
 
-  EXPECT_TRUE(dlp_rules_manager_->IsFilesPolicyEnabled());
+  EXPECT_TRUE(dlp_rules_manager_.IsFilesPolicyEnabled());
 
-  auto result = dlp_rules_manager_->GetAggregatedComponents(
+  auto result = dlp_rules_manager_.GetAggregatedComponents(
       GURL(kExampleUrl), DlpRulesManager::Restriction::kFiles);
   std::map<DlpRulesManager::Level, std::set<data_controls::Component>> expected;
   expected[DlpRulesManager::Level::kBlock].insert(
@@ -980,7 +962,7 @@
       FROM_HERE, run_loop_.QuitClosure());
   run_loop_.Run();
 
-  EXPECT_TRUE(dlp_rules_manager_->IsFilesPolicyEnabled());
+  EXPECT_TRUE(dlp_rules_manager_.IsFilesPolicyEnabled());
   EXPECT_EQ(chromeos::DlpClient::Get()
                 ->GetTestInterface()
                 ->GetSetDlpFilesPolicyCount(),
diff --git a/chrome/browser/download/download_target_determiner_unittest.cc b/chrome/browser/download/download_target_determiner_unittest.cc
index 713a132..0781cf3c 100644
--- a/chrome/browser/download/download_target_determiner_unittest.cc
+++ b/chrome/browser/download/download_target_determiner_unittest.cc
@@ -2846,9 +2846,8 @@
 
   class MockFilesController : public policy::DlpFilesControllerAsh {
    public:
-    explicit MockFilesController(const policy::DlpRulesManager& rules_manager,
-                                 Profile* profile)
-        : DlpFilesControllerAsh(rules_manager, profile) {}
+    explicit MockFilesController(const policy::DlpRulesManager& rules_manager)
+        : DlpFilesControllerAsh(rules_manager) {}
     ~MockFilesController() override = default;
 
     MOCK_METHOD(bool,
@@ -2874,7 +2873,6 @@
   }
 
   void TearDown() override {
-    mock_files_controller_.reset();
     scoped_user_manager_.reset();
     profile_.reset();
 
@@ -2900,7 +2898,7 @@
     ON_CALL(*rules_manager_, IsFilesPolicyEnabled)
         .WillByDefault(testing::Return(true));
     mock_files_controller_ =
-        std::make_unique<MockFilesController>(*rules_manager_, profile_.get());
+        std::make_unique<MockFilesController>(*rules_manager_);
     ON_CALL(*rules_manager_, GetDlpFilesController)
         .WillByDefault(testing::Return(mock_files_controller_.get()));
   }
diff --git a/chrome/browser/engagement/important_sites_util.cc b/chrome/browser/engagement/important_sites_util.cc
index 6e5ee46..f4af4e95 100644
--- a/chrome/browser/engagement/important_sites_util.cc
+++ b/chrome/browser/engagement/important_sites_util.cc
@@ -41,9 +41,9 @@
 #include "url/url_util.h"
 
 #if !BUILDFLAG(IS_ANDROID)
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
+#include "components/webapps/common/web_app_id.h"
 #endif
 
 namespace site_engagement {
diff --git a/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc b/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc
index f30d5c02..fbd2fa8 100644
--- a/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc
+++ b/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc
@@ -329,7 +329,7 @@
   GURL start_url = embedded_test_server()->GetURL("/test_app.html");
   auto web_app_info = std::make_unique<web_app::WebAppInstallInfo>();
   web_app_info->start_url = start_url;
-  web_app::AppId app_id =
+  webapps::AppId app_id =
       web_app::test::InstallWebApp(profile(), std::move(web_app_info));
   Browser* app_browser = web_app::LaunchWebAppBrowserAndWait(profile(), app_id);
 
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc
index 4959e8e..3ee59fc 100644
--- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc
+++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc
@@ -37,7 +37,7 @@
 #include "extensions/browser/api/declarative_net_request/declarative_net_request_prefs_helper.h"
 #include "extensions/browser/api/declarative_net_request/file_backed_ruleset_source.h"
 #include "extensions/browser/api/declarative_net_request/parse_info.h"
-#include "extensions/browser/api/declarative_net_request/rules_count_pair.h"
+#include "extensions/browser/api/declarative_net_request/rule_counts.h"
 #include "extensions/browser/api/declarative_net_request/rules_monitor_service.h"
 #include "extensions/browser/api/declarative_net_request/ruleset_manager.h"
 #include "extensions/browser/api/declarative_net_request/ruleset_matcher.h"
@@ -1518,11 +1518,11 @@
 
   const RulesMonitorService* service =
       RulesMonitorService::Get(browser_context());
-  RulesCountPair expected_count(100 /* rule_count */, 0 /* regex_rule_count */);
+  RuleCounts expected_count(100 /* rule_count */, 0 /* regex_rule_count */);
   EXPECT_EQ(expected_count,
-            service->GetRulesCountPair(extension()->id(), kDynamicRulesetID));
+            service->GetRuleCounts(extension()->id(), kDynamicRulesetID));
   EXPECT_EQ(expected_count,
-            service->GetRulesCountPair(extension()->id(), kSessionRulesetID));
+            service->GetRuleCounts(extension()->id(), kSessionRulesetID));
 
   // Adding any more dynamic rules will fail.
   expected_error = kDynamicRuleCountExceeded;
@@ -1560,11 +1560,11 @@
 
   const RulesMonitorService* service =
       RulesMonitorService::Get(browser_context());
-  RulesCountPair expected_count(60 /* rule_count */, 50 /* regex_rule_count */);
+  RuleCounts expected_count(60 /* rule_count */, 50 /* regex_rule_count */);
   EXPECT_EQ(expected_count,
-            service->GetRulesCountPair(extension()->id(), kDynamicRulesetID));
+            service->GetRuleCounts(extension()->id(), kDynamicRulesetID));
   EXPECT_EQ(expected_count,
-            service->GetRulesCountPair(extension()->id(), kSessionRulesetID));
+            service->GetRuleCounts(extension()->id(), kSessionRulesetID));
 
   // Adding more regex based dynamic or session rules should fail.
   std::string expected_error = kDynamicRegexRuleCountExceeded;
@@ -1586,9 +1586,9 @@
 
   expected_count.rule_count++;
   EXPECT_EQ(expected_count,
-            service->GetRulesCountPair(extension()->id(), kDynamicRulesetID));
+            service->GetRuleCounts(extension()->id(), kDynamicRulesetID));
   EXPECT_EQ(expected_count,
-            service->GetRulesCountPair(extension()->id(), kSessionRulesetID));
+            service->GetRuleCounts(extension()->id(), kSessionRulesetID));
 }
 
 // Test that getMatchedRules will return an error if an invalid tab id is
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index a66353c7..96d71ff2 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -8237,6 +8237,11 @@
     "expiry_milestone": 120
   },
   {
+    "name": "use-shared-images-for-pepper-video",
+    "owners": [ "vasilyt", "blundell" ],
+    "expiry_milestone": 122
+  },
+  {
     "name": "use-stork-smds-server-address",
     "owners": [ "cros-connectivity@google.com", "hsuregan"],
     // This flag is required for dev testing via Stork profiles which can be quickly
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 40edb7b5..ef9bb83 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -337,6 +337,12 @@
 const char kUseAndroidStagingSmdsDescription[] =
     "Use the Android staging address when fetching pending eSIM profiles.";
 
+const char kUseSharedImagesForPepperVideoName[] =
+    "Use SharedImages for PPAPI Video";
+const char kUseSharedImagesForPepperVideoDescription[] =
+    "Enables use of SharedImages for textures that are used by PPAPI "
+    "VideoDecoder";
+
 const char kUseStorkSmdsServerAddressName[] = "Use Stork SM-DS address";
 const char kUseStorkSmdsServerAddressDescription[] =
     "Use the Stork SM-DS address to fetch pending eSIM profiles managed by the "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index a16e595..832aa8f 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -224,6 +224,9 @@
 extern const char kUseAndroidStagingSmdsName[];
 extern const char kUseAndroidStagingSmdsDescription[];
 
+extern const char kUseSharedImagesForPepperVideoName[];
+extern const char kUseSharedImagesForPepperVideoDescription[];
+
 extern const char kUseStorkSmdsServerAddressName[];
 extern const char kUseStorkSmdsServerAddressDescription[];
 
diff --git a/chrome/browser/ip_protection/ip_protection_config_provider.cc b/chrome/browser/ip_protection/ip_protection_config_provider.cc
index 16ab921..5e7d344 100644
--- a/chrome/browser/ip_protection/ip_protection_config_provider.cc
+++ b/chrome/browser/ip_protection/ip_protection_config_provider.cc
@@ -139,7 +139,9 @@
             << static_cast<int>(error.state());
     TryGetAuthTokensComplete(
         absl::nullopt, std::move(callback),
-        IpProtectionTryGetAuthTokensResult::kFailedOAuthToken);
+        error.IsTransientError()
+            ? IpProtectionTryGetAuthTokensResult::kFailedOAuthTokenTransient
+            : IpProtectionTryGetAuthTokensResult::kFailedOAuthTokenPersistent);
     return;
   }
 
@@ -251,14 +253,14 @@
     // called in unit tests.
     return;
   }
-  // Notify the main profile network context to invalidate its stored cooldown
+  // Notify the main profile network context to invalidate its stored backoff
   // time.
   profile_->GetDefaultStoragePartition()
       ->GetNetworkContext()
       ->InvalidateIpProtectionConfigCacheTryAgainAfterTime();
 
   // If an associated incognito profile exists, tell it to invalidate its
-  // cooldown time as well.
+  // backoff time as well.
   if (profile_->HasPrimaryOTRProfile()) {
     profile_->GetPrimaryOTRProfile(/*create_if_needed=*/false)
         ->GetDefaultStoragePartition()
@@ -275,7 +277,7 @@
     case IpProtectionTryGetAuthTokensResult::kSuccess:
       break;
     case IpProtectionTryGetAuthTokensResult::kFailedNoAccount:
-    case IpProtectionTryGetAuthTokensResult::kFailedOAuthToken:
+    case IpProtectionTryGetAuthTokensResult::kFailedOAuthTokenPersistent:
       backoff = base::TimeDelta::Max();
       break;
     case IpProtectionTryGetAuthTokensResult::kFailedNotEligible:
@@ -290,9 +292,10 @@
       // to change quickly.
       backoff = kNotEligibleBackoff;
       break;
+    case IpProtectionTryGetAuthTokensResult::kFailedOAuthTokenTransient:
     case IpProtectionTryGetAuthTokensResult::kFailedBSAOther:
-      // Failure to fetch an OAuth token, or some other error from BSA, is
-      // probably transient.
+      // Transient failure to fetch an OAuth token, or some other error from
+      // BSA that is probably transient.
       backoff = kTransientBackoff;
       exponential = true;
       break;
@@ -302,6 +305,8 @@
       backoff = kBugBackoff;
       exponential = true;
       break;
+    case IpProtectionTryGetAuthTokensResult::kFailedOAuthTokenDeprecated:
+      NOTREACHED_NORETURN();
   }
 
   // Note that we calculate the backoff assuming that we've waited for
@@ -317,10 +322,10 @@
   //  backoff until after the first request(s))
   //
   // We can't do much about the first case, but for the others we could track
-  // the cooldown time here and not request tokens again until afterward.
+  // the backoff time here and not request tokens again until afterward.
   //
   // TODO(https://crbug.com/1476891): Track the backoff time in the browser
-  // process and don't make new requests if we are in a cooldown period.
+  // process and don't make new requests if we are in a backoff period.
   if (exponential) {
     if (last_try_get_auth_tokens_backoff_ &&
         last_try_get_auth_tokens_result_ == result) {
@@ -328,8 +333,8 @@
     }
   }
 
-  // If the cooldown is due to a user account issue, then only update the
-  // cooldown time based on account status changes (via the login observer) and
+  // If the backoff is due to a user account issue, then only update the
+  // backoff time based on account status changes (via the login observer) and
   // not based on the result of any `TryGetAuthTokens()` calls.
   if (last_try_get_auth_tokens_backoff_ &&
       *last_try_get_auth_tokens_backoff_ == base::TimeDelta::Max()) {
@@ -379,6 +384,16 @@
   // they are eventually cleaned up.
 }
 
+void IpProtectionConfigProvider::ClearOAuthTokenProblemBackoff() {
+  // End the backoff period if it was caused by account-related issues. Also,
+  // tell the `IpProtectionConfigCache()` in the Network Service so that it
+  // will begin making token requests.
+  if (last_try_get_auth_tokens_backoff_ == base::TimeDelta::Max()) {
+    last_try_get_auth_tokens_backoff_.reset();
+    InvalidateNetworkContextTryAgainAfterTime();
+  }
+}
+
 void IpProtectionConfigProvider::OnPrimaryAccountChanged(
     const signin::PrimaryAccountChangeEvent& event) {
   auto signin_event_type = event.GetEventTypeFor(signin::ConsentLevel::kSignin);
@@ -386,14 +401,9 @@
           << static_cast<int>(signin_event_type);
   switch (signin_event_type) {
     case signin::PrimaryAccountChangeEvent::Type::kSet: {
-      // If a cooldown is active because no account information was available,
-      // reset it and then tell the `IpProtectionConfigCache()` in the
-      // Network Service also (or else it won't request tokens again until after
-      // the backoff time has been reached).
-      if (last_try_get_auth_tokens_backoff_ == base::TimeDelta::Max()) {
-        last_try_get_auth_tokens_backoff_.reset();
-        InvalidateNetworkContextTryAgainAfterTime();
-      }
+      // Account information is now available, so resume making requests for the
+      // OAuth token.
+      ClearOAuthTokenProblemBackoff();
       break;
     }
     case signin::PrimaryAccountChangeEvent::Type::kCleared:
@@ -406,6 +416,25 @@
   }
 }
 
+void IpProtectionConfigProvider::OnErrorStateOfRefreshTokenUpdatedForAccount(
+    const CoreAccountInfo& account_info,
+    const GoogleServiceAuthError& error) {
+  VLOG(2) << "IPATP::OnErrorStateOfRefreshTokenUpdatedForAccount: "
+          << error.ToString();
+  // Workspace user accounts can have account credential expirations that cause
+  // persistent OAuth token errors until the user logs in to Chrome again. To
+  // handle this, watch for these error events and treat them the same way we do
+  // login/logout events.
+  if (error.state() == GoogleServiceAuthError::State::NONE) {
+    ClearOAuthTokenProblemBackoff();
+    return;
+  }
+  if (error.IsPersistentError()) {
+    last_try_get_auth_tokens_backoff_ = base::TimeDelta::Max();
+    return;
+  }
+}
+
 void IpProtectionConfigProvider::SetIpProtectionConfigHttpForTesting(
     std::unique_ptr<IpProtectionConfigHttp> ip_protection_config_http) {
   // `blind_sign_auth_` carries a raw pointer to `ip_protection_config_http_`,
diff --git a/chrome/browser/ip_protection/ip_protection_config_provider.h b/chrome/browser/ip_protection/ip_protection_config_provider.h
index b02663c..e0f8a88 100644
--- a/chrome/browser/ip_protection/ip_protection_config_provider.h
+++ b/chrome/browser/ip_protection/ip_protection_config_provider.h
@@ -42,7 +42,8 @@
   // Chrome determined the primary account is not eligible.
   kFailedNotEligible = 2,
   // There was a failure fetching an OAuth token for the primary account.
-  kFailedOAuthToken = 3,
+  // Deprecated in favor of `kFailedOAuthToken{Transient,Persistent}`.
+  kFailedOAuthTokenDeprecated = 3,
   // There was a failure in BSA with the given status code.
   kFailedBSA400 = 4,
   kFailedBSA401 = 5,
@@ -51,7 +52,14 @@
   // Any other issue calling BSA.
   kFailedBSAOther = 7,
 
-  kMaxValue = kFailedBSAOther,
+  // There was a transient failure fetching an OAuth token for the primary
+  // account.
+  kFailedOAuthTokenTransient = 8,
+  // There was a persistent failure fetching an OAuth token for the primary
+  // account.
+  kFailedOAuthTokenPersistent = 9,
+
+  kMaxValue = kFailedOAuthTokenPersistent,
 };
 
 // Fetches IP protection tokens on demand for the network service.
@@ -140,6 +148,8 @@
       TryGetAuthTokensCallback callback,
       absl::StatusOr<absl::Span<quiche::BlindSignToken>>);
 
+  void ClearOAuthTokenProblemBackoff();
+
   // The object used to get an OAuth token. `identity_manager_` will be set to
   // nullptr after `Shutdown()` is called, but will otherwise be non-null.
   raw_ptr<signin::IdentityManager> identity_manager_;
@@ -170,6 +180,9 @@
   // IdentityManager::Observer:
   void OnPrimaryAccountChanged(
       const signin::PrimaryAccountChangeEvent& event) override;
+  void OnErrorStateOfRefreshTokenUpdatedForAccount(
+      const CoreAccountInfo& account_info,
+      const GoogleServiceAuthError& error) override;
 
   // The BlindSignAuth implementation used to fetch blind-signed auth tokens. A
   // raw pointer to `url_loader_factory_` gets passed to
diff --git a/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc b/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc
index fd11018..3b35449 100644
--- a/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc
+++ b/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc
@@ -112,8 +112,12 @@
   // Primary account not set.
   kNone,
 
-  // Primary account exists but returns an error fetching access token.
-  kTokenFetchError,
+  // Primary account exists but returns a transient error fetching access token.
+  kTokenFetchTransientError,
+
+  // Primary account exists but returns a persistent error fetching access
+  // token.
+  kTokenFetchPersistentError,
 
   // Primary account exists but is not eligible for IP protection.
   kIneligible,
@@ -163,13 +167,10 @@
       identity_test_env_.MakePrimaryAccountAvailable(
           kTestEmail, signin::ConsentLevel::kSignin);
 
-      if (primary_account_behavior_ ==
-              PrimaryAccountBehavior::kUnknownEligibility ||
-          primary_account_behavior_ == PrimaryAccountBehavior::kReturnsToken) {
-        SetCanUseChromeIpProtectionCapability(true);
-      } else if (primary_account_behavior_ ==
-                 PrimaryAccountBehavior::kIneligible) {
+      if (primary_account_behavior_ == PrimaryAccountBehavior::kIneligible) {
         SetCanUseChromeIpProtectionCapability(false);
+      } else {
+        SetCanUseChromeIpProtectionCapability(true);
       }
     }
 
@@ -179,12 +180,18 @@
       case PrimaryAccountBehavior::kNone:
       case PrimaryAccountBehavior::kIneligible:
         break;
-      case PrimaryAccountBehavior::kTokenFetchError:
+      case PrimaryAccountBehavior::kTokenFetchTransientError:
         identity_test_env_
             .WaitForAccessTokenRequestIfNecessaryAndRespondWithError(
                 GoogleServiceAuthError(
                     GoogleServiceAuthError::CONNECTION_FAILED));
         break;
+      case PrimaryAccountBehavior::kTokenFetchPersistentError:
+        identity_test_env_
+            .WaitForAccessTokenRequestIfNecessaryAndRespondWithError(
+                GoogleServiceAuthError(
+                    GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
+        break;
       case PrimaryAccountBehavior::kUnknownEligibility:
       case PrimaryAccountBehavior::kReturnsToken:
         identity_test_env_
@@ -397,9 +404,24 @@
   histogram_tester_.ExpectTotalCount(kTokenBatchHistogram, 1);
 }
 
-// Fetching OAuth token returns an error.
-TEST_F(IpProtectionConfigProviderTest, AuthTokenError) {
-  primary_account_behavior_ = PrimaryAccountBehavior::kTokenFetchError;
+// Fetching OAuth token returns a transient error.
+TEST_F(IpProtectionConfigProviderTest, AuthTokenTransientError) {
+  primary_account_behavior_ = PrimaryAccountBehavior::kTokenFetchTransientError;
+
+  TryGetAuthTokens(1);
+
+  EXPECT_FALSE(bsa_->get_tokens_called_);
+  ExpectTryGetAuthTokensResultFailed(
+      IpProtectionConfigProvider::kTransientBackoff);
+  histogram_tester_.ExpectUniqueSample(
+      kTryGetAuthTokensResultHistogram,
+      IpProtectionTryGetAuthTokensResult::kFailedOAuthTokenTransient, 1);
+}
+
+// Fetching OAuth token returns a persistent error.
+TEST_F(IpProtectionConfigProviderTest, AuthTokenPersistentError) {
+  primary_account_behavior_ =
+      PrimaryAccountBehavior::kTokenFetchPersistentError;
 
   TryGetAuthTokens(1);
 
@@ -407,7 +429,7 @@
   ExpectTryGetAuthTokensResultFailed(base::TimeDelta::Max());
   histogram_tester_.ExpectUniqueSample(
       kTryGetAuthTokensResultHistogram,
-      IpProtectionTryGetAuthTokensResult::kFailedOAuthToken, 1);
+      IpProtectionTryGetAuthTokensResult::kFailedOAuthTokenPersistent, 1);
 }
 
 // No primary account.
@@ -428,7 +450,7 @@
 // No primary account initially but this changes when the account status
 // changes.
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
-TEST_F(IpProtectionConfigProviderTest, AccountLoginTriggersCooldownReset) {
+TEST_F(IpProtectionConfigProviderTest, AccountLoginTriggersBackoffReset) {
   primary_account_behavior_ = PrimaryAccountBehavior::kNone;
 
   TryGetAuthTokens(1);
@@ -447,12 +469,51 @@
 }
 #endif
 
+// If the account session token expires and is renewed, the persistent backoff
+// should be cleared.
+TEST_F(IpProtectionConfigProviderTest, SessionRefreshTriggersBackoffReset) {
+  AccountInfo account_info = identity_test_env_.MakePrimaryAccountAvailable(
+      kTestEmail, signin::ConsentLevel::kSignin);
+  SetCanUseChromeIpProtectionCapability(true);
+
+  identity_test_env_.UpdatePersistentErrorOfRefreshTokenForAccount(
+      account_info.account_id,
+      GoogleServiceAuthError(
+          GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS));
+
+  base::test::TestFuture<
+      absl::optional<std::vector<network::mojom::BlindSignedAuthTokenPtr>>,
+      absl::optional<base::Time>>
+      tokens_future;
+  getter_->TryGetAuthTokens(1, tokens_future.GetCallback());
+  const absl::optional<base::Time>& try_again_after =
+      tokens_future.Get<absl::optional<base::Time>>();
+  ASSERT_TRUE(try_again_after);
+  EXPECT_EQ(*try_again_after, base::Time::Max());
+
+  identity_test_env_.UpdatePersistentErrorOfRefreshTokenForAccount(
+      account_info.account_id,
+      GoogleServiceAuthError(GoogleServiceAuthError::State::NONE));
+
+  bsa_->tokens_ = {{"single-use-1", absl_expiration_time_}};
+  tokens_future.Clear();
+  getter_->TryGetAuthTokens(1, tokens_future.GetCallback());
+  identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
+      "access_token", base::Time::Now());
+  const absl::optional<std::vector<network::mojom::BlindSignedAuthTokenPtr>>&
+      tokens = tokens_future.Get<absl::optional<
+          std::vector<network::mojom::BlindSignedAuthTokenPtr>>>();
+  ASSERT_TRUE(tokens);
+}
+
 // Backoff calculations.
 TEST_F(IpProtectionConfigProviderTest, CalculateBackoff) {
   using enum IpProtectionTryGetAuthTokensResult;
 
   auto check = [&](IpProtectionTryGetAuthTokensResult result,
                    absl::optional<base::TimeDelta> backoff, bool exponential) {
+    SCOPED_TRACE(::testing::Message()
+                 << "result: " << static_cast<int>(result));
     EXPECT_EQ(getter_->CalculateBackoff(result), backoff);
     if (backoff && exponential) {
       EXPECT_EQ(getter_->CalculateBackoff(result), (*backoff) * 2);
@@ -468,15 +529,29 @@
   check(kFailedBSA401, getter_->kBugBackoff, true);
   check(kFailedBSA403, getter_->kNotEligibleBackoff, false);
   check(kFailedBSAOther, getter_->kTransientBackoff, true);
+  check(kFailedOAuthTokenTransient, getter_->kTransientBackoff, true);
+
   check(kFailedNoAccount, base::TimeDelta::Max(), false);
-  check(kFailedOAuthToken, base::TimeDelta::Max(), false);
   // The account-related backoffs should not be changed except by account change
   // events.
   check(kFailedBSA400, base::TimeDelta::Max(), false);
-  identity_test_env_.MakePrimaryAccountAvailable(kTestEmail,
-                                                 signin::ConsentLevel::kSignin);
+  AccountInfo account_info = identity_test_env_.MakePrimaryAccountAvailable(
+      kTestEmail, signin::ConsentLevel::kSignin);
   // The backoff time should have been reset.
   check(kFailedBSA400, getter_->kBugBackoff, true);
+
+  check(kFailedOAuthTokenPersistent, base::TimeDelta::Max(), false);
+  check(kFailedBSA400, base::TimeDelta::Max(), false);
+  // Change the refresh token error state to an error state and then back to a
+  // no-error state so that the latter clears the backoff time.
+  identity_test_env_.UpdatePersistentErrorOfRefreshTokenForAccount(
+      account_info.account_id,
+      GoogleServiceAuthError(
+          GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS));
+  identity_test_env_.UpdatePersistentErrorOfRefreshTokenForAccount(
+      account_info.account_id,
+      GoogleServiceAuthError(GoogleServiceAuthError::State::NONE));
+  check(kFailedBSA400, getter_->kBugBackoff, true);
 }
 
 TEST_F(IpProtectionConfigProviderTest, GetProxyList) {
diff --git a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/translate/FakeTranslateBridgeJni.java b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/translate/FakeTranslateBridgeJni.java
index 9dae1f5e..78d0977 100644
--- a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/translate/FakeTranslateBridgeJni.java
+++ b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/translate/FakeTranslateBridgeJni.java
@@ -31,6 +31,7 @@
     private HashSet<String> mAlwaysLanguages;
     private TreeMap<String, LanguageItem> mChromeLanguages;
     private boolean mAppLanguagePromptShown;
+    private String mCurrentLanguage;
 
     public FakeTranslateBridgeJni(Collection<LanguageItem> chromeLanguages,
             Collection<String> userAcceptLanguages, Collection<String> neverLanguages,
@@ -158,6 +159,19 @@
         mAppLanguagePromptShown = shown;
     }
 
+    @Override
+    public String getCurrentLanguage(WebContents webContents) {
+        return mCurrentLanguage;
+    }
+
+    /**
+     * Set the web content's current language for testing.
+     * @param language String value of what getCurrentLanguage should return.
+     */
+    public void setCurrentLanguage(String language) {
+        mCurrentLanguage = language;
+    }
+
     /**
      * Following methods are not implemented yet since they are not needed by current tests.
      */
@@ -193,11 +207,6 @@
         throw new UnsupportedOperationException();
     }
 
-    @Override
-    public String getCurrentLanguage(WebContents webContents) {
-        throw new UnsupportedOperationException();
-    }
-
     /**
      * Extra utility functions for MockTranslateBridge
      */
diff --git a/chrome/browser/metrics/chromeos_system_profile_provider_unittest.cc b/chrome/browser/metrics/chromeos_system_profile_provider_unittest.cc
index ef43e84..71271d5 100644
--- a/chrome/browser/metrics/chromeos_system_profile_provider_unittest.cc
+++ b/chrome/browser/metrics/chromeos_system_profile_provider_unittest.cc
@@ -209,9 +209,6 @@
   fake_multidevice_setup_client_->SetFeatureState(
       ash::multidevice_setup::mojom::Feature::kSmartLock,
       ash::multidevice_setup::mojom::FeatureState::kEnabledByUser);
-  fake_multidevice_setup_client_->SetFeatureState(
-      ash::multidevice_setup::mojom::Feature::kMessages,
-      ash::multidevice_setup::mojom::FeatureState::kFurtherSetupRequired);
 
   // |scoped_enabler| takes over the lifetime of |user_manager|.
   auto* user_manager = new ash::FakeChromeUserManager();
diff --git a/chrome/browser/payments/webapps/payment_request_lacros_browsertest.cc b/chrome/browser/payments/webapps/payment_request_lacros_browsertest.cc
index 87de76a..bb6fa187 100644
--- a/chrome/browser/payments/webapps/payment_request_lacros_browsertest.cc
+++ b/chrome/browser/payments/webapps/payment_request_lacros_browsertest.cc
@@ -17,11 +17,11 @@
 #include "chrome/browser/ui/web_applications/web_app_controller_browsertest.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
 #include "chrome/browser/web_applications/user_display_mode.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chromeos/crosapi/mojom/web_app_service.mojom.h"
 #include "chromeos/lacros/lacros_service.h"
 #include "components/payments/core/features.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/content_mock_cert_verifier.h"
@@ -121,7 +121,7 @@
     return https_server()->GetURL(kTestAppHost, "/simple.html");
   }
 
-  const web_app::AppId& app_id() const { return app_id_; }
+  const webapps::AppId& app_id() const { return app_id_; }
 
  protected:
   const bool has_associated_package_;
@@ -152,7 +152,7 @@
   testing::NiceMock<MockWebAppService> service_;
   mojo::Receiver<crosapi::mojom::WebAppService> receiver_{&service_};
 
-  web_app::AppId app_id_;
+  webapps::AppId app_id_;
 };
 
 IN_PROC_BROWSER_TEST_P(PaymentRequestLacrosBrowserTest, BrowserTab) {
diff --git a/chrome/browser/payments/webapps/twa_package_helper.cc b/chrome/browser/payments/webapps/twa_package_helper.cc
index f51c2f1..4c63f17 100644
--- a/chrome/browser/payments/webapps/twa_package_helper.cc
+++ b/chrome/browser/payments/webapps/twa_package_helper.cc
@@ -34,7 +34,7 @@
 #if BUILDFLAG(IS_CHROMEOS)
 // Returns `nullopt` if `rfh` is null, or is not a web app window, or if the
 // current url is not within the scope of the web app.
-absl::optional<web_app::AppId> GetWebAppId(content::RenderFrameHost* rfh) {
+absl::optional<webapps::AppId> GetWebAppId(content::RenderFrameHost* rfh) {
   auto* web_contents = content::WebContents::FromRenderFrameHost(rfh);
   if (!web_contents) {
     return absl::nullopt;
@@ -46,7 +46,7 @@
     return absl::nullopt;
   }
 
-  web_app::AppId app_id = browser->app_controller()->app_id();
+  webapps::AppId app_id = browser->app_controller()->app_id();
   auto* web_app_provider =
       web_app::WebAppProvider::GetForWebApps(browser->profile());
   if (!web_app_provider ||
@@ -63,7 +63,7 @@
 // Obtains the Android package name of the Trusted Web Activity that invoked
 // this browser, if any.
 std::string FetchTwaPackageName(content::RenderFrameHost* rfh) {
-  absl::optional<web_app::AppId> app_id = GetWebAppId(rfh);
+  absl::optional<webapps::AppId> app_id = GetWebAppId(rfh);
   if (!app_id.has_value()) {
     return "";
   }
@@ -93,7 +93,7 @@
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   auto* lacros_service = chromeos::LacrosService::Get();
-  absl::optional<web_app::AppId> app_id = GetWebAppId(render_frame_host);
+  absl::optional<webapps::AppId> app_id = GetWebAppId(render_frame_host);
   if (!lacros_service || !app_id.has_value()) {
     on_twa_package_name_ready_.Signal();
     return;
diff --git a/chrome/browser/privacy_sandbox/tracking_protection_notice_browsertest.cc b/chrome/browser/privacy_sandbox/tracking_protection_notice_browsertest.cc
new file mode 100644
index 0000000..3f519e8
--- /dev/null
+++ b/chrome/browser/privacy_sandbox/tracking_protection_notice_browsertest.cc
@@ -0,0 +1,467 @@
+// 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/privacy_sandbox/tracking_protection_notice_factory.h"
+#include "chrome/browser/privacy_sandbox/tracking_protection_onboarding_factory.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/feature_engagement/public/feature_constants.h"
+#include "components/privacy_sandbox/tracking_protection_onboarding.h"
+#include "components/user_education/test/feature_promo_test_util.h"
+#include "components/user_education/views/help_bubble_factory_views.h"
+#include "components/user_education/views/help_bubble_view.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "net/dns/mock_host_resolver.h"
+#include "ui/views/interaction/interaction_test_util_views.h"
+
+namespace {
+
+void WaitForFeatureEngagement(Browser* browser) {
+  BrowserView* const browser_view =
+      BrowserView::GetBrowserViewForBrowser(browser);
+  ASSERT_TRUE(user_education::test::WaitForFeatureEngagementReady(
+      browser_view->GetFeaturePromoController()));
+}
+
+BrowserFeaturePromoController* GetFeaturePromoController(Browser* browser) {
+  auto* promo_controller = static_cast<BrowserFeaturePromoController*>(
+      browser->window()->GetFeaturePromoController());
+  return promo_controller;
+}
+
+enum class PromoButton { kDefault, kNonDefault };
+
+void PressPromoButton(Browser* browser,
+                      PromoButton button = PromoButton::kDefault) {
+  auto* const promo_controller = GetFeaturePromoController(browser);
+  auto* promo_bubble = promo_controller->promo_bubble_for_testing()
+                           ->AsA<user_education::HelpBubbleViews>()
+                           ->bubble_view();
+  switch (button) {
+    case PromoButton::kDefault:
+      views::test::InteractionTestUtilSimulatorViews::PressButton(
+          promo_bubble->GetDefaultButtonForTesting(),
+          ui::test::InteractionTestUtil::InputType::kMouse);
+      return;
+    case PromoButton::kNonDefault:
+      views::test::InteractionTestUtilSimulatorViews::PressButton(
+          promo_bubble->GetNonDefaultButtonForTesting(0),
+          ui::test::InteractionTestUtil::InputType::kMouse);
+      return;
+  }
+}
+
+class TrackingProtectionNoticeBrowserTest : public InProcessBrowserTest {
+ protected:
+  TrackingProtectionNoticeBrowserTest() {
+    std::vector<base::test::FeatureRef> enabled_features = {
+        feature_engagement::kIPHTrackingProtectionOnboardingFeature};
+    feature_list_.InitAndEnableFeatures(enabled_features);
+  }
+
+  void SetUpOnMainThread() override {
+    host_resolver()->AddRule("*", "127.0.0.1");
+    https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
+    https_server_.AddDefaultHandlers(GetChromeTestDataDir());
+
+    content::SetupCrossSiteRedirector(&https_server_);
+    ASSERT_TRUE(https_server_.Start());
+    ASSERT_TRUE(embedded_test_server()->Start());
+  }
+
+  privacy_sandbox::TrackingProtectionOnboarding* onboarding_service() {
+    return TrackingProtectionOnboardingFactory::GetForProfile(
+        browser()->profile());
+  }
+
+  privacy_sandbox::TrackingProtectionNoticeService* notice_service() {
+    return TrackingProtectionNoticeFactory::GetForProfile(browser()->profile());
+  }
+
+  net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS};
+
+ private:
+  feature_engagement::test::ScopedIphFeatureList feature_list_;
+};
+
+// Navigation
+
+// Profile marked eligible, then the user navigates to a new Secure HTTPS tab
+// with the lock button.
+// Should be shown the notice
+IN_PROC_BROWSER_TEST_F(TrackingProtectionNoticeBrowserTest,
+                       NewTabEligiblePage) {
+  // Setup
+  auto lock = BrowserFeaturePromoController::BlockActiveWindowCheckForTesting();
+  WaitForFeatureEngagement(browser());
+  onboarding_service()->MaybeMarkEligible();
+
+  browser()->window()->Activate();
+  // Action: Navigate to an HTTPS eligible page in current tab.
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("a.test", "/empty.html"), 1,
+      WindowOpenDisposition::NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  // Verification
+  // Profile is onboarded
+  EXPECT_EQ(onboarding_service()->GetOnboardingStatus(),
+            privacy_sandbox::TrackingProtectionOnboarding::OnboardingStatus::
+                kOnboarded);
+  // Notice is showing.
+  EXPECT_TRUE(GetFeaturePromoController(browser())->IsPromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+}
+
+// Profile marked eligible, the user navigates to a new Secure HTTPS tab
+// with the lock button. Is shown the notice, navigates to another eligible
+// page.
+// Notice should remain on the page.
+IN_PROC_BROWSER_TEST_F(TrackingProtectionNoticeBrowserTest,
+                       SecondEligibleNavigation) {
+  // Setup
+  auto lock = BrowserFeaturePromoController::BlockActiveWindowCheckForTesting();
+  WaitForFeatureEngagement(browser());
+  onboarding_service()->MaybeMarkEligible();
+
+  browser()->window()->Activate();
+  // Action: Navigate to an HTTPS eligible page in current tab.
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("a.test", "/empty.html"), 1,
+      WindowOpenDisposition::NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+  // Then navigate to another eligible page.
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("b.test", "/empty.html"), 1,
+      WindowOpenDisposition::CURRENT_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  // Verification
+  // Notice is showing.
+  EXPECT_TRUE(GetFeaturePromoController(browser())->IsPromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+}
+
+// User is shown the notice, but was marked as Acked somehow.
+// Hide the notice
+IN_PROC_BROWSER_TEST_F(TrackingProtectionNoticeBrowserTest,
+                       NoticeWasShowingWhenAckPrefUpdated) {
+  // Setup
+  auto lock = BrowserFeaturePromoController::BlockActiveWindowCheckForTesting();
+  WaitForFeatureEngagement(browser());
+  onboarding_service()->MaybeMarkEligible();
+
+  browser()->window()->Activate();
+  // Action: Navigate to an HTTPS eligible page in current tab.
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("a.test", "/empty.html"), 1,
+      WindowOpenDisposition::NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+  // Simulate backend ack
+  onboarding_service()->NoticeActionTaken(
+      privacy_sandbox::TrackingProtectionOnboarding::NoticeAction::kGotIt);
+  // Then navigate to another eligible page.
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("b.test", "/empty.html"), 1,
+      WindowOpenDisposition::CURRENT_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  // Verification
+  // Notice is no longer showing.
+  EXPECT_FALSE(GetFeaturePromoController(browser())->IsPromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+}
+
+// Profile Marked eligible, added navigation to a new eligible background tab
+// Current tab is eligible.
+// Does not show the notice as the current tab was created before eligibility,
+// therefore not tracked, and the new navigation happened in an inactive tab.
+IN_PROC_BROWSER_TEST_F(TrackingProtectionNoticeBrowserTest,
+                       NewBackgroundTabEligiblePage) {
+  // Setup
+  auto lock = BrowserFeaturePromoController::BlockActiveWindowCheckForTesting();
+  WaitForFeatureEngagement(browser());
+  onboarding_service()->MaybeMarkEligible();
+
+  browser()->window()->Activate();
+  // Action: Navigate to an HTTPS eligible page in current tab and New
+  // background tab.
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("a.test", "/empty.html"), 1,
+      WindowOpenDisposition::CURRENT_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("a.test", "/empty.html"), 1,
+      WindowOpenDisposition::NEW_BACKGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  // Verification
+  // Profile is onboarded
+  EXPECT_EQ(onboarding_service()->GetOnboardingStatus(),
+            privacy_sandbox::TrackingProtectionOnboarding::OnboardingStatus::
+                kEligible);
+  // Notice is showing.
+  EXPECT_FALSE(GetFeaturePromoController(browser())->IsPromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+}
+
+// Profile Marked eligible, added navigation to a new Ineligible Foreground tab
+// Does not show the notice as the page isn't eligible.
+IN_PROC_BROWSER_TEST_F(TrackingProtectionNoticeBrowserTest,
+                       NewTabIneligiblePage) {
+  // Setup
+  auto lock = BrowserFeaturePromoController::BlockActiveWindowCheckForTesting();
+  WaitForFeatureEngagement(browser());
+  onboarding_service()->MaybeMarkEligible();
+
+  browser()->window()->Activate();
+  // Action: Navigate to an HTTP ineligible page in current tab. ( No lock icon)
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), embedded_test_server()->GetURL("a.test", "/empty.html"), 1,
+      WindowOpenDisposition::NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  // Verification
+  // Profile stays Eligible
+  EXPECT_EQ(onboarding_service()->GetOnboardingStatus(),
+            privacy_sandbox::TrackingProtectionOnboarding::OnboardingStatus::
+                kEligible);
+  // Notice is not showing.
+  EXPECT_FALSE(GetFeaturePromoController(browser())->IsPromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+}
+
+// Switching between eligible/ineligible tabs shows/hides the notice
+// accordingly.
+IN_PROC_BROWSER_TEST_F(TrackingProtectionNoticeBrowserTest, SwitchesTabs) {
+  // Setup
+  auto lock = BrowserFeaturePromoController::BlockActiveWindowCheckForTesting();
+  WaitForFeatureEngagement(browser());
+
+  browser()->window()->Activate();
+  //  Navigate to an HTTPS eligible page in current tab
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("a.test", "/empty.html"), 1,
+      WindowOpenDisposition::CURRENT_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+  // Creates new background tab and navigates to Ineligible page.
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), embedded_test_server()->GetURL("b.test", "/empty.html"), 1,
+      WindowOpenDisposition::NEW_BACKGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  // Action: Profile becomes eligible.
+  onboarding_service()->MaybeMarkEligible();
+
+  // Verification
+  // Notice is not yet showing.
+  EXPECT_FALSE(GetFeaturePromoController(browser())->IsPromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+
+  // This selects the second tab (ineligible). Promo shouldn't show, and profile
+  // not yet onboarded.
+  browser()->tab_strip_model()->SelectNextTab();
+  EXPECT_FALSE(GetFeaturePromoController(browser())->IsPromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+  EXPECT_EQ(onboarding_service()->GetOnboardingStatus(),
+            privacy_sandbox::TrackingProtectionOnboarding::OnboardingStatus::
+                kEligible);
+
+  // Goes back to eligible tab. Promo will show, and profile is onboarded.
+  browser()->tab_strip_model()->SelectPreviousTab();
+  EXPECT_TRUE(GetFeaturePromoController(browser())->IsPromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+  EXPECT_EQ(onboarding_service()->GetOnboardingStatus(),
+            privacy_sandbox::TrackingProtectionOnboarding::OnboardingStatus::
+                kOnboarded);
+
+  // Goes to the ineligible tab again. Notice should hide, and profile remain
+  // onboarded.
+  browser()->tab_strip_model()->SelectNextTab();
+  EXPECT_FALSE(GetFeaturePromoController(browser())->IsPromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+  EXPECT_EQ(onboarding_service()->GetOnboardingStatus(),
+            privacy_sandbox::TrackingProtectionOnboarding::OnboardingStatus::
+                kOnboarded);
+}
+
+// Popup to eligible page does not show the notice.
+IN_PROC_BROWSER_TEST_F(TrackingProtectionNoticeBrowserTest,
+                       NewPopupEligiblePage) {
+  // Setup
+  auto lock = BrowserFeaturePromoController::BlockActiveWindowCheckForTesting();
+  WaitForFeatureEngagement(browser());
+  onboarding_service()->MaybeMarkEligible();
+
+  browser()->window()->Activate();
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("a.test", "/empty.html"), 1,
+      WindowOpenDisposition::NEW_POPUP,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  // Verification
+  // Profile is not onboarded - remains eligible.
+  EXPECT_EQ(onboarding_service()->GetOnboardingStatus(),
+            privacy_sandbox::TrackingProtectionOnboarding::OnboardingStatus::
+                kEligible);
+  // Notice is Not showing.
+  EXPECT_FALSE(GetFeaturePromoController(browser())->IsPromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+}
+
+// New Browser Window picks up the promo if it navigates to an eligible page.
+IN_PROC_BROWSER_TEST_F(TrackingProtectionNoticeBrowserTest,
+                       NewWindowEligiblePage) {
+  // Setup
+  auto lock = BrowserFeaturePromoController::BlockActiveWindowCheckForTesting();
+  WaitForFeatureEngagement(browser());
+  onboarding_service()->MaybeMarkEligible();
+
+  browser()->window()->Activate();
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("a.test", "/empty.html"), 1,
+      WindowOpenDisposition::NEW_WINDOW,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  // Notice is showing on the new active window.
+  EXPECT_TRUE(
+      GetFeaturePromoController(BrowserList::GetInstance()->get(1))
+          ->IsPromoActive(
+              feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+}
+
+// The promo will only show on a single window.
+IN_PROC_BROWSER_TEST_F(TrackingProtectionNoticeBrowserTest,
+                       FirstWindowEligibleSecondWindowEligible) {
+  // Setup
+  auto lock = BrowserFeaturePromoController::BlockActiveWindowCheckForTesting();
+  WaitForFeatureEngagement(browser());
+  onboarding_service()->MaybeMarkEligible();
+
+  browser()->window()->Activate();
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("a.test", "/empty.html"), 1,
+      WindowOpenDisposition::NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  // Promo shown on first window as expected.
+  EXPECT_TRUE(GetFeaturePromoController(browser())->IsPromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+
+  // Open new eligible window.
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("b.test", "/empty.html"), 1,
+      WindowOpenDisposition::NEW_WINDOW,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  // Verification
+  EXPECT_TRUE(GetFeaturePromoController(browser())->IsPromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+
+  // Doesn't create a second notice on the second window.
+  EXPECT_FALSE(
+      GetFeaturePromoController(BrowserList::GetInstance()->get(1))
+          ->IsPromoActive(
+              feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+}
+
+// Notice Acknowledgement
+
+// Profile marked Onboarded, but not yet acknowledged still shows the notice.
+IN_PROC_BROWSER_TEST_F(TrackingProtectionNoticeBrowserTest, OnboardedNotAck) {
+  // Setup
+  auto lock = BrowserFeaturePromoController::BlockActiveWindowCheckForTesting();
+  WaitForFeatureEngagement(browser());
+
+  onboarding_service()->MaybeMarkEligible();
+  // Telling the OnboardingService that the notice has been shown so it marks
+  // the profile as Onboarded.
+  onboarding_service()->NoticeShown();
+
+  // Action: Navigate to an HTTPS eligible page in current tab.
+  browser()->window()->Activate();
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("a.test", "/empty.html"), 1,
+      WindowOpenDisposition::NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  // Verification
+  // Notice is showing.
+  EXPECT_TRUE(GetFeaturePromoController(browser())->IsPromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+}
+
+// Profile marked Onboarded and Ack no longer shows the notice.
+IN_PROC_BROWSER_TEST_F(TrackingProtectionNoticeBrowserTest,
+                       AcknowledgesTheNotice) {
+  // Setup
+  auto lock = BrowserFeaturePromoController::BlockActiveWindowCheckForTesting();
+  WaitForFeatureEngagement(browser());
+  // Action
+  onboarding_service()->MaybeMarkEligible();
+  // Navigates to eligible page.
+  browser()->window()->Activate();
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("a.test", "/empty.html"), 1,
+      WindowOpenDisposition::NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  PressPromoButton(browser(), PromoButton::kNonDefault);
+
+  // Verification - Notice acknowledged.
+  EXPECT_FALSE(GetFeaturePromoController(browser())->IsPromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature));
+  EXPECT_FALSE(onboarding_service()->ShouldShowOnboardingNotice());
+}
+
+// Observation
+
+// Profile is ineligible. Notice Service is not observing tab changes.
+IN_PROC_BROWSER_TEST_F(TrackingProtectionNoticeBrowserTest,
+                       DoesntStartObserving) {
+  EXPECT_FALSE(TabStripModelObserver::IsObservingAny(notice_service()));
+  EXPECT_FALSE(privacy_sandbox::TrackingProtectionNoticeService::TabHelper::
+                   IsHelperNeeded(browser()->profile()));
+}
+
+// Profile is eligible. Notice service is observing tab changes.
+IN_PROC_BROWSER_TEST_F(TrackingProtectionNoticeBrowserTest, StartsObserving) {
+  // Action
+  onboarding_service()->MaybeMarkEligible();
+  browser()->window()->Activate();
+  // Verification
+  EXPECT_TRUE(TabStripModelObserver::IsObservingAny(notice_service()));
+  EXPECT_TRUE(privacy_sandbox::TrackingProtectionNoticeService::TabHelper::
+                  IsHelperNeeded(browser()->profile()));
+}
+
+// Notice is acknowledged. Notice Service stops observing tab changes.
+IN_PROC_BROWSER_TEST_F(TrackingProtectionNoticeBrowserTest, StopsObserving) {
+  // Setup
+  auto lock = BrowserFeaturePromoController::BlockActiveWindowCheckForTesting();
+  WaitForFeatureEngagement(browser());
+  // Action
+  onboarding_service()->MaybeMarkEligible();
+  // Navigates to eligible page.
+  browser()->window()->Activate();
+  ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
+      browser(), https_server_.GetURL("a.test", "/empty.html"), 1,
+      WindowOpenDisposition::NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  PressPromoButton(browser());
+
+  // Verification - Observation stops
+  EXPECT_FALSE(TabStripModelObserver::IsObservingAny(notice_service()));
+  EXPECT_FALSE(privacy_sandbox::TrackingProtectionNoticeService::TabHelper::
+                   IsHelperNeeded(browser()->profile()));
+}
+
+}  // namespace
diff --git a/chrome/browser/privacy_sandbox/tracking_protection_notice_service.cc b/chrome/browser/privacy_sandbox/tracking_protection_notice_service.cc
index 672d3059d..535518e 100644
--- a/chrome/browser/privacy_sandbox/tracking_protection_notice_service.cc
+++ b/chrome/browser/privacy_sandbox/tracking_protection_notice_service.cc
@@ -3,29 +3,200 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/privacy_sandbox/tracking_protection_notice_service.h"
+#include <memory>
 #include "base/check.h"
+#include "components/feature_engagement/public/feature_constants.h"
 
 #include "chrome/browser/privacy_sandbox/tracking_protection_notice_factory.h"
 #include "chrome/browser/privacy_sandbox/tracking_protection_onboarding_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/browser_finder.h"
+#include "chrome/browser/ui/browser_tab_strip_tracker.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "components/omnibox/browser/location_bar_model.h"
 #include "components/privacy_sandbox/tracking_protection_onboarding.h"
+#include "components/user_education/common/feature_promo_controller.h"
+#include "content/public/browser/navigation_handle.h"
 
 namespace privacy_sandbox {
 
+namespace {
+
+bool IsLocationBarEligible(Browser* browser) {
+  bool is_secure = browser->location_bar_model()->GetSecurityLevel() ==
+                   security_state::SECURE;
+
+  bool is_element_visible =
+      ui::ElementTracker::GetElementTracker()->IsElementVisible(
+          kLocationIconElementId, browser->window()->GetElementContext());
+
+  return is_secure && is_element_visible;
+}
+
+bool IsPromoShowing(Browser* browser) {
+  return browser->window()->IsFeaturePromoActive(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature);
+}
+
+void HidePromo(Browser* browser) {
+  browser->window()->CloseFeaturePromo(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature,
+      user_education::FeaturePromoCloseReason::kAbortPromo);
+}
+
+}  // namespace
+
 TrackingProtectionNoticeService::TrackingProtectionNoticeService(
     Profile* profile,
     TrackingProtectionOnboarding* onboarding_service)
     : profile_(profile), onboarding_service_(onboarding_service) {
   CHECK(profile_);
   CHECK(onboarding_service_);
+  onboarding_observation_.Observe(onboarding_service_);
+
+  // We call this once here manually for initialization.
+  OnShouldShowNoticeUpdated();
 }
 
 TrackingProtectionNoticeService::~TrackingProtectionNoticeService() = default;
 
+void TrackingProtectionNoticeService::InitializeTabStripTracker() {
+  tab_strip_tracker_ = std::make_unique<BrowserTabStripTracker>(this, this);
+  tab_strip_tracker_->Init();
+}
+
+void TrackingProtectionNoticeService::ResetTabStripTracker() {
+  tab_strip_tracker_ = nullptr;
+}
+
+void TrackingProtectionNoticeService::OnShouldShowNoticeUpdated() {
+  if (onboarding_service_->ShouldShowOnboardingNotice()) {
+    // We only start watching updates on TabStripTracker when we actually need
+    // to show a notice.
+    InitializeTabStripTracker();
+  } else {
+    // If we no longer need to show the notice, we stop watching so we don't run
+    // logic unnecessarily.
+    ResetTabStripTracker();
+  }
+}
+
+void TrackingProtectionNoticeService::OnNoticeClosed(
+    base::Time showed_when,
+    user_education::FeaturePromoController* promo_controller) {
+  if (!promo_controller) {
+    return;
+  }
+
+  user_education::FeaturePromoStorageService::CloseReason close_reason;
+  bool has_been_dismissed = promo_controller->HasPromoBeenDismissed(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature,
+      &close_reason);
+
+  if (!has_been_dismissed) {
+    return;
+  }
+  switch (close_reason) {
+    case user_education::FeaturePromoStorageService::kDismiss:
+      onboarding_service_->NoticeActionTaken(
+          TrackingProtectionOnboarding::NoticeAction::kGotIt);
+      return;
+    case user_education::FeaturePromoStorageService::kAction:
+      onboarding_service_->NoticeActionTaken(
+          TrackingProtectionOnboarding::NoticeAction::kSettings);
+      return;
+    case user_education::FeaturePromoStorageService::kCancel:
+      onboarding_service_->NoticeActionTaken(
+          TrackingProtectionOnboarding::NoticeAction::kClosed);
+      return;
+    default:
+      return;
+  }
+}
+
+void TrackingProtectionNoticeService::MaybeUpdateNoticeVisibility(
+    content::WebContents* web_content) {
+  if (!web_content) {
+    return;
+  }
+
+  auto* browser = chrome::FindBrowserWithWebContents(web_content);
+
+  if (!browser || !browser->window() || !browser->location_bar_model() ||
+      !browser->tab_strip_model()) {
+    return;
+  }
+
+  // Exclude Popups, PWAs and other non normal browsers.
+  if (browser->type() != Browser::TYPE_NORMAL) {
+    return;
+  }
+
+  // If the notice should no longer be shown, then hide it and add metrics.
+  if (!onboarding_service_->ShouldShowOnboardingNotice()) {
+    if (IsPromoShowing(browser)) {
+      HidePromo(browser);
+      // TODO(b/302008359) Add Metrics. We shouldn't be in this state.
+    }
+    return;
+  }
+
+  // If tab triggering the update isn't the active one, avoid triggering the
+  // promo.
+  // No additional checks on the window Active/Minimized, as the Promos can only
+  // be shown on active windows.
+  if (browser->tab_strip_model()->GetActiveWebContents() != web_content) {
+    return;
+  }
+
+  // We should hide the notice at this point if the browser isn't eligible.
+  if (!IsLocationBarEligible(browser)) {
+    HidePromo(browser);
+    return;
+  }
+
+  // At this point, the update is happening in an active tab, Secure location,
+  // with a visible LocationIcon. We should attempt to show the notice if it's
+  // not already shown.
+  if (IsPromoShowing(browser)) {
+    return;
+  }
+
+  base::Time shown_when = base::Time::Now();
+  auto is_notice_shown = browser->window()->MaybeShowFeaturePromo(
+      feature_engagement::kIPHTrackingProtectionOnboardingFeature,
+      base::BindOnce(&TrackingProtectionNoticeService::OnNoticeClosed,
+                     base::Unretained(this), shown_when,
+                     browser->window()->GetFeaturePromoController()));
+  if (is_notice_shown) {
+    onboarding_service_->NoticeShown();
+    // TODO(b/302008359) Emit metrics
+  } else {
+    // TODO(b/302008359) Emit metrics
+  }
+}
+
 bool TrackingProtectionNoticeService::IsNoticeNeeded() {
   return onboarding_service_->ShouldShowOnboardingNotice();
 }
 
+bool TrackingProtectionNoticeService::ShouldTrackBrowser(Browser* browser) {
+  return browser->profile() == profile_ &&
+         browser->type() == Browser::TYPE_NORMAL;
+}
+
+void TrackingProtectionNoticeService::OnTabStripModelChanged(
+    TabStripModel* tab_strip_model,
+    const TabStripModelChange& change,
+    const TabStripSelectionChange& selection) {
+  if (!selection.active_tab_changed()) {
+    return;
+  }
+  MaybeUpdateNoticeVisibility(selection.new_contents);
+}
+
 TrackingProtectionNoticeService::TabHelper::TabHelper(
     content::WebContents* web_contents)
     : WebContentsObserver(web_contents),
@@ -41,6 +212,20 @@
   return notice_service && notice_service->IsNoticeNeeded();
 }
 
+void TrackingProtectionNoticeService::TabHelper::DidFinishNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle || !navigation_handle->HasCommitted() ||
+      !navigation_handle->IsInPrimaryMainFrame() ||
+      navigation_handle->IsSameDocument()) {
+    return;
+  }
+  Profile* profile =
+      Profile::FromBrowserContext(GetWebContents().GetBrowserContext());
+
+  TrackingProtectionNoticeFactory::GetForProfile(profile)
+      ->MaybeUpdateNoticeVisibility(web_contents());
+}
+
 WEB_CONTENTS_USER_DATA_KEY_IMPL(TrackingProtectionNoticeService::TabHelper);
 
 }  // namespace privacy_sandbox
diff --git a/chrome/browser/privacy_sandbox/tracking_protection_notice_service.h b/chrome/browser/privacy_sandbox/tracking_protection_notice_service.h
index 41445bb..bb93bf1 100644
--- a/chrome/browser/privacy_sandbox/tracking_protection_notice_service.h
+++ b/chrome/browser/privacy_sandbox/tracking_protection_notice_service.h
@@ -6,9 +6,16 @@
 #ifndef CHROME_BROWSER_PRIVACY_SANDBOX_TRACKING_PROTECTION_NOTICE_SERVICE_H_
 #define CHROME_BROWSER_PRIVACY_SANDBOX_TRACKING_PROTECTION_NOTICE_SERVICE_H_
 
+#include <memory>
 #include "base/memory/raw_ptr.h"
+#include "base/scoped_observation.h"
+#include "chrome/browser/ui/browser_tab_strip_tracker.h"
+#include "chrome/browser/ui/browser_tab_strip_tracker_delegate.h"
+#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/privacy_sandbox/tracking_protection_onboarding.h"
+#include "components/user_education/common/feature_promo_controller.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
@@ -27,7 +34,20 @@
 // If the profile is not to be shown the notice at all due to ineligibility,
 // then this service doesn't observe anything (Except the
 // TrackingProtectionOnboarding Service).
-class TrackingProtectionNoticeService : public KeyedService {
+// We are observing two different types of interactions:
+//    1. Using the TabStripModelObserver: All updates to the tabs: This allows
+//    us to show/hide the notice on all tabs (including tabs that we started
+//    observing newly created webcontents) after the user selects a new one.
+//
+//    2. Using the WebContentsObserver: Navigation updates to the active
+//    webcontent: This allows us to show/hide the notice based on the
+//    navigation, in case the user doesn't update the tab, but only its
+//    webcontent through navigation.
+class TrackingProtectionNoticeService
+    : public KeyedService,
+      public TabStripModelObserver,
+      public BrowserTabStripTrackerDelegate,
+      public TrackingProtectionOnboarding::Observer {
  public:
   TrackingProtectionNoticeService(
       Profile* profile,
@@ -50,6 +70,10 @@
     friend class content::WebContentsUserData<TabHelper>;
     explicit TabHelper(content::WebContents* web_contents);
 
+    // contents::WebContentsObserver:
+    void DidFinishNavigation(
+        content::NavigationHandle* navigation_handle) override;
+
     WEB_CONTENTS_USER_DATA_KEY_DECL();
   };
 
@@ -57,8 +81,41 @@
   // Indicates if the notice is needed to be displayed.
   bool IsNoticeNeeded();
 
+  // Assumes this is a time to show the user the onboarding Notice. This
+  // method will attempt do so.
+  void MaybeUpdateNoticeVisibility(content::WebContents* web_content);
+
+  // Fires when the Notice is closed (for any reason).
+  void OnNoticeClosed(base::Time showed_when,
+                      user_education::FeaturePromoController* promo_controller);
+
+  // This is called internally when the service should start observing the tab
+  // strip model across all eligible browsers. Browser eligibility is determined
+  // by the  "ShouldTrackBrowser" below.
+  void InitializeTabStripTracker();
+
+  // This is called internally when the service should no longer observe changes
+  // to the tab strip model.
+  void ResetTabStripTracker();
+
+  // TabStripModelObserver
+  void OnTabStripModelChanged(
+      TabStripModel* tab_strip_model,
+      const TabStripModelChange& change,
+      const TabStripSelectionChange& selection) override;
+
+  // BrowserTabStripTrackerDelegate
+  bool ShouldTrackBrowser(Browser* browser) override;
+
+  // TrackingProtectionOnboarding::Observer
+  void OnShouldShowNoticeUpdated() override;
+
   raw_ptr<Profile> profile_;
+  std::unique_ptr<BrowserTabStripTracker> tab_strip_tracker_;
   raw_ptr<TrackingProtectionOnboarding> onboarding_service_;
+  base::ScopedObservation<TrackingProtectionOnboarding,
+                          TrackingProtectionOnboarding::Observer>
+      onboarding_observation_{this};
 };
 
 }  // namespace privacy_sandbox
diff --git a/chrome/browser/profiles/DEPS b/chrome/browser/profiles/DEPS
index 80e2e00..f636b39 100644
--- a/chrome/browser/profiles/DEPS
+++ b/chrome/browser/profiles/DEPS
@@ -1,6 +1,5 @@
 include_rules = [
   "+components/live_caption:constants",
-  "+components/media_effects",
   "+components/profile_metrics",
   "+device/fido/cros/credential_store.h",
   "+device/fido/mac/credential_store.h",
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index c41e8c8..1fac3fd 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -206,7 +206,6 @@
 #include "components/commerce/core/proto/commerce_subscription_db_content.pb.h"
 #include "components/commerce/core/proto/persisted_state_db_content.pb.h"
 #include "components/enterprise/content/clipboard_restriction_service.h"
-#include "components/media_effects/media_effects_service_factory.h"
 #include "components/offline_pages/buildflags/buildflags.h"
 #include "components/omnibox/browser/autocomplete_controller_emitter.h"
 #include "components/optimization_guide/core/optimization_guide_switches.h"
@@ -819,12 +818,6 @@
 #if BUILDFLAG(IS_ANDROID)
   MediaDrmOriginIdManagerFactory::GetInstance();
 #endif
-
-#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
-  if (base::FeatureList::IsEnabled(media::kCameraMicEffects)) {
-    MediaEffectsServiceFactory::GetInstance();
-  }
-#endif
   if (MediaEngagementService::IsEnabled()) {
     MediaEngagementServiceFactory::GetInstance();
   }
diff --git a/chrome/browser/readaloud/android/BUILD.gn b/chrome/browser/readaloud/android/BUILD.gn
index cf8fb7f..560ca5b 100644
--- a/chrome/browser/readaloud/android/BUILD.gn
+++ b/chrome/browser/readaloud/android/BUILD.gn
@@ -3,7 +3,6 @@
 # found in the LICENSE file.
 
 import("//build/config/android/rules.gni")
-
 android_library("java") {
   sources = [
     "java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java",
@@ -104,13 +103,17 @@
     ":hooks_java",
     ":java",
     ":java_resources",
+    ":player_java",
     ":player_junit_java",
     ":player_state_java",
     "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
+    "//base:jni_java",
     "//chrome/android/modules/readaloud/public:java",
     "//chrome/browser/flags:java",
+    "//chrome/browser/language/android:java",
+    "//chrome/browser/language/android:junit",
     "//chrome/browser/profiles/android:java",
     "//chrome/browser/signin/services/android:java",
     "//chrome/browser/tab:java",
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java
index 75c4e81..60468046 100644
--- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java
+++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java
@@ -22,7 +22,11 @@
 import org.chromium.chrome.browser.tabmodel.TabModelTabObserver;
 import org.chromium.chrome.browser.translate.TranslateBridge;
 import org.chromium.chrome.modules.readaloud.ExpandedPlayer;
+import org.chromium.chrome.modules.readaloud.Playback;
+import org.chromium.chrome.modules.readaloud.PlaybackListener;
 import org.chromium.chrome.modules.readaloud.PlaybackArgs;
+import org.chromium.chrome.modules.readaloud.ReadAloudPlaybackHooks;
+import org.chromium.chrome.modules.readaloud.ReadAloudPlaybackHooksProvider;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.embedder_support.util.UrlConstants;
 import org.chromium.url.GURL;
@@ -45,11 +49,23 @@
     private final TabModel mTabModel;
     private final ExpandedPlayer mExpandedPlayer;
     private final PlayerCoordinator mPlayerCoordinator;
+    @Nullable
+    private static PlayerCoordinator sPlayerCoordinatorForTesting;
+
     private TabModelTabObserver mTabObserver;
 
     private final ReadAloudReadabilityHooks mReadabilityHooks;
     @Nullable
     private static ReadAloudReadabilityHooks sReadabilityHooksForTesting;
+    @Nullable
+    private ReadAloudPlaybackHooks mPlaybackHooks;
+    @Nullable
+    private static ReadAloudPlaybackHooks sPlaybackHooksForTesting;
+    // When playback is reset, it should be set to null together with the mCurrentlyPlayingTab
+    @Nullable
+    private Playback mPlayback;
+    @Nullable
+    private Tab mCurrentlyPlayingTab;
 
     /**
      * Kicks of readability check on a page load iff: the url is valid, no previous
@@ -76,6 +92,22 @@
                 }
             };
 
+    private ReadAloudPlaybackHooks.CreatePlaybackCallback mPlaybackCallback =
+            new ReadAloudPlaybackHooks.CreatePlaybackCallback() {
+                @Override
+                public void onSuccess(Playback playback) {
+                    Log.i(TAG, "Playback created");
+                    mPlayback = playback;
+                    mPlayerCoordinator.playbackReady(mPlayback, PlaybackListener.State.PLAYING);
+                    mPlayback.play();
+                }
+                @Override
+                public void onFailure(Throwable t) {
+                    Log.i(TAG, t.getMessage());
+                    mPlayerCoordinator.playbackFailed();
+                }
+            };
+
     public ReadAloudController(Context context, ObservableSupplier<Profile> profileSupplier,
             TabModel tabModel, ViewStub miniPlayerStub,
             BottomSheetController bottomSheetController) {
@@ -85,7 +117,10 @@
                 ? sReadabilityHooksForTesting
                 : new ReadAloudReadabilityHooksImpl(context, ReadAloudFeatures.getApiKeyOverride());
         mExpandedPlayer = new ExpandedPlayerCoordinator(context, bottomSheetController);
-        mPlayerCoordinator = new PlayerCoordinator(context);
+        mPlayerCoordinator = sPlayerCoordinatorForTesting != null
+                ? sPlayerCoordinatorForTesting
+                : new PlayerCoordinator(context);
+
         if (mReadabilityHooks.isEnabled()) {
             mTabObserver = new TabModelTabObserver(mTabModel) {
                 @Override
@@ -167,14 +202,29 @@
     }
 
     public void playTab(Tab tab) {
-        Log.e(TAG, "playTab() not implemented.");
-        PlaybackArgs args =
-                new PlaybackArgs(tab.getUrl().getSpec(), TranslateBridge.getCurrentLanguage(tab),
-                        /* voice=*/null, /* dateModifiedMsSinceEpock=*/0);
-        // TODO request playback here and call mPlayerCoordinator.playbackReady()
+        assert tab.getUrl().isValid();
+        if (mPlaybackHooks == null) {
+            mPlaybackHooks = sPlaybackHooksForTesting != null
+                    ? sPlaybackHooksForTesting
+                    : ReadAloudPlaybackHooksProvider.getInstance();
+        }
+        // only start a new playback if different URL or no active playback for that url
+        if (mCurrentlyPlayingTab == null || !tab.getUrl().equals(mCurrentlyPlayingTab.getUrl())) {
+            mCurrentlyPlayingTab = tab;
 
-        // Notify player UI that playback is happening soon.
-        mPlayerCoordinator.playTabRequested();
+            if (mPlayback != null) {
+                mPlayback.release();
+                mPlayback = null;
+            }
+
+            PlaybackArgs args = new PlaybackArgs(tab.getUrl().getSpec(),
+                    TranslateBridge.getCurrentLanguage(tab),
+                    /* voice=*/null, /* dateModifiedMsSinceEpock=*/0);
+            mPlaybackHooks.createPlayback(args, mPlaybackCallback);
+
+            // Notify player UI that playback is happening soon.
+            mPlayerCoordinator.playTabRequested();
+        }
     }
 
     /**
@@ -191,11 +241,20 @@
 
     /** Cleanup: unregister listeners. */
     public void destroy() {
+        // Stop playback and hide players.
+        mPlayerCoordinator.destroy();
+
         if (mTabObserver != null) {
             mTabObserver.destroy();
         }
-        // Stop playback and hide players.
-        mPlayerCoordinator.destroy();
+
+        if (mPlayback != null) {
+            mPlayback.release();
+            mPlayback = null;
+        }
+        if (mCurrentlyPlayingTab != null) {
+            mCurrentlyPlayingTab = null;
+        }
     }
 
     @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
@@ -203,4 +262,16 @@
         sReadabilityHooksForTesting = hooks;
         ResettersForTesting.register(() -> sReadabilityHooksForTesting = null);
     }
+
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    public static void setPlaybackHooks(ReadAloudPlaybackHooks hooks) {
+        sPlaybackHooksForTesting = hooks;
+        ResettersForTesting.register(() -> sPlaybackHooksForTesting = null);
+    }
+
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    public static void setPlayerCoordinator(PlayerCoordinator coordinator) {
+        sPlayerCoordinatorForTesting = coordinator;
+        ResettersForTesting.register(() -> sPlayerCoordinatorForTesting = null);
+    }
 }
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudControllerUnitTest.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudControllerUnitTest.java
index 71ef05b..c28e2cf 100644
--- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudControllerUnitTest.java
+++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudControllerUnitTest.java
@@ -34,9 +34,15 @@
 import org.chromium.base.test.util.Features;
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.readaloud.player.PlayerCoordinator;
 import org.chromium.chrome.browser.signin.services.UnifiedConsentServiceBridge;
 import org.chromium.chrome.browser.tab.MockTab;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.translate.FakeTranslateBridgeJni;
+import org.chromium.chrome.browser.translate.TranslateBridgeJni;
+import org.chromium.chrome.modules.readaloud.Playback;
+import org.chromium.chrome.modules.readaloud.PlaybackListener;
+import org.chromium.chrome.modules.readaloud.ReadAloudPlaybackHooks;
 import org.chromium.chrome.test.util.browser.tabmodel.MockTabModelSelector;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.url.GURL;
@@ -55,6 +61,8 @@
     public JniMocker mJniMocker = new JniMocker();
     @Rule
     public TestRule mProcessor = new Features.JUnitProcessor();
+
+    private FakeTranslateBridgeJni mFakeTranslateBridge;
     @Mock
     private ObservableSupplier<Profile> mMockProfileSupplier;
     @Mock
@@ -64,14 +72,22 @@
     @Mock
     private ReadAloudReadabilityHooksImpl mHooksImpl;
     @Mock
+    private ReadAloudPlaybackHooks mPlaybackHooks;
+    @Mock
     private ViewStub mViewStub;
     @Mock
+    private PlayerCoordinator mPlayerCoordinator;
+    @Mock
     private BottomSheetController mBottomSheetController;
 
     MockTabModelSelector mTabModelSelector;
 
     @Captor
     ArgumentCaptor<ReadAloudReadabilityHooks.ReadabilityCallback> mCallbackCaptor;
+    @Captor
+    ArgumentCaptor<ReadAloudPlaybackHooks.CreatePlaybackCallback> mPlaybackCallbackCaptor;
+    @Mock
+    private Playback mPlayback;
 
     @Before
     public void setUp() {
@@ -81,13 +97,17 @@
         when(mMockProfile.isOffTheRecord()).thenReturn(false);
         UnifiedConsentServiceBridge.setUrlKeyedAnonymizedDataCollectionEnabled(true);
 
+        mFakeTranslateBridge = new FakeTranslateBridgeJni();
+        mJniMocker.mock(TranslateBridgeJni.TEST_HOOKS, mFakeTranslateBridge);
         mTabModelSelector = new MockTabModelSelector(
                 /* tabCount= */ 2, /* incognitoTabCount= */ 1, (id, incognito) -> {
                     Tab tab = spy(MockTab.createAndInitialize(id, incognito));
                     return tab;
                 });
         when(mHooksImpl.isEnabled()).thenReturn(true);
+        ReadAloudController.setPlayerCoordinator(mPlayerCoordinator);
         ReadAloudController.setReadabilityHooks(mHooksImpl);
+        ReadAloudController.setPlaybackHooks(mPlaybackHooks);
         mController = new ReadAloudController(mContext, mMockProfileSupplier,
                 mTabModelSelector.getModel(false), mViewStub, mBottomSheetController);
 
@@ -215,4 +235,36 @@
                 .isPageReadable(Mockito.anyString(),
                         Mockito.any(ReadAloudReadabilityHooks.ReadabilityCallback.class));
     }
+
+    @Test
+    public void testPlayTab() {
+        mFakeTranslateBridge.setCurrentLanguage("en");
+        mTab.setGurlOverrideForTesting(new GURL("https://en.wikipedia.org/wiki/Google"));
+        mController.playTab(mTab);
+
+        verify(mPlaybackHooks, times(1))
+                .createPlayback(Mockito.any(), mPlaybackCallbackCaptor.capture());
+
+        mPlaybackCallbackCaptor.getValue().onSuccess(mPlayback);
+        verify(mPlayerCoordinator, times(1)).playbackReady(eq(mPlayback), eq(PlaybackListener.State.PLAYING));
+
+        // test that previous playback is released when another playback is called
+        MockTab newTab = (MockTab) mTabModelSelector.addMockTab();
+        newTab.setGurlOverrideForTesting(new GURL("https://en.wikipedia.org/wiki/Alphabet_Inc."));
+        mController.playTab(newTab);
+        verify(mPlayback, times(1)).release();
+    }
+
+    @Test
+    public void testPlayTab_onFailure() {
+        mFakeTranslateBridge.setCurrentLanguage("en");
+        mTab.setGurlOverrideForTesting(new GURL("https://en.wikipedia.org/wiki/Google"));
+        mController.playTab(mTab);
+
+        verify(mPlaybackHooks, times(1))
+                .createPlayback(Mockito.any(), mPlaybackCallbackCaptor.capture());
+
+        mPlaybackCallbackCaptor.getValue().onFailure(new Throwable());
+        verify(mPlayerCoordinator, times(1)).playbackFailed();
+    }
 }
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
index 3facc3cc..25781c91 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
@@ -191,8 +191,8 @@
 #if BUILDFLAG(IS_CHROMEOS)
 class MockDlpRulesManager : public policy::DlpRulesManagerImpl {
  public:
-  explicit MockDlpRulesManager(PrefService* local_state, Profile* profile)
-      : DlpRulesManagerImpl(local_state, profile) {}
+  explicit MockDlpRulesManager(PrefService* local_state)
+      : DlpRulesManagerImpl(local_state) {}
 };
 #endif
 
@@ -749,8 +749,7 @@
 
   EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB));
 
-  TestingProfile profile;
-  MockDlpRulesManager mock_dlp_rules_manager(local_state(), &profile);
+  MockDlpRulesManager mock_dlp_rules_manager(local_state());
   menu->set_dlp_rules_manager(&mock_dlp_rules_manager);
   EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB));
 
@@ -777,8 +776,7 @@
 
   EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW));
 
-  TestingProfile profile;
-  MockDlpRulesManager mock_dlp_rules_manager(local_state(), &profile);
+  MockDlpRulesManager mock_dlp_rules_manager(local_state());
   menu->set_dlp_rules_manager(&mock_dlp_rules_manager);
   EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW));
 
@@ -805,8 +803,7 @@
 
   EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_OPENLINKINPROFILE));
 
-  TestingProfile profile;
-  MockDlpRulesManager mock_dlp_rules_manager(local_state(), &profile);
+  MockDlpRulesManager mock_dlp_rules_manager(local_state());
   menu->set_dlp_rules_manager(&mock_dlp_rules_manager);
   EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_OPENLINKINPROFILE));
 
@@ -833,8 +830,7 @@
   EXPECT_TRUE(
       menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP));
 
-  TestingProfile profile;
-  MockDlpRulesManager mock_dlp_rules_manager(local_state(), &profile);
+  MockDlpRulesManager mock_dlp_rules_manager(local_state());
   menu->set_dlp_rules_manager(&mock_dlp_rules_manager);
   EXPECT_TRUE(
       menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP));
@@ -863,8 +859,7 @@
 
   EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_GOTOURL));
 
-  TestingProfile profile;
-  MockDlpRulesManager mock_dlp_rules_manager(local_state(), &profile);
+  MockDlpRulesManager mock_dlp_rules_manager(local_state());
   menu->set_dlp_rules_manager(&mock_dlp_rules_manager);
   EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_GOTOURL));
 
@@ -887,8 +882,7 @@
 
   EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_SEARCHWEBFOR));
 
-  TestingProfile profile;
-  MockDlpRulesManager mock_dlp_rules_manager(local_state(), &profile);
+  MockDlpRulesManager mock_dlp_rules_manager(local_state());
   menu->set_dlp_rules_manager(&mock_dlp_rules_manager);
   EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_SEARCHWEBFOR));
 
@@ -912,8 +906,7 @@
 
   EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_SEARCHWEBFORNEWTAB));
 
-  TestingProfile profile;
-  MockDlpRulesManager mock_dlp_rules_manager(local_state(), &profile);
+  MockDlpRulesManager mock_dlp_rules_manager(local_state());
   menu->set_dlp_rules_manager(&mock_dlp_rules_manager);
   EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_SEARCHWEBFORNEWTAB));
 
diff --git a/chrome/browser/resources/ash/settings/os_files_page/google_drive_browser_proxy.ts b/chrome/browser/resources/ash/settings/os_files_page/google_drive_browser_proxy.ts
index 0464bad..7ee1a48 100644
--- a/chrome/browser/resources/ash/settings/os_files_page/google_drive_browser_proxy.ts
+++ b/chrome/browser/resources/ash/settings/os_files_page/google_drive_browser_proxy.ts
@@ -24,7 +24,7 @@
     return instance || (instance = new GoogleDriveBrowserProxy());
   }
 
-  static setInstance(proxy: GoogleDriveBrowserProxy) {
+  static setInstance(proxy: GoogleDriveBrowserProxy): void {
     instance = proxy;
   }
 }
diff --git a/chrome/browser/resources/ash/settings/os_files_page/google_drive_confirmation_dialog.ts b/chrome/browser/resources/ash/settings/os_files_page/google_drive_confirmation_dialog.ts
index 0c6722953..c1b2b08 100644
--- a/chrome/browser/resources/ash/settings/os_files_page/google_drive_confirmation_dialog.ts
+++ b/chrome/browser/resources/ash/settings/os_files_page/google_drive_confirmation_dialog.ts
@@ -52,21 +52,21 @@
   /**
    * When the cancel button is pressed, cancel the dialog.
    */
-  private onCancelClick_() {
+  private onCancelClick_(): void {
     this.$.dialog.cancel();
   }
 
   /**
    * When the action button is pressed, close the dialog.
    */
-  private onActionClick_() {
+  private onActionClick_(): void {
     this.$.dialog.close();
   }
 
   /**
    * When the dialog is cancelled ensure the `accept_` is false.
    */
-  private onDialogCancel_() {
+  private onDialogCancel_(): void {
     this.accept_ = false;
   }
 
@@ -74,7 +74,7 @@
    * When the dialog is closed (either through cancellation or acceptance) send
    * a custom event to the enclosing container.
    */
-  private onDialogClose_(e: Event) {
+  private onDialogClose_(e: Event): void {
     e.stopPropagation();
 
     const closeEvent = new CustomEvent(
diff --git a/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts b/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts
index 88d068e..c5bca7b 100644
--- a/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts
+++ b/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts
@@ -23,7 +23,7 @@
 import {RouteObserverMixin} from '../route_observer_mixin.js';
 import {Route, routes} from '../router.js';
 
-import {GoogleDriveBrowserProxy, Stage, Status} from './google_drive_browser_proxy.js';
+import {GoogleDriveBrowserProxy, GoogleDrivePageCallbackRouter, GoogleDrivePageHandlerRemote, Stage, Status} from './google_drive_browser_proxy.js';
 import {getTemplate} from './google_drive_subpage.html.js';
 
 const SettingsGoogleDriveSubpageElementBase =
@@ -180,14 +180,14 @@
   /**
    * Returns the browser proxy page handler (to invoke functions).
    */
-  get pageHandler() {
+  get pageHandler(): GoogleDrivePageHandlerRemote {
     return this.proxy_.handler;
   }
 
   /**
    * Returns the browser proxy callback router (to receive async messages).
    */
-  get callbackRouter() {
+  get callbackRouter(): GoogleDrivePageCallbackRouter {
     return this.proxy_.observer;
   }
 
@@ -195,7 +195,7 @@
    * Returns the required space that is currently stored or -1 of no value. Used
    * for testing.
    */
-  get requiredSpace() {
+  get requiredSpace(): string {
     return this.bulkPinningStatus_?.requiredSpace || '-1';
   }
 
@@ -203,7 +203,7 @@
    * Returns the free space that is currently stored or -1 of no value.
    * Used for testing.
    */
-  get freeSpace() {
+  get freeSpace(): string {
     return this.bulkPinningStatus_?.freeSpace || '-1';
   }
 
@@ -211,7 +211,7 @@
    * Returns the total pinned size stored.
    * Used for testing.
    */
-  get contentCacheSize() {
+  get contentCacheSize(): string {
     return this.contentCacheSize_;
   }
 
@@ -219,14 +219,14 @@
    * Returns the current number of listed files.
    * Used for testing.
    */
-  get listedFiles() {
+  get listedFiles(): bigint {
     return this.listedFiles_;
   }
 
   /**
    * Returns the current confirmation dialog showing.
    */
-  get dialogType() {
+  get dialogType(): ConfirmationDialogType {
     return this.dialogType_;
   }
 
@@ -234,25 +234,25 @@
    * Returns the current bulk pinning stage, or 'unknown' if not defined.
    * Used for testing.
    */
-  get stage() {
+  get stage(): Stage|'unknown' {
     return this.bulkPinningStatus_?.stage || 'unknown';
   }
 
-  override connectedCallback() {
+  override connectedCallback(): void {
     super.connectedCallback();
     this.callbackRouter.onServiceUnavailable.addListener(
         this.onServiceUnavailable_.bind(this));
     this.callbackRouter.onProgress.addListener(this.onProgress_.bind(this));
   }
 
-  override disconnectedCallback() {
+  override disconnectedCallback(): void {
     clearInterval(this.updateContentCacheSizeInterval_);
   }
 
   /**
    * Invoked when the underlying service is not longer available.
    */
-  private onServiceUnavailable_() {
+  private onServiceUnavailable_(): void {
     this.bulkPinningServiceUnavailable_ = true;
     clearInterval(this.updateListedFilesInterval_);
     this.updateListedFilesInterval_ = undefined;
@@ -262,7 +262,7 @@
    * Invoked when progress has occurred with the underlying pinning operation.
    * This could also end up in an error state (e.g. no free space).
    */
-  private onProgress_(status: Status) {
+  private onProgress_(status: Status): void {
     this.bulkPinningServiceUnavailable_ = false;
 
     if (status.stage !== this.bulkPinningStatus_?.stage ||
@@ -300,7 +300,7 @@
    * too many changes. When listing files has finished, ensure the interval is
    * cleared and the dialog is closed if it is kept open.
    */
-  private stopUpdatingListedFilesAndClearDialog_() {
+  private stopUpdatingListedFilesAndClearDialog_(): void {
     clearInterval(this.updateListedFilesInterval_);
     this.updateListedFilesInterval_ = undefined;
     this.listedFiles_ = 0n;
@@ -313,7 +313,7 @@
   /**
    * Retrieves the total pinned size of items in Drive and stores the total.
    */
-  private async updateContentCacheSize_() {
+  private async updateContentCacheSize_(): Promise<void> {
     if (!this.contentCacheSize_) {
       // Only set the total pinned size to calculating on the first update.
       this.contentCacheSize_ = ContentCacheSizeType.CALCULATING;
@@ -329,7 +329,7 @@
   /**
    * Invoked when the `prefs.gdata.disabled` preference changes value.
    */
-  private updateDriveDisabled_() {
+  private updateDriveDisabled_(): void {
     const disabled = this.getPref(GOOGLE_DRIVE_DISABLED_PREF).value;
     this.driveDisabled_ = disabled;
     if (disabled) {
@@ -337,7 +337,7 @@
     }
   }
 
-  override currentRouteChanged(route: Route, _oldRoute?: Route) {
+  override currentRouteChanged(route: Route, _oldRoute?: Route): void {
     // Does not apply to this page.
     if (route !== routes.GOOGLE_DRIVE) {
       clearInterval(this.updateContentCacheSizeInterval_);
@@ -350,7 +350,7 @@
   /**
    * Invokes methods when the route is navigated to.
    */
-  onNavigated() {
+  onNavigated(): void {
     this.attemptDeepLink();
     this.pageHandler.calculateRequiredSpace();
     this.updateContentCacheSize_();
@@ -415,7 +415,7 @@
    * pressed, all remaining actions (e.g. Cancel, ESC) should not update the
    * preference.
    */
-  private async onDriveConfirmationDialogClose_(e: CustomEvent) {
+  private async onDriveConfirmationDialogClose_(e: CustomEvent): Promise<void> {
     const closedDialogType = this.dialogType_;
     this.dialogType_ = ConfirmationDialogType.NONE;
     if (!e.detail.accept) {
@@ -467,7 +467,7 @@
    * the dialog.
    */
   private shouldShowConfirmationDialog_(
-      type: ConfirmationDialogType, requestedType: string) {
+      type: ConfirmationDialogType, requestedType: string): boolean {
     return type === requestedType;
   }
 
@@ -475,7 +475,7 @@
    * Spawn a confirmation dialog to the user if they choose to disable the bulk
    * pinning feature, for enabling just update the preference.
    */
-  private onToggleBulkPinning_(e: Event) {
+  private onToggleBulkPinning_(e: Event): void {
     const target = e.target as SettingsToggleButtonElement;
     const newValueAfterToggle =
         !this.getPref(GOOGLE_DRIVE_BULK_PINNING_PREF).value;
@@ -498,7 +498,7 @@
    * ListingFiles) then ensure the toggle isn't enabled, otherwise don't show a
    * dialog and enable immediately.
    */
-  private tryEnableBulkPinning_(target: SettingsToggleButtonElement) {
+  private tryEnableBulkPinning_(target: SettingsToggleButtonElement): void {
     target.checked = false;
 
     // When the device is offline, don't allow the user to enable the toggle.
@@ -536,7 +536,7 @@
   /**
    * Returns true if the bulk pinning preference is disabled.
    */
-  private shouldEnableCleanUpStorageButton_() {
+  private shouldEnableCleanUpStorageButton_(): boolean {
     return !this.getPref(GOOGLE_DRIVE_BULK_PINNING_PREF).value &&
         this.contentCacheSize_ !== ContentCacheSizeType.UNKNOWN &&
         this.contentCacheSize_ !== ContentCacheSizeType.CALCULATING &&
@@ -547,7 +547,7 @@
    * Returns the string used in the confirmation dialog when cleaning the users
    * offline storage, this includes the total GB used by offline files.
    */
-  private getCleanUpStorageConfirmationDialogBody() {
+  private getCleanUpStorageConfirmationDialogBody(): TrustedHTML {
     return this.i18nAdvanced('googleDriveOfflineCleanStorageDialogBody', {
       tags: ['a'],
       substitutions: [
@@ -557,7 +557,7 @@
     });
   }
 
-  private getListingFilesDialogBody_() {
+  private getListingFilesDialogBody_(): string {
     return this.listedFiles_ > 0n ?
         this.i18n(
             'googleDriveFileSyncListingFilesItemsFoundBody',
@@ -569,7 +569,7 @@
    * When the "Clean up storage" button is clicked, should not clean up
    * immediately but show the confirmation dialog first.
    */
-  private async onCleanUpStorage_() {
+  private onCleanUpStorage_(): void {
     this.dialogType_ = ConfirmationDialogType.BULK_PINNING_CLEAN_UP_STORAGE;
   }
 }
diff --git a/chrome/browser/resources/ash/settings/os_files_page/one_drive_browser_proxy.ts b/chrome/browser/resources/ash/settings/os_files_page/one_drive_browser_proxy.ts
index 26daf69..fee4daf3 100644
--- a/chrome/browser/resources/ash/settings/os_files_page/one_drive_browser_proxy.ts
+++ b/chrome/browser/resources/ash/settings/os_files_page/one_drive_browser_proxy.ts
@@ -23,7 +23,7 @@
     return instance || (instance = new OneDriveBrowserProxy());
   }
 
-  static setInstance(proxy: OneDriveBrowserProxy) {
+  static setInstance(proxy: OneDriveBrowserProxy): void {
     instance = proxy;
   }
 }
diff --git a/chrome/browser/resources/ash/settings/os_files_page/one_drive_subpage.ts b/chrome/browser/resources/ash/settings/os_files_page/one_drive_subpage.ts
index 57116a4..3de3cfe 100644
--- a/chrome/browser/resources/ash/settings/os_files_page/one_drive_subpage.ts
+++ b/chrome/browser/resources/ash/settings/os_files_page/one_drive_subpage.ts
@@ -58,17 +58,17 @@
   private userEmailAddress_: string|null;
   private oneDriveProxy_: OneDriveBrowserProxy;
 
-  override connectedCallback() {
+  override connectedCallback(): void {
     super.connectedCallback();
     this.oneDriveProxy_.observer.onODFSMountOrUnmount.addListener(
         this.updateUserEmailAddress_.bind(this));
   }
 
-  updateConnectionStateForTesting(connectionState: string) {
+  updateConnectionStateForTesting(connectionState: string): void {
     this.connectionState_ = connectionState;
   }
 
-  private async updateUserEmailAddress_() {
+  private async updateUserEmailAddress_(): Promise<void> {
     this.connectionState_ = OneDriveConnectionState.LOADING;
     const {email} = await this.oneDriveProxy_.handler.getUserEmailAddress();
     this.userEmailAddress_ = email;
@@ -77,11 +77,11 @@
         OneDriveConnectionState.CONNECTED;
   }
 
-  private isConnected_(connectionState: string) {
+  private isConnected_(connectionState: string): boolean {
     return connectionState === OneDriveConnectionState.CONNECTED;
   }
 
-  private isLoading_(connectionState: string) {
+  private isLoading_(connectionState: string): boolean {
     return connectionState === OneDriveConnectionState.LOADING;
   }
 
@@ -99,7 +99,7 @@
     }
   }
 
-  private connectDisconnectButtonLabel_(connectionState: string) {
+  private connectDisconnectButtonLabel_(connectionState: string): string {
     return this.i18n(
         connectionState === OneDriveConnectionState.CONNECTED ?
             'oneDriveDisconnect' :
diff --git a/chrome/browser/resources/ash/settings/os_files_page/smb_shares_page.ts b/chrome/browser/resources/ash/settings/os_files_page/smb_shares_page.ts
index ccfc4c1c..327afc4 100644
--- a/chrome/browser/resources/ash/settings/os_files_page/smb_shares_page.ts
+++ b/chrome/browser/resources/ash/settings/os_files_page/smb_shares_page.ts
@@ -50,18 +50,18 @@
   /**
    * Overridden from RouteObserverMixin.
    */
-  override currentRouteChanged(route: Route) {
+  override currentRouteChanged(route: Route): void {
     if (route === routes.SMB_SHARES) {
       this.showAddSmbDialog_ = Router.getInstance().getQueryParameters().get(
                                    'showAddShare') === 'true';
     }
   }
 
-  private onAddShareClick_() {
+  private onAddShareClick_(): void {
     this.showAddSmbDialog_ = true;
   }
 
-  private onAddSmbDialogClosed_() {
+  private onAddSmbDialogClosed_(): void {
     this.showAddSmbDialog_ = false;
   }
 }
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/input_page.ts b/chrome/browser/resources/ash/settings/os_languages_page/input_page.ts
index a7651149..29ff97c 100644
--- a/chrome/browser/resources/ash/settings/os_languages_page/input_page.ts
+++ b/chrome/browser/resources/ash/settings/os_languages_page/input_page.ts
@@ -629,8 +629,8 @@
     }
   }
 
-  private shouldShowSpinner_(_item:
-                                 chrome.languageSettingsPrivate.InputMethod) {
+  private shouldShowSpinner_(_item: chrome.languageSettingsPrivate.InputMethod):
+      boolean {
     return this.languagePacksInSettingsEnabled_;
   }
 }
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/classic_background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/classic_background.js
index 148246a..9c1a6cc 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/classic_background.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/classic_background.js
@@ -43,26 +43,6 @@
     });
   }
 
-  /**
-   * Called when a TTS message is received from a page content script.
-   * @param {Object} msg The TTS message.
-   */
-  onTtsMessage(msg) {
-    if (msg['action'] !== 'speak') {
-      return;
-    }
-    // The only caller sending this message is a ChromeVox Classic api client.
-    // Deny empty strings.
-    if (msg['text'] === '') {
-      return;
-    }
-
-    ChromeVox.tts.speak(
-        msg['text'],
-        /** @type {QueueMode} */ (msg['queueMode']),
-        new TtsSpeechProperties(msg['properties']));
-  }
-
   /** Initializes classic background object. */
   static init() {
     const background = new ChromeVoxBackground();
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html
index 1efc2b3..3899c59 100644
--- a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html
+++ b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html
@@ -230,3 +230,9 @@
     </div>
   </template>
 </template>
+
+<template is="dom-if" if="[[isApnRevampEnabled_]]" restamp>
+  <cr-toast id="errorToast" duration="5000">
+    <span id="errorToastMessage">[[errorToastMessage_]]</span>
+  </cr-toast>
+</template>
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js
index 2597cc61..2e50e07c 100644
--- a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js
+++ b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.js
@@ -15,6 +15,7 @@
 import 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
 import 'chrome://resources/cr_elements/cr_page_host_style.css.js';
+import 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
 import 'chrome://resources/cr_elements/icons.html.js';
 import 'chrome://resources/cr_elements/cr_shared_style.css.js';
 import 'chrome://resources/cr_elements/chromeos/cros_color_overrides.css.js';
@@ -145,6 +146,15 @@
       value: false,
       computed: 'computeIsNumCustomApnsLimitReached_(managedProperties_)',
     },
+
+    /**
+     * The message to be displayed in the error toast when shown.
+     * @private
+     */
+    errorToastMessage_: {
+      type: String,
+      value: '',
+    },
   },
 
   /**
@@ -177,6 +187,13 @@
   },
 
   /** @override */
+  ready() {
+    this.addEventListener('show-error-toast', (event) => {
+      this.onShowErrorToast_(event);
+    });
+  },
+
+  /** @override */
   attached() {
     this.browserProxy_ = InternetDetailDialogBrowserProxyImpl.getInstance();
     const dialogArgs = this.browserProxy_.getDialogArguments();
@@ -880,4 +897,16 @@
         this.managedProperties_.typeProperties.cellular.customApnList;
     return !!customApnList && customApnList.length >= MAX_NUM_CUSTOM_APNS;
   },
+
+  /**
+   * @param {!Event} event
+   * @private
+   */
+  onShowErrorToast_(event) {
+    if (!this.isApnRevampEnabled_) {
+      return;
+    }
+    this.errorToastMessage_ = event.detail;
+    this.shadowRoot.querySelector('#errorToast').show();
+  },
 });
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html
index 214017ea..74c1366d 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_page.html
+++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -871,21 +871,42 @@
           <div class="content-settings-header secondary">
             $i18n{siteSettingsMidiDescription}
           </div>
-          <settings-category-default-radio-group
+          <template is="dom-if" if="[[!blockMidiByDefault_]]" no-search>
+            <!-- midi-sysex radio group and exception category -->
+            <settings-category-default-radio-group
               category="[[contentSettingsTypesEnum_.MIDI_DEVICES]]"
               allow-option-label=
                   "$i18n{siteSettingsMidiAllowed}"
               allow-option-icon="settings:midi"
               block-option-label="$i18n{siteSettingsMidiBlocked}"
               block-option-icon="settings:midi-off">
-          </settings-category-default-radio-group>
-          <category-setting-exceptions
+            </settings-category-default-radio-group>
+            <category-setting-exceptions
               category="[[contentSettingsTypesEnum_.MIDI_DEVICES]]"
               read-only-list
               allow-header="$i18n{siteSettingsMidiAllowedExceptions}"
               block-header="$i18n{siteSettingsMidiBlockedExceptions}"
               search-filter="[[searchFilter_]]">
-          </category-setting-exceptions>
+            </category-setting-exceptions>
+          </template>
+          <template is="dom-if" if="[[blockMidiByDefault_]]" no-search>
+            <!-- midi radio group and exception category -->
+            <settings-category-default-radio-group
+              category="[[contentSettingsTypesEnum_.MIDI]]"
+              allow-option-label=
+                  "$i18n{siteSettingsMidiAllowed}"
+              allow-option-icon="settings:midi"
+              block-option-label="$i18n{siteSettingsMidiBlocked}"
+              block-option-icon="settings:midi-off">
+            </settings-category-default-radio-group>
+            <category-setting-exceptions
+              category="[[contentSettingsTypesEnum_.MIDI]]"
+              read-only-list
+              allow-header="$i18n{siteSettingsMidiAllowedExceptions}"
+              block-header="$i18n{siteSettingsMidiBlockedExceptions}"
+              search-filter="[[searchFilter_]]">
+            </category-setting-exceptions>
+          </template>
         </settings-subpage>
       </template>
       <template is="dom-if" route-path="/content/usbDevices" no-search>
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.ts b/chrome/browser/resources/settings/privacy_page/privacy_page.ts
index 41539979..3c73c73 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_page.ts
+++ b/chrome/browser/resources/settings/privacy_page/privacy_page.ts
@@ -209,6 +209,11 @@
         },
       },
 
+      blockMidiByDefault_: {
+        type: Boolean,
+        value: () => loadTimeData.getBoolean('blockMidiByDefault'),
+      },
+
       focusConfig_: {
         type: Object,
         value() {
@@ -332,6 +337,7 @@
   private cookieSettingDescription_: string;
   private enableBlockAutoplayContentSetting_: boolean;
   private blockAutoplayStatus_: BlockAutoplayStatus;
+  private blockMidiByDefault_: boolean;
   private enableFederatedIdentityApiContentSetting_: boolean;
   private enablePaymentHandlerContentSetting_: boolean;
   private enableExperimentalWebPlatformFeatures_: boolean;
diff --git a/chrome/browser/resources/settings/site_settings/constants.ts b/chrome/browser/resources/settings/site_settings/constants.ts
index 8150ceb2..83cac685 100644
--- a/chrome/browser/resources/settings/site_settings/constants.ts
+++ b/chrome/browser/resources/settings/site_settings/constants.ts
@@ -33,6 +33,7 @@
   JAVASCRIPT = 'javascript',
   LOCAL_FONTS = 'local-fonts',
   MIC = 'media-stream-mic',  // AKA Microphone.
+  MIDI = 'midi',
   MIDI_DEVICES = 'midi-sysex',
   MIXEDSCRIPT = 'mixed-script',
   NOTIFICATIONS = 'notifications',
diff --git a/chrome/browser/resources/settings/site_settings/settings_category_default_radio_group.ts b/chrome/browser/resources/settings/site_settings/settings_category_default_radio_group.ts
index 30a5a05..c122da82 100644
--- a/chrome/browser/resources/settings/site_settings/settings_category_default_radio_group.ts
+++ b/chrome/browser/resources/settings/site_settings/settings_category_default_radio_group.ts
@@ -150,6 +150,7 @@
       case ContentSettingsTypes.IDLE_DETECTION:
       case ContentSettingsTypes.LOCAL_FONTS:
       case ContentSettingsTypes.MIC:
+      case ContentSettingsTypes.MIDI:
       case ContentSettingsTypes.MIDI_DEVICES:
       case ContentSettingsTypes.NOTIFICATIONS:
       case ContentSettingsTypes.SERIAL_PORTS:
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page_util.ts b/chrome/browser/resources/settings/site_settings_page/site_settings_page_util.ts
index fc49dc84..8e528c00 100644
--- a/chrome/browser/resources/settings/site_settings_page/site_settings_page_util.ts
+++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page_util.ts
@@ -51,6 +51,7 @@
       return 'siteSettingsFontAccessMidSentence';
     case ContentSettingsTypes.MIC:
       return 'siteSettingsMicMidSentence';
+    case ContentSettingsTypes.MIDI:
     case ContentSettingsTypes.MIDI_DEVICES:
       return 'siteSettingsMidiDevicesMidSentence';
     case ContentSettingsTypes.MIXEDSCRIPT:
diff --git a/chrome/browser/sharesheet/sharesheet_service.cc b/chrome/browser/sharesheet/sharesheet_service.cc
index c7c9310..1550d3a 100644
--- a/chrome/browser/sharesheet/sharesheet_service.cc
+++ b/chrome/browser/sharesheet/sharesheet_service.cc
@@ -298,25 +298,17 @@
 
   // Making a copy because we move |intent_launch_info| out below.
   auto app_id = intent_launch_info[index].app_id;
-  // TODO(crbug.com/1412708): Update when we have the icon effect interface.
-  absl::optional<apps::IconKey> icon_key =
-      app_service_proxy_->app_icon_loader()->GetIconKey(app_id);
-  if (icon_key.has_value()) {
-    if (intent_launch_info[index].is_dlp_blocked) {
-      icon_key->icon_effects |= apps::IconEffects::kBlocked;
-    }
-    app_service_proxy_->LoadIconFromIconKey(
-        app_service_proxy_->AppRegistryCache().GetAppType(app_id), app_id,
-        icon_key.value(), apps::IconType::kStandard, kIconSize,
-        /*allow_placeholder_icon=*/false,
-        base::BindOnce(&SharesheetService::OnIconLoaded,
-                       weak_factory_.GetWeakPtr(),
-                       std::move(intent_launch_info), std::move(targets), index,
-                       std::move(callback)));
-  } else {
-    OnIconLoaded(std::move(intent_launch_info), std::move(targets), index,
-                 std::move(callback), std::make_unique<apps::IconValue>());
+  uint32_t icon_effects = app_service_proxy_->GetIconEffects(app_id);
+  if (intent_launch_info[index].is_dlp_blocked) {
+    icon_effects |= apps::IconEffects::kBlocked;
   }
+  app_service_proxy_->LoadIconWithIconEffects(
+      app_service_proxy_->AppRegistryCache().GetAppType(app_id), app_id,
+      icon_effects, apps::IconType::kStandard, kIconSize,
+      /*allow_placeholder_icon=*/false,
+      base::BindOnce(&SharesheetService::OnIconLoaded,
+                     weak_factory_.GetWeakPtr(), std::move(intent_launch_info),
+                     std::move(targets), index, std::move(callback)));
 }
 
 void SharesheetService::OnIconLoaded(
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index ea7db3f..b453e18 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -3129,6 +3129,8 @@
       "webui/ash/login/welcome_screen_handler.h",
       "webui/ash/login/wrong_hwid_screen_handler.cc",
       "webui/ash/login/wrong_hwid_screen_handler.h",
+      "webui/ash/mako/mako_bubble_coordinator.cc",
+      "webui/ash/mako/mako_bubble_coordinator.h",
       "webui/ash/mako/mako_ui.cc",
       "webui/ash/mako/mako_ui.h",
       "webui/ash/mako/url_constants.cc",
diff --git a/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinator.java b/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinator.java
index f6b085b..196f0d7 100644
--- a/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinator.java
+++ b/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinator.java
@@ -54,10 +54,6 @@
      * @param activity The activity hosting this page.
      * @param account The account that will be used for the reauthentication challenge, or null
      *                if reauthentication is not needed.
-     *
-     * TODO (crbug.com/1481799)
-     * Refactor to take in a Context instead of an Activity if
-     * AccountManagerFacade#confirmCredentials no longer takes an Activity,
      */
     public DeviceLockCoordinator(Delegate delegate, WindowAndroid windowAndroid, Activity activity,
             @Nullable Account account) {
diff --git a/chrome/browser/ui/android/plus_addresses/plus_address_creation_view_android_browsertest.cc b/chrome/browser/ui/android/plus_addresses/plus_address_creation_view_android_browsertest.cc
new file mode 100644
index 0000000..cdabc3de
--- /dev/null
+++ b/chrome/browser/ui/android/plus_addresses/plus_address_creation_view_android_browsertest.cc
@@ -0,0 +1,152 @@
+// 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 "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
+#include "base/test/mock_callback.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/plus_addresses/plus_address_service_factory.h"
+#include "chrome/browser/profiles/profile_test_util.h"
+#include "chrome/browser/ui/android/plus_addresses/plus_address_creation_controller_android.h"
+#include "chrome/test/base/android/android_browser_test.h"
+#include "chrome/test/base/chrome_test_utils.h"
+#include "components/plus_addresses/features.h"
+#include "components/plus_addresses/plus_address_service.h"
+#include "content/public/test/browser_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace plus_addresses {
+
+namespace {
+
+constexpr char kFakeEmailAddressForCallback[] = "plus+plus@plus.plus";
+
+// Used to control the behavior of the controller's `plus_address_service_`
+// (though mocking would also be fine). Most importantly, this avoids the
+// requirement to mock the identity portions of the `PlusAddressService`.
+class FakePlusAddressService : public PlusAddressService {
+ public:
+  FakePlusAddressService() = default;
+
+  void OfferPlusAddressCreation(const url::Origin& origin,
+                                PlusAddressCallback callback) override {
+    std::move(callback).Run(kFakeEmailAddressForCallback);
+  }
+
+  absl::optional<std::string> GetPrimaryEmail() override {
+    return "plus+primary@plus.plus";
+  }
+};
+}  // namespace
+
+// TODO(crbug.com/1467623): Consolidate android/desktop controllers, and
+// presumably switch to the `PlatformBrowserTest` pattern.
+class PlusAddressCreationViewAndroidBrowserTest : public AndroidBrowserTest {
+ public:
+  PlusAddressCreationViewAndroidBrowserTest()
+      : override_profile_selections_(
+            PlusAddressServiceFactory::GetInstance(),
+            PlusAddressServiceFactory::CreateProfileSelections()) {}
+
+  void SetUpOnMainThread() override {
+    AndroidBrowserTest::SetUpOnMainThread();
+    PlusAddressServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+        chrome_test_utils::GetActiveWebContents(this)->GetBrowserContext(),
+        base::BindRepeating(&PlusAddressCreationViewAndroidBrowserTest::
+                                PlusAddressServiceTestFactory,
+                            base::Unretained(this)));
+  }
+
+  std::unique_ptr<KeyedService> PlusAddressServiceTestFactory(
+      content::BrowserContext* context) {
+    return std::make_unique<FakePlusAddressService>();
+  }
+
+ protected:
+  base::test::ScopedFeatureList features_{kFeature};
+  profiles::testing::ScopedProfileSelectionsForFactoryTesting
+      override_profile_selections_;
+};
+
+IN_PROC_BROWSER_TEST_F(PlusAddressCreationViewAndroidBrowserTest, OfferUi) {
+  PlusAddressCreationControllerAndroid::CreateForWebContents(
+      chrome_test_utils::GetActiveWebContents(this));
+  PlusAddressCreationControllerAndroid* controller =
+      PlusAddressCreationControllerAndroid::FromWebContents(
+          chrome_test_utils::GetActiveWebContents(this));
+  base::MockOnceCallback<void(const std::string&)> callback;
+  controller->OfferCreation(
+      url::Origin::Create(GURL("https://mattwashere.com")), callback.Get());
+
+  EXPECT_CALL(callback, Run(kFakeEmailAddressForCallback)).Times(1);
+  controller->OnConfirmed();
+}
+
+IN_PROC_BROWSER_TEST_F(PlusAddressCreationViewAndroidBrowserTest,
+                       DoubleOfferUi) {
+  PlusAddressCreationControllerAndroid::CreateForWebContents(
+      chrome_test_utils::GetActiveWebContents(this));
+  PlusAddressCreationControllerAndroid* controller =
+      PlusAddressCreationControllerAndroid::FromWebContents(
+          chrome_test_utils::GetActiveWebContents(this));
+
+  // First, offer creation like normal.
+  base::MockOnceCallback<void(const std::string&)> callback;
+  controller->OfferCreation(
+      url::Origin::Create(GURL("https://mattwashere.com")), callback.Get());
+
+  // Then, offer creation a second time, without first dismissing the UI.
+  base::MockOnceCallback<void(const std::string&)> second_callback;
+  controller->OfferCreation(
+      url::Origin::Create(GURL("https://mattwashere.com")),
+      second_callback.Get());
+
+  EXPECT_CALL(callback, Run(kFakeEmailAddressForCallback)).Times(1);
+  EXPECT_CALL(second_callback, Run).Times(0);
+  controller->OnConfirmed();
+}
+
+IN_PROC_BROWSER_TEST_F(PlusAddressCreationViewAndroidBrowserTest, Cancel) {
+  PlusAddressCreationControllerAndroid::CreateForWebContents(
+      chrome_test_utils::GetActiveWebContents(this));
+  PlusAddressCreationControllerAndroid* controller =
+      PlusAddressCreationControllerAndroid::FromWebContents(
+          chrome_test_utils::GetActiveWebContents(this));
+
+  // First, offer creation.
+  base::MockOnceCallback<void(const std::string&)> callback;
+  controller->OfferCreation(
+      url::Origin::Create(GURL("https://mattwashere.com")), callback.Get());
+  // Then, cancel, and ensure that `callback` is not run.
+  EXPECT_CALL(callback, Run).Times(0);
+  controller->OnCanceled();
+}
+
+IN_PROC_BROWSER_TEST_F(PlusAddressCreationViewAndroidBrowserTest,
+                       CancelThenShowAgain) {
+  PlusAddressCreationControllerAndroid::CreateForWebContents(
+      chrome_test_utils::GetActiveWebContents(this));
+  PlusAddressCreationControllerAndroid* controller =
+      PlusAddressCreationControllerAndroid::FromWebContents(
+          chrome_test_utils::GetActiveWebContents(this));
+
+  // First, offer creation.
+  base::MockOnceCallback<void(const std::string&)> callback;
+  controller->OfferCreation(
+      url::Origin::Create(GURL("https://mattwashere.com")), callback.Get());
+  // Then, cancel, destroy, and ensure that `callback` is not run.
+  EXPECT_CALL(callback, Run).Times(0);
+  controller->OnCanceled();
+  controller->OnDialogDestroyed();
+
+  // After re-showing, confirmation should run `second_callback`.
+  base::MockOnceCallback<void(const std::string&)> second_callback;
+  controller->OfferCreation(
+      url::Origin::Create(GURL("https://mattwashere.com")),
+      second_callback.Get());
+  EXPECT_CALL(second_callback, Run(kFakeEmailAddressForCallback)).Times(1);
+  controller->OnConfirmed();
+}
+
+}  //  namespace plus_addresses
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetTest.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetTest.java
index d86fa54..a43993e 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetTest.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetTest.java
@@ -926,11 +926,6 @@
             mLaunched = true;
         }
 
-        @Override
-        public void presentDeviceLockChallenge(Context context,
-                boolean requireDeviceLockReauthentication, WindowAndroid windowAndroid,
-                Runnable callback) {}
-
         boolean isLaunched() {
             return mLaunched;
         }
diff --git a/chrome/browser/ui/ash/app_access_notifier.cc b/chrome/browser/ui/ash/app_access_notifier.cc
index 539f930..38e10391 100644
--- a/chrome/browser/ui/ash/app_access_notifier.cc
+++ b/chrome/browser/ui/ash/app_access_notifier.cc
@@ -55,8 +55,9 @@
     absl::optional<std::u16string> name;
     registry_cache->ForOneApp(app,
                               [&app_id, &name](const apps::AppUpdate& update) {
-                                if (update.AppId() == app_id)
+                                if (update.AppId() == app_id) {
                                   name = base::UTF8ToUTF16(update.ShortName());
+                                }
                               });
     if (name.has_value())
       return name;
@@ -255,8 +256,9 @@
     return name;
 
   registry_cache->ForEachApp([&app_id, &name](const apps::AppUpdate& update) {
-    if (update.AppId() == app_id)
+    if (update.AppId() == app_id) {
       name = base::UTF8ToUTF16(update.ShortName());
+    }
   });
   return name;
 }
diff --git a/chrome/browser/ui/ash/arc_open_url_delegate_impl.cc b/chrome/browser/ui/ash/arc_open_url_delegate_impl.cc
index 992da40..6acc710f 100644
--- a/chrome/browser/ui/ash/arc_open_url_delegate_impl.cc
+++ b/chrome/browser/ui/ash/arc_open_url_delegate_impl.cc
@@ -41,7 +41,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/settings_window_manager_chromeos.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/browser/webshare/prepare_directory_task.h"
 #include "chrome/common/webui_url_constants.h"
@@ -54,6 +53,7 @@
 #include "components/services/app_service/public/cpp/intent_util.h"
 #include "components/services/app_service/public/cpp/types_util.h"
 #include "components/user_manager/user_manager.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/common/url_constants.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "net/base/filename_util.h"
@@ -341,7 +341,7 @@
   if (!profile)
     return;
 
-  absl::optional<web_app::AppId> app_id =
+  absl::optional<webapps::AppId> app_id =
       web_app::IsWebAppsCrosapiEnabled()
           ? FindWebAppForURL(profile, url)
           : web_app::FindInstalledAppWithUrlInScope(profile, url,
@@ -476,7 +476,7 @@
   if (!profile)
     return;
 
-  web_app::AppId app_id =
+  webapps::AppId app_id =
       web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, start_url);
 
   bool app_installed = false;
diff --git a/chrome/browser/ui/ash/chrome_new_window_client.cc b/chrome/browser/ui/ash/chrome_new_window_client.cc
index 11d487b8..687c294 100644
--- a/chrome/browser/ui/ash/chrome_new_window_client.cc
+++ b/chrome/browser/ui/ash/chrome_new_window_client.cc
@@ -59,7 +59,6 @@
 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
 #include "chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_id_constants.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
@@ -76,6 +75,7 @@
 #include "components/url_formatter/url_fixer.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/constants.h"
diff --git a/chrome/browser/ui/ash/float_controller_browsertest.cc b/chrome/browser/ui/ash/float_controller_browsertest.cc
index 15a51e9..5912d7e6 100644
--- a/chrome/browser/ui/ash/float_controller_browsertest.cc
+++ b/chrome/browser/ui/ash/float_controller_browsertest.cc
@@ -49,7 +49,7 @@
 }
 
 void CreateSystemWebApp(Profile* profile, ash::SystemWebAppType app_type) {
-  web_app::AppId app_id = *ash::GetAppIdForSystemWebApp(profile, app_type);
+  webapps::AppId app_id = *ash::GetAppIdForSystemWebApp(profile, app_type);
   apps::AppLaunchParams params(
       app_id, apps::LaunchContainer::kLaunchContainerWindow,
       WindowOpenDisposition::NEW_WINDOW, apps::LaunchSource::kFromTest);
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_browsertest.cc b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_browsertest.cc
index 8f47d05d..0566843 100644
--- a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_browsertest.cc
@@ -120,9 +120,8 @@
  public:
   class MockFilesController : public policy::DlpFilesControllerAsh {
    public:
-    explicit MockFilesController(const policy::DlpRulesManager& rules_manager,
-                                 Profile* profile)
-        : DlpFilesControllerAsh(rules_manager, profile) {}
+    explicit MockFilesController(const policy::DlpRulesManager& rules_manager)
+        : DlpFilesControllerAsh(rules_manager) {}
     ~MockFilesController() override = default;
 
     MOCK_METHOD(bool,
@@ -131,14 +130,6 @@
                 (override));
   };
 
-  void TearDownOnMainThread() override {
-    // The files controller must be destroyed before the profile since it's
-    // holding a pointer to it.
-    mock_files_controller_.reset();
-
-    SharesheetBubbleViewBrowserTest::TearDownOnMainThread();
-  }
-
   void SetupRulesManager(bool is_dlp_blocked) {
     policy::DlpRulesManagerFactory::GetInstance()->SetTestingFactory(
         browser()->profile(),
@@ -149,6 +140,10 @@
 
     ON_CALL(*rules_manager_, IsFilesPolicyEnabled)
         .WillByDefault(testing::Return(true));
+    mock_files_controller_ =
+        std::make_unique<MockFilesController>(*rules_manager_);
+    ON_CALL(*rules_manager_, GetDlpFilesController)
+        .WillByDefault(testing::Return(mock_files_controller_.get()));
 
     EXPECT_CALL(*mock_files_controller_.get(), IsLaunchBlocked)
         .WillOnce(testing::Return(is_dlp_blocked));
@@ -216,12 +211,6 @@
     auto dlp_rules_manager =
         std::make_unique<testing::NiceMock<policy::MockDlpRulesManager>>();
     rules_manager_ = dlp_rules_manager.get();
-
-    mock_files_controller_ = std::make_unique<MockFilesController>(
-        *rules_manager_, Profile::FromBrowserContext(context));
-    ON_CALL(*rules_manager_, GetDlpFilesController)
-        .WillByDefault(testing::Return(mock_files_controller_.get()));
-
     return dlp_rules_manager;
   }
 
diff --git a/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_shelf_item_controller.cc b/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_shelf_item_controller.cc
index a007879..7969e1f1 100644
--- a/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_shelf_item_controller.cc
+++ b/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_shelf_item_controller.cc
@@ -44,9 +44,10 @@
   apps::AppServiceProxy* proxy = apps::AppServiceProxyFactory::GetForProfile(
       ProfileManager::GetPrimaryUserProfile());
 
-  icon_loader_releaser_ = proxy->LoadIconFromIconKey(
+  icon_loader_releaser_ = proxy->LoadIconWithIconEffects(
       apps::AppType::kStandaloneBrowserChromeApp, shelf_id.app_id,
-      apps::IconKey(), apps::IconType::kStandard, /*size_hint_in_dip=*/48,
+      apps::IconEffects::kNone, apps::IconType::kStandard,
+      /*size_hint_in_dip=*/48,
       /*allow_placeholder_icon=*/false,
       base::BindOnce(
           &StandaloneBrowserExtensionAppShelfItemController::OnLoadIcon,
diff --git a/chrome/browser/ui/ash/thumbnail_loader.cc b/chrome/browser/ui/ash/thumbnail_loader.cc
index 417fe30..aa6ce2f 100644
--- a/chrome/browser/ui/ash/thumbnail_loader.cc
+++ b/chrome/browser/ui/ash/thumbnail_loader.cc
@@ -55,7 +55,7 @@
 
 // Returns whether the given `file_path` is supported by the `ThumbnailLoader`.
 bool IsSupported(const base::FilePath& file_path) {
-  constexpr std::array<std::pair<const char*, const char*>, 24>
+  constexpr std::array<std::pair<const char*, const char*>, 25>
       kFileMatchPatterns = {{
           // Document types ----------------------------------------------------
           {
@@ -95,6 +95,10 @@
               /*extension=*/"(?i)\\.svg$",
               /*mime_type=*/"(?i)image\\/svg\\+xml",
           },
+          {
+              /*extension=*/"(?i)\\.avif$",
+              /*mime_type=*/"(?i)image\\/avif",
+          },
           // Raw types ---------------------------------------------------------
           {
               /*extension=*/"(?i)\\.arw$",
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index fc0edb4c..b97f57a77 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -73,7 +73,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/common/buildflags.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
@@ -99,6 +98,7 @@
 #include "components/strings/grit/components_strings.h"
 #include "components/translate/core/browser/language_state.h"
 #include "components/translate/core/common/language_detection_details.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/favicon_status.h"
 #include "content/public/browser/host_zoom_map.h"
@@ -1249,7 +1249,7 @@
   ASSERT_EQ(1, browser()->tab_strip_model()->count());
 
   // Load an app.
-  web_app::AppId app_id = web_app::test::InstallDummyWebApp(
+  webapps::AppId app_id = web_app::test::InstallDummyWebApp(
       browser()->profile(), "testapp", GURL("https://testapp.com"));
   base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
   command_line.AppendSwitchASCII(switches::kAppId, app_id);
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index ff28722..5d63864f 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -103,7 +103,6 @@
 #include "chrome/browser/upgrade_detector/upgrade_detector.h"
 #include "chrome/browser/web_applications/web_app_constants.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
@@ -145,6 +144,7 @@
 #include "components/translate/core/common/translate_constants.h"
 #include "components/user_education/common/feature_promo_controller.h"
 #include "components/web_modal/web_contents_modal_dialog_manager.h"
+#include "components/webapps/common/web_app_id.h"
 #include "components/zoom/page_zoom.h"
 #include "components/zoom/zoom_controller.h"
 #include "content/public/browser/browsing_data_remover.h"
@@ -866,7 +866,7 @@
 #if BUILDFLAG(IS_MAC)
   // Web apps should open a window to their launch page.
   if (browser->app_controller()) {
-    const web_app::AppId app_id = browser->app_controller()->app_id();
+    const webapps::AppId app_id = browser->app_controller()->app_id();
 
     auto launch_container = apps::LaunchContainer::kLaunchContainerWindow;
 
diff --git a/chrome/browser/ui/browser_dialogs.h b/chrome/browser/ui/browser_dialogs.h
index dd95d83..b6214fc 100644
--- a/chrome/browser/ui/browser_dialogs.h
+++ b/chrome/browser/ui/browser_dialogs.h
@@ -16,10 +16,10 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/ui/bookmarks/bookmark_editor.h"
 #include "chrome/browser/web_applications/web_app_callback_app_identity.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chrome/browser/web_applications/web_app_uninstall_dialog_user_options.h"
 #include "components/webapps/browser/installable/installable_metrics.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/browser/bluetooth_delegate.h"
 #include "content/public/browser/login_delegate.h"
 #include "extensions/buildflags/buildflags.h"
@@ -208,7 +208,7 @@
 // to uninstall an installed dPWA from a variety of OS surfaces and chrome.
 void ShowWebAppUninstallDialog(
     Profile* profile,
-    const web_app::AppId& app_id,
+    const webapps::AppId& app_id,
     webapps::WebappUninstallSource uninstall_source,
     gfx::NativeWindow parent,
     std::map<SquareSizePx, SkBitmap> icon_bitmaps,
@@ -226,14 +226,14 @@
 void ShowWebAppProtocolLaunchDialog(
     const GURL& url,
     Profile* profile,
-    const web_app::AppId& app_id,
+    const webapps::AppId& app_id,
     WebAppLaunchAcceptanceCallback close_callback);
 
 // Shows the pre-launch dialog for a file handling PWA launch. The user can
 // allow or block the launch.
 void ShowWebAppFileLaunchDialog(const std::vector<base::FilePath>& file_paths,
                                 Profile* profile,
-                                const web_app::AppId& app_id,
+                                const webapps::AppId& app_id,
                                 WebAppLaunchAcceptanceCallback close_callback);
 #endif  // !BUILDFLAG(IS_ANDROID)
 
diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc
index c0aaf81..e76824b 100644
--- a/chrome/browser/ui/browser_navigator.cc
+++ b/chrome/browser/ui/browser_navigator.cc
@@ -182,7 +182,7 @@
   Profile* profile = params.initiating_profile;
 
   if (params.open_pwa_window_if_possible) {
-    absl::optional<web_app::AppId> app_id =
+    absl::optional<webapps::AppId> app_id =
         web_app::FindInstalledAppWithUrlInScope(profile, params.url,
                                                 /*window_only=*/true);
     if (!app_id && params.force_open_pwa_window) {
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
index d956bf5..dd01e3f65 100644
--- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc
+++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -47,7 +47,6 @@
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
 #include "chrome/browser/web_applications/web_app_constants.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chrome/browser/web_applications/web_app_install_manager.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
@@ -57,6 +56,7 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/sessions/core/tab_restore_service.h"
 #include "components/webapps/browser/installable/installable_metrics.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/browser/child_process_security_policy.h"
 #include "content/public/browser/context_menu_params.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/ui/extensions/notifications_custom_bindings_browsertest.cc b/chrome/browser/ui/extensions/notifications_custom_bindings_browsertest.cc
new file mode 100644
index 0000000..97ac006
--- /dev/null
+++ b/chrome/browser/ui/extensions/notifications_custom_bindings_browsertest.cc
@@ -0,0 +1,77 @@
+// 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 "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "base/strings/strcat.h"
+#include "base/strings/stringprintf.h"
+#include "base/threading/thread_restrictions.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/test/base/chrome_test_utils.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+
+class NotificationsCustomBindingsBrowserTest : public InProcessBrowserTest {
+ public:
+  NotificationsCustomBindingsBrowserTest(
+      const NotificationsCustomBindingsBrowserTest&) = delete;
+  NotificationsCustomBindingsBrowserTest& operator=(
+      const NotificationsCustomBindingsBrowserTest&) = delete;
+  ~NotificationsCustomBindingsBrowserTest() override = default;
+
+ protected:
+  NotificationsCustomBindingsBrowserTest() = default;
+
+  virtual void RunTest(const std::string& trigger) {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    base::PathService::Get(base::DIR_SOURCE_ROOT, &src_root_);
+    content::WebContents* web_contents =
+        chrome_test_utils::GetActiveWebContents(this);
+    LoadLibrary(
+        "chrome/renderer/resources/extensions/notifications_test_util.js",
+        web_contents);
+    LoadLibrary(
+        "chrome/renderer/resources/extensions/notifications_custom_bindings.js",
+        web_contents);
+    LoadLibrary(
+        "chrome/renderer/resources/extensions/"
+        "notifications_custom_bindings_test.js",
+        web_contents);
+
+    ASSERT_TRUE(ExecJs(web_contents->GetPrimaryMainFrame(), trigger));
+  }
+
+ private:
+  void LoadLibrary(const std::string& path,
+                   content::WebContents* web_contents) {
+    base::FilePath full_path =
+        base::MakeAbsoluteFilePath(src_root_.AppendASCII(path));
+    std::string library_content;
+    if (!base::ReadFileToString(full_path, &library_content)) {
+      FAIL() << "Failed reading " << path;
+    }
+    ASSERT_TRUE(ExecJs(web_contents->GetPrimaryMainFrame(), library_content));
+  }
+
+  base::FilePath src_root_;
+};
+
+IN_PROC_BROWSER_TEST_F(NotificationsCustomBindingsBrowserTest,
+                       TestImageDataSetter) {
+  RunTest("testImageDataSetter()");
+}
+
+IN_PROC_BROWSER_TEST_F(NotificationsCustomBindingsBrowserTest,
+                       TestGetUrlSpecs) {
+  RunTest("testGetUrlSpecs()");
+}
+
+IN_PROC_BROWSER_TEST_F(NotificationsCustomBindingsBrowserTest,
+                       TestGetUrlSpecsScaled) {
+  RunTest("testGetUrlSpecsScaled()");
+}
diff --git a/chrome/browser/ui/intent_picker_tab_helper.cc b/chrome/browser/ui/intent_picker_tab_helper.cc
index 66dc3054..44173438 100644
--- a/chrome/browser/ui/intent_picker_tab_helper.cc
+++ b/chrome/browser/ui/intent_picker_tab_helper.cc
@@ -471,10 +471,10 @@
 }
 
 void IntentPickerTabHelper::OnWebAppWillBeUninstalled(
-    const web_app::AppId& app_id) {
+    const webapps::AppId& app_id) {
   // WebAppTabHelper has an app_id but it is reset during
   // OnWebAppWillBeUninstalled so using FindAppWithUrlInScope.
-  absl::optional<web_app::AppId> local_app_id =
+  absl::optional<webapps::AppId> local_app_id =
       registrar_->FindAppWithUrlInScope(web_contents()->GetLastCommittedURL());
   if (app_id == local_app_id)
     ShowOrHideIcon(web_contents(), /*should_show_icon=*/false);
diff --git a/chrome/browser/ui/intent_picker_tab_helper.h b/chrome/browser/ui/intent_picker_tab_helper.h
index dffb51a..994cd7e 100644
--- a/chrome/browser/ui/intent_picker_tab_helper.h
+++ b/chrome/browser/ui/intent_picker_tab_helper.h
@@ -119,7 +119,7 @@
       content::NavigationHandle* navigation_handle) override;
 
   // web_app::WebAppInstallManagerObserver:
-  void OnWebAppWillBeUninstalled(const web_app::AppId& app_id) override;
+  void OnWebAppWillBeUninstalled(const webapps::AppId& app_id) override;
   void OnWebAppInstallManagerDestroyed() override;
 
   const raw_ptr<web_app::WebAppRegistrar, DanglingUntriaged> registrar_;
diff --git a/chrome/browser/ui/prevent_close_test_base.cc b/chrome/browser/ui/prevent_close_test_base.cc
index b4d08ba..d338400 100644
--- a/chrome/browser/ui/prevent_close_test_base.cc
+++ b/chrome/browser/ui/prevent_close_test_base.cc
@@ -12,7 +12,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_id_constants.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chrome/common/chrome_features.h"
@@ -21,6 +20,7 @@
 #include "components/policy/core/common/mock_configuration_policy_provider.h"
 #include "components/policy/core/common/policy_map.h"
 #include "components/policy/policy_constants.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/test/browser_test.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "ui/base/window_open_disposition.h"
@@ -59,16 +59,16 @@
 }
 
 void PreventCloseTestBase::InstallPWA(const GURL& app_url,
-                                      const web_app::AppId& app_id) {
+                                      const webapps::AppId& app_id) {
   auto web_app_info = std::make_unique<web_app::WebAppInstallInfo>();
   web_app_info->start_url = app_url;
   web_app_info->scope = app_url.GetWithoutFilename();
-  web_app::AppId installed_app_id = web_app::test::InstallWebApp(
+  webapps::AppId installed_app_id = web_app::test::InstallWebApp(
       browser()->profile(), std::move(web_app_info));
   EXPECT_EQ(app_id, installed_app_id);
 }
 
-Browser* PreventCloseTestBase::LaunchPWA(const web_app::AppId& app_id,
+Browser* PreventCloseTestBase::LaunchPWA(const webapps::AppId& app_id,
                                          bool launch_in_window) {
   return launch_in_window
              ? web_app::LaunchWebAppBrowserAndWait(
diff --git a/chrome/browser/ui/prevent_close_test_base.h b/chrome/browser/ui/prevent_close_test_base.h
index 07374d16..ef91fec 100644
--- a/chrome/browser/ui/prevent_close_test_base.h
+++ b/chrome/browser/ui/prevent_close_test_base.h
@@ -9,8 +9,8 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/values.h"
 #include "chrome/browser/policy/policy_test_utils.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "components/policy/core/common/mock_configuration_policy_provider.h"
+#include "components/webapps/common/web_app_id.h"
 
 #if BUILDFLAG(IS_WIN)
 #include "base/base_paths_win.h"
@@ -34,8 +34,8 @@
 
   void SetWebAppSettings(base::StringPiece config);
   void ClearWebAppSettings();
-  void InstallPWA(const GURL& app_url, const web_app::AppId& app_id);
-  Browser* LaunchPWA(const web_app::AppId& app_id, bool launch_in_window);
+  void InstallPWA(const GURL& app_url, const webapps::AppId& app_id);
+  Browser* LaunchPWA(const webapps::AppId& app_id, bool launch_in_window);
   base::Value ReturnPolicyValueFromJson(base::StringPiece policy);
 
   Profile* profile();
diff --git a/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc b/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc
index 2bf96db..7d4a1ec 100644
--- a/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc
+++ b/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc
@@ -104,7 +104,7 @@
   EXPECT_EQ(1u, GetNumberOfSettingsWindows());
 
   // Launching via LaunchService should also de-dupe to the same browser.
-  web_app::AppId settings_app_id = *ash::GetAppIdForSystemWebApp(
+  webapps::AppId settings_app_id = *ash::GetAppIdForSystemWebApp(
       browser()->profile(), ash::SystemWebAppType::SETTINGS);
   content::WebContents* contents =
       apps::AppServiceProxyFactory::GetForProfile(browser()->profile())
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
index 49dac07d..8d00cc0 100644
--- a/chrome/browser/ui/tab_helpers.cc
+++ b/chrome/browser/ui/tab_helpers.cc
@@ -276,6 +276,10 @@
 #include "chrome/browser/supervised_user/supervised_user_navigation_observer.h"
 #endif
 
+#if !BUILDFLAG(IS_ANDROID)
+#include "chrome/browser/privacy_sandbox/tracking_protection_notice_service.h"
+#endif
+
 using content::WebContents;
 
 namespace {
@@ -552,6 +556,13 @@
   SadTabHelper::CreateForWebContents(web_contents);
   SearchTabHelper::CreateForWebContents(web_contents);
   TabDialogs::CreateForWebContents(web_contents);
+#if !BUILDFLAG(IS_ANDROID)
+  if (privacy_sandbox::TrackingProtectionNoticeService::TabHelper::
+          IsHelperNeeded(profile)) {
+    privacy_sandbox::TrackingProtectionNoticeService::TabHelper::
+        CreateForWebContents(web_contents);
+  }
+#endif
   HighEfficiencyChipTabHelper::CreateForWebContents(web_contents);
   if (base::FeatureList::IsEnabled(
           performance_manager::features::kMemoryUsageInHovercards)) {
diff --git a/chrome/browser/ui/tabs/organization/tab_organization.cc b/chrome/browser/ui/tabs/organization/tab_organization.cc
index 6de7b5c..c4c40f6 100644
--- a/chrome/browser/ui/tabs/organization/tab_organization.cc
+++ b/chrome/browser/ui/tabs/organization/tab_organization.cc
@@ -10,6 +10,10 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 
+namespace {
+constexpr int kMinValidTabsForOrganizing = 2;
+}
+
 TabOrganization::TabOrganization(
     TabDatas tab_datas,
     std::vector<std::u16string> names,
@@ -33,6 +37,20 @@
   return u"";
 }
 
+bool TabOrganization::IsValidForOrganizing() const {
+  // there must be at least 2 tabs that are valid for organization.
+  int valid_tab_count = 0;
+  for (const std::unique_ptr<TabData>& tab_data : tab_datas_) {
+    if (tab_data->IsValidForOrganizing()) {
+      valid_tab_count++;
+      if (valid_tab_count >= kMinValidTabsForOrganizing) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 // TODO(1469128) Add UKM/UMA Logging on user add.
 void TabOrganization::AddTabData(std::unique_ptr<TabData> tab_data) {
   tab_datas_.emplace_back(std::move(tab_data));
diff --git a/chrome/browser/ui/tabs/organization/tab_organization.h b/chrome/browser/ui/tabs/organization/tab_organization.h
index 09285e58..b02f6d37 100644
--- a/chrome/browser/ui/tabs/organization/tab_organization.h
+++ b/chrome/browser/ui/tabs/organization/tab_organization.h
@@ -37,6 +37,8 @@
   const absl::optional<UserChoice> choice() const { return choice_; }
   const std::u16string GetDisplayName() const;
 
+  bool IsValidForOrganizing() const;
+
   void AddTabData(std::unique_ptr<TabData> tab_data);
   void RemoveTabData(TabData::TabID id);
   void SetCurrentName(absl::variant<size_t, std::u16string> new_current_name);
diff --git a/chrome/browser/ui/tabs/organization/tab_organization_unittest.cc b/chrome/browser/ui/tabs/organization/tab_organization_unittest.cc
index 79c2ac2..e0c7c16 100644
--- a/chrome/browser/ui/tabs/organization/tab_organization_unittest.cc
+++ b/chrome/browser/ui/tabs/organization/tab_organization_unittest.cc
@@ -48,9 +48,18 @@
                                                              nullptr);
   }
 
+  GURL GetUniqueTestURL() {
+    static int offset = 1;
+    GURL url("chrome://page_" + base::NumberToString(offset));
+    offset++;
+    return url;
+  }
+
   content::WebContents* AddTab(TabStripModel* tab_strip_model = nullptr) {
     std::unique_ptr<content::WebContents> contents_unique_ptr =
         CreateWebContents();
+    content::WebContentsTester::For(contents_unique_ptr.get())
+        ->NavigateAndCommit(GURL(GetUniqueTestURL()));
     content::WebContents* content_ptr = contents_unique_ptr.get();
     if (!tab_strip_model) {
       tab_strip_model = tab_strip_model_.get();
@@ -60,6 +69,14 @@
     return content_ptr;
   }
 
+  void InvalidateTabData(TabData* tab_data) {
+    // TabData is invalidated from new URL which are different from their
+    // original URL. as long as the original URL was created via
+    // GetUniqueTestURL this will invalidate.
+    content::WebContentsTester::For(tab_data->web_contents())
+        ->NavigateAndCommit(GetUniqueTestURL());
+  }
+
  private:
   content::BrowserTaskEnvironment task_environment_;
   content::RenderViewHostTestEnabler rvh_test_enabler_;
@@ -86,7 +103,7 @@
 // Check that TabData isn't updated when the tabstrip updates.
 TEST_F(TabOrganizationTest, TabDataTabStripTabUpdatingURL) {
   content::WebContents* web_contents = AddTab();
-  GURL old_gurl = GURL("chrome://page_1");
+  GURL old_gurl = GURL(GetUniqueTestURL());
   content::WebContentsTester::For(web_contents)->NavigateAndCommit(old_gurl);
 
   std::unique_ptr<TabData> tab_data =
@@ -94,7 +111,7 @@
 
   // When updating tab URL, the TabData shouldn't update.
   content::WebContentsTester::For(web_contents)
-      ->NavigateAndCommit(GURL("chrome://page_2"));
+      ->NavigateAndCommit(GURL(GetUniqueTestURL()));
   EXPECT_NE(tab_data->original_url(), web_contents->GetLastCommittedURL());
 }
 
@@ -116,8 +133,6 @@
 
 TEST_F(TabOrganizationTest, TabDataOnDestroyWebContentsSetToNull) {
   content::WebContents* web_contents = AddTab();
-  GURL old_gurl = GURL("chrome://page_1");
-  content::WebContentsTester::For(web_contents)->NavigateAndCommit(old_gurl);
 
   std::unique_ptr<TabData> tab_data =
       std::make_unique<TabData>(tab_strip_model(), web_contents);
@@ -130,8 +145,6 @@
 
 TEST_F(TabOrganizationTest, TabDataOnDestroyWebContentsReplaceUpdatesContents) {
   content::WebContents* old_contents = AddTab();
-  GURL old_gurl = GURL("chrome://page_1");
-  content::WebContentsTester::For(old_contents)->NavigateAndCommit(old_gurl);
 
   std::unique_ptr<TabData> tab_data =
       std::make_unique<TabData>(tab_strip_model(), old_contents);
@@ -147,7 +160,7 @@
 
 TEST_F(TabOrganizationTest, TabDataURLChangeIsNotValidForOrganizing) {
   content::WebContents* web_contents = AddTab();
-  GURL old_gurl = GURL("chrome://page_1");
+  GURL old_gurl = GURL(GetUniqueTestURL());
   content::WebContentsTester::For(web_contents)->NavigateAndCommit(old_gurl);
 
   std::unique_ptr<TabData> tab_data =
@@ -157,19 +170,18 @@
 
   // update the URL for the webcontents, expect the tab data to not be valid.
   // When updating tab URL, the TabData shouldn't update.
-  content::WebContentsTester::For(web_contents)
-      ->NavigateAndCommit(GURL("chrome://page_2"));
+  content::WebContentsTester::For(tab_data->web_contents())
+      ->NavigateAndCommit(GetUniqueTestURL());
   EXPECT_FALSE(tab_data->IsValidForOrganizing());
 }
 
 TEST_F(TabOrganizationTest, TabDataWebContentsDeletionIsNotValidForOrganizing) {
   content::WebContents* web_contents = AddTab();
-  GURL old_gurl = GURL("chrome://page_1");
+  GURL old_gurl = GURL(GetUniqueTestURL());
   content::WebContentsTester::For(web_contents)->NavigateAndCommit(old_gurl);
 
   std::unique_ptr<TabData> tab_data =
       std::make_unique<TabData>(tab_strip_model(), web_contents);
-
   EXPECT_TRUE(tab_data->IsValidForOrganizing());
 
   // Add a new tab so that the tabstripmodel doesnt close.
@@ -253,6 +265,33 @@
   EXPECT_DEATH(organization.Reject(), "");
 }
 
+TEST_F(TabOrganizationTest, TabOrganizationIsValidForOrganizing) {
+  TabOrganization organization({}, {u"default_name"}, 0, absl::nullopt);
+
+  content::WebContents* tab_1 = AddTab();
+  std::unique_ptr<TabData> tab_data_1 =
+      std::make_unique<TabData>(tab_strip_model(), tab_1);
+  organization.AddTabData(std::move(tab_data_1));
+
+  EXPECT_FALSE(organization.IsValidForOrganizing());
+
+  content::WebContents* tab_2 = AddTab();
+  std::unique_ptr<TabData> tab_data_2 =
+      std::make_unique<TabData>(tab_strip_model(), tab_2);
+  TabData* tab_data_2_ptr = tab_data_2.get();
+  organization.AddTabData(std::move(tab_data_2));
+  EXPECT_TRUE(organization.IsValidForOrganizing());
+
+  InvalidateTabData(tab_data_2_ptr);
+  EXPECT_FALSE(organization.IsValidForOrganizing());
+
+  content::WebContents* tab_3 = AddTab();
+  std::unique_ptr<TabData> tab_data_3 =
+      std::make_unique<TabData>(tab_strip_model(), tab_3);
+  organization.AddTabData(std::move(tab_data_3));
+  EXPECT_TRUE(organization.IsValidForOrganizing());
+}
+
 TEST_F(TabOrganizationTest, TabOrganizationRequestOnStartRequest) {
   bool start_called = false;
   TabOrganizationRequest request(
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc
index 0c501822..86abf373 100644
--- a/chrome/browser/ui/toolbar/app_menu_model.cc
+++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -195,7 +195,7 @@
 // Returns the appropriate menu label for the IDC_OPEN_IN_PWA_WINDOW command if
 // available.
 std::u16string GetOpenPWALabel(const Browser* browser) {
-  absl::optional<web_app::AppId> app_id =
+  absl::optional<webapps::AppId> app_id =
       web_app::GetWebAppForActiveTab(browser);
   if (!app_id.has_value()) {
     return std::u16string();
diff --git a/chrome/browser/ui/unload_controller.cc b/chrome/browser/ui/unload_controller.cc
index 80f1cf9..a8dbb0a 100644
--- a/chrome/browser/ui/unload_controller.cc
+++ b/chrome/browser/ui/unload_controller.cc
@@ -18,10 +18,10 @@
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
 #include "chrome/browser/ui/web_applications/web_app_tabbed_utils.h"
 #include "chrome/browser/web_applications/policy/web_app_policy_manager.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_tab_helper.h"
 #include "components/tab_groups/tab_group_id.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/buildflags/buildflags.h"
diff --git a/chrome/browser/ui/unload_controller_browsertest.cc b/chrome/browser/ui/unload_controller_browsertest.cc
index 1a58595..d549a8a 100644
--- a/chrome/browser/ui/unload_controller_browsertest.cc
+++ b/chrome/browser/ui/unload_controller_browsertest.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/ui/prevent_close_test_base.h"
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_id_constants.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chrome/common/chrome_features.h"
@@ -23,6 +22,7 @@
 #include "components/policy/core/common/mock_configuration_policy_provider.h"
 #include "components/policy/core/common/policy_map.h"
 #include "components/policy/policy_constants.h"
+#include "components/webapps/common/web_app_id.h"
 #include "content/public/test/browser_test.h"
 #include "ui/base/window_open_disposition.h"
 #include "url/gurl.h"
diff --git a/chrome/browser/ui/url_identity.cc b/chrome/browser/ui/url_identity.cc
index e421c5e6..2c2d043 100644
--- a/chrome/browser/ui/url_identity.cc
+++ b/chrome/browser/ui/url_identity.cc
@@ -20,9 +20,9 @@
 #if BUILDFLAG(ENABLE_EXTENSIONS)
 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
 #include "chrome/browser/web_applications/web_app.h"
-#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
+#include "components/webapps/common/web_app_id.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
@@ -84,7 +84,7 @@
                          base::UTF8ToUTF16(extension->name()), false)};
 }
 
-absl::optional<web_app::AppId> GetIsolatedWebAppIdFromUrl(const GURL& url) {
+absl::optional<webapps::AppId> GetIsolatedWebAppIdFromUrl(const GURL& url) {
   base::expected<web_app::IsolatedWebAppUrlInfo, std::string> url_info =
       web_app::IsolatedWebAppUrlInfo::Create(url);
   return url_info.has_value() ? absl::make_optional(url_info.value().app_id())
@@ -106,7 +106,7 @@
     return CreateDefaultUrlIdentityFromUrl(url, options);
   }
 
-  absl::optional<web_app::AppId> app_id = GetIsolatedWebAppIdFromUrl(url);
+  absl::optional<webapps::AppId> app_id = GetIsolatedWebAppIdFromUrl(url);
   if (!app_id.has_value()) {  // fallback to default
     return CreateDefaultUrlIdentityFromUrl(url, options);
   }
diff --git a/chrome/browser/ui/url_identity_unittest.cc b/chrome/browser/ui/url_identity_unittest.cc
index 4e85070..5a400a0c 100644
--- a/chrome/browser/ui/url_identity_unittest.cc
+++ b/chrome/browser/ui/url_identity_unittest.cc
@@ -15,7 +15,7 @@
 #include "chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
 #include "chrome/browser/web_applications/test/web_app_test_utils.h"
-#include "chrome/browser/web_applications/web_app_id.h"
+#include "components/webapps/common/web_app_id.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_builder.h"
diff --git a/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view_browsertest.cc b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view_browsertest.cc
index 37613ac..3fa8ea7 100644
--- a/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view_browsertest.cc
@@ -217,7 +217,7 @@
   web_app_info->scope = start_url;
   web_app_info->user_display_mode =
       web_app::mojom::UserDisplayMode::kStandalone;
-  web_app::AppId app_id = web_app::test::InstallWebApp(browser()->profile(),
+  webapps::AppId app_id = web_app::test::InstallWebApp(browser()->profile(),
                                                        std::move(web_app_info));
   Browser* app_browser =
       web_app::LaunchWebAppBrowser(browser()->profile(), app_id);
diff --git a/chrome/browser/ui/views/frame/browser_frame_browsertest.cc b/chrome/browser/ui/views/frame/browser_frame_browsertest.cc
index fa523fd..a2ff144 100644
--- a/chrome/browser/ui/views/frame/browser_frame_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_frame_browsertest.cc
@@ -85,7 +85,7 @@
 IN_PROC_BROWSER_TEST_F(BrowserFrameTest, WebAppsHasBoundsOnOpen) {
   auto web_app_info = std::make_unique<web_app::WebAppInstallInfo>();
   web_app_info->start_url = GURL("http://example.org/");
-  web_app::AppId app_id = web_app::test::InstallWebApp(browser()->profile(),
+  webapps::AppId app_id = web_app::test::InstallWebApp(browser()->profile(),
                                                        std::move(web_app_info));
 
   Browser* app_browser =
diff --git a/chrome/browser/ui/views/frame/browser_frame_view_browsertest_win.cc b/chrome/browser/ui/views/frame/browser_frame_view_browsertest_win.cc
index e636c10..9ee1bfe 100644
--- a/chrome/browser/ui/views/frame/browser_frame_view_browsertest_win.cc
+++ b/chrome/browser/ui/views/frame/browser_frame_view_browsertest_win.cc
@@ -161,7 +161,7 @@
       web_app_info->theme_color = *theme_color_;
     }
 
-    web_app::AppId app_id = web_app::test::InstallWebApp(
+    webapps::AppId app_id = web_app::test::InstallWebApp(
         browser()->profile(), std::move(web_app_info));
     content::TestNavigationObserver navigation_observer(GetStartURL());
     navigation_observer.StartWatchingNewWebContents();
@@ -289,7 +289,7 @@
     web_app_info->title = u"A Web App";
     web_app_info->display_override = display_overrides;
 
-    web_app::AppId app_id = web_app::test::InstallWebApp(
+    webapps::AppId app_id = web_app::test::InstallWebApp(
         browser()->profile(), std::move(web_app_info));
 
     content::TestNavigationObserver navigation_observer(start_url);
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
index 2e6a597..aaa3fc5 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
@@ -94,7 +94,7 @@
     web_app::UpdateWebAppInfoFromManifest(manifest, manifest_url,
                                           web_app_info.get());
 
-    web_app::AppId app_id =
+    webapps::AppId app_id =
         web_app::test::InstallWebApp(profile(), std::move(web_app_info));
     app_browser_ = web_app::LaunchWebAppBrowser(profile(), app_id);
     web_contents_ = app_browser_->tab_strip_model()->GetActiveWebContents();
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
index 0d91b3c9..aa6164f 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
@@ -250,8 +250,8 @@
   }
 
   // Installs the web app under test, blocking until installation is complete,
-  // and returning the `web_app::AppId` for the installed web app.
-  web_app::AppId WaitForAppInstall() {
+  // and returning the `webapps::AppId` for the installed web app.
+  webapps::AppId WaitForAppInstall() {
     switch (GetThemeChangeTestMode()) {
       case ThemeChangeTestMode::kSWA:
         system_web_app_installation_->WaitForAppInstall();
@@ -327,7 +327,7 @@
     GTEST_SKIP();
   }
 
-  const web_app::AppId app_id = WaitForAppInstall();
+  const webapps::AppId app_id = WaitForAppInstall();
   auto* browser = web_app::LaunchWebAppBrowser(profile(), app_id);
   auto* contents_web_view =
       BrowserView::GetBrowserViewForBrowser(browser)->contents_web_view();
@@ -771,7 +771,7 @@
     web_app_info->display_mode = blink::mojom::DisplayMode::kStandalone;
     web_app_info->theme_color = GetThemeColor();
 
-    web_app::AppId app_id = web_app::test::InstallWebApp(
+    webapps::AppId app_id = web_app::test::InstallWebApp(
         browser()->profile(), std::move(web_app_info));
     content::TestNavigationObserver navigation_observer(GetAppURL());
     navigation_observer.StartWatchingNewWebContents();
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.h
index e250bcf..0fc54bc 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.h
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.h
@@ -69,7 +69,7 @@
   void PaintChildren(const views::PaintInfo& info) override;
 
   // web_app::WebAppRegistrarObserver
-  void OnAlwaysShowToolbarInFullscreenChanged(const web_app::AppId& app_id,
+  void OnAlwaysShowToolbarInFullscreenChanged(const webapps::AppId& app_id,
                                               bool show) override;
   void OnAppRegistrarDestroyed() override;
 
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
index 769f5aa..e734196 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
@@ -317,7 +317,7 @@
 }
 
 void BrowserNonClientFrameViewMac::OnAlwaysShowToolbarInFullscreenChanged(
-    const web_app::AppId& app_id,
+    const webapps::AppId& app_id,
     bool show) {
   if (web_app::AppBrowserController::IsForWebApp(browser_view()->browser(),
                                                  app_id)) {
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac_browsertest.mm b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac_browsertest.mm
index d107517..0384a7f2 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac_browsertest.mm
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac_browsertest.mm
@@ -87,7 +87,7 @@
   ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen;
 
   const GURL start_url = GetInstallableAppURL();
-  const web_app::AppId app_id = InstallPWA(start_url);
+  const webapps::AppId app_id = InstallPWA(start_url);
   Browser* const browser = LaunchWebAppBrowser(app_id);
   content::WebContents* const web_contents =
       browser->tab_strip_model()->GetActiveWebContents();
@@ -142,7 +142,7 @@
   ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen;
 
   const GURL start_url = GetInstallableAppURL();
-  const web_app::AppId app_id = InstallPWA(start_url);
+  const webapps::AppId app_id = InstallPWA(start_url);
   Browser* const browser = LaunchWebAppBrowser(app_id);
 
   BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_chromeos_browsertest.cc
index 21a2b0d..a2420735 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_chromeos_browsertest.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_chromeos_browsertest.cc
@@ -132,7 +132,7 @@
   }
 
  private:
-  web_app::AppId app_id;
+  webapps::AppId app_id;
   raw_ptr<Browser, DanglingUntriaged | ExperimentalAsh> browser_ = nullptr;
   raw_ptr<ImmersiveModeController, DanglingUntriaged | ExperimentalAsh>
       controller_ = nullptr;
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc
index 251053d..ca73b7a3 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc
@@ -89,7 +89,7 @@
     web_app_info->scope = GetAppURL().GetWithoutFilename();
     web_app_info->theme_color = theme_color;
 
-    web_app::AppId app_id = web_app::test::InstallWebApp(
+    webapps::AppId app_id = web_app::test::InstallWebApp(
         browser()->profile(), std::move(web_app_info));
     Browser* app_browser =
         web_app::LaunchWebAppBrowser(browser()->profile(), app_id);
@@ -365,7 +365,7 @@
     web_app_info->display_override = {
         blink::mojom::DisplayMode::kWindowControlsOverlay};
 
-    web_app::AppId app_id = web_app::test::InstallWebApp(
+    webapps::AppId app_id = web_app::test::InstallWebApp(
         browser()->profile(), std::move(web_app_info));
 
     Browser* app_browser =
diff --git a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
index 6cf14465..148a45b 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
+++ b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
@@ -748,9 +748,8 @@
  protected:
   class MockFilesController : public policy::DlpFilesControllerAsh {
    public:
-    explicit MockFilesController(const policy::DlpRulesManager& rules_manager,
-                                 Profile* profile)
-        : DlpFilesControllerAsh(rules_manager, profile) {}
+    explicit MockFilesController(const policy::DlpRulesManager& rules_manager)
+        : DlpFilesControllerAsh(rules_manager) {}
     ~MockFilesController() override = default;
 
     MOCK_METHOD(void,
@@ -767,24 +766,11 @@
                 (override));
   };
 
-  void TearDownOnMainThread() override {
-    // The files controller must be destroyed before the profile since it's
-    // holding a pointer to it.
-    mock_files_controller_.reset();
-    BaseSelectFileDialogExtensionBrowserTest::TearDownOnMainThread();
-  }
-
   std::unique_ptr<KeyedService> SetDlpRulesManager(
       content::BrowserContext* context) {
     auto dlp_rules_manager =
         std::make_unique<testing::NiceMock<policy::MockDlpRulesManager>>();
     rules_manager_ = dlp_rules_manager.get();
-
-    mock_files_controller_ = std::make_unique<MockFilesController>(
-        *rules_manager_, Profile::FromBrowserContext(context));
-    ON_CALL(*rules_manager_, GetDlpFilesController)
-        .WillByDefault(testing::Return(mock_files_controller_.get()));
-
     return dlp_rules_manager;
   }
 
@@ -797,6 +783,10 @@
 
     ON_CALL(*rules_manager_, IsFilesPolicyEnabled)
         .WillByDefault(testing::Return(true));
+    mock_files_controller_ =
+        std::make_unique<MockFilesController>(*rules_manager_);
+    ON_CALL(*rules_manager_, GetDlpFilesController)
+        .WillByDefault(testing::Return(mock_files_controller_.get()));
   }
 
   raw_ptr<policy::MockDlpRulesManager, DanglingUntriaged | ExperimentalAsh>
diff --git a/chrome/browser/ui/views/side_panel/lens/lens_core_tab_side_panel_helper.cc b/chrome/browser/ui/views/side_panel/lens/lens_core_tab_side_panel_helper.cc
index 9d08da2..9e19f1e 100644
--- a/chrome/browser/ui/views/side_panel/lens/lens_core_tab_side_panel_helper.cc
+++ b/chrome/browser/ui/views/side_panel/lens/lens_core_tab_side_panel_helper.cc
@@ -71,28 +71,10 @@
 }
 
 bool IsSidePanelEnabledForLens(content::WebContents* web_contents) {
-  // Companion feature being enabled should disable Lens in the side panel.
-  bool is_companion_enabled = false;
-#if !BUILDFLAG(IS_ANDROID)
-  Profile* profile =
-      Profile::FromBrowserContext(web_contents->GetBrowserContext());
-  // Consider companion as enabled if (i) It's enabled via field trial, or (ii)
-  // User has cleared exps waiting list and is in the corresponding field trial.
-  is_companion_enabled =
-      base::FeatureList::IsEnabled(
-          companion::features::internal::kSidePanelCompanion) ||
-      base::FeatureList::IsEnabled(
-          companion::features::internal::kSidePanelCompanion2) ||
-      (base::FeatureList::IsEnabled(
-           companion::features::internal::
-               kCompanionEnabledByObservingExpsNavigations) &&
-       profile->GetPrefs()->GetBoolean(
-           companion::kHasNavigatedToExpsSuccessPage));
-#endif
   return search::DefaultSearchProviderIsGoogle(
              lens::internal::GetTemplateURLService(web_contents)) &&
          lens::internal::IsSidePanelEnabled(web_contents) &&
-         lens::features::IsLensSidePanelEnabled() && !is_companion_enabled;
+         lens::features::IsLensSidePanelEnabled();
 }
 
 bool IsSidePanelEnabledForLensRegionSearch(content::WebContents* web_contents) {
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 34ba940..868070b 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
@@ -1706,6 +1706,8 @@
   // The viewport dimension params should be set to a value
   EXPECT_TRUE(GetLastViewportHeightParam() > 0);
   EXPECT_TRUE(GetLastViewportWidthParam() > 0);
+  histogram_tester_->ExpectBucketCount(
+      "Search.Lens.ViewportDimensionsSent.Success", true, 1);
   histogram_tester_->ExpectBucketCount("Companion.SidePanel.ShowUiSuccess",
                                        true, 1);
 }
diff --git a/chrome/browser/ui/webui/app_management/app_management_page_handler.cc b/chrome/browser/ui/webui/app_management/app_management_page_handler.cc
index 03e4d16e..b7cf00b 100644
--- a/chrome/browser/ui/webui/app_management/app_management_page_handler.cc
+++ b/chrome/browser/ui/webui/app_management/app_management_page_handler.cc
@@ -437,7 +437,7 @@
       "AppManagementPageHandler::GetOverlappingPreferredApps",
       std::make_unique<web_app::AllAppsLockDescription>(),
       base::BindOnce(
-          [](const web_app::AppId& app_id,
+          [](const webapps::AppId& app_id,
              GetOverlappingPreferredAppsCallback callback,
              web_app::AllAppsLock& all_apps_lock) {
             std::move(callback).Run(
@@ -500,7 +500,7 @@
 }
 
 void AppManagementPageHandler::OnWebAppFileHandlerApprovalStateChanged(
-    const web_app::AppId& app_id) {
+    const webapps::AppId& app_id) {
 #if BUILDFLAG(IS_CHROMEOS)
   NOTREACHED();
 #endif
@@ -527,7 +527,7 @@
 
 #if !BUILDFLAG(IS_CHROMEOS)
 void AppManagementPageHandler::OnWebAppUserLinkCapturingPreferencesChanged(
-    const web_app::AppId& app_id,
+    const webapps::AppId& app_id,
     bool is_preferred) {
   OnPreferredAppChanged(app_id, is_preferred);
 }
@@ -768,7 +768,7 @@
 
 #if !BUILDFLAG(IS_CHROMEOS)
 void AppManagementPageHandler::MakeAppPreferredAndResetOthers(
-    const web_app::AppId& app_id,
+    const webapps::AppId& app_id,
     bool set_to_preferred,
     web_app::AllAppsLock& lock) {
   bool is_already_preferred = lock.registrar().CapturesLinksInScope(app_id);
@@ -784,7 +784,7 @@
 
   // TODO(b/273830801): Automatically call observers when changes are committed
   //  to the web_app DB.
-  for (const web_app::AppId& id : lock.registrar().GetAppIds()) {
+  for (const webapps::AppId& id : lock.registrar().GetAppIds()) {
     if (id == app_id) {
       {
         web_app::ScopedRegistryUpdate update = lock.sync_bridge().BeginUpdate();
diff --git a/chrome/browser/ui/webui/app_management/app_management_page_handler.h b/chrome/browser/ui/webui/app_management/app_management_page_handler.h
index db817b0..b226813 100644
--- a/chrome/browser/ui/webui/app_management/app_management_page_handler.h
+++ b/chrome/browser/ui/webui/app_management/app_management_page_handler.h
@@ -92,7 +92,7 @@
 
   // web_app::WebAppRegistrarObserver:
   void OnWebAppFileHandlerApprovalStateChanged(
-      const web_app::AppId& app_id) override;
+      const webapps::AppId& app_id) override;
   void OnAppRegistrarDestroyed() override;
 
   // The following observers are used for user link capturing on W/M/L platforms
@@ -100,7 +100,7 @@
   // in the registrar, so as to propagate the changes to the app-settings/ page
   // to change the UI dynamically.
 #if !BUILDFLAG(IS_CHROMEOS)
-  void OnWebAppUserLinkCapturingPreferencesChanged(const web_app::AppId& app_id,
+  void OnWebAppUserLinkCapturingPreferencesChanged(const webapps::AppId& app_id,
                                                    bool is_preferred) override;
 #endif  // !BUILDFLAG(IS_CHROMEOS)
 
@@ -119,7 +119,7 @@
       apps::PreferredAppsListHandle* handle) override;
 
 #if !BUILDFLAG(IS_CHROMEOS)
-  void MakeAppPreferredAndResetOthers(const web_app::AppId& app_id,
+  void MakeAppPreferredAndResetOthers(const webapps::AppId& app_id,
                                       bool set_to_preferred,
                                       web_app::AllAppsLock& lock);
 #endif  // !BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/app_management/app_management_page_handler_unittest.cc b/chrome/browser/ui/webui/app_management/app_management_page_handler_unittest.cc
index edf5f4c..0dc17815 100644
--- a/chrome/browser/ui/webui/app_management/app_management_page_handler_unittest.cc
+++ b/chrome/browser/ui/webui/app_management/app_management_page_handler_unittest.cc
@@ -84,14 +84,14 @@
     provider->command_manager().AwaitAllCommandsCompleteForTesting();
   }
 
-  bool IsAppPreferred(const web_app::AppId& app_id) {
+  bool IsAppPreferred(const webapps::AppId& app_id) {
     base::test::TestFuture<app_management::mojom::AppPtr> result;
     handler()->GetApp(app_id, result.GetCallback());
     return result.Get()->is_preferred_app;
   }
 
   std::vector<std::string> GetOverlappingPreferredApps(
-      const web_app::AppId& app_id) {
+      const webapps::AppId& app_id) {
     base::test::TestFuture<const std::vector<std::string>&> result;
     handler()->GetOverlappingPreferredApps(app_id, result.GetCallback());
     EXPECT_TRUE(result.Wait());
@@ -721,13 +721,13 @@
   arc_test()->app_instance()->SendRefreshAppList(apps);
   ash::ApkWebAppService* service = ash::ApkWebAppService::Get(profile());
 
-  base::test::TestFuture<const std::string&, const web_app::AppId&>
+  base::test::TestFuture<const std::string&, const webapps::AppId&>
       installed_result;
 
   service->SetWebAppInstalledCallbackForTesting(installed_result.GetCallback());
   arc_test()->app_instance()->SendRefreshPackageList(std::move(packages));
 
-  web_app::AppId app_id = installed_result.Get<1>();
+  webapps::AppId app_id = installed_result.Get<1>();
   handler()->OpenStorePage(app_id);
 
   auto* intent_helper = arc_test()->intent_helper_instance();
diff --git a/chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.cc b/chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.cc
new file mode 100644
index 0000000..8d7418a
--- /dev/null
+++ b/chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.cc
@@ -0,0 +1,186 @@
+// 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/ui/webui/ash/mako/mako_bubble_coordinator.h"
+
+#include "base/check.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/views/bubble/webui_bubble_dialog_view.h"
+#include "chrome/browser/ui/webui/ash/mako/mako_ui.h"
+#include "chrome/browser/ui/webui/ash/mako/url_constants.h"
+#include "chrome/grit/orca_resources.h"
+#include "chrome/grit/orca_resources_map.h"
+#include "content/public/common/url_constants.h"
+#include "net/base/url_util.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/base/ime/ash/ime_bridge.h"
+#include "ui/base/metadata/metadata_header_macros.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
+#include "ui/display/screen.h"
+#include "ui/gfx/geometry/outsets.h"
+#include "ui/views/view_utils.h"
+
+namespace ash {
+
+namespace {
+
+constexpr int kCursorVerticalPadding = 8;
+
+constexpr int kMakoCornerRadius = 20;
+
+// Height threshold of the mako rewrite UI which determines its screen position.
+// Tall UI is centered on the display screen containing the caret, while short
+// UI is anchored at the caret.
+constexpr int kMakoRewriteHeightThreshold = 400;
+
+// TODO(b/289969807): As a placeholder, use 3961 which is the emoji picker
+// identifier for task manager. We should create a proper one for mako.
+constexpr int kMakoTaskManagerStringID = 3961;
+
+std::string_view ToOrcaModeParamValue(MakoEditorMode mode) {
+  return mode == MakoEditorMode::kWrite ? kOrcaWriteMode : kOrcaRewriteMode;
+}
+
+const ui::TextInputClient* GetTextInputClient() {
+  const ui::InputMethod* input_method =
+      IMEBridge::Get()->GetInputContextHandler()->GetInputMethod();
+  return input_method ? input_method->GetTextInputClient() : nullptr;
+}
+
+class MakoRewriteView : public WebUIBubbleDialogView {
+ public:
+  METADATA_HEADER(MakoRewriteView);
+  MakoRewriteView(BubbleContentsWrapper* contents_wrapper,
+                  const gfx::Rect& caret_bounds)
+      : WebUIBubbleDialogView(nullptr, contents_wrapper),
+        caret_bounds_(caret_bounds) {
+    set_has_parent(false);
+    set_corner_radius(kMakoCornerRadius);
+    set_adjust_if_offscreen(true);
+  }
+  MakoRewriteView(const MakoRewriteView&) = delete;
+  MakoRewriteView& operator=(const MakoRewriteView&) = delete;
+  ~MakoRewriteView() override = default;
+
+  void ResizeDueToAutoResize(content::WebContents* source,
+                             const gfx::Size& new_size) override {
+    if (new_size.height() > kMakoRewriteHeightThreshold) {
+      // Place tall UI at the center of the screen.
+      SetArrowWithoutResizing(views::BubbleBorder::FLOAT);
+      SetAnchorRect(display::Screen::GetScreen()
+                        ->GetDisplayMatching(caret_bounds_)
+                        .work_area());
+    } else {
+      // Anchor short UI at the caret.
+      SetArrowWithoutResizing(views::BubbleBorder::TOP_LEFT);
+      gfx::Rect anchor_rect = caret_bounds_;
+      anchor_rect.Outset(gfx::Outsets::VH(kCursorVerticalPadding, 0));
+      SetAnchorRect(anchor_rect);
+    }
+    WebUIBubbleDialogView::ResizeDueToAutoResize(source, new_size);
+  }
+
+ private:
+  gfx::Rect caret_bounds_;
+};
+
+BEGIN_METADATA(MakoRewriteView, WebUIBubbleDialogView)
+END_METADATA
+
+class MakoConsentView : public WebUIBubbleDialogView {
+ public:
+  METADATA_HEADER(MakoConsentView);
+  MakoConsentView(BubbleContentsWrapper* contents_wrapper,
+                  const gfx::Rect& caret_bounds)
+      : WebUIBubbleDialogView(nullptr, contents_wrapper) {
+    set_has_parent(false);
+    set_corner_radius(kMakoCornerRadius);
+    SetModalType(ui::MODAL_TYPE_SYSTEM);
+    SetArrowWithoutResizing(views::BubbleBorder::FLOAT);
+    SetAnchorRect(display::Screen::GetScreen()
+                      ->GetDisplayMatching(caret_bounds)
+                      .work_area());
+  }
+  MakoConsentView(const MakoConsentView&) = delete;
+  MakoConsentView& operator=(const MakoConsentView&) = delete;
+  ~MakoConsentView() override = default;
+};
+
+BEGIN_METADATA(MakoConsentView, WebUIBubbleDialogView)
+END_METADATA
+
+}  // namespace
+
+MakoBubbleCoordinator::MakoBubbleCoordinator() = default;
+
+MakoBubbleCoordinator::~MakoBubbleCoordinator() {
+  CloseUI();
+}
+
+void MakoBubbleCoordinator::ShowConsentUI(Profile* profile) {
+  if (!GetTextInputClient()) {
+    return;
+  }
+
+  caret_bounds_ = GetTextInputClient()->GetCaretBounds();
+  contents_wrapper_ = std::make_unique<BubbleContentsWrapperT<MakoUntrustedUI>>(
+      GURL(kChromeUIMakoPrivacyURL), profile, kMakoTaskManagerStringID);
+  contents_wrapper_->ReloadWebContents();
+  views::BubbleDialogDelegateView::CreateBubble(
+      std::make_unique<MakoConsentView>(contents_wrapper_.get(),
+                                        caret_bounds_.value()))
+      ->Show();
+}
+
+void MakoBubbleCoordinator::ShowEditorUI(
+    Profile* profile,
+    MakoEditorMode mode,
+    absl::optional<std::string_view> preset_query_id,
+    absl::optional<std::string_view> freeform_text) {
+  if (IsShowingUI()) {
+    // If switching contents (e.g. from consent UI to rewrite UI), close the
+    // current contents and use the cached caret bounds.
+    contents_wrapper_->CloseUI();
+    CHECK(caret_bounds_.has_value());
+  } else if (const auto* text_input_client = GetTextInputClient()) {
+    // Otherwise, try to get the caret bounds from the text input client.
+    caret_bounds_ = text_input_client->GetCaretBounds();
+  } else {
+    // Otherwise, don't show mako UI.
+    return;
+  }
+
+  GURL url = net::AppendOrReplaceQueryParameter(GURL(kChromeUIMakoOrcaURL),
+                                                kOrcaModeParamKey,
+                                                ToOrcaModeParamValue(mode));
+  url = net::AppendOrReplaceQueryParameter(url, kOrcaPresetParamKey,
+                                           preset_query_id);
+  url = net::AppendOrReplaceQueryParameter(url, kOrcaFreeformParamKey,
+                                           freeform_text);
+
+  contents_wrapper_ = std::make_unique<BubbleContentsWrapperT<MakoUntrustedUI>>(
+      url, profile, kMakoTaskManagerStringID);
+  contents_wrapper_->ReloadWebContents();
+  views::BubbleDialogDelegateView::CreateBubble(
+      std::make_unique<MakoRewriteView>(contents_wrapper_.get(),
+                                        caret_bounds_.value()))
+      ->Show();
+}
+
+void MakoBubbleCoordinator::CloseUI() {
+  if (contents_wrapper_) {
+    contents_wrapper_->CloseUI();
+    contents_wrapper_ = nullptr;
+    caret_bounds_ = absl::nullopt;
+  }
+}
+
+bool MakoBubbleCoordinator::IsShowingUI() const {
+  // TODO(b/301518440): To accurately check if the bubble is open, detect when
+  // the JS has finished loading instead of checking this pointer.
+  return contents_wrapper_ != nullptr &&
+         contents_wrapper_->GetHost() != nullptr;
+}
+
+}  // namespace ash
diff --git a/chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.h b/chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.h
new file mode 100644
index 0000000..500e642
--- /dev/null
+++ b/chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.h
@@ -0,0 +1,55 @@
+// 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_UI_WEBUI_ASH_MAKO_MAKO_BUBBLE_COORDINATOR_H_
+#define CHROME_BROWSER_UI_WEBUI_ASH_MAKO_MAKO_BUBBLE_COORDINATOR_H_
+
+#include <string_view>
+
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/gfx/geometry/rect.h"
+
+class BubbleContentsWrapper;
+class Profile;
+
+namespace ash {
+
+enum class MakoEditorMode {
+  kWrite,
+  kRewrite,
+};
+
+// Class used to manage the state of Mako WebUI bubble contents.
+class MakoBubbleCoordinator {
+ public:
+  MakoBubbleCoordinator();
+  MakoBubbleCoordinator(const MakoBubbleCoordinator&) = delete;
+  MakoBubbleCoordinator& operator=(const MakoBubbleCoordinator&) = delete;
+  ~MakoBubbleCoordinator();
+
+  void ShowConsentUI(Profile* profile);
+  void ShowEditorUI(Profile* profile,
+                    MakoEditorMode mode,
+                    absl::optional<std::string_view> preset_query_id,
+                    absl::optional<std::string_view> freeform_text);
+  void CloseUI();
+
+  bool IsShowingUI() const;
+
+ private:
+  // Cached caret bounds to use as the mako UI anchor when there is no text
+  // input client (e.g. if focus is not regained after switching from the
+  // consent UI to the rewrite UI).
+  absl::optional<gfx::Rect> caret_bounds_;
+
+  // TODO(b/300554470): This doesn't seem like the right class to own the
+  // contents wrapper and probably won't handle the bubble widget lifetimes
+  // correctly. Figure out how WebUI bubbles work, then implement this properly
+  // (maybe using a WebUIBubbleManager).
+  std::unique_ptr<BubbleContentsWrapper> contents_wrapper_;
+};
+
+}  // namespace ash
+
+#endif  // CHROME_BROWSER_UI_WEBUI_ASH_MAKO_MAKO_BUBBLE_COORDINATOR_H_
diff --git a/chrome/browser/ui/webui/ash/mako/mako_ui.cc b/chrome/browser/ui/webui/ash/mako/mako_ui.cc
index 30e4ef5..825d1ba 100644
--- a/chrome/browser/ui/webui/ash/mako/mako_ui.cc
+++ b/chrome/browser/ui/webui/ash/mako/mako_ui.cc
@@ -10,7 +10,6 @@
 #include "base/hash/sha1.h"
 #include "chrome/browser/ash/input_method/editor_mediator.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/views/bubble/webui_bubble_dialog_view.h"
 #include "chrome/browser/ui/webui/ash/mako/url_constants.h"
 #include "chrome/browser/ui/webui/webui_util.h"
 #include "chrome/grit/orca_resources.h"
@@ -21,101 +20,10 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "content/public/common/url_constants.h"
-#include "net/base/url_util.h"
-#include "ui/base/ime/ash/ime_bridge.h"
-#include "ui/base/metadata/metadata_header_macros.h"
-#include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/display/screen.h"
-#include "ui/gfx/geometry/outsets.h"
 #include "ui/webui/untrusted_bubble_web_ui_controller.h"
 
 namespace ash {
 
-namespace {
-
-constexpr int kCursorVerticalPadding = 8;
-
-constexpr int kMakoCornerRadius = 20;
-
-// Height threshold of the mako rewrite UI which determines its screen position.
-// Tall UI is centered on the display screen containing the caret, while short
-// UI is anchored at the caret.
-constexpr int kMakoRewriteHeightThreshold = 400;
-
-// TODO(b/289969807): As a placeholder, use 3961 which is the emoji picker
-// identifier for task manager. We should create a proper one for mako.
-constexpr int kMakoTaskManagerStringID = 3961;
-
-const ui::TextInputClient* GetTextInputClient() {
-  const ui::InputMethod* input_method =
-      IMEBridge::Get()->GetInputContextHandler()->GetInputMethod();
-  return input_method ? input_method->GetTextInputClient() : nullptr;
-}
-
-class MakoRewriteView : public WebUIBubbleDialogView {
- public:
-  METADATA_HEADER(MakoRewriteView);
-  MakoRewriteView(BubbleContentsWrapper* contents_wrapper,
-                  const gfx::Rect& caret_bounds)
-      : WebUIBubbleDialogView(nullptr, contents_wrapper),
-        caret_bounds_(caret_bounds) {
-    set_has_parent(false);
-    set_corner_radius(kMakoCornerRadius);
-    set_adjust_if_offscreen(true);
-  }
-  MakoRewriteView(const MakoRewriteView&) = delete;
-  MakoRewriteView& operator=(const MakoRewriteView&) = delete;
-  ~MakoRewriteView() override = default;
-
-  void ResizeDueToAutoResize(content::WebContents* source,
-                             const gfx::Size& new_size) override {
-    if (new_size.height() > kMakoRewriteHeightThreshold) {
-      // Place tall UI at the center of the screen.
-      SetArrowWithoutResizing(views::BubbleBorder::FLOAT);
-      SetAnchorRect(display::Screen::GetScreen()
-                        ->GetDisplayMatching(caret_bounds_)
-                        .work_area());
-    } else {
-      // Anchor short UI at the caret.
-      SetArrowWithoutResizing(views::BubbleBorder::TOP_LEFT);
-      gfx::Rect anchor_rect = caret_bounds_;
-      anchor_rect.Outset(gfx::Outsets::VH(kCursorVerticalPadding, 0));
-      SetAnchorRect(anchor_rect);
-    }
-    WebUIBubbleDialogView::ResizeDueToAutoResize(source, new_size);
-  }
-
- private:
-  gfx::Rect caret_bounds_;
-};
-
-BEGIN_METADATA(MakoRewriteView, WebUIBubbleDialogView)
-END_METADATA
-
-class MakoConsentView : public WebUIBubbleDialogView {
- public:
-  METADATA_HEADER(MakoConsentView);
-  MakoConsentView(BubbleContentsWrapper* contents_wrapper,
-                  const gfx::Rect& caret_bounds)
-      : WebUIBubbleDialogView(nullptr, contents_wrapper) {
-    set_has_parent(false);
-    set_corner_radius(kMakoCornerRadius);
-    SetModalType(ui::MODAL_TYPE_SYSTEM);
-    SetArrowWithoutResizing(views::BubbleBorder::FLOAT);
-    SetAnchorRect(display::Screen::GetScreen()
-                      ->GetDisplayMatching(caret_bounds)
-                      .work_area());
-  }
-  MakoConsentView(const MakoConsentView&) = delete;
-  MakoConsentView& operator=(const MakoConsentView&) = delete;
-  ~MakoConsentView() override = default;
-};
-
-BEGIN_METADATA(MakoConsentView, WebUIBubbleDialogView)
-END_METADATA
-
-}  // namespace
-
 MakoUntrustedUIConfig::MakoUntrustedUIConfig()
     : WebUIConfig(content::kChromeUIUntrustedScheme, ash::kChromeUIMakoHost) {}
 
@@ -179,96 +87,4 @@
 
 WEB_UI_CONTROLLER_TYPE_IMPL(MakoUntrustedUI)
 
-MakoPageHandler::MakoPageHandler() = default;
-
-MakoPageHandler::~MakoPageHandler() {
-  CloseUI();
-}
-
-void MakoPageHandler::ShowConsentUI(Profile* profile) {
-  if (!GetTextInputClient()) {
-    return;
-  }
-
-  caret_bounds_ = GetTextInputClient()->GetCaretBounds();
-  contents_wrapper_ = std::make_unique<BubbleContentsWrapperT<MakoUntrustedUI>>(
-      GURL(kChromeUIMakoPrivacyURL), profile, kMakoTaskManagerStringID);
-  contents_wrapper_->ReloadWebContents();
-  views::BubbleDialogDelegateView::CreateBubble(
-      std::make_unique<MakoConsentView>(contents_wrapper_.get(),
-                                        caret_bounds_.value()))
-      ->Show();
-}
-
-void MakoPageHandler::ShowWriteUI(Profile* profile) {
-  ShowEditorUI(
-      net::AppendOrReplaceQueryParameter(GURL(kChromeUIMakoOrcaURL),
-                                         kOrcaModeParamKey, kOrcaWriteMode),
-      profile);
-}
-
-void MakoPageHandler::ShowRewriteUI(Profile* profile) {
-  ShowEditorUI(
-      net::AppendOrReplaceQueryParameter(GURL(kChromeUIMakoOrcaURL),
-                                         kOrcaModeParamKey, kOrcaRewriteMode),
-      profile);
-}
-
-void MakoPageHandler::ShowRewriteUIFromPreset(Profile* profile,
-                                              std::string_view text_query_id) {
-  GURL url = net::AppendOrReplaceQueryParameter(
-      GURL(kChromeUIMakoOrcaURL), kOrcaModeParamKey, kOrcaRewriteMode);
-  ShowEditorUI(net::AppendOrReplaceQueryParameter(url, kOrcaPresetParamKey,
-                                                  text_query_id),
-               profile);
-}
-
-void MakoPageHandler::ShowRewriteUIFromFreeform(Profile* profile,
-                                                std::string_view text) {
-  GURL url = net::AppendOrReplaceQueryParameter(
-      GURL(kChromeUIMakoOrcaURL), kOrcaModeParamKey, kOrcaRewriteMode);
-  ShowEditorUI(
-      net::AppendOrReplaceQueryParameter(url, kOrcaPresetParamKey, text),
-      profile);
-}
-
-void MakoPageHandler::ShowEditorUI(const GURL& url,
-                                   content::BrowserContext* browser_context) {
-  if (contents_wrapper_ != nullptr) {
-    // If switching contents (e.g. from consent UI to rewrite UI), close the
-    // current contents and use the cached caret bounds.
-    contents_wrapper_->CloseUI();
-    CHECK(caret_bounds_.has_value());
-  } else if (const auto* text_input_client = GetTextInputClient()) {
-    // Otherwise, try to get the caret bounds from the text input client.
-    caret_bounds_ = text_input_client->GetCaretBounds();
-  } else {
-    // Otherwise, don't show mako UI.
-    return;
-  }
-
-  contents_wrapper_ = std::make_unique<BubbleContentsWrapperT<MakoUntrustedUI>>(
-      url, browser_context, kMakoTaskManagerStringID);
-  contents_wrapper_->ReloadWebContents();
-  views::BubbleDialogDelegateView::CreateBubble(
-      std::make_unique<MakoRewriteView>(contents_wrapper_.get(),
-                                        caret_bounds_.value()))
-      ->Show();
-}
-
-void MakoPageHandler::CloseUI() {
-  if (contents_wrapper_) {
-    contents_wrapper_->CloseUI();
-    contents_wrapper_ = nullptr;
-    caret_bounds_ = absl::nullopt;
-  }
-}
-
-bool MakoPageHandler::IsVisible() const {
-  // TODO(b/301518440): To accurately check if the bubble is open, detect when
-  // the JS has finished loading instead of checking this pointer.
-  return contents_wrapper_ != nullptr &&
-         contents_wrapper_->GetHost() != nullptr;
-}
-
 }  // namespace ash
diff --git a/chrome/browser/ui/webui/ash/mako/mako_ui.h b/chrome/browser/ui/webui/ash/mako/mako_ui.h
index 5842110..8c81c1d 100644
--- a/chrome/browser/ui/webui/ash/mako/mako_ui.h
+++ b/chrome/browser/ui/webui/ash/mako/mako_ui.h
@@ -7,13 +7,8 @@
 
 #include "chromeos/ash/services/orca/public/mojom/orca_service.mojom.h"
 #include "content/public/browser/webui_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
-#include "ui/gfx/geometry/rect.h"
 #include "ui/webui/untrusted_bubble_web_ui_controller.h"
 
-class BubbleContentsWrapper;
-class Profile;
-
 namespace ash {
 
 // WebUIConfig for chrome://mako
@@ -41,39 +36,6 @@
   WEB_UI_CONTROLLER_TYPE_DECL();
 };
 
-// Handles showing and hiding the mako WebUI.
-class MakoPageHandler {
- public:
-  MakoPageHandler();
-  MakoPageHandler(const MakoPageHandler&) = delete;
-  MakoPageHandler& operator=(const MakoPageHandler&) = delete;
-  ~MakoPageHandler();
-
-  void ShowConsentUI(Profile* profile);
-  void ShowWriteUI(Profile* profile);
-  void ShowRewriteUI(Profile* profile);
-  void ShowRewriteUIFromPreset(Profile* profile,
-                               std::string_view text_query_id);
-  void ShowRewriteUIFromFreeform(Profile* profile, std::string_view text);
-  void CloseUI();
-
-  bool IsVisible() const;
-
- private:
-  void ShowEditorUI(const GURL& url, content::BrowserContext* browser_context);
-
-  // Cached caret bounds to use as the mako UI anchor when there is no text
-  // input client (e.g. if focus is not regained after switching from the
-  // consent UI to the rewrite UI).
-  absl::optional<gfx::Rect> caret_bounds_;
-
-  // TODO(b/300554470): This doesn't seem like the right class to own the
-  // contents wrapper and probably won't handle the bubble widget lifetimes
-  // correctly. Figure out how WebUI bubbles work, then implement this properly
-  // (maybe using a WebUIBubbleManager).
-  std::unique_ptr<BubbleContentsWrapper> contents_wrapper_;
-};
-
 }  // namespace ash
 
 #endif  // CHROME_BROWSER_UI_WEBUI_ASH_MAKO_MAKO_UI_H_
diff --git a/chrome/browser/ui/webui/settings/safety_hub_handler_unittest.cc b/chrome/browser/ui/webui/settings/safety_hub_handler_unittest.cc
index 52673d5..5e1061c 100644
--- a/chrome/browser/ui/webui/settings/safety_hub_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/safety_hub_handler_unittest.cc
@@ -490,7 +490,6 @@
   // TODO(crbug.com/1459305): Remove this after adding names for those
   // types.
   std::list<ContentSettingsType> no_name_types = {
-      ContentSettingsType::MIDI,
       ContentSettingsType::DURABLE_STORAGE,
       ContentSettingsType::ACCESSIBILITY_EVENTS,
       ContentSettingsType::NFC,
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index b8654a10..94d2959b 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -3324,6 +3324,10 @@
       base::FeatureList::IsEnabled(
           permissions::features::kPermissionDedicatedCpssSetting));
 
+  html_source->AddBoolean(
+      "blockMidiByDefault",
+      base::FeatureList::IsEnabled(permissions::features::kBlockMidiByDefault));
+
   // The exception placeholder should not be translated. See
   // crbug.com/1095878.
   html_source->AddString("addSiteExceptionPlaceholder", "[*.]example.com");
diff --git a/chrome/browser/ui/webui/settings/site_settings_helper.cc b/chrome/browser/ui/webui/settings/site_settings_helper.cc
index 9bc1f508..0038a43 100644
--- a/chrome/browser/ui/webui/settings/site_settings_helper.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_helper.cc
@@ -45,6 +45,7 @@
 #include "components/content_settings/core/common/content_settings_pattern.h"
 #include "components/content_settings/core/common/content_settings_utils.h"
 #include "components/permissions/contexts/bluetooth_chooser_context.h"
+#include "components/permissions/features.h"
 #include "components/permissions/object_permission_context_base.h"
 #include "components/permissions/permission_decision_auto_blocker.h"
 #include "components/permissions/permission_util.h"
@@ -101,6 +102,7 @@
     {ContentSettingsType::MEDIASTREAM_CAMERA, "media-stream-camera"},
     {ContentSettingsType::PROTOCOL_HANDLERS, "register-protocol-handler"},
     {ContentSettingsType::AUTOMATIC_DOWNLOADS, "multiple-automatic-downloads"},
+    {ContentSettingsType::MIDI, "midi"},
     {ContentSettingsType::MIDI_SYSEX, "midi-sysex"},
     {ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER, "protected-content"},
     {ContentSettingsType::BACKGROUND_SYNC, "background-sync"},
@@ -150,7 +152,6 @@
     {ContentSettingsType::IMPORTANT_SITE_INFO, nullptr},
     {ContentSettingsType::PERMISSION_AUTOBLOCKER_DATA, nullptr},
     {ContentSettingsType::ADS_DATA, nullptr},
-    {ContentSettingsType::MIDI, nullptr},
     {ContentSettingsType::PASSWORD_PROTECTION, nullptr},
     {ContentSettingsType::MEDIA_ENGAGEMENT, nullptr},
     {ContentSettingsType::CLIENT_HINTS, nullptr},
@@ -513,7 +514,6 @@
       ContentSettingsType::LOCAL_FONTS,
       ContentSettingsType::MEDIASTREAM_CAMERA,
       ContentSettingsType::MEDIASTREAM_MIC,
-      ContentSettingsType::MIDI_SYSEX,
       ContentSettingsType::MIXEDSCRIPT,
       ContentSettingsType::NOTIFICATIONS,
       ContentSettingsType::POPUPS,
@@ -563,6 +563,13 @@
       base_types->push_back(ContentSettingsType::AUTO_PICTURE_IN_PICTURE);
     }
 
+    if (base::FeatureList::IsEnabled(
+            permissions::features::kBlockMidiByDefault)) {
+      base_types->push_back(ContentSettingsType::MIDI);
+    } else {
+      base_types->push_back(ContentSettingsType::MIDI_SYSEX);
+    }
+
     initialized = true;
   }
 
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.cc
index 3596062..fa3e1149 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.cc
@@ -97,10 +97,9 @@
     base::OnceCallback<void(base::expected<IsolatedWebAppUrlInfo, std::string>)>
         callback) {
   absl::visit(base::Overloaded{
-                  [&](const InstalledBundle&) {
-                    std::move(callback).Run(base::unexpected(
-                        "Getting IsolationInfo from |InstalledBundle| is not "
-                        "implemented"));
+                  [&](const InstalledBundle& installed_bundle) {
+                    GetSignedWebBundleIdByPath(installed_bundle.path,
+                                               std::move(callback));
                   },
                   [&](const DevModeBundle& dev_mode_bundle) {
                     GetSignedWebBundleIdByPath(dev_mode_bundle.path,
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info_unittest.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info_unittest.cc
index e27e87c..d0d1c1df4 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info_unittest.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info_unittest.cc
@@ -148,13 +148,21 @@
 
 TEST_F(IsolatedWebAppUrlInfoFromIsolatedWebAppLocationTest,
        GetIsolatedWebAppUrlInfoWhenInstalledBundleSucceeds) {
-  IsolatedWebAppLocation location = InstalledBundle{};
+  base::ScopedTempDir temp_dir;
+  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+  base::FilePath path =
+      temp_dir.GetPath().Append(base::FilePath::FromASCII("test-0.swbn"));
+  TestSignedWebBundle bundle = TestSignedWebBundleBuilder::BuildDefault();
+  ASSERT_TRUE(base::WriteFile(path, bundle.data));
+
+  IsolatedWebAppLocation location = InstalledBundle{.path = path};
   base::test::TestFuture<base::expected<IsolatedWebAppUrlInfo, std::string>>
       test_future;
-
   IsolatedWebAppUrlInfo::CreateFromIsolatedWebAppLocation(
       location, test_future.GetCallback());
-  EXPECT_THAT(test_future.Get(), ErrorIs(HasSubstr("is not implemented")));
+  EXPECT_THAT(
+      test_future.Get(),
+      ValueIs(Property(&IsolatedWebAppUrlInfo::web_bundle_id, bundle.id)));
 }
 
 TEST_F(IsolatedWebAppUrlInfoFromIsolatedWebAppLocationTest,
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt
index 2497bf3..c070a50 100644
--- a/chrome/build/android-arm32.pgo.txt
+++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@
-chrome-android32-main-1695642859-ac235d17b32ea34b1616435cb1bc243e828a65c9.profdata
+chrome-android32-main-1695686089-b818f7a4fcae1d2b71c52ee1f97f971820511889.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt
index 71c39f3a..0b44a4d4 100644
--- a/chrome/build/android-arm64.pgo.txt
+++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@
-chrome-android64-main-1695664785-44d72b2e8d4b94ba4d5911b7d5829c079851df59.profdata
+chrome-android64-main-1695686089-a6031d3e58908d65dd7fefdce8f0b2098db364bc.profdata
diff --git a/chrome/build/lacros64.pgo.txt b/chrome/build/lacros64.pgo.txt
index facdfb6f..be924ae 100644
--- a/chrome/build/lacros64.pgo.txt
+++ b/chrome/build/lacros64.pgo.txt
@@ -1 +1 @@
-chrome-chromeos-amd64-generic-main-1695643449-0dbe2596dc6b331fd6e7e12f1479b76c0d519408.profdata
+chrome-chromeos-amd64-generic-main-1695686089-7227fcad6f635bdf43314d2f20e26de2cc7b1994.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index d59068c..bf03b4c 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1695642859-b6361fcf35177f216c1bec3e95d29382fafd03da.profdata
+chrome-linux-main-1695686089-0abd28a7afeaef1d74538bbcc14446034bd7b354.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 8c629fc..9222e24 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1695657547-58d18301c394642dce4f361841d34491488cc57a.profdata
+chrome-mac-arm-main-1695693373-77f2c3286f859d095bc135cf979a9d6e010879fd.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 9c20be4..d8879133 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1695664785-37a0b1feeb020f3cc7b25bdf7c42cae5fe9ea65f.profdata
+chrome-mac-main-1695686089-8fd56b66cc0077094ecfa2e27104a8bbedfca19a.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt
index f440d33..70add03 100644
--- a/chrome/build/win-arm64.pgo.txt
+++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@
-chrome-win-arm64-main-1695664785-0d5f9c725b42dfae2bf853216e66461ce6d2c242.profdata
+chrome-win-arm64-main-1695686089-11b243d8de9ed5002dc9eafb6dde8b25ae27d744.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 29254c3..3911c5f9 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1695653701-02bbfb651cab302ec6d42833e801ab28ce50f3ab.profdata
+chrome-win32-main-1695675537-45bcc26294e0efde5935dacba75e40fd4623b1d2.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 631600c..8ce5675 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1695653701-0f1ba024ea31314714fd860d2eab5d2c64deb139.profdata
+chrome-win64-main-1695686089-a6ed345156e0ae859891b7437ada3ba756544b29.profdata
diff --git a/chrome/renderer/resources/extensions/notifications_custom_bindings.gtestjs b/chrome/renderer/resources/extensions/notifications_custom_bindings_test.js
similarity index 79%
rename from chrome/renderer/resources/extensions/notifications_custom_bindings.gtestjs
rename to chrome/renderer/resources/extensions/notifications_custom_bindings_test.js
index d1475a8..829609f 100644
--- a/chrome/renderer/resources/extensions/notifications_custom_bindings.gtestjs
+++ b/chrome/renderer/resources/extensions/notifications_custom_bindings_test.js
@@ -1,35 +1,34 @@
-// Copyright 2014 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.
 
-/**
- * Test fixture for the notifications custom bindings adapter.
- * @constructor
- * @extends {testing.Test}
- */
-function NotificationsCustomBindingsTest() {
-  testing.Test.call(this);
+function assertTrue(condition) {
+  if (!condition) {
+    throw new Error('Assertion failed: expected ' + condition + ' to be true');
+  }
 }
 
-NotificationsCustomBindingsTest.prototype = {
-  __proto__: testing.Test.prototype,
+function assertEquals(a, b) {
+  if (a !== b) {
+    throw new Error('Assertion failed: expected ' + a + ' to equal ' + b);
+  }
+}
 
-  /** @Override */
-  extraLibraries: [
-    'notifications_test_util.js',
-    'notifications_custom_bindings.js'
-  ],
-};
+function assertFalse(condition) {
+  if (!!condition) {
+    throw new Error('Assertion failed: expected ' + condition + ' to be false');
+  }
+}
 
-TEST_F('NotificationsCustomBindingsTest', 'TestImageDataSetter', function () {
+function testImageDataSetter() {
   var c = {};
   var k = "key";
   var callback = imageDataSetter(c, k);
   callback('val');
   assertTrue(c[k] === 'val');
-});
+}
 
-TEST_F('NotificationsCustomBindingsTest', 'TestGetUrlSpecs', function () {
+function testGetUrlSpecs() {
   var imageSizes = {
     scaleFactor: 1.0,
     icon: { width: 10, height: 10 },
@@ -71,9 +70,9 @@
       notificationDetails.buttons[0].iconBitmap === "buttonOneIconUrl|2|2");
   assertTrue(
       notificationDetails.buttons[1].iconBitmap === "buttonTwoIconUrl|2|2");
-});
+}
 
-TEST_F('NotificationsCustomBindingsTest', 'TestGetUrlSpecsScaled', function () {
+function testGetUrlSpecsScaled() {
   var imageSizes = {
     scaleFactor: 2.0,
     icon: { width: 10, height: 10 },
@@ -101,4 +100,4 @@
                "buttonOneIconUrl|4|4");
   assertEquals(notificationDetails.buttons[1].iconBitmap,
                "buttonTwoIconUrl|4|4");
-});
+}
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 62ef159..f0ca99d 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1169,6 +1169,7 @@
       "../browser/toolbar_manager_test_helper_android.h",
       "../browser/trusted_vault/trusted_vault_encryption_keys_tab_helper_browsertest.cc",
       "../browser/ui/android/autofill/save_update_address_profile_flow_manager_browsertest.cc",
+      "../browser/ui/android/plus_addresses/plus_address_creation_view_android_browsertest.cc",
       "../browser/ui/autofill/payments/offer_notification_controller_android_browsertest.cc",
       "../browser/ui/webui/policy/policy_test_ui_browsertest.cc",
       "../browser/ui/webui/policy/policy_ui_browsertest.cc",
@@ -1202,6 +1203,7 @@
       "//components/messages/android/test:test_support_java",
       "//components/optimization_guide/core:test_support",
       "//components/password_manager/content/browser:browser",
+      "//components/plus_addresses",
       "//components/policy:chrome_settings_proto_generated_compile",
       "//components/policy/core/browser:test_support",
       "//components/privacy_sandbox/privacy_sandbox_attestations",
@@ -1907,6 +1909,7 @@
       "data/",
       "//ash/components/arc/test/data/icons",
       "//chrome/browser/page_load_metrics/integration_tests/data/",
+      "//chrome/renderer/resources/extensions/",
       "//chrome/test/data/cart/",
       "//components/test/data/ad_tagging/",
       "//components/test/data/ads_observer/",
@@ -2327,6 +2330,7 @@
       "../browser/preloading/prefetch/zero_suggest_prefetch/zero_suggest_prefetch_tab_helper_browsertest.cc",
       "../browser/privacy_sandbox/privacy_sandbox_attestations_component_installer_browsertest.cc",
       "../browser/privacy_sandbox/privacy_sandbox_settings_browsertest.cc",
+      "../browser/privacy_sandbox/tracking_protection_notice_browsertest.cc",
       "../browser/privacy_sandbox/tracking_protection_settings_browsertest.cc",
       "../browser/profile_resetter/profile_resetter_browsertest.cc",
       "../browser/profiles/host_zoom_map_browsertest.cc",
@@ -2482,6 +2486,7 @@
       "../browser/ui/extensions/extension_image_util_browsertest.cc",
       "../browser/ui/extensions/extension_side_panel_test_utils.h",
       "../browser/ui/extensions/hosted_app_browsertest.cc",
+      "../browser/ui/extensions/notifications_custom_bindings_browsertest.cc",
       "../browser/ui/extensions/settings_overridden_params_providers_browsertest.cc",
       "../browser/ui/find_bar/find_bar_controller_browsertest.cc",
       "../browser/ui/find_bar/find_bar_host_browsertest.cc",
@@ -7969,13 +7974,9 @@
 
     data += [ "//ash/components/arc/test/data/icons/" ]
 
-    if (include_js2gtest_tests) {
-      deps += [ "//chrome/test/data/webui:unit_tests_js" ]
-      if (is_chromeos_ash) {
-        deps += [
-          "//chrome/browser/resources/chromeos/accessibility:unit_tests_js",
-        ]
-      }
+    if (include_js2gtest_tests && is_chromeos_ash) {
+      deps +=
+          [ "//chrome/browser/resources/chromeos/accessibility:unit_tests_js" ]
     }
   }
 
diff --git a/chrome/test/base/chromeos/crosier/upstart_test.cc b/chrome/test/base/chromeos/crosier/upstart_test.cc
index 24b85e4..ca4c2e5 100644
--- a/chrome/test/base/chromeos/crosier/upstart_test.cc
+++ b/chrome/test/base/chromeos/crosier/upstart_test.cc
@@ -55,7 +55,8 @@
   EXPECT_EQ(result, ui);
 }
 
-TEST(Upstart, GetJobStatus) {
+// TODO(crbug.com/1486711) This fails connecting to the test helper sometimes.
+TEST(Upstart, DISABLED_GetJobStatus) {
   // Random nonexistent job.
   JobStatus result = GetJobStatus("nonexistent-job");
   EXPECT_FALSE(result.is_valid);
@@ -68,12 +69,14 @@
   EXPECT_GT(result.pid, 0);
 }
 
-TEST(Upstart, JobExists) {
+// TODO(crbug.com/1486711) This fails connecting to the test helper sometimes.
+TEST(Upstart, DISABLED_JobExists) {
   EXPECT_FALSE(JobExists("nonexistent-job"));
   EXPECT_TRUE(JobExists("dbus"));
 }
 
-TEST(Upstart, WaitForJobStatus) {
+// TODO(crbug.com/1486711) This fails connecting to the test helper sometimes.
+TEST(Upstart, DISABLED_WaitForJobStatus) {
   // This is hard to test without making a lot of assumptions or messing with
   // the system. Instead, we just validate some simple cases that don't change
   // anything.
diff --git a/chrome/test/data/unit/framework_unittest.gtestjs b/chrome/test/data/unit/framework_unittest.gtestjs
deleted file mode 100644
index bc47bc46..0000000
--- a/chrome/test/data/unit/framework_unittest.gtestjs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2011 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * Class for testing the unit_test framework.
- * @constructor
- * @extends {testing.Test}
- */
-function FrameworkUnitTest() {}
-
-FrameworkUnitTest.prototype = {
-  __proto__: testing.Test.prototype,
-};
-
-TEST_F('FrameworkUnitTest', 'AssertTrueOk', function() {
-  assertTrue(true);
-});
-
-/**
- * Failing version of FrameworkUnitTest.
- * @constructor
- * @extends {FrameworkUnitTest}
- */
-function FrameworkUnitTestFail() {}
-
-FrameworkUnitTestFail.prototype = {
-  __proto__: FrameworkUnitTest.prototype,
-
-  /** inheritDoc */
-  testShouldFail: true,
-};
-
-TEST_F('FrameworkUnitTestFail', 'AssertFailFails', function() {
-  assertNotReached();
-});
diff --git a/chrome/test/data/unit/framework_unittest.js b/chrome/test/data/unit/framework_unittest.js
deleted file mode 100644
index 3339cf4a5..0000000
--- a/chrome/test/data/unit/framework_unittest.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2011 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * Class for testing the unit_test framework.
- * @constructor
- */
-function FrameworkUnitTest() {}
-
-FrameworkUnitTest.prototype = {
-  __proto__: testing.Test.prototype,
-};
-
-TEST_F('FrameworkUnitTest', 'testAssertTrueOk', function() {
-  assertTrue(true);
-});
-
-/**
- * Failing version of FrameworkUnitTest.
- * @constructor
- */
-function FrameworkUnitTestFail() {}
-
-FrameworkUnitTestFail.prototype = {
-  __proto__: FrameworkUnitTest.prototype,
-
-  /** inheritDoc */
-  testShouldFail: true,
-};
-
-TEST_F('FrameworkUnitTestFail', 'testAssertFailFails', function() {
-  assertNotReached();
-});
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn
index fb73acc4..c4c544b6 100644
--- a/chrome/test/data/webui/BUILD.gn
+++ b/chrome/test/data/webui/BUILD.gn
@@ -306,18 +306,6 @@
       defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
     }
   }
-
-  js2gtest("unit_tests_js") {
-    test_type = "unit"
-    sources = [
-      "../../../renderer/resources/extensions/notifications_custom_bindings.gtestjs",
-      "../unit/framework_unittest.gtestjs",
-    ]
-    extra_js_files = [
-      "../../../renderer/resources/extensions/notifications_custom_bindings.js",
-      "../../../renderer/resources/extensions/notifications_test_util.js",
-    ]
-  }
 }
 
 if (is_chromeos_ash) {
diff --git a/chrome/test/data/webui/certificate_viewer_dialog_browsertest.cc b/chrome/test/data/webui/certificate_viewer_dialog_browsertest.cc
index d7538af..c8bd541b 100644
--- a/chrome/test/data/webui/certificate_viewer_dialog_browsertest.cc
+++ b/chrome/test/data/webui/certificate_viewer_dialog_browsertest.cc
@@ -49,6 +49,13 @@
     return certs;
   }
 
+  void RunTestCase(const std::string& testCase) {
+    RunTestWithoutTestLoader(
+        "certificate_viewer_dialog_test.js",
+        base::StringPrintf("runMochaTest('CertificateViewer', '%s');",
+                           testCase.c_str()));
+  }
+
  private:
   content::WebContents* ShowCertificateViewer(
       std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> certs) {
@@ -70,18 +77,15 @@
 };
 
 IN_PROC_BROWSER_TEST_F(CertificateViewerUITest, DialogURL) {
-  RunTestWithoutTestLoader("certificate_viewer_dialog_test.js",
-                           "mocha.grep('DialogURL').run()");
+  RunTestCase("DialogURL");
 }
 
 IN_PROC_BROWSER_TEST_F(CertificateViewerUITest, CommonName) {
-  RunTestWithoutTestLoader("certificate_viewer_dialog_test.js",
-                           "mocha.grep('CommonName').run()");
+  RunTestCase("CommonName");
 }
 
 IN_PROC_BROWSER_TEST_F(CertificateViewerUITest, Details) {
-  RunTestWithoutTestLoader("certificate_viewer_dialog_test.js",
-                           "mocha.grep('Details').run()");
+  RunTestCase("Details");
 }
 
 class CertificateViewerUIInvalidCertTest : public CertificateViewerUITest {
@@ -96,6 +100,5 @@
 };
 
 IN_PROC_BROWSER_TEST_F(CertificateViewerUIInvalidCertTest, InvalidCert) {
-  RunTestWithoutTestLoader("certificate_viewer_dialog_test.js",
-                           "mocha.grep('InvalidCert').run()");
+  RunTestCase("InvalidCert");
 }
diff --git a/chrome/test/data/webui/chromeos/internet_detail_dialog_test.js b/chrome/test/data/webui/chromeos/internet_detail_dialog_test.js
index 925d3b4..efcaf66a 100644
--- a/chrome/test/data/webui/chromeos/internet_detail_dialog_test.js
+++ b/chrome/test/data/webui/chromeos/internet_detail_dialog_test.js
@@ -456,4 +456,42 @@
       }
     });
   });
+
+  test('Show toast on show-error-toast event', async function() {
+    loadTimeData.overrideValues({
+      apnRevamp: true,
+    });
+    await init();
+    const getErrorToast = () =>
+        internetDetailDialog.shadowRoot.querySelector('#errorToast');
+    assertFalse(getErrorToast().open);
+
+    const message = 'Toast message';
+    const event = new CustomEvent('show-error-toast', {detail: message});
+    internetDetailDialog.dispatchEvent(event);
+    await flushAsync();
+    assertTrue(getErrorToast().open);
+    assertEquals(
+        internetDetailDialog.shadowRoot.querySelector('#errorToastMessage')
+            .innerHTML,
+        message);
+  });
+
+  test(
+      'Dont show toast on show-error-toast event when ApnRevamp false',
+      async function() {
+        loadTimeData.overrideValues({
+          apnRevamp: false,
+        });
+        await init();
+        const getErrorToast = () =>
+            internetDetailDialog.shadowRoot.querySelector('#errorToast');
+        assertFalse(!!getErrorToast());
+
+        const message = 'Toast message';
+        const event = new CustomEvent('show-error-toast', {detail: message});
+        internetDetailDialog.dispatchEvent(event);
+        await flushAsync();
+        assertFalse(!!getErrorToast());
+      });
 });
diff --git a/chrome/updater/ipc/proxy_impl_base_win.h b/chrome/updater/ipc/proxy_impl_base_win.h
index 691995df..8116e43 100644
--- a/chrome/updater/ipc/proxy_impl_base_win.h
+++ b/chrome/updater/ipc/proxy_impl_base_win.h
@@ -11,6 +11,7 @@
 #include <utility>
 
 #include "base/check.h"
+#include "base/debug/alias.h"
 #include "base/functional/callback.h"
 #include "base/logging.h"
 #include "base/memory/scoped_refptr.h"
@@ -101,6 +102,58 @@
     if (FAILED(hr)) {
       VLOG(2) << "Failed to query the interface: "
               << base::win::WStringFromGUID(iid) << ": " << std::hex << hr;
+      [&]() {
+        if (hr != E_NOINTERFACE) {
+          return;
+        }
+        static bool dumped_once = false;
+        if (dumped_once) {
+          return;
+        }
+
+        base::ThreadPool::PostTask(
+            FROM_HERE, {base::MayBlock(), base::WithBaseSyncPrimitives()},
+            base::BindOnce(
+                [](std::wstring hkey_root, std::wstring interface_iid) {
+                  std::wstring log_string;
+                  for (const auto& reg_key : {
+                           base::StrCat({hkey_root,
+                                         L"\\SOFTWARE\\Classes\\Interface\\",
+                                         interface_iid}),
+                           base::StrCat({hkey_root,
+                                         L"\\SOFTWARE\\Classes\\TypeLib\\",
+                                         interface_iid}),
+                           base::StrCat({hkey_root,
+                                         L"\\SOFTWARE\\WOW6432Node\\Classes"
+                                         L"\\Interface\\",
+                                         interface_iid}),
+                           base::StrCat({hkey_root,
+                                         L"\\SOFTWARE\\WOW6432Node\\Classes"
+                                         L"\\TypeLib\\",
+                                         interface_iid}),
+                           base::StrCat({L"HKCR\\Interface\\", interface_iid}),
+                           base::StrCat({L"HKCR\\TypeLib\\", interface_iid}),
+                           base::StrCat({L"HKCR\\WOW6432Node\\Interface\\",
+                                         interface_iid}),
+                           base::StrCat({L"HKCR\\WOW6432Node\\TypeLib\\",
+                                         interface_iid}),
+                       }) {
+                    absl::optional<std::wstring> contents =
+                        GetRegKeyContents(reg_key);
+                    log_string +=
+                        base::StrCat({L"Contents of *", reg_key, L"* = ",
+                                      contents ? *contents : L"", L"\n"});
+                  }
+                  std::wstring local_log_string = log_string;
+                  base::debug::Alias(&local_log_string);
+                  DUMP_WILL_BE_CHECK(false);
+                },
+                IsSystemInstall(scope_) ? L"HKLM" : L"HKCU",
+                base::win::WStringFromGUID(iid)));
+
+        base::PlatformThread::Sleep(base::Seconds(5));
+        dumped_once = true;
+      }();
       return base::unexpected(hr);
     }
 
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc
index 824c966..39890376 100644
--- a/chrome/updater/test/integration_tests.cc
+++ b/chrome/updater/test/integration_tests.cc
@@ -1822,12 +1822,13 @@
   const base::FilePath crx_path = GetInstallerPath(kAppCRX);
   ExpectAppsUpdateSequence(
       UpdaterScope::kSystem, test_server_.get(),
+      /*request_attributes=*/{},
       {
           AppUpdateExpectation(
               BuildCommandLineArgs(GetTestScope(), kAppId1, kApp1Version),
               kAppId1, base::Version({0, 0, 0, 0}), kApp1Version,
               /*is_install=*/true,
-              /*should_update=*/true, false, "", crx_path),
+              /*should_update=*/true, false, "", "", crx_path),
       });
 
   ASSERT_NO_FATAL_FAILURE(InstallAppViaService(kAppId1));
@@ -1866,12 +1867,13 @@
   const base::FilePath crx_path = GetInstallerPath(kAppCRX);
   ExpectAppsUpdateSequence(
       UpdaterScope::kSystem, test_server_.get(),
+      /*request_attributes=*/{},
       {
           AppUpdateExpectation(
               BuildCommandLineArgs(GetTestScope(), kAppId1, kApp1Version),
               kAppId1, base::Version({0, 0, 0, 0}), kApp1Version,
               /*is_install=*/true,
-              /*should_update=*/true, false, "", crx_path),
+              /*should_update=*/true, false, "", "", crx_path),
       });
   ExpectUpdateCheckRequest(test_server_.get());
 
@@ -1923,25 +1925,26 @@
   const base::FilePath crx_path = GetInstallerPath(kAppCRX);
   ExpectAppsUpdateSequence(
       UpdaterScope::kSystem, test_server_.get(),
+      /*request_attributes=*/{},
       {
           AppUpdateExpectation(BuildCommandLineArgs(GetTestScope(), kAppId1,
                                                     kApp1UpdatedVersion),
                                kAppId1, kApp1InitialVersion,
                                kApp1UpdatedVersion,
                                /*is_install=*/false,
-                               /*should_update=*/true, false, "", crx_path),
+                               /*should_update=*/true, false, "", "", crx_path),
           AppUpdateExpectation(BuildCommandLineArgs(GetTestScope(), kAppId2,
                                                     kApp2UpdatedVersion),
                                kAppId2, kApp2InitialVersion,
                                kApp2UpdatedVersion,
                                /*is_install=*/false,
-                               /*should_update=*/true, false, "", crx_path),
-          AppUpdateExpectation(BuildCommandLineArgs(GetTestScope(), kAppId3,
-                                                    kApp3UpdatedVersion),
-                               kAppId3, kApp3InitialVersion,
-                               kApp3UpdatedVersion,
-                               /*is_install=*/false,
-                               /*should_update=*/false, false, "", crx_path),
+                               /*should_update=*/true, false, "", "", crx_path),
+          AppUpdateExpectation(
+              BuildCommandLineArgs(GetTestScope(), kAppId3,
+                                   kApp3UpdatedVersion),
+              kAppId3, kApp3InitialVersion, kApp3UpdatedVersion,
+              /*is_install=*/false,
+              /*should_update=*/false, false, "", "", crx_path),
       });
   ASSERT_NO_FATAL_FAILURE(RunWake(0));
   ASSERT_TRUE(WaitForUpdaterExit());
@@ -1969,10 +1972,16 @@
   ASSERT_NO_FATAL_FAILURE(InstallAppWithVersion(kAppId3, kApp3InitialVersion));
 
   base::Value::Dict policies;
-  policies.Set("Default", base::Value::Dict().Set("Update", kPolicyDisabled));
-  policies.Set(kAppId1, base::Value::Dict().Set("Update", kPolicyDisabled));
+  policies.Set("", base::Value::Dict()
+                       .Set("UpdateDefault", kPolicyDisabled)
+                       .Set("DownloadPreference", "cacheable"));
+  policies.Set(kAppId1, base::Value::Dict()
+                            .Set("Update", kPolicyDisabled)
+                            .Set("TargetChannel", "beta"));
   policies.Set(kAppId2, base::Value::Dict().Set("Update", kPolicyEnabled));
-  policies.Set(kAppId3, base::Value::Dict().Set("Update", kPolicyEnabled));
+  policies.Set(kAppId3, base::Value::Dict()
+                            .Set("Update", kPolicyEnabled)
+                            .Set("TargetChannel", "canary"));
   ASSERT_NO_FATAL_FAILURE(SetPlatformPolicies(policies));
 
   // Overrides app1 to auto-update, app2 to manual-update with cloud policy.
@@ -1983,6 +1992,7 @@
   ApplicationSettings app1;
   app1.set_app_guid(kAppId1);
   app1.set_update(enterprise_management::AUTOMATIC_UPDATES_ONLY);
+  app1.set_target_channel("beta_canary");
   omaha_settings.mutable_application_settings()->Add(std::move(app1));
   ApplicationSettings app2;
   app2.set_app_guid(kAppId2);
@@ -1994,25 +2004,26 @@
   const base::FilePath crx_path = GetInstallerPath(kAppCRX);
   ExpectAppsUpdateSequence(
       UpdaterScope::kSystem, test_server_.get(),
+      /*request_attributes=*/base::Value::Dict().Set("dlpref", "cacheable"),
       {
-          AppUpdateExpectation(BuildCommandLineArgs(GetTestScope(), kAppId1,
-                                                    kApp1UpdatedVersion),
-                               kAppId1, kApp1InitialVersion,
-                               kApp1UpdatedVersion,
-                               /*is_install=*/false,
-                               /*should_update=*/true, false, "", crx_path),
-          AppUpdateExpectation(BuildCommandLineArgs(GetTestScope(), kAppId2,
-                                                    kApp2UpdatedVersion),
-                               kAppId2, kApp2InitialVersion,
-                               kApp2InitialVersion,
-                               /*is_install=*/false,
-                               /*should_update=*/false, false, "", crx_path),
-          AppUpdateExpectation(BuildCommandLineArgs(GetTestScope(), kAppId3,
-                                                    kApp3UpdatedVersion),
-                               kAppId3, kApp3InitialVersion,
-                               kApp3UpdatedVersion,
-                               /*is_install=*/false,
-                               /*should_update=*/true, false, "", crx_path),
+          AppUpdateExpectation(
+              BuildCommandLineArgs(GetTestScope(), kAppId1,
+                                   kApp1UpdatedVersion),
+              kAppId1, kApp1InitialVersion, kApp1UpdatedVersion,
+              /*is_install=*/false,
+              /*should_update=*/true, false, "", "beta_canary", crx_path),
+          AppUpdateExpectation(
+              BuildCommandLineArgs(GetTestScope(), kAppId2,
+                                   kApp2UpdatedVersion),
+              kAppId2, kApp2InitialVersion, kApp2InitialVersion,
+              /*is_install=*/false,
+              /*should_update=*/false, false, "", "", crx_path),
+          AppUpdateExpectation(
+              BuildCommandLineArgs(GetTestScope(), kAppId3,
+                                   kApp3UpdatedVersion),
+              kAppId3, kApp3InitialVersion, kApp3UpdatedVersion,
+              /*is_install=*/false,
+              /*should_update=*/true, false, "", "canary", crx_path),
       });
   ASSERT_NO_FATAL_FAILURE(RunWake(0));
   ASSERT_TRUE(WaitForUpdaterExit());
@@ -2049,12 +2060,13 @@
 
   ExpectAppsUpdateSequence(
       UpdaterScope::kSystem, test_server_.get(),
+      /*request_attributes=*/{},
       {AppUpdateExpectation(
           BuildCommandLineArgs(GetTestScope(), kAppId1, kAppRollbackVersion),
           kAppId1, kAppInitialVersion, kAppRollbackVersion,
           /*is_install=*/false,
           /*should_update=*/true, /*allow_rollback=*/true, kTargetVersionPrefix,
-          GetInstallerPath(kAppCRX))});
+          "", GetInstallerPath(kAppCRX))});
   ASSERT_NO_FATAL_FAILURE(RunWake(0));
   ASSERT_TRUE(WaitForUpdaterExit());
   ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId1, kAppRollbackVersion));
@@ -2143,11 +2155,12 @@
   const base::FilePath crx_path = GetInstallerPath(kMsiCrx);
   ExpectAppsUpdateSequence(
       UpdaterScope::kSystem, test_server_.get(),
+      /*request_attributes=*/{},
       {
           AppUpdateExpectation({}, kMsiAppId, base::Version({0, 0, 0, 0}),
                                kMsiUpdatedVersion,
                                /*is_install=*/true,
-                               /*should_update=*/true, false, "", crx_path),
+                               /*should_update=*/true, false, "", "", crx_path),
       });
 
   ASSERT_NO_FATAL_FAILURE(InstallAppViaService(kMsiAppId));
@@ -2160,11 +2173,12 @@
   const base::FilePath crx_path = GetInstallerPath(kMsiCrx);
   ExpectAppsUpdateSequence(
       UpdaterScope::kSystem, test_server_.get(),
+      /*request_attributes=*/{},
       {
           AppUpdateExpectation({}, kMsiAppId, base::Version({0, 0, 0, 0}),
                                kMsiUpdatedVersion,
                                /*is_install=*/true,
-                               /*should_update=*/true, false, "", crx_path),
+                               /*should_update=*/true, false, "", "", crx_path),
       });
 
   ASSERT_NO_FATAL_FAILURE(InstallUpdaterAndApp(
@@ -2185,11 +2199,12 @@
   const base::FilePath crx_path = GetInstallerPath(kMsiCrx);
   ExpectAppsUpdateSequence(
       UpdaterScope::kSystem, test_server_.get(),
+      /*request_attributes=*/{},
       {
           AppUpdateExpectation({}, kMsiAppId, kMsiInitialVersion,
                                kMsiUpdatedVersion,
                                /*is_install=*/false,
-                               /*should_update=*/true, false, "", crx_path),
+                               /*should_update=*/true, false, "", "", crx_path),
       });
   ASSERT_NO_FATAL_FAILURE(RunWake(0));
   ASSERT_TRUE(WaitForUpdaterExit());
@@ -2286,11 +2301,12 @@
 
   ExpectAppsUpdateSequence(
       UpdaterScope::kSystem, test_server_.get(),
+      /*request_attributes=*/{},
       {
           AppUpdateExpectation(
               GetParam().command_line_args, kMsiAppId,
               base::Version({0, 0, 0, 0}), kMsiUpdatedVersion,
-              /*is_install=*/true, should_install_successfully, false, "",
+              /*is_install=*/true, should_install_successfully, false, "", "",
               crx_relative_path,
               /*always_serve_crx=*/true, UpdateService::ErrorCategory::kInstall,
               GetParam().error_code, /*EVENT_INSTALL_COMPLETE=*/2),
diff --git a/chrome/updater/test/integration_tests_impl.cc b/chrome/updater/test/integration_tests_impl.cc
index c3643f5a..4dde4b8 100644
--- a/chrome/updater/test/integration_tests_impl.cc
+++ b/chrome/updater/test/integration_tests_impl.cc
@@ -330,6 +330,7 @@
     bool should_update,
     bool allow_rollback,
     const std::string& target_version_prefix,
+    const std::string& target_channel,
     const base::FilePath& crx_relative_path,
     bool always_serve_crx,
     const UpdateService::ErrorCategory error_category,
@@ -343,6 +344,7 @@
       should_update(should_update),
       allow_rollback(allow_rollback),
       target_version_prefix(target_version_prefix),
+      target_channel(target_channel),
       crx_relative_path(crx_relative_path),
       always_serve_crx(always_serve_crx),
       error_category(error_category),
@@ -524,6 +526,7 @@
 
 void ExpectAppsUpdateSequence(UpdaterScope scope,
                               ScopedServer* test_server,
+                              const base::Value::Dict& request_attributes,
                               const std::vector<AppUpdateExpectation>& apps) {
 #if BUILDFLAG(IS_WIN)
   const base::FilePath::StringType kExeExtension = FILE_PATH_LITERAL(".exe");
@@ -535,12 +538,21 @@
   ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &exe_path));
 
   // First request: update check.
+  std::vector<std::string> attributes;
+  for (const auto [key, value] : request_attributes) {
+    attributes.push_back(base::StringPrintf(R"("%s":"%s")", key.c_str(),
+                                            value.GetString().c_str()));
+  }
   std::vector<std::string> app_requests;
   std::vector<std::string> app_responses;
   for (const AppUpdateExpectation& app : apps) {
-    const base::FilePath crx_path = exe_path.Append(app.crx_relative_path);
     app_requests.push_back(
         base::StringPrintf(R"("appid":"%s")", app.app_id.c_str()));
+    if (!app.target_channel.empty()) {
+      app_requests.push_back(base::StringPrintf(R"("release_channel":"%s",)",
+                                                app.target_channel.c_str()));
+    }
+    const base::FilePath crx_path = exe_path.Append(app.crx_relative_path);
     const base::FilePath base_name = crx_path.BaseName().RemoveExtension();
     const base::FilePath run_action =
         base_name.Extension().empty() ? base_name.AddExtension(kExeExtension)
@@ -551,6 +563,7 @@
   }
   test_server->ExpectOnce({request::GetPathMatcher(test_server->update_path()),
                            request::GetUpdaterUserAgentMatcher(),
+                           request::GetContentMatcher(attributes),
                            request::GetContentMatcher(app_requests),
                            request::GetScopeMatcher(scope)},
                           GetUpdateResponse(app_responses));
diff --git a/chrome/updater/test/integration_tests_impl.h b/chrome/updater/test/integration_tests_impl.h
index b65faf02..4ba0a994 100644
--- a/chrome/updater/test/integration_tests_impl.h
+++ b/chrome/updater/test/integration_tests_impl.h
@@ -50,6 +50,7 @@
                        bool should_update,
                        bool allow_rollback,
                        const std::string& target_version_prefix,
+                       const std::string& target_channel,
                        const base::FilePath& crx_relative_path,
                        bool always_serve_crx = false,
                        const UpdateService::ErrorCategory error_category =
@@ -68,6 +69,7 @@
   const bool should_update;
   const bool allow_rollback;
   const std::string target_version_prefix;
+  const std::string target_channel;
   const base::FilePath crx_relative_path;
   const bool always_serve_crx;
   const UpdateService::ErrorCategory error_category;
@@ -338,6 +340,7 @@
 
 void ExpectAppsUpdateSequence(UpdaterScope scope,
                               ScopedServer* test_server,
+                              const base::Value::Dict& request_attributes,
                               const std::vector<AppUpdateExpectation>& apps);
 
 void StressUpdateService(UpdaterScope scope);
diff --git a/chrome/updater/util/win_util.cc b/chrome/updater/util/win_util.cc
index 291b1d0..2197f87 100644
--- a/chrome/updater/util/win_util.cc
+++ b/chrome/updater/util/win_util.cc
@@ -35,6 +35,7 @@
 #include "base/memory/free_deleter.h"
 #include "base/path_service.h"
 #include "base/process/kill.h"
+#include "base/process/launch.h"
 #include "base/process/process.h"
 #include "base/process/process_iterator.h"
 #include "base/ranges/algorithm.h"
@@ -1053,4 +1054,21 @@
       .AppendASCII(PRODUCT_FULLNAME_STRING);
 }
 
+absl::optional<std::wstring> GetRegKeyContents(const std::wstring& reg_key) {
+  base::FilePath system_path;
+  if (!base::PathService::Get(base::DIR_SYSTEM, &system_path)) {
+    return {};
+  }
+
+  std::string output;
+  if (!base::GetAppOutput(
+          base::StrCat({system_path.Append(L"reg.exe").value(), L" query ",
+                        base::CommandLine::QuoteForCommandLineToArgvW(reg_key),
+                        L" /s"}),
+          &output)) {
+    return {};
+  }
+  return base::ASCIIToWide(output);
+}
+
 }  // namespace updater
diff --git a/chrome/updater/util/win_util.h b/chrome/updater/util/win_util.h
index f96e8ecb..dd3710d 100644
--- a/chrome/updater/util/win_util.h
+++ b/chrome/updater/util/win_util.h
@@ -433,6 +433,9 @@
 [[nodiscard]] absl::optional<base::FilePath> GetInstallDirectoryX86(
     UpdaterScope scope);
 
+// Gets the contents under a given registry key.
+absl::optional<std::wstring> GetRegKeyContents(const std::wstring& reg_key);
+
 }  // namespace updater
 
 #endif  // CHROME_UPDATER_UTIL_WIN_UTIL_H_
diff --git a/chrome/updater/util/win_util_unittest.cc b/chrome/updater/util/win_util_unittest.cc
index b09f7d4a6..9ef570db 100644
--- a/chrome/updater/util/win_util_unittest.cc
+++ b/chrome/updater/util/win_util_unittest.cc
@@ -527,4 +527,34 @@
   DeleteAppClientStateKey(GetTestScope(), base::ASCIIToWide(kTestAppID));
 }
 
+struct WinUtilGetRegKeyContentsTestCase {
+  const std::wstring reg_key;
+  const std::wstring expected_substring;
+};
+
+class WinUtilGetRegKeyContentsTest
+    : public ::testing::TestWithParam<WinUtilGetRegKeyContentsTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(
+    WinUtilGetRegKeyContentsTestCases,
+    WinUtilGetRegKeyContentsTest,
+    ::testing::ValuesIn(std::vector<WinUtilGetRegKeyContentsTestCase>{
+        {L"HKLM\\SOFTWARE\\Classes\\CLSID\\{00020424-0000-0000-C000-"
+         L"000000000046}",
+         L"{00020424-0000-0000-C000-000000000046}"},
+        {L"HKLM\\SOFTWARE\\WOW6432Node\\Classes\\CLSID\\{00020424-0000-0000-"
+         L"C000-000000000046}",
+         L"{00020424-0000-0000-C000-000000000046}"},
+        {L"HKCR\\CLSID\\{00020424-0000-0000-C000-000000000046}",
+         L"{00020424-0000-0000-C000-000000000046}"},
+        {L"HKCR\\WOW6432Node\\CLSID\\{00020424-0000-0000-C000-000000000046}",
+         L"{00020424-0000-0000-C000-000000000046}"},
+    }));
+
+TEST_P(WinUtilGetRegKeyContentsTest, TestCases) {
+  absl::optional<std::wstring> contents = GetRegKeyContents(GetParam().reg_key);
+  ASSERT_TRUE(contents);
+  ASSERT_NE(contents->find(GetParam().expected_substring), std::wstring::npos);
+}
+
 }  // namespace updater
diff --git a/chromeos/ash/components/settings/cros_settings_names.cc b/chromeos/ash/components/settings/cros_settings_names.cc
index d553703..e7556cc 100644
--- a/chromeos/ash/components/settings/cros_settings_names.cc
+++ b/chromeos/ash/components/settings/cros_settings_names.cc
@@ -615,9 +615,4 @@
 const char kDeviceHindiInscriptLayoutEnabled[] =
     "cros.device.hindi_inscript_layout_enabled";
 
-// A list of strings representing DLC identifiers to be pre downloaded on the
-// device.
-const char kDeviceDlcPredownloadList[] =
-    "cros.device.device_dlc_predownload_list";
-
 }  // namespace ash
diff --git a/chromeos/ash/components/settings/cros_settings_names.h b/chromeos/ash/components/settings/cros_settings_names.h
index 9d36f78..5c82307d 100644
--- a/chromeos/ash/components/settings/cros_settings_names.h
+++ b/chromeos/ash/components/settings/cros_settings_names.h
@@ -396,9 +396,6 @@
 COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_SETTINGS)
 extern const char kDeviceHindiInscriptLayoutEnabled[];
 
-COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_SETTINGS)
-extern const char kDeviceDlcPredownloadList[];
-
 }  // namespace ash
 
 namespace chromeos {
diff --git a/chromeos/ash/services/multidevice_setup/android_sms_app_installing_status_observer.cc b/chromeos/ash/services/multidevice_setup/android_sms_app_installing_status_observer.cc
index b525557..45ff066f 100644
--- a/chromeos/ash/services/multidevice_setup/android_sms_app_installing_status_observer.cc
+++ b/chromeos/ash/services/multidevice_setup/android_sms_app_installing_status_observer.cc
@@ -86,8 +86,7 @@
     DoesFeatureStateAllowInstallation() {
   mojom::FeatureState feature_state =
       feature_state_manager_->GetFeatureStates()[mojom::Feature::kMessages];
-  if (feature_state != mojom::FeatureState::kEnabledByUser &&
-      feature_state != mojom::FeatureState::kFurtherSetupRequired) {
+  if (feature_state != mojom::FeatureState::kEnabledByUser) {
     return false;
   }
 
diff --git a/chromeos/ash/services/multidevice_setup/feature_state_manager.cc b/chromeos/ash/services/multidevice_setup/feature_state_manager.cc
index c579be49..c422f1e4 100644
--- a/chromeos/ash/services/multidevice_setup/feature_state_manager.cc
+++ b/chromeos/ash/services/multidevice_setup/feature_state_manager.cc
@@ -20,9 +20,7 @@
 
   // Changing the state is only allowed when changing from enabled to disabled
   // or disabled to enabled.
-  if ((((state == mojom::FeatureState::kEnabledByUser) ||
-        (state == mojom::FeatureState::kFurtherSetupRequired)) &&
-       !enabled) ||
+  if (((state == mojom::FeatureState::kEnabledByUser) && !enabled) ||
       (state == mojom::FeatureState::kDisabledByUser && enabled)) {
     PerformSetFeatureEnabledState(feature, enabled);
     return true;
diff --git a/chromeos/ash/services/multidevice_setup/feature_state_manager.h b/chromeos/ash/services/multidevice_setup/feature_state_manager.h
index 91bcb56..d54b1de 100644
--- a/chromeos/ash/services/multidevice_setup/feature_state_manager.h
+++ b/chromeos/ash/services/multidevice_setup/feature_state_manager.h
@@ -39,8 +39,7 @@
 
   // Attempts to enable or disable the feature; returns whether this operation
   // succeeded. A feature can only be changed via this function if the current
-  // state is mojom::FeatureState::kEnabledByUser,
-  // mojom::FeatureState::kFurtherSetupRequired or
+  // state is mojom::FeatureState::kEnabledByUser or
   // mojom::FeatureState::kDisabledByUser.
   bool SetFeatureEnabledState(mojom::Feature feature, bool enabled);
 
diff --git a/chromeos/ash/services/multidevice_setup/feature_state_manager_impl.cc b/chromeos/ash/services/multidevice_setup/feature_state_manager_impl.cc
index 2aa7bfd..18b2d1c 100644
--- a/chromeos/ash/services/multidevice_setup/feature_state_manager_impl.cc
+++ b/chromeos/ash/services/multidevice_setup/feature_state_manager_impl.cc
@@ -40,7 +40,6 @@
       {mojom::Feature::kBetterTogetherSuite,
        kBetterTogetherSuiteEnabledPrefName},
       {mojom::Feature::kInstantTethering, kInstantTetheringEnabledPrefName},
-      {mojom::Feature::kMessages, kMessagesEnabledPrefName},
       {mojom::Feature::kSmartLock, kSmartLockEnabledPrefName},
       {mojom::Feature::kPhoneHub, kPhoneHubEnabledPrefName},
       {mojom::Feature::kPhoneHubCameraRoll, kPhoneHubCameraRollEnabledPrefName},
@@ -55,7 +54,6 @@
 GenerateFeatureToAllowedPrefNameMap() {
   return base::flat_map<mojom::Feature, std::string>{
       {mojom::Feature::kInstantTethering, kInstantTetheringAllowedPrefName},
-      {mojom::Feature::kMessages, kMessagesAllowedPrefName},
       {mojom::Feature::kSmartLock, kSmartLockAllowedPrefName},
       {mojom::Feature::kPhoneHub, kPhoneHubAllowedPrefName},
       {mojom::Feature::kPhoneHubCameraRoll, kPhoneHubCameraRollAllowedPrefName},
@@ -76,8 +74,6 @@
        mojom::FeatureState::kUnavailableNoVerifiedHost_NoEligibleHosts},
       {mojom::Feature::kInstantTethering,
        mojom::FeatureState::kUnavailableNoVerifiedHost_NoEligibleHosts},
-      {mojom::Feature::kMessages,
-       mojom::FeatureState::kUnavailableNoVerifiedHost_NoEligibleHosts},
       {mojom::Feature::kSmartLock,
        mojom::FeatureState::kUnavailableNoVerifiedHost_NoEligibleHosts},
       {mojom::Feature::kPhoneHub,
@@ -157,8 +153,7 @@
       mojom::FeatureState::kDisabledByUser) {
     for (auto& map_entry : feature_states_map) {
       mojom::FeatureState& feature_state = map_entry.second;
-      if (feature_state == mojom::FeatureState::kEnabledByUser ||
-          feature_state == mojom::FeatureState::kFurtherSetupRequired) {
+      if (feature_state == mojom::FeatureState::kEnabledByUser) {
         feature_state = mojom::FeatureState::kUnavailableSuiteDisabled;
       }
     }
@@ -389,10 +384,6 @@
     return mojom::FeatureState::kNotSupportedByPhone;
   }
 
-  if (RequiresFurtherSetup(feature)) {
-    return mojom::FeatureState::kFurtherSetupRequired;
-  }
-
   return GetEnabledOrDisabledState(feature);
 }
 
@@ -417,8 +408,6 @@
            multidevice::SoftwareFeature::kBetterTogetherClient},
           {mojom::Feature::kInstantTethering,
            multidevice::SoftwareFeature::kInstantTetheringClient},
-          {mojom::Feature::kMessages,
-           multidevice::SoftwareFeature::kMessagesForWebClient},
           {mojom::Feature::kSmartLock,
            multidevice::SoftwareFeature::kSmartLockClient},
           // Note: Most Phone Hub-related features use the same SoftwareFeature.
@@ -486,8 +475,6 @@
            multidevice::SoftwareFeature::kBetterTogetherHost},
           {mojom::Feature::kInstantTethering,
            multidevice::SoftwareFeature::kInstantTetheringHost},
-          {mojom::Feature::kMessages,
-           multidevice::SoftwareFeature::kMessagesForWebHost},
           {mojom::Feature::kSmartLock,
            multidevice::SoftwareFeature::kSmartLockHost},
           // Note: Most Phone Hub-related features use the same SoftwareFeature.
@@ -564,22 +551,6 @@
   return false;
 }
 
-// TODO(khorimoto): Add a way to determine whether Phone Hub notification
-// access has been granted by the user on the phone.
-bool FeatureStateManagerImpl::RequiresFurtherSetup(mojom::Feature feature) {
-  if (feature != mojom::Feature::kMessages) {
-    return false;
-  }
-
-  if (GetEnabledOrDisabledState(feature) ==
-      mojom::FeatureState::kDisabledByUser) {
-    return false;
-  }
-
-  return android_sms_pairing_state_tracker_ &&
-         !android_sms_pairing_state_tracker_->IsAndroidSmsPairingComplete();
-}
-
 mojom::FeatureState FeatureStateManagerImpl::GetEnabledOrDisabledState(
     mojom::Feature feature) {
   if (global_state_feature_managers_.contains(feature)) {
@@ -609,9 +580,6 @@
       cached_feature_state_map_.find(mojom::Feature::kInstantTethering)
           ->second);
   base::UmaHistogramEnumeration(
-      "AndroidSms.MultiDeviceFeatureState",
-      cached_feature_state_map_.find(mojom::Feature::kMessages)->second);
-  base::UmaHistogramEnumeration(
       "SmartLock.MultiDeviceFeatureState",
       cached_feature_state_map_.find(mojom::Feature::kSmartLock)->second);
   base::UmaHistogramEnumeration(
diff --git a/chromeos/ash/services/multidevice_setup/feature_state_manager_impl_unittest.cc b/chromeos/ash/services/multidevice_setup/feature_state_manager_impl_unittest.cc
index e15646c3..116df03 100644
--- a/chromeos/ash/services/multidevice_setup/feature_state_manager_impl_unittest.cc
+++ b/chromeos/ash/services/multidevice_setup/feature_state_manager_impl_unittest.cc
@@ -44,9 +44,6 @@
   raw_device->software_features
       [multidevice::SoftwareFeature::kInstantTetheringClient] =
       multidevice::SoftwareFeatureState::kNotSupported;
-  raw_device
-      ->software_features[multidevice::SoftwareFeature::kMessagesForWebClient] =
-      multidevice::SoftwareFeatureState::kNotSupported;
   raw_device->software_features[multidevice::SoftwareFeature::kPhoneHubClient] =
       multidevice::SoftwareFeatureState::kNotSupported;
   raw_device->software_features[multidevice::SoftwareFeature::kWifiSyncClient] =
@@ -71,9 +68,6 @@
   raw_device
       ->software_features[multidevice::SoftwareFeature::kInstantTetheringHost] =
       multidevice::SoftwareFeatureState::kSupported;
-  raw_device
-      ->software_features[multidevice::SoftwareFeature::kMessagesForWebHost] =
-      multidevice::SoftwareFeatureState::kSupported;
   raw_device->software_features[multidevice::SoftwareFeature::kPhoneHubHost] =
       multidevice::SoftwareFeatureState::kSupported;
   raw_device->software_features[multidevice::SoftwareFeature::kWifiSyncHost] =
@@ -309,9 +303,6 @@
                           multidevice::SoftwareFeature::kSmartLockClient,
                           multidevice::SoftwareFeatureState::kSupported);
   SetSoftwareFeatureState(true /* use_local_device */,
-                          multidevice::SoftwareFeature::kMessagesForWebClient,
-                          multidevice::SoftwareFeatureState::kSupported);
-  SetSoftwareFeatureState(true /* use_local_device */,
                           multidevice::SoftwareFeature::kPhoneHubClient,
                           multidevice::SoftwareFeatureState::kSupported);
   SetSoftwareFeatureState(true /* use_local_device */,
@@ -324,8 +315,6 @@
   VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
                      mojom::Feature::kInstantTethering);
   VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
-                     mojom::Feature::kMessages);
-  VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
                      mojom::Feature::kSmartLock);
   VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
                      mojom::Feature::kPhoneHub);
@@ -367,9 +356,6 @@
                           multidevice::SoftwareFeature::kSmartLockClient,
                           multidevice::SoftwareFeatureState::kSupported);
   SetSoftwareFeatureState(true /* use_local_device */,
-                          multidevice::SoftwareFeature::kMessagesForWebClient,
-                          multidevice::SoftwareFeatureState::kSupported);
-  SetSoftwareFeatureState(true /* use_local_device */,
                           multidevice::SoftwareFeature::kPhoneHubClient,
                           multidevice::SoftwareFeatureState::kSupported);
   SetSoftwareFeatureState(true /* use_local_device */,
@@ -379,27 +365,26 @@
   // Now, the suite should be considered enabled.
   VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
                      mojom::Feature::kBetterTogetherSuite);
-  VerifyFeatureStateChange(6u /* expected_index */,
+  VerifyFeatureStateChange(5u /* expected_index */,
                            mojom::Feature::kBetterTogetherSuite,
                            mojom::FeatureState::kEnabledByUser);
 
   test_pref_service()->SetBoolean(kBetterTogetherSuiteEnabledPrefName, false);
   VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
                      mojom::Feature::kBetterTogetherSuite);
-  VerifyFeatureStateChange(7u /* expected_index */,
+  VerifyFeatureStateChange(6u /* expected_index */,
                            mojom::Feature::kBetterTogetherSuite,
                            mojom::FeatureState::kDisabledByUser);
 
   // Set all features to prohibited. This should cause the Better Together suite
   // to become prohibited as well.
   test_pref_service()->SetBoolean(kInstantTetheringAllowedPrefName, false);
-  test_pref_service()->SetBoolean(kMessagesAllowedPrefName, false);
   test_pref_service()->SetBoolean(kSmartLockAllowedPrefName, false);
   test_pref_service()->SetBoolean(kPhoneHubAllowedPrefName, false);
   test_pref_service()->SetBoolean(kWifiSyncAllowedPrefName, false);
   VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
                      mojom::Feature::kBetterTogetherSuite);
-  VerifyFeatureStateChange(12u /* expected_index */,
+  VerifyFeatureStateChange(10u /* expected_index */,
                            mojom::Feature::kBetterTogetherSuite,
                            mojom::FeatureState::kProhibitedByPolicy);
 }
@@ -431,9 +416,6 @@
                           multidevice::SoftwareFeature::kSmartLockClient,
                           multidevice::SoftwareFeatureState::kSupported);
   SetSoftwareFeatureState(true /* use_local_device */,
-                          multidevice::SoftwareFeature::kMessagesForWebClient,
-                          multidevice::SoftwareFeatureState::kSupported);
-  SetSoftwareFeatureState(true /* use_local_device */,
                           multidevice::SoftwareFeature::kPhoneHubClient,
                           multidevice::SoftwareFeatureState::kSupported);
   SetSoftwareFeatureState(true /* use_local_device */,
@@ -443,27 +425,26 @@
   // Now, the suite should be considered enabled.
   VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
                      mojom::Feature::kBetterTogetherSuite);
-  VerifyFeatureStateChange(5u /* expected_index */,
+  VerifyFeatureStateChange(4u /* expected_index */,
                            mojom::Feature::kBetterTogetherSuite,
                            mojom::FeatureState::kEnabledByUser);
 
   test_pref_service()->SetBoolean(kBetterTogetherSuiteEnabledPrefName, false);
   VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
                      mojom::Feature::kBetterTogetherSuite);
-  VerifyFeatureStateChange(6u /* expected_index */,
+  VerifyFeatureStateChange(5u /* expected_index */,
                            mojom::Feature::kBetterTogetherSuite,
                            mojom::FeatureState::kDisabledByUser);
 
   // Set all features to prohibited. This should cause the Better Together suite
   // to become prohibited as well.
   test_pref_service()->SetBoolean(kInstantTetheringAllowedPrefName, false);
-  test_pref_service()->SetBoolean(kMessagesAllowedPrefName, false);
   test_pref_service()->SetBoolean(kSmartLockAllowedPrefName, false);
   test_pref_service()->SetBoolean(kPhoneHubAllowedPrefName, false);
   test_pref_service()->SetBoolean(kWifiSyncAllowedPrefName, false);
   VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
                      mojom::Feature::kBetterTogetherSuite);
-  VerifyFeatureStateChange(11u /* expected_index */,
+  VerifyFeatureStateChange(9u /* expected_index */,
                            mojom::Feature::kBetterTogetherSuite,
                            mojom::FeatureState::kProhibitedByPolicy);
 }
@@ -517,67 +498,6 @@
                            mojom::FeatureState::kProhibitedByPolicy);
 }
 
-TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, Messages) {
-  SetupFeatureStateManager();
-
-  TryAllUnverifiedHostStatesAndVerifyFeatureState(mojom::Feature::kMessages);
-
-  SetVerifiedHost();
-  VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
-                     mojom::Feature::kMessages);
-
-  SetSoftwareFeatureState(true /* use_local_device */,
-                          multidevice::SoftwareFeature::kMessagesForWebClient,
-                          multidevice::SoftwareFeatureState::kSupported);
-  VerifyFeatureState(mojom::FeatureState::kNotSupportedByPhone,
-                     mojom::Feature::kMessages);
-  VerifyFeatureStateChange(2u /* expected_index */, mojom::Feature::kMessages,
-                           mojom::FeatureState::kNotSupportedByPhone);
-
-  SetSoftwareFeatureState(false /* use_local_device */,
-                          multidevice::SoftwareFeature::kMessagesForWebHost,
-                          multidevice::SoftwareFeatureState::kEnabled);
-  VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
-                     mojom::Feature::kMessages);
-  VerifyFeatureStateChange(3u /* expected_index */, mojom::Feature::kMessages,
-                           mojom::FeatureState::kEnabledByUser);
-
-  SetAndroidSmsPairingState(false /* is_paired */);
-  VerifyFeatureState(mojom::FeatureState::kFurtherSetupRequired,
-                     mojom::Feature::kMessages);
-  VerifyFeatureStateChange(4u /* expected_index */, mojom::Feature::kMessages,
-                           mojom::FeatureState::kFurtherSetupRequired);
-
-  SetAndroidSmsPairingState(true /* is_paired */);
-  VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
-                     mojom::Feature::kMessages);
-  VerifyFeatureStateChange(5u /* expected_index */, mojom::Feature::kMessages,
-                           mojom::FeatureState::kEnabledByUser);
-
-  SetAndroidSmsPairingState(false /* is_paired */);
-  MakeBetterTogetherSuiteDisabledByUser();
-  VerifyFeatureState(mojom::FeatureState::kUnavailableSuiteDisabled,
-                     mojom::Feature::kMessages);
-  VerifyFeatureStateChange(8u /* expected_index */, mojom::Feature::kMessages,
-                           mojom::FeatureState::kUnavailableSuiteDisabled);
-
-  SetAndroidSmsPairingState(true /* is_paired */);
-  VerifyFeatureState(mojom::FeatureState::kUnavailableSuiteDisabled,
-                     mojom::Feature::kMessages);
-
-  test_pref_service()->SetBoolean(kMessagesEnabledPrefName, false);
-  VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
-                     mojom::Feature::kMessages);
-  VerifyFeatureStateChange(9u /* expected_index */, mojom::Feature::kMessages,
-                           mojom::FeatureState::kDisabledByUser);
-
-  test_pref_service()->SetBoolean(kMessagesAllowedPrefName, false);
-  VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
-                     mojom::Feature::kMessages);
-  VerifyFeatureStateChange(10u /* expected_index */, mojom::Feature::kMessages,
-                           mojom::FeatureState::kProhibitedByPolicy);
-}
-
 TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, SmartLock) {
   SetupFeatureStateManager();
 
diff --git a/chromeos/ash/services/multidevice_setup/public/mojom/multidevice_setup.mojom b/chromeos/ash/services/multidevice_setup/public/mojom/multidevice_setup.mojom
index 9dad7ae..8390bb12 100644
--- a/chromeos/ash/services/multidevice_setup/public/mojom/multidevice_setup.mojom
+++ b/chromeos/ash/services/multidevice_setup/public/mojom/multidevice_setup.mojom
@@ -108,9 +108,7 @@
   // because the entire Better Together suite has been disabled by the user.
   kUnavailableSuiteDisabled = 7,
 
-  // The feature still requires further setup to be ready for use (e.g., Android
-  // Messages requires a separate pairing flow after unified setup).
-  kFurtherSetupRequired = 8,
+  // kFurtherSetupRequired (8) is deprecated.
 
   // The feature has been enabled by the user, but it is still unavailable
   // because it is a sub-feature of a top-level feature, and that top-level
diff --git a/clank b/clank
index 340aed4..da219a1 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit 340aed4c542ac53f950fd007ee452c3f1099739f
+Subproject commit da219a17d5eabce16b35e68f276e7d265377236b
diff --git a/components/BUILD.gn b/components/BUILD.gn
index df03872..8d6f027 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -463,6 +463,7 @@
       "//components/reporting/resources:unit_tests",
       "//components/services/heap_profiling:unit_tests",
       "//components/services/storage:tests",
+      "//components/session_proto_db:unit_tests",
       "//components/subresource_filter/content/common:unit_tests",
       "//components/subresource_filter/content/renderer:unit_tests",
       "//components/tracing:unit_tests",
@@ -533,7 +534,6 @@
       "//components/permissions/prediction_service:unit_tests",
       "//components/privacy_sandbox:unit_tests",
       "//components/privacy_sandbox/privacy_sandbox_attestations:unit_tests",
-      "//components/session_proto_db:unit_tests",
 
       # TODO(chromium: 1169835) components / reporting / storage / resources: unit_tests
       # can't be run on iOS until they are updated.
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
index 5a2d1993..0bf2b38d 100644
--- a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
@@ -83,6 +83,10 @@
 #include "content/public/test/mock_navigation_handle.h"
 #endif
 
+#if BUILDFLAG(IS_ANDROID)
+#include "base/android/build_info.h"
+#endif
+
 using base::ASCIIToUTF16;
 using testing::NiceMock;
 
@@ -644,6 +648,14 @@
     CreditCardAccessManagerTest::SetUp();
     feature_list_.InitWithFeatureState(
         features::kAutofillEnablePaymentsMandatoryReauth, FeatureFlagIsOn());
+#if BUILDFLAG(IS_ANDROID)
+    if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+      autofill_client_.GetPrefs()->SetBoolean(
+          prefs::kAutofillPaymentMethodsMandatoryReauth,
+          /*value=*/true);
+      return;
+    }
+#endif  // BUILDFLAG(IS_ANDROID)
     autofill_client_.GetPrefs()->SetBoolean(
         prefs::kAutofillPaymentMethodsMandatoryReauth,
         /*value=*/PrefIsEnabled());
@@ -659,6 +671,15 @@
 
   bool isBiometric() const { return std::get<3>(GetParam()); }
 
+  bool IsMandatoryReauthEnabled() {
+#if BUILDFLAG(IS_ANDROID)
+    if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+      return true;
+    }
+#endif
+    return FeatureFlagIsOn() && PrefIsEnabled();
+  }
+
   void SetUpDeviceAuthenticatorResponseMock() {
     if (isBiometric()) {
       ON_CALL(mandatory_reauth_manager(), GetAuthenticationMethod)
@@ -671,8 +692,8 @@
     }
 
     // We should only expect an AuthenticateWithMessage() call if the feature
-    // flag is on and the pref is enabled.
-    if (FeatureFlagIsOn() && PrefIsEnabled()) {
+    // flag is on and the pref is enabled, or if the device is automotive.
+    if (IsMandatoryReauthEnabled()) {
       ON_CALL(mandatory_reauth_manager(),
 #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
               AuthenticateWithMessage)
@@ -720,11 +741,9 @@
   SetUpDeviceAuthenticatorResponseMock();
   credit_card_access_manager().FetchCreditCard(card, accessor_->GetWeakPtr());
 
-  // The only time we should expect an error is if the feature flag is on, the
-  // pref is enabled, but the mandatory re-auth authentication was not
-  // successful.
-  if (FeatureFlagIsOn() && PrefIsEnabled() &&
-      !MandatoryReauthResponseIsSuccess()) {
+  // The only time we should expect an error is if mandatory re-auth is
+  // enabled, but the mandatory re-auth authentication was not successful.
+  if (IsMandatoryReauthEnabled() && !MandatoryReauthResponseIsSuccess()) {
     EXPECT_EQ(accessor_->result(), CreditCardFetchResult::kTransientError);
     EXPECT_TRUE(accessor_->number().empty());
   } else {
@@ -734,7 +753,7 @@
   std::string histogram_name =
       "Autofill.PaymentMethods.CheckoutFlow.ReauthUsage.LocalCard";
   histogram_name += isBiometric() ? ".Biometric" : ".ScreenLock";
-  if (FeatureFlagIsOn() && PrefIsEnabled()) {
+  if (IsMandatoryReauthEnabled()) {
     histogram_tester.ExpectBucketCount(
         histogram_name,
         autofill_metrics::MandatoryReauthAuthenticationFlowEvent::kFlowStarted,
@@ -782,8 +801,7 @@
       AutofillClient::PaymentsRpcResult::kSuccess, response);
 
   // Expect the accessor receives the correct response.
-  if (FeatureFlagIsOn() && PrefIsEnabled() &&
-      !MandatoryReauthResponseIsSuccess()) {
+  if (IsMandatoryReauthEnabled() && !MandatoryReauthResponseIsSuccess()) {
     EXPECT_EQ(accessor_->result(), CreditCardFetchResult::kTransientError);
   } else {
     EXPECT_EQ(accessor_->result(), CreditCardFetchResult::kSuccess);
@@ -795,7 +813,7 @@
   std::string histogram_name =
       "Autofill.PaymentMethods.CheckoutFlow.ReauthUsage.VirtualCard";
   histogram_name += isBiometric() ? ".Biometric" : ".ScreenLock";
-  if (FeatureFlagIsOn() && PrefIsEnabled()) {
+  if (IsMandatoryReauthEnabled()) {
     histogram_tester.ExpectBucketCount(
         histogram_name,
         autofill_metrics::MandatoryReauthAuthenticationFlowEvent::kFlowStarted,
@@ -821,6 +839,12 @@
 
 // Tests retrieving local cards.
 TEST_F(CreditCardAccessManagerTest, FetchLocalCardSuccess) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   CreateLocalCard(kTestGUID, kTestNumber);
   CreditCard* card = personal_data().GetCreditCardByGUID(kTestGUID);
 
@@ -2590,6 +2614,12 @@
 
 TEST_F(CreditCardAccessManagerTest, RiskBasedVirtualCardUnmasking_Success) {
   base::HistogramTester histogram_tester;
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   CreateServerCard(kTestGUID, kTestNumber, /*masked=*/false, kTestServerId);
   CreditCard* virtual_card = personal_data().GetCreditCardByGUID(kTestGUID);
   virtual_card->set_record_type(CreditCard::RecordType::kVirtualCard);
diff --git a/components/autofill/core/browser/payments/mandatory_reauth_manager_unittest.cc b/components/autofill/core/browser/payments/mandatory_reauth_manager_unittest.cc
index 018c132b..8830a19 100644
--- a/components/autofill/core/browser/payments/mandatory_reauth_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/mandatory_reauth_manager_unittest.cc
@@ -17,6 +17,10 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if BUILDFLAG(IS_ANDROID)
+#include "base/android/build_info.h"
+#endif
+
 namespace autofill::payments {
 
 using autofill_metrics::MandatoryReauthOfferOptInDecision;
@@ -143,6 +147,12 @@
 // Test that the MandatoryReauthManager returns that we should offer re-auth
 // opt-in if the conditions for offering it are all met for local cards.
 TEST_F(MandatoryReauthManagerTest, ShouldOfferOptin_LocalCard) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndEnableFeature(
       features::kAutofillEnablePaymentsMandatoryReauth);
@@ -188,6 +198,12 @@
 // Test that the MandatoryReauthManager returns that we should offer re-auth
 // opt-in if the conditions for offering it are all met for virtual cards.
 TEST_F(MandatoryReauthManagerTest, ShouldOfferOptin_VirtualCard) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   base::test::ScopedFeatureList feature_list(
       features::kAutofillEnablePaymentsMandatoryReauth);
 
@@ -200,6 +216,12 @@
 // opt-in if the user has already made a decision on opting in or out of
 // re-auth.
 TEST_F(MandatoryReauthManagerTest, ShouldOfferOptin_UserAlreadyMadeDecision) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   base::test::ScopedFeatureList feature_list(
       features::kAutofillEnablePaymentsMandatoryReauth);
 
@@ -217,6 +239,12 @@
 // opt-in if authentication is not available on the device.
 TEST_F(MandatoryReauthManagerTest,
        ShouldOfferOptin_AuthenticationNotAvailable) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   base::test::ScopedFeatureList feature_list(
       features::kAutofillEnablePaymentsMandatoryReauth);
 
@@ -239,6 +267,12 @@
 TEST_F(
     MandatoryReauthManagerTest,
     ShouldOfferOptin_FilledCardWentThroughInteractiveAuthenticationOrNoAutofill) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   base::test::ScopedFeatureList feature_list(
       features::kAutofillEnablePaymentsMandatoryReauth);
 
@@ -258,6 +292,12 @@
 TEST_F(
     MandatoryReauthManagerTest,
     ShouldOfferOptin_ServerCardWithMatchingLocalCard_LastFilledCardWasLocalCard) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   base::test::ScopedFeatureList feature_list(
       features::kAutofillEnablePaymentsMandatoryReauth);
 
@@ -280,6 +320,12 @@
 // Test that the MandatoryReauthManager correctly handles the case where the
 // user accepts the re-auth prompt.
 TEST_F(MandatoryReauthManagerTest, OnUserAcceptedOptInPrompt) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
 #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
   ON_CALL(*autofill_client_->GetDeviceAuthenticatorPtr(),
           AuthenticateWithMessage)
@@ -340,6 +386,12 @@
 // Test that the MandatoryReauthManager correctly handles the case where the
 // user cancels the re-auth prompt.
 TEST_F(MandatoryReauthManagerTest, OnUserCancelledOptInPrompt) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   EXPECT_FALSE(autofill_client_->GetPrefs()->GetUserPrefValue(
       prefs::kAutofillPaymentMethodsMandatoryReauth));
 
@@ -354,6 +406,12 @@
 // Test that the MandatoryReauthManager correctly handles the case where the
 // user closed the re-auth prompt.
 TEST_F(MandatoryReauthManagerTest, OnUserClosedOptInPrompt) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   EXPECT_EQ(autofill_client_->GetPrefs()->GetInteger(
                 prefs::kAutofillPaymentMethodsMandatoryReauthPromoShownCounter),
             0);
@@ -405,6 +463,12 @@
 };
 
 TEST_P(MandatoryReauthManagerOptInFlowTest, OptInSuccess) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   base::test::ScopedFeatureList feature_list(
       features::kAutofillEnablePaymentsMandatoryReauth);
   base::HistogramTester histogram_tester;
@@ -451,6 +515,12 @@
 }
 
 TEST_P(MandatoryReauthManagerOptInFlowTest, OptInShownButAuthFailure) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   base::test::ScopedFeatureList feature_list(
       features::kAutofillEnablePaymentsMandatoryReauth);
   base::HistogramTester histogram_tester;
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 8a4ef73f..731aadf 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -85,6 +85,10 @@
 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
 #include "ui/base/l10n/l10n_util.h"
 
+#if BUILDFLAG(IS_ANDROID)
+#include "base/android/build_info.h"
+#endif
+
 namespace {
 // Checks the order of preference of the `original_card` with the
 // `duplicate_card` and returns whether to dedupe/erase the `duplicate_card`
@@ -1997,13 +2001,28 @@
     return false;
   }
 
-  // If the user has made a decision on this feature previously, then we should
-  // not show the opt-in promo.
+  // There is no need to show the promo if the feature is already enabled.
+  if (prefs::IsPaymentMethodsMandatoryReauthEnabled(pref_service_)) {
+#if BUILDFLAG(IS_ANDROID)
+    // The mandatory reauth feature is always enabled on automotive, there
+    // is/was no opt-in. As such, there is no need to log anything here on
+    // automotive.
+    if (!base::android::BuildInfo::GetInstance()->is_automotive()) {
+      LogMandatoryReauthOfferOptInDecision(
+          MandatoryReauthOfferOptInDecision::kAlreadyOptedIn);
+    }
+#else
+    LogMandatoryReauthOfferOptInDecision(
+        MandatoryReauthOfferOptInDecision::kAlreadyOptedIn);
+#endif  // BUILDFLAG(IS_ANDROID)
+    return false;
+  }
+
+  // If the user has explicitly opted out of this feature previously, then we
+  // should not show the opt-in promo.
   if (prefs::IsPaymentMethodsMandatoryReauthSetExplicitly(pref_service_)) {
     LogMandatoryReauthOfferOptInDecision(
-        prefs::IsPaymentMethodsMandatoryReauthEnabled(pref_service_)
-            ? MandatoryReauthOfferOptInDecision::kAlreadyOptedIn
-            : MandatoryReauthOfferOptInDecision::kAlreadyOptedOut);
+        MandatoryReauthOfferOptInDecision::kAlreadyOptedOut);
     return false;
   }
 
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index 76ff782..18f143b 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -21,6 +21,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/gmock_callback_support.h"
+#include "base/test/gtest_util.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
@@ -59,6 +60,10 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/image/image_unittest_util.h"
 
+#if BUILDFLAG(IS_ANDROID)
+#include "base/android/build_info.h"
+#endif
+
 namespace autofill {
 
 namespace {
@@ -894,10 +899,38 @@
   EXPECT_EQ(kLocalProfile.Compare(kAccountProfile), 0);
 }
 
+#if BUILDFLAG(IS_ANDROID)
+TEST_F(PersonalDataManagerTest,
+       AutofillPaymentMethodsMandatoryReauthAlwaysEnabledOnAutomotive) {
+  if (!base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should only run on automotive.";
+  }
+
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(
+      features::kAutofillEnablePaymentsMandatoryReauth);
+
+  EXPECT_TRUE(personal_data_->IsPaymentMethodsMandatoryReauthEnabled());
+
+  EXPECT_CHECK_DEATH_WITH(
+      { personal_data_->SetPaymentMethodsMandatoryReauthEnabled(false); },
+      "This feature should not be able to be turned off on automotive "
+      "devices.");
+
+  EXPECT_TRUE(personal_data_->IsPaymentMethodsMandatoryReauthEnabled());
+}
+#endif  // BUILDFLAG(IS_ANDROID)
+
 #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
 // Test that setting the `kAutofillEnablePaymentsMandatoryReauth` pref works
 // correctly.
 TEST_F(PersonalDataManagerTest, AutofillPaymentMethodsMandatoryReauthEnabled) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndEnableFeature(
       features::kAutofillEnablePaymentsMandatoryReauth);
@@ -916,6 +949,11 @@
 // enable the feature when the flag is off.
 TEST_F(PersonalDataManagerTest,
        AutofillPaymentMethodsMandatoryReauthEnabled_FlagOff) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndDisableFeature(
       features::kAutofillEnablePaymentsMandatoryReauth);
@@ -933,6 +971,12 @@
 TEST_F(
     PersonalDataManagerTest,
     ShouldShowPaymentMethodsMandatoryReauthPromo_MaxValueForPromoShownCounterReached) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndEnableFeature(
       features::kAutofillEnablePaymentsMandatoryReauth);
@@ -978,6 +1022,12 @@
 // returns that we should not show the promo if the user has already opted out.
 TEST_F(PersonalDataManagerTest,
        ShouldShowPaymentMethodsMandatoryReauthPromo_UserOptedOut) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndEnableFeature(
       features::kAutofillEnablePaymentsMandatoryReauth);
diff --git a/components/autofill/core/common/autofill_prefs.cc b/components/autofill/core/common/autofill_prefs.cc
index 01d9ff1a..72acec8 100644
--- a/components/autofill/core/common/autofill_prefs.cc
+++ b/components/autofill/core/common/autofill_prefs.cc
@@ -14,6 +14,10 @@
 #include "components/prefs/scoped_user_pref_update.h"
 #include "crypto/sha2.h"
 
+#if BUILDFLAG(IS_ANDROID)
+#include "base/android/build_info.h"
+#endif
+
 namespace autofill {
 namespace prefs {
 namespace {
@@ -174,7 +178,19 @@
   registry->RegisterTimePref(prefs::kAutofillUploadEventsLastResetTimestamp,
                              base::Time());
   registry->RegisterDictionaryPref(prefs::kAutofillSyncTransportOptIn);
-#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
+  // Automotive devices require stricter data protection for user privacy, so
+  // mandatory reauth for autofill payment methods should always be enabled.
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    registry->RegisterBooleanPref(prefs::kAutofillPaymentMethodsMandatoryReauth,
+                                  true);
+  } else {
+    registry->RegisterBooleanPref(prefs::kAutofillPaymentMethodsMandatoryReauth,
+                                  false);
+  }
+  registry->RegisterIntegerPref(
+      prefs::kAutofillPaymentMethodsMandatoryReauthPromoShownCounter, 0);
+#elif BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
   registry->RegisterBooleanPref(prefs::kAutofillPaymentMethodsMandatoryReauth,
                                 false);
   registry->RegisterIntegerPref(
@@ -257,8 +273,14 @@
 bool IsPaymentMethodsMandatoryReauthEnabled(const PrefService* prefs) {
 #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || \
     BUILDFLAG(IS_IOS)
-  return base::FeatureList::IsEnabled(
-             features::kAutofillEnablePaymentsMandatoryReauth) &&
+  bool featureEnabled = base::FeatureList::IsEnabled(
+      features::kAutofillEnablePaymentsMandatoryReauth);
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    featureEnabled = true;
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+  return featureEnabled &&
          prefs->GetBoolean(kAutofillPaymentMethodsMandatoryReauth);
 #else
   return false;
@@ -267,6 +289,11 @@
 }
 
 void SetPaymentMethodsMandatoryReauthEnabled(PrefService* prefs, bool enabled) {
+#if BUILDFLAG(IS_ANDROID)
+  // The user should not be able to update the pref value on automotive devices.
+  CHECK(!base::android::BuildInfo::GetInstance()->is_automotive());
+#endif  // BUILDFLAG(IS_ANDROID)
+
 #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || \
     BUILDFLAG(IS_IOS)
   prefs->SetBoolean(kAutofillPaymentMethodsMandatoryReauth, enabled);
diff --git a/components/browser_ui/device_lock/android/java/src/org/chromium/components/browser_ui/device_lock/DeviceLockActivityLauncher.java b/components/browser_ui/device_lock/android/java/src/org/chromium/components/browser_ui/device_lock/DeviceLockActivityLauncher.java
index 217c89f..aca35dcb 100644
--- a/components/browser_ui/device_lock/android/java/src/org/chromium/components/browser_ui/device_lock/DeviceLockActivityLauncher.java
+++ b/components/browser_ui/device_lock/android/java/src/org/chromium/components/browser_ui/device_lock/DeviceLockActivityLauncher.java
@@ -26,19 +26,4 @@
     void launchDeviceLockActivity(Context context, @Nullable String selectedAccount,
             boolean requireDeviceLockReauthentication, WindowAndroid windowAndroid,
             WindowAndroid.IntentCallback callback);
-
-    /**
-     * Ensures that the device has a device lock set up to protect the user's data privacy and that
-     * the current user knows those credentials. This may launch the {@link DeviceLockActivity} to
-     * set a new device lock if none exists, otherwise it will ask the user to reauthenticate for
-     * and existing device lock.
-     *
-     * @param context The context to launch the {@link DeviceLockActivity} with.
-     * @param requireDeviceLockReauthentication Whether or not the reauthentication of the device
-     *        lock credentials should be required (if a device lock is already present).
-     * @param windowAndroid The host activity's {@link WindowAndroid}.
-     * @param callback A callback to run after the {@link DeviceLockActivity} finishes.
-     */
-    void presentDeviceLockChallenge(Context context, boolean requireDeviceLockReauthentication,
-            WindowAndroid windowAndroid, Runnable callback);
 }
diff --git a/components/feedback/redaction_tool/redaction_tool.cc b/components/feedback/redaction_tool/redaction_tool.cc
index 95daf517..8be265a 100644
--- a/components/feedback/redaction_tool/redaction_tool.cc
+++ b/components/feedback/redaction_tool/redaction_tool.cc
@@ -109,6 +109,18 @@
      "([0-9a-zA-Z\\-.:\\/\\\\\\x00-\\x09\\x0B-\\x1F]+)(\\b)",
      PIIType::kSerial},
     {"Serial", "( Serial Number )(\\d+)(\\b)", PIIType::kSerial},
+    // USB Serial numbers, as outputted from the lsusb --verbose tool.
+    // "iSerial" followed by some spaces, then up to 5 digits of the iSerial index
+    // which is not part of the serial number itself, followed by the serial number string.
+    // The iSerial index must be nonzero, as an index of zero indicates no string descriptor
+    // is present. The serial number string itself is up to the manufacturer, but is
+    // observed to be alphanumetric (numbers, and both upper and lower case letters).
+    {"Serial", "(iSerial\\s*[1-9]\\d{0,4}\\s)([0-9a-zA-Z-]+)(\\b)", PIIType::kSerial},
+    // USB Serial number as generated by usbguard.
+    {"Serial",
+     "(?i-s)(\\bserial\\s\")"
+     "([0-9a-z\\-.:\\/\\\\\\x00-\\x09\\x0B-\\x1F]+)(\")",
+     PIIType::kSerial},
     // The attested device id, a serial number, that comes from vpd_2.0.txt.
     // The pattern was recently clarified as being a case insensitive string of
     // ASCII letters and digits, plus the dash/hyphen character. The dash cannot
diff --git a/components/feedback/redaction_tool/redaction_tool_unittest.cc b/components/feedback/redaction_tool/redaction_tool_unittest.cc
index 37e59cd0..82f20638 100644
--- a/components/feedback/redaction_tool/redaction_tool_unittest.cc
+++ b/components/feedback/redaction_tool/redaction_tool_unittest.cc
@@ -510,6 +510,15 @@
             RedactCustomPatterns("\"attested_device_id\"=\"-5CD045B0DZ\""));
   EXPECT_EQ("\"attested_device_id\"=\"5CD045B0DZ-\"",
             RedactCustomPatterns("\"attested_device_id\"=\"5CD045B0DZ-\""));
+  // redact lsusb's iSerial with a nonzero index.
+  EXPECT_EQ("iSerial    3 (Serial: 14)",
+            RedactCustomPatterns("iSerial    3 12345abcdEFG"));
+  // Do not redact lsusb's iSerial when the index is 0.
+  EXPECT_EQ("iSerial    0 ",
+            RedactCustomPatterns("iSerial    0 "));
+  // redact usbguard's serial number in syslog
+  EXPECT_EQ("serial \"(Serial: 15)\"",
+            RedactCustomPatterns("serial \"usb1234AA5678\""));
 
   // Valid PSM identifiers.
   EXPECT_EQ("PSM id: (PSM ID: 1)", RedactCustomPatterns("PSM id: ABCZ/123xx"));
diff --git a/components/lens/BUILD.gn b/components/lens/BUILD.gn
index bc1d9d8..ae0f925 100644
--- a/components/lens/BUILD.gn
+++ b/components/lens/BUILD.gn
@@ -67,6 +67,7 @@
   deps = [
     ":lens",
     "//base",
+    "//base/test:test_support",
     "//testing/gmock",
     "//testing/gtest",
     "//url",
diff --git a/components/lens/lens_url_utils.cc b/components/lens/lens_url_utils.cc
index e7181eb..d601394 100644
--- a/components/lens/lens_url_utils.cc
+++ b/components/lens/lens_url_utils.cc
@@ -7,6 +7,7 @@
 #include <map>
 
 #include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
@@ -205,6 +206,8 @@
         modified_url, kViewportHeightQueryParameter,
         base::NumberToString(viewport_height));
   }
+  base::UmaHistogramBoolean("Search.Lens.ViewportDimensionsSent.Success",
+                            viewport_width != 0 && viewport_height != 0);
   return modified_url;
 }
 
diff --git a/components/lens/lens_url_utils_unittest.cc b/components/lens/lens_url_utils_unittest.cc
index 7cfe3b7f..d169864 100644
--- a/components/lens/lens_url_utils_unittest.cc
+++ b/components/lens/lens_url_utils_unittest.cc
@@ -5,6 +5,7 @@
 #include "components/lens/lens_url_utils.h"
 
 #include "base/strings/string_number_conversions.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.h"
 #include "components/lens/lens_entrypoints.h"
 #include "components/lens/lens_rendering_environment.h"
@@ -30,10 +31,30 @@
 
 TEST(LensUrlUtilsTest,
      AppendOrReplaceViewportSizeForRequestSetsSidePanelSizeParams) {
+  base::HistogramTester histogram_tester;
   GURL original_url = GURL("https://lens.google.com/");
   GURL url = lens::AppendOrReplaceViewportSizeForRequest(original_url,
                                                          gfx::Size(10, 10));
   EXPECT_THAT(url.query(), MatchesRegex("vpw=10&vph=10"));
+  histogram_tester.ExpectBucketCount(
+      "Search.Lens.ViewportDimensionsSent.Success", true, 1);
+}
+
+TEST(LensUrlUtilsTest,
+     AppendOrReplaceViewportSizeForRequestOnlySetsNonZeroSizes) {
+  base::HistogramTester histogram_tester;
+  GURL original_url = GURL("https://lens.google.com/");
+  GURL url_with_height = lens::AppendOrReplaceViewportSizeForRequest(
+      original_url, gfx::Size(0, 10));
+  EXPECT_THAT(url_with_height.query(), MatchesRegex("vph=10"));
+  GURL url_with_width = lens::AppendOrReplaceViewportSizeForRequest(
+      original_url, gfx::Size(10, 0));
+  EXPECT_THAT(url_with_width.query(), MatchesRegex("vpw=10"));
+  GURL url_with_neither = lens::AppendOrReplaceViewportSizeForRequest(
+      original_url, gfx::Size(0, 0));
+  EXPECT_THAT(url_with_neither.query(), MatchesRegex(""));
+  histogram_tester.ExpectBucketCount(
+      "Search.Lens.ViewportDimensionsSent.Success", false, 3);
 }
 
 TEST(LensUrlUtilsTest, GetRegionSearchNewTabQueryParameterTest) {
diff --git a/components/media_effects/BUILD.gn b/components/media_effects/BUILD.gn
index 659f96c..c7f2a0e 100644
--- a/components/media_effects/BUILD.gn
+++ b/components/media_effects/BUILD.gn
@@ -8,8 +8,6 @@
     "//third_party/abseil-cpp:absl",
   ]
   sources = [
-    "media_effects_manager_binder.cc",
-    "media_effects_manager_binder.h",
     "media_effects_service.cc",
     "media_effects_service.h",
     "media_effects_service_factory.cc",
@@ -30,7 +28,6 @@
     "//testing/gtest",
   ]
   sources = [
-    "media_effects_manager_binder_unittest.cc",
     "media_effects_service_factory_unittest.cc",
     "media_effects_service_unittest.cc",
     "video_effects_manager_impl_unittest.cc",
diff --git a/components/media_effects/media_effects_manager_binder.cc b/components/media_effects/media_effects_manager_binder.cc
deleted file mode 100644
index efe1ec5e..0000000
--- a/components/media_effects/media_effects_manager_binder.cc
+++ /dev/null
@@ -1,47 +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 "components/media_effects/media_effects_manager_binder.h"
-#include "components/media_effects/media_effects_service_factory.h"
-#include "content/public/browser/browser_thread.h"
-
-namespace {
-void BindVideoEffectsManagerOnUIThread(
-    const std::string& device_id,
-    content::BrowserContext* browser_context,
-    mojo::PendingReceiver<video_capture::mojom::VideoEffectsManager>
-        video_effects_manager) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  auto* media_effects_service =
-      MediaEffectsServiceFactory::GetForBrowserContext(browser_context);
-  if (!media_effects_service) {
-    LOG(WARNING) << "Video device not registered because no service was "
-                    "returned for the current BrowserContext";
-    return;
-  }
-
-  media_effects_service->BindVideoEffectsManager(
-      device_id, std::move(video_effects_manager));
-}
-}  // namespace
-
-namespace media_effects {
-
-void BindVideoEffectsManager(
-    const std::string& device_id,
-    content::BrowserContext* browser_context,
-    mojo::PendingReceiver<video_capture::mojom::VideoEffectsManager>
-        video_effects_manager) {
-  if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
-    BindVideoEffectsManagerOnUIThread(device_id, browser_context,
-                                      std::move(video_effects_manager));
-    return;
-  }
-  // The function wasn't called from the UI thread, so post a task.
-  content::GetUIThreadTaskRunner()->PostTask(
-      FROM_HERE,
-      base::BindOnce(&BindVideoEffectsManagerOnUIThread, device_id,
-                     browser_context, std::move(video_effects_manager)));
-}
-}  // namespace media_effects
diff --git a/components/media_effects/media_effects_manager_binder.h b/components/media_effects/media_effects_manager_binder.h
deleted file mode 100644
index 28bf5764..0000000
--- a/components/media_effects/media_effects_manager_binder.h
+++ /dev/null
@@ -1,22 +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.
-
-#ifndef COMPONENTS_MEDIA_EFFECTS_MEDIA_EFFECTS_MANAGER_BINDER_H_
-#define COMPONENTS_MEDIA_EFFECTS_MEDIA_EFFECTS_MANAGER_BINDER_H_
-
-#include "content/public/browser/browser_context.h"
-#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "services/video_capture/public/mojom/video_effects_manager.mojom.h"
-
-namespace media_effects {
-
-void BindVideoEffectsManager(
-    const std::string& device_id,
-    content::BrowserContext* browser_context,
-    mojo::PendingReceiver<video_capture::mojom::VideoEffectsManager>
-        video_effects_manager);
-
-}  // namespace media_effects
-
-#endif  // COMPONENTS_MEDIA_EFFECTS_MEDIA_EFFECTS_MANAGER_BINDER_H_
diff --git a/components/media_effects/media_effects_manager_binder_unittest.cc b/components/media_effects/media_effects_manager_binder_unittest.cc
deleted file mode 100644
index cbd0a63..0000000
--- a/components/media_effects/media_effects_manager_binder_unittest.cc
+++ /dev/null
@@ -1,54 +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 "components/media_effects/media_effects_manager_binder.h"
-#include "base/test/test_future.h"
-#include "components/user_prefs/test/test_browser_context_with_prefs.h"
-#include "content/public/test/browser_task_environment.h"
-#include "mojo/public/cpp/bindings/remote.h"
-#include "services/video_capture/public/mojom/video_effects_manager.mojom.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/insets_f.h"
-
-namespace {
-video_capture::mojom::VideoEffectsConfigurationPtr GetConfigurationSync(
-    mojo::Remote<video_capture::mojom::VideoEffectsManager>& effect_manager) {
-  base::test::TestFuture<video_capture::mojom::VideoEffectsConfigurationPtr>
-      output_configuration;
-  effect_manager->GetConfiguration(output_configuration.GetCallback());
-  return output_configuration.Take();
-}
-}  // namespace
-
-class MediaEffectsManagerBinderTest : public testing::Test {
- protected:
-  content::BrowserTaskEnvironment task_environment_;
-  user_prefs::TestBrowserContextWithPrefs browser_context_;
-};
-
-TEST_F(MediaEffectsManagerBinderTest, BindVideoEffectsManager) {
-  const char* kDeviceId = "device_id";
-
-  mojo::Remote<video_capture::mojom::VideoEffectsManager> video_effects_manager;
-  media_effects::BindVideoEffectsManager(
-      kDeviceId, &browser_context_,
-      video_effects_manager.BindNewPipeAndPassReceiver());
-
-  // Allow queued device registration to complete.
-  base::RunLoop().RunUntilIdle();
-
-  const float kPaddingRatio = 0.383;
-  base::test::TestFuture<video_capture::mojom::SetConfigurationResult>
-      result_future;
-  video_effects_manager->SetConfiguration(
-      video_capture::mojom::VideoEffectsConfiguration::New(
-          nullptr, nullptr,
-          video_capture::mojom::Framing::New(gfx::InsetsF{kPaddingRatio})),
-      result_future.GetCallback());
-  EXPECT_EQ(video_capture::mojom::SetConfigurationResult::kOk,
-            result_future.Get());
-
-  EXPECT_EQ(kPaddingRatio, GetConfigurationSync(video_effects_manager)
-                               ->framing->padding_ratios.top());
-}
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto
index f7aa42e..3752a1eb 100644
--- a/components/policy/proto/chrome_device_policy.proto
+++ b/components/policy/proto/chrome_device_policy.proto
@@ -2029,5 +2029,4 @@
   optional StringListPolicyProto device_authentication_url_allowlist = 152;
   optional DeviceSwitchFunctionKeysBehaviorEnabledProto
       device_switch_function_keys_behavior_enabled = 153;
-  optional StringListPolicyProto device_dlc_predownload_list = 154;
 }
diff --git a/components/policy/resources/templates/policies.yaml b/components/policy/resources/templates/policies.yaml
index 9eb9ebf7..7d1a4c8bc 100644
--- a/components/policy/resources/templates/policies.yaml
+++ b/components/policy/resources/templates/policies.yaml
@@ -1158,7 +1158,6 @@
   1157: SafeBrowsingDeepScanningEnabled
   1158: DriveFileSyncAvailable
   1159: DeviceSwitchFunctionKeysBehaviorEnabled
-  1160: DeviceDlcPredownloadList
 atomic_groups:
   1: Homepage
   2: RemoteAccess
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/DeviceDlcPredownloadList.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/DeviceDlcPredownloadList.yaml
deleted file mode 100644
index 66b5126..0000000
--- a/components/policy/resources/templates/policy_definitions/Miscellaneous/DeviceDlcPredownloadList.yaml
+++ /dev/null
@@ -1,28 +0,0 @@
-owners:
-- nedol@google.com
-- ust@google.com
-- file://chromeos/printing/OWNERS
-caption: Select DLCs (Downloadable Content) that need to be pre downloaded
-desc: |-
-  This policy allows to set a list of DLCs (Downloadable Content) to be downloaded as soon as possible. Downloaded DLCs are then available for all users on the device.
-
-  This is useful when the administrator knows that a feature that requires the presence of the DLC will likely be used by the users of the device.
-future_on: ['chrome_os']
-device_only: true
-features:
-  dynamic_refresh: true
-  per_profile: false
-type: string-enum-list
-schema:
-  items:
-    enum:
-    - scanner_drivers
-    type: string
-  type: array
-items:
-- caption: Scanner drivers
-  name: scanner_drivers
-  value: scanner_drivers
-example_value:
-- scanner_drivers
-tags: []
\ No newline at end of file
diff --git a/components/policy/test/data/policy_test_cases.json b/components/policy/test/data/policy_test_cases.json
index 3ef1a03..e77dfaf 100644
--- a/components/policy/test/data/policy_test_cases.json
+++ b/components/policy/test/data/policy_test_cases.json
@@ -24872,8 +24872,5 @@
         }
       }
     ]
-  },
-  "DeviceDlcPredownloadList": {
-    "reason_for_missing_test": "Maps into CrosSettings"
   }
 }
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
index d1c93d9b..514bf6a 100644
--- a/components/printing/renderer/print_render_frame_helper.cc
+++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -241,19 +241,23 @@
   ParamWithFitToPageScale<mojom::PrintParamsPtr> result;
   result.param = css_params.Clone();
 
-  double content_width =
-      static_cast<double>(result.param->content_size.width());
-  double content_height =
-      static_cast<double>(result.param->content_size.height());
-  int default_page_size_height = page_params.page_size.height();
-  int default_page_size_width = page_params.page_size.width();
-  int css_page_size_height = result.param->page_size.height();
-  int css_page_size_width = result.param->page_size.width();
-
   if (page_params.page_size == result.param->page_size) {
     return result;
   }
 
+  float content_width = result.param->content_size.width();
+  float content_height = result.param->content_size.height();
+  float default_page_size_height = page_params.page_size.height();
+  float default_page_size_width = page_params.page_size.width();
+  float css_page_size_height = result.param->page_size.height();
+  float css_page_size_width = result.param->page_size.width();
+
+  if ((default_page_size_width > default_page_size_height) !=
+      (css_page_size_width > css_page_size_height)) {
+    // Match orientation.
+    std::swap(default_page_size_width, default_page_size_height);
+  }
+
   double scale_factor = 1.0f;
   if (default_page_size_width < css_page_size_width ||
       default_page_size_height < css_page_size_height) {
@@ -272,8 +276,8 @@
       (default_page_size_width - css_page_size_width * scale_factor) / 2 +
       (result.param->margin_left * scale_factor));
   result.param->content_size = gfx::SizeF(content_width, content_height);
-  result.param->page_size = page_params.page_size;
-
+  result.param->page_size.SetSize(default_page_size_width,
+                                  default_page_size_height);
   result.fit_to_page_scale_factor = scale_factor;
 
   return result;
diff --git a/components/printing/test/print_render_frame_helper_browsertest.cc b/components/printing/test/print_render_frame_helper_browsertest.cc
index 9cb0efcd..1c8cb64 100644
--- a/components/printing/test/print_render_frame_helper_browsertest.cc
+++ b/components/printing/test/print_render_frame_helper_browsertest.cc
@@ -1791,6 +1791,46 @@
   OnClosePrintPreviewDialog();
 }
 
+// Test to verify that print preview workflow scale the html page contents to
+// fit the page size, and that orientation implied by specified CSS page size is
+// honored.
+TEST_F(PrintRenderFrameHelperPreviewTest,
+       ShrinkToFitPageMatchOrientationCssMargins) {
+  LoadHTML(R"HTML(
+      <style>
+        @page {
+          size: 20in 17in;
+          margin: 1in 2in 3in 4in;
+        }
+      </style>
+      :-D
+  )HTML");
+  // The default page size is 8.5 by 11 inches. The @page descriptor wants it in
+  // landscape mode, so 11 by 8.5 inches, then. The content should be scaled to
+  // fit on the page. The requested page size is 20 by 17 inches. Figure out
+  // which axis needs the most scaling. 20/11 < 17/8.5. 17/8.5 is 2. The content
+  // needs to be scaled down by a factor of 2. To retain the aspect ratio of the
+  // paper size, additional horizontal margins will be inserted, so that the
+  // page width before scaling becomes 22in (11*2). The requested page size is
+  // 20in, so add an additional 1in to the left and the right margins. This
+  // means that the result would be the same as if this were in the CSS:
+  //
+  // @page {
+  //   size: 22in 17in;
+  //   margin: 1in 3in 3in 5in;
+  // }
+  //
+  // Then scale everything down by a factor of 2.
+
+  print_settings().Set(kSettingPrinterType,
+                       static_cast<int>(mojom::PrinterType::kLocal));
+  OnPrintPreview();
+
+  EXPECT_EQ(0u, preview_ui()->print_preview_pages_remaining());
+  VerifyDefaultPageLayout(504, 468, 36, 108, 180, 108, true, true);
+  OnClosePrintPreviewDialog();
+}
+
 TEST_F(PrintRenderFrameHelperPreviewTest, MarginsAndInputScaleToPdf1) {
   // The default page size in these tests is US Letter - 8.5 by 11 inches.
   // Setting vertical margins to 0.5in results in a page area of 10 inches.
diff --git a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
index 6e81886d..f905c843 100644
--- a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
+++ b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
@@ -13,6 +13,7 @@
 
 #include "base/base64.h"
 #include "base/base64url.h"
+#include "base/command_line.h"
 #include "base/containers/cxx20_erase.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
@@ -75,6 +76,11 @@
 
 // static
 WebUIInfoSingleton* WebUIInfoSingleton::GetInstance() {
+  CHECK(base::CommandLine::ForCurrentProcess()
+            ->GetSwitchValueASCII("type")
+            .empty())
+      << "chrome://safe-browsing WebUI is only available in the browser "
+         "process";
   return base::Singleton<WebUIInfoSingleton>::get();
 }
 
diff --git a/components/session_proto_db/BUILD.gn b/components/session_proto_db/BUILD.gn
index dd6bf45..b20836a 100644
--- a/components/session_proto_db/BUILD.gn
+++ b/components/session_proto_db/BUILD.gn
@@ -26,8 +26,9 @@
   ]
 }
 
-# TODO(crbug.com/1399914) Make tests more general and run on iOS trybot.
-if (!is_ios) {
+# TODO(crbug.com/1399914) Make tests more general and run on iOS non-blink
+# trybot.
+if (use_blink) {
   source_set("unit_tests") {
     testonly = true
     sources = [ "session_proto_db_unittest.cc" ]
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 5dcd887..6ade3be 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -2713,8 +2713,15 @@
   } else if (is_ios) {
     sources += [
       "child_process_launcher_helper_ios.cc",
+      "date_time_chooser/ios/date_time_chooser_coordinator.h",
+      "date_time_chooser/ios/date_time_chooser_coordinator.mm",
+      "date_time_chooser/ios/date_time_chooser_delegate.h",
       "date_time_chooser/ios/date_time_chooser_ios.h",
       "date_time_chooser/ios/date_time_chooser_ios.mm",
+      "date_time_chooser/ios/date_time_chooser_mediator.h",
+      "date_time_chooser/ios/date_time_chooser_mediator.mm",
+      "date_time_chooser/ios/date_time_chooser_view_controller.h",
+      "date_time_chooser/ios/date_time_chooser_view_controller.mm",
       "devtools/protocol/native_input_event_builder_ios.mm",
       "renderer_host/browser_compositor_ios.h",
       "renderer_host/browser_compositor_ios.mm",
diff --git a/content/browser/date_time_chooser/ios/date_time_chooser_coordinator.h b/content/browser/date_time_chooser/ios/date_time_chooser_coordinator.h
new file mode 100644
index 0000000..e4a67787
--- /dev/null
+++ b/content/browser/date_time_chooser/ios/date_time_chooser_coordinator.h
@@ -0,0 +1,34 @@
+// 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 CONTENT_BROWSER_DATE_TIME_CHOOSER_IOS_DATE_TIME_CHOOSER_COORDINATOR_H_
+#define CONTENT_BROWSER_DATE_TIME_CHOOSER_IOS_DATE_TIME_CHOOSER_COORDINATOR_H_
+
+#import <Foundation/Foundation.h>
+
+#import "third_party/blink/public/mojom/choosers/date_time_chooser.mojom.h"
+#import "ui/gfx/native_widget_types.h"
+
+using DateTimeDialogValuePtr = blink::mojom::DateTimeDialogValuePtr;
+
+@class DateTimeChooserViewController;
+@class DateTimeChooserMediator;
+@class UIViewController;
+
+namespace content {
+class DateTimeChooserIOS;
+}
+
+// Holds a controller and a mediator so that communicates UI and Mojo
+// implementations.
+@interface DateTimeChooserCoordinator : NSObject
+
+// Initializer.
+- (instancetype)initWithDateTimeChooser:(content::DateTimeChooserIOS*)chooser
+                                configs:(DateTimeDialogValuePtr)configs
+                     baseViewController:(UIViewController*)baseViewController;
+
+@end
+
+#endif  // CONTENT_BROWSER_DATE_TIME_CHOOSER_IOS_DATE_TIME_CHOOSER_COORDINATOR_H_
diff --git a/content/browser/date_time_chooser/ios/date_time_chooser_coordinator.mm b/content/browser/date_time_chooser/ios/date_time_chooser_coordinator.mm
new file mode 100644
index 0000000..602672f
--- /dev/null
+++ b/content/browser/date_time_chooser/ios/date_time_chooser_coordinator.mm
@@ -0,0 +1,51 @@
+// 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 "content/browser/date_time_chooser/ios/date_time_chooser_coordinator.h"
+
+#import "content/browser/date_time_chooser/ios/date_time_chooser_mediator.h"
+#import "content/browser/date_time_chooser/ios/date_time_chooser_view_controller.h"
+#import "ui/gfx/native_widget_types.h"
+
+@interface DateTimeChooserCoordinator ()
+// The controller that has UI components.
+@property(nonatomic, strong)
+    DateTimeChooserViewController* dateTimeChooserController;
+
+// The mediator that has DateTimeChooser.
+@property(nonatomic, strong) DateTimeChooserMediator* dateTimeChooserMediator;
+@end
+
+@implementation DateTimeChooserCoordinator
+
+- (instancetype)initWithDateTimeChooser:(content::DateTimeChooserIOS*)chooser
+                                configs:(DateTimeDialogValuePtr)configs
+                     baseViewController:(UIViewController*)baseViewController {
+  if (!(self = [super init])) {
+    return nil;
+  }
+  _dateTimeChooserMediator =
+      [[DateTimeChooserMediator alloc] initWithDateTimeChooser:chooser];
+
+  _dateTimeChooserController = [[DateTimeChooserViewController alloc]
+      initWithConfigs:std::move(configs)];
+  _dateTimeChooserController.delegate = _dateTimeChooserMediator;
+  _dateTimeChooserController.view.backgroundColor = [UIColor whiteColor];
+  _dateTimeChooserController.modalInPresentation = true;
+  _dateTimeChooserController.modalPresentationStyle =
+      UIModalPresentationPopover;
+  _dateTimeChooserController.popoverPresentationController.delegate =
+      _dateTimeChooserController;
+  _dateTimeChooserController.popoverPresentationController.sourceView =
+      baseViewController.view;
+  _dateTimeChooserController.popoverPresentationController.sourceRect =
+      baseViewController.view.bounds;
+
+  [baseViewController presentViewController:_dateTimeChooserController
+                                   animated:true
+                                 completion:nil];
+  return self;
+}
+
+@end
diff --git a/content/browser/date_time_chooser/ios/date_time_chooser_delegate.h b/content/browser/date_time_chooser/ios/date_time_chooser_delegate.h
new file mode 100644
index 0000000..80c3832
--- /dev/null
+++ b/content/browser/date_time_chooser/ios/date_time_chooser_delegate.h
@@ -0,0 +1,22 @@
+// 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 CONTENT_BROWSER_DATE_TIME_CHOOSER_IOS_DATE_TIME_CHOOSER_DELEGATE_H_
+#define CONTENT_BROWSER_DATE_TIME_CHOOSER_IOS_DATE_TIME_CHOOSER_DELEGATE_H_
+
+#import <Foundation/Foundation.h>
+
+@class DateTimeChooserViewController;
+
+// Delegate to handle actions.
+@protocol DateTimeChooserDelegate <NSObject>
+
+// Method invoked when the user closed a dialog.
+- (void)dateTimeChooser:(DateTimeChooserViewController*)chooser
+    didCloseSuccessfully:(BOOL)success
+                withDate:(NSDate*)date;
+
+@end
+
+#endif  // CONTENT_BROWSER_DATE_TIME_CHOOSER_IOS_DATE_TIME_CHOOSER_DELEGATE_H_
diff --git a/content/browser/date_time_chooser/ios/date_time_chooser_ios.h b/content/browser/date_time_chooser/ios/date_time_chooser_ios.h
index 181a7ce..cb38e92 100644
--- a/content/browser/date_time_chooser/ios/date_time_chooser_ios.h
+++ b/content/browser/date_time_chooser/ios/date_time_chooser_ios.h
@@ -9,6 +9,8 @@
 #include "content/common/content_export.h"
 #include "third_party/blink/public/mojom/choosers/date_time_chooser.mojom-forward.h"
 
+@class DateTimeChooserCoordinator;
+
 namespace content {
 
 // IOS implementation for DateTimeChooser dialogs.
@@ -20,11 +22,17 @@
   DateTimeChooserIOS(const DateTimeChooserIOS&) = delete;
   DateTimeChooserIOS& operator=(const DateTimeChooserIOS&) = delete;
 
+  // Called when a dialog is closed by a user action.
+  void OnDialogClosed(bool success, double value);
+
  protected:
   // DateTimeChooser:
   void OpenPlatformDialog(blink::mojom::DateTimeDialogValuePtr value,
                           OpenDateTimeDialogCallback callback) override;
   void ClosePlatformDialog() override;
+
+ private:
+  DateTimeChooserCoordinator* __strong coordinator_;
 };
 
 }  // namespace content
diff --git a/content/browser/date_time_chooser/ios/date_time_chooser_ios.mm b/content/browser/date_time_chooser/ios/date_time_chooser_ios.mm
index c372a40..8fc2057 100644
--- a/content/browser/date_time_chooser/ios/date_time_chooser_ios.mm
+++ b/content/browser/date_time_chooser/ios/date_time_chooser_ios.mm
@@ -4,6 +4,11 @@
 
 #import "content/browser/date_time_chooser/ios/date_time_chooser_ios.h"
 
+#import <UIKit/UIKit.h>
+
+#import "content/browser/date_time_chooser/ios/date_time_chooser_coordinator.h"
+#import "ui/gfx/native_widget_types.h"
+
 namespace content {
 
 // DateTimeChooserIOS implementation
@@ -12,15 +17,26 @@
 
 DateTimeChooserIOS::~DateTimeChooserIOS() = default;
 
+void DateTimeChooserIOS::OnDialogClosed(bool success, double value) {
+  if (open_date_time_response_callback_) {
+    std::move(open_date_time_response_callback_).Run(success, value);
+  }
+  ClosePlatformDialog();
+}
+
 void DateTimeChooserIOS::OpenPlatformDialog(
     blink::mojom::DateTimeDialogValuePtr value,
     OpenDateTimeDialogCallback callback) {
-  // TODO(crbug.com/1461947): Create a coordninator to handle UI components.
-  std::move(callback).Run(false, 0);
+  open_date_time_response_callback_ = std::move(callback);
+  gfx::NativeWindow gfx_window = GetWebContents().GetTopLevelNativeWindow();
+  coordinator_ = [[DateTimeChooserCoordinator alloc]
+      initWithDateTimeChooser:this
+                      configs:std::move(value)
+           baseViewController:gfx_window.Get().rootViewController];
 }
 
 void DateTimeChooserIOS::ClosePlatformDialog() {
-  // TODO(crbug.com/1461947): Close a dialog and clean it up.
+  coordinator_ = nil;
 }
 
 // static
diff --git a/content/browser/date_time_chooser/ios/date_time_chooser_mediator.h b/content/browser/date_time_chooser/ios/date_time_chooser_mediator.h
new file mode 100644
index 0000000..3b5b054
--- /dev/null
+++ b/content/browser/date_time_chooser/ios/date_time_chooser_mediator.h
@@ -0,0 +1,24 @@
+// 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 CONTENT_BROWSER_DATE_TIME_CHOOSER_IOS_DATE_TIME_CHOOSER_MEDIATOR_H_
+#define CONTENT_BROWSER_DATE_TIME_CHOOSER_IOS_DATE_TIME_CHOOSER_MEDIATOR_H_
+
+#import <Foundation/Foundation.h>
+
+#import "content/browser/date_time_chooser/ios/date_time_chooser_delegate.h"
+
+namespace content {
+class DateTimeChooserIOS;
+}  // namespace content
+
+// Communicates with content::DateTimeChooserIOS.
+@interface DateTimeChooserMediator : NSObject <DateTimeChooserDelegate>
+
+// Initializer.
+- (instancetype)initWithDateTimeChooser:
+    (content::DateTimeChooserIOS*)dateTimeChooser;
+@end
+
+#endif  // CONTENT_BROWSER_DATE_TIME_CHOOSER_IOS_DATE_TIME_CHOOSER_MEDIATOR_H_
diff --git a/content/browser/date_time_chooser/ios/date_time_chooser_mediator.mm b/content/browser/date_time_chooser/ios/date_time_chooser_mediator.mm
new file mode 100644
index 0000000..90c5af07
--- /dev/null
+++ b/content/browser/date_time_chooser/ios/date_time_chooser_mediator.mm
@@ -0,0 +1,33 @@
+// 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 "content/browser/date_time_chooser/ios/date_time_chooser_mediator.h"
+
+#import "content/browser/date_time_chooser/ios/date_time_chooser_ios.h"
+
+@interface DateTimeChooserMediator ()
+@property(nonatomic, assign) content::DateTimeChooserIOS* dateTimeChooser;
+@end
+
+@implementation DateTimeChooserMediator
+- (instancetype)initWithDateTimeChooser:
+    (content::DateTimeChooserIOS*)dateTimeChooser {
+  if (!(self = [super init])) {
+    return nil;
+  }
+
+  _dateTimeChooser = dateTimeChooser;
+  return self;
+}
+
+#pragma mark - DateTimeChooserDelegate
+
+- (void)dateTimeChooser:(DateTimeChooserViewController*)chooser
+    didCloseSuccessfully:(BOOL)success
+                withDate:(NSDate*)date {
+  self.dateTimeChooser->OnDialogClosed(success,
+                                       [date timeIntervalSince1970] * 1000);
+}
+
+@end
diff --git a/content/browser/date_time_chooser/ios/date_time_chooser_view_controller.h b/content/browser/date_time_chooser/ios/date_time_chooser_view_controller.h
new file mode 100644
index 0000000..68db22f
--- /dev/null
+++ b/content/browser/date_time_chooser/ios/date_time_chooser_view_controller.h
@@ -0,0 +1,26 @@
+// 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 CONTENT_BROWSER_DATE_TIME_CHOOSER_IOS_DATE_TIME_CHOOSER_VIEW_CONTROLLER_H_
+#define CONTENT_BROWSER_DATE_TIME_CHOOSER_IOS_DATE_TIME_CHOOSER_VIEW_CONTROLLER_H_
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+
+#import "content/browser/date_time_chooser/ios/date_time_chooser_coordinator.h"
+#import "content/browser/date_time_chooser/ios/date_time_chooser_delegate.h"
+
+// The ViewController that has UIDatePicker.
+@interface DateTimeChooserViewController
+    : UIViewController <UIPopoverPresentationControllerDelegate>
+
+// Delegate used to tell DateTimeChooser the controller status.
+@property(nonatomic, weak) id<DateTimeChooserDelegate> delegate;
+
+// Initializer.
+- (instancetype)initWithConfigs:(DateTimeDialogValuePtr)configs;
+
+@end
+
+#endif  // CONTENT_BROWSER_DATE_TIME_CHOOSER_IOS_DATE_TIME_CHOOSER_VIEW_CONTROLLER_H_
diff --git a/content/browser/date_time_chooser/ios/date_time_chooser_view_controller.mm b/content/browser/date_time_chooser/ios/date_time_chooser_view_controller.mm
new file mode 100644
index 0000000..2dd0155
--- /dev/null
+++ b/content/browser/date_time_chooser/ios/date_time_chooser_view_controller.mm
@@ -0,0 +1,137 @@
+// 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 "content/browser/date_time_chooser/ios/date_time_chooser_view_controller.h"
+
+#import "base/notreached.h"
+#import "third_party/blink/public/mojom/choosers/date_time_chooser.mojom.h"
+#import "ui/base/ime/text_input_type.h"
+
+const CGFloat kToolBarHeight = 44;
+
+@interface DateTimeChooserViewController ()
+// The type to set the date picker mode
+@property(nonatomic, assign) ui::TextInputType type;
+// Initalized time for the date picker
+@property(nonatomic, assign) NSInteger initTimeInMS;
+// Updated with the selected date in the date picker
+@property(nonatomic, assign) NSDate* selectedDate;
+@end
+
+@implementation DateTimeChooserViewController
+
+- (instancetype)initWithConfigs:(DateTimeDialogValuePtr)configs {
+  if (!(self = [super init])) {
+    return nil;
+  }
+  _delegate = nil;
+  _type = configs->dialog_type;
+  _initTimeInMS = configs->dialog_value;
+  return self;
+}
+
+- (UIDatePicker*)createUIDatePicker {
+  UIDatePicker* datePicker = [[UIDatePicker alloc] init];
+  switch (self.type) {
+    case ui::TextInputType::TEXT_INPUT_TYPE_DATE:
+      datePicker.datePickerMode = UIDatePickerModeDate;
+      break;
+    case ui::TextInputType::TEXT_INPUT_TYPE_DATE_TIME:
+    case ui::TextInputType::TEXT_INPUT_TYPE_DATE_TIME_LOCAL:
+    case ui::TextInputType::TEXT_INPUT_TYPE_MONTH:
+    case ui::TextInputType::TEXT_INPUT_TYPE_TIME:
+    case ui::TextInputType::TEXT_INPUT_TYPE_WEEK:
+      // TODO(crbug.com/1461947): Set the mode based on each type and handle the
+      // selected value with the format matched to the mode.
+      datePicker.datePickerMode = UIDatePickerModeDate;
+      break;
+    default:
+      NOTREACHED() << "Invalid type for a DateTimeChooser.";
+      break;
+  }
+  datePicker.preferredDatePickerStyle = UIDatePickerStyleInline;
+
+  // Convert milliseconds to seconds.
+  NSTimeInterval dialogValue = self.initTimeInMS / 1000;
+  NSDate* initValue = [NSDate dateWithTimeIntervalSince1970:dialogValue];
+  [datePicker setDate:initValue animated:FALSE];
+  [datePicker addTarget:self
+                 action:@selector(datePickerValueChanged:)
+       forControlEvents:UIControlEventValueChanged];
+  return datePicker;
+}
+
+- (void)cancelButtonTapped {
+  [[self presentingViewController] dismissViewControllerAnimated:YES
+                                                      completion:nil];
+  [self.delegate dateTimeChooser:self
+            didCloseSuccessfully:FALSE
+                        withDate:self.selectedDate];
+}
+
+- (void)doneButtonTapped {
+  [[self presentingViewController] dismissViewControllerAnimated:YES
+                                                      completion:nil];
+  // Convert seconds to miliseconds.
+  [self.delegate dateTimeChooser:self
+            didCloseSuccessfully:TRUE
+                        withDate:self.selectedDate];
+}
+
+- (void)datePickerValueChanged:(UIDatePicker*)datePicker {
+  self.selectedDate = datePicker.date;
+}
+
+// Adds subviews for a UI component with UIDatePicker and buttons.
+//
+// -------------------------------------
+//
+//
+//              UIDatePicker
+//
+//
+// --------------------------------------
+// | Cancel  |  flexibleSpace  |  Done  |
+// --------------------------------------
+//
+- (void)viewWillAppear:(BOOL)animated {
+  UIDatePicker* datePicker = [self createUIDatePicker];
+  // Create a ToolBar for buttons.
+  UIToolbar* toolbar = [[UIToolbar alloc]
+      initWithFrame:CGRectMake(0, 0, datePicker.frame.size.width,
+                               kToolBarHeight)];
+  UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc]
+      initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+                           target:self
+                           action:@selector(cancelButtonTapped)];
+  UIBarButtonItem* flexibleSpace = [[UIBarButtonItem alloc]
+      initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
+                           target:nil
+                           action:nil];
+  UIBarButtonItem* doneButton = [[UIBarButtonItem alloc]
+      initWithBarButtonSystemItem:UIBarButtonSystemItemDone
+                           target:self
+                           action:@selector(doneButtonTapped)];
+
+  // Add the UIBarButtonItem to the UIToolbar
+  [toolbar setItems:@[ cancelButton, flexibleSpace, doneButton ]];
+
+  // Vertical stack view that holds UIDatePicker and buttons.
+  UIStackView* verticalStack =
+      [[UIStackView alloc] initWithArrangedSubviews:@[ datePicker, toolbar ]];
+  verticalStack.axis = UILayoutConstraintAxisVertical;
+  verticalStack.spacing = 0;
+  verticalStack.distribution = UIStackViewDistributionFill;
+  verticalStack.layoutMarginsRelativeArrangement = YES;
+  verticalStack.layoutMargins = UIEdgeInsetsMake(0, 0, 0, 0);
+  verticalStack.translatesAutoresizingMaskIntoConstraints = NO;
+  [self.view addSubview:verticalStack];
+  [self.view setBounds:CGRectMake(CGRectGetMinX(datePicker.bounds),
+                                  CGRectGetMinY(datePicker.bounds),
+                                  CGRectGetWidth(datePicker.bounds),
+                                  CGRectGetHeight(datePicker.bounds) +
+                                      CGRectGetHeight(toolbar.bounds))];
+}
+
+@end
diff --git a/content/browser/preloading/prerender/prerender_browsertest.cc b/content/browser/preloading/prerender/prerender_browsertest.cc
index 2d2b678..611f697 100644
--- a/content/browser/preloading/prerender/prerender_browsertest.cc
+++ b/content/browser/preloading/prerender/prerender_browsertest.cc
@@ -5176,12 +5176,23 @@
 class PrerenderSequentialPrerenderingBrowserTest : public PrerenderBrowserTest {
  public:
   PrerenderSequentialPrerenderingBrowserTest() {
-    feature_list_.InitWithFeaturesAndParameters(
-        {{blink::features::kPrerender2,
-          {{"max_num_of_running_speculation_rules",
-            base::NumberToString(MaxNumOfRunningPrerenders())},
-           {"embedder_blocked_hosts", "a.test,b.test,c.test"}}}},
-        {});
+    if (base::FeatureList::IsEnabled(
+            features::kPrerender2NewLimitAndScheduler)) {
+      feature_list_.InitWithFeaturesAndParameters(
+          {{features::kPrerender2NewLimitAndScheduler,
+            {{"max_num_of_running_speculation_rules_eager_prerenders",
+              base::NumberToString(MaxNumOfRunningPrerenders())}}},
+           {blink::features::kPrerender2,
+            {{"embedder_blocked_hosts", "a.test,b.test,c.test"}}}},
+          {});
+    } else {
+      feature_list_.InitWithFeaturesAndParameters(
+          {{blink::features::kPrerender2,
+            {{"max_num_of_running_speculation_rules",
+              base::NumberToString(MaxNumOfRunningPrerenders())},
+             {"embedder_blocked_hosts", "a.test,b.test,c.test"}}}},
+          {});
+    }
   }
 
   int MaxNumOfRunningPrerenders() const { return 4; }
@@ -8891,18 +8902,31 @@
 class MultiplePrerendersBrowserTest : public PrerenderBrowserTest {
  public:
   MultiplePrerendersBrowserTest() {
-    feature_list_.InitWithFeaturesAndParameters(
-        {{blink::features::kPrerender2,
-          {{"max_num_of_running_speculation_rules",
-            base::NumberToString(MaxNumOfRunningPrerenders())}}},
-         {blink::features::kPrerender2MemoryControls,
-          // A value 100 allows prerenderings regardless of the current memory
-          // usage.
-          {{"acceptable_percent_of_system_memory", "100"},
-           // Allow prerendering on low-end trybot devices so that prerendering
-           // can run on any bots.
-           {"memory_threshold_in_mb", "0"}}}},
-        {});
+    base::test::FeatureRefAndParams memory_controls{
+        blink::features::kPrerender2MemoryControls,
+        // A value 100 allows prerenderings regardless of the current memory
+        // usage.
+        {{"acceptable_percent_of_system_memory", "100"},
+         // Allow prerendering on low-end trybot devices so that prerendering
+         // can run on any bots.
+         {"memory_threshold_in_mb", "0"}}};
+
+    if (base::FeatureList::IsEnabled(
+            features::kPrerender2NewLimitAndScheduler)) {
+      feature_list_.InitWithFeaturesAndParameters(
+          {{features::kPrerender2NewLimitAndScheduler,
+            {{"max_num_of_running_speculation_rules_eager_prerenders",
+              base::NumberToString(MaxNumOfRunningPrerenders())}}},
+           memory_controls},
+          {});
+    } else {
+      feature_list_.InitWithFeaturesAndParameters(
+          {{blink::features::kPrerender2,
+            {{"max_num_of_running_speculation_rules",
+              base::NumberToString(MaxNumOfRunningPrerenders())}}},
+           memory_controls},
+          {});
+    }
   }
 
   int MaxNumOfRunningPrerenders() const { return 4; }
@@ -8915,17 +8939,30 @@
     : public MultiplePrerendersBrowserTest {
  public:
   MultiplePrerendersWithLimitedMemoryBrowserTest() {
-    feature_list_.InitWithFeaturesAndParameters(
-        {{blink::features::kPrerender2,
-          {{"max_num_of_running_speculation_rules",
-            base::NumberToString(MaxNumOfRunningPrerenders())}}},
-         {blink::features::kPrerender2MemoryControls,
-          // A value 0 doesn't allow any prerendering.
-          {{"acceptable_percent_of_system_memory", "0"},
-           // Allow prerendering on low-end trybot devices so that prerendering
-           // can run on any bots.
-           {"memory_threshold_in_mb", "0"}}}},
-        {features::kPrerender2BypassMemoryLimitCheck});
+    base::test::FeatureRefAndParams memory_controls{
+        blink::features::kPrerender2MemoryControls,
+        // A value 0 doesn't allow any prerendering.
+        {{"acceptable_percent_of_system_memory", "0"},
+         // Allow prerendering on low-end trybot devices so that prerendering
+         // can run on any bots.
+         {"memory_threshold_in_mb", "0"}}};
+
+    if (base::FeatureList::IsEnabled(
+            features::kPrerender2NewLimitAndScheduler)) {
+      feature_list_.InitWithFeaturesAndParameters(
+          {{features::kPrerender2NewLimitAndScheduler,
+            {{"max_num_of_running_speculation_rules_eager_prerenders",
+              base::NumberToString(MaxNumOfRunningPrerenders())}}},
+           memory_controls},
+          {features::kPrerender2BypassMemoryLimitCheck});
+    } else {
+      feature_list_.InitWithFeaturesAndParameters(
+          {{blink::features::kPrerender2,
+            {{"max_num_of_running_speculation_rules",
+              base::NumberToString(MaxNumOfRunningPrerenders())}}},
+           memory_controls},
+          {features::kPrerender2BypassMemoryLimitCheck});
+    }
   }
 
  private:
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 5d00859c..ecbd03a 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -1600,12 +1600,4 @@
   return true;
 }
 
-#if !BUILDFLAG(IS_ANDROID)
-void ContentBrowserClient::BindVideoEffectsManager(
-    const std::string& device_id,
-    content::BrowserContext* browser_context,
-    mojo::PendingReceiver<video_capture::mojom::VideoEffectsManager>
-        video_effects_manager) {}
-#endif  // !BUILDFLAG(IS_ANDROID)
-
 }  // namespace content
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 401eef3..fb6b64a 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -82,10 +82,6 @@
 #include "content/public/browser/posix_file_descriptor_info.h"
 #endif
 
-#if !BUILDFLAG(IS_ANDROID)
-#include "services/video_capture/public/mojom/video_effects_manager.mojom.h"
-#endif  // !BUILDFLAG(IS_ANDROID)
-
 namespace net {
 class SiteForCookies;
 class IsolationInfo;
@@ -2634,16 +2630,6 @@
   // Set whether the browser is running in minimal mode (where most subsystems
   // are left uninitialized).
   virtual void SetIsMinimalMode(bool minimal) {}
-
-#if !BUILDFLAG(IS_ANDROID)
-  // Allows the embedder to correlate backend media services with profile-keyed
-  // effect settings.
-  virtual void BindVideoEffectsManager(
-      const std::string& device_id,
-      content::BrowserContext* browser_context,
-      mojo::PendingReceiver<video_capture::mojom::VideoEffectsManager>
-          video_effects_manager);
-#endif  // !BUILDFLAG(IS_ANDROID)
 };
 
 }  // namespace content
diff --git a/content/renderer/media/win/dcomp_texture_wrapper_impl.cc b/content/renderer/media/win/dcomp_texture_wrapper_impl.cc
index 87239e3..93057fbf 100644
--- a/content/renderer/media/win/dcomp_texture_wrapper_impl.cc
+++ b/content/renderer/media/win/dcomp_texture_wrapper_impl.cc
@@ -181,7 +181,7 @@
   }
 
   auto frame = media::VideoFrame::WrapNativeTextures(
-      media::PIXEL_FORMAT_ARGB, holders,
+      media::PIXEL_FORMAT_BGRA, holders,
       base::BindPostTask(
           media_task_runner_,
           base::BindOnce(&OnReleaseVideoFrame, dcomp_texture_resources_)),
@@ -208,7 +208,7 @@
 
   std::unique_ptr<gfx::GpuMemoryBuffer> gmb =
       gpu::GpuMemoryBufferImplDXGI::CreateFromHandle(
-          std::move(dx_handle), natural_size, gfx::BufferFormat::RGBA_8888,
+          std::move(dx_handle), natural_size, gfx::BufferFormat::BGRA_8888,
           gfx::BufferUsage::GPU_READ, base::NullCallback(), nullptr, nullptr);
 
   // The VideoFrame object requires a 4 array mailbox holder because some
@@ -218,7 +218,7 @@
   // holder.
   gpu::MailboxHolder holder[media::VideoFrame::kMaxPlanes];
   gpu::Mailbox mailbox = sii->CreateSharedImage(
-      viz::SinglePlaneFormat::kRGBA_8888, natural_size, gfx::ColorSpace(),
+      viz::SinglePlaneFormat::kBGRA_8888, natural_size, gfx::ColorSpace(),
       kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, usage,
       "DCOMPTextureWrapperImpl", gmb->CloneHandle());
   gpu::SyncToken sync_token = sii->GenVerifiedSyncToken();
diff --git a/content/test/gpu/gpu_tests/gpu_integration_test.py b/content/test/gpu/gpu_tests/gpu_integration_test.py
index 57e53d9f..9212063 100644
--- a/content/test/gpu/gpu_tests/gpu_integration_test.py
+++ b/content/test/gpu/gpu_tests/gpu_integration_test.py
@@ -8,9 +8,10 @@
 import fnmatch
 import importlib
 import inspect
-import pkgutil
+import json
 import logging
 import os
+import pkgutil
 import re
 import sys
 import types
@@ -32,6 +33,8 @@
 from gpu_tests import common_typing as ct
 from gpu_tests import gpu_helper
 
+TEST_WAS_SLOW = 'test_was_slow'
+
 _START_BROWSER_RETRIES = 3
 _MAX_TEST_TRIES = 3
 
@@ -586,6 +589,8 @@
       (expected_results,
        should_retry_on_failure) = _GetExpectedResultsAndShouldRetry()
       self._HandlePass(test_name, expected_crashes, expected_results)
+    finally:
+      self.additionalTags[TEST_WAS_SLOW] = json.dumps(self._TestWasSlow())
 
   def _HandleExpectedFailureOrFlake(self, test_name: str,
                                     expected_crashes: Dict[str, int],
@@ -637,6 +642,9 @@
     if self._ShouldRestartBrowserAfterFailure():
       self._RestartBrowser('unexpected test failure')
 
+  def _TestWasSlow(self) -> bool:  # pylint: disable=no-self-use
+    return False
+
   def _ShouldRestartBrowserAfterFailure(self) -> bool:
     return not self._skip_post_failure_browser_restart
 
diff --git a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
index 480b3b2..c6d47e9 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
@@ -136,6 +136,9 @@
 crbug.com/1470336 [ android-oreo android-nexus-5x ] WebCodecs_EncodingRateControl_vp8_prefer-hardware_constant_3000000 [ Failure ]
 crbug.com/1474916 [ android-nexus-5x ] WebCodecs_EncodeColorSpace_avc1.42001E_prefer-hardware [ Failure ]
 
+crbug.com/1486660 [ chromeos chromeos-board-jacuzzi ] WebCodecs_copyTo_sw_decoder [ Failure ]
+crbug.com/1486660 [ chromeos chromeos-board-jacuzzi ] WebCodecs_EncodeColorSpace_avc1.42001E_prefer-hardware [ Failure ]
+
 #######################################################################
 # Automated Entries After This Point - Do Not Manually Add Below Here #
 #######################################################################
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
index 7f3dbce..725a07a 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -229,6 +229,29 @@
 crbug.com/1429756 [ chromeos chromeos-board-kevin passthrough ] WebglExtension_WEBGL_clip_cull_distance [ Skip ]
 crbug.com/1429756 [ chromeos chromeos-board-kevin ] WebglExtension_WEBGL_provoking_vertex [ Skip ]
 
+# Extensions not available on jacuzzi ChromeOS devices.
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_EXT_blend_func_extended [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_EXT_clip_control [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_EXT_conservative_depth [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_EXT_depth_clamp [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_EXT_polygon_offset_clamp [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_EXT_render_snorm [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_EXT_texture_compression_bptc [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_EXT_texture_compression_rgtc [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_EXT_texture_mirror_clamp_to_edge [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_EXT_texture_norm16 [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi passthrough angle-opengles ] WebglExtension_KHR_parallel_shader_compile [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_NV_shader_noperspective_interpolation [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_OES_texture_float_linear [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_OVR_multiview2 [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_WEBGL_clip_cull_distance [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_WEBGL_compressed_texture_pvrtc [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_WEBGL_compressed_texture_s3tc [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_WEBGL_compressed_texture_s3tc_srgb [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi passthrough ] WebglExtension_WEBGL_polygon_mode [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_WEBGL_provoking_vertex [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi passthrough angle-opengles ] WebglExtension_WEBGL_render_shared_exponent [ Skip ]
+
 # Parallel Shader compile/link is currently slower with Vulkan backend.
 crbug.com/angleproject/6748 [ angle-vulkan passthrough ] WebglExtension_KHR_parallel_shader_compile [ Skip ]
 crbug.com/angleproject/6748 [ angle-swiftshader passthrough ] WebglExtension_KHR_parallel_shader_compile [ Skip ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
index 27b61d5..609440c 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -220,6 +220,20 @@
 crbug.com/1473838 [ chromeos passthrough ] WebglExtension_EXT_texture_mirror_clamp_to_edge [ Skip ]
 crbug.com/1473838 [ chromeos passthrough ] WebglExtension_WEBGL_polygon_mode [ Skip ]
 
+# Extensions not available on jacuzzi ChromeOS devices.
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_EXT_color_buffer_half_float [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_EXT_frag_depth [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_EXT_texture_compression_bptc [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_EXT_texture_compression_rgtc [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_OES_texture_float [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_OES_texture_float_linear [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_OES_texture_half_float [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_OES_texture_half_float_linear [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_WEBGL_color_buffer_float [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_WEBGL_compressed_texture_s3tc [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_WEBGL_compressed_texture_s3tc_srgb [ Skip ]
+crbug.com/1486664 [ chromeos cros-chrome chromeos-board-jacuzzi ] WebglExtension_WEBGL_draw_buffers [ Skip ]
+
 # Extensions not available on LaCrOS (ChromeOS / Intel bot).
 crbug.com/1473838 [ linux intel passthrough display-server-wayland ] WebglExtension_EXT_texture_mirror_clamp_to_edge [ Skip ]
 crbug.com/1473838 [ linux intel passthrough display-server-wayland ] WebglExtension_WEBGL_polygon_mode [ Skip ]
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 a6cfe5e..5280e1d 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
@@ -34,6 +34,10 @@
 SLOW_MULTIPLIER = 4
 WEBENGINE_MULTIPLIER = 4
 
+# Thresholds for how slow parts of the test have to be for the test to be
+# considered slow overall.
+SLOW_HEARTBEAT_THRESHOLD = 0.5
+
 # Non-standard timeouts that can't be handled by a Slow expectation, likely due
 # to being particularly long or not specific to a configuration. Try to use
 # expectations first.
@@ -85,6 +89,10 @@
 
   websocket_server: Optional[wss.WebsocketServer] = None
 
+  def __init__(self, *args, **kwargs):
+    super().__init__(*args, **kwargs)
+    self._longest_time_between_heartbeats = 0
+
   @classmethod
   def _SuiteSupportsParallelTests(cls) -> bool:
     return True
@@ -216,6 +224,13 @@
     # See crbug.com/1079244.
     return 'chromeos-board-amd64-generic' in self.GetPlatformTags(self.browser)
 
+  def _TestWasSlow(self) -> bool:
+    # Consider the test slow if it had a relatively long time between
+    # heartbeats.
+    heartbeat_fraction = (self._longest_time_between_heartbeats /
+                          self._GetNonSlowHeartbeatTimeout())
+    return heartbeat_fraction > SLOW_HEARTBEAT_THRESHOLD
+
   def RunActualGpuTest(self, test_path: str, args: ct.TestArgs) -> None:
     # This indirection allows these tests to trampoline through
     # _RunGpuTest.
@@ -312,8 +327,12 @@
     start_time = time.time()
     try:
       while True:
+        response_start_time = time.time()
         response = self.__class__.websocket_server.Receive(
             self._GetHeartbeatTimeout())
+        self._longest_time_between_heartbeats = max(
+            self._longest_time_between_heartbeats,
+            time.time() - response_start_time)
         response = json.loads(response)
         response_type = response['type']
 
@@ -356,23 +375,29 @@
           'caused by a renderer crash' % (time.time() - start_time)) from e
 
   def _GetHeartbeatTimeout(self) -> int:
-    return int(
-        NON_STANDARD_HEARTBEAT_TIMEOUTS.get(self.shortName(),
-                                            HEARTBEAT_TIMEOUT_S) *
-        self._GetTimeoutMultiplier())
+    return int(self._GetNonSlowHeartbeatTimeout() * self._GetSlowMultiplier())
 
-  def _GetTimeoutMultiplier(self) -> float:
+  def _GetNonSlowHeartbeatTimeout(self) -> float:
+    return (NON_STANDARD_HEARTBEAT_TIMEOUTS.get(self.shortName(),
+                                                HEARTBEAT_TIMEOUT_S) *
+            self._GetBrowserTimeoutMultiplier())
+
+  def _GetBrowserTimeoutMultiplier(self) -> float:
+    """Compute the multiplier to account for overall browser slowness."""
     # Parallel jobs increase load and can slow down test execution, so scale
     # based on the number of jobs. Target 2x increase with 4 jobs.
     multiplier = 1 + (self.child.jobs - 1) / 3.0
     if self.is_asan:
       multiplier *= ASAN_MULTIPLIER
-    if self._IsSlowTest():
-      multiplier *= SLOW_MULTIPLIER
     if self._finder_options.browser_type == 'web-engine-shell':
       multiplier *= WEBENGINE_MULTIPLIER
     return multiplier
 
+  def _GetSlowMultiplier(self) -> float:
+    if self._IsSlowTest():
+      return SLOW_MULTIPLIER
+    return 1
+
   def _IsSlowTest(self) -> bool:
     # We access the expectations directly instead of using
     # self.GetExpectationsForTest since we need the raw results, but that method
diff --git a/content/test/gpu/gpu_tests/webgpu_cts_integration_test.py b/content/test/gpu/gpu_tests/webgpu_cts_integration_test.py
index a40451568..54db405 100644
--- a/content/test/gpu/gpu_tests/webgpu_cts_integration_test.py
+++ b/content/test/gpu/gpu_tests/webgpu_cts_integration_test.py
@@ -48,6 +48,11 @@
 MESSAGE_TIMEOUT_HEARTBEAT = 5
 MESSAGE_TIMEOUT_TEST_LOG = 1
 
+# Thresholds for how slow parts of the test have to be for the test to be
+# considered slow overall.
+SLOW_HEARTBEAT_THRESHOLD = 0.5
+SLOW_GLOBAL_TIMEOUT_THRESHOLD = 0.8
+
 HTML_FILENAME = os.path.join('webgpu-cts', 'test_page.html')
 
 JAVASCRIPT_DURATION = 'javascript_duration'
@@ -98,6 +103,10 @@
     super().__init__(*args, **kwargs)
     self._query: Optional[str] = None
     self._run_in_worker = False
+    self._longest_time_between_heartbeats = 0
+    self._heartbeat_timeout = 0
+    self._test_duration = 0
+    self._global_timeout_without_slow_multiplier = 1
 
   # Only perform the pre/post test cleanup every X tests instead of every test
   # to reduce overhead.
@@ -382,6 +391,19 @@
     # Retry in case the timeout was a flake.
     return True
 
+  def _TestWasSlow(self) -> bool:
+    # Consider the test slow if it either had a relatively long time between
+    # heartbeats or took up a significant chunk of the global timeout.
+    heartbeat_fraction = (self._longest_time_between_heartbeats /
+                          self._heartbeat_timeout)
+    heartbeat_was_slow = heartbeat_fraction > SLOW_HEARTBEAT_THRESHOLD
+
+    global_fraction = (self._test_duration /
+                       self._global_timeout_without_slow_multiplier)
+    global_was_slow = global_fraction > SLOW_GLOBAL_TIMEOUT_THRESHOLD
+
+    return heartbeat_was_slow or global_was_slow
+
   def RunActualGpuTest(self, test_path: str, args: ct.TestArgs) -> None:
     self._query, self._run_in_worker = args
     # Only a single instance is used to run tests despite a number of instances
@@ -444,16 +466,20 @@
     Returns:
       A float.
     """
-    # Scale the test timeout if test execution is expected to be slow: the test
-    # is explicitly marked as slow, or we're running with backend validation.
+    return (self._GetTestExecutionTimeoutMultiplierWithoutSlowMultiplier() *
+            self._GetSlowTestMultiplier())
+
+  def _GetTestExecutionTimeoutMultiplierWithoutSlowMultiplier(self) -> float:
     test_execution_timeout_multiplier = 1
-    if self._IsSlowTest():
-      test_execution_timeout_multiplier *= SLOW_MULTIPLIER
     if self._enable_dawn_backend_validation:
       test_execution_timeout_multiplier *= BACKEND_VALIDATION_MULTIPLIER
-
     return test_execution_timeout_multiplier
 
+  def _GetSlowTestMultiplier(self) -> float:
+    if self._IsSlowTest():
+      return SLOW_MULTIPLIER
+    return 1
+
   def HandleMessageLoop(self, first_load) -> WebGpuTestResult:
     """Helper function to handle the loop for the message protocol.
 
@@ -482,6 +508,10 @@
 
     global_timeout = (self._test_timeout * test_execution_timeout_multiplier *
                       browser_timeout_multiplier)
+    self._global_timeout_without_slow_multiplier = (
+        self._test_timeout *
+        self._GetTestExecutionTimeoutMultiplierWithoutSlowMultiplier() *
+        browser_timeout_multiplier)
     start_time = time.time()
 
     # Loop until one of the following happens:
@@ -495,8 +525,13 @@
     #     which case we report a message protocol error.
     while True:
       timeout = step_timeout * browser_timeout_multiplier
+      self._heartbeat_timeout = timeout
       try:
+        response_start_time = time.time()
         response = WebGpuCtsIntegrationTest.websocket_server.Receive(timeout)
+        self._longest_time_between_heartbeats = max(
+            self._longest_time_between_heartbeats,
+            time.time() - response_start_time)
         response = json.loads(response)
         response_type = response['type']
 
@@ -544,6 +579,8 @@
         raise WebGpuMessageTimeoutError(
             'Timed out waiting %.3f seconds for a message. Message state: %s' %
             (timeout, message_state)) from e
+      finally:
+        self._test_duration = time.time() - start_time
     return result
 
   def HandleDurationTagOnFailure(self, message_state: Dict[str, bool],
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn
index 1cba010..b0e8d20 100644
--- a/extensions/browser/BUILD.gn
+++ b/extensions/browser/BUILD.gn
@@ -132,8 +132,8 @@
     "api/declarative_net_request/request_action.h",
     "api/declarative_net_request/request_params.cc",
     "api/declarative_net_request/request_params.h",
-    "api/declarative_net_request/rules_count_pair.cc",
-    "api/declarative_net_request/rules_count_pair.h",
+    "api/declarative_net_request/rule_counts.cc",
+    "api/declarative_net_request/rule_counts.h",
     "api/declarative_net_request/rules_monitor_service.cc",
     "api/declarative_net_request/rules_monitor_service.h",
     "api/declarative_net_request/ruleset_install_pref.cc",
diff --git a/extensions/browser/api/declarative_net_request/file_sequence_helper.cc b/extensions/browser/api/declarative_net_request/file_sequence_helper.cc
index ee748c0..63b90d4 100644
--- a/extensions/browser/api/declarative_net_request/file_sequence_helper.cc
+++ b/extensions/browser/api/declarative_net_request/file_sequence_helper.cc
@@ -25,7 +25,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "extensions/browser/api/declarative_net_request/constants.h"
 #include "extensions/browser/api/declarative_net_request/parse_info.h"
-#include "extensions/browser/api/declarative_net_request/rules_count_pair.h"
+#include "extensions/browser/api/declarative_net_request/rule_counts.h"
 #include "extensions/browser/api/declarative_net_request/utils.h"
 #include "extensions/browser/extension_file_task_runner.h"
 #include "extensions/common/api/declarative_net_request.h"
@@ -169,7 +169,7 @@
 bool GetNewDynamicRules(const FileBackedRulesetSource& source,
                         std::vector<int> rule_ids_to_remove,
                         std::vector<dnr_api::Rule> rules_to_add,
-                        const RulesCountPair& rule_limit,
+                        const RuleCounts& rule_limit,
                         std::vector<dnr_api::Rule>* new_rules,
                         std::string* error,
                         UpdateDynamicRulesStatus* status) {
@@ -233,7 +233,7 @@
 bool UpdateAndIndexDynamicRules(const FileBackedRulesetSource& source,
                                 std::vector<int> rule_ids_to_remove,
                                 std::vector<dnr_api::Rule> rules_to_add,
-                                const RulesCountPair& rule_limit,
+                                const RuleCounts& rule_limit,
                                 int* ruleset_checksum,
                                 std::string* error,
                                 UpdateDynamicRulesStatus* status) {
@@ -425,7 +425,7 @@
     LoadRequestData load_data,
     std::vector<int> rule_ids_to_remove,
     std::vector<api::declarative_net_request::Rule> rules_to_add,
-    const RulesCountPair& rule_limit,
+    const RuleCounts& rule_limit,
     UpdateDynamicRulesUICallback ui_callback) const {
   DCHECK(GetExtensionFileTaskRunner()->RunsTasksInCurrentSequence());
   DCHECK_EQ(1u, load_data.rulesets.size());
diff --git a/extensions/browser/api/declarative_net_request/file_sequence_helper.h b/extensions/browser/api/declarative_net_request/file_sequence_helper.h
index a70d9a7e..f6ff0aa 100644
--- a/extensions/browser/api/declarative_net_request/file_sequence_helper.h
+++ b/extensions/browser/api/declarative_net_request/file_sequence_helper.h
@@ -27,7 +27,7 @@
 
 namespace declarative_net_request {
 enum class DynamicRuleUpdateAction;
-struct RulesCountPair;
+struct RuleCounts;
 
 // Holds the data relating to the loading of a single ruleset.
 class RulesetInfo {
@@ -137,7 +137,7 @@
       LoadRequestData load_data,
       std::vector<int> rule_ids_to_remove,
       std::vector<api::declarative_net_request::Rule> rules_to_add,
-      const RulesCountPair& rule_limit,
+      const RuleCounts& rule_limit,
       UpdateDynamicRulesUICallback ui_callback) const;
 
  private:
diff --git a/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc b/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc
index d05057f..efd34a25 100644
--- a/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc
+++ b/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc
@@ -19,7 +19,7 @@
 #include "extensions/browser/api/declarative_net_request/constants.h"
 #include "extensions/browser/api/declarative_net_request/file_backed_ruleset_source.h"
 #include "extensions/browser/api/declarative_net_request/parse_info.h"
-#include "extensions/browser/api/declarative_net_request/rules_count_pair.h"
+#include "extensions/browser/api/declarative_net_request/rule_counts.h"
 #include "extensions/browser/api/declarative_net_request/test_utils.h"
 #include "extensions/browser/api/declarative_net_request/utils.h"
 #include "extensions/browser/extension_file_task_runner.h"
@@ -109,7 +109,7 @@
         &FileSequenceHelper::UpdateDynamicRules,
         base::Unretained(helper_.get()), std::move(data),
         /* rule_ids_to_remove */ std::vector<int>(), std::move(rules_to_add),
-        RulesCountPair(GetDynamicAndSessionRuleLimit(), GetRegexRuleLimit()),
+        RuleCounts(GetDynamicAndSessionRuleLimit(), GetRegexRuleLimit()),
         std::move(add_rules_callback));
 
     base::HistogramTester tester;
diff --git a/extensions/browser/api/declarative_net_request/rule_counts.cc b/extensions/browser/api/declarative_net_request/rule_counts.cc
new file mode 100644
index 0000000..ffd841f
--- /dev/null
+++ b/extensions/browser/api/declarative_net_request/rule_counts.cc
@@ -0,0 +1,44 @@
+// 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 "extensions/browser/api/declarative_net_request/rule_counts.h"
+
+#include "base/check_op.h"
+
+namespace extensions::declarative_net_request {
+
+RuleCounts::RuleCounts() = default;
+RuleCounts::RuleCounts(size_t rule_count, size_t regex_rule_count)
+    : rule_count(rule_count), regex_rule_count(regex_rule_count) {}
+
+RuleCounts& RuleCounts::operator+=(const RuleCounts& that) {
+  rule_count += that.rule_count;
+  regex_rule_count += that.regex_rule_count;
+  return *this;
+}
+
+RuleCounts& RuleCounts::operator-=(const RuleCounts& that) {
+  CHECK_GE(rule_count, that.rule_count);
+  CHECK_GE(regex_rule_count, that.regex_rule_count);
+  rule_count -= that.rule_count;
+  regex_rule_count -= that.regex_rule_count;
+  return *this;
+}
+
+RuleCounts operator+(const RuleCounts& lhs, const RuleCounts& rhs) {
+  RuleCounts result = lhs;
+  return result += rhs;
+}
+
+RuleCounts operator-(const RuleCounts& lhs, const RuleCounts& rhs) {
+  RuleCounts result = lhs;
+  return result -= rhs;
+}
+
+bool operator==(const RuleCounts& lhs, const RuleCounts& rhs) {
+  return lhs.rule_count == rhs.rule_count &&
+         lhs.regex_rule_count == rhs.regex_rule_count;
+}
+
+}  // namespace extensions::declarative_net_request
diff --git a/extensions/browser/api/declarative_net_request/rule_counts.h b/extensions/browser/api/declarative_net_request/rule_counts.h
new file mode 100644
index 0000000..43271d3
--- /dev/null
+++ b/extensions/browser/api/declarative_net_request/rule_counts.h
@@ -0,0 +1,38 @@
+// 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 EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_RULE_COUNTS_H_
+#define EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_RULE_COUNTS_H_
+
+#include <cstddef>
+
+namespace extensions::declarative_net_request {
+
+// Represents the pair of total rule count and regex rule count for a ruleset.
+struct RuleCounts {
+  RuleCounts();
+  RuleCounts(size_t rule_count, size_t regex_rule_count);
+
+  RuleCounts& operator+=(const RuleCounts& that);
+
+  // This CHECKs that counts in |that| are smaller than or equal to the one in
+  // |this|.
+  RuleCounts& operator-=(const RuleCounts& that);
+
+  size_t rule_count = 0;
+  size_t regex_rule_count = 0;
+  // TODO(crbug.com/1485747): Add an unsafe_rule_count here.
+};
+
+RuleCounts operator+(const RuleCounts& lhs, const RuleCounts& rhs);
+
+// This CHECKs that counts in |rhs| are smaller than or equal to the one in
+// |lhs|.
+RuleCounts operator-(const RuleCounts& lhs, const RuleCounts& rhs);
+
+bool operator==(const RuleCounts& lhs, const RuleCounts& rhs);
+
+}  // namespace extensions::declarative_net_request
+
+#endif  // EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_RULE_COUNTS_H_
diff --git a/extensions/browser/api/declarative_net_request/rules_count_pair.cc b/extensions/browser/api/declarative_net_request/rules_count_pair.cc
deleted file mode 100644
index 9558df7..0000000
--- a/extensions/browser/api/declarative_net_request/rules_count_pair.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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 "extensions/browser/api/declarative_net_request/rules_count_pair.h"
-
-#include "base/check_op.h"
-
-namespace extensions {
-namespace declarative_net_request {
-
-RulesCountPair::RulesCountPair() = default;
-RulesCountPair::RulesCountPair(size_t rule_count, size_t regex_rule_count)
-    : rule_count(rule_count), regex_rule_count(regex_rule_count) {}
-
-RulesCountPair& RulesCountPair::operator+=(const RulesCountPair& that) {
-  rule_count += that.rule_count;
-  regex_rule_count += that.regex_rule_count;
-  return *this;
-}
-
-RulesCountPair& RulesCountPair::operator-=(const RulesCountPair& that) {
-  CHECK_GE(rule_count, that.rule_count);
-  CHECK_GE(regex_rule_count, that.regex_rule_count);
-  rule_count -= that.rule_count;
-  regex_rule_count -= that.regex_rule_count;
-  return *this;
-}
-
-RulesCountPair operator+(const RulesCountPair& lhs, const RulesCountPair& rhs) {
-  RulesCountPair result = lhs;
-  return result += rhs;
-}
-
-RulesCountPair operator-(const RulesCountPair& lhs, const RulesCountPair& rhs) {
-  RulesCountPair result = lhs;
-  return result -= rhs;
-}
-
-bool operator==(const RulesCountPair& lhs, const RulesCountPair& rhs) {
-  return lhs.rule_count == rhs.rule_count &&
-         lhs.regex_rule_count == rhs.regex_rule_count;
-}
-
-}  // namespace declarative_net_request
-}  // namespace extensions
diff --git a/extensions/browser/api/declarative_net_request/rules_count_pair.h b/extensions/browser/api/declarative_net_request/rules_count_pair.h
deleted file mode 100644
index c4f16c0..0000000
--- a/extensions/browser/api/declarative_net_request/rules_count_pair.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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 EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_RULES_COUNT_PAIR_H_
-#define EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_RULES_COUNT_PAIR_H_
-
-#include <cstddef>
-
-namespace extensions {
-namespace declarative_net_request {
-
-// Represents the pair of total rule count and regex rule count for a ruleset.
-struct RulesCountPair {
-  RulesCountPair();
-  RulesCountPair(size_t rule_count, size_t regex_rule_count);
-
-  RulesCountPair& operator+=(const RulesCountPair& that);
-
-  // This CHECKs that counts in |that| are smaller than or equal to the one in
-  // |this|.
-  RulesCountPair& operator-=(const RulesCountPair& that);
-
-  size_t rule_count = 0;
-  size_t regex_rule_count = 0;
-};
-
-RulesCountPair operator+(const RulesCountPair& lhs, const RulesCountPair& rhs);
-
-// This CHECKs that counts in |rhs| are smaller than or equal to the one in
-// |lhs|.
-RulesCountPair operator-(const RulesCountPair& lhs, const RulesCountPair& rhs);
-
-bool operator==(const RulesCountPair& lhs, const RulesCountPair& rhs);
-
-}  // namespace declarative_net_request
-}  // namespace extensions
-
-#endif  // EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_RULES_COUNT_PAIR_H_
diff --git a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
index 60349ba..d06cc8b 100644
--- a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
+++ b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
@@ -28,7 +28,7 @@
 #include "extensions/browser/api/declarative_net_request/file_backed_ruleset_source.h"
 #include "extensions/browser/api/declarative_net_request/file_sequence_helper.h"
 #include "extensions/browser/api/declarative_net_request/parse_info.h"
-#include "extensions/browser/api/declarative_net_request/rules_count_pair.h"
+#include "extensions/browser/api/declarative_net_request/rule_counts.h"
 #include "extensions/browser/api/declarative_net_request/ruleset_manager.h"
 #include "extensions/browser/api/declarative_net_request/ruleset_matcher.h"
 #include "extensions/browser/api/web_request/extension_web_request_event_router.h"
@@ -185,7 +185,7 @@
       LoadRequestData load_data,
       std::vector<int> rule_ids_to_remove,
       std::vector<dnr_api::Rule> rules_to_add,
-      const RulesCountPair& rule_limit,
+      const RuleCounts& rule_limit,
       FileSequenceHelper::UpdateDynamicRulesUICallback ui_callback) const {
     // base::Unretained is safe here because we trigger the destruction of
     // |file_sequence_state_| on |file_task_runner_| from our destructor. Hence
@@ -408,19 +408,18 @@
           std::move(callback));
 }
 
-RulesCountPair RulesMonitorService::GetRulesCountPair(
-    const ExtensionId& extension_id,
-    RulesetID id) const {
+RuleCounts RulesMonitorService::GetRuleCounts(const ExtensionId& extension_id,
+                                              RulesetID id) const {
   const CompositeMatcher* matcher =
       ruleset_manager_.GetMatcherForExtension(extension_id);
   if (!matcher)
-    return RulesCountPair();
+    return RuleCounts();
 
   const RulesetMatcher* ruleset_matcher = matcher->GetMatcherWithID(id);
   if (!ruleset_matcher)
-    return RulesCountPair();
+    return RuleCounts();
 
-  return ruleset_matcher->GetRulesCountPair();
+  return ruleset_matcher->GetRuleCounts();
 }
 
 RulesMonitorService::RulesMonitorService(
@@ -631,11 +630,11 @@
   // another simultaneous api call since we ensure that for a given extension,
   // only up to 1 updateDynamicRules/updateSessionRules call is in progress. See
   // the usage of `ApiCallQueue`.
-  RulesCountPair shared_rules_limit(GetDynamicAndSessionRuleLimit(),
-                                    GetRegexRuleLimit());
-  RulesCountPair session_rules_count =
-      GetRulesCountPair(extension_id, kSessionRulesetID);
-  RulesCountPair available_limit = shared_rules_limit - session_rules_count;
+  RuleCounts shared_rules_limit(GetDynamicAndSessionRuleLimit(),
+                                GetRegexRuleLimit());
+  RuleCounts session_rules_count =
+      GetRuleCounts(extension_id, kSessionRulesetID);
+  RuleCounts available_limit = shared_rules_limit - session_rules_count;
 
   // We are updating the indexed ruleset. Don't set the expected checksum since
   // it'll change.
@@ -680,11 +679,11 @@
 
   // Check if the update would exceed shared rule limits.
   {
-    RulesCountPair dynamic_rule_count =
-        GetRulesCountPair(extension_id, kDynamicRulesetID);
-    RulesCountPair shared_rule_limit(GetDynamicAndSessionRuleLimit(),
-                                     GetRegexRuleLimit());
-    RulesCountPair available_limit = shared_rule_limit - dynamic_rule_count;
+    RuleCounts dynamic_rule_count =
+        GetRuleCounts(extension_id, kDynamicRulesetID);
+    RuleCounts shared_rule_limit(GetDynamicAndSessionRuleLimit(),
+                                 GetRegexRuleLimit());
+    RuleCounts available_limit = shared_rule_limit - dynamic_rule_count;
     if (new_rules.size() > available_limit.rule_count) {
       std::move(callback).Run(kSessionRuleCountExceeded);
       return;
@@ -865,11 +864,11 @@
   // at install time (by raising a hard error) to maintain forwards
   // compatibility. Since we iterate based on the order of ruleset ID, we'll
   // give more preference to rulesets occurring first in the manifest.
-  RulesCountPair static_rule_count;
+  RuleCounts static_rule_count;
   bool notify_ruleset_failed_to_load = false;
   bool global_rule_limit_exceeded = false;
 
-  RulesCountPair static_rule_limit(
+  RuleCounts static_rule_limit(
       global_rules_tracker_.GetAvailableAllocation(load_data.extension_id) +
           GetStaticGuaranteedMinimumRuleCount(),
       GetRegexRuleLimit());
@@ -882,7 +881,7 @@
 
     std::unique_ptr<RulesetMatcher> matcher = ruleset.TakeMatcher();
 
-    RulesCountPair matcher_count = matcher->GetRulesCountPair();
+    RuleCounts matcher_count = matcher->GetRuleCounts();
 
     // Per-ruleset limits should have been enforced during
     // indexing/installation.
@@ -895,7 +894,7 @@
       continue;
     }
 
-    RulesCountPair new_ruleset_count = static_rule_count + matcher_count;
+    RuleCounts new_ruleset_count = static_rule_count + matcher_count;
     if (new_ruleset_count.rule_count > static_rule_limit.rule_count) {
       global_rule_limit_exceeded = true;
       continue;
@@ -955,7 +954,7 @@
   }
 
   int static_ruleset_count = 0;
-  RulesCountPair static_rule_count;
+  RuleCounts static_rule_count;
   CompositeMatcher* matcher =
       ruleset_manager_.GetMatcherForExtension(load_data.extension_id);
   if (matcher) {
@@ -977,7 +976,7 @@
         continue;
 
       static_ruleset_count += 1;
-      static_rule_count += ruleset_matcher->GetRulesCountPair();
+      static_rule_count += ruleset_matcher->GetRuleCounts();
     }
   }
 
@@ -991,7 +990,7 @@
 
     std::unique_ptr<RulesetMatcher> ruleset_matcher = ruleset.TakeMatcher();
 
-    RulesCountPair matcher_count = ruleset_matcher->GetRulesCountPair();
+    RuleCounts matcher_count = ruleset_matcher->GetRuleCounts();
 
     // Per-ruleset limits should have been enforced during
     // indexing/installation.
diff --git a/extensions/browser/api/declarative_net_request/rules_monitor_service.h b/extensions/browser/api/declarative_net_request/rules_monitor_service.h
index f467410..85b5538 100644
--- a/extensions/browser/api/declarative_net_request/rules_monitor_service.h
+++ b/extensions/browser/api/declarative_net_request/rules_monitor_service.h
@@ -46,7 +46,7 @@
 class RulesetMatcher;
 enum class DynamicRuleUpdateAction;
 struct LoadRequestData;
-struct RulesCountPair;
+struct RuleCounts;
 
 // Observes loading and unloading of extensions to load and unload their
 // rulesets for the Declarative Net Request API. Lives on the UI thread. Note: A
@@ -135,9 +135,9 @@
       std::vector<api::declarative_net_request::Rule> rules_to_add,
       ApiCallback callback);
 
-  // Returns the RulesCountPair for the |extension_id| and |ruleset_id| pair.
-  RulesCountPair GetRulesCountPair(const ExtensionId& extension_id,
-                                   RulesetID ruleset_id) const;
+  // Returns the RuleCounts for the |extension_id| and |ruleset_id| pair.
+  RuleCounts GetRuleCounts(const ExtensionId& extension_id,
+                           RulesetID ruleset_id) const;
 
   RulesetManager* ruleset_manager() { return &ruleset_manager_; }
 
diff --git a/extensions/browser/api/declarative_net_request/ruleset_matcher.cc b/extensions/browser/api/declarative_net_request/ruleset_matcher.cc
index 1b85d21..306620c8 100644
--- a/extensions/browser/api/declarative_net_request/ruleset_matcher.cc
+++ b/extensions/browser/api/declarative_net_request/ruleset_matcher.cc
@@ -12,7 +12,7 @@
 #include "base/memory/ptr_util.h"
 #include "extensions/browser/api/declarative_net_request/constants.h"
 #include "extensions/browser/api/declarative_net_request/request_action.h"
-#include "extensions/browser/api/declarative_net_request/rules_count_pair.h"
+#include "extensions/browser/api/declarative_net_request/rule_counts.h"
 #include "extensions/browser/api/declarative_net_request/utils.h"
 
 namespace extensions {
@@ -73,8 +73,8 @@
   return regex_matcher_.GetRulesCount();
 }
 
-RulesCountPair RulesetMatcher::GetRulesCountPair() const {
-  return RulesCountPair(GetRulesCount(), GetRegexRulesCount());
+RuleCounts RulesetMatcher::GetRuleCounts() const {
+  return RuleCounts(GetRulesCount(), GetRegexRulesCount());
 }
 
 void RulesetMatcher::OnRenderFrameCreated(content::RenderFrameHost* host) {
diff --git a/extensions/browser/api/declarative_net_request/ruleset_matcher.h b/extensions/browser/api/declarative_net_request/ruleset_matcher.h
index 5d489054..cb5137f2 100644
--- a/extensions/browser/api/declarative_net_request/ruleset_matcher.h
+++ b/extensions/browser/api/declarative_net_request/ruleset_matcher.h
@@ -26,7 +26,7 @@
 
 namespace declarative_net_request {
 
-struct RulesCountPair;
+struct RuleCounts;
 
 namespace flat {
 struct ExtensionIndexedRuleset;
@@ -61,7 +61,7 @@
   bool IsExtraHeadersMatcher() const;
   size_t GetRulesCount() const;
   size_t GetRegexRulesCount() const;
-  RulesCountPair GetRulesCountPair() const;
+  RuleCounts GetRuleCounts() const;
 
   void OnRenderFrameCreated(content::RenderFrameHost* host);
   void OnRenderFrameDeleted(content::RenderFrameHost* host);
diff --git a/extensions/browser/api/declarative_net_request/test_utils.cc b/extensions/browser/api/declarative_net_request/test_utils.cc
index ebdaae9..dd211d5 100644
--- a/extensions/browser/api/declarative_net_request/test_utils.cc
+++ b/extensions/browser/api/declarative_net_request/test_utils.cc
@@ -17,7 +17,7 @@
 #include "extensions/browser/api/declarative_net_request/composite_matcher.h"
 #include "extensions/browser/api/declarative_net_request/file_backed_ruleset_source.h"
 #include "extensions/browser/api/declarative_net_request/indexed_rule.h"
-#include "extensions/browser/api/declarative_net_request/rules_count_pair.h"
+#include "extensions/browser/api/declarative_net_request/rule_counts.h"
 #include "extensions/browser/api/declarative_net_request/ruleset_matcher.h"
 #include "extensions/browser/api/declarative_net_request/ruleset_source.h"
 #include "extensions/browser/api/web_request/web_request_info.h"
@@ -349,8 +349,8 @@
   return output;
 }
 
-std::ostream& operator<<(std::ostream& output, const RulesCountPair& count) {
-  output << "\nRulesCountPair\n";
+std::ostream& operator<<(std::ostream& output, const RuleCounts& count) {
+  output << "\nRuleCounts\n";
   output << "|rule_count| " << count.rule_count << "\n";
   output << "|regex_rule_count| " << count.regex_rule_count << "\n";
   return output;
diff --git a/extensions/browser/api/declarative_net_request/test_utils.h b/extensions/browser/api/declarative_net_request/test_utils.h
index 4df8b49d..da812a8e 100644
--- a/extensions/browser/api/declarative_net_request/test_utils.h
+++ b/extensions/browser/api/declarative_net_request/test_utils.h
@@ -36,7 +36,7 @@
 
 class FileBackedRulesetSource;
 class RulesetMatcher;
-struct RulesCountPair;
+struct RuleCounts;
 struct TestRule;
 
 // Enum specifying the extension load type. Used for parameterized tests.
@@ -62,7 +62,7 @@
 std::ostream& operator<<(std::ostream& output,
                          const absl::optional<RequestAction>& action);
 std::ostream& operator<<(std::ostream& output, LoadRulesetResult result);
-std::ostream& operator<<(std::ostream& output, const RulesCountPair& count);
+std::ostream& operator<<(std::ostream& output, const RuleCounts& count);
 
 // Returns true if the given extension's indexed static rulesets are all valid.
 // Should be called on a sequence where file IO is allowed.
diff --git a/gpu/command_buffer/service/error_state.cc b/gpu/command_buffer/service/error_state.cc
index 81bb7bc..b4afee2 100644
--- a/gpu/command_buffer/service/error_state.cc
+++ b/gpu/command_buffer/service/error_state.cc
@@ -17,6 +17,17 @@
 
 namespace gpu {
 namespace gles2 {
+namespace {
+GLenum GetErrorHelper() {
+  // Skip calling glGetError if no context is bound - this should only happen
+  // when GL is not used e.g. with Graphite.
+  if (gl::g_current_gl_driver) {
+    gl::GLApi* const api = gl::g_current_gl_context;
+    return api->glGetErrorFn();
+  }
+  return GL_NO_ERROR;
+}
+}  // namespace
 
 class ErrorStateImpl : public ErrorState {
  public:
@@ -109,7 +120,7 @@
 }
 
 GLenum ErrorStateImpl::GetErrorHandleContextLoss() {
-  GLenum error = glGetError();
+  GLenum error = GetErrorHelper();
   if (error == GL_CONTEXT_LOST_KHR) {
     client_->OnContextLostError();
     // Do not expose GL_CONTEXT_LOST_KHR, as the version of the robustness
@@ -206,7 +217,7 @@
     const char* filename, int line, const char* function_name) {
   // Clears and logs all current gl errors.
   GLenum error;
-  while ((error = glGetError()) != GL_NO_ERROR) {
+  while ((error = GetErrorHelper()) != GL_NO_ERROR) {
     if (error != GL_CONTEXT_LOST_KHR && error != GL_OUT_OF_MEMORY) {
       // GL_OUT_OF_MEMORY can legally happen on lost device.
       logger_->LogMessage(
diff --git a/gpu/ipc/host/gpu_disk_cache_unittest.cc b/gpu/ipc/host/gpu_disk_cache_unittest.cc
index f0707b0..b1f345f 100644
--- a/gpu/ipc/host/gpu_disk_cache_unittest.cc
+++ b/gpu/ipc/host/gpu_disk_cache_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "gpu/ipc/host/gpu_disk_cache.h"
 
+#include "base/debug/leak_annotations.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/functional/callback_helpers.h"
@@ -25,7 +26,15 @@
 
 class GpuDiskCacheTest : public testing::Test {
  protected:
-  GpuDiskCacheTest() = default;
+  GpuDiskCacheTest() {
+    // Leak the factory on purpose. In production, the factory is a singleton,
+    // and when a GpuDiskCache object is created, a second reference to it is
+    // added to a globally held Backend object. These instances may leak, by
+    // design, and must have a valid reference to the factory, otherwise raw_ptr
+    // checks will fail. See https://crbug.com/1486674
+    factory_ = new GpuDiskCacheFactory;
+    ANNOTATE_LEAKING_OBJECT_PTR(factory_);
+  }
 
   GpuDiskCacheTest(const GpuDiskCacheTest&) = delete;
   GpuDiskCacheTest& operator=(const GpuDiskCacheTest&) = delete;
@@ -37,10 +46,10 @@
   void InitCache() {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     handle_ =
-        factory_.GetCacheHandle(GpuDiskCacheType::kGlShaders, cache_path());
+        factory_->GetCacheHandle(GpuDiskCacheType::kGlShaders, cache_path());
   }
 
-  GpuDiskCacheFactory* factory() { return &factory_; }
+  GpuDiskCacheFactory* factory() { return factory_.get(); }
 
   void TearDown() override {
     // Run all pending tasks before destroying TaskEnvironment. Otherwise,
@@ -51,7 +60,7 @@
 
   base::test::TaskEnvironment task_environment_;
   base::ScopedTempDir temp_dir_;
-  GpuDiskCacheFactory factory_;
+  raw_ptr<GpuDiskCacheFactory> factory_;
   GpuDiskCacheHandle handle_;
 };
 
diff --git a/infra/config/generated/luci/project.cfg b/infra/config/generated/luci/project.cfg
index 53584bc..05b8cb08 100644
--- a/infra/config/generated/luci/project.cfg
+++ b/infra/config/generated/luci/project.cfg
@@ -7,7 +7,7 @@
 name: "chromium"
 access: "group:all"
 lucicfg {
-  version: "1.39.18"
+  version: "1.39.19"
   package_dir: "../.."
   config_dir: "generated/luci"
   entry_point: "main.star"
diff --git a/infra/config/generated/testing/variants.pyl b/infra/config/generated/testing/variants.pyl
index cc87d404..849417e 100644
--- a/infra/config/generated/testing/variants.pyl
+++ b/infra/config/generated/testing/variants.pyl
@@ -118,16 +118,16 @@
   },
   'LACROS_VERSION_SKEW_STABLE': {
     'identifier': 'Lacros version skew testing ash stable',
-    'description': 'Run with ash-chrome version 116.0.5845.210',
+    'description': 'Run with ash-chrome version 117.0.5938.115',
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome',
     ],
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v116.0.5845.210',
-          'revision': 'version:116.0.5845.210',
+          'location': 'lacros_version_skew_tests_v117.0.5938.115',
+          'revision': 'version:117.0.5938.115',
         },
       ],
     },
diff --git a/infra/config/targets/lacros-version-skew-variants.json b/infra/config/targets/lacros-version-skew-variants.json
index fb684fee..b0af595 100644
--- a/infra/config/targets/lacros-version-skew-variants.json
+++ b/infra/config/targets/lacros-version-skew-variants.json
@@ -49,16 +49,16 @@
   },
   "LACROS_VERSION_SKEW_STABLE": {
     "args": [
-      "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome"
+      "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome"
     ],
-    "description": "Run with ash-chrome version 116.0.5845.210",
+    "description": "Run with ash-chrome version 117.0.5938.115",
     "identifier": "Lacros version skew testing ash stable",
     "swarming": {
       "cipd_packages": [
         {
           "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-          "location": "lacros_version_skew_tests_v116.0.5845.210",
-          "revision": "version:116.0.5845.210"
+          "location": "lacros_version_skew_tests_v117.0.5938.115",
+          "revision": "version:117.0.5938.115"
         }
       ]
     }
diff --git a/internal b/internal
index c62e1f4..66c70f7 160000
--- a/internal
+++ b/internal
@@ -1 +1 @@
-Subproject commit c62e1f4b248dcad36232a1a959455b2bbc9cd7f3
+Subproject commit 66c70f7165712e360b0cd864b15a4875fff95137
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
index 5597cc4..af1926ac 100644
--- a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
@@ -1168,6 +1168,13 @@
 
   [[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config];
 
+  if (![ChromeEarlGrey isIPadIdiom]) {
+    [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft
+                                  error:nil];
+    [[EarlGrey selectElementWithMatcher:chrome_test_util::NTPCollectionView()]
+        performAction:grey_scrollInDirection(kGREYDirectionDown, 100)];
+  }
+
   // Verify Most Visited Tiles module title is visible.
   [[EarlGrey selectElementWithMatcher:
                  grey_accessibilityID(l10n_util::GetNSString(
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift
index 8be9aff..a0027a3 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import Combine
 import SwiftUI
 
 /// A view displaying a list of destinations.
@@ -74,14 +75,14 @@
   /// The destinations for this view.
   @Binding var destinations: [OverflowMenuDestination]
 
-  var extraTopMargin: CGFloat = 0
+  var extraTopMargin: CGFloat
 
   weak var metricsHandler: PopupMenuMetricsHandler?
 
   @ObservedObject var uiConfiguration: OverflowMenuUIConfiguration
 
   // The drag handler to use for drag interactions on this list
-  var dragHandler: DestinationDragHandler?
+  @ObservedObject var dragHandlerContainer: DestinationDragHandlerContainer
 
   /// The namespace for the animation of this view appearing or disappearing.
   let namespace: Namespace.ID
@@ -92,6 +93,21 @@
   /// of the list first.
   @State var listOffset: CGFloat? = nil
 
+  init(
+    destinations: Binding<[OverflowMenuDestination]>, extraTopMargin: CGFloat = 0,
+    metricsHandler: PopupMenuMetricsHandler? = nil,
+    uiConfiguration: OverflowMenuUIConfiguration,
+    dragHandler: DestinationDragHandler? = nil,
+    namespace: Namespace.ID
+  ) {
+    self._destinations = destinations
+    self.extraTopMargin = extraTopMargin
+    self.metricsHandler = metricsHandler
+    self.uiConfiguration = uiConfiguration
+    dragHandlerContainer = DestinationDragHandlerContainer(dragHandler: dragHandler)
+    self.namespace = namespace
+  }
+
   var body: some View {
     GeometryReader { geometry in
       scrollView(in: geometry)
@@ -150,11 +166,11 @@
                 metricsHandler: metricsHandler
               )
               let destinationBeingDragged =
-                dragHandler?.dragOnDestinations ?? false
-                && dragHandler?.currentDrag?.item == destination
+                dragHandlerContainer.dragHandler?.dragOnDestinations ?? false
+                && dragHandlerContainer.dragHandler?.currentDrag?.item == destination
               destinationView
                 .id(destination.destination)
-                .ifLet(dragHandler) { view, dragHandler in
+                .ifLet(dragHandlerContainer.dragHandler) { view, dragHandler in
                   view
                     .opacity(destinationBeingDragged ? 0.01 : 1)
                     .onDrag {
@@ -345,3 +361,28 @@
   /// locations.
   static let editButton = Alignment(horizontal: .editButton, vertical: .editButton)
 }
+
+/// Before iOS 17, it was not possible to directly observe optional objects
+/// e.g.
+/// ```
+/// @ObservedObject var myOptional: Foo?
+/// ```
+/// `DestinationDragHandler` is often optional, so this simple class wraps it
+/// in a container that just re-publishes any changes to the underlying drag
+/// handler.
+/// The `Observable` macro in iOS 17 looks to also solve this issue, and
+/// this should be migrateable once iOS 17 is the minimum version supported.
+class DestinationDragHandlerContainer: ObservableObject {
+  // The underlying drag handler.
+  let dragHandler: DestinationDragHandler?
+
+  var cancellable: AnyCancellable?
+
+  init(dragHandler: DestinationDragHandler?) {
+    self.dragHandler = dragHandler
+
+    cancellable = dragHandler?.objectWillChange.sink { [weak self] in
+      self?.objectWillChange.send()
+    }
+  }
+}
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index 8e83362..9c2faca 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -1627,6 +1627,12 @@
              "UseWindowBoundsForPip",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+// Use SharedImages instead of legacy mailboxes to copy VideoFrames to for
+// pepper video decode.
+BASE_FEATURE(kUseSharedImagesForPepperVideo,
+             "UseSharedImagesForPepperVideo",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
 bool IsChromeWideEchoCancellationEnabled() {
 #if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
   return base::FeatureList::IsEnabled(kChromeWideEchoCancellation);
diff --git a/media/base/media_switches.h b/media/base/media_switches.h
index 5071116..17fcb82 100644
--- a/media/base/media_switches.h
+++ b/media/base/media_switches.h
@@ -472,6 +472,8 @@
 
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseWindowBoundsForPip);
 
+MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseSharedImagesForPepperVideo);
+
 // Based on a |command_line| and the current platform, returns the effective
 // autoplay policy. In other words, it will take into account the default policy
 // if none is specified via the command line and options passed for testing.
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
index 664e57b0..381960eac 100644
--- a/media/base/video_frame.cc
+++ b/media/base/video_frame.cc
@@ -388,7 +388,8 @@
       format != PIXEL_FORMAT_I420 && format != PIXEL_FORMAT_ABGR &&
       format != PIXEL_FORMAT_XBGR && format != PIXEL_FORMAT_XR30 &&
       format != PIXEL_FORMAT_XB30 && format != PIXEL_FORMAT_P016LE &&
-      format != PIXEL_FORMAT_RGBAF16 && format != PIXEL_FORMAT_YV12) {
+      format != PIXEL_FORMAT_RGBAF16 && format != PIXEL_FORMAT_YV12 &&
+      format != PIXEL_FORMAT_BGRA) {
     DLOG(ERROR) << "Unsupported pixel format: "
                 << VideoPixelFormatToString(format);
     return nullptr;
diff --git a/media/filters/hls_codec_detector.cc b/media/filters/hls_codec_detector.cc
index 0da3f813..3de1e29 100644
--- a/media/filters/hls_codec_detector.cc
+++ b/media/filters/hls_codec_detector.cc
@@ -22,11 +22,10 @@
   CHECK(!callback_);
   callback_ = std::move(cb);
   parser_ = nullptr;
-  rendition_host_->ReadStream(
-      std::move(stream),
-      base::BindPostTaskToCurrentDefault(base::BindOnce(
-          &HlsCodecDetector::OnStreamFetched, weak_factory_.GetWeakPtr(),
-          /*container_only=*/true)));
+  rendition_host_->ReadStream(std::move(stream),
+                              base::BindOnce(&HlsCodecDetector::OnStreamFetched,
+                                             weak_factory_.GetWeakPtr(),
+                                             /*container_only=*/true));
 }
 
 void HlsCodecDetector::DetermineContainerAndCodec(
@@ -36,11 +35,10 @@
   CHECK(!callback_);
   callback_ = std::move(cb);
   parser_ = nullptr;
-  rendition_host_->ReadStream(
-      std::move(stream),
-      base::BindPostTaskToCurrentDefault(base::BindOnce(
-          &HlsCodecDetector::OnStreamFetched, weak_factory_.GetWeakPtr(),
-          /*container_only=*/false)));
+  rendition_host_->ReadStream(std::move(stream),
+                              base::BindOnce(&HlsCodecDetector::OnStreamFetched,
+                                             weak_factory_.GetWeakPtr(),
+                                             /*container_only=*/false));
 }
 
 void HlsCodecDetector::OnStreamFetched(
@@ -126,10 +124,10 @@
   // chunk initially anyway, so fetching the whole thing isn't going to be an
   // issue.
   stream->Flush();
-  rendition_host_->ReadStream(std::move(stream),
-                              base::BindPostTaskToCurrentDefault(base::BindOnce(
-                                  &HlsCodecDetector::OnStreamFetched,
-                                  weak_factory_.GetWeakPtr(), container_only)));
+  rendition_host_->ReadStream(
+      std::move(stream),
+      base::BindOnce(&HlsCodecDetector::OnStreamFetched,
+                     weak_factory_.GetWeakPtr(), container_only));
 }
 
 void HlsCodecDetector::DetermineContainer(bool container_only,
diff --git a/media/filters/hls_manifest_demuxer_engine.cc b/media/filters/hls_manifest_demuxer_engine.cc
index 0eb70af..622a724 100644
--- a/media/filters/hls_manifest_demuxer_engine.cc
+++ b/media/filters/hls_manifest_demuxer_engine.cc
@@ -118,7 +118,10 @@
     : data_source_provider_(std::move(dsp)),
       media_task_runner_(std::move(media_task_runner)),
       root_playlist_uri_(std::move(root_playlist_uri)),
-      media_log_(media_log->Clone()) {}
+      media_log_(media_log->Clone()) {
+  // This is always created on the main sequence, but used on the media sequence
+  DETACH_FROM_SEQUENCE(media_sequence_checker_);
+}
 
 HlsManifestDemuxerEngine::PlaylistParseInfo::PlaylistParseInfo(
     GURL uri,
@@ -141,7 +144,7 @@
 
 void HlsManifestDemuxerEngine::Initialize(ManifestDemuxerEngineHost* host,
                                           PipelineStatusCallback status_cb) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
 
   // Initialize the codec detector on the media thread.
   codec_detector_ = std::make_unique<HlsCodecDetector>(media_log_.get(), this);
@@ -157,7 +160,7 @@
 void HlsManifestDemuxerEngine::OnTimeUpdate(base::TimeDelta time,
                                             double playback_rate,
                                             ManifestDemuxer::DelayCallback cb) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   if (renditions_.empty()) {
     std::move(cb).Run(kNoTimestamp);
     return;
@@ -172,7 +175,7 @@
     ManifestDemuxer::DelayCallback cb,
     size_t rendition_index,
     absl::optional<base::TimeDelta> response_time) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   if (rendition_index >= renditions_.size()) {
     // The response time collected at this point _must_ be valid.
     std::move(cb).Run(response_time.value());
@@ -196,7 +199,7 @@
     absl::optional<base::TimeDelta> prior_delay,
     base::OnceCallback<void(absl::optional<base::TimeDelta>)> cb,
     base::TimeDelta delay_time) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   if (prior_delay.value_or(kNoTimestamp) == kNoTimestamp) {
     std::move(cb).Run(delay_time);
     return;
@@ -222,7 +225,7 @@
 }
 
 bool HlsManifestDemuxerEngine::Seek(base::TimeDelta time) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   bool needs_more_data = false;
   for (auto& rendition : renditions_) {
     needs_more_data |= rendition->Seek(time);
@@ -231,28 +234,25 @@
 }
 
 void HlsManifestDemuxerEngine::StartWaitingForSeek() {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
+  AbortPendingReads();
   for (auto& rendition : renditions_) {
     rendition->CancelPendingNetworkRequests();
   }
 }
 
 void HlsManifestDemuxerEngine::AbortPendingReads() {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   // Deleting a stream aborts any pending reads on the underlying data source.
   stream_map_.clear();
 }
 
-bool HlsManifestDemuxerEngine::IsSeekable() {
-  // TODO(crbug/1266991): Check that all renditions are either live or non, and
-  // determine how to surface an error in the case where they report liveness
-  // differently.
-  for (auto& rendition : renditions_) {
-    if (!rendition->GetDuration().has_value()) {
-      return false;
-    }
-  }
-  return true;
+bool HlsManifestDemuxerEngine::IsSeekable() const {
+  // `IsSeekable()` is only ever called from the pipeline after the
+  // initialization step has completed successfully. The initialization step
+  // must set is_seekable_ in order to complete successfully.
+  CHECK(is_seekable_.has_value());
+  return *is_seekable_;
 }
 
 int64_t HlsManifestDemuxerEngine::GetMemoryUsage() const {
@@ -262,7 +262,7 @@
 }
 
 void HlsManifestDemuxerEngine::Stop() {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   AbortPendingReads();
   for (auto& rendition : renditions_) {
     rendition->Stop();
@@ -307,7 +307,7 @@
 }
 
 void HlsManifestDemuxerEngine::Abort(HlsDemuxerStatus status) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   if (!host_) {
     return;
   }
@@ -316,7 +316,7 @@
 }
 
 void HlsManifestDemuxerEngine::Abort(hls::ParseStatus status) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   if (!host_) {
     return;
   }
@@ -325,7 +325,7 @@
 }
 
 void HlsManifestDemuxerEngine::Abort(HlsDataSource::ReadStatus status) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   if (!host_) {
     return;
   }
@@ -336,7 +336,7 @@
 void HlsManifestDemuxerEngine::ReadStream(
     std::unique_ptr<HlsDataSourceStream> stream,
     HlsDataSourceStreamManager::ReadCb cb) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   if (!data_source_provider_) {
     std::move(cb).Run(HlsDataSource::ReadStatus::Codes::kAborted);
     return;
@@ -345,16 +345,15 @@
   auto it = stream_map_.try_emplace(ticket, std::move(stream));
   it.first->second->ReadChunk(
       base::PassKey<HlsManifestDemuxerEngine>(),
-      base::BindPostTaskToCurrentDefault(
-          base::BindOnce(&HlsManifestDemuxerEngine::ExchangeStreamId,
-                         weak_factory_.GetWeakPtr(), ticket, std::move(cb))));
+      base::BindOnce(&HlsManifestDemuxerEngine::ExchangeStreamId,
+                     weak_factory_.GetWeakPtr(), ticket, std::move(cb)));
 }
 
 void HlsManifestDemuxerEngine::ExchangeStreamId(
     HlsDataSourceStream::StreamId ticket,
     HlsDataSourceStreamManager::ReadCb cb,
     HlsDataSource::ReadStatus::Or<size_t> result) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   auto it = stream_map_.find(ticket);
   if (it == stream_map_.end()) {
     std::move(cb).Run(HlsDataSource::ReadStatus::Codes::kAborted);
@@ -372,7 +371,7 @@
 void HlsManifestDemuxerEngine::ReadDataSource(
     HlsDataSourceStreamManager::ReadCb cb,
     std::unique_ptr<HlsDataSource> source) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   if (!source) {
     Abort(HlsDemuxerStatus::Codes::kPlaylistUrlInvalid);
     return;
@@ -384,7 +383,7 @@
 void HlsManifestDemuxerEngine::ReadUntilExhausted(
     HlsDataSourceStreamManager::ReadCb cb,
     HlsDataSourceStreamManager::ReadResult result) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   if (!result.has_value()) {
     std::move(cb).Run(std::move(result));
     return;
@@ -406,7 +405,7 @@
     bool read_chunked,
     absl::optional<hls::types::ByteRange> range,
     HlsDataSourceStreamManager::ReadCb cb) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   if (!data_source_provider_) {
     std::move(cb).Run(HlsDataSource::ReadStatus::Codes::kAborted);
     return;
@@ -428,7 +427,7 @@
     PipelineStatusCallback parse_complete_cb,
     PlaylistParseInfo parse_info,
     HlsDataSourceStreamManager::ReadResult m_stream) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   if (!m_stream.has_value()) {
     return Abort(std::move(m_stream).error().AddHere());
   }
@@ -476,19 +475,24 @@
     base::StringPiece source,
     GURL uri,
     hls::types::DecimalInteger version) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   return hls::MediaPlaylist::Parse(source, uri, version,
                                    multivariant_root_.get());
 }
 
 void HlsManifestDemuxerEngine::AddRenditionForTesting(
     std::unique_ptr<HlsRendition> test_rendition) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
+  bool is_seekable = test_rendition->GetDuration().has_value();
+  CHECK_EQ(is_seekable_.value_or(is_seekable), is_seekable);
+  is_seekable_ = is_seekable;
   renditions_.push_back(std::move(test_rendition));
 }
 
 void HlsManifestDemuxerEngine::OnMultivariantPlaylist(
     PipelineStatusCallback parse_complete_cb,
     scoped_refptr<hls::MultivariantPlaylist> playlist) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   CHECK(!rendition_selector_);
   multivariant_root_ = std::move(playlist);
   rendition_selector_ = std::make_unique<hls::RenditionSelector>(
@@ -554,6 +558,7 @@
     std::vector<PlaylistParseInfo> playlists,
     PipelineStatusCallback cb,
     PipelineStatus exit_on_error) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   if (!exit_on_error.is_ok() || playlists.empty()) {
     // We've either hit the end of the list with a success, or have errored out
     // early. Either way, the status should be forwarded to the cb.
@@ -578,10 +583,10 @@
     PipelineStatusCallback parse_complete_cb,
     PlaylistParseInfo parse_info,
     scoped_refptr<hls::MediaPlaylist> playlist) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   hls::MediaPlaylist* playlist_ptr = playlist.get();
   DetermineStreamContainerAndCodecs(
-      playlist_ptr, parse_info,
+      playlist_ptr,
       base::BindOnce(&HlsManifestDemuxerEngine::OnPlaylistContainerDetermined,
                      weak_factory_.GetWeakPtr(), std::move(parse_complete_cb),
                      std::move(parse_info), std::move(playlist)));
@@ -592,7 +597,7 @@
     PlaylistParseInfo parse_info,
     scoped_refptr<hls::MediaPlaylist> playlist,
     HlsDemuxerStatus::Or<HlsCodecDetector::ContainerAndCodecs> maybe_info) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   if (!maybe_info.has_value()) {
     std::move(parse_complete_cb)
         .Run({DEMUXER_ERROR_COULD_NOT_OPEN, std::move(maybe_info).error()});
@@ -641,48 +646,47 @@
     }
   }
 
+  bool seekable = rendition->GetDuration().has_value();
+  if (is_seekable_.value_or(seekable) != seekable) {
+    std::move(parse_complete_cb).Run(DEMUXER_ERROR_COULD_NOT_PARSE);
+    return;
+  }
+  is_seekable_ = seekable;
   renditions_.push_back(std::move(rendition));
   std::move(parse_complete_cb).Run(OkStatus());
 }
 
 void HlsManifestDemuxerEngine::DetermineStreamContainerAndCodecs(
     hls::MediaPlaylist* playlist,
-    PlaylistParseInfo parse_info,
     HlsDemuxerStatusCb<HlsCodecDetector::ContainerAndCodecs> container_cb) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   const auto& segments = playlist->GetSegments();
   if (segments.empty()) {
     std::move(container_cb).Run(HlsDemuxerStatus::Codes::kUnsupportedContainer);
     return;
   }
 
-  const auto& first_segment_uri = segments[0]->GetUri();
-  data_source_provider_.AsyncCall(&HlsDataSourceProvider::RequestDataSource)
-      .WithArgs(std::move(first_segment_uri), segments[0]->GetByteRange(),
-                base::BindPostTask(
-                    media_task_runner_,
-                    base::BindOnce(&HlsManifestDemuxerEngine::PeekFirstSegment,
-                                   weak_factory_.GetWeakPtr(), parse_info,
-                                   std::move(container_cb))));
+  ReadFromUrl(
+      segments[0]->GetUri(), true, segments[0]->GetByteRange(),
+      base::BindOnce(&HlsManifestDemuxerEngine::PeekFirstSegment,
+                     weak_factory_.GetWeakPtr(), std::move(container_cb)));
 }
 
 void HlsManifestDemuxerEngine::PeekFirstSegment(
-    PlaylistParseInfo parse_info,
     HlsDemuxerStatusCb<HlsCodecDetector::ContainerAndCodecs> cb,
-    std::unique_ptr<HlsDataSource> data_source) {
-  if (!data_source) {
+    HlsDataSourceStreamManager::ReadResult maybe_stream) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
+  if (!maybe_stream.has_value()) {
     std::move(cb).Run(HlsDemuxerStatus::Codes::kInvalidSegmentUri);
     return;
   }
-  codec_detector_->DetermineContainerAndCodec(
-      std::make_unique<HlsDataSourceStream>(std::move(data_source)),
-      std::move(cb));
+  codec_detector_->DetermineContainerAndCodec(std::move(maybe_stream).value(),
+                                              std::move(cb));
 }
-
 void HlsManifestDemuxerEngine::OnChunkDemuxerParseWarning(
     std::string role,
     SourceBufferParseWarning warning) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   MEDIA_LOG(WARNING, media_log_)
       << "ParseWarning (" << role << "): " << static_cast<int>(warning);
 }
@@ -690,7 +694,7 @@
 void HlsManifestDemuxerEngine::OnChunkDemuxerTracksChanged(
     std::string role,
     std::unique_ptr<MediaTracks> tracks) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK_CALLED_ON_VALID_SEQUENCE(media_sequence_checker_);
   MEDIA_LOG(WARNING, media_log_) << "TracksChanged for role: " << role;
 }
 
diff --git a/media/filters/hls_manifest_demuxer_engine.h b/media/filters/hls_manifest_demuxer_engine.h
index 9923241..a3c3779 100644
--- a/media/filters/hls_manifest_demuxer_engine.h
+++ b/media/filters/hls_manifest_demuxer_engine.h
@@ -49,7 +49,7 @@
   bool Seek(base::TimeDelta time) override;
   void StartWaitingForSeek() override;
   void AbortPendingReads() override;
-  bool IsSeekable() override;
+  bool IsSeekable() const override;
   int64_t GetMemoryUsage() const override;
   void Stop() override;
   void ReadFromUrl(GURL uri,
@@ -161,7 +161,6 @@
                        scoped_refptr<hls::MediaPlaylist> playlist);
   void DetermineStreamContainerAndCodecs(
       hls::MediaPlaylist* playlist,
-      PlaylistParseInfo parse_info,
       HlsDemuxerStatusCb<HlsCodecDetector::ContainerAndCodecs> container_cb);
   void OnPlaylistContainerDetermined(
       PipelineStatusCallback parse_complete_cb,
@@ -169,9 +168,8 @@
       scoped_refptr<hls::MediaPlaylist> playlist,
       HlsDemuxerStatus::Or<HlsCodecDetector::ContainerAndCodecs> maybe_info);
   void PeekFirstSegment(
-      PlaylistParseInfo parse_info,
       HlsDemuxerStatusCb<HlsCodecDetector::ContainerAndCodecs> cb,
-      std::unique_ptr<HlsDataSource> data_source);
+      HlsDataSourceStreamManager::ReadResult maybe_stream);
 
   void OnChunkDemuxerParseWarning(std::string role,
                                   SourceBufferParseWarning warning);
@@ -185,31 +183,46 @@
   GURL root_playlist_uri_;
 
   std::unique_ptr<MediaLog> media_log_;
-  raw_ptr<ManifestDemuxerEngineHost> host_ = nullptr;
+  raw_ptr<ManifestDemuxerEngineHost> host_
+      GUARDED_BY_CONTEXT(media_sequence_checker_) = nullptr;
 
   // The codec detector is a reusable way for determining codecs in a media
   // stream.
-  std::unique_ptr<HlsCodecDetector> codec_detector_;
+  std::unique_ptr<HlsCodecDetector> codec_detector_
+      GUARDED_BY_CONTEXT(media_sequence_checker_);
 
   // If the root playlist is multivariant, we need to store it for parsing the
   // dependant media playlists.
-  scoped_refptr<hls::MultivariantPlaylist> multivariant_root_;
-  std::unique_ptr<hls::RenditionSelector> rendition_selector_;
+  scoped_refptr<hls::MultivariantPlaylist> multivariant_root_
+      GUARDED_BY_CONTEXT(media_sequence_checker_);
+  std::unique_ptr<hls::RenditionSelector> rendition_selector_
+      GUARDED_BY_CONTEXT(media_sequence_checker_);
 
   // Multiple renditions are allowed, and have to be synchronized.
-  std::vector<std::unique_ptr<HlsRendition>> renditions_;
+  std::vector<std::unique_ptr<HlsRendition>> renditions_
+      GUARDED_BY_CONTEXT(media_sequence_checker_);
+
+  // When renditions are added, this ensures that they are all of the same
+  // liveness, and allows access to the liveness check later.
+  absl::optional<bool> is_seekable_ = absl::nullopt;
 
   // Preferences for selecting optimal renditions. Storing them allows them
   // to be changed later due to network constraints or user changes.
-  hls::RenditionSelector::VideoPlaybackPreferences video_preferences_ = {
-      absl::nullopt, absl::nullopt};
-  hls::RenditionSelector::AudioPlaybackPreferences audio_preferences_ = {
-      absl::nullopt, absl::nullopt};
+  hls::RenditionSelector::VideoPlaybackPreferences video_preferences_
+      GUARDED_BY_CONTEXT(media_sequence_checker_) = {absl::nullopt,
+                                                     absl::nullopt};
+  hls::RenditionSelector::AudioPlaybackPreferences audio_preferences_
+      GUARDED_BY_CONTEXT(media_sequence_checker_) = {absl::nullopt,
+                                                     absl::nullopt};
 
-  HlsDataSourceStream::StreamId::Generator stream_ticket_generator_;
+  HlsDataSourceStream::StreamId::Generator stream_ticket_generator_
+      GUARDED_BY_CONTEXT(media_sequence_checker_);
   base::flat_map<HlsDataSourceStream::StreamId,
                  std::unique_ptr<HlsDataSourceStream>>
-      stream_map_;
+      stream_map_ GUARDED_BY_CONTEXT(media_sequence_checker_);
+
+  // Ensure that safe member fields are only accessed on the media sequence.
+  SEQUENCE_CHECKER(media_sequence_checker_);
 
   base::WeakPtrFactory<HlsManifestDemuxerEngine> weak_factory_{this};
 };
diff --git a/media/filters/hls_manifest_demuxer_engine_unittest.cc b/media/filters/hls_manifest_demuxer_engine_unittest.cc
index ff0ce70..ec42063d 100644
--- a/media/filters/hls_manifest_demuxer_engine_unittest.cc
+++ b/media/filters/hls_manifest_demuxer_engine_unittest.cc
@@ -35,6 +35,18 @@
     "http://media.example.com/third.ts\n"
     "#EXT-X-ENDLIST\n";
 
+const std::string kSimpleLiveMediaPlaylist =
+    "#EXTM3U\n"
+    "#EXT-X-TARGETDURATION:10\n"
+    "#EXT-X-VERSION:3\n"
+    "#EXT-X-MEDIA-SEQUENCE:18698597\n"
+    "#EXTINF:9.009,\n"
+    "http://media.example.com/first.ts\n"
+    "#EXTINF:9.009,\n"
+    "http://media.example.com/second.ts\n"
+    "#EXTINF:3.003,\n"
+    "http://media.example.com/third.ts\n";
+
 const std::string kSingleInfoMediaPlaylist =
     "#EXTM3U\n"
     "#EXT-X-TARGETDURATION:10\n"
@@ -192,6 +204,7 @@
   EXPECT_CALL(*mock_mdeh_, SetDuration(21.021));
   EXPECT_CALL(*mock_mdeh_, AddRole(base::StringPiece("primary"), "video/mp2t",
                                    "avc1.420000, mp4a.40.05"));
+  EXPECT_CALL(*mock_mdeh_, RemoveRole(base::StringPiece("primary")));
   BindUrlToDataSource<StringHlsDataSource>(
       "http://media.example.com/manifest.m3u8", kSimpleMediaPlaylist);
   BindUrlToDataSource<FileHlsDataSource>("http://media.example.com/first.ts",
@@ -199,6 +212,22 @@
   EXPECT_CALL(*this, MockInitComplete(HasStatusCode(PIPELINE_OK)));
   InitializeEngine();
   task_environment_.RunUntilIdle();
+  ASSERT_TRUE(engine_->IsSeekable());
+}
+
+TEST_F(HlsManifestDemuxerEngineTest, TestSimpleLiveConfigAddsOnePrimaryRole) {
+  EXPECT_CALL(*mock_mdeh_, SetSequenceMode(base::StringPiece("primary"), true));
+  EXPECT_CALL(*mock_mdeh_, AddRole(base::StringPiece("primary"), "video/mp2t",
+                                   "avc1.420000, mp4a.40.05"));
+  EXPECT_CALL(*mock_mdeh_, RemoveRole(base::StringPiece("primary")));
+  BindUrlToDataSource<StringHlsDataSource>(
+      "http://media.example.com/manifest.m3u8", kSimpleLiveMediaPlaylist);
+  BindUrlToDataSource<FileHlsDataSource>("http://media.example.com/first.ts",
+                                         "bear-1280x720-hls.ts");
+  EXPECT_CALL(*this, MockInitComplete(HasStatusCode(PIPELINE_OK)));
+  InitializeEngine();
+  task_environment_.RunUntilIdle();
+  ASSERT_FALSE(engine_->IsSeekable());
 }
 
 TEST_F(HlsManifestDemuxerEngineTest, TestMultivariantPlaylistNoAlternates) {
@@ -262,6 +291,9 @@
 TEST_F(HlsManifestDemuxerEngineTest, TestMultiRenditionCheckState) {
   auto rendition1 = std::make_unique<MockHlsRendition>();
   auto rendition2 = std::make_unique<MockHlsRendition>();
+  EXPECT_CALL(*rendition1, GetDuration()).WillOnce(Return(absl::nullopt));
+  EXPECT_CALL(*rendition2, GetDuration()).WillOnce(Return(absl::nullopt));
+
   auto* rend1 = rendition1.get();
   auto* rend2 = rendition2.get();
   engine_->AddRenditionForTesting(std::move(rendition1));
@@ -367,6 +399,7 @@
   CHECK(read_cb);
 
   auto rendition = std::make_unique<MockHlsRendition>();
+  EXPECT_CALL(*rendition, GetDuration()).WillOnce(Return(absl::nullopt));
   auto* rend = rendition.get();
   engine_->AddRenditionForTesting(std::move(rendition));
 
diff --git a/media/filters/manifest_demuxer.cc b/media/filters/manifest_demuxer.cc
index a95fae50..81fda02 100644
--- a/media/filters/manifest_demuxer.cc
+++ b/media/filters/manifest_demuxer.cc
@@ -65,6 +65,7 @@
 
 ManifestDemuxer::~ManifestDemuxer() {
   DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  impl_->Stop();
   impl_.reset();
   chunk_demuxer_.reset();
 }
diff --git a/media/filters/manifest_demuxer.h b/media/filters/manifest_demuxer.h
index 0353f54..0882fe7 100644
--- a/media/filters/manifest_demuxer.h
+++ b/media/filters/manifest_demuxer.h
@@ -139,7 +139,7 @@
 
     // Returns whether this engine supports seeking. Some live stream content
     // can't be seeked.
-    virtual bool IsSeekable() = 0;
+    virtual bool IsSeekable() const = 0;
 
     // Gets the memory usage of the engine.
     virtual int64_t GetMemoryUsage() const = 0;
diff --git a/media/filters/manifest_demuxer_unittest.cc b/media/filters/manifest_demuxer_unittest.cc
index ef8274b25..ff378b6 100644
--- a/media/filters/manifest_demuxer_unittest.cc
+++ b/media/filters/manifest_demuxer_unittest.cc
@@ -41,7 +41,7 @@
   MOCK_METHOD(bool, Seek, (base::TimeDelta time), (override));
   MOCK_METHOD(void, StartWaitingForSeek, (), (override));
   MOCK_METHOD(void, AbortPendingReads, (), (override));
-  MOCK_METHOD(bool, IsSeekable, (), (override));
+  MOCK_METHOD(bool, IsSeekable, (), (const override));
   MOCK_METHOD(int64_t, GetMemoryUsage, (), (const, override));
   MOCK_METHOD(void, Stop, (), (override));
 };
diff --git a/media/renderers/win/media_foundation_texture_pool.cc b/media/renderers/win/media_foundation_texture_pool.cc
index 34df928..2731210 100644
--- a/media/renderers/win/media_foundation_texture_pool.cc
+++ b/media/renderers/win/media_foundation_texture_pool.cc
@@ -51,7 +51,7 @@
       1,
       1,
       // TODO(crbug.com/1276134): Need to handle higher bit-depths like HDR.
-      DXGI_FORMAT_R8G8B8A8_UNORM,
+      DXGI_FORMAT_B8G8R8A8_UNORM,
       {1, 0},
       D3D11_USAGE_DEFAULT,
       D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
diff --git a/net/third_party/quiche/BUILD.gn b/net/third_party/quiche/BUILD.gn
index e710cdf..2970254 100644
--- a/net/third_party/quiche/BUILD.gn
+++ b/net/third_party/quiche/BUILD.gn
@@ -880,7 +880,6 @@
     "src/quiche/blind_sign_auth/proto/key_services.proto",
     "src/quiche/blind_sign_auth/proto/public_metadata.proto",
     "src/quiche/blind_sign_auth/proto/spend_token_data.proto",
-    "src/quiche/blind_sign_auth/proto/timestamp.proto",
   ]
   cc_generator_options = "lite=true,dllexport_decl=COMPONENT_EXPORT(QUICHE):"
   cc_include = "base/component_export.h"
diff --git a/net/third_party/quiche/src b/net/third_party/quiche/src
index 4c9b668..8c88ebf 160000
--- a/net/third_party/quiche/src
+++ b/net/third_party/quiche/src
@@ -1 +1 @@
-Subproject commit 4c9b668a0bbd6e5a5e0be3423213b20ae54ca0ac
+Subproject commit 8c88ebfbe42f3e19a33b0c5db67c52970549389a
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index a8b8e57..d52cc0ee 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -5096,9 +5096,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5108,8 +5108,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
@@ -5242,9 +5242,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5254,8 +5254,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
@@ -5376,9 +5376,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5388,8 +5388,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json
index 61dce2f..b7d94d05 100644
--- a/testing/buildbot/chromium.coverage.json
+++ b/testing/buildbot/chromium.coverage.json
@@ -25442,9 +25442,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25454,8 +25454,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
@@ -25588,9 +25588,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25600,8 +25600,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
@@ -25722,9 +25722,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25734,8 +25734,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index d5c95f67..8e85a1a 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -43513,9 +43513,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -43524,8 +43524,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
@@ -43659,9 +43659,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -43670,8 +43670,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
@@ -43793,9 +43793,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -43804,8 +43804,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
@@ -45117,9 +45117,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -45128,8 +45128,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
@@ -45263,9 +45263,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -45274,8 +45274,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
@@ -45397,9 +45397,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -45408,8 +45408,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
@@ -46105,9 +46105,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -46116,8 +46116,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index a45baa9..e77dddf 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -16428,12 +16428,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -16443,8 +16443,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
@@ -16594,12 +16594,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -16609,8 +16609,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
@@ -16743,12 +16743,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 116.0.5845.210",
+        "description": "Run with ash-chrome version 117.0.5938.115",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -16758,8 +16758,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v116.0.5845.210",
-              "revision": "version:116.0.5845.210"
+              "location": "lacros_version_skew_tests_v117.0.5938.115",
+              "revision": "version:117.0.5938.115"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index cc87d404..849417e 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -118,16 +118,16 @@
   },
   'LACROS_VERSION_SKEW_STABLE': {
     'identifier': 'Lacros version skew testing ash stable',
-    'description': 'Run with ash-chrome version 116.0.5845.210',
+    'description': 'Run with ash-chrome version 117.0.5938.115',
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5845.210/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v117.0.5938.115/test_ash_chrome',
     ],
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v116.0.5845.210',
-          'revision': 'version:116.0.5845.210',
+          'location': 'lacros_version_skew_tests_v117.0.5938.115',
+          'revision': 'version:117.0.5938.115',
         },
       ],
     },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 0551939e0..102b55a 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -6666,35 +6666,6 @@
             ]
         }
     ],
-    "FirstPartySets": [
-        {
-            "platforms": [
-                "android",
-                "chromeos",
-                "chromeos_lacros",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "EnabledWithoutWait_20230705",
-                    "params": {
-                        "FirstPartySetsNavigationThrottleTimeout": "0s"
-                    },
-                    "enable_features": [
-                        "FirstPartySets",
-                        "PrivacySandboxFirstPartySetsUI",
-                        "StorageAccessAPI",
-                        "StorageAccessAPIForOriginExtension"
-                    ],
-                    "disable_features": [
-                        "WaitForFirstPartySetsInit"
-                    ]
-                }
-            ]
-        }
-    ],
     "FixInputQueueingBug": [
         {
             "platforms": [
diff --git a/third_party/angle b/third_party/angle
index 29d0fe5..c995564 160000
--- a/third_party/angle
+++ b/third_party/angle
@@ -1 +1 @@
-Subproject commit 29d0fe5143aaf475602925483f774f134910beaf
+Subproject commit c9955641bcc2323ea2c92f9ff3d827466ac0a2db
diff --git a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
index 5ca7d69..93ef31d 100644
--- a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
+++ b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
@@ -3610,8 +3610,25 @@
     const ComputedStyle& style,
     const LayoutObject* layout_object,
     bool allow_visited_style) {
+  // Trailing non-initial values should be dropped.
+  // TODO(kschmi): Also handle `<custom-ident>` behavior, where if only
+  // one is specified for columns, rows also apply that value.
+  unsigned last_index = shorthand.length();
+  // Work backwards to determine the final non-initial index. For grid
+  // shorthands, we can drop all trailing `none` and `auto` values.
+  for (; last_index > 1; --last_index) {
+    const CSSValue* value =
+        shorthand.properties()[last_index - 1]->CSSValueFromComputedStyle(
+            style, layout_object, allow_visited_style);
+    if ((!IsA<CSSIdentifierValue>(value) ||
+         (To<CSSIdentifierValue>(value)->GetValueID() != CSSValueID::kNone &&
+          To<CSSIdentifierValue>(value)->GetValueID() != CSSValueID::kAuto))) {
+      break;
+    }
+  }
+
   CSSValueList* list = CSSValueList::CreateSlashSeparated();
-  for (unsigned i = 0; i < shorthand.length(); ++i) {
+  for (unsigned i = 0; i < last_index; ++i) {
     const CSSValue* value =
         shorthand.properties()[i]->CSSValueFromComputedStyle(
             style, layout_object, allow_visited_style);
diff --git a/third_party/blink/renderer/core/css/style_property_serializer.cc b/third_party/blink/renderer/core/css/style_property_serializer.cc
index d26c217..2cba9232 100644
--- a/third_party/blink/renderer/core/css/style_property_serializer.cc
+++ b/third_party/blink/renderer/core/css/style_property_serializer.cc
@@ -578,7 +578,7 @@
     case CSSPropertyID::kGridRow:
       return GetShorthandValue(gridRowShorthand(), " / ");
     case CSSPropertyID::kGridArea:
-      return GetShorthandValue(gridAreaShorthand(), " / ");
+      return GetShorthandValueForGridArea(gridAreaShorthand());
     case CSSPropertyID::kGap:
       return Get2Values(gapShorthand());
     case CSSPropertyID::kInset:
@@ -2024,6 +2024,36 @@
   return result.ReleaseString();
 }
 
+String StylePropertySerializer::GetShorthandValueForGridArea(
+    const StylePropertyShorthand& shorthand) const {
+  const String separator = " / ";
+  StringBuilder result;
+
+  unsigned last_index = shorthand.length();
+  // Work backwards to determine the final non-initial index. For `grid-area`
+  // the initial value is `auto`.
+  for (; last_index > 1; --last_index) {
+    const CSSValue* value = property_set_.GetPropertyCSSValue(
+        *shorthand.properties()[last_index - 1]);
+    if ((!IsA<CSSIdentifierValue>(value) ||
+         (To<CSSIdentifierValue>(value)->GetValueID() != CSSValueID::kAuto))) {
+      break;
+    }
+  }
+
+  for (size_t i = 0; i < last_index; ++i) {
+    const CSSValue* value =
+        property_set_.GetPropertyCSSValue(*shorthand.properties()[i]);
+    String value_text = value->CssText();
+
+    if (!result.empty()) {
+      result.Append(separator);
+    }
+    result.Append(value_text);
+  }
+  return result.ReleaseString();
+}
+
 String StylePropertySerializer::GetShorthandValueForGridTemplate(
     const StylePropertyShorthand& shorthand) const {
   const CSSValue* template_row_values =
diff --git a/third_party/blink/renderer/core/css/style_property_serializer.h b/third_party/blink/renderer/core/css/style_property_serializer.h
index 0be2ea4..2ad438b2 100644
--- a/third_party/blink/renderer/core/css/style_property_serializer.h
+++ b/third_party/blink/renderer/core/css/style_property_serializer.h
@@ -67,6 +67,7 @@
   String GetShorthandValueForDoubleBarCombinator(
       const StylePropertyShorthand&) const;
   String GetShorthandValueForGrid(const StylePropertyShorthand&) const;
+  String GetShorthandValueForGridArea(const StylePropertyShorthand&) const;
   String GetShorthandValueForGridTemplate(const StylePropertyShorthand&) const;
   String ContainerValue() const;
   String TimelineValue(const StylePropertyShorthand&) const;
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index 4b4273e..974f349 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -3306,9 +3306,10 @@
 
   const auto& first_page = To<NGPhysicalBoxFragment>(
       *layout_view->GetPhysicalFragment(0)->Children()[0]);
-  if (const AtomicString& page_name = first_page.PageName()) {
+  const AtomicString& first_page_name = first_page.PageName();
+  if (first_page_name) {
     PhysicalSize new_size =
-        layout_view->PageAreaSize(/* page_index */ 0u, page_name);
+        layout_view->PageAreaSize(/* page_index */ 0u, first_page_name);
     if (new_size != initial_containing_block_size) {
       // If the first page was named (this isn't something we can detect without
       // laying out first), and the size of the first page is different from
@@ -3359,12 +3360,12 @@
     // Re-layout and apply the same scale factor to all pages. PageScaleFactor()
     // has already been set to honor any scale factor from print settings. That
     // has to be included as well.
-    //
-    // Note that we deliberately don't set a new initial containing block size
-    // here. But should we? EdgeHTML does it. Gecko doesn't. WebKit is buggy
-    // (uses the initial block based on the browser frame size).
     layout_view->SetPageScaleFactor(layout_view->PageScaleFactor() *
                                     overall_scale_factor);
+    PhysicalSize new_size =
+        layout_view->PageAreaSize(/* page_index */ 0u, first_page_name);
+    layout_view->SetInitialContainingBlockSizeForPagination(new_size);
+    frame_->GetDocument()->LayoutViewportWasResized();
     layout_view->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
         layout_invalidation_reason::kPrintingChanged);
     frame_->GetDocument()->UpdateStyleAndLayout(
diff --git a/third_party/blink/renderer/core/html/forms/date_time_field_element.cc b/third_party/blink/renderer/core/html/forms/date_time_field_element.cc
index d81cf84..c760af3c 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_field_element.cc
+++ b/third_party/blink/renderer/core/html/forms/date_time_field_element.cc
@@ -27,6 +27,7 @@
 
 #include "third_party/blink/renderer/core/css/style_change_reason.h"
 #include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/node_computed_style.h"
 #include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/editing/frame_selection.h"
 #include "third_party/blink/renderer/core/editing/position.h"
@@ -81,8 +82,10 @@
     return;
 
   const String& key = keyboard_event.key();
+  bool is_horizontal = GetComputedStyle()->IsHorizontalWritingMode();
 
-  if (key == "ArrowLeft") {
+  if ((is_horizontal && key == "ArrowLeft") ||
+      (!is_horizontal && key == "ArrowUp")) {
     if (!field_owner_)
       return;
     // FIXME: We'd like to use FocusController::advanceFocus(FocusDirectionLeft,
@@ -92,7 +95,8 @@
     return;
   }
 
-  if (key == "ArrowRight") {
+  if ((is_horizontal && key == "ArrowRight") ||
+      (!is_horizontal && key == "ArrowDown")) {
     if (!field_owner_)
       return;
     // FIXME: We'd like to use
@@ -106,7 +110,8 @@
   if (IsFieldOwnerReadOnly())
     return;
 
-  if (key == "ArrowDown") {
+  if ((is_horizontal && key == "ArrowDown") ||
+      (!is_horizontal && key == "ArrowLeft")) {
     if (keyboard_event.getModifierState("Alt"))
       return;
     keyboard_event.SetDefaultHandled();
@@ -114,7 +119,8 @@
     return;
   }
 
-  if (key == "ArrowUp") {
+  if ((is_horizontal && key == "ArrowUp") ||
+      (!is_horizontal && key == "ArrowRight")) {
     keyboard_event.SetDefaultHandled();
     StepUp();
     return;
diff --git a/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc b/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc
index 5701027..f8bdc87e5 100644
--- a/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc
+++ b/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc
@@ -28,7 +28,9 @@
   style_builder.SetFlexShrink(1);
   // min-width: 0; is needed for correct shrinking.
   style_builder.SetMinWidth(Length::Fixed(0));
-  style_builder.SetHasLineIfEmpty(true);
+  if (parent_style.ApplyControlFixedSize()) {
+    style_builder.SetHasLineIfEmpty(true);
+  }
   style_builder.SetOverflowX(EOverflow::kHidden);
   style_builder.SetOverflowY(EOverflow::kHidden);
   style_builder.SetShouldIgnoreOverflowPropertyForInlineBlockBaseline();
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 0cfcb15..e076c8e 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -1370,7 +1370,8 @@
   const bool apply_fixed_size = StyleRef().ApplyControlFixedSize();
   const auto* select = DynamicTo<HTMLSelectElement>(element);
   if (UNLIKELY(select && select->UsesMenuList())) {
-    return MenuListIntrinsicInlineSize(*select, *this);
+    return apply_fixed_size ? MenuListIntrinsicInlineSize(*select, *this)
+                            : kIndefiniteSize;
   }
   const auto* input = DynamicTo<HTMLInputElement>(element);
   if (UNLIKELY(input)) {
@@ -1409,21 +1410,6 @@
   // get here.
   DCHECK(!HasOverrideIntrinsicContentLogicalHeight());
 
-  const bool apply_fixed_size = StyleRef().ApplyControlFixedSize();
-  if (const auto* select = DynamicTo<HTMLSelectElement>(GetNode())) {
-    if (select->UsesMenuList())
-      return MenuListIntrinsicBlockSize(*select, *this);
-    return ListBoxItemBlockSize(*select, *this) * select->ListBoxSize() -
-           ComputeLogicalScrollbars().BlockSum();
-  }
-  if (IsTextField() && apply_fixed_size) {
-    return TextFieldIntrinsicBlockSize(*To<HTMLInputElement>(GetNode()), *this);
-  }
-  if (IsTextArea() && apply_fixed_size) {
-    return TextAreaIntrinsicBlockSize(*To<HTMLTextAreaElement>(GetNode()),
-                                      *this);
-  }
-
   auto effective_appearance = StyleRef().EffectiveAppearance();
   if (effective_appearance == kCheckboxPart) {
     return ThemePartIntrinsicSize(*this, WebThemeEngine::kPartCheckbox)
@@ -1433,6 +1419,23 @@
     return ThemePartIntrinsicSize(*this, WebThemeEngine::kPartRadio).block_size;
   }
 
+  if (!StyleRef().ApplyControlFixedSize()) {
+    return kIndefiniteSize;
+  }
+  if (const auto* select = DynamicTo<HTMLSelectElement>(GetNode())) {
+    if (select->UsesMenuList())
+      return MenuListIntrinsicBlockSize(*select, *this);
+    return ListBoxItemBlockSize(*select, *this) * select->ListBoxSize() -
+           ComputeLogicalScrollbars().BlockSum();
+  }
+  if (IsTextField()) {
+    return TextFieldIntrinsicBlockSize(*To<HTMLInputElement>(GetNode()), *this);
+  }
+  if (IsTextArea()) {
+    return TextAreaIntrinsicBlockSize(*To<HTMLTextAreaElement>(GetNode()),
+                                      *this);
+  }
+
   return kIndefiniteSize;
 }
 
diff --git a/third_party/blink/renderer/core/layout/layout_multi_column_set.cc b/third_party/blink/renderer/core/layout/layout_multi_column_set.cc
index 6686e7fe..0d0180d 100644
--- a/third_party/blink/renderer/core/layout/layout_multi_column_set.cc
+++ b/third_party/blink/renderer/core/layout/layout_multi_column_set.cc
@@ -358,11 +358,6 @@
   SetHasBoxDecorationBackground(true);
 }
 
-void LayoutMultiColumnSet::UpdateLayout() {
-  NOT_DESTROYED();
-  NOTREACHED_NORETURN();
-}
-
 LayoutUnit LayoutMultiColumnSet::ColumnGap() const {
   NOT_DESTROYED();
   LayoutBlockFlow* parent_block = MultiColumnBlockFlow();
diff --git a/third_party/blink/renderer/core/layout/layout_multi_column_set.h b/third_party/blink/renderer/core/layout/layout_multi_column_set.h
index 7156061..16501000 100644
--- a/third_party/blink/renderer/core/layout/layout_multi_column_set.h
+++ b/third_party/blink/renderer/core/layout/layout_multi_column_set.h
@@ -200,7 +200,6 @@
   void EndFlow(LayoutUnit offset_in_flow_thread);
 
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
-  void UpdateLayout() override;
 
   void AttachToFlowThread();
   void DetachFromFlowThread();
diff --git a/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.cc b/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.cc
index 429e061..df4bdcc 100644
--- a/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.cc
+++ b/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.cc
@@ -102,37 +102,11 @@
   LayoutBox::WillBeRemovedFromTree();
 }
 
-void LayoutMultiColumnSpannerPlaceholder::RecalcVisualOverflow() {
-  NOT_DESTROYED();
-  LayoutBox::RecalcVisualOverflow();
-  ClearVisualOverflow();
-  AddContentsVisualOverflow(
-      layout_object_in_flow_thread_->VisualOverflowRect());
-}
-
 void LayoutMultiColumnSpannerPlaceholder::UpdateLayout() {
   NOT_DESTROYED();
   NOTREACHED_NORETURN();
 }
 
-void LayoutMultiColumnSpannerPlaceholder::Paint(
-    const PaintInfo& paint_info) const {
-  NOT_DESTROYED();
-  if (!layout_object_in_flow_thread_->HasSelfPaintingLayer())
-    layout_object_in_flow_thread_->Paint(paint_info);
-}
-
-bool LayoutMultiColumnSpannerPlaceholder::NodeAtPoint(
-    HitTestResult& result,
-    const HitTestLocation& hit_test_location,
-    const PhysicalOffset& accumulated_offset,
-    HitTestPhase phase) {
-  NOT_DESTROYED();
-  return !layout_object_in_flow_thread_->HasSelfPaintingLayer() &&
-         layout_object_in_flow_thread_->NodeAtPoint(result, hit_test_location,
-                                                    accumulated_offset, phase);
-}
-
 LayoutPoint LayoutMultiColumnSpannerPlaceholder::LocationInternal() const {
   NOT_DESTROYED();
   if (RuntimeEnabledFeatures::LayoutNGNoCopyBackEnabled()) {
diff --git a/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h b/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h
index 03f8670c..2b2dfd9 100644
--- a/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h
+++ b/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h
@@ -72,13 +72,7 @@
  protected:
   void InsertedIntoTree() override;
   void WillBeRemovedFromTree() override;
-  void RecalcVisualOverflow() override;
   void UpdateLayout() override;
-  void Paint(const PaintInfo&) const override;
-  bool NodeAtPoint(HitTestResult&,
-                   const HitTestLocation&,
-                   const PhysicalOffset& accumulated_offset,
-                   HitTestPhase) override;
 
  private:
   LayoutPoint LocationInternal() const override;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
index 0b29b99..2d8a109 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -294,8 +294,9 @@
   if (block_node.IsTextControl() && apply_form_sizing) {
     return inline_size;
   }
-  if (IsA<HTMLSelectElement>(node))
+  if (IsA<HTMLSelectElement>(node) && apply_form_sizing) {
     return inline_size;
+  }
   if (const auto* input_element = DynamicTo<HTMLInputElement>(node)) {
     const AtomicString& type = input_element->type();
     if (type == input_type_names::kFile)
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_encoder.cc b/third_party/blink/renderer/modules/webcodecs/audio_encoder.cc
index a4fd981..fec84819 100644
--- a/third_party/blink/renderer/modules/webcodecs/audio_encoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/audio_encoder.cc
@@ -418,9 +418,19 @@
 
   request->StartTracing();
 
+  String js_error_message;
+  if (!VerifyCodecSupport(active_config_, &js_error_message)) {
+    blocking_request_in_progress_ = request;
+    QueueHandleError(MakeGarbageCollected<DOMException>(
+        DOMExceptionCode::kNotSupportedError, js_error_message));
+    request->EndTracing();
+    return;
+  }
+
   media_encoder_ = CreateMediaAudioEncoder(*active_config_);
   if (!media_encoder_) {
-    HandleError(logger_->MakeOperationError(
+    blocking_request_in_progress_ = request;
+    QueueHandleError(logger_->MakeOperationError(
         "Encoder creation error.",
         media::EncoderStatus(
             media::EncoderStatus::Codes::kEncoderInitializationError,
@@ -502,16 +512,11 @@
   if (data->channel_count() != active_config_->options.channels ||
       data->sample_rate() != active_config_->options.sample_rate) {
     // Per spec we must queue a task for error handling.
-    callback_runner_->PostTask(
-        FROM_HERE,
-        WTF::BindOnce(
-            &AudioEncoder::HandleError, WrapWeakPersistent(this),
-            WrapPersistent(logger_->MakeEncodingError(
-                "Input audio buffer is incompatible with codec parameters",
-                media::EncoderStatus(
-                    media::EncoderStatus::Codes::kEncoderFailedEncode)
-                    .WithData("channels", data->channel_count())
-                    .WithData("sampleRate", data->sample_rate())))));
+    QueueHandleError(logger_->MakeEncodingError(
+        "Input audio buffer is incompatible with codec parameters",
+        media::EncoderStatus(media::EncoderStatus::Codes::kEncoderFailedEncode)
+            .WithData("channels", data->channel_count())
+            .WithData("sampleRate", data->sample_rate())));
 
     request->EndTracing();
 
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
index 9eb2dab..4375d34 100644
--- a/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
+++ b/third_party/blink/renderer/modules/webcodecs/decoder_template.cc
@@ -143,11 +143,6 @@
 
   absl::optional<MediaConfigType> media_config =
       MakeMediaConfig(*config, &js_error_message);
-  if (!media_config) {
-    Shutdown(MakeGarbageCollected<DOMException>(
-        DOMExceptionCode::kNotSupportedError, js_error_message));
-    return;
-  }
 
   MarkCodecActive();
 
@@ -156,7 +151,11 @@
 
   Request* request = MakeGarbageCollected<Request>();
   request->type = Request::Type::kConfigure;
-  request->media_config = std::make_unique<MediaConfigType>(*media_config);
+  if (media_config.has_value()) {
+    request->media_config = std::make_unique<MediaConfigType>(*media_config);
+  } else {
+    request->js_error_message = js_error_message;
+  }
   request->reset_generation = reset_generation_;
   request->hw_pref = GetHardwarePreference(*config);
   request->low_delay = GetLowDelayPreference(*config);
@@ -293,7 +292,6 @@
   DCHECK(!IsClosed());
   DCHECK(!pending_request_);
   DCHECK_EQ(request->type, Request::Type::kConfigure);
-  DCHECK(request->media_config);
 
   if (decoder() &&
       pending_decodes_.size() + 1 >
@@ -307,6 +305,17 @@
   pending_request_ = request;
   pending_request_->StartTracing();
 
+  if (!request->media_config) {
+    main_thread_task_runner_->PostTask(
+        FROM_HERE,
+        WTF::BindOnce(&DecoderTemplate<Traits>::Shutdown,
+                      WrapWeakPersistent(this),
+                      WrapPersistent(MakeGarbageCollected<DOMException>(
+                          DOMExceptionCode::kNotSupportedError,
+                          request->js_error_message))));
+    return false;
+  }
+
   if (gpu_factories_.has_value()) {
     ContinueConfigureWithGpuFactories(request, gpu_factories_.value());
   } else if (Traits::kNeedsGpuFactories) {
@@ -505,7 +514,7 @@
                     DOMExceptionCode::kAbortError, "Aborted due to close()"));
     }
 
-    pending_request_.Release()->EndTracing(/*shutting_down*/ true);
+    pending_request_.Release()->EndTracing(/*shutting_down=*/true);
   }
 
   // Abort all upcoming work.
@@ -544,7 +553,7 @@
     // OnResetDone() will never execute, since we are now in a kClosed state,
     // and |decoder_| has been reset.
     DCHECK_EQ(pending_request_->type, Request::Type::kReset);
-    pending_request_.Release()->EndTracing(/*shutting_down*/ true);
+    pending_request_.Release()->EndTracing(/*shutting_down=*/true);
   }
 
   bool trace_enabled = false;
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template.h b/third_party/blink/renderer/modules/webcodecs/decoder_template.h
index 202d349..021c504 100644
--- a/third_party/blink/renderer/modules/webcodecs/decoder_template.h
+++ b/third_party/blink/renderer/modules/webcodecs/decoder_template.h
@@ -145,10 +145,12 @@
     Type type;
 
     // For kConfigure Requests. Prefer absl::optional<> to ensure values are
-    // only accessed on the proper request type.
+    // only accessed on the proper request type. If `media_config` is null then
+    // `js_error_message` will have details on why the config isn't supported.
     std::unique_ptr<MediaConfigType> media_config;
     absl::optional<HardwarePreference> hw_pref;
     absl::optional<bool> low_delay;
+    String js_error_message;
 
     // For kDecode Requests.
     scoped_refptr<media::DecoderBuffer> decoder_buffer;
diff --git a/third_party/blink/renderer/modules/webcodecs/encoder_base.cc b/third_party/blink/renderer/modules/webcodecs/encoder_base.cc
index 29d2a457..d7cb270 100644
--- a/third_party/blink/renderer/modules/webcodecs/encoder_base.cc
+++ b/third_party/blink/renderer/modules/webcodecs/encoder_base.cc
@@ -109,13 +109,6 @@
     return;
   }
 
-  String js_error_message;
-  if (!VerifyCodecSupport(parsed_config, &js_error_message)) {
-    HandleError(MakeGarbageCollected<DOMException>(
-        DOMExceptionCode::kNotSupportedError, js_error_message));
-    return;
-  }
-
   MarkCodecActive();
 
   Request* request = MakeGarbageCollected<Request>();
@@ -263,6 +256,13 @@
 }
 
 template <typename Traits>
+void EncoderBase<Traits>::QueueHandleError(DOMException* ex) {
+  callback_runner_->PostTask(
+      FROM_HERE, WTF::BindOnce(&EncoderBase<Traits>::HandleError,
+                               WrapWeakPersistent(this), WrapPersistent(ex)));
+}
+
+template <typename Traits>
 void EncoderBase<Traits>::HandleError(DOMException* ex) {
   if (state_.AsEnum() == V8CodecState::Enum::kClosed)
     return;
diff --git a/third_party/blink/renderer/modules/webcodecs/encoder_base.h b/third_party/blink/renderer/modules/webcodecs/encoder_base.h
index 90c9e59..1563399 100644
--- a/third_party/blink/renderer/modules/webcodecs/encoder_base.h
+++ b/third_party/blink/renderer/modules/webcodecs/encoder_base.h
@@ -121,6 +121,7 @@
 #endif
   };
 
+  void QueueHandleError(DOMException* ex);
   virtual void HandleError(DOMException* ex);
   virtual void EnqueueRequest(Request* request);
   virtual void ProcessRequests();
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
index 9323e556..f5f86d7e 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -1120,6 +1120,14 @@
 
   blocking_request_in_progress_ = request;
 
+  String js_error_message;
+  if (!VerifyCodecSupport(active_config_, &js_error_message)) {
+    QueueHandleError(MakeGarbageCollected<DOMException>(
+        DOMExceptionCode::kNotSupportedError, js_error_message));
+    request->EndTracing();
+    return;
+  }
+
   if (active_config_->hw_pref == HardwarePreference::kPreferSoftware &&
       !MayHaveOSSoftwareEncoder(active_config_->profile)) {
     ContinueConfigureWithGpuFactories(request, nullptr);
diff --git a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc
index c021670..42ecb8d1 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc
@@ -25,7 +25,7 @@
 
 // Snap |bounds| if within floating-point numeric limits of an integral rect.
 void PreserveNearIntegralBounds(gfx::RectF& bounds) {
-  constexpr float kTolerance = 1e-4f;
+  constexpr float kTolerance = 1e-3f;
   if (std::abs(std::round(bounds.x()) - bounds.x()) <= kTolerance &&
       std::abs(std::round(bounds.y()) - bounds.y()) <= kTolerance &&
       std::abs(std::round(bounds.right()) - bounds.right()) <= kTolerance &&
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests
index 4137ed4..9aa55dd 100644
--- a/third_party/blink/web_tests/SlowTests
+++ b/third_party/blink/web_tests/SlowTests
@@ -20,11 +20,6 @@
 crbug.com/24182 [ Mac11 Release ] storage/indexeddb/objectstore-cursor.html [ Slow ]
 crbug.com/24182 [ Mac12 ] storage/indexeddb/objectstore-cursor.html [ Slow ]
 crbug.com/24182 [ Release Win ] storage/indexeddb/objectstore-cursor.html [ Slow ]
-crbug.com/24182 [ Linux ] storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Slow ]
-crbug.com/24182 [ Mac10.15 Release ] storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Slow ]
-crbug.com/24182 [ Mac11 Release ] storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Slow ]
-crbug.com/24182 [ Mac12 ] storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Slow ]
-crbug.com/24182 [ Release Win ] storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Slow ]
 crbug.com/24182 editing/selection/modify_move/move-by-word-visually-mac.html [ Slow ]
 crbug.com/24182 compositing/culling/filter-occlusion-blur-large.html [ Slow ]
 crbug.com/24182 [ Linux ] editing/selection/caret-at-bidi-boundary.html [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 87a8c6d..0484594f 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3529,10 +3529,10 @@
 crbug.com/1463891 external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-colon-001.html [ Failure ]
 crbug.com/1463891 external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-dot-001.html [ Failure ]
 crbug.com/1463891 external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-chws-001.html [ Failure ]
-crbug.com/1463891 virtual/css-text-autospace/external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-001.html [ Pass ]
-crbug.com/1463891 virtual/css-text-autospace/external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-colon-001.html [ Pass ]
-crbug.com/1463891 virtual/css-text-autospace/external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-dot-001.html [ Pass ]
-crbug.com/1463891 virtual/css-text-autospace/external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-chws-001.html [ Pass ]
+crbug.com/1463891 virtual/css-text-spacing-trim/external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-001.html [ Pass ]
+crbug.com/1463891 virtual/css-text-spacing-trim/external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-colon-001.html [ Pass ]
+crbug.com/1463891 virtual/css-text-spacing-trim/external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-dot-001.html [ Pass ]
+crbug.com/1463891 virtual/css-text-spacing-trim/external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-chws-001.html [ Pass ]
 
 # Implement text-decoration correctly for vertical text
 crbug.com/1133806 external/wpt/css/css-text-decor/text-decoration-thickness-vertical-002.html [ Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index 95c8806..dc6460d 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -893,7 +893,6 @@
       "external/wpt/css/css-text/parsing/text-autospace-computed.html",
       "external/wpt/css/css-text/parsing/text-autospace-valid.html",
       "external/wpt/css/css-text/text-autospace/",
-      "external/wpt/css/css-text/text-spacing-trim/",
       "external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-002.html",
       "external/wpt/web-animations/animation-model/animation-types/addition-per-property-002.html",
       "external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-002.html",
@@ -903,7 +902,7 @@
       "virtual/text-antialias/justify-ideograph-leading-expansion.html"
     ],
     "args": [
-      "--enable-blink-features=CSSTextAutoSpace,CSSTextSpacingTrim",
+      "--enable-blink-features=CSSTextAutoSpace",
       "--disable-threaded-compositing", "--disable-threaded-animation"],
     "expires": "Dec 1, 2023"
   },
@@ -937,6 +936,23 @@
     "expires": "Dec 1, 2023"
   },
   {
+    "prefix": "css-text-spacing-trim",
+    "owners": [
+      "kojii@chromium.org",
+      "lingqi@chromium.org"
+    ],
+    "platforms": [
+      "Linux"
+    ],
+    "bases": [
+      "external/wpt/css/css-text/text-spacing-trim/"
+    ],
+    "args": [
+      "--enable-blink-features=CSSTextAutoSpace,CSSTextSpacingTrim",
+      "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "expires": "Apr 1, 2024"
+  },
+  {
     "prefix": "import-maps-disabled",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/import-maps/not-as-classic-script.html"],
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties-expected.txt
index b40da759..84d802c 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 140 tests; 121 PASS, 19 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 140 tests; 131 PASS, 9 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS display: grid
 PASS display: inline-grid
 PASS grid-template-columns
@@ -32,13 +32,13 @@
 PASS grid-template-areas.<string>+
 PASS grid-template-areas.reset
 PASS grid-template
-FAIL grid-template.initial assert_equals: initial value of grid-template should be 50px 50px 50px / 150px expected "50px 50px 50px / 150px" but got "50px 50px 50px / 150px / none"
-FAIL grid-template.none assert_equals: none expected "50px 50px 50px / 150px" but got "50px 50px 50px / 150px / none"
-FAIL grid-template.<grid-template-rows> / <grid-template-columns> assert_equals: <grid-template-rows> / <grid-template-columns> expected "100px 100px / 200px 200px" but got "100px 100px / 200px 200px / none"
-FAIL grid-template.<line-names> assert_equals: <line-names> expected "[a] auto [b] auto [c] / [d] auto [e] auto [f]" but got "[a] 50px [b] 50px [c] / [d] 150px [e] 100px [f] / none"
+PASS grid-template.initial
+PASS grid-template.none
+PASS grid-template.<grid-template-rows> / <grid-template-columns>
+FAIL grid-template.<line-names> assert_equals: <line-names> expected "[a] auto [b] auto [c] / [d] auto [e] auto [f]" but got "[a] 50px [b] 50px [c] / [d] 150px [e] 100px [f]"
 FAIL grid-template.<string>+ assert_equals: <string>+ expected "\"a b\" \"a b\"" but got "50px 50px / 150px 100px / \"a b\" \"a b\""
 FAIL grid-template.<string><track-size>+ assert_equals: <string><track-size>+ expected "100px / \"a b\" 50px" but got "\"a b\" \"a b\""
-FAIL grid-template.reset assert_equals: reset expected "50px 50px 50px / 150px" but got "50px 50px 50px / 150px / none"
+PASS grid-template.reset
 PASS grid-auto-columns
 PASS grid-auto-columns.initial
 PASS grid-auto-columns.<track-size>.auto
@@ -108,7 +108,7 @@
 PASS grid-column-end.span <integer> <custom-ident>
 PASS grid-column-end.reset
 PASS grid-column
-FAIL grid-column.initial assert_equals: initial value of grid-column should be auto expected "auto" but got "auto / auto"
+PASS grid-column.initial
 FAIL grid-column.auto assert_equals: auto expected "auto" but got "auto / auto"
 PASS grid-column.<custom-ident>
 FAIL grid-column.<integer> start assert_equals: <integer> start expected "1" but got "1 / auto"
@@ -119,7 +119,7 @@
 PASS grid-column.span <integer> <custom-ident>
 FAIL grid-column.reset assert_equals: reset expected "auto" but got "auto / auto"
 PASS grid-row
-FAIL grid-row.initial assert_equals: initial value of grid-row should be auto expected "auto" but got "auto / auto"
+PASS grid-row.initial
 FAIL grid-row.auto assert_equals: auto expected "auto" but got "auto / auto"
 PASS grid-row.<custom-ident>
 FAIL grid-row.<integer> start assert_equals: <integer> start expected "1" but got "1 / auto"
@@ -130,15 +130,15 @@
 PASS grid-row.span <integer> <custom-ident>
 FAIL grid-row.reset assert_equals: reset expected "auto" but got "auto / auto"
 PASS grid-area
-FAIL grid-area.initial assert_equals: initial value of grid-area should be auto expected "auto" but got "auto / auto / auto / auto"
-FAIL grid-area.auto assert_equals: auto expected "auto" but got "auto / auto / auto / auto"
+PASS grid-area.initial
+PASS grid-area.auto
 PASS grid-area.<custom-ident>
-FAIL grid-area.<integer> start assert_equals: <integer> start expected "1 / 2" but got "1 / 2 / auto / auto"
+PASS grid-area.<integer> start
 PASS grid-area.<integer>
 PASS grid-area.<integer> <ident>
 PASS grid-area.span <integer>
 PASS grid-area.span <custom-ident>
 PASS grid-area.span <integer> <custom-ident>
-FAIL grid-area.reset assert_equals: reset expected "auto" but got "auto / auto / auto / auto"
+PASS grid-area.reset
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties.html.ini b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties.html.ini
index 64256d5..ee0fc3e 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties.html.ini
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-layout-properties.html.ini
@@ -1,25 +1,10 @@
 [grid-layout-properties.html]
-  [grid-area.<integer> start]
-    expected: FAIL
-
-  [grid-area.auto]
-    expected: FAIL
-
-  [grid-area.initial]
-    expected: FAIL
-
-  [grid-area.reset]
-    expected: FAIL
-
   [grid-column.<integer> start]
     expected: FAIL
 
   [grid-column.auto]
     expected: FAIL
 
-  [grid-column.initial]
-    expected: FAIL
-
   [grid-column.reset]
     expected: FAIL
 
@@ -29,15 +14,9 @@
   [grid-row.auto]
     expected: FAIL
 
-  [grid-row.initial]
-    expected: FAIL
-
   [grid-row.reset]
     expected: FAIL
 
-  [grid-template.<grid-template-rows> / <grid-template-columns>]
-    expected: FAIL
-
   [grid-template.<line-names>]
     expected: FAIL
 
@@ -46,12 +25,3 @@
 
   [grid-template.<string><track-size>+]
     expected: FAIL
-
-  [grid-template.initial]
-    expected: FAIL
-
-  [grid-template.none]
-    expected: FAIL
-
-  [grid-template.reset]
-    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-valid-expected.txt
index 6ce291e..ec790f9 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-valid-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-valid-expected.txt
@@ -1,10 +1,10 @@
 This is a testharness.js-based test.
-Found 56 tests; 24 PASS, 32 FAIL, 0 TIMEOUT, 0 NOTRUN.
-FAIL e.style['grid-area'] = "auto" should set the property value assert_equals: serialization should be canonical expected "auto" but got "auto / auto / auto / auto"
-FAIL e.style['grid-area'] = "auto / auto" should set the property value assert_equals: serialization should be canonical expected "auto" but got "auto / auto / auto / auto"
-FAIL e.style['grid-area'] = "auto / auto / auto" should set the property value assert_equals: serialization should be canonical expected "auto" but got "auto / auto / auto / auto"
-FAIL e.style['grid-area'] = "auto / auto / auto / auto" should set the property value assert_equals: serialization should be canonical expected "auto" but got "auto / auto / auto / auto"
-FAIL e.style['grid-area'] = "AuTo" should set the property value assert_equals: serialization should be canonical expected "auto" but got "auto / auto / auto / auto"
+Found 56 tests; 34 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS e.style['grid-area'] = "auto" should set the property value
+PASS e.style['grid-area'] = "auto / auto" should set the property value
+PASS e.style['grid-area'] = "auto / auto / auto" should set the property value
+PASS e.style['grid-area'] = "auto / auto / auto / auto" should set the property value
+PASS e.style['grid-area'] = "AuTo" should set the property value
 FAIL e.style['grid-row'] = "auto" should set the property value assert_equals: serialization should be canonical expected "auto" but got "auto / auto"
 FAIL e.style['grid-row'] = "auto/auto" should set the property value assert_equals: serialization should be canonical expected "auto" but got "auto / auto"
 PASS e.style['grid-column-end'] = "AuTo" should set the property value
@@ -15,8 +15,8 @@
 PASS e.style['grid-row-start'] = "AZ" should set the property value
 PASS e.style['grid-column-start'] = "-_π" should set the property value
 PASS e.style['grid-row-end'] = "_9" should set the property value
-FAIL e.style['grid-area'] = "1" should set the property value assert_equals: serialization should be canonical expected "1" but got "1 / auto / auto / auto"
-FAIL e.style['grid-area'] = "+90 -a-" should set the property value assert_equals: serialization should be canonical expected "90 -a-" but got "90 -a- / auto / auto / auto"
+PASS e.style['grid-area'] = "1" should set the property value
+PASS e.style['grid-area'] = "+90 -a-" should set the property value
 FAIL e.style['grid-row'] = "az 2" should set the property value assert_equals: serialization should be canonical expected "2 az" but got "2 az / auto"
 FAIL e.style['grid-column'] = "9" should set the property value assert_equals: serialization should be canonical expected "9" but got "9 / auto"
 FAIL e.style['grid-column'] = "-19 zA" should set the property value assert_equals: serialization should be canonical expected "-19 zA" but got "-19 zA / auto"
@@ -27,8 +27,8 @@
 PASS e.style['grid-column-start'] = "Z -44" should set the property value
 PASS e.style['grid-row-end'] = "1 -πA" should set the property value
 PASS e.style['grid-column-end'] = "π_ +5" should set the property value
-FAIL e.style['grid-area'] = "span 2 i" should set the property value assert_equals: serialization should be canonical expected "span 2 i" but got "span 2 i / auto / auto / auto"
-FAIL e.style['grid-area'] = "i 2 SpAn" should set the property value assert_equals: serialization should be canonical expected "span 2 i" but got "span 2 i / auto / auto / auto"
+PASS e.style['grid-area'] = "span 2 i" should set the property value
+PASS e.style['grid-area'] = "i 2 SpAn" should set the property value
 FAIL e.style['grid-row'] = "span 2" should set the property value assert_equals: serialization should be canonical expected "span 2" but got "span 2 / auto"
 FAIL e.style['grid-column'] = "i SpAn" should set the property value assert_equals: serialization should be canonical expected "span i" but got "span i / auto"
 PASS e.style['grid-row-start'] = "span i" should set the property value
@@ -39,13 +39,13 @@
 FAIL e.style['grid-area'] = "auto / i / auto / i" should set the property value assert_equals: serialization should be canonical expected "auto / i" but got "auto / i / auto / i"
 PASS e.style['grid-area'] = "auto / i / auto / 2 i" should set the property value
 FAIL e.style['grid-area'] = "1 / i  / auto / i" should set the property value assert_equals: serialization should be canonical expected "1 / i" but got "1 / i / auto / i"
-FAIL e.style['grid-area'] = "1 / auto / auto / auto" should set the property value assert_equals: serialization should be canonical expected "1" but got "1 / auto / auto / auto"
-FAIL e.style['grid-area'] = "1 / auto / i / auto" should set the property value assert_equals: serialization should be canonical expected "1 / auto / i" but got "1 / auto / i / auto"
+PASS e.style['grid-area'] = "1 / auto / auto / auto" should set the property value
+PASS e.style['grid-area'] = "1 / auto / i / auto" should set the property value
 PASS e.style['grid-area'] = "1 / j / i / k" should set the property value
-FAIL e.style['grid-area'] = "1 / auto / 2 / auto" should set the property value assert_equals: serialization should be canonical expected "1 / auto / 2" but got "1 / auto / 2 / auto"
-PASS e.style['grid-area'] = "1 / i / 2 / auto" should set the property value
-PASS e.style['grid-area'] = "i / i / auto / auto" should set the property value
-FAIL e.style['grid-area'] = "i / auto / i / auto" should set the property value assert_equals: serialization should be canonical expected "i / auto" but got "i / auto / i / auto"
+PASS e.style['grid-area'] = "1 / auto / 2 / auto" should set the property value
+FAIL e.style['grid-area'] = "1 / i / 2 / auto" should set the property value assert_equals: serialization should be canonical expected "1 / i / 2 / auto" but got "1 / i / 2"
+FAIL e.style['grid-area'] = "i / i / auto / auto" should set the property value assert_equals: serialization should be canonical expected "i / i / auto / auto" but got "i / i"
+FAIL e.style['grid-area'] = "i / auto / i / auto" should set the property value assert_equals: serialization should be canonical expected "i / auto" but got "i / auto / i"
 FAIL e.style['grid-area'] = "auto / i / 2 j" should set the property value assert_equals: serialization should be canonical expected "auto / i / 2 j" but got "auto / i / 2 j / i"
 PASS e.style['grid-area'] = "auto / i / 2 j / span 3 k" should set the property value
 PASS e.style['grid-row'] = "auto / i" should set the property value
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-valid.html.ini b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-valid.html.ini
index a5253c7..d65602bc 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-valid.html.ini
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-valid.html.ini
@@ -1,37 +1,11 @@
 [grid-area-valid.html]
-  [e.style['grid-area'\] = "+90 -a-" should set the property value]
-    expected: FAIL
 
   [e.style['grid-area'\] = "--a" should set the property value]
     expected: FAIL
 
-  [e.style['grid-area'\] = "1 / auto / 2 / auto" should set the property value]
-    expected: FAIL
-
-  [e.style['grid-area'\] = "1 / auto / auto / auto" should set the property value]
-    expected: FAIL
-
-  [e.style['grid-area'\] = "1 / auto / i / auto" should set the property value]
-    expected: FAIL
-
   [e.style['grid-area'\] = "1 / i  / auto / i" should set the property value]
     expected: FAIL
 
-  [e.style['grid-area'\] = "1" should set the property value]
-    expected: FAIL
-
-  [e.style['grid-area'\] = "AuTo" should set the property value]
-    expected: FAIL
-
-  [e.style['grid-area'\] = "auto / auto / auto / auto" should set the property value]
-    expected: FAIL
-
-  [e.style['grid-area'\] = "auto / auto / auto" should set the property value]
-    expected: FAIL
-
-  [e.style['grid-area'\] = "auto / auto" should set the property value]
-    expected: FAIL
-
   [e.style['grid-area'\] = "auto / i / 2 j" should set the property value]
     expected: FAIL
 
@@ -41,18 +15,9 @@
   [e.style['grid-area'\] = "auto / i" should set the property value]
     expected: FAIL
 
-  [e.style['grid-area'\] = "auto" should set the property value]
-    expected: FAIL
-
   [e.style['grid-area'\] = "i / auto / i / auto" should set the property value]
     expected: FAIL
 
-  [e.style['grid-area'\] = "i 2 SpAn" should set the property value]
-    expected: FAIL
-
-  [e.style['grid-area'\] = "span 2 i" should set the property value]
-    expected: FAIL
-
   [e.style['grid-column'\] = "-19 zA" should set the property value]
     expected: FAIL
 
@@ -80,9 +45,6 @@
   [e.style['grid-row'\] = "2 i / auto" should set the property value]
     expected: FAIL
 
-  [e.style['grid-row'\] = "auto" should set the property value]
-    expected: FAIL
-
   [e.style['grid-row'\] = "auto/auto" should set the property value]
     expected: FAIL
 
@@ -91,6 +53,3 @@
 
   [e.style['grid-row'\] = "i / i" should set the property value]
     expected: FAIL
-
-  [e.style['grid-row'\] = "span 2" should set the property value]
-    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-column-shortest-serialization-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-column-shortest-serialization-expected.txt
index 3b29a6b..8a8d72a3 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-column-shortest-serialization-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-column-shortest-serialization-expected.txt
@@ -1,19 +1,19 @@
 This is a testharness.js-based test.
-FAIL Property grid-column value 'auto / auto' assert_equals: expected "auto" but got "auto / auto"
-FAIL Property grid-column value 'auto' assert_equals: expected "auto" but got "auto / auto"
-FAIL Property grid-column value '10 / auto' assert_equals: expected "10" but got "10 / auto"
-FAIL Property grid-column value '10' assert_equals: expected "10" but got "10 / auto"
-FAIL Property grid-column value '-10 / auto' assert_equals: expected "-10" but got "-10 / auto"
-FAIL Property grid-column value '-10' assert_equals: expected "-10" but got "-10 / auto"
+PASS Property grid-column value 'auto / auto'
+PASS Property grid-column value 'auto'
+PASS Property grid-column value '10 / auto'
+PASS Property grid-column value '10'
+PASS Property grid-column value '-10 / auto'
+PASS Property grid-column value '-10'
 FAIL Property grid-column value 'first / first' assert_equals: expected "first" but got "first / first"
 FAIL Property grid-column value 'first' assert_equals: expected "first" but got "first / first"
-FAIL Property grid-column value 'span 2 / auto' assert_equals: expected "span 2" but got "span 2 / auto"
-FAIL Property grid-column value 'span 2' assert_equals: expected "span 2" but got "span 2 / auto"
-FAIL Property grid-column value '2 first / auto' assert_equals: expected "2 first" but got "2 first / auto"
-FAIL Property grid-column value '2 first' assert_equals: expected "2 first" but got "2 first / auto"
-FAIL Property grid-column value 'span first / auto' assert_equals: expected "span first" but got "span first / auto"
-FAIL Property grid-column value 'span first' assert_equals: expected "span first" but got "span first / auto"
-FAIL Property grid-column value 'span 2 first / auto' assert_equals: expected "span 2 first" but got "span 2 first / auto"
-FAIL Property grid-column value 'span 2 first' assert_equals: expected "span 2 first" but got "span 2 first / auto"
+PASS Property grid-column value 'span 2 / auto'
+PASS Property grid-column value 'span 2'
+PASS Property grid-column value '2 first / auto'
+PASS Property grid-column value '2 first'
+PASS Property grid-column value 'span first / auto'
+PASS Property grid-column value 'span first'
+PASS Property grid-column value 'span 2 first / auto'
+PASS Property grid-column value 'span 2 first'
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-column-shortest-serialization.html.ini b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-column-shortest-serialization.html.ini
index 24958db..60047a0 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-column-shortest-serialization.html.ini
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-column-shortest-serialization.html.ini
@@ -1,48 +1,6 @@
-[grid-column-shortest-serialization.html]
-  [Property grid-column value '-10 / auto']
+[grid-row-shortest-serialization.html]
+  [Property grid-row value 'first / first']
     expected: FAIL
 
-  [Property grid-column value '-10']
-    expected: FAIL
-
-  [Property grid-column value '10 / auto']
-    expected: FAIL
-
-  [Property grid-column value '10']
-    expected: FAIL
-
-  [Property grid-column value '2 first / auto']
-    expected: FAIL
-
-  [Property grid-column value '2 first']
-    expected: FAIL
-
-  [Property grid-column value 'auto / auto']
-    expected: FAIL
-
-  [Property grid-column value 'auto']
-    expected: FAIL
-
-  [Property grid-column value 'first / first']
-    expected: FAIL
-
-  [Property grid-column value 'first']
-    expected: FAIL
-
-  [Property grid-column value 'span 2 / auto']
-    expected: FAIL
-
-  [Property grid-column value 'span 2 first / auto']
-    expected: FAIL
-
-  [Property grid-column value 'span 2 first']
-    expected: FAIL
-
-  [Property grid-column value 'span 2']
-    expected: FAIL
-
-  [Property grid-column value 'span first / auto']
-    expected: FAIL
-
-  [Property grid-column value 'span first']
+  [Property grid-row value 'first']
     expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-row-shortest-serialization-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-row-shortest-serialization-expected.txt
index 53f9af2..40ea961 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-row-shortest-serialization-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-row-shortest-serialization-expected.txt
@@ -1,18 +1,18 @@
 This is a testharness.js-based test.
-FAIL Property grid-row value 'auto / auto' assert_equals: expected "auto" but got "auto / auto"
-FAIL Property grid-row value 'auto' assert_equals: expected "auto" but got "auto / auto"
-FAIL Property grid-row value '10 / auto' assert_equals: expected "10" but got "10 / auto"
-FAIL Property grid-row value '10' assert_equals: expected "10" but got "10 / auto"
-FAIL Property grid-row value '-10 / auto' assert_equals: expected "-10" but got "-10 / auto"
-FAIL Property grid-row value '-10' assert_equals: expected "-10" but got "-10 / auto"
-FAIL Property grid-row value 'span 2 / auto' assert_equals: expected "span 2" but got "span 2 / auto"
-FAIL Property grid-row value 'span 2' assert_equals: expected "span 2" but got "span 2 / auto"
-FAIL Property grid-row value '3 last / auto' assert_equals: expected "3 last" but got "3 last / auto"
-FAIL Property grid-row value '3 last' assert_equals: expected "3 last" but got "3 last / auto"
-FAIL Property grid-row value 'span first / auto' assert_equals: expected "span first" but got "span first / auto"
-FAIL Property grid-row value 'span first' assert_equals: expected "span first" but got "span first / auto"
-FAIL Property grid-row value 'span 2 first / auto' assert_equals: expected "span 2 first" but got "span 2 first / auto"
-FAIL Property grid-row value 'span 2 first' assert_equals: expected "span 2 first" but got "span 2 first / auto"
+PASS Property grid-row value 'auto / auto'
+PASS Property grid-row value 'auto'
+PASS Property grid-row value '10 / auto'
+PASS Property grid-row value '10'
+PASS Property grid-row value '-10 / auto'
+PASS Property grid-row value '-10'
+PASS Property grid-row value 'span 2 / auto'
+PASS Property grid-row value 'span 2'
+PASS Property grid-row value '3 last / auto'
+PASS Property grid-row value '3 last'
+PASS Property grid-row value 'span first / auto'
+PASS Property grid-row value 'span first'
+PASS Property grid-row value 'span 2 first / auto'
+PASS Property grid-row value 'span 2 first'
 FAIL Property grid-row value 'last / last' assert_equals: expected "last" but got "last / last"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-row-shortest-serialization.html.ini b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-row-shortest-serialization.html.ini
index a07d082..b66087f 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-row-shortest-serialization.html.ini
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-row-shortest-serialization.html.ini
@@ -1,45 +1,3 @@
-[grid-row-shortest-serialization.html]
-  [Property grid-row value '-10 / auto']
-    expected: FAIL
-
-  [Property grid-row value '-10']
-    expected: FAIL
-
-  [Property grid-row value '10 / auto']
-    expected: FAIL
-
-  [Property grid-row value '10']
-    expected: FAIL
-
-  [Property grid-row value '3 last / auto']
-    expected: FAIL
-
-  [Property grid-row value '3 last']
-    expected: FAIL
-
-  [Property grid-row value 'auto / auto']
-    expected: FAIL
-
-  [Property grid-row value 'auto']
-    expected: FAIL
-
-  [Property grid-row value 'last / last']
-    expected: FAIL
-
-  [Property grid-row value 'span 2 / auto']
-    expected: FAIL
-
-  [Property grid-row value 'span 2 first / auto']
-    expected: FAIL
-
-  [Property grid-row value 'span 2 first']
-    expected: FAIL
-
-  [Property grid-row value 'span 2']
-    expected: FAIL
-
-  [Property grid-row value 'span first / auto']
-    expected: FAIL
-
-  [Property grid-row value 'span first']
+[grid-column-shortest-serialization.html]
+  [Property grid-column value 'last / last']
     expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/cssom-getPropertyValue-common-checks-expected.txt b/third_party/blink/web_tests/external/wpt/css/cssom/cssom-getPropertyValue-common-checks-expected.txt
index 4d339360..1955721 100644
--- a/third_party/blink/web_tests/external/wpt/css/cssom/cssom-getPropertyValue-common-checks-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/cssom/cssom-getPropertyValue-common-checks-expected.txt
@@ -1,6 +1,6 @@
 This is a testharness.js-based test.
 PASS All properties can serialize 'initial'
-FAIL All properties (except 'all') can serialize their initial value (computed) assert_array_equals: lengths differ, expected array [] length 0, got [["grid", "none / none / none / row / auto / auto"], ["grid-template", "none / none / none"], ["page-orientation", ""], ["popover-hide-delay", "infinity * 1s"], ["size", ""]] length 5
+FAIL All properties (except 'all') can serialize their initial value (computed) assert_array_equals: lengths differ, expected array [] length 0, got [["grid", "none / none / none / row / auto / auto"], ["page-orientation", ""], ["popover-hide-delay", "infinity * 1s"], ["size", ""]] length 4
 FAIL All properties (except 'all') can serialize their initial value (specified) assert_array_equals: lengths differ, expected array [] length 0, got [["grid-column-gap", "normal", ""], ["grid-gap", "normal normal", ""], ["grid-row-gap", "normal", ""]] length 3
 PASS All shorthands can serialize their longhands set to 'initial'
 FAIL All shorthands (except 'all') can serialize their longhands set to their initial value assert_array_equals: lengths differ, expected array [] length 0, got [["border", ""], ["grid-gap", ""]] length 2
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/widgets/form-sizing-select.tentative.html b/third_party/blink/web_tests/external/wpt/html/rendering/widgets/form-sizing-select.tentative.html
new file mode 100644
index 0000000..f9efdc74
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/rendering/widgets/form-sizing-select.tentative.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<link rel="help" href="https://github.com/w3c/csswg-drafts/pull/9251">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<style>
+.disable-default {
+  form-sizing: normal;
+}
+</style>
+<div id="container"></div>
+<script>
+const container = document.querySelector('#container');
+const DISABLE = 'class="disable-default"';
+
+// Tests for drop-down box ====================================================
+
+test(() => {
+  const s = '<select>><option>1<option>quick brown<option>fox</select>';
+  container.innerHTML = s + s;
+  container.lastElementChild.style.formSizing = 'normal';
+  const widthForContent1 = container.lastElementChild.offsetWidth;
+  assert_greater_than(container.firstElementChild.offsetWidth,
+                      widthForContent1);
+  container.lastElementChild.selectedIndex = 1;
+  const widthForContentQuickBrown = container.lastElementChild.offsetWidth;
+  assert_greater_than(widthForContentQuickBrown, widthForContent1);
+}, 'dropdown: The width should depend on the selected OPTION');
+
+test(() => {
+  container.innerHTML = '<select><option>foo<option>quick brown fox</select>';
+  const select = container.firstElementChild;
+  const initialWidth = select.offsetWidth;
+  select.style.formSizing = 'normal';
+  assert_less_than(select.offsetWidth, initialWidth);
+  select.style.formSizing = 'auto';
+  assert_equals(select.offsetWidth, initialWidth);
+}, 'dropdown: Change the form-sizing value dynamically');
+
+// Tests for list box =========================================================
+
+// Some paltforms don't support list box rendering.
+container.innerHTML = '<select></select><select multiple></select>';
+if (container.firstElementChild.offsetHeight != container.lastElementChild.offsetHeight) {
+
+  test(() => {
+    container.innerHTML = `<select multiple><option>fox</select>` +
+                          `<select multiple ${DISABLE}><option>fox</select>`;
+    const former = container.firstElementChild;
+    const latter = container.lastElementChild;
+    const widthForOneItem = latter.offsetWidth;
+    const heightForOneItem = latter.offsetHeight;
+    assert_equals(former.offsetWidth, widthForOneItem);
+    assert_greater_than(former.offsetHeight, heightForOneItem);
+
+    latter.add(new Option('quick brown'));
+    assert_greater_than(latter.offsetWidth, widthForOneItem);
+    assert_greater_than(latter.offsetHeight, heightForOneItem);
+  }, 'listbox: The size depend on the content');
+
+  test(() => {
+    container.innerHTML = `<select size="4"></select><select size="4" ${DISABLE}></select>`;
+    const former = container.firstElementChild;
+    const latter = container.lastElementChild;
+    const widthForZeroItem = latter.offsetWidth;
+    const heightForZeroItem = latter.offsetHeight;
+    assert_equals(former.offsetWidth, widthForZeroItem);
+    assert_greater_than(former.offsetHeight, heightForZeroItem);
+
+    latter.add(new Option('quick brown'));
+    assert_greater_than(latter.offsetWidth, widthForZeroItem);
+    assert_greater_than(latter.offsetHeight, heightForZeroItem);
+  }, 'listbox: The size attribute value is ignored');
+
+  test(() => {
+    container.innerHTML = '<select multiple><option>foo<option>quick brown fox</select>';
+    const select = container.firstElementChild;
+    const initialHeight = select.offsetHeight;
+    select.style.formSizing = 'normal';
+    assert_less_than(select.offsetHeight, initialHeight);
+    select.style.formSizing = 'auto';
+    assert_equals(select.offsetHeight, initialHeight);
+  }, 'listbox: Change the form-sizing value dynamically');
+
+}
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/audio-decoder.https.any.js b/third_party/blink/web_tests/external/wpt/webcodecs/audio-decoder.https.any.js
index 52e6d768..606b052 100644
--- a/third_party/blink/web_tests/external/wpt/webcodecs/audio-decoder.https.any.js
+++ b/third_party/blink/web_tests/external/wpt/webcodecs/audio-decoder.https.any.js
@@ -150,7 +150,7 @@
             .then(t.unreached_func('flush succeeded unexpectedly'))
             .catch(t.step_func(e => {
               assert_true(e instanceof DOMException);
-              assert_equals(e.name, 'InvalidStateError');
+              assert_equals(e.name, 'NotSupportedError');
               assert_equals(codec.state, 'closed', 'state');
             }));
       },
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/audio-encoder-config.https.any.js b/third_party/blink/web_tests/external/wpt/webcodecs/audio-encoder-config.https.any.js
index 99b64cd4..98a9513 100644
--- a/third_party/blink/web_tests/external/wpt/webcodecs/audio-encoder-config.https.any.js
+++ b/third_party/blink/web_tests/external/wpt/webcodecs/audio-encoder-config.https.any.js
@@ -228,7 +228,7 @@
             .then(t.unreached_func('flush succeeded unexpectedly'))
             .catch(t.step_func(e => {
               assert_true(e instanceof DOMException);
-              assert_equals(e.name, 'InvalidStateError');
+              assert_equals(e.name, 'NotSupportedError');
               assert_equals(codec.state, 'closed', 'state');
             }));
       },
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/video-decoder.https.any.js b/third_party/blink/web_tests/external/wpt/webcodecs/video-decoder.https.any.js
index 38e0338a..190a524 100644
--- a/third_party/blink/web_tests/external/wpt/webcodecs/video-decoder.https.any.js
+++ b/third_party/blink/web_tests/external/wpt/webcodecs/video-decoder.https.any.js
@@ -111,7 +111,7 @@
             .then(t.unreached_func('flush succeeded unexpectedly'))
             .catch(t.step_func(e => {
               assert_true(e instanceof DOMException);
-              assert_equals(e.name, 'InvalidStateError');
+              assert_equals(e.name, 'NotSupportedError');
               assert_equals(codec.state, 'closed', 'state');
             }));
       },
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/video-encoder-config.https.any.js b/third_party/blink/web_tests/external/wpt/webcodecs/video-encoder-config.https.any.js
index 9966848..e480736 100644
--- a/third_party/blink/web_tests/external/wpt/webcodecs/video-encoder-config.https.any.js
+++ b/third_party/blink/web_tests/external/wpt/webcodecs/video-encoder-config.https.any.js
@@ -204,7 +204,7 @@
             .then(t.unreached_func('flush succeeded unexpectedly'))
             .catch(t.step_func(e => {
               assert_true(e instanceof DOMException);
-              assert_equals(e.name, 'InvalidStateError');
+              assert_equals(e.name, 'NotSupportedError');
               assert_equals(codec.state, 'closed', 'state');
             }));
       },
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/grid-item-column-row-get-set-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/grid-item-column-row-get-set-expected.txt
index 421e6d5..7eefad2 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/grid-item-column-row-get-set-expected.txt
+++ b/third_party/blink/web_tests/fast/css-grid-layout/grid-item-column-row-get-set-expected.txt
@@ -3,234 +3,158 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 Test getting grid-column and grid-row set through CSS
-PASS getComputedStyle(gridItemWithNoCSSRule, '').getPropertyValue('grid-column') is "auto / auto"
+PASS getComputedStyle(gridItemWithNoCSSRule, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItemWithNoCSSRule, '').getPropertyValue('grid-row') is "auto"
 PASS getComputedStyle(gridItemWithNoCSSRule, '').getPropertyValue('grid-column-start') is "auto"
 PASS getComputedStyle(gridItemWithNoCSSRule, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithNoCSSRule, '').getPropertyValue('grid-row') is "auto / auto"
 PASS getComputedStyle(gridItemWithNoCSSRule, '').getPropertyValue('grid-row-start') is "auto"
 PASS getComputedStyle(gridItemWithNoCSSRule, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-column') is "10 / auto"
+PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-column') is "10"
+PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-row') is "15"
 PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-column-start') is "10"
 PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-row') is "15 / auto"
 PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-row-start') is "15"
 PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-column') is "-10 / auto"
+PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-column') is "-10"
+PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-row') is "-15"
 PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-column-start') is "-10"
 PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-row') is "-15 / auto"
 PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-row-start') is "-15"
 PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-column') is "auto / auto"
+PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-row') is "auto"
 PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-column-start') is "auto"
 PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-row') is "auto / auto"
 PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-row-start') is "auto"
 PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-row-end') is "auto"
 PASS getComputedStyle(gridItemWith2IntegerElement, '').getPropertyValue('grid-column') is "10 / 15"
+PASS getComputedStyle(gridItemWith2IntegerElement, '').getPropertyValue('grid-row') is "5 / 5"
 PASS getComputedStyle(gridItemWith2IntegerElement, '').getPropertyValue('grid-column-start') is "10"
 PASS getComputedStyle(gridItemWith2IntegerElement, '').getPropertyValue('grid-column-end') is "15"
-PASS getComputedStyle(gridItemWith2IntegerElement, '').getPropertyValue('grid-row') is "5 / 5"
 PASS getComputedStyle(gridItemWith2IntegerElement, '').getPropertyValue('grid-row-start') is "5"
 PASS getComputedStyle(gridItemWith2IntegerElement, '').getPropertyValue('grid-row-end') is "5"
 PASS getComputedStyle(gridItemWithNegativePositiveIntegerElement, '').getPropertyValue('grid-column') is "10 / -10"
+PASS getComputedStyle(gridItemWithNegativePositiveIntegerElement, '').getPropertyValue('grid-row') is "-8 / 5"
 PASS getComputedStyle(gridItemWithNegativePositiveIntegerElement, '').getPropertyValue('grid-column-start') is "10"
 PASS getComputedStyle(gridItemWithNegativePositiveIntegerElement, '').getPropertyValue('grid-column-end') is "-10"
-PASS getComputedStyle(gridItemWithNegativePositiveIntegerElement, '').getPropertyValue('grid-row') is "-8 / 5"
 PASS getComputedStyle(gridItemWithNegativePositiveIntegerElement, '').getPropertyValue('grid-row-start') is "-8"
 PASS getComputedStyle(gridItemWithNegativePositiveIntegerElement, '').getPropertyValue('grid-row-end') is "5"
 PASS getComputedStyle(gridItemWithBeforeSpanElement, '').getPropertyValue('grid-column') is "span 2 / 4"
+PASS getComputedStyle(gridItemWithBeforeSpanElement, '').getPropertyValue('grid-row') is "3 / span 5"
 PASS getComputedStyle(gridItemWithBeforeSpanElement, '').getPropertyValue('grid-column-start') is "span 2"
 PASS getComputedStyle(gridItemWithBeforeSpanElement, '').getPropertyValue('grid-column-end') is "4"
-PASS getComputedStyle(gridItemWithBeforeSpanElement, '').getPropertyValue('grid-row') is "3 / span 5"
 PASS getComputedStyle(gridItemWithBeforeSpanElement, '').getPropertyValue('grid-row-start') is "3"
 PASS getComputedStyle(gridItemWithBeforeSpanElement, '').getPropertyValue('grid-row-end') is "span 5"
-PASS getComputedStyle(gridItemWith2OnlySpanElement, '').getPropertyValue('grid-column') is "auto / auto"
+PASS getComputedStyle(gridItemWith2OnlySpanElement, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItemWith2OnlySpanElement, '').getPropertyValue('grid-row') is "auto"
 PASS getComputedStyle(gridItemWith2OnlySpanElement, '').getPropertyValue('grid-column-start') is "auto"
 PASS getComputedStyle(gridItemWith2OnlySpanElement, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWith2OnlySpanElement, '').getPropertyValue('grid-row') is "auto / auto"
 PASS getComputedStyle(gridItemWith2OnlySpanElement, '').getPropertyValue('grid-row-start') is "auto"
 PASS getComputedStyle(gridItemWith2OnlySpanElement, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWith2AutoElement, '').getPropertyValue('grid-column') is "auto / auto"
+PASS getComputedStyle(gridItemWith2AutoElement, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItemWith2AutoElement, '').getPropertyValue('grid-row') is "auto"
 PASS getComputedStyle(gridItemWith2AutoElement, '').getPropertyValue('grid-column-start') is "auto"
 PASS getComputedStyle(gridItemWith2AutoElement, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWith2AutoElement, '').getPropertyValue('grid-row') is "auto / auto"
 PASS getComputedStyle(gridItemWith2AutoElement, '').getPropertyValue('grid-row-start') is "auto"
 PASS getComputedStyle(gridItemWith2AutoElement, '').getPropertyValue('grid-row-end') is "auto"
 PASS getComputedStyle(gridItemWithBothShortLongHandElement, '').getPropertyValue('grid-column') is "10 / 11"
+PASS getComputedStyle(gridItemWithBothShortLongHandElement, '').getPropertyValue('grid-row') is "4 / 5"
 PASS getComputedStyle(gridItemWithBothShortLongHandElement, '').getPropertyValue('grid-column-start') is "10"
 PASS getComputedStyle(gridItemWithBothShortLongHandElement, '').getPropertyValue('grid-column-end') is "11"
-PASS getComputedStyle(gridItemWithBothShortLongHandElement, '').getPropertyValue('grid-row') is "4 / 5"
 PASS getComputedStyle(gridItemWithBothShortLongHandElement, '').getPropertyValue('grid-row-start') is "4"
 PASS getComputedStyle(gridItemWithBothShortLongHandElement, '').getPropertyValue('grid-row-end') is "5"
 PASS getComputedStyle(gridItemWithNoSpaceElement, '').getPropertyValue('grid-column') is "auto / 1"
+PASS getComputedStyle(gridItemWithNoSpaceElement, '').getPropertyValue('grid-row') is "5"
 PASS getComputedStyle(gridItemWithNoSpaceElement, '').getPropertyValue('grid-column-start') is "auto"
 PASS getComputedStyle(gridItemWithNoSpaceElement, '').getPropertyValue('grid-column-end') is "1"
-PASS getComputedStyle(gridItemWithNoSpaceElement, '').getPropertyValue('grid-row') is "5 / auto"
 PASS getComputedStyle(gridItemWithNoSpaceElement, '').getPropertyValue('grid-row-start') is "5"
 PASS getComputedStyle(gridItemWithNoSpaceElement, '').getPropertyValue('grid-row-end') is "auto"
 PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-column') is "first / first"
+PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-row') is "last / last"
 PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-column-start') is "first"
 PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-column-end') is "first"
-PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-row') is "last / last"
 PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-row-start') is "last"
 PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-row-end') is "last"
 PASS getComputedStyle(gridItemWithNonExistingCustomIdent, '').getPropertyValue('grid-column') is "nav / nav"
+PASS getComputedStyle(gridItemWithNonExistingCustomIdent, '').getPropertyValue('grid-row') is "foo / foo"
 PASS getComputedStyle(gridItemWithNonExistingCustomIdent, '').getPropertyValue('grid-column-start') is "nav"
 PASS getComputedStyle(gridItemWithNonExistingCustomIdent, '').getPropertyValue('grid-column-end') is "nav"
-PASS getComputedStyle(gridItemWithNonExistingCustomIdent, '').getPropertyValue('grid-row') is "foo / foo"
 PASS getComputedStyle(gridItemWithNonExistingCustomIdent, '').getPropertyValue('grid-row-start') is "foo"
 PASS getComputedStyle(gridItemWithNonExistingCustomIdent, '').getPropertyValue('grid-row-end') is "foo"
 PASS getComputedStyle(gridItemWithSpanCustomIdent, '').getPropertyValue('grid-column') is "1 / span first"
+PASS getComputedStyle(gridItemWithSpanCustomIdent, '').getPropertyValue('grid-row') is "-1 / span last"
 PASS getComputedStyle(gridItemWithSpanCustomIdent, '').getPropertyValue('grid-column-start') is "1"
 PASS getComputedStyle(gridItemWithSpanCustomIdent, '').getPropertyValue('grid-column-end') is "span first"
-PASS getComputedStyle(gridItemWithSpanCustomIdent, '').getPropertyValue('grid-row') is "-1 / span last"
 PASS getComputedStyle(gridItemWithSpanCustomIdent, '').getPropertyValue('grid-row-start') is "-1"
 PASS getComputedStyle(gridItemWithSpanCustomIdent, '').getPropertyValue('grid-row-end') is "span last"
 PASS getComputedStyle(gridItemWithSpanNumberCustomIdent, '').getPropertyValue('grid-column') is "1 / span 3 first"
+PASS getComputedStyle(gridItemWithSpanNumberCustomIdent, '').getPropertyValue('grid-row') is "-1 / span 2 last"
 PASS getComputedStyle(gridItemWithSpanNumberCustomIdent, '').getPropertyValue('grid-column-start') is "1"
 PASS getComputedStyle(gridItemWithSpanNumberCustomIdent, '').getPropertyValue('grid-column-end') is "span 3 first"
-PASS getComputedStyle(gridItemWithSpanNumberCustomIdent, '').getPropertyValue('grid-row') is "-1 / span 2 last"
 PASS getComputedStyle(gridItemWithSpanNumberCustomIdent, '').getPropertyValue('grid-row-start') is "-1"
 PASS getComputedStyle(gridItemWithSpanNumberCustomIdent, '').getPropertyValue('grid-row-end') is "span 2 last"
 PASS getComputedStyle(gridItemWithSingleNamedGridArea, '').getPropertyValue('grid-column') is "thirdArea / thirdArea"
+PASS getComputedStyle(gridItemWithSingleNamedGridArea, '').getPropertyValue('grid-row') is "firstArea / firstArea"
 PASS getComputedStyle(gridItemWithSingleNamedGridArea, '').getPropertyValue('grid-column-start') is "thirdArea"
 PASS getComputedStyle(gridItemWithSingleNamedGridArea, '').getPropertyValue('grid-column-end') is "thirdArea"
-PASS getComputedStyle(gridItemWithSingleNamedGridArea, '').getPropertyValue('grid-row') is "firstArea / firstArea"
 PASS getComputedStyle(gridItemWithSingleNamedGridArea, '').getPropertyValue('grid-row-start') is "firstArea"
 PASS getComputedStyle(gridItemWithSingleNamedGridArea, '').getPropertyValue('grid-row-end') is "firstArea"
 PASS getComputedStyle(gridItemWithNamedGridAreaAndSpan, '').getPropertyValue('grid-column') is "thirdArea / span 1"
+PASS getComputedStyle(gridItemWithNamedGridAreaAndSpan, '').getPropertyValue('grid-row') is "firstArea / span 2"
 PASS getComputedStyle(gridItemWithNamedGridAreaAndSpan, '').getPropertyValue('grid-column-start') is "thirdArea"
 PASS getComputedStyle(gridItemWithNamedGridAreaAndSpan, '').getPropertyValue('grid-column-end') is "span 1"
-PASS getComputedStyle(gridItemWithNamedGridAreaAndSpan, '').getPropertyValue('grid-row') is "firstArea / span 2"
 PASS getComputedStyle(gridItemWithNamedGridAreaAndSpan, '').getPropertyValue('grid-row-start') is "firstArea"
 PASS getComputedStyle(gridItemWithNamedGridAreaAndSpan, '').getPropertyValue('grid-row-end') is "span 2"
 
 
 Test the initial value
-PASS getComputedStyle(element, '').getPropertyValue('grid-column') is 'auto / auto'
+PASS getComputedStyle(element, '').getPropertyValue('grid-column') is 'auto'
 PASS getComputedStyle(element, '').getPropertyValue('grid-column-start') is 'auto'
 PASS getComputedStyle(element, '').getPropertyValue('grid-column-end') is 'auto'
-PASS getComputedStyle(element, '').getPropertyValue('grid-row') is 'auto / auto'
+PASS getComputedStyle(element, '').getPropertyValue('grid-row') is 'auto'
 PASS getComputedStyle(element, '').getPropertyValue('grid-row-start') is 'auto'
 PASS getComputedStyle(element, '').getPropertyValue('grid-row-end') is 'auto'
 
 
 Test getting and setting grid-column and grid-row through JS
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "18 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "18"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "66 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "66"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "-55 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "-55"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "-40 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "-40"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "18"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "66"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "-55"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "-40"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "10 / 55"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "10"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "55"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "1 / 10"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "1"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "10"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "span 5 / 5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "span 5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "5"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "4 / span 4"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "4"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "span 4"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "-5 / 5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "-5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "5"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "4 / -4"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "4"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "-4"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "4 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "4"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "5 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "4"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "5"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / 5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "5"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / 8"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "8"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "span 1 / 3"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "span 1"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "3"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "5 / span 1"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "span 1"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "span first / 3"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "span first"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "3"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "5 / span last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "span last"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "first / last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "first"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "last"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "nav / span last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "nav"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "span last"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "3 first / 2 last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "3 first"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "2 last"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "5 nav / span 7 last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "5 nav"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "span 7 last"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "span 3 first / -3 last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "span 3 first"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "-3 last"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 2 last / -1 nav"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span 2 last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "-1 nav"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "5 / none"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "none"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "8 / foobar"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "8"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "foobar"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "nonExistent / none"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "nonExistent"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "none"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "nonExistent / foobar"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "nonExistent"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "foobar"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "span 3 first / none"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "span 3 first"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "none"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span last / foobar"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "foobar"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "span 5 / span 2"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "span 5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "span 2"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span first / span last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span first"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "span last"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "span 5 first / span 2 last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "span 5 first"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "span 2 last"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 3 first / span 7 last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span 3 first"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "span 7 last"
 
 
 Test setting grid-column and grid-row back to 'auto' through JS
@@ -240,267 +164,103 @@
 PASS getComputedStyle(element, '').getPropertyValue('grid-row') is '66 / 68'
 PASS getComputedStyle(element, '').getPropertyValue('grid-row-start') is '66'
 PASS getComputedStyle(element, '').getPropertyValue('grid-row-end') is '68'
-PASS getComputedStyle(element, '').getPropertyValue('grid-column') is 'auto / auto'
+PASS getComputedStyle(element, '').getPropertyValue('grid-column') is 'auto'
 PASS getComputedStyle(element, '').getPropertyValue('grid-column-start') is 'auto'
 PASS getComputedStyle(element, '').getPropertyValue('grid-column-end') is 'auto'
-PASS getComputedStyle(element, '').getPropertyValue('grid-row') is 'auto / auto'
+PASS getComputedStyle(element, '').getPropertyValue('grid-row') is 'auto'
 PASS getComputedStyle(element, '').getPropertyValue('grid-row-start') is 'auto'
 PASS getComputedStyle(element, '').getPropertyValue('grid-row-end') is 'auto'
 
 
 Test getting and setting 'initial' grid-column and grid-row through JS
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "1 / span 2"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "1"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "span 2"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 3 / 5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span 3"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 3 / 5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span 3"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
 
 
 Test getting and setting 'inherit' grid-column and grid-row through JS
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "1 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "1"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "1"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 1 / 7"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span 1"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "7"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "6 / span 2"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "6"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "span 2"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "1 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "1"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "1"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "6 / span 2"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "6"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "span 2"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 1 / 7"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span 1"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "7"
 
 
 Test getting and setting invalid grid-column and grid-row through JS
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/grid-item-column-row-get-set.html b/third_party/blink/web_tests/fast/css-grid-layout/grid-item-column-row-get-set.html
index 1ff7150..a30fa5c 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/grid-item-column-row-get-set.html
+++ b/third_party/blink/web_tests/fast/css-grid-layout/grid-item-column-row-get-set.html
@@ -109,53 +109,53 @@
     description('Test that setting and getting grid-column and grid-row works as expected');
 
     debug("Test getting grid-column and grid-row set through CSS");
-    testColumnRowCSSParsing("gridItemWithNoCSSRule", "auto / auto", "auto / auto");
-    testColumnRowCSSParsing("gridItemWithPositiveInteger", "10 / auto", "15 / auto");
-    testColumnRowCSSParsing("gridItemWithNegativeInteger", "-10 / auto", "-15 / auto");
-    testColumnRowCSSParsing("gridItemWithAutoElement", "auto / auto", "auto / auto");
-    testColumnRowCSSParsing("gridItemWith2IntegerElement", "10 / 15", "5 / 5");
-    testColumnRowCSSParsing("gridItemWithNegativePositiveIntegerElement", "10 / -10", "-8 / 5");
-    testColumnRowCSSParsing("gridItemWithBeforeSpanElement", "span 2 / 4", "3 / span 5");
-    testColumnRowCSSParsing("gridItemWith2OnlySpanElement", "auto / auto", "auto / auto");
-    testColumnRowCSSParsing("gridItemWith2AutoElement", "auto / auto" , "auto / auto");
-    testColumnRowCSSParsing("gridItemWithBothShortLongHandElement", "10 / 11", "4 / 5");
-    testColumnRowCSSParsing("gridItemWithNoSpaceElement", "auto / 1", "5 / auto");
-    testColumnRowCSSParsing("gridItemWithCustomIdent", "first / first", "last / last");
-    testColumnRowCSSParsing("gridItemWithNonExistingCustomIdent", "nav / nav", "foo / foo");
-    testColumnRowCSSParsing("gridItemWithSpanCustomIdent", "1 / span first", "-1 / span last");
-    testColumnRowCSSParsing("gridItemWithSpanNumberCustomIdent", "1 / span 3 first", "-1 / span 2 last");
-    testColumnRowCSSParsing("gridItemWithSingleNamedGridArea", "thirdArea / thirdArea", "firstArea / firstArea");
-    testColumnRowCSSParsing("gridItemWithNamedGridAreaAndSpan", "thirdArea / span 1", "firstArea / span 2");
+    testColumnRowCSSParsing("gridItemWithNoCSSRule", "auto", "auto", "auto", "auto", "auto", "auto");
+    testColumnRowCSSParsing("gridItemWithPositiveInteger", "10", "15", "10", "auto", "15", "auto");
+    testColumnRowCSSParsing("gridItemWithNegativeInteger", "-10", "-15", "-10", "auto", "-15", "auto");
+    testColumnRowCSSParsing("gridItemWithAutoElement", "auto", "auto", "auto", "auto", "auto", "auto");
+    testColumnRowCSSParsing("gridItemWith2IntegerElement", "10 / 15", "5 / 5", "10", "15", "5", "5");
+    testColumnRowCSSParsing("gridItemWithNegativePositiveIntegerElement", "10 / -10", "-8 / 5", "10", "-10", "-8", "5");
+    testColumnRowCSSParsing("gridItemWithBeforeSpanElement", "span 2 / 4", "3 / span 5", "span 2", "4", "3", "span 5");
+    testColumnRowCSSParsing("gridItemWith2OnlySpanElement", "auto", "auto", "auto", "auto", "auto", "auto");
+    testColumnRowCSSParsing("gridItemWith2AutoElement", "auto" , "auto", "auto", "auto", "auto", "auto");
+    testColumnRowCSSParsing("gridItemWithBothShortLongHandElement", "10 / 11", "4 / 5", "10", "11", "4", "5");
+    testColumnRowCSSParsing("gridItemWithNoSpaceElement", "auto / 1", "5", "auto", "1", "5", "auto");
+    testColumnRowCSSParsing("gridItemWithCustomIdent", "first / first", "last / last", "first", "first", "last", "last");
+    testColumnRowCSSParsing("gridItemWithNonExistingCustomIdent", "nav / nav", "foo / foo", "nav", "nav", "foo", "foo");
+    testColumnRowCSSParsing("gridItemWithSpanCustomIdent", "1 / span first", "-1 / span last", "1", "span first", "-1", "span last");
+    testColumnRowCSSParsing("gridItemWithSpanNumberCustomIdent", "1 / span 3 first", "-1 / span 2 last", "1", "span 3 first", "-1", "span 2 last");
+    testColumnRowCSSParsing("gridItemWithSingleNamedGridArea", "thirdArea / thirdArea", "firstArea / firstArea", "thirdArea", "thirdArea", "firstArea", "firstArea");
+    testColumnRowCSSParsing("gridItemWithNamedGridAreaAndSpan", "thirdArea / span 1", "firstArea / span 2", "thirdArea", "span 1", "firstArea", "span 2");
 
     debug("");
     debug("Test the initial value");
     var element = document.createElement("div");
     document.body.appendChild(element);
-    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column')", "'auto / auto'");
+    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column')", "'auto'");
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column-start')", "'auto'");
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column-end')", "'auto'");
-    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row')", "'auto / auto'");
+    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row')", "'auto'");
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row-start')", "'auto'");
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row-end')", "'auto'");
 
     debug("");
     debug("Test getting and setting grid-column and grid-row through JS");
-    testColumnRowJSParsing("18", "66", "18 / auto", "66 / auto");
-    testColumnRowJSParsing("-55", "-40", "-55 / auto", "-40 / auto");
-    testColumnRowJSParsing("auto", "auto", "auto / auto", "auto / auto");
-    testColumnRowJSParsing("10 / 55", "1 / 10");
-    testColumnRowJSParsing("span 5 / 5", "4 / span 4");
-    testColumnRowJSParsing("-5 / 5", "4 / -4");
-    testColumnRowJSParsing("4 / auto", "5 / auto");
-    testColumnRowJSParsing("auto / 5", "auto / 8");
-    testColumnRowJSParsing("span / 3", "5 / span", "auto / auto", "auto / auto");
+    testColumnRowJSParsing("18", "66", "18", "66");
+    testColumnRowJSParsing("-55", "-40", "-55", "-40");
+    testColumnRowJSParsing("auto", "auto", "auto", "auto");
+    testColumnRowJSParsing("10 / 55", "1 / 10", "10 / 55", "1 / 10");
+    testColumnRowJSParsing("span 5 / 5", "4 / span 4", "span 5 / 5", "4 / span 4");
+    testColumnRowJSParsing("-5 / 5", "4 / -4", "-5 / 5", "4 / -4");
+    testColumnRowJSParsing("4 / auto", "5 / auto", "4", "5");
+    testColumnRowJSParsing("auto / 5", "auto / 8", "auto / 5", "auto / 8");
+    testColumnRowJSParsing("span / 3", "5 / span", "auto", "auto");
     testColumnRowJSParsing("span 1 / 3", "5 / span 1", "span 1 / 3", "5 / span 1");
     testColumnRowJSParsing("first span / 3", "5 / last span", "span first / 3", "5 / span last");
     testColumnRowJSParsing("first / last", "nav / last span", "first / last", "nav / span last");
     testColumnRowJSParsing("3 first / 2 last", "5 nav / last 7 span", "3 first / 2 last", "5 nav / span 7 last");
     testColumnRowJSParsing("3 first span / -3 last", "last 2 span / -1 nav", "span 3 first / -3 last", "span 2 last / -1 nav");
-    testColumnRowJSParsing("5 / none", "8 / foobar");
-    testColumnRowJSParsing("nonExistent / none", "nonExistent / foobar");
+    testColumnRowJSParsing("5 / none", "8 / foobar", "5 / none", "8 / foobar");
+    testColumnRowJSParsing("nonExistent / none", "nonExistent / foobar", "nonExistent / none", "nonExistent / foobar");
     testColumnRowJSParsing("span first 3 / none", "last span / foobar", "span 3 first / none", "span last / foobar");
     testColumnRowJSParsing("5 span / span 2", "span first / last span", "span 5 / span 2", "span first / span last");
     testColumnRowJSParsing("span 5 first / span last 2", "3 first span / last 7 span", "span 5 first / span 2 last", "span 3 first / span 7 last");
@@ -173,10 +173,10 @@
 
     element.style.gridColumn = "auto";
     element.style.gridRow = "auto";
-    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column')", "'auto / auto'");
+    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column')", "'auto'");
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column-start')", "'auto'");
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column-end')", "'auto'");
-    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row')", "'auto / auto'");
+    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row')", "'auto'");
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row-start')", "'auto'");
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row-end')", "'auto'");
 
@@ -186,8 +186,8 @@
 
     debug("");
     debug("Test getting and setting 'inherit' grid-column and grid-row through JS");
-    testColumnRowInheritJSParsing("1 / auto", "inherit");
-    testColumnRowInheritJSParsing("inherit", "1 / auto");
+    testColumnRowInheritJSParsing("1", "inherit");
+    testColumnRowInheritJSParsing("inherit", "1");
     testColumnRowInheritJSParsing("inherit", "inherit");
 
     debug("");
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/grid-item-end-after-get-set-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/grid-item-end-after-get-set-expected.txt
index 2a990e0..129d809 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/grid-item-end-after-get-set-expected.txt
+++ b/third_party/blink/web_tests/fast/css-grid-layout/grid-item-end-after-get-set-expected.txt
@@ -3,214 +3,86 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 Test getting grid-column-end and grid-row-end set through CSS
-PASS getComputedStyle(gridElement, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridElement, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridElement, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridElement, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridElement, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridElement, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(gridElement, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridElement, '').getPropertyValue('grid-row') is "auto"
 PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-column') is "auto / 10"
-PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-column-end') is "10"
 PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-row') is "auto / 15"
-PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-row-end') is "15"
 PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-column') is "auto / -10"
-PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-column-end') is "-10"
 PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-row') is "auto / -15"
-PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-row-end') is "-15"
 PASS getComputedStyle(gridItemWithBeforeSpan, '').getPropertyValue('grid-column') is "auto / span 2"
-PASS getComputedStyle(gridItemWithBeforeSpan, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithBeforeSpan, '').getPropertyValue('grid-column-end') is "span 2"
 PASS getComputedStyle(gridItemWithBeforeSpan, '').getPropertyValue('grid-row') is "auto / span 9"
-PASS getComputedStyle(gridItemWithBeforeSpan, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithBeforeSpan, '').getPropertyValue('grid-row-end') is "span 9"
 PASS getComputedStyle(gridItemWithAfterSpan, '').getPropertyValue('grid-column') is "auto / span 2"
-PASS getComputedStyle(gridItemWithAfterSpan, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithAfterSpan, '').getPropertyValue('grid-column-end') is "span 2"
 PASS getComputedStyle(gridItemWithAfterSpan, '').getPropertyValue('grid-row') is "auto / span 9"
-PASS getComputedStyle(gridItemWithAfterSpan, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithAfterSpan, '').getPropertyValue('grid-row-end') is "span 9"
-PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-row') is "auto"
 PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-column') is "auto / first"
-PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-column-end') is "first"
 PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-row') is "auto / last"
-PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-row-end') is "last"
 PASS getComputedStyle(gridItemWithNumberCustomIdent, '').getPropertyValue('grid-column') is "auto / 2 first"
-PASS getComputedStyle(gridItemWithNumberCustomIdent, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithNumberCustomIdent, '').getPropertyValue('grid-column-end') is "2 first"
 PASS getComputedStyle(gridItemWithNumberCustomIdent, '').getPropertyValue('grid-row') is "auto / 3 last"
-PASS getComputedStyle(gridItemWithNumberCustomIdent, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithNumberCustomIdent, '').getPropertyValue('grid-row-end') is "3 last"
 PASS getComputedStyle(gridItemWithSpanCustomIdentElement, '').getPropertyValue('grid-column') is "auto / span first"
-PASS getComputedStyle(gridItemWithSpanCustomIdentElement, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithSpanCustomIdentElement, '').getPropertyValue('grid-column-end') is "span first"
 PASS getComputedStyle(gridItemWithSpanCustomIdentElement, '').getPropertyValue('grid-row') is "auto / span last"
-PASS getComputedStyle(gridItemWithSpanCustomIdentElement, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithSpanCustomIdentElement, '').getPropertyValue('grid-row-end') is "span last"
 PASS getComputedStyle(gridItemWithSpanNumberCustomIdentElement, '').getPropertyValue('grid-column') is "auto / span 2 first"
-PASS getComputedStyle(gridItemWithSpanNumberCustomIdentElement, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithSpanNumberCustomIdentElement, '').getPropertyValue('grid-column-end') is "span 2 first"
 PASS getComputedStyle(gridItemWithSpanNumberCustomIdentElement, '').getPropertyValue('grid-row') is "auto / span 3 last"
-PASS getComputedStyle(gridItemWithSpanNumberCustomIdentElement, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithSpanNumberCustomIdentElement, '').getPropertyValue('grid-row-end') is "span 3 last"
 PASS getComputedStyle(gridItemWithArea, '').getPropertyValue('grid-column') is "auto / firstArea"
-PASS getComputedStyle(gridItemWithArea, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithArea, '').getPropertyValue('grid-column-end') is "firstArea"
 PASS getComputedStyle(gridItemWithArea, '').getPropertyValue('grid-row') is "auto / thirdArea"
-PASS getComputedStyle(gridItemWithArea, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithArea, '').getPropertyValue('grid-row-end') is "thirdArea"
-PASS getComputedStyle(gridItemWithCSSWideKeyword, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItemWithCSSWideKeyword, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithCSSWideKeyword, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithCSSWideKeyword, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItemWithCSSWideKeyword, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithCSSWideKeyword, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithCSSWideKeyword2, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItemWithCSSWideKeyword2, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithCSSWideKeyword2, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithCSSWideKeyword2, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItemWithCSSWideKeyword2, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithCSSWideKeyword2, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithSpanAuto, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItemWithSpanAuto, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithSpanAuto, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithSpanAuto, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItemWithSpanAuto, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithSpanAuto, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithOneAuto, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItemWithOneAuto, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithOneAuto, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithOneAuto, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItemWithOneAuto, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithOneAuto, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithSpanAutoOne, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItemWithSpanAutoOne, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithSpanAutoOne, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithSpanAutoOne, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItemWithSpanAutoOne, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithSpanAutoOne, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(gridItemWithCSSWideKeyword, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItemWithCSSWideKeyword, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItemWithCSSWideKeyword2, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItemWithCSSWideKeyword2, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItemWithSpanAuto, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItemWithSpanAuto, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItemWithOneAuto, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItemWithOneAuto, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItemWithSpanAutoOne, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItemWithSpanAutoOne, '').getPropertyValue('grid-row') is "auto"
 
 
 Test the initial value
 PASS getComputedStyle(element, '').getPropertyValue('grid-column-end') is 'auto'
-PASS getComputedStyle(element, '').getPropertyValue('grid-column') is 'auto / auto'
+PASS getComputedStyle(element, '').getPropertyValue('grid-column') is 'auto'
 PASS getComputedStyle(element, '').getPropertyValue('grid-row-end') is 'auto'
-PASS getComputedStyle(element, '').getPropertyValue('grid-row') is 'auto / auto'
+PASS getComputedStyle(element, '').getPropertyValue('grid-row') is 'auto'
 
 
 Test getting and setting grid-column-end and grid-row-end through JS
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / 18"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "18"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / 66"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "66"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / -55"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "-55"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / -40"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "-40"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / first"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "first"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "last"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / span 7"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "span 7"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / span 2"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "span 2"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / span first"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "span first"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / span last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "span last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / thirdArea"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "thirdArea"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / secondArea"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "secondArea"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / nonExistentArea"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "nonExistentArea"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / secondArea"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "secondArea"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / secondArea"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "secondArea"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / nonExistentArea"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "nonExistentArea"
 
 
 Test setting grid-column-start and grid-row-start to 'inherit' through JS
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / span 2"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "span 2"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / 18"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "18"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / 2"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "2"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / 7"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "7"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / span 2"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "span 2"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / 7"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "7"
 
 
 Test setting grid-column-start and grid-row-start to 'initial' through JS
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "1 / span 2"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "1"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "span 2"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 3 / 5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span 3"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "1 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "1"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "1"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 3 / 5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span 3"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "1 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "1"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 3 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span 3"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "1"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 3"
 
 
 Test setting grid-column-end and grid-row-end back to 'auto' through JS
@@ -219,9 +91,9 @@
 PASS getComputedStyle(element, '').getPropertyValue('grid-row-end') is '66'
 PASS getComputedStyle(element, '').getPropertyValue('grid-row') is 'auto / 66'
 PASS getComputedStyle(element, '').getPropertyValue('grid-column-end') is 'auto'
-PASS getComputedStyle(element, '').getPropertyValue('grid-column') is 'auto / auto'
+PASS getComputedStyle(element, '').getPropertyValue('grid-column') is 'auto'
 PASS getComputedStyle(element, '').getPropertyValue('grid-row-end') is 'auto'
-PASS getComputedStyle(element, '').getPropertyValue('grid-row') is 'auto / auto'
+PASS getComputedStyle(element, '').getPropertyValue('grid-row') is 'auto'
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/grid-item-end-after-get-set.html b/third_party/blink/web_tests/fast/css-grid-layout/grid-item-end-after-get-set.html
index 8095720..58bf1e0e 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/grid-item-end-after-get-set.html
+++ b/third_party/blink/web_tests/fast/css-grid-layout/grid-item-end-after-get-set.html
@@ -101,32 +101,32 @@
     description('Test that setting and getting grid-column-end and grid-row-end works as expected');
 
     debug("Test getting grid-column-end and grid-row-end set through CSS");
-    testColumnRowCSSParsing("gridElement", "auto / auto", "auto / auto");
+    testColumnRowCSSParsing("gridElement", "auto", "auto");
     testColumnRowCSSParsing("gridItemWithPositiveInteger", "auto / 10", "auto / 15");
     testColumnRowCSSParsing("gridItemWithNegativeInteger", "auto / -10", "auto / -15");
     testColumnRowCSSParsing("gridItemWithBeforeSpan", "auto / span 2", "auto / span 9");
     testColumnRowCSSParsing("gridItemWithAfterSpan", "auto / span 2", "auto / span 9");
-    testColumnRowCSSParsing("gridItemWithOnlySpan", "auto / auto", "auto / auto");
-    testColumnRowCSSParsing("gridItemWithAutoElement", "auto / auto", "auto / auto");
+    testColumnRowCSSParsing("gridItemWithOnlySpan", "auto", "auto");
+    testColumnRowCSSParsing("gridItemWithAutoElement", "auto", "auto");
     testColumnRowCSSParsing("gridItemWithCustomIdent", "auto / first", "auto / last");
     testColumnRowCSSParsing("gridItemWithNumberCustomIdent", "auto / 2 first", "auto / 3 last");
     testColumnRowCSSParsing("gridItemWithSpanCustomIdentElement", "auto / span first", "auto / span last");
     testColumnRowCSSParsing("gridItemWithSpanNumberCustomIdentElement", "auto / span 2 first", "auto / span 3 last");
     testColumnRowCSSParsing("gridItemWithArea", "auto / firstArea", "auto / thirdArea");
-    testColumnRowCSSParsing("gridItemWithCSSWideKeyword", "auto / auto", "auto / auto");
-    testColumnRowCSSParsing("gridItemWithCSSWideKeyword2", "auto / auto", "auto / auto");
-    testColumnRowCSSParsing("gridItemWithSpanAuto", "auto / auto", "auto / auto");
-    testColumnRowCSSParsing("gridItemWithOneAuto", "auto / auto", "auto / auto");
-    testColumnRowCSSParsing("gridItemWithSpanAutoOne", "auto / auto", "auto / auto");
+    testColumnRowCSSParsing("gridItemWithCSSWideKeyword", "auto", "auto");
+    testColumnRowCSSParsing("gridItemWithCSSWideKeyword2", "auto", "auto");
+    testColumnRowCSSParsing("gridItemWithSpanAuto", "auto", "auto");
+    testColumnRowCSSParsing("gridItemWithOneAuto", "auto", "auto");
+    testColumnRowCSSParsing("gridItemWithSpanAutoOne", "auto", "auto");
 
     debug("");
     debug("Test the initial value");
     var element = document.createElement("div");
     document.body.appendChild(element);
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column-end')", "'auto'");
-    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column')", "'auto / auto'");
+    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column')", "'auto'");
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row-end')", "'auto'");
-    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row')", "'auto / auto'");
+    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row')", "'auto'");
 
     debug("");
     debug("Test getting and setting grid-column-end and grid-row-end through JS");
@@ -161,9 +161,9 @@
     element.style.gridColumnEnd = "auto";
     element.style.gridRowEnd = "auto";
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column-end')", "'auto'");
-    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column')", "'auto / auto'");
+    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column')", "'auto'");
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row-end')", "'auto'");
-    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row')", "'auto / auto'");
+    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row')", "'auto'");
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/grid-item-start-before-get-set-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/grid-item-start-before-get-set-expected.txt
index aca3866..0e07a1c 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/grid-item-start-before-get-set-expected.txt
+++ b/third_party/blink/web_tests/fast/css-grid-layout/grid-item-start-before-get-set-expected.txt
@@ -4,192 +4,88 @@
 
 Test getting grid-column-start and grid-row-start set through CSS
 PASS getComputedStyle(gridElement, '').getPropertyValue('grid-column-start') is 'auto'
-PASS getComputedStyle(gridElement, '').getPropertyValue('grid-column') is 'auto / auto'
+PASS getComputedStyle(gridElement, '').getPropertyValue('grid-column') is 'auto'
 PASS getComputedStyle(gridElement, '').getPropertyValue('grid-row-start') is 'auto'
-PASS getComputedStyle(gridElement, '').getPropertyValue('grid-row') is 'auto / auto'
-PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-column') is "10 / auto"
-PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-column-start') is "10"
-PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-row') is "15 / auto"
-PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-row-start') is "15"
-PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-column') is "-10 / auto"
-PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-column-start') is "-10"
-PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-row') is "-15 / auto"
-PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-row-start') is "-15"
-PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithBeforeSpan, '').getPropertyValue('grid-column') is "span 2 / auto"
-PASS getComputedStyle(gridItemWithBeforeSpan, '').getPropertyValue('grid-column-start') is "span 2"
-PASS getComputedStyle(gridItemWithBeforeSpan, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithBeforeSpan, '').getPropertyValue('grid-row') is "span 8 / auto"
-PASS getComputedStyle(gridItemWithBeforeSpan, '').getPropertyValue('grid-row-start') is "span 8"
-PASS getComputedStyle(gridItemWithBeforeSpan, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithAfterSpan, '').getPropertyValue('grid-column') is "span 2 / auto"
-PASS getComputedStyle(gridItemWithAfterSpan, '').getPropertyValue('grid-column-start') is "span 2"
-PASS getComputedStyle(gridItemWithAfterSpan, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithAfterSpan, '').getPropertyValue('grid-row') is "span 8 / auto"
-PASS getComputedStyle(gridItemWithAfterSpan, '').getPropertyValue('grid-row-start') is "span 8"
-PASS getComputedStyle(gridItemWithAfterSpan, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-column') is "first / auto"
-PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-column-start') is "first"
-PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-row') is "last / auto"
-PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-row-start') is "last"
-PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithNumberCustomIdent, '').getPropertyValue('grid-column') is "2 first / auto"
-PASS getComputedStyle(gridItemWithNumberCustomIdent, '').getPropertyValue('grid-column-start') is "2 first"
-PASS getComputedStyle(gridItemWithNumberCustomIdent, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithNumberCustomIdent, '').getPropertyValue('grid-row') is "3 last / auto"
-PASS getComputedStyle(gridItemWithNumberCustomIdent, '').getPropertyValue('grid-row-start') is "3 last"
-PASS getComputedStyle(gridItemWithNumberCustomIdent, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithSpanCustomIdentElement, '').getPropertyValue('grid-column') is "span first / auto"
-PASS getComputedStyle(gridItemWithSpanCustomIdentElement, '').getPropertyValue('grid-column-start') is "span first"
-PASS getComputedStyle(gridItemWithSpanCustomIdentElement, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithSpanCustomIdentElement, '').getPropertyValue('grid-row') is "span last / auto"
-PASS getComputedStyle(gridItemWithSpanCustomIdentElement, '').getPropertyValue('grid-row-start') is "span last"
-PASS getComputedStyle(gridItemWithSpanCustomIdentElement, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithSpanNumberCustomIdentElement, '').getPropertyValue('grid-column') is "span 2 first / auto"
-PASS getComputedStyle(gridItemWithSpanNumberCustomIdentElement, '').getPropertyValue('grid-column-start') is "span 2 first"
-PASS getComputedStyle(gridItemWithSpanNumberCustomIdentElement, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithSpanNumberCustomIdentElement, '').getPropertyValue('grid-row') is "span 3 last / auto"
-PASS getComputedStyle(gridItemWithSpanNumberCustomIdentElement, '').getPropertyValue('grid-row-start') is "span 3 last"
-PASS getComputedStyle(gridItemWithSpanNumberCustomIdentElement, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItemWithArea, '').getPropertyValue('grid-column') is "firstArea / auto"
-PASS getComputedStyle(gridItemWithArea, '').getPropertyValue('grid-column-start') is "firstArea"
-PASS getComputedStyle(gridItemWithArea, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItemWithArea, '').getPropertyValue('grid-row') is "thirdArea / auto"
-PASS getComputedStyle(gridItemWithArea, '').getPropertyValue('grid-row-start') is "thirdArea"
-PASS getComputedStyle(gridItemWithArea, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(gridElement, '').getPropertyValue('grid-row') is 'auto'
+PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-column') is "10"
+PASS getComputedStyle(gridItemWithPositiveInteger, '').getPropertyValue('grid-row') is "15"
+PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-column') is "-10"
+PASS getComputedStyle(gridItemWithNegativeInteger, '').getPropertyValue('grid-row') is "-15"
+PASS getComputedStyle(gridItemWithBeforeSpan, '').getPropertyValue('grid-column') is "span 2"
+PASS getComputedStyle(gridItemWithBeforeSpan, '').getPropertyValue('grid-row') is "span 8"
+PASS getComputedStyle(gridItemWithAfterSpan, '').getPropertyValue('grid-column') is "span 2"
+PASS getComputedStyle(gridItemWithAfterSpan, '').getPropertyValue('grid-row') is "span 8"
+PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItemWithOnlySpan, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItemWithAutoElement, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-column') is "first"
+PASS getComputedStyle(gridItemWithCustomIdent, '').getPropertyValue('grid-row') is "last"
+PASS getComputedStyle(gridItemWithNumberCustomIdent, '').getPropertyValue('grid-column') is "2 first"
+PASS getComputedStyle(gridItemWithNumberCustomIdent, '').getPropertyValue('grid-row') is "3 last"
+PASS getComputedStyle(gridItemWithSpanCustomIdentElement, '').getPropertyValue('grid-column') is "span first"
+PASS getComputedStyle(gridItemWithSpanCustomIdentElement, '').getPropertyValue('grid-row') is "span last"
+PASS getComputedStyle(gridItemWithSpanNumberCustomIdentElement, '').getPropertyValue('grid-column') is "span 2 first"
+PASS getComputedStyle(gridItemWithSpanNumberCustomIdentElement, '').getPropertyValue('grid-row') is "span 3 last"
+PASS getComputedStyle(gridItemWithArea, '').getPropertyValue('grid-column') is "firstArea"
+PASS getComputedStyle(gridItemWithArea, '').getPropertyValue('grid-row') is "thirdArea"
 
 
 Test the initial value
 PASS getComputedStyle(element, '').getPropertyValue('grid-column-start') is 'auto'
-PASS getComputedStyle(element, '').getPropertyValue('grid-column') is 'auto / auto'
+PASS getComputedStyle(element, '').getPropertyValue('grid-column') is 'auto'
 PASS getComputedStyle(element, '').getPropertyValue('grid-row-start') is 'auto'
-PASS getComputedStyle(element, '').getPropertyValue('grid-row') is 'auto / auto'
+PASS getComputedStyle(element, '').getPropertyValue('grid-row') is 'auto'
 
 
 Test getting and setting grid-column-start and grid-row-start through JS
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "18 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "18"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "66 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "66"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "-55 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "-55"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "-40 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "-40"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "nav / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "nav"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "last / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "span 3 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "span 3"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 20 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span 20"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "span nav / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "span nav"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span last / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span last"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "thirdArea / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "thirdArea"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "secondArea / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "secondArea"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "nonExistentArea / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "nonExistentArea"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "secondArea / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "secondArea"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "secondArea / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "secondArea"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "nonExistentArea / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "nonExistentArea"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "18"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "66"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "-55"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "-40"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "nav"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "last"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "span 3"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 20"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "span nav"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span last"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "thirdArea"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "secondArea"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "nonExistentArea"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "secondArea"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "secondArea"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "nonExistentArea"
 
 
 Test setting grid-column-start and grid-row-start to 'inherit' through JS
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "6 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "6"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "18 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "18"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "2 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "2"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 1 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span 1"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "6 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "6"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 1 / auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span 1"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "6"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "18"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "2"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 1"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "6"
+PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 1"
 
 
 Test setting grid-column-start and grid-row-start to 'initial' through JS
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "1 / span 2"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "1"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "span 2"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 3 / 5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span 3"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "5"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / span 2"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "span 2"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "span 3 / 5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "span 3"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "5"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column') is "auto / span 2"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-column-end') is "span 2"
 PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row') is "auto / 5"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(gridItem, '').getPropertyValue('grid-row-end') is "5"
 
 
 Test setting grid-column-start and grid-row-start back to 'auto' through JS
 PASS getComputedStyle(element, '').getPropertyValue('grid-column-start') is '18'
-PASS getComputedStyle(element, '').getPropertyValue('grid-column') is '18 / auto'
+PASS getComputedStyle(element, '').getPropertyValue('grid-column') is '18'
 PASS getComputedStyle(element, '').getPropertyValue('grid-row-start') is '66'
-PASS getComputedStyle(element, '').getPropertyValue('grid-row') is '66 / auto'
+PASS getComputedStyle(element, '').getPropertyValue('grid-row') is '66'
 PASS getComputedStyle(element, '').getPropertyValue('grid-column-start') is 'auto'
-PASS getComputedStyle(element, '').getPropertyValue('grid-column') is 'auto / auto'
+PASS getComputedStyle(element, '').getPropertyValue('grid-column') is 'auto'
 PASS getComputedStyle(element, '').getPropertyValue('grid-row-start') is 'auto'
-PASS getComputedStyle(element, '').getPropertyValue('grid-row') is 'auto / auto'
+PASS getComputedStyle(element, '').getPropertyValue('grid-row') is 'auto'
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/grid-item-start-before-get-set.html b/third_party/blink/web_tests/fast/css-grid-layout/grid-item-start-before-get-set.html
index 1c8a3e7b..929325e 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/grid-item-start-before-get-set.html
+++ b/third_party/blink/web_tests/fast/css-grid-layout/grid-item-start-before-get-set.html
@@ -78,30 +78,30 @@
     debug("Test getting grid-column-start and grid-row-start set through CSS");
     var gridElement = document.getElementById("gridElement");
     shouldBe("getComputedStyle(gridElement, '').getPropertyValue('grid-column-start')", "'auto'");
-    shouldBe("getComputedStyle(gridElement, '').getPropertyValue('grid-column')", "'auto / auto'");
+    shouldBe("getComputedStyle(gridElement, '').getPropertyValue('grid-column')", "'auto'");
     shouldBe("getComputedStyle(gridElement, '').getPropertyValue('grid-row-start')", "'auto'");
-    shouldBe("getComputedStyle(gridElement, '').getPropertyValue('grid-row')", "'auto / auto'");
+    shouldBe("getComputedStyle(gridElement, '').getPropertyValue('grid-row')", "'auto'");
 
-    testColumnRowCSSParsing("gridItemWithPositiveInteger", "10 / auto", "15 / auto");
-    testColumnRowCSSParsing("gridItemWithNegativeInteger", "-10 / auto", "-15 / auto");
-    testColumnRowCSSParsing("gridItemWithBeforeSpan", "span 2 / auto", "span 8 / auto");
-    testColumnRowCSSParsing("gridItemWithAfterSpan", "span 2 / auto", "span 8 / auto");
-    testColumnRowCSSParsing("gridItemWithOnlySpan", "auto / auto", "auto / auto");
-    testColumnRowCSSParsing("gridItemWithAutoElement", "auto / auto", "auto / auto");
-    testColumnRowCSSParsing("gridItemWithCustomIdent", "first / auto", "last / auto");
-    testColumnRowCSSParsing("gridItemWithNumberCustomIdent", "2 first / auto", "3 last / auto");
-    testColumnRowCSSParsing("gridItemWithSpanCustomIdentElement", "span first / auto", "span last / auto");
-    testColumnRowCSSParsing("gridItemWithSpanNumberCustomIdentElement", "span 2 first / auto", "span 3 last / auto");
-    testColumnRowCSSParsing("gridItemWithArea", "firstArea / auto", "thirdArea / auto");
+    testColumnRowCSSParsing("gridItemWithPositiveInteger", "10", "15");
+    testColumnRowCSSParsing("gridItemWithNegativeInteger", "-10", "-15");
+    testColumnRowCSSParsing("gridItemWithBeforeSpan", "span 2", "span 8");
+    testColumnRowCSSParsing("gridItemWithAfterSpan", "span 2", "span 8");
+    testColumnRowCSSParsing("gridItemWithOnlySpan", "auto", "auto");
+    testColumnRowCSSParsing("gridItemWithAutoElement", "auto", "auto");
+    testColumnRowCSSParsing("gridItemWithCustomIdent", "first", "last");
+    testColumnRowCSSParsing("gridItemWithNumberCustomIdent", "2 first", "3 last");
+    testColumnRowCSSParsing("gridItemWithSpanCustomIdentElement", "span first", "span last");
+    testColumnRowCSSParsing("gridItemWithSpanNumberCustomIdentElement", "span 2 first", "span 3 last");
+    testColumnRowCSSParsing("gridItemWithArea", "firstArea", "thirdArea");
 
     debug("");
     debug("Test the initial value");
     var element = document.createElement("div");
     document.body.appendChild(element);
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column-start')", "'auto'");
-    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column')", "'auto / auto'");
+    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column')", "'auto'");
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row-start')", "'auto'");
-    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row')", "'auto / auto'");
+    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row')", "'auto'");
 
     debug("");
     debug("Test getting and setting grid-column-start and grid-row-start through JS");
@@ -130,15 +130,15 @@
     element.style.gridColumnStart = "18";
     element.style.gridRowStart = "66";
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column-start')", "'18'");
-    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column')", "'18 / auto'");
+    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column')", "'18'");
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row-start')", "'66'");
-    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row')", "'66 / auto'");
+    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row')", "'66'");
     element.style.gridColumnStart = "auto";
     element.style.gridRowStart = "auto";
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column-start')", "'auto'");
-    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column')", "'auto / auto'");
+    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-column')", "'auto'");
     shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row-start')", "'auto'");
-    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row')", "'auto / auto'");
+    shouldBe("getComputedStyle(element, '').getPropertyValue('grid-row')", "'auto'");
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/grid-shorthands-style-format-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/grid-shorthands-style-format-expected.txt
index c278ea5..27d926a 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/grid-shorthands-style-format-expected.txt
+++ b/third_party/blink/web_tests/fast/css-grid-layout/grid-shorthands-style-format-expected.txt
@@ -17,13 +17,13 @@
 PASS item.style.gridRow is "foo / span bar"
 PASS item.style.gridRow is "2 foo / span 3 bar"
 Test grid-area shorthand
-PASS item.style.gridArea is "1 / auto / auto / auto"
-PASS item.style.gridArea is "1 / 3 / auto / auto"
-PASS item.style.gridArea is "1 / span 2 / auto / auto"
+PASS item.style.gridArea is "1"
+PASS item.style.gridArea is "1 / 3"
+PASS item.style.gridArea is "1 / span 2"
 PASS item.style.gridArea is "foo / foo / foo / foo"
 PASS item.style.gridArea is "foo / bar / foo / bar"
-PASS item.style.gridArea is "2 foo / span 3 bar / auto / auto"
-PASS item.style.gridArea is "1 / 2 / 3 / auto"
+PASS item.style.gridArea is "2 foo / span 3 bar"
+PASS item.style.gridArea is "1 / 2 / 3"
 PASS item.style.gridArea is "1 / 3 / 2 / 4"
 PASS item.style.gridArea is "1 / span 2 / 1 / span 2"
 PASS item.style.gridArea is "foo / bar / baz / qux"
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/grid-shorthands-style-format.html b/third_party/blink/web_tests/fast/css-grid-layout/grid-shorthands-style-format.html
index 719f5326..f05075c 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/grid-shorthands-style-format.html
+++ b/third_party/blink/web_tests/fast/css-grid-layout/grid-shorthands-style-format.html
@@ -39,19 +39,19 @@
 
     debug("Test grid-area shorthand");
     item.style.gridArea = "1";
-    shouldBeEqualToString("item.style.gridArea", "1 / auto / auto / auto");
+    shouldBeEqualToString("item.style.gridArea", "1");
     item.style.gridArea = "1 / 3";
-    shouldBeEqualToString("item.style.gridArea", "1 / 3 / auto / auto");
+    shouldBeEqualToString("item.style.gridArea", "1 / 3");
     item.style.gridArea = "1 / span 2";
-    shouldBeEqualToString("item.style.gridArea", "1 / span 2 / auto / auto");
+    shouldBeEqualToString("item.style.gridArea", "1 / span 2");
     item.style.gridArea = "foo / foo";
     shouldBeEqualToString("item.style.gridArea", "foo / foo / foo / foo");
     item.style.gridArea = "foo / bar";
     shouldBeEqualToString("item.style.gridArea", "foo / bar / foo / bar");
     item.style.gridArea = "2 foo / span 3 bar";
-    shouldBeEqualToString("item.style.gridArea", "2 foo / span 3 bar / auto / auto");
+    shouldBeEqualToString("item.style.gridArea", "2 foo / span 3 bar");
     item.style.gridArea = "1 / 2 / 3";
-    shouldBeEqualToString("item.style.gridArea", "1 / 2 / 3 / auto");
+    shouldBeEqualToString("item.style.gridArea", "1 / 2 / 3");
     item.style.gridArea = "1 / 3 / 2 / 4";
     shouldBeEqualToString("item.style.gridArea", "1 / 3 / 2 / 4");
     item.style.gridArea = "1 / span 2 / 1 / span 2";
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/named-grid-lines-with-named-grid-areas-get-set-expected.txt b/third_party/blink/web_tests/fast/css-grid-layout/named-grid-lines-with-named-grid-areas-get-set-expected.txt
index c6c90b4..41d9ddd 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/named-grid-lines-with-named-grid-areas-get-set-expected.txt
+++ b/third_party/blink/web_tests/fast/css-grid-layout/named-grid-lines-with-named-grid-areas-get-set-expected.txt
@@ -1,315 +1,107 @@
 PASS getComputedStyle(GridUniqueColumnB, '').getPropertyValue('grid-column') is "b / b"
-PASS getComputedStyle(GridUniqueColumnB, '').getPropertyValue('grid-column-start') is "b"
-PASS getComputedStyle(GridUniqueColumnB, '').getPropertyValue('grid-column-end') is "b"
-PASS getComputedStyle(GridUniqueColumnB, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridUniqueColumnB, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridUniqueColumnB, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(GridUniqueRowE, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridUniqueRowE, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridUniqueRowE, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(GridUniqueColumnB, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(GridUniqueRowE, '').getPropertyValue('grid-column') is "auto"
 PASS getComputedStyle(GridUniqueRowE, '').getPropertyValue('grid-row') is "e / e"
-PASS getComputedStyle(GridUniqueRowE, '').getPropertyValue('grid-row-start') is "e"
-PASS getComputedStyle(GridUniqueRowE, '').getPropertyValue('grid-row-end') is "e"
 PASS getComputedStyle(GridUniqueColumnBStart, '').getPropertyValue('grid-column') is "b-start / b-start"
-PASS getComputedStyle(GridUniqueColumnBStart, '').getPropertyValue('grid-column-start') is "b-start"
-PASS getComputedStyle(GridUniqueColumnBStart, '').getPropertyValue('grid-column-end') is "b-start"
-PASS getComputedStyle(GridUniqueColumnBStart, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridUniqueColumnBStart, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridUniqueColumnBStart, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(GridUniqueRowGStart, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridUniqueRowGStart, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridUniqueRowGStart, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(GridUniqueColumnBStart, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(GridUniqueRowGStart, '').getPropertyValue('grid-column') is "auto"
 PASS getComputedStyle(GridUniqueRowGStart, '').getPropertyValue('grid-row') is "g-start / g-start"
-PASS getComputedStyle(GridUniqueRowGStart, '').getPropertyValue('grid-row-start') is "g-start"
-PASS getComputedStyle(GridUniqueRowGStart, '').getPropertyValue('grid-row-end') is "g-start"
 PASS getComputedStyle(GridUniqueColumnBD, '').getPropertyValue('grid-column') is "b / d"
-PASS getComputedStyle(GridUniqueColumnBD, '').getPropertyValue('grid-column-start') is "b"
-PASS getComputedStyle(GridUniqueColumnBD, '').getPropertyValue('grid-column-end') is "d"
-PASS getComputedStyle(GridUniqueColumnBD, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridUniqueColumnBD, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridUniqueColumnBD, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(GridUniqueRowGH, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridUniqueRowGH, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridUniqueRowGH, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(GridUniqueColumnBD, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(GridUniqueRowGH, '').getPropertyValue('grid-column') is "auto"
 PASS getComputedStyle(GridUniqueRowGH, '').getPropertyValue('grid-row') is "g / h"
-PASS getComputedStyle(GridUniqueRowGH, '').getPropertyValue('grid-row-start') is "g"
-PASS getComputedStyle(GridUniqueRowGH, '').getPropertyValue('grid-row-end') is "h"
 PASS getComputedStyle(GridUniqueColumnCRowF, '').getPropertyValue('grid-column') is "c / c"
-PASS getComputedStyle(GridUniqueColumnCRowF, '').getPropertyValue('grid-column-start') is "c"
-PASS getComputedStyle(GridUniqueColumnCRowF, '').getPropertyValue('grid-column-end') is "c"
 PASS getComputedStyle(GridUniqueColumnCRowF, '').getPropertyValue('grid-row') is "f / f"
-PASS getComputedStyle(GridUniqueColumnCRowF, '').getPropertyValue('grid-row-start') is "f"
-PASS getComputedStyle(GridUniqueColumnCRowF, '').getPropertyValue('grid-row-end') is "f"
 PASS getComputedStyle(GridUniqueColumnBInteger, '').getPropertyValue('grid-column') is "b / 4"
-PASS getComputedStyle(GridUniqueColumnBInteger, '').getPropertyValue('grid-column-start') is "b"
-PASS getComputedStyle(GridUniqueColumnBInteger, '').getPropertyValue('grid-column-end') is "4"
-PASS getComputedStyle(GridUniqueColumnBInteger, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridUniqueColumnBInteger, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridUniqueColumnBInteger, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(GridUniqueRowIntegerH, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridUniqueRowIntegerH, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridUniqueRowIntegerH, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(GridUniqueColumnBInteger, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(GridUniqueRowIntegerH, '').getPropertyValue('grid-column') is "auto"
 PASS getComputedStyle(GridUniqueRowIntegerH, '').getPropertyValue('grid-row') is "3 / h"
-PASS getComputedStyle(GridUniqueRowIntegerH, '').getPropertyValue('grid-row-start') is "3"
-PASS getComputedStyle(GridUniqueRowIntegerH, '').getPropertyValue('grid-row-end') is "h"
-PASS getComputedStyle(GridUniqueColumnIntegerRowG, '').getPropertyValue('grid-column') is "2 / auto"
-PASS getComputedStyle(GridUniqueColumnIntegerRowG, '').getPropertyValue('grid-column-start') is "2"
-PASS getComputedStyle(GridUniqueColumnIntegerRowG, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(GridUniqueColumnIntegerRowG, '').getPropertyValue('grid-column') is "2"
 PASS getComputedStyle(GridUniqueColumnIntegerRowG, '').getPropertyValue('grid-row') is "g / g"
-PASS getComputedStyle(GridUniqueColumnIntegerRowG, '').getPropertyValue('grid-row-start') is "g"
-PASS getComputedStyle(GridUniqueColumnIntegerRowG, '').getPropertyValue('grid-row-end') is "g"
 PASS getComputedStyle(GridUniqueColumnARowInteger, '').getPropertyValue('grid-column') is "a / a"
-PASS getComputedStyle(GridUniqueColumnARowInteger, '').getPropertyValue('grid-column-start') is "a"
-PASS getComputedStyle(GridUniqueColumnARowInteger, '').getPropertyValue('grid-column-end') is "a"
-PASS getComputedStyle(GridUniqueColumnARowInteger, '').getPropertyValue('grid-row') is "2 / auto"
-PASS getComputedStyle(GridUniqueColumnARowInteger, '').getPropertyValue('grid-row-start') is "2"
-PASS getComputedStyle(GridUniqueColumnARowInteger, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(GridUniqueColumnARowInteger, '').getPropertyValue('grid-row') is "2"
 PASS getComputedStyle(GridUniqueColumnCStart, '').getPropertyValue('grid-column') is "c-start / c-start"
-PASS getComputedStyle(GridUniqueColumnCStart, '').getPropertyValue('grid-column-start') is "c-start"
-PASS getComputedStyle(GridUniqueColumnCStart, '').getPropertyValue('grid-column-end') is "c-start"
-PASS getComputedStyle(GridUniqueColumnCStart, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridUniqueColumnCStart, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridUniqueColumnCStart, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(GridUniqueRowFStart, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridUniqueRowFStart, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridUniqueRowFStart, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(GridUniqueColumnCStart, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(GridUniqueRowFStart, '').getPropertyValue('grid-column') is "auto"
 PASS getComputedStyle(GridUniqueRowFStart, '').getPropertyValue('grid-row') is "f-start / f-start"
-PASS getComputedStyle(GridUniqueRowFStart, '').getPropertyValue('grid-row-start') is "f-start"
-PASS getComputedStyle(GridUniqueRowFStart, '').getPropertyValue('grid-row-end') is "f-start"
 PASS getComputedStyle(GridUniqueColumnCStartRowFEnd, '').getPropertyValue('grid-column') is "c-start / c-start"
-PASS getComputedStyle(GridUniqueColumnCStartRowFEnd, '').getPropertyValue('grid-column-start') is "c-start"
-PASS getComputedStyle(GridUniqueColumnCStartRowFEnd, '').getPropertyValue('grid-column-end') is "c-start"
 PASS getComputedStyle(GridUniqueColumnCStartRowFEnd, '').getPropertyValue('grid-row') is "f-end / f-end"
-PASS getComputedStyle(GridUniqueColumnCStartRowFEnd, '').getPropertyValue('grid-row-start') is "f-end"
-PASS getComputedStyle(GridUniqueColumnCStartRowFEnd, '').getPropertyValue('grid-row-end') is "f-end"
 PASS getComputedStyle(GridUniqueColumnBEndRowHStart, '').getPropertyValue('grid-column') is "b-end / b-end"
-PASS getComputedStyle(GridUniqueColumnBEndRowHStart, '').getPropertyValue('grid-column-start') is "b-end"
-PASS getComputedStyle(GridUniqueColumnBEndRowHStart, '').getPropertyValue('grid-column-end') is "b-end"
 PASS getComputedStyle(GridUniqueColumnBEndRowHStart, '').getPropertyValue('grid-row') is "h-start / h-start"
-PASS getComputedStyle(GridUniqueColumnBEndRowHStart, '').getPropertyValue('grid-row-start') is "h-start"
-PASS getComputedStyle(GridUniqueColumnBEndRowHStart, '').getPropertyValue('grid-row-end') is "h-start"
 PASS getComputedStyle(GridAreasNoNamesColumnAStartRowDStart, '').getPropertyValue('grid-column') is "a-start / a-start"
-PASS getComputedStyle(GridAreasNoNamesColumnAStartRowDStart, '').getPropertyValue('grid-column-start') is "a-start"
-PASS getComputedStyle(GridAreasNoNamesColumnAStartRowDStart, '').getPropertyValue('grid-column-end') is "a-start"
 PASS getComputedStyle(GridAreasNoNamesColumnAStartRowDStart, '').getPropertyValue('grid-row') is "d-start / d-start"
-PASS getComputedStyle(GridAreasNoNamesColumnAStartRowDStart, '').getPropertyValue('grid-row-start') is "d-start"
-PASS getComputedStyle(GridAreasNoNamesColumnAStartRowDStart, '').getPropertyValue('grid-row-end') is "d-start"
 PASS getComputedStyle(GridAreasNoNamesColumnAStartRowD, '').getPropertyValue('grid-column') is "a-start / a-start"
-PASS getComputedStyle(GridAreasNoNamesColumnAStartRowD, '').getPropertyValue('grid-column-start') is "a-start"
-PASS getComputedStyle(GridAreasNoNamesColumnAStartRowD, '').getPropertyValue('grid-column-end') is "a-start"
 PASS getComputedStyle(GridAreasNoNamesColumnAStartRowD, '').getPropertyValue('grid-row') is "d / d"
-PASS getComputedStyle(GridAreasNoNamesColumnAStartRowD, '').getPropertyValue('grid-row-start') is "d"
-PASS getComputedStyle(GridAreasNoNamesColumnAStartRowD, '').getPropertyValue('grid-row-end') is "d"
 PASS getComputedStyle(GridAreasNoNamesColumnDStartRowCStart, '').getPropertyValue('grid-column') is "d-start / d-start"
-PASS getComputedStyle(GridAreasNoNamesColumnDStartRowCStart, '').getPropertyValue('grid-column-start') is "d-start"
-PASS getComputedStyle(GridAreasNoNamesColumnDStartRowCStart, '').getPropertyValue('grid-column-end') is "d-start"
 PASS getComputedStyle(GridAreasNoNamesColumnDStartRowCStart, '').getPropertyValue('grid-row') is "c-start / c-start"
-PASS getComputedStyle(GridAreasNoNamesColumnDStartRowCStart, '').getPropertyValue('grid-row-start') is "c-start"
-PASS getComputedStyle(GridAreasNoNamesColumnDStartRowCStart, '').getPropertyValue('grid-row-end') is "c-start"
 PASS getComputedStyle(GridAreasNoNamesColumnD, '').getPropertyValue('grid-column') is "d / d"
-PASS getComputedStyle(GridAreasNoNamesColumnD, '').getPropertyValue('grid-column-start') is "d"
-PASS getComputedStyle(GridAreasNoNamesColumnD, '').getPropertyValue('grid-column-end') is "d"
-PASS getComputedStyle(GridAreasNoNamesColumnD, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridAreasNoNamesColumnD, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridAreasNoNamesColumnD, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(GridAreasNoNamesRowD, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridAreasNoNamesRowD, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridAreasNoNamesRowD, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(GridAreasNoNamesColumnD, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(GridAreasNoNamesRowD, '').getPropertyValue('grid-column') is "auto"
 PASS getComputedStyle(GridAreasNoNamesRowD, '').getPropertyValue('grid-row') is "d / d"
-PASS getComputedStyle(GridAreasNoNamesRowD, '').getPropertyValue('grid-row-start') is "d"
-PASS getComputedStyle(GridAreasNoNamesRowD, '').getPropertyValue('grid-row-end') is "d"
 PASS getComputedStyle(GridAreasNoNamesColumnC, '').getPropertyValue('grid-column') is "c / c"
-PASS getComputedStyle(GridAreasNoNamesColumnC, '').getPropertyValue('grid-column-start') is "c"
-PASS getComputedStyle(GridAreasNoNamesColumnC, '').getPropertyValue('grid-column-end') is "c"
-PASS getComputedStyle(GridAreasNoNamesColumnC, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridAreasNoNamesColumnC, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridAreasNoNamesColumnC, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(GridAreasNoNamesRowC, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridAreasNoNamesRowC, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridAreasNoNamesRowC, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(GridAreasNoNamesColumnC, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(GridAreasNoNamesRowC, '').getPropertyValue('grid-column') is "auto"
 PASS getComputedStyle(GridAreasNoNamesRowC, '').getPropertyValue('grid-row') is "c / c"
-PASS getComputedStyle(GridAreasNoNamesRowC, '').getPropertyValue('grid-row-start') is "c"
-PASS getComputedStyle(GridAreasNoNamesRowC, '').getPropertyValue('grid-row-end') is "c"
 PASS getComputedStyle(GridAreasNoNamesColumnA, '').getPropertyValue('grid-column') is "a / a"
-PASS getComputedStyle(GridAreasNoNamesColumnA, '').getPropertyValue('grid-column-start') is "a"
-PASS getComputedStyle(GridAreasNoNamesColumnA, '').getPropertyValue('grid-column-end') is "a"
-PASS getComputedStyle(GridAreasNoNamesColumnA, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridAreasNoNamesColumnA, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridAreasNoNamesColumnA, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(GridAreasNoNamesRowA, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridAreasNoNamesRowA, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridAreasNoNamesRowA, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(GridAreasNoNamesColumnA, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(GridAreasNoNamesRowA, '').getPropertyValue('grid-column') is "auto"
 PASS getComputedStyle(GridAreasNoNamesRowA, '').getPropertyValue('grid-row') is "a / a"
-PASS getComputedStyle(GridAreasNoNamesRowA, '').getPropertyValue('grid-row-start') is "a"
-PASS getComputedStyle(GridAreasNoNamesRowA, '').getPropertyValue('grid-row-end') is "a"
 PASS getComputedStyle(GridAreasNoNamesColumnARowA, '').getPropertyValue('grid-column') is "a / a"
-PASS getComputedStyle(GridAreasNoNamesColumnARowA, '').getPropertyValue('grid-column-start') is "a"
-PASS getComputedStyle(GridAreasNoNamesColumnARowA, '').getPropertyValue('grid-column-end') is "a"
 PASS getComputedStyle(GridAreasNoNamesColumnARowA, '').getPropertyValue('grid-row') is "a / a"
-PASS getComputedStyle(GridAreasNoNamesColumnARowA, '').getPropertyValue('grid-row-start') is "a"
-PASS getComputedStyle(GridAreasNoNamesColumnARowA, '').getPropertyValue('grid-row-end') is "a"
 PASS getComputedStyle(GridAreasNamedLineAfterColumnD, '').getPropertyValue('grid-column') is "d / d"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnD, '').getPropertyValue('grid-column-start') is "d"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnD, '').getPropertyValue('grid-column-end') is "d"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnD, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnD, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnD, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(GridAreasNamedLineAfterRowD, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridAreasNamedLineAfterRowD, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridAreasNamedLineAfterRowD, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(GridAreasNamedLineAfterColumnD, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(GridAreasNamedLineAfterRowD, '').getPropertyValue('grid-column') is "auto"
 PASS getComputedStyle(GridAreasNamedLineAfterRowD, '').getPropertyValue('grid-row') is "d / d"
-PASS getComputedStyle(GridAreasNamedLineAfterRowD, '').getPropertyValue('grid-row-start') is "d"
-PASS getComputedStyle(GridAreasNamedLineAfterRowD, '').getPropertyValue('grid-row-end') is "d"
 PASS getComputedStyle(GridAreasNamedLineAfterColumnC, '').getPropertyValue('grid-column') is "c / c"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnC, '').getPropertyValue('grid-column-start') is "c"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnC, '').getPropertyValue('grid-column-end') is "c"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnC, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnC, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnC, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(GridAreasNamedLineAfterRowC, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridAreasNamedLineAfterRowC, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridAreasNamedLineAfterRowC, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(GridAreasNamedLineAfterColumnC, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(GridAreasNamedLineAfterRowC, '').getPropertyValue('grid-column') is "auto"
 PASS getComputedStyle(GridAreasNamedLineAfterRowC, '').getPropertyValue('grid-row') is "c / c"
-PASS getComputedStyle(GridAreasNamedLineAfterRowC, '').getPropertyValue('grid-row-start') is "c"
-PASS getComputedStyle(GridAreasNamedLineAfterRowC, '').getPropertyValue('grid-row-end') is "c"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnStartAStart, '').getPropertyValue('grid-column') is "a-start / auto"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnStartAStart, '').getPropertyValue('grid-column-start') is "a-start"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnStartAStart, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnStartAStart, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnStartAStart, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnStartAStart, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(GridAreasNamedLineAfterRowStartCStart, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridAreasNamedLineAfterRowStartCStart, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridAreasNamedLineAfterRowStartCStart, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(GridAreasNamedLineAfterRowStartCStart, '').getPropertyValue('grid-row') is "c-start / auto"
-PASS getComputedStyle(GridAreasNamedLineAfterRowStartCStart, '').getPropertyValue('grid-row-start') is "c-start"
-PASS getComputedStyle(GridAreasNamedLineAfterRowStartCStart, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(GridAreasNamedLineAfterColumnStartAStart, '').getPropertyValue('grid-column') is "a-start"
+PASS getComputedStyle(GridAreasNamedLineAfterColumnStartAStart, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(GridAreasNamedLineAfterRowStartCStart, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(GridAreasNamedLineAfterRowStartCStart, '').getPropertyValue('grid-row') is "c-start"
 PASS getComputedStyle(GridAreasNamedLineAfterColumnA, '').getPropertyValue('grid-column') is "a / a"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnA, '').getPropertyValue('grid-column-start') is "a"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnA, '').getPropertyValue('grid-column-end') is "a"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnA, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnA, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnA, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(GridAreasNamedLineAfterColumnA, '').getPropertyValue('grid-row') is "auto"
 PASS getComputedStyle(GridAreasNamedLineAfterColumnARowD, '').getPropertyValue('grid-column') is "a / a"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnARowD, '').getPropertyValue('grid-column-start') is "a"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnARowD, '').getPropertyValue('grid-column-end') is "a"
 PASS getComputedStyle(GridAreasNamedLineAfterColumnARowD, '').getPropertyValue('grid-row') is "d / d"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnARowD, '').getPropertyValue('grid-row-start') is "d"
-PASS getComputedStyle(GridAreasNamedLineAfterColumnARowD, '').getPropertyValue('grid-row-end') is "d"
 PASS getComputedStyle(GridAreasNamedLineBeforeColumnD, '').getPropertyValue('grid-column') is "d / d"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnD, '').getPropertyValue('grid-column-start') is "d"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnD, '').getPropertyValue('grid-column-end') is "d"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnD, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnD, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnD, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowD, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowD, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowD, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(GridAreasNamedLineBeforeColumnD, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(GridAreasNamedLineBeforeRowD, '').getPropertyValue('grid-column') is "auto"
 PASS getComputedStyle(GridAreasNamedLineBeforeRowD, '').getPropertyValue('grid-row') is "d / d"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowD, '').getPropertyValue('grid-row-start') is "d"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowD, '').getPropertyValue('grid-row-end') is "d"
 PASS getComputedStyle(GridAreasNamedLineBeforeColumnC, '').getPropertyValue('grid-column') is "c / c"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnC, '').getPropertyValue('grid-column-start') is "c"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnC, '').getPropertyValue('grid-column-end') is "c"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnC, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnC, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnC, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowC, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowC, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowC, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(GridAreasNamedLineBeforeColumnC, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(GridAreasNamedLineBeforeRowC, '').getPropertyValue('grid-column') is "auto"
 PASS getComputedStyle(GridAreasNamedLineBeforeRowC, '').getPropertyValue('grid-row') is "c / c"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowC, '').getPropertyValue('grid-row-start') is "c"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowC, '').getPropertyValue('grid-row-end') is "c"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnStartDStart, '').getPropertyValue('grid-column') is "d-start / auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnStartDStart, '').getPropertyValue('grid-column-start') is "d-start"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnStartDStart, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnStartDStart, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnStartDStart, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnStartDStart, '').getPropertyValue('grid-row-end') is "auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowStartDStart, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowStartDStart, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowStartDStart, '').getPropertyValue('grid-column-end') is "auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowStartDStart, '').getPropertyValue('grid-row') is "d-start / auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowStartDStart, '').getPropertyValue('grid-row-start') is "d-start"
-PASS getComputedStyle(GridAreasNamedLineBeforeRowStartDStart, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(GridAreasNamedLineBeforeColumnStartDStart, '').getPropertyValue('grid-column') is "d-start"
+PASS getComputedStyle(GridAreasNamedLineBeforeColumnStartDStart, '').getPropertyValue('grid-row') is "auto"
+PASS getComputedStyle(GridAreasNamedLineBeforeRowStartDStart, '').getPropertyValue('grid-column') is "auto"
+PASS getComputedStyle(GridAreasNamedLineBeforeRowStartDStart, '').getPropertyValue('grid-row') is "d-start"
 PASS getComputedStyle(GridAreasNamedLineBeforeColumnA, '').getPropertyValue('grid-column') is "a / a"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnA, '').getPropertyValue('grid-column-start') is "a"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnA, '').getPropertyValue('grid-column-end') is "a"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnA, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnA, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnA, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(GridAreasNamedLineBeforeColumnA, '').getPropertyValue('grid-row') is "auto"
 PASS getComputedStyle(GridAreasNamedLineBeforeColumnARowD, '').getPropertyValue('grid-column') is "a / a"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnARowD, '').getPropertyValue('grid-column-start') is "a"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnARowD, '').getPropertyValue('grid-column-end') is "a"
 PASS getComputedStyle(GridAreasNamedLineBeforeColumnARowD, '').getPropertyValue('grid-row') is "d / d"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnARowD, '').getPropertyValue('grid-row-start') is "d"
-PASS getComputedStyle(GridAreasNamedLineBeforeColumnARowD, '').getPropertyValue('grid-row-end') is "d"
 PASS getComputedStyle(GridAreasNoNamesColumnAAStartRowDStart, '').getPropertyValue('grid-column') is "a / a-start"
-PASS getComputedStyle(GridAreasNoNamesColumnAAStartRowDStart, '').getPropertyValue('grid-column-start') is "a"
-PASS getComputedStyle(GridAreasNoNamesColumnAAStartRowDStart, '').getPropertyValue('grid-column-end') is "a-start"
 PASS getComputedStyle(GridAreasNoNamesColumnAAStartRowDStart, '').getPropertyValue('grid-row') is "d-start / d-start"
-PASS getComputedStyle(GridAreasNoNamesColumnAAStartRowDStart, '').getPropertyValue('grid-row-start') is "d-start"
-PASS getComputedStyle(GridAreasNoNamesColumnAAStartRowDStart, '').getPropertyValue('grid-row-end') is "d-start"
 PASS getComputedStyle(GridAreasNoNamesColumnDDStartRowCStart, '').getPropertyValue('grid-column') is "d / d-start"
-PASS getComputedStyle(GridAreasNoNamesColumnDDStartRowCStart, '').getPropertyValue('grid-column-start') is "d"
-PASS getComputedStyle(GridAreasNoNamesColumnDDStartRowCStart, '').getPropertyValue('grid-column-end') is "d-start"
 PASS getComputedStyle(GridAreasNoNamesColumnDDStartRowCStart, '').getPropertyValue('grid-row') is "c-start / c-start"
-PASS getComputedStyle(GridAreasNoNamesColumnDDStartRowCStart, '').getPropertyValue('grid-row-start') is "c-start"
-PASS getComputedStyle(GridAreasNoNamesColumnDDStartRowCStart, '').getPropertyValue('grid-row-end') is "c-start"
 PASS getComputedStyle(GridAreasNoNamesColumnCRowAAStart, '').getPropertyValue('grid-column') is "c / c"
-PASS getComputedStyle(GridAreasNoNamesColumnCRowAAStart, '').getPropertyValue('grid-column-start') is "c"
-PASS getComputedStyle(GridAreasNoNamesColumnCRowAAStart, '').getPropertyValue('grid-column-end') is "c"
 PASS getComputedStyle(GridAreasNoNamesColumnCRowAAStart, '').getPropertyValue('grid-row') is "a / a-start"
-PASS getComputedStyle(GridAreasNoNamesColumnCRowAAStart, '').getPropertyValue('grid-row-start') is "a"
-PASS getComputedStyle(GridAreasNoNamesColumnCRowAAStart, '').getPropertyValue('grid-row-end') is "a-start"
 PASS getComputedStyle(GridAreasNoNamesColumnDRowCCStart, '').getPropertyValue('grid-column') is "d / d"
-PASS getComputedStyle(GridAreasNoNamesColumnDRowCCStart, '').getPropertyValue('grid-column-start') is "d"
-PASS getComputedStyle(GridAreasNoNamesColumnDRowCCStart, '').getPropertyValue('grid-column-end') is "d"
 PASS getComputedStyle(GridAreasNoNamesColumnDRowCCStart, '').getPropertyValue('grid-row') is "c / c-start"
-PASS getComputedStyle(GridAreasNoNamesColumnDRowCCStart, '').getPropertyValue('grid-row-start') is "c"
-PASS getComputedStyle(GridAreasNoNamesColumnDRowCCStart, '').getPropertyValue('grid-row-end') is "c-start"
 PASS getComputedStyle(GridAreasEnd, '').getPropertyValue('grid-column') is "a / a"
-PASS getComputedStyle(GridAreasEnd, '').getPropertyValue('grid-column-start') is "a"
-PASS getComputedStyle(GridAreasEnd, '').getPropertyValue('grid-column-end') is "a"
-PASS getComputedStyle(GridAreasEnd, '').getPropertyValue('grid-row') is "auto / auto"
-PASS getComputedStyle(GridAreasEnd, '').getPropertyValue('grid-row-start') is "auto"
-PASS getComputedStyle(GridAreasEnd, '').getPropertyValue('grid-row-end') is "auto"
+PASS getComputedStyle(GridAreasEnd, '').getPropertyValue('grid-row') is "auto"
 PASS getComputedStyle(GridAreasEndColumnARowC, '').getPropertyValue('grid-column') is "a / a"
-PASS getComputedStyle(GridAreasEndColumnARowC, '').getPropertyValue('grid-column-start') is "a"
-PASS getComputedStyle(GridAreasEndColumnARowC, '').getPropertyValue('grid-column-end') is "a"
 PASS getComputedStyle(GridAreasEndColumnARowC, '').getPropertyValue('grid-row') is "c / c"
-PASS getComputedStyle(GridAreasEndColumnARowC, '').getPropertyValue('grid-row-start') is "c"
-PASS getComputedStyle(GridAreasEndColumnARowC, '').getPropertyValue('grid-row-end') is "c"
-PASS getComputedStyle(GridAreasEndRowD, '').getPropertyValue('grid-column') is "auto / auto"
-PASS getComputedStyle(GridAreasEndRowD, '').getPropertyValue('grid-column-start') is "auto"
-PASS getComputedStyle(GridAreasEndRowD, '').getPropertyValue('grid-column-end') is "auto"
+PASS getComputedStyle(GridAreasEndRowD, '').getPropertyValue('grid-column') is "auto"
 PASS getComputedStyle(GridAreasEndRowD, '').getPropertyValue('grid-row') is "d / d"
-PASS getComputedStyle(GridAreasEndRowD, '').getPropertyValue('grid-row-start') is "d"
-PASS getComputedStyle(GridAreasEndRowD, '').getPropertyValue('grid-row-end') is "d"
 PASS getComputedStyle(GridAreasEndColumnARowD, '').getPropertyValue('grid-column') is "a / a"
-PASS getComputedStyle(GridAreasEndColumnARowD, '').getPropertyValue('grid-column-start') is "a"
-PASS getComputedStyle(GridAreasEndColumnARowD, '').getPropertyValue('grid-column-end') is "a"
 PASS getComputedStyle(GridAreasEndColumnARowD, '').getPropertyValue('grid-row') is "d / d"
-PASS getComputedStyle(GridAreasEndColumnARowD, '').getPropertyValue('grid-row-start') is "d"
-PASS getComputedStyle(GridAreasEndColumnARowD, '').getPropertyValue('grid-row-end') is "d"
 PASS getComputedStyle(GridAreasRepeatColumnDRowC, '').getPropertyValue('grid-column') is "d / d"
-PASS getComputedStyle(GridAreasRepeatColumnDRowC, '').getPropertyValue('grid-column-start') is "d"
-PASS getComputedStyle(GridAreasRepeatColumnDRowC, '').getPropertyValue('grid-column-end') is "d"
 PASS getComputedStyle(GridAreasRepeatColumnDRowC, '').getPropertyValue('grid-row') is "c / c"
-PASS getComputedStyle(GridAreasRepeatColumnDRowC, '').getPropertyValue('grid-row-start') is "c"
-PASS getComputedStyle(GridAreasRepeatColumnDRowC, '').getPropertyValue('grid-row-end') is "c"
 PASS getComputedStyle(GridAreasRepeatColumnDStartDEndRowCStartCEnd, '').getPropertyValue('grid-column') is "d-start / d-end"
-PASS getComputedStyle(GridAreasRepeatColumnDStartDEndRowCStartCEnd, '').getPropertyValue('grid-column-start') is "d-start"
-PASS getComputedStyle(GridAreasRepeatColumnDStartDEndRowCStartCEnd, '').getPropertyValue('grid-column-end') is "d-end"
 PASS getComputedStyle(GridAreasRepeatColumnDStartDEndRowCStartCEnd, '').getPropertyValue('grid-row') is "c-start / c-end"
-PASS getComputedStyle(GridAreasRepeatColumnDStartDEndRowCStartCEnd, '').getPropertyValue('grid-row-start') is "c-start"
-PASS getComputedStyle(GridAreasRepeatColumnDStartDEndRowCStartCEnd, '').getPropertyValue('grid-row-end') is "c-end"
 PASS getComputedStyle(GridAreasRepeatColumnCRowD, '').getPropertyValue('grid-column') is "c / c"
-PASS getComputedStyle(GridAreasRepeatColumnCRowD, '').getPropertyValue('grid-column-start') is "c"
-PASS getComputedStyle(GridAreasRepeatColumnCRowD, '').getPropertyValue('grid-column-end') is "c"
 PASS getComputedStyle(GridAreasRepeatColumnCRowD, '').getPropertyValue('grid-row') is "d / d"
-PASS getComputedStyle(GridAreasRepeatColumnCRowD, '').getPropertyValue('grid-row-start') is "d"
-PASS getComputedStyle(GridAreasRepeatColumnCRowD, '').getPropertyValue('grid-row-end') is "d"
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/named-grid-lines-with-named-grid-areas-get-set.html b/third_party/blink/web_tests/fast/css-grid-layout/named-grid-lines-with-named-grid-areas-get-set.html
index a3a0758..fbaa9faa 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/named-grid-lines-with-named-grid-areas-get-set.html
+++ b/third_party/blink/web_tests/fast/css-grid-layout/named-grid-lines-with-named-grid-areas-get-set.html
@@ -187,22 +187,22 @@
 
 <script src="resources/grid-item-column-row-parsing-utils.js"></script>
 <script>
-  testColumnRowCSSParsing("GridUniqueColumnB", "b / b", "auto / auto");
-  testColumnRowCSSParsing("GridUniqueRowE", "auto / auto", "e / e");
-  testColumnRowCSSParsing("GridUniqueColumnBStart", "b-start / b-start", "auto / auto");
-  testColumnRowCSSParsing("GridUniqueRowGStart", "auto / auto", "g-start / g-start");
+  testColumnRowCSSParsing("GridUniqueColumnB", "b / b", "auto");
+  testColumnRowCSSParsing("GridUniqueRowE", "auto", "e / e");
+  testColumnRowCSSParsing("GridUniqueColumnBStart", "b-start / b-start", "auto");
+  testColumnRowCSSParsing("GridUniqueRowGStart", "auto", "g-start / g-start");
 
-  testColumnRowCSSParsing("GridUniqueColumnBD", "b / d", "auto / auto");
-  testColumnRowCSSParsing("GridUniqueRowGH", "auto / auto", "g / h");
+  testColumnRowCSSParsing("GridUniqueColumnBD", "b / d", "auto");
+  testColumnRowCSSParsing("GridUniqueRowGH", "auto", "g / h");
   testColumnRowCSSParsing("GridUniqueColumnCRowF", "c / c", "f / f");
 
-  testColumnRowCSSParsing("GridUniqueColumnBInteger", "b / 4", "auto / auto");
-  testColumnRowCSSParsing("GridUniqueRowIntegerH", "auto / auto", "3 / h");
-  testColumnRowCSSParsing("GridUniqueColumnIntegerRowG", "2 / auto", "g / g");
-  testColumnRowCSSParsing("GridUniqueColumnARowInteger", "a / a", "2 / auto");
+  testColumnRowCSSParsing("GridUniqueColumnBInteger", "b / 4", "auto");
+  testColumnRowCSSParsing("GridUniqueRowIntegerH", "auto", "3 / h");
+  testColumnRowCSSParsing("GridUniqueColumnIntegerRowG", "2", "g / g");
+  testColumnRowCSSParsing("GridUniqueColumnARowInteger", "a / a", "2");
 
-  testColumnRowCSSParsing("GridUniqueColumnCStart", "c-start / c-start", "auto / auto");
-  testColumnRowCSSParsing("GridUniqueRowFStart", "auto / auto", "f-start / f-start");
+  testColumnRowCSSParsing("GridUniqueColumnCStart", "c-start / c-start", "auto");
+  testColumnRowCSSParsing("GridUniqueRowFStart", "auto", "f-start / f-start");
   testColumnRowCSSParsing("GridUniqueColumnCStartRowFEnd", "c-start / c-start", "f-end / f-end");
   testColumnRowCSSParsing("GridUniqueColumnBEndRowHStart", "b-end / b-end", "h-start / h-start");
 
@@ -210,35 +210,35 @@
   testColumnRowCSSParsing("GridAreasNoNamesColumnAStartRowD", "a-start / a-start", "d / d");
   testColumnRowCSSParsing("GridAreasNoNamesColumnDStartRowCStart", "d-start / d-start", "c-start / c-start");
 
-  testColumnRowCSSParsing("GridAreasNoNamesColumnD", "d / d", "auto / auto");
-  testColumnRowCSSParsing("GridAreasNoNamesRowD", "auto / auto", "d / d");
-  testColumnRowCSSParsing("GridAreasNoNamesColumnC", "c / c", "auto / auto");
-  testColumnRowCSSParsing("GridAreasNoNamesRowC", "auto / auto", "c / c");
+  testColumnRowCSSParsing("GridAreasNoNamesColumnD", "d / d", "auto");
+  testColumnRowCSSParsing("GridAreasNoNamesRowD", "auto", "d / d");
+  testColumnRowCSSParsing("GridAreasNoNamesColumnC", "c / c", "auto");
+  testColumnRowCSSParsing("GridAreasNoNamesRowC", "auto", "c / c");
 
-  testColumnRowCSSParsing("GridAreasNoNamesColumnA", "a / a", "auto / auto");
-  testColumnRowCSSParsing("GridAreasNoNamesRowA", "auto / auto", "a / a");
+  testColumnRowCSSParsing("GridAreasNoNamesColumnA", "a / a", "auto");
+  testColumnRowCSSParsing("GridAreasNoNamesRowA", "auto", "a / a");
   testColumnRowCSSParsing("GridAreasNoNamesColumnARowA", "a / a", "a / a");
 
-  testColumnRowCSSParsing("GridAreasNamedLineAfterColumnD", "d / d", "auto / auto");
-  testColumnRowCSSParsing("GridAreasNamedLineAfterRowD", "auto / auto", "d / d");
-  testColumnRowCSSParsing("GridAreasNamedLineAfterColumnC", "c / c", "auto / auto");
-  testColumnRowCSSParsing("GridAreasNamedLineAfterRowC", "auto / auto", "c / c");
+  testColumnRowCSSParsing("GridAreasNamedLineAfterColumnD", "d / d", "auto");
+  testColumnRowCSSParsing("GridAreasNamedLineAfterRowD", "auto", "d / d");
+  testColumnRowCSSParsing("GridAreasNamedLineAfterColumnC", "c / c", "auto");
+  testColumnRowCSSParsing("GridAreasNamedLineAfterRowC", "auto", "c / c");
 
-  testColumnRowCSSParsing("GridAreasNamedLineAfterColumnStartAStart", "a-start / auto", "auto / auto");
-  testColumnRowCSSParsing("GridAreasNamedLineAfterRowStartCStart", "auto / auto", "c-start / auto");
+  testColumnRowCSSParsing("GridAreasNamedLineAfterColumnStartAStart", "a-start", "auto");
+  testColumnRowCSSParsing("GridAreasNamedLineAfterRowStartCStart", "auto", "c-start");
 
-  testColumnRowCSSParsing("GridAreasNamedLineAfterColumnA", "a / a", "auto / auto");
+  testColumnRowCSSParsing("GridAreasNamedLineAfterColumnA", "a / a", "auto");
   testColumnRowCSSParsing("GridAreasNamedLineAfterColumnARowD", "a / a", "d / d");
 
-  testColumnRowCSSParsing("GridAreasNamedLineBeforeColumnD", "d / d", "auto / auto");
-  testColumnRowCSSParsing("GridAreasNamedLineBeforeRowD", "auto / auto", "d / d");
-  testColumnRowCSSParsing("GridAreasNamedLineBeforeColumnC", "c / c", "auto / auto");
-  testColumnRowCSSParsing("GridAreasNamedLineBeforeRowC", "auto / auto", "c / c");
+  testColumnRowCSSParsing("GridAreasNamedLineBeforeColumnD", "d / d", "auto");
+  testColumnRowCSSParsing("GridAreasNamedLineBeforeRowD", "auto", "d / d");
+  testColumnRowCSSParsing("GridAreasNamedLineBeforeColumnC", "c / c", "auto");
+  testColumnRowCSSParsing("GridAreasNamedLineBeforeRowC", "auto", "c / c");
 
-  testColumnRowCSSParsing("GridAreasNamedLineBeforeColumnStartDStart", "d-start / auto", "auto / auto");
-  testColumnRowCSSParsing("GridAreasNamedLineBeforeRowStartDStart", "auto / auto", "d-start / auto");
+  testColumnRowCSSParsing("GridAreasNamedLineBeforeColumnStartDStart", "d-start", "auto");
+  testColumnRowCSSParsing("GridAreasNamedLineBeforeRowStartDStart", "auto", "d-start");
 
-  testColumnRowCSSParsing("GridAreasNamedLineBeforeColumnA", "a / a", "auto / auto");
+  testColumnRowCSSParsing("GridAreasNamedLineBeforeColumnA", "a / a", "auto");
   testColumnRowCSSParsing("GridAreasNamedLineBeforeColumnARowD", "a / a", "d / d");
 
   testColumnRowCSSParsing("GridAreasNoNamesColumnAAStartRowDStart", "a / a-start", "d-start / d-start");
@@ -246,9 +246,9 @@
   testColumnRowCSSParsing("GridAreasNoNamesColumnCRowAAStart", "c / c", "a / a-start");
   testColumnRowCSSParsing("GridAreasNoNamesColumnDRowCCStart", "d / d", "c / c-start");
 
-  testColumnRowCSSParsing("GridAreasEnd", "a / a", "auto / auto");
+  testColumnRowCSSParsing("GridAreasEnd", "a / a", "auto");
   testColumnRowCSSParsing("GridAreasEndColumnARowC", "a / a", "c / c");
-  testColumnRowCSSParsing("GridAreasEndRowD", "auto / auto", "d / d");
+  testColumnRowCSSParsing("GridAreasEndRowD", "auto", "d / d");
   testColumnRowCSSParsing("GridAreasEndColumnARowD", "a / a", "d / d");
 
   testColumnRowCSSParsing("GridAreasRepeatColumnDRowC", "d / d", "c / c");
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/resources/grid-item-column-row-parsing-utils.js b/third_party/blink/web_tests/fast/css-grid-layout/resources/grid-item-column-row-parsing-utils.js
index c4fb8a86..c843578 100644
--- a/third_party/blink/web_tests/fast/css-grid-layout/resources/grid-item-column-row-parsing-utils.js
+++ b/third_party/blink/web_tests/fast/css-grid-layout/resources/grid-item-column-row-parsing-utils.js
@@ -1,30 +1,30 @@
 (function() {
 
-function checkColumnRowValues(gridItem, columnValue, rowValue)
+function checkColumnRowValues(gridItem, columnValue, rowValue, columnStartValue, columnEndValue, rowStartValue, rowEndValue)
 {
     this.gridItem = gridItem;
     var gridItemId = gridItem.id ? gridItem.id : "gridItem";
 
-    var gridColumnStartEndValues = columnValue.split("/")
-    var gridColumnStartValue = gridColumnStartEndValues[0].trim();
-    var gridColumnEndValue = gridColumnStartEndValues[1].trim();
-
-    var gridRowStartEndValues = rowValue.split("/")
-    var gridRowStartValue = gridRowStartEndValues[0].trim();
-    var gridRowEndValue = gridRowStartEndValues[1].trim();
-
     shouldBeEqualToString("getComputedStyle(" + gridItemId + ", '').getPropertyValue('grid-column')", columnValue);
-    shouldBeEqualToString("getComputedStyle(" + gridItemId + ", '').getPropertyValue('grid-column-start')", gridColumnStartValue);
-    shouldBeEqualToString("getComputedStyle(" + gridItemId + ", '').getPropertyValue('grid-column-end')", gridColumnEndValue);
     shouldBeEqualToString("getComputedStyle(" + gridItemId + ", '').getPropertyValue('grid-row')", rowValue);
-    shouldBeEqualToString("getComputedStyle(" + gridItemId + ", '').getPropertyValue('grid-row-start')", gridRowStartValue);
-    shouldBeEqualToString("getComputedStyle(" + gridItemId + ", '').getPropertyValue('grid-row-end')", gridRowEndValue);
+    if (columnStartValue) {
+        shouldBeEqualToString("getComputedStyle(" + gridItemId + ", '').getPropertyValue('grid-column-start')", columnStartValue);
+    }
+    if (columnEndValue) {
+        shouldBeEqualToString("getComputedStyle(" + gridItemId + ", '').getPropertyValue('grid-column-end')", columnEndValue);
+    }
+    if (rowStartValue) {
+        shouldBeEqualToString("getComputedStyle(" + gridItemId + ", '').getPropertyValue('grid-row-start')", rowStartValue);
+    }
+    if (rowEndValue) {
+        shouldBeEqualToString("getComputedStyle(" + gridItemId + ", '').getPropertyValue('grid-row-end')", rowEndValue);
+    }
 }
 
-window.testColumnRowCSSParsing = function(id, columnValue, rowValue)
+window.testColumnRowCSSParsing = function(id, columnValue, rowValue, columnStartValue, columnEndValue, rowStartValue, rowEndValue)
 {
     var gridItem = document.getElementById(id);
-    checkColumnRowValues(gridItem, columnValue, rowValue);
+    checkColumnRowValues(gridItem, columnValue, rowValue, columnStartValue, columnEndValue, rowStartValue, rowEndValue);
 }
 
 window.testColumnRowJSParsing = function(columnValue, rowValue, expectedColumnValue, expectedRowValue)
@@ -35,7 +35,7 @@
     gridItem.style.gridColumn = columnValue;
     gridItem.style.gridRow = rowValue;
 
-    checkColumnRowValues(gridItem, expectedColumnValue ? expectedColumnValue : columnValue, expectedRowValue ? expectedRowValue : rowValue);
+    checkColumnRowValues(gridItem, expectedColumnValue, expectedRowValue);
 
     gridElement.removeChild(gridItem);
 }
@@ -53,7 +53,7 @@
     if (expectedRowStartValue === undefined)
         expectedRowStartValue = rowStartValue;
 
-    checkColumnRowValues(gridItem, expectedColumnStartValue + " / auto", expectedRowStartValue + " / auto");
+    checkColumnRowValues(gridItem, expectedColumnStartValue, expectedRowStartValue);
 
     gridElement.removeChild(gridItem);
 }
@@ -71,7 +71,10 @@
     if (expectedRowEndValue === undefined)
         expectedRowEndValue = rowEndValue;
 
-    checkColumnRowValues(gridItem, "auto / " + expectedColumnEndValue, "auto / " + expectedRowEndValue);
+    var expectedColumnValue = expectedColumnEndValue == "auto" ? expectedColumnEndValue : "auto / " + expectedColumnEndValue;
+    var expectedRowValue = expectedRowEndValue == "auto" ? expectedRowEndValue : "auto / " + expectedRowEndValue;
+
+    checkColumnRowValues(gridItem, expectedColumnValue, expectedRowValue);
 
     gridElement.removeChild(gridItem);
 }
@@ -83,7 +86,7 @@
     gridItem.style.gridColumn = columnValue;
     gridItem.style.gridRow = rowValue;
 
-    checkColumnRowValues(gridItem, "auto / auto", "auto / auto");
+    checkColumnRowValues(gridItem, "auto", "auto");
 
     document.body.removeChild(gridItem);
 }
@@ -145,8 +148,8 @@
     gridItem.style.gridRowStart = rowStartValue;
 
     // Initial value is 'auto' but we shouldn't touch the opposite grid line.
-    var columnValueForInherit = (columnStartValue !== "inherit" ? columnStartValue : placeholderParentColumnStartValueForInherit) + " / auto";
-    var rowValueForInherit = (rowStartValue !== "inherit" ? rowStartValue : placeholderParentRowStartValueForInherit) + " / auto";
+    var columnValueForInherit = (columnStartValue !== "inherit" ? columnStartValue : placeholderParentColumnStartValueForInherit);
+    var rowValueForInherit = (rowStartValue !== "inherit" ? rowStartValue : placeholderParentRowStartValueForInherit);
     checkColumnRowValues(parentElement.firstChild, columnValueForInherit, rowValueForInherit);
 
     document.body.removeChild(parentElement);
@@ -172,10 +175,10 @@
     var gridItem = setupInitialTest();
 
     gridItem.style.gridColumn = "initial";
-    checkColumnRowValues(gridItem, "auto / auto", placeholderRowValueForInitial);
+    checkColumnRowValues(gridItem, "auto", placeholderRowValueForInitial);
 
     gridItem.style.gridRow = "initial";
-    checkColumnRowValues(gridItem, "auto / auto", "auto / auto");
+    checkColumnRowValues(gridItem, "auto", "auto");
 
     document.body.removeChild(gridItem);
 }
@@ -198,10 +201,10 @@
     var gridItem = setupInitialTest();
 
     gridItem.style.gridColumnEnd = "initial";
-    checkColumnRowValues(gridItem, placeholderColumnStartValueForInitial + " / auto", placeholderRowValueForInitial);
+    checkColumnRowValues(gridItem, placeholderColumnStartValueForInitial, placeholderRowValueForInitial);
 
     gridItem.style.gridRowEnd = "initial";
-    checkColumnRowValues(gridItem, placeholderColumnStartValueForInitial + " / auto", placeholderRowStartValueForInitial + " / auto");
+    checkColumnRowValues(gridItem, placeholderColumnStartValueForInitial, placeholderRowStartValueForInitial);
 
     document.body.removeChild(gridItem);
 }
diff --git a/third_party/blink/web_tests/fast/forms/date/date-keyoperation.html b/third_party/blink/web_tests/fast/forms/date/date-keyoperation.html
index e99fa715..dd932b50 100644
--- a/third_party/blink/web_tests/fast/forms/date/date-keyoperation.html
+++ b/third_party/blink/web_tests/fast/forms/date/date-keyoperation.html
@@ -8,6 +8,21 @@
 function testKeyOperations(writingMode) {
     if (!window.eventSender)
         return;
+    let stepDownKey;
+    let stepUpKey;
+    let focusNextKey;
+    let focusPrevKey;
+    if (writingMode == "horizontal-tb") {
+      stepDownKey = 'ArrowDown';
+      stepUpKey = 'ArrowUp';
+      focusNextKey = 'ArrowRight';
+      focusPrevKey = 'ArrowLeft';
+    } else {
+      stepDownKey = 'ArrowLeft';
+      stepUpKey = 'ArrowRight';
+      focusNextKey = 'ArrowDown';
+      focusPrevKey = 'ArrowUp';
+    }
     test(() => {
         const input = document.createElement('input');
         document.body.appendChild(input);
@@ -17,12 +32,12 @@
         input.min = "2023-07-22";
         input.max = "2023-07-24";
         input.focus();
-        // Using arrow down goes to max value
-        eventSender.keyDown('ArrowDown');
+        // Using step down goes to max value
+        eventSender.keyDown(stepDownKey);
         assert_equals(input.value, "2023-07-24");
-        eventSender.keyDown('ArrowDown');
+        eventSender.keyDown(stepDownKey);
         assert_equals(input.value, "2023-07-23");
-        eventSender.keyDown('ArrowUp');
+        eventSender.keyDown(stepUpKey);
         assert_equals(input.value, "2023-07-24");
         document.body.removeChild(input);
     }, `input[type=date writing-mode=${writingMode}] key operations should respect max/min`);
@@ -34,17 +49,17 @@
         input.style.writingMode = writingMode;
         input.value = "2023-07-22";
         input.focus();
-        eventSender.keyDown('ArrowDown');
-        eventSender.keyDown('ArrowRight');
-        eventSender.keyDown('ArrowDown');
-        eventSender.keyDown('ArrowRight');
-        eventSender.keyDown('ArrowDown');
+        eventSender.keyDown(stepDownKey);
+        eventSender.keyDown(focusNextKey);
+        eventSender.keyDown(stepDownKey);
+        eventSender.keyDown(focusNextKey);
+        eventSender.keyDown(stepDownKey);
         assert_equals(input.value, "2022-06-21");
-        eventSender.keyDown('ArrowUp');
-        eventSender.keyDown('ArrowLeft');
-        eventSender.keyDown('ArrowUp');
-        eventSender.keyDown('ArrowLeft');
-        eventSender.keyDown('ArrowUp');
+        eventSender.keyDown(stepUpKey);
+        eventSender.keyDown(focusPrevKey);
+        eventSender.keyDown(stepUpKey);
+        eventSender.keyDown(focusPrevKey);
+        eventSender.keyDown(stepUpKey);
         assert_equals(input.value, "2023-07-22");
         document.body.removeChild(input);
     }, `input[type=date writing-mode=${writingMode}] key operations should move between DD/MM/YYYY`);
@@ -58,12 +73,12 @@
         input.min = "2023-W25";
         input.max = "2023-W27";
         input.focus();
-        eventSender.keyDown('ArrowDown');
+        eventSender.keyDown(stepDownKey);
         assert_equals(input.value, "2023-W25");
-        // Using arrow down goes to max value
-        eventSender.keyDown('ArrowDown');
+        // Using step down goes to max value
+        eventSender.keyDown(stepDownKey);
         assert_equals(input.value, "2023-W27");
-        eventSender.keyDown('ArrowUp');
+        eventSender.keyDown(stepUpKey);
         assert_equals(input.value, "2023-W25");
         document.body.removeChild(input);
     }, `input[type=week writing-mode=${writingMode}] key operations should respect max/min`);
@@ -75,13 +90,13 @@
         input.style.writingMode = writingMode;
         input.value = "2023-W10";
         input.focus();
-        eventSender.keyDown('ArrowDown');
-        eventSender.keyDown('ArrowRight');
-        eventSender.keyDown('ArrowDown');
+        eventSender.keyDown(stepDownKey);
+        eventSender.keyDown(focusNextKey);
+        eventSender.keyDown(stepDownKey);
         assert_equals(input.value, "2022-W09");
-        eventSender.keyDown('ArrowUp');
-        eventSender.keyDown('ArrowLeft');
-        eventSender.keyDown('ArrowUp');
+        eventSender.keyDown(stepUpKey);
+        eventSender.keyDown(focusPrevKey);
+        eventSender.keyDown(stepUpKey);
         assert_equals(input.value, "2023-W10");
         document.body.removeChild(input);
     }, `input[type=week writing-mode=${writingMode}] key operations should move between YYYY-WW`);
@@ -95,11 +110,11 @@
         input.min = "2023-05";
         input.max = "2023-10";
         input.focus();
-        eventSender.keyDown('ArrowDown');
+        eventSender.keyDown(stepDownKey);
         assert_equals(input.value, "2023-06");
-        // Using arrow right cannot access year
-        eventSender.keyDown('ArrowRight');
-        eventSender.keyDown('ArrowUp');
+        // Using step up cannot access year
+        eventSender.keyDown(focusNextKey);
+        eventSender.keyDown(stepUpKey);
         assert_equals(input.value, "2023-07");
         document.body.removeChild(input);
     }, `input[type=month writing-mode=${writingMode}] key operations should respect max/min`);
@@ -111,13 +126,13 @@
         input.style.writingMode = writingMode;
         input.value = "2023-07";
         input.focus();
-        eventSender.keyDown('ArrowDown');
-        eventSender.keyDown('ArrowRight');
-        eventSender.keyDown('ArrowDown');
+        eventSender.keyDown(stepDownKey);
+        eventSender.keyDown(focusNextKey);
+        eventSender.keyDown(stepDownKey);
         assert_equals(input.value, "2022-06");
-        eventSender.keyDown('ArrowUp');
-        eventSender.keyDown('ArrowLeft');
-        eventSender.keyDown('ArrowUp');
+        eventSender.keyDown(stepUpKey);
+        eventSender.keyDown(focusPrevKey);
+        eventSender.keyDown(stepUpKey);
         assert_equals(input.value, "2023-07");
         document.body.removeChild(input);
     }, `input[type=month writing-mode=${writingMode}] key operations should move between MM YYYY`);
@@ -130,19 +145,19 @@
         input.value = "10:00";
         input.step = 60 * 5;
         input.focus();
-        eventSender.keyDown('ArrowDown');
+        eventSender.keyDown(stepDownKey);
         assert_equals(input.value, "09:00");
-        eventSender.keyDown('ArrowRight');
-        eventSender.keyDown('ArrowDown');
+        eventSender.keyDown(focusNextKey);
+        eventSender.keyDown(stepDownKey);
         assert_equals(input.value, "09:55");
-        eventSender.keyDown('ArrowUp');
+        eventSender.keyDown(stepUpKey);
         assert_equals(input.value, "09:00");
-        eventSender.keyDown('ArrowRight');
-        eventSender.keyDown('ArrowUp');
+        eventSender.keyDown(focusNextKey);
+        eventSender.keyDown(stepUpKey);
         assert_equals(input.value, "21:00");
-        eventSender.keyDown('ArrowLeft');
-        eventSender.keyDown('ArrowLeft');
-        eventSender.keyDown('ArrowUp');
+        eventSender.keyDown(focusPrevKey);
+        eventSender.keyDown(focusPrevKey);
+        eventSender.keyDown(stepUpKey);
         assert_equals(input.value, "22:00");
         document.body.removeChild(input);
     }, `input[type=time writing-mode=${writingMode}] key operations should respect step and move between HH:MM`);
@@ -158,35 +173,35 @@
         input.min = "2023-06-10T00:00";
         input.step = 60 * 30;
         input.focus();
-        eventSender.keyDown('ArrowDown');
+        eventSender.keyDown(stepDownKey);
         assert_equals(input.value, "2023-06-11T19:30");
-        eventSender.keyDown('ArrowRight');
-        eventSender.keyDown('ArrowDown');
+        eventSender.keyDown(focusNextKey);
+        eventSender.keyDown(stepDownKey);
         assert_equals(input.value, "2023-06-11T18:30");
-        eventSender.keyDown('ArrowRight');
-        eventSender.keyDown('ArrowDown');
+        eventSender.keyDown(focusNextKey);
+        eventSender.keyDown(stepDownKey);
         assert_equals(input.value, "2023-06-11T18:00");
-        eventSender.keyDown('ArrowRight');
-        eventSender.keyDown('ArrowDown');
+        eventSender.keyDown(focusNextKey);
+        eventSender.keyDown(stepDownKey);
         assert_equals(input.value, "2023-06-11T06:00");
 
-        eventSender.keyDown('ArrowUp');
-        eventSender.keyDown('ArrowLeft');
-        eventSender.keyDown('ArrowUp');
-        eventSender.keyDown('ArrowLeft');
-        eventSender.keyDown('ArrowUp');
-        eventSender.keyDown('ArrowLeft');
-        eventSender.keyDown('ArrowUp');
+        eventSender.keyDown(stepUpKey);
+        eventSender.keyDown(focusPrevKey);
+        eventSender.keyDown(stepUpKey);
+        eventSender.keyDown(focusPrevKey);
+        eventSender.keyDown(stepUpKey);
+        eventSender.keyDown(focusPrevKey);
+        eventSender.keyDown(stepUpKey);
         assert_equals(input.value, "2023-06-12T19:30");
         // Cannot modify month and year so moving left will still modify day
-        eventSender.keyDown('ArrowLeft');
-        eventSender.keyDown('ArrowUp');
+        eventSender.keyDown(focusPrevKey);
+        eventSender.keyDown(stepUpKey);
         assert_equals(input.value, "2023-06-13T19:30");
         document.body.removeChild(input);
     }, `input[type=datetime writing-mode=${writingMode}] key operations should respect max/min, step and move between YYYY-MM-DDTHH:MM`);
 }
 
-testKeyOperations('horizonta-tb');
+testKeyOperations('horizontal-tb');
 testKeyOperations('vertical-lr');
 testKeyOperations('vertical-rl');
 </script>
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/test_objectStore_openKeyCursor.js b/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/test_objectStore_openKeyCursor.js
deleted file mode 100644
index 85d938c6..0000000
--- a/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/test_objectStore_openKeyCursor.js
+++ /dev/null
@@ -1,411 +0,0 @@
-// Imported from:
-// * http://mxr.mozilla.org/mozilla-central/source/dom/indexedDB/test/unit/test_objectStore_openKeyCursor.js
-// Changes:
-// * added 'use strict' since some ES6 features NYI w/o it
-// * function -> function*
-// * this.window -> window
-// * Added deleteDatabase() step to reset storage state
-
-'use strict';
-
-/**
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-let testGenerator = testSteps();
-
-function* testSteps() {
-  const dbName = window ?
-                 window.location.pathname :
-                 "test_objectStore_openKeyCursor";
-  indexedDB.deleteDatabase(dbName);
-  const dbVersion = 1;
-  const objectStoreName = "foo";
-  const keyCount = 100;
-
-  let request = indexedDB.open(dbName, dbVersion);
-  request.onerror = errorHandler;
-  request.onupgradeneeded = grabEventAndContinueHandler;
-  request.onsuccess = unexpectedSuccessHandler;
-
-  let event = yield undefined;
-
-  info("Creating database");
-
-  let db = event.target.result;
-  let objectStore = db.createObjectStore(objectStoreName);
-  for (let i = 0; i < keyCount; i++) {
-    objectStore.add(true, i);
-  }
-
-  request.onupgradeneeded = unexpectedSuccessHandler;
-  request.onsuccess = grabEventAndContinueHandler;
-
-  event = yield undefined;
-
-  db = event.target.result;
-  objectStore = db.transaction(objectStoreName, "readwrite")
-                  .objectStore(objectStoreName);
-
-  info("Getting all keys");
-  objectStore.getAllKeys().onsuccess = grabEventAndContinueHandler;
-  event = yield undefined;
-
-  const allKeys = event.target.result;
-
-  ok(Array.isArray(allKeys), "Got an array result");
-  is(allKeys.length, keyCount, "Got correct array length");
-
-  info("Opening normal key cursor");
-
-  let seenKeys = [];
-  objectStore.openKeyCursor().onsuccess = event => {
-    let cursor = event.target.result;
-    if (!cursor) {
-      continueToNextStepSync();
-      return;
-    }
-
-    is(cursor.source, objectStore, "Correct source");
-    is(cursor.direction, "next", "Correct direction");
-
-    let exception = null;
-    try {
-      cursor.update(10);
-    } catch(e) {
-      exception = e;
-    }
-    ok(!!exception, "update() throws for key cursor");
-
-    exception = null;
-    try {
-      cursor.delete();
-    } catch(e) {
-      exception = e;
-    }
-    ok(!!exception, "delete() throws for key cursor");
-
-    is(cursor.key, cursor.primaryKey, "key and primaryKey match");
-    ok(!("value" in cursor), "No 'value' property on key cursor");
-
-    seenKeys.push(cursor.key);
-    cursor.continue();
-  };
-  yield undefined;
-
-  is(seenKeys.length, allKeys.length, "Saw the right number of keys");
-
-  let match = true;
-  for (let i = 0; i < seenKeys.length; i++) {
-    if (seenKeys[i] !== allKeys[i]) {
-      match = false;
-      break;
-    }
-  }
-  ok(match, "All keys matched");
-
-  info("Opening key cursor with keyRange");
-
-  let keyRange = IDBKeyRange.bound(10, 20, false, true);
-
-  seenKeys = [];
-  objectStore.openKeyCursor(keyRange).onsuccess = event => {
-    let cursor = event.target.result;
-    if (!cursor) {
-      continueToNextStepSync();
-      return;
-    }
-
-    is(cursor.source, objectStore, "Correct source");
-    is(cursor.direction, "next", "Correct direction");
-
-    let exception = null;
-    try {
-      cursor.update(10);
-    } catch(e) {
-      exception = e;
-    }
-    ok(!!exception, "update() throws for key cursor");
-
-    exception = null;
-    try {
-      cursor.delete();
-    } catch(e) {
-      exception = e;
-    }
-    ok(!!exception, "delete() throws for key cursor");
-
-    is(cursor.key, cursor.primaryKey, "key and primaryKey match");
-    ok(!("value" in cursor), "No 'value' property on key cursor");
-
-    seenKeys.push(cursor.key);
-    cursor.continue();
-  };
-  yield undefined;
-
-  is(seenKeys.length, 10, "Saw the right number of keys");
-
-  match = true;
-  for (let i = 0; i < seenKeys.length; i++) {
-    if (seenKeys[i] !== allKeys[i + 10]) {
-      match = false;
-      break;
-    }
-  }
-  ok(match, "All keys matched");
-
-  info("Opening key cursor with unmatched keyRange");
-
-  keyRange = IDBKeyRange.bound(10000, 200000);
-
-  seenKeys = [];
-  objectStore.openKeyCursor(keyRange).onsuccess = event => {
-    let cursor = event.target.result;
-    if (!cursor) {
-      continueToNextStepSync();
-      return;
-    }
-
-    ok(false, "Shouldn't have any keys here");
-    cursor.continue();
-  };
-  yield undefined;
-
-  is(seenKeys.length, 0, "Saw the right number of keys");
-
-  info("Opening reverse key cursor");
-
-  seenKeys = [];
-  objectStore.openKeyCursor(null, "prev").onsuccess = event => {
-    let cursor = event.target.result;
-    if (!cursor) {
-      continueToNextStepSync();
-      return;
-    }
-
-    is(cursor.source, objectStore, "Correct source");
-    is(cursor.direction, "prev", "Correct direction");
-
-    let exception = null;
-    try {
-      cursor.update(10);
-    } catch(e) {
-      exception = e;
-    }
-    ok(!!exception, "update() throws for key cursor");
-
-    exception = null;
-    try {
-      cursor.delete();
-    } catch(e) {
-      exception = e;
-    }
-    ok(!!exception, "delete() throws for key cursor");
-
-    is(cursor.key, cursor.primaryKey, "key and primaryKey match");
-    ok(!("value" in cursor), "No 'value' property on key cursor");
-
-    seenKeys.push(cursor.key);
-    cursor.continue();
-  };
-  yield undefined;
-
-  is(seenKeys.length, allKeys.length, "Saw the right number of keys");
-
-  seenKeys.reverse();
-
-  match = true;
-  for (let i = 0; i < seenKeys.length; i++) {
-    if (seenKeys[i] !== allKeys[i]) {
-      match = false;
-      break;
-    }
-  }
-  ok(match, "All keys matched");
-
-  info("Opening reverse key cursor with key range");
-
-  keyRange = IDBKeyRange.bound(10, 20, false, true);
-
-  seenKeys = [];
-  objectStore.openKeyCursor(keyRange, "prev").onsuccess = event => {
-    let cursor = event.target.result;
-    if (!cursor) {
-      continueToNextStepSync();
-      return;
-    }
-
-    is(cursor.source, objectStore, "Correct source");
-    is(cursor.direction, "prev", "Correct direction");
-
-    let exception = null;
-    try {
-      cursor.update(10);
-    } catch(e) {
-      exception = e;
-    }
-    ok(!!exception, "update() throws for key cursor");
-
-    exception = null;
-    try {
-      cursor.delete();
-    } catch(e) {
-      exception = e;
-    }
-    ok(!!exception, "delete() throws for key cursor");
-
-    is(cursor.key, cursor.primaryKey, "key and primaryKey match");
-    ok(!("value" in cursor), "No 'value' property on key cursor");
-
-    seenKeys.push(cursor.key);
-    cursor.continue();
-  };
-  yield undefined;
-
-  is(seenKeys.length, 10, "Saw the right number of keys");
-
-  seenKeys.reverse();
-
-  match = true;
-  for (let i = 0; i < 10; i++) {
-    if (seenKeys[i] !== allKeys[i + 10]) {
-      match = false;
-      break;
-    }
-  }
-  ok(match, "All keys matched");
-
-  info("Opening reverse key cursor with unmatched key range");
-
-  keyRange = IDBKeyRange.bound(10000, 200000);
-
-  seenKeys = [];
-  objectStore.openKeyCursor(keyRange, "prev").onsuccess = event => {
-    let cursor = event.target.result;
-    if (!cursor) {
-      continueToNextStepSync();
-      return;
-    }
-
-    ok(false, "Shouldn't have any keys here");
-    cursor.continue();
-  };
-  yield undefined;
-
-  is(seenKeys.length, 0, "Saw the right number of keys");
-
-  info("Opening key cursor with advance");
-
-  seenKeys = [];
-  objectStore.openKeyCursor().onsuccess = event => {
-    let cursor = event.target.result;
-    if (!cursor) {
-      continueToNextStepSync();
-      return;
-    }
-
-    is(cursor.source, objectStore, "Correct source");
-    is(cursor.direction, "next", "Correct direction");
-
-    let exception = null;
-    try {
-      cursor.update(10);
-    } catch(e) {
-      exception = e;
-    }
-    ok(!!exception, "update() throws for key cursor");
-
-    exception = null;
-    try {
-      cursor.delete();
-    } catch(e) {
-      exception = e;
-    }
-    ok(!!exception, "delete() throws for key cursor");
-
-    is(cursor.key, cursor.primaryKey, "key and primaryKey match");
-    ok(!("value" in cursor), "No 'value' property on key cursor");
-
-    seenKeys.push(cursor.key);
-    if (seenKeys.length == 1) {
-      cursor.advance(10);
-    } else {
-      cursor.continue();
-    }
-  };
-  yield undefined;
-
-  is(seenKeys.length, allKeys.length - 9, "Saw the right number of keys");
-
-  match = true;
-  for (let i = 0, j = 0; i < seenKeys.length; i++) {
-    if (seenKeys[i] !== allKeys[i + j]) {
-      match = false;
-      break;
-    }
-    if (i == 0) {
-      j = 9;
-    }
-  }
-  ok(match, "All keys matched");
-
-  info("Opening key cursor with continue-to-key");
-
-  seenKeys = [];
-  objectStore.openKeyCursor().onsuccess = event => {
-    let cursor = event.target.result;
-    if (!cursor) {
-      continueToNextStepSync();
-      return;
-    }
-
-    is(cursor.source, objectStore, "Correct source");
-    is(cursor.direction, "next", "Correct direction");
-
-    let exception = null;
-    try {
-      cursor.update(10);
-    } catch(e) {
-      exception = e;
-    }
-    ok(!!exception, "update() throws for key cursor");
-
-    exception = null;
-    try {
-      cursor.delete();
-    } catch(e) {
-      exception = e;
-    }
-    ok(!!exception, "delete() throws for key cursor");
-
-    is(cursor.key, cursor.primaryKey, "key and primaryKey match");
-    ok(!("value" in cursor), "No 'value' property on key cursor");
-
-    seenKeys.push(cursor.key);
-
-    if (seenKeys.length == 1) {
-      cursor.continue(10);
-    } else {
-      cursor.continue();
-    }
-  };
-  yield undefined;
-
-  is(seenKeys.length, allKeys.length - 9, "Saw the right number of keys");
-
-  match = true;
-  for (let i = 0, j = 0; i < seenKeys.length; i++) {
-    if (seenKeys[i] !== allKeys[i + j]) {
-      match = false;
-      break;
-    }
-    if (i == 0) {
-      j = 9;
-    }
-  }
-  ok(match, "All keys matched");
-
-  finishTest();
-  yield undefined;
-}
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/test_objectStore_openKeyCursor-expected.txt b/third_party/blink/web_tests/storage/indexeddb/mozilla/test_objectStore_openKeyCursor-expected.txt
deleted file mode 100644
index 434b953b..0000000
--- a/third_party/blink/web_tests/storage/indexeddb/mozilla/test_objectStore_openKeyCursor-expected.txt
+++ /dev/null
@@ -1,2446 +0,0 @@
-IDBObjectStore.openKeyCursor()
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-Creating database
-Getting all keys
-PASS Got an array result
-PASS Got correct array length
-Opening normal key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Saw the right number of keys
-PASS All keys matched
-Opening key cursor with keyRange
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Saw the right number of keys
-PASS All keys matched
-Opening key cursor with unmatched keyRange
-PASS Saw the right number of keys
-Opening reverse key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Saw the right number of keys
-PASS All keys matched
-Opening reverse key cursor with key range
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Saw the right number of keys
-PASS All keys matched
-Opening reverse key cursor with unmatched key range
-PASS Saw the right number of keys
-Opening key cursor with advance
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Saw the right number of keys
-PASS All keys matched
-Opening key cursor with continue-to-key
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Correct source
-PASS Correct direction
-PASS update() throws for key cursor
-PASS delete() throws for key cursor
-PASS key and primaryKey match
-PASS No 'value' property on key cursor
-PASS Saw the right number of keys
-PASS All keys matched
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html b/third_party/blink/web_tests/storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html
deleted file mode 100644
index 3e14e35..0000000
--- a/third_party/blink/web_tests/storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE html>
-<title>IDBObjectStore.openKeyCursor()</title>
-<script src="../../../resources/js-test.js"></script>
-<script>description(document.title);</script>
-<script src="resources/test_objectStore_openKeyCursor.js"></script>
-<script src="resources/generator_test_adapter.js"></script>
diff --git a/third_party/blink/web_tests/virtual/css-text-spacing-trim/README.md b/third_party/blink/web_tests/virtual/css-text-spacing-trim/README.md
new file mode 100644
index 0000000..d49cb89
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/css-text-spacing-trim/README.md
@@ -0,0 +1,3 @@
+Tests for text-autospace property that requires --enable-blink-features=CSSTextSpacingTrim.
+This property changes the default behavior, so it is disabled by default in web
+tests.
diff --git a/third_party/blink/web_tests/virtual/css-text-autospace/external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-combinations-001-expected.txt b/third_party/blink/web_tests/virtual/css-text-spacing-trim/external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-combinations-001-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/css-text-autospace/external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-combinations-001-expected.txt
rename to third_party/blink/web_tests/virtual/css-text-spacing-trim/external/wpt/css/css-text/text-spacing-trim/text-spacing-trim-combinations-001-expected.txt
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/nonstable-css-properties-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/nonstable-css-properties-expected.txt
index b6c69846..b56c16e 100644
--- a/third_party/blink/web_tests/virtual/stable/webexposed/nonstable-css-properties-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/webexposed/nonstable-css-properties-expected.txt
@@ -49,17 +49,17 @@
 
 el.style.setProperty('grid-column', 'auto')
 el.style.getPropertyValue('grid-column') is auto / auto
-getComputedStyle(el).getPropertyValue('grid-column') is auto / auto
+getComputedStyle(el).getPropertyValue('grid-column') is auto
 
 
 el.style.setProperty('grid-row', '1')
 el.style.getPropertyValue('grid-row') is 1 / auto
-getComputedStyle(el).getPropertyValue('grid-row') is 1 / auto
+getComputedStyle(el).getPropertyValue('grid-row') is 1
 
 
 el.style.setProperty('grid-area', '2')
-el.style.getPropertyValue('grid-area') is 2 / auto / auto / auto
-getComputedStyle(el).getPropertyValue('grid-area') is 2 / auto / auto / auto
+el.style.getPropertyValue('grid-area') is 2
+getComputedStyle(el).getPropertyValue('grid-area') is 2
 
 
 el.style.setProperty('grid-auto-flow', 'column')
diff --git a/third_party/blink/web_tests/webexposed/nonstable-css-properties-expected.txt b/third_party/blink/web_tests/webexposed/nonstable-css-properties-expected.txt
index b6c69846..b56c16e 100644
--- a/third_party/blink/web_tests/webexposed/nonstable-css-properties-expected.txt
+++ b/third_party/blink/web_tests/webexposed/nonstable-css-properties-expected.txt
@@ -49,17 +49,17 @@
 
 el.style.setProperty('grid-column', 'auto')
 el.style.getPropertyValue('grid-column') is auto / auto
-getComputedStyle(el).getPropertyValue('grid-column') is auto / auto
+getComputedStyle(el).getPropertyValue('grid-column') is auto
 
 
 el.style.setProperty('grid-row', '1')
 el.style.getPropertyValue('grid-row') is 1 / auto
-getComputedStyle(el).getPropertyValue('grid-row') is 1 / auto
+getComputedStyle(el).getPropertyValue('grid-row') is 1
 
 
 el.style.setProperty('grid-area', '2')
-el.style.getPropertyValue('grid-area') is 2 / auto / auto / auto
-getComputedStyle(el).getPropertyValue('grid-area') is 2 / auto / auto / auto
+el.style.getPropertyValue('grid-area') is 2
+getComputedStyle(el).getPropertyValue('grid-area') is 2
 
 
 el.style.setProperty('grid-auto-flow', 'column')
diff --git a/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-001-print-ref.html b/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-001-print-ref.html
new file mode 100644
index 0000000..59e9c38
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-001-print-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+  @page {
+    size: 300px 200px;
+    margin: 0;
+  }
+  body { margin: 0; }
+</style>
+<div style="float:right; width:100px; height:100px; background:green;"></div>
diff --git a/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-001-print.html b/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-001-print.html
new file mode 100644
index 0000000..3819129
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-001-print.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1485969">
+<link rel="match" href="icb-scaling-001-print-ref.html">
+<style>
+  @page {
+    size: 300px 200px;
+    margin: 0;
+  }
+  body { margin: 0; }
+</style>
+<!-- This test assumes that the printing implementation shrinks the content (and
+     grows the initial containing block) to avoid overflowing content. -->
+<div style="width:450px; height:100px;">
+  <div style="position:fixed; width:150px; height:150px; right:0; top:0; background:green;"></div>
+</div>
diff --git a/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-002-print-ref.html b/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-002-print-ref.html
new file mode 100644
index 0000000..3eab486
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-002-print-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+  @page {
+    size: 300px 600px;
+    margin: 0;
+  }
+  body { margin: 0; }
+</style>
+<div style="margin-left:100px; margin-top:100px; width:150px; height:300px; background:green;"></div>
diff --git a/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-002-print.html b/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-002-print.html
new file mode 100644
index 0000000..bca3ce9
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-002-print.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1485969">
+<link rel="match" href="icb-scaling-002-print-ref.html">
+<style>
+  @page {
+    size: 300px 600px;
+    margin: 0;
+  }
+  body { margin: 0; }
+</style>
+<!-- This test assumes that the printing implementation shrinks the content (and
+     grows the initial containing block) to avoid overflowing content. -->
+<div style="width:450px; height:100px;">
+  <div style="position:absolute; left:150px; top:150px; width:50%; height:50%; background:green;"></div>
+</div>
diff --git a/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-003-print-ref.html b/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-003-print-ref.html
new file mode 100644
index 0000000..3eab486
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-003-print-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+  @page {
+    size: 300px 600px;
+    margin: 0;
+  }
+  body { margin: 0; }
+</style>
+<div style="margin-left:100px; margin-top:100px; width:150px; height:300px; background:green;"></div>
diff --git a/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-003-print.html b/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-003-print.html
new file mode 100644
index 0000000..f94321a
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/printing/icb-scaling-003-print.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1485969">
+<link rel="match" href="icb-scaling-003-print-ref.html">
+<style>
+  @page {
+    size: 300px 600px;
+    margin: 0;
+  }
+  body { margin: 0; }
+</style>
+<!-- This test assumes that the printing implementation shrinks the content (and
+     grows the initial containing block) to avoid overflowing content. -->
+<div style="width:450px; height:100px;">
+  <div style="position:absolute; left:150px; top:150px; width:50vw; height:50vh; background:green;"></div>
+</div>
diff --git a/third_party/catapult b/third_party/catapult
index 3c4b5cf..7c462e0 160000
--- a/third_party/catapult
+++ b/third_party/catapult
@@ -1 +1 @@
-Subproject commit 3c4b5cf37f825a7e13c9fc65f18551f49791399c
+Subproject commit 7c462e0d55cd87448af2c1ba66ce223e5294fe0c
diff --git a/third_party/chromium-variations b/third_party/chromium-variations
index ca0c802..3869a87d 160000
--- a/third_party/chromium-variations
+++ b/third_party/chromium-variations
@@ -1 +1 @@
-Subproject commit ca0c802ac159ed51ed640cabeb3b67e953c40aec
+Subproject commit 3869a87d4512536dcce862b55f2274b8c5e9f438
diff --git a/third_party/depot_tools b/third_party/depot_tools
index f936d54..0827dd2 160000
--- a/third_party/depot_tools
+++ b/third_party/depot_tools
@@ -1 +1 @@
-Subproject commit f936d540e1811967bd3cc819089b498b98b1e1be
+Subproject commit 0827dd28f1c4d25f3cd90776f7e221cba6243c2f
diff --git a/third_party/farmhash/README.chromium b/third_party/farmhash/README.chromium
index 9ed73c3..317a6d1 100644
--- a/third_party/farmhash/README.chromium
+++ b/third_party/farmhash/README.chromium
@@ -2,9 +2,9 @@
 Short Name: farmhash
 URL: https://github.com/google/farmhash
 Version: 1.1
-Date: 2017/09/13
+Date: 2017-09-13
 Revision: 816a4ae622e964763ca0862d9dbd19324a1eaf45
-License: Custom
+License: MIT
 License File: LICENSE
 Security Critical: Yes
 Shipped: yes
diff --git a/third_party/fft2d/README.chromium b/third_party/fft2d/README.chromium
index 803b7c6..af0b7674 100644
--- a/third_party/fft2d/README.chromium
+++ b/third_party/fft2d/README.chromium
@@ -2,8 +2,8 @@
 Short Name: fft2d
 URL: http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html
 Version: 2006/12/28
-Date: 2006/12/28
-License: Custom
+Date: 2006-12-28
+License: FFT2D
 License File: LICENSE
 Security Critical: yes
 Shipped: yes
diff --git a/third_party/libaom/README.chromium b/third_party/libaom/README.chromium
index 78a8e42..bd8ddef 100644
--- a/third_party/libaom/README.chromium
+++ b/third_party/libaom/README.chromium
@@ -2,8 +2,8 @@
 Short Name: libaom
 URL: https://aomedia.googlesource.com/aom/
 Version: 0
-Date: Monday August 28 2023
-Revision: 5f8db64abce68a3698fb732697ae50880bc9cac4
+Date: Friday September 22 2023
+Revision: 82018abee6cb2c4cb8b26cd83eff569e766f1722
 CPEPrefix: cpe:/a:aomedia:aomedia:3.6.1
 License: BSD
 License File: source/libaom/LICENSE
diff --git a/third_party/libaom/libaom_srcs.gni b/third_party/libaom/libaom_srcs.gni
index c8c96d8..48f572e 100644
--- a/third_party/libaom/libaom_srcs.gni
+++ b/third_party/libaom/libaom_srcs.gni
@@ -191,8 +191,9 @@
 
 aom_av1_encoder_asm_ssse3_x86_64 = [ "//third_party/libaom/source/libaom/av1/encoder/x86/av1_quantize_ssse3_x86_64.asm" ]
 
-aom_av1_encoder_intrin_arm_crc32 =
-    [ "//third_party/libaom/source/libaom/av1/encoder/arm/crc32/hash_crc32.c" ]
+aom_av1_encoder_intrin_arm_crc32 = [
+  "//third_party/libaom/source/libaom/av1/encoder/arm/crc32/hash_arm_crc32.c",
+]
 
 aom_av1_encoder_intrin_avx2 = [
   "//third_party/libaom/source/libaom/av1/encoder/x86/av1_quantize_avx2.c",
diff --git a/third_party/libaom/source/config/config/aom_version.h b/third_party/libaom/source/config/config/aom_version.h
index c5f244e..c1ece5c5 100644
--- a/third_party/libaom/source/config/config/aom_version.h
+++ b/third_party/libaom/source/config/config/aom_version.h
@@ -10,10 +10,10 @@
  */
 
 #define VERSION_MAJOR 3
-#define VERSION_MINOR 6
-#define VERSION_PATCH 1
-#define VERSION_EXTRA "1084-g5f8db64abc"
+#define VERSION_MINOR 7
+#define VERSION_PATCH 0
+#define VERSION_EXTRA "450-g82018abee6"
 #define VERSION_PACKED \
   ((VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_PATCH))
-#define VERSION_STRING_NOSP "3.6.1-1084-g5f8db64abc"
-#define VERSION_STRING " 3.6.1-1084-g5f8db64abc"
+#define VERSION_STRING_NOSP "3.7.0-450-g82018abee6"
+#define VERSION_STRING " 3.7.0-450-g82018abee6"
diff --git a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_dsp_rtcd.h
index bd538ad..d5bc3b9 100644
--- a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_dsp_rtcd.h
@@ -2625,7 +2625,16 @@
 RTCD_EXTERN unsigned int (*aom_mse8x8)(const uint8_t *src_ptr, int  source_stride, const uint8_t *ref_ptr, int  recon_stride, unsigned int *sse);
 
 uint64_t aom_mse_16xh_16bit_c(uint8_t *dst, int dstride,uint16_t *src, int w, int h);
-#define aom_mse_16xh_16bit aom_mse_16xh_16bit_c
+uint64_t aom_mse_16xh_16bit_neon(uint8_t* dst,
+                                 int dstride,
+                                 uint16_t* src,
+                                 int w,
+                                 int h);
+RTCD_EXTERN uint64_t (*aom_mse_16xh_16bit)(uint8_t* dst,
+                                           int dstride,
+                                           uint16_t* src,
+                                           int w,
+                                           int h);
 
 uint64_t aom_mse_wxh_16bit_c(uint8_t *dst, int dstride,uint16_t *src, int sstride, int w, int h);
 uint64_t aom_mse_wxh_16bit_neon(uint8_t *dst, int dstride,uint16_t *src, int sstride, int w, int h);
@@ -4723,6 +4732,10 @@
     if (flags & HAS_NEON) aom_mse8x16 = aom_mse8x16_neon;
     aom_mse8x8 = aom_mse8x8_c;
     if (flags & HAS_NEON) aom_mse8x8 = aom_mse8x8_neon;
+    aom_mse_16xh_16bit = aom_mse_16xh_16bit_c;
+    if (flags & HAS_NEON) {
+      aom_mse_16xh_16bit = aom_mse_16xh_16bit_neon;
+    }
     aom_mse_wxh_16bit = aom_mse_wxh_16bit_c;
     if (flags & HAS_NEON) aom_mse_wxh_16bit = aom_mse_wxh_16bit_neon;
     aom_paeth_predictor_16x16 = aom_paeth_predictor_16x16_c;
diff --git a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/av1_rtcd.h b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/av1_rtcd.h
index 19eeedb..d4f3787a 100644
--- a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/av1_rtcd.h
@@ -194,7 +194,22 @@
 RTCD_EXTERN int64_t (*av1_block_error_lp)(const int16_t *coeff, const int16_t *dqcoeff, intptr_t block_size);
 
 void av1_build_compound_diffwtd_mask_c(uint8_t *mask, DIFFWTD_MASK_TYPE mask_type, const uint8_t *src0, int src0_stride, const uint8_t *src1, int src1_stride, int h, int w);
-#define av1_build_compound_diffwtd_mask av1_build_compound_diffwtd_mask_c
+void av1_build_compound_diffwtd_mask_neon(uint8_t* mask,
+                                          DIFFWTD_MASK_TYPE mask_type,
+                                          const uint8_t* src0,
+                                          int src0_stride,
+                                          const uint8_t* src1,
+                                          int src1_stride,
+                                          int h,
+                                          int w);
+RTCD_EXTERN void (*av1_build_compound_diffwtd_mask)(uint8_t* mask,
+                                                    DIFFWTD_MASK_TYPE mask_type,
+                                                    const uint8_t* src0,
+                                                    int src0_stride,
+                                                    const uint8_t* src1,
+                                                    int src1_stride,
+                                                    int h,
+                                                    int w);
 
 void av1_build_compound_diffwtd_mask_d16_c(uint8_t *mask, DIFFWTD_MASK_TYPE mask_type, const CONV_BUF_TYPE *src0, int src0_stride, const CONV_BUF_TYPE *src1, int src1_stride, int h, int w, ConvolveParams *conv_params, int bd);
 void av1_build_compound_diffwtd_mask_d16_neon(uint8_t *mask, DIFFWTD_MASK_TYPE mask_type, const CONV_BUF_TYPE *src0, int src0_stride, const CONV_BUF_TYPE *src1, int src1_stride, int h, int w, ConvolveParams *conv_params, int bd);
@@ -279,10 +294,8 @@
 RTCD_EXTERN void (*av1_dr_prediction_z3)(uint8_t *dst, ptrdiff_t stride, int bw, int bh, const uint8_t *above, const uint8_t *left, int upsample_left, int dx, int dy);
 
 void av1_filter_intra_edge_c(uint8_t *p, int sz, int strength);
-#define av1_filter_intra_edge av1_filter_intra_edge_c
-
-void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength);
-#define av1_filter_intra_edge_high av1_filter_intra_edge_high_c
+void av1_filter_intra_edge_neon(uint8_t* p, int sz, int strength);
+RTCD_EXTERN void (*av1_filter_intra_edge)(uint8_t* p, int sz, int strength);
 
 void av1_filter_intra_predictor_c(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
 void av1_filter_intra_predictor_neon(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
@@ -569,10 +582,8 @@
 RTCD_EXTERN void (*av1_txb_init_levels)(const tran_low_t *const coeff, const int width, const int height, uint8_t *const levels);
 
 void av1_upsample_intra_edge_c(uint8_t *p, int sz);
-#define av1_upsample_intra_edge av1_upsample_intra_edge_c
-
-void av1_upsample_intra_edge_high_c(uint16_t *p, int sz, int bd);
-#define av1_upsample_intra_edge_high av1_upsample_intra_edge_high_c
+void av1_upsample_intra_edge_neon(uint8_t* p, int sz);
+RTCD_EXTERN void (*av1_upsample_intra_edge)(uint8_t* p, int sz);
 
 void av1_warp_affine_c(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
 void av1_warp_affine_neon(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
@@ -694,6 +705,10 @@
     if (flags & HAS_NEON) av1_block_error = av1_block_error_neon;
     av1_block_error_lp = av1_block_error_lp_c;
     if (flags & HAS_NEON) av1_block_error_lp = av1_block_error_lp_neon;
+    av1_build_compound_diffwtd_mask = av1_build_compound_diffwtd_mask_c;
+    if (flags & HAS_NEON) {
+      av1_build_compound_diffwtd_mask = av1_build_compound_diffwtd_mask_neon;
+    }
     av1_build_compound_diffwtd_mask_d16 = av1_build_compound_diffwtd_mask_d16_c;
     if (flags & HAS_NEON) av1_build_compound_diffwtd_mask_d16 = av1_build_compound_diffwtd_mask_d16_neon;
     av1_calc_indices_dim1 = av1_calc_indices_dim1_c;
@@ -726,6 +741,10 @@
     if (flags & HAS_NEON) av1_dr_prediction_z2 = av1_dr_prediction_z2_neon;
     av1_dr_prediction_z3 = av1_dr_prediction_z3_c;
     if (flags & HAS_NEON) av1_dr_prediction_z3 = av1_dr_prediction_z3_neon;
+    av1_filter_intra_edge = av1_filter_intra_edge_c;
+    if (flags & HAS_NEON) {
+      av1_filter_intra_edge = av1_filter_intra_edge_neon;
+    }
     av1_filter_intra_predictor = av1_filter_intra_predictor_c;
     if (flags & HAS_NEON) av1_filter_intra_predictor = av1_filter_intra_predictor_neon;
     av1_fwd_txfm2d_16x16 = av1_fwd_txfm2d_16x16_c;
@@ -850,6 +869,10 @@
     if (flags & HAS_NEON) av1_selfguided_restoration = av1_selfguided_restoration_neon;
     av1_txb_init_levels = av1_txb_init_levels_c;
     if (flags & HAS_NEON) av1_txb_init_levels = av1_txb_init_levels_neon;
+    av1_upsample_intra_edge = av1_upsample_intra_edge_c;
+    if (flags & HAS_NEON) {
+      av1_upsample_intra_edge = av1_upsample_intra_edge_neon;
+    }
     av1_warp_affine = av1_warp_affine_c;
     if (flags & HAS_NEON) av1_warp_affine = av1_warp_affine_neon;
     av1_wedge_sse_from_residuals = av1_wedge_sse_from_residuals_c;
diff --git a/third_party/libaom/source/config/linux/arm-neon/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/linux/arm-neon/config/aom_dsp_rtcd.h
index 33dcf45..55f5486 100644
--- a/third_party/libaom/source/config/linux/arm-neon/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/linux/arm-neon/config/aom_dsp_rtcd.h
@@ -1823,7 +1823,12 @@
 #define aom_mse8x8 aom_mse8x8_neon
 
 uint64_t aom_mse_16xh_16bit_c(uint8_t *dst, int dstride,uint16_t *src, int w, int h);
-#define aom_mse_16xh_16bit aom_mse_16xh_16bit_c
+uint64_t aom_mse_16xh_16bit_neon(uint8_t* dst,
+                                 int dstride,
+                                 uint16_t* src,
+                                 int w,
+                                 int h);
+#define aom_mse_16xh_16bit aom_mse_16xh_16bit_neon
 
 uint64_t aom_mse_wxh_16bit_c(uint8_t *dst, int dstride,uint16_t *src, int sstride, int w, int h);
 uint64_t aom_mse_wxh_16bit_neon(uint8_t *dst, int dstride,uint16_t *src, int sstride, int w, int h);
diff --git a/third_party/libaom/source/config/linux/arm-neon/config/av1_rtcd.h b/third_party/libaom/source/config/linux/arm-neon/config/av1_rtcd.h
index 5de044b..4dcd2e8 100644
--- a/third_party/libaom/source/config/linux/arm-neon/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/linux/arm-neon/config/av1_rtcd.h
@@ -154,7 +154,15 @@
 #define av1_block_error_lp av1_block_error_lp_neon
 
 void av1_build_compound_diffwtd_mask_c(uint8_t *mask, DIFFWTD_MASK_TYPE mask_type, const uint8_t *src0, int src0_stride, const uint8_t *src1, int src1_stride, int h, int w);
-#define av1_build_compound_diffwtd_mask av1_build_compound_diffwtd_mask_c
+void av1_build_compound_diffwtd_mask_neon(uint8_t* mask,
+                                          DIFFWTD_MASK_TYPE mask_type,
+                                          const uint8_t* src0,
+                                          int src0_stride,
+                                          const uint8_t* src1,
+                                          int src1_stride,
+                                          int h,
+                                          int w);
+#define av1_build_compound_diffwtd_mask av1_build_compound_diffwtd_mask_neon
 
 void av1_build_compound_diffwtd_mask_d16_c(uint8_t *mask, DIFFWTD_MASK_TYPE mask_type, const CONV_BUF_TYPE *src0, int src0_stride, const CONV_BUF_TYPE *src1, int src1_stride, int h, int w, ConvolveParams *conv_params, int bd);
 void av1_build_compound_diffwtd_mask_d16_neon(uint8_t *mask, DIFFWTD_MASK_TYPE mask_type, const CONV_BUF_TYPE *src0, int src0_stride, const CONV_BUF_TYPE *src1, int src1_stride, int h, int w, ConvolveParams *conv_params, int bd);
@@ -229,10 +237,8 @@
 #define av1_dr_prediction_z3 av1_dr_prediction_z3_neon
 
 void av1_filter_intra_edge_c(uint8_t *p, int sz, int strength);
-#define av1_filter_intra_edge av1_filter_intra_edge_c
-
-void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength);
-#define av1_filter_intra_edge_high av1_filter_intra_edge_high_c
+void av1_filter_intra_edge_neon(uint8_t* p, int sz, int strength);
+#define av1_filter_intra_edge av1_filter_intra_edge_neon
 
 void av1_filter_intra_predictor_c(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
 void av1_filter_intra_predictor_neon(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
@@ -517,10 +523,8 @@
 #define av1_txb_init_levels av1_txb_init_levels_neon
 
 void av1_upsample_intra_edge_c(uint8_t *p, int sz);
-#define av1_upsample_intra_edge av1_upsample_intra_edge_c
-
-void av1_upsample_intra_edge_high_c(uint16_t *p, int sz, int bd);
-#define av1_upsample_intra_edge_high av1_upsample_intra_edge_high_c
+void av1_upsample_intra_edge_neon(uint8_t* p, int sz);
+#define av1_upsample_intra_edge av1_upsample_intra_edge_neon
 
 void av1_warp_affine_c(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
 void av1_warp_affine_neon(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
diff --git a/third_party/libaom/source/config/linux/arm/config/av1_rtcd.h b/third_party/libaom/source/config/linux/arm/config/av1_rtcd.h
index e9d471d..3f755c4 100644
--- a/third_party/libaom/source/config/linux/arm/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/linux/arm/config/av1_rtcd.h
@@ -159,9 +159,6 @@
 void av1_filter_intra_edge_c(uint8_t *p, int sz, int strength);
 #define av1_filter_intra_edge av1_filter_intra_edge_c
 
-void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength);
-#define av1_filter_intra_edge_high av1_filter_intra_edge_high_c
-
 void av1_filter_intra_predictor_c(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
 #define av1_filter_intra_predictor av1_filter_intra_predictor_c
 
@@ -383,9 +380,6 @@
 void av1_upsample_intra_edge_c(uint8_t *p, int sz);
 #define av1_upsample_intra_edge av1_upsample_intra_edge_c
 
-void av1_upsample_intra_edge_high_c(uint16_t *p, int sz, int bd);
-#define av1_upsample_intra_edge_high av1_upsample_intra_edge_high_c
-
 void av1_warp_affine_c(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
 #define av1_warp_affine av1_warp_affine_c
 
diff --git a/third_party/libaom/source/config/linux/arm64-cpu-detect/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/linux/arm64-cpu-detect/config/aom_dsp_rtcd.h
index 421c9e7b..3e095816 100644
--- a/third_party/libaom/source/config/linux/arm64-cpu-detect/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/linux/arm64-cpu-detect/config/aom_dsp_rtcd.h
@@ -3672,7 +3672,12 @@
                               uint16_t* src,
                               int w,
                               int h);
-#define aom_mse_16xh_16bit aom_mse_16xh_16bit_c
+uint64_t aom_mse_16xh_16bit_neon(uint8_t* dst,
+                                 int dstride,
+                                 uint16_t* src,
+                                 int w,
+                                 int h);
+#define aom_mse_16xh_16bit aom_mse_16xh_16bit_neon
 
 uint64_t aom_mse_wxh_16bit_c(uint8_t* dst,
                              int dstride,
diff --git a/third_party/libaom/source/config/linux/arm64-cpu-detect/config/av1_rtcd.h b/third_party/libaom/source/config/linux/arm64-cpu-detect/config/av1_rtcd.h
index 576677c..8f0ce177 100644
--- a/third_party/libaom/source/config/linux/arm64-cpu-detect/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/linux/arm64-cpu-detect/config/av1_rtcd.h
@@ -257,7 +257,15 @@
                                        int src1_stride,
                                        int h,
                                        int w);
-#define av1_build_compound_diffwtd_mask av1_build_compound_diffwtd_mask_c
+void av1_build_compound_diffwtd_mask_neon(uint8_t* mask,
+                                          DIFFWTD_MASK_TYPE mask_type,
+                                          const uint8_t* src0,
+                                          int src0_stride,
+                                          const uint8_t* src1,
+                                          int src1_stride,
+                                          int h,
+                                          int w);
+#define av1_build_compound_diffwtd_mask av1_build_compound_diffwtd_mask_neon
 
 void av1_build_compound_diffwtd_mask_d16_c(uint8_t* mask,
                                            DIFFWTD_MASK_TYPE mask_type,
@@ -684,10 +692,8 @@
 #define av1_dr_prediction_z3 av1_dr_prediction_z3_neon
 
 void av1_filter_intra_edge_c(uint8_t* p, int sz, int strength);
-#define av1_filter_intra_edge av1_filter_intra_edge_c
-
-void av1_filter_intra_edge_high_c(uint16_t* p, int sz, int strength);
-#define av1_filter_intra_edge_high av1_filter_intra_edge_high_c
+void av1_filter_intra_edge_neon(uint8_t* p, int sz, int strength);
+#define av1_filter_intra_edge av1_filter_intra_edge_neon
 
 void av1_filter_intra_predictor_c(uint8_t* dst,
                                   ptrdiff_t stride,
@@ -1521,10 +1527,8 @@
 #define av1_txb_init_levels av1_txb_init_levels_neon
 
 void av1_upsample_intra_edge_c(uint8_t* p, int sz);
-#define av1_upsample_intra_edge av1_upsample_intra_edge_c
-
-void av1_upsample_intra_edge_high_c(uint16_t* p, int sz, int bd);
-#define av1_upsample_intra_edge_high av1_upsample_intra_edge_high_c
+void av1_upsample_intra_edge_neon(uint8_t* p, int sz);
+#define av1_upsample_intra_edge av1_upsample_intra_edge_neon
 
 void av1_warp_affine_c(const int32_t* mat,
                        const uint8_t* ref,
diff --git a/third_party/libaom/source/config/linux/generic/config/av1_rtcd.h b/third_party/libaom/source/config/linux/generic/config/av1_rtcd.h
index 485bb69e..6347b76 100644
--- a/third_party/libaom/source/config/linux/generic/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/linux/generic/config/av1_rtcd.h
@@ -159,9 +159,6 @@
 void av1_filter_intra_edge_c(uint8_t *p, int sz, int strength);
 #define av1_filter_intra_edge av1_filter_intra_edge_c
 
-void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength);
-#define av1_filter_intra_edge_high av1_filter_intra_edge_high_c
-
 void av1_filter_intra_predictor_c(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
 #define av1_filter_intra_predictor av1_filter_intra_predictor_c
 
@@ -383,9 +380,6 @@
 void av1_upsample_intra_edge_c(uint8_t *p, int sz);
 #define av1_upsample_intra_edge av1_upsample_intra_edge_c
 
-void av1_upsample_intra_edge_high_c(uint16_t *p, int sz, int bd);
-#define av1_upsample_intra_edge_high av1_upsample_intra_edge_high_c
-
 void av1_warp_affine_c(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
 #define av1_warp_affine av1_warp_affine_c
 
diff --git a/third_party/libaom/source/config/linux/ia32/config/av1_rtcd.h b/third_party/libaom/source/config/linux/ia32/config/av1_rtcd.h
index 46444e53..58ad6a3 100644
--- a/third_party/libaom/source/config/linux/ia32/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/linux/ia32/config/av1_rtcd.h
@@ -212,10 +212,6 @@
 void av1_filter_intra_edge_sse4_1(uint8_t *p, int sz, int strength);
 RTCD_EXTERN void (*av1_filter_intra_edge)(uint8_t *p, int sz, int strength);
 
-void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength);
-void av1_filter_intra_edge_high_sse4_1(uint16_t *p, int sz, int strength);
-RTCD_EXTERN void (*av1_filter_intra_edge_high)(uint16_t *p, int sz, int strength);
-
 void av1_filter_intra_predictor_c(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
 void av1_filter_intra_predictor_sse4_1(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
 RTCD_EXTERN void (*av1_filter_intra_predictor)(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
@@ -504,10 +500,6 @@
 void av1_upsample_intra_edge_sse4_1(uint8_t *p, int sz);
 RTCD_EXTERN void (*av1_upsample_intra_edge)(uint8_t *p, int sz);
 
-void av1_upsample_intra_edge_high_c(uint16_t *p, int sz, int bd);
-void av1_upsample_intra_edge_high_sse4_1(uint16_t *p, int sz, int bd);
-RTCD_EXTERN void (*av1_upsample_intra_edge_high)(uint16_t *p, int sz, int bd);
-
 void av1_warp_affine_c(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
 void av1_warp_affine_sse4_1(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
 void av1_warp_affine_avx2(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
@@ -704,8 +696,6 @@
     if (flags & HAS_AVX2) av1_dr_prediction_z3 = av1_dr_prediction_z3_avx2;
     av1_filter_intra_edge = av1_filter_intra_edge_c;
     if (flags & HAS_SSE4_1) av1_filter_intra_edge = av1_filter_intra_edge_sse4_1;
-    av1_filter_intra_edge_high = av1_filter_intra_edge_high_c;
-    if (flags & HAS_SSE4_1) av1_filter_intra_edge_high = av1_filter_intra_edge_high_sse4_1;
     av1_filter_intra_predictor = av1_filter_intra_predictor_c;
     if (flags & HAS_SSE4_1) av1_filter_intra_predictor = av1_filter_intra_predictor_sse4_1;
     av1_fwd_txfm2d_16x16 = av1_fwd_txfm2d_16x16_c;
@@ -803,8 +793,6 @@
     if (flags & HAS_AVX2) av1_txb_init_levels = av1_txb_init_levels_avx2;
     av1_upsample_intra_edge = av1_upsample_intra_edge_c;
     if (flags & HAS_SSE4_1) av1_upsample_intra_edge = av1_upsample_intra_edge_sse4_1;
-    av1_upsample_intra_edge_high = av1_upsample_intra_edge_high_c;
-    if (flags & HAS_SSE4_1) av1_upsample_intra_edge_high = av1_upsample_intra_edge_high_sse4_1;
     av1_warp_affine = av1_warp_affine_c;
     if (flags & HAS_SSE4_1) av1_warp_affine = av1_warp_affine_sse4_1;
     if (flags & HAS_AVX2) av1_warp_affine = av1_warp_affine_avx2;
diff --git a/third_party/libaom/source/config/linux/x64/config/av1_rtcd.h b/third_party/libaom/source/config/linux/x64/config/av1_rtcd.h
index 46444e53..58ad6a3 100644
--- a/third_party/libaom/source/config/linux/x64/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/linux/x64/config/av1_rtcd.h
@@ -212,10 +212,6 @@
 void av1_filter_intra_edge_sse4_1(uint8_t *p, int sz, int strength);
 RTCD_EXTERN void (*av1_filter_intra_edge)(uint8_t *p, int sz, int strength);
 
-void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength);
-void av1_filter_intra_edge_high_sse4_1(uint16_t *p, int sz, int strength);
-RTCD_EXTERN void (*av1_filter_intra_edge_high)(uint16_t *p, int sz, int strength);
-
 void av1_filter_intra_predictor_c(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
 void av1_filter_intra_predictor_sse4_1(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
 RTCD_EXTERN void (*av1_filter_intra_predictor)(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
@@ -504,10 +500,6 @@
 void av1_upsample_intra_edge_sse4_1(uint8_t *p, int sz);
 RTCD_EXTERN void (*av1_upsample_intra_edge)(uint8_t *p, int sz);
 
-void av1_upsample_intra_edge_high_c(uint16_t *p, int sz, int bd);
-void av1_upsample_intra_edge_high_sse4_1(uint16_t *p, int sz, int bd);
-RTCD_EXTERN void (*av1_upsample_intra_edge_high)(uint16_t *p, int sz, int bd);
-
 void av1_warp_affine_c(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
 void av1_warp_affine_sse4_1(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
 void av1_warp_affine_avx2(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
@@ -704,8 +696,6 @@
     if (flags & HAS_AVX2) av1_dr_prediction_z3 = av1_dr_prediction_z3_avx2;
     av1_filter_intra_edge = av1_filter_intra_edge_c;
     if (flags & HAS_SSE4_1) av1_filter_intra_edge = av1_filter_intra_edge_sse4_1;
-    av1_filter_intra_edge_high = av1_filter_intra_edge_high_c;
-    if (flags & HAS_SSE4_1) av1_filter_intra_edge_high = av1_filter_intra_edge_high_sse4_1;
     av1_filter_intra_predictor = av1_filter_intra_predictor_c;
     if (flags & HAS_SSE4_1) av1_filter_intra_predictor = av1_filter_intra_predictor_sse4_1;
     av1_fwd_txfm2d_16x16 = av1_fwd_txfm2d_16x16_c;
@@ -803,8 +793,6 @@
     if (flags & HAS_AVX2) av1_txb_init_levels = av1_txb_init_levels_avx2;
     av1_upsample_intra_edge = av1_upsample_intra_edge_c;
     if (flags & HAS_SSE4_1) av1_upsample_intra_edge = av1_upsample_intra_edge_sse4_1;
-    av1_upsample_intra_edge_high = av1_upsample_intra_edge_high_c;
-    if (flags & HAS_SSE4_1) av1_upsample_intra_edge_high = av1_upsample_intra_edge_high_sse4_1;
     av1_warp_affine = av1_warp_affine_c;
     if (flags & HAS_SSE4_1) av1_warp_affine = av1_warp_affine_sse4_1;
     if (flags & HAS_AVX2) av1_warp_affine = av1_warp_affine_avx2;
diff --git a/third_party/libaom/source/config/win/arm64-cpu-detect/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/win/arm64-cpu-detect/config/aom_dsp_rtcd.h
index 421c9e7b..3e095816 100644
--- a/third_party/libaom/source/config/win/arm64-cpu-detect/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/win/arm64-cpu-detect/config/aom_dsp_rtcd.h
@@ -3672,7 +3672,12 @@
                               uint16_t* src,
                               int w,
                               int h);
-#define aom_mse_16xh_16bit aom_mse_16xh_16bit_c
+uint64_t aom_mse_16xh_16bit_neon(uint8_t* dst,
+                                 int dstride,
+                                 uint16_t* src,
+                                 int w,
+                                 int h);
+#define aom_mse_16xh_16bit aom_mse_16xh_16bit_neon
 
 uint64_t aom_mse_wxh_16bit_c(uint8_t* dst,
                              int dstride,
diff --git a/third_party/libaom/source/config/win/arm64-cpu-detect/config/av1_rtcd.h b/third_party/libaom/source/config/win/arm64-cpu-detect/config/av1_rtcd.h
index 576677c..8f0ce177 100644
--- a/third_party/libaom/source/config/win/arm64-cpu-detect/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/win/arm64-cpu-detect/config/av1_rtcd.h
@@ -257,7 +257,15 @@
                                        int src1_stride,
                                        int h,
                                        int w);
-#define av1_build_compound_diffwtd_mask av1_build_compound_diffwtd_mask_c
+void av1_build_compound_diffwtd_mask_neon(uint8_t* mask,
+                                          DIFFWTD_MASK_TYPE mask_type,
+                                          const uint8_t* src0,
+                                          int src0_stride,
+                                          const uint8_t* src1,
+                                          int src1_stride,
+                                          int h,
+                                          int w);
+#define av1_build_compound_diffwtd_mask av1_build_compound_diffwtd_mask_neon
 
 void av1_build_compound_diffwtd_mask_d16_c(uint8_t* mask,
                                            DIFFWTD_MASK_TYPE mask_type,
@@ -684,10 +692,8 @@
 #define av1_dr_prediction_z3 av1_dr_prediction_z3_neon
 
 void av1_filter_intra_edge_c(uint8_t* p, int sz, int strength);
-#define av1_filter_intra_edge av1_filter_intra_edge_c
-
-void av1_filter_intra_edge_high_c(uint16_t* p, int sz, int strength);
-#define av1_filter_intra_edge_high av1_filter_intra_edge_high_c
+void av1_filter_intra_edge_neon(uint8_t* p, int sz, int strength);
+#define av1_filter_intra_edge av1_filter_intra_edge_neon
 
 void av1_filter_intra_predictor_c(uint8_t* dst,
                                   ptrdiff_t stride,
@@ -1521,10 +1527,8 @@
 #define av1_txb_init_levels av1_txb_init_levels_neon
 
 void av1_upsample_intra_edge_c(uint8_t* p, int sz);
-#define av1_upsample_intra_edge av1_upsample_intra_edge_c
-
-void av1_upsample_intra_edge_high_c(uint16_t* p, int sz, int bd);
-#define av1_upsample_intra_edge_high av1_upsample_intra_edge_high_c
+void av1_upsample_intra_edge_neon(uint8_t* p, int sz);
+#define av1_upsample_intra_edge av1_upsample_intra_edge_neon
 
 void av1_warp_affine_c(const int32_t* mat,
                        const uint8_t* ref,
diff --git a/third_party/libaom/source/config/win/ia32/config/av1_rtcd.h b/third_party/libaom/source/config/win/ia32/config/av1_rtcd.h
index 46444e53..58ad6a3 100644
--- a/third_party/libaom/source/config/win/ia32/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/win/ia32/config/av1_rtcd.h
@@ -212,10 +212,6 @@
 void av1_filter_intra_edge_sse4_1(uint8_t *p, int sz, int strength);
 RTCD_EXTERN void (*av1_filter_intra_edge)(uint8_t *p, int sz, int strength);
 
-void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength);
-void av1_filter_intra_edge_high_sse4_1(uint16_t *p, int sz, int strength);
-RTCD_EXTERN void (*av1_filter_intra_edge_high)(uint16_t *p, int sz, int strength);
-
 void av1_filter_intra_predictor_c(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
 void av1_filter_intra_predictor_sse4_1(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
 RTCD_EXTERN void (*av1_filter_intra_predictor)(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
@@ -504,10 +500,6 @@
 void av1_upsample_intra_edge_sse4_1(uint8_t *p, int sz);
 RTCD_EXTERN void (*av1_upsample_intra_edge)(uint8_t *p, int sz);
 
-void av1_upsample_intra_edge_high_c(uint16_t *p, int sz, int bd);
-void av1_upsample_intra_edge_high_sse4_1(uint16_t *p, int sz, int bd);
-RTCD_EXTERN void (*av1_upsample_intra_edge_high)(uint16_t *p, int sz, int bd);
-
 void av1_warp_affine_c(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
 void av1_warp_affine_sse4_1(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
 void av1_warp_affine_avx2(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
@@ -704,8 +696,6 @@
     if (flags & HAS_AVX2) av1_dr_prediction_z3 = av1_dr_prediction_z3_avx2;
     av1_filter_intra_edge = av1_filter_intra_edge_c;
     if (flags & HAS_SSE4_1) av1_filter_intra_edge = av1_filter_intra_edge_sse4_1;
-    av1_filter_intra_edge_high = av1_filter_intra_edge_high_c;
-    if (flags & HAS_SSE4_1) av1_filter_intra_edge_high = av1_filter_intra_edge_high_sse4_1;
     av1_filter_intra_predictor = av1_filter_intra_predictor_c;
     if (flags & HAS_SSE4_1) av1_filter_intra_predictor = av1_filter_intra_predictor_sse4_1;
     av1_fwd_txfm2d_16x16 = av1_fwd_txfm2d_16x16_c;
@@ -803,8 +793,6 @@
     if (flags & HAS_AVX2) av1_txb_init_levels = av1_txb_init_levels_avx2;
     av1_upsample_intra_edge = av1_upsample_intra_edge_c;
     if (flags & HAS_SSE4_1) av1_upsample_intra_edge = av1_upsample_intra_edge_sse4_1;
-    av1_upsample_intra_edge_high = av1_upsample_intra_edge_high_c;
-    if (flags & HAS_SSE4_1) av1_upsample_intra_edge_high = av1_upsample_intra_edge_high_sse4_1;
     av1_warp_affine = av1_warp_affine_c;
     if (flags & HAS_SSE4_1) av1_warp_affine = av1_warp_affine_sse4_1;
     if (flags & HAS_AVX2) av1_warp_affine = av1_warp_affine_avx2;
diff --git a/third_party/libaom/source/config/win/x64/config/av1_rtcd.h b/third_party/libaom/source/config/win/x64/config/av1_rtcd.h
index 46444e53..58ad6a3 100644
--- a/third_party/libaom/source/config/win/x64/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/win/x64/config/av1_rtcd.h
@@ -212,10 +212,6 @@
 void av1_filter_intra_edge_sse4_1(uint8_t *p, int sz, int strength);
 RTCD_EXTERN void (*av1_filter_intra_edge)(uint8_t *p, int sz, int strength);
 
-void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength);
-void av1_filter_intra_edge_high_sse4_1(uint16_t *p, int sz, int strength);
-RTCD_EXTERN void (*av1_filter_intra_edge_high)(uint16_t *p, int sz, int strength);
-
 void av1_filter_intra_predictor_c(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
 void av1_filter_intra_predictor_sse4_1(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
 RTCD_EXTERN void (*av1_filter_intra_predictor)(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left, int mode);
@@ -504,10 +500,6 @@
 void av1_upsample_intra_edge_sse4_1(uint8_t *p, int sz);
 RTCD_EXTERN void (*av1_upsample_intra_edge)(uint8_t *p, int sz);
 
-void av1_upsample_intra_edge_high_c(uint16_t *p, int sz, int bd);
-void av1_upsample_intra_edge_high_sse4_1(uint16_t *p, int sz, int bd);
-RTCD_EXTERN void (*av1_upsample_intra_edge_high)(uint16_t *p, int sz, int bd);
-
 void av1_warp_affine_c(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
 void av1_warp_affine_sse4_1(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
 void av1_warp_affine_avx2(const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta);
@@ -704,8 +696,6 @@
     if (flags & HAS_AVX2) av1_dr_prediction_z3 = av1_dr_prediction_z3_avx2;
     av1_filter_intra_edge = av1_filter_intra_edge_c;
     if (flags & HAS_SSE4_1) av1_filter_intra_edge = av1_filter_intra_edge_sse4_1;
-    av1_filter_intra_edge_high = av1_filter_intra_edge_high_c;
-    if (flags & HAS_SSE4_1) av1_filter_intra_edge_high = av1_filter_intra_edge_high_sse4_1;
     av1_filter_intra_predictor = av1_filter_intra_predictor_c;
     if (flags & HAS_SSE4_1) av1_filter_intra_predictor = av1_filter_intra_predictor_sse4_1;
     av1_fwd_txfm2d_16x16 = av1_fwd_txfm2d_16x16_c;
@@ -803,8 +793,6 @@
     if (flags & HAS_AVX2) av1_txb_init_levels = av1_txb_init_levels_avx2;
     av1_upsample_intra_edge = av1_upsample_intra_edge_c;
     if (flags & HAS_SSE4_1) av1_upsample_intra_edge = av1_upsample_intra_edge_sse4_1;
-    av1_upsample_intra_edge_high = av1_upsample_intra_edge_high_c;
-    if (flags & HAS_SSE4_1) av1_upsample_intra_edge_high = av1_upsample_intra_edge_high_sse4_1;
     av1_warp_affine = av1_warp_affine_c;
     if (flags & HAS_SSE4_1) av1_warp_affine = av1_warp_affine_sse4_1;
     if (flags & HAS_AVX2) av1_warp_affine = av1_warp_affine_avx2;
diff --git a/third_party/libaom/source/libaom b/third_party/libaom/source/libaom
index 5f8db64..82018ab 160000
--- a/third_party/libaom/source/libaom
+++ b/third_party/libaom/source/libaom
@@ -1 +1 @@
-Subproject commit 5f8db64abce68a3698fb732697ae50880bc9cac4
+Subproject commit 82018abee6cb2c4cb8b26cd83eff569e766f1722
diff --git a/third_party/perfetto b/third_party/perfetto
index 43ee4b9..c478eb8 160000
--- a/third_party/perfetto
+++ b/third_party/perfetto
@@ -1 +1 @@
-Subproject commit 43ee4b90e33bcc0c9191d569b74e6f76585d314a
+Subproject commit c478eb8ffb74aa961c2320efb2c901a5d1d69cba
diff --git a/third_party/re2/src b/third_party/re2/src
index 09de536..26f7d88 160000
--- a/third_party/re2/src
+++ b/third_party/re2/src
@@ -1 +1 @@
-Subproject commit 09de536bb7c77c2e0869a001f012d49560f56cbe
+Subproject commit 26f7d889e1f7e75e95e65490086538edf9f5275c
diff --git a/third_party/ruy/README.chromium b/third_party/ruy/README.chromium
index eeeaa10..c11dda7 100644
--- a/third_party/ruy/README.chromium
+++ b/third_party/ruy/README.chromium
@@ -1,8 +1,8 @@
 Name: The ruy matrix multiplication library
 Short Name: ruy
 URL: https://github.com/google/ruy
-Version: c04e5e52ae6b144f74ac032652e3c538bda15c9b
-Date: 2023/07/31
+Version: 6ffa93a89376555b09134c59b84d8f5e9cfc6ce6
+Date: 2023-09-25
 License: Apache 2
 License File: LICENSE
 Security Critical: Yes
diff --git a/third_party/ruy/src b/third_party/ruy/src
index c04e5e5..6ffa93a 160000
--- a/third_party/ruy/src
+++ b/third_party/ruy/src
@@ -1 +1 @@
-Subproject commit c04e5e52ae6b144f74ac032652e3c538bda15c9b
+Subproject commit 6ffa93a89376555b09134c59b84d8f5e9cfc6ce6
diff --git a/third_party/skia b/third_party/skia
index 31ceb16..b961fc3 160000
--- a/third_party/skia
+++ b/third_party/skia
@@ -1 +1 @@
-Subproject commit 31ceb1669d1cf6a82be0d7ec63aaaf14cce1a4d6
+Subproject commit b961fc35371508346c7552cb8f79651f154f10c3
diff --git a/third_party/tflite/README.chromium b/third_party/tflite/README.chromium
index e5e071c..2c58266e 100644
--- a/third_party/tflite/README.chromium
+++ b/third_party/tflite/README.chromium
@@ -1,8 +1,8 @@
 Name: TensorFlow Lite
 Short Name: tflite
 URL: https://github.com/tensorflow/tensorflow
-Version: bc6d7a48432f1c7e1fd9b34ee3e90c919982ab8c
-Date: 2023/09/18
+Version: edf7215123c67d76199d099779137b974b6e1293
+Date: 2023-09-25
 License: Apache 2.0
 License File: LICENSE
 Security Critical: Yes
diff --git a/third_party/tflite/src b/third_party/tflite/src
index bc6d7a4..edf7215 160000
--- a/third_party/tflite/src
+++ b/third_party/tflite/src
@@ -1 +1 @@
-Subproject commit bc6d7a48432f1c7e1fd9b34ee3e90c919982ab8c
+Subproject commit edf7215123c67d76199d099779137b974b6e1293
diff --git a/third_party/webgpu-cts/src b/third_party/webgpu-cts/src
index 0447990..a50d090 160000
--- a/third_party/webgpu-cts/src
+++ b/third_party/webgpu-cts/src
@@ -1 +1 @@
-Subproject commit 0447990a43973392ca18aec8a0422f67e5b6776e
+Subproject commit a50d0906eedac478595363ad1342787a581f9e2e
diff --git a/third_party/xnnpack/README.chromium b/third_party/xnnpack/README.chromium
index eebe49608..be641ac 100644
--- a/third_party/xnnpack/README.chromium
+++ b/third_party/xnnpack/README.chromium
@@ -1,8 +1,8 @@
 Name: XNNPACK
 Short Name: xnnpack
 URL: https://github.com/google/xnnpack
-Version: 60c997b99b3d98b8d146d267072cd4edb68535bd
-Date: 2023/09/11
+Version: bbbaa7352a3ea729987d3e654d37be93e8009691
+Date: 2023-09-25
 License: BSD
 License File: src/LICENSE
 Security Critical: Yes
diff --git a/third_party/xnnpack/src b/third_party/xnnpack/src
index 60c997b..bbbaa73 160000
--- a/third_party/xnnpack/src
+++ b/third_party/xnnpack/src
@@ -1 +1 @@
-Subproject commit 60c997b99b3d98b8d146d267072cd4edb68535bd
+Subproject commit bbbaa7352a3ea729987d3e654d37be93e8009691
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 370f7625..9b1c61b 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -578,7 +578,7 @@
       'linux-archive-rel-goma-rbe-ats-canary': 'release_bot',
       'linux-archive-rel-goma-rbe-canary': 'release_bot',
 
-      'mac-archive-rel-goma-rbe-canary': 'release_bot_mac_strip_minimal_symbols',
+      'mac-archive-rel-goma-rbe-canary': 'release_bot_minimal_symbols',
     },
 
     'chromium.gpu': {
@@ -1592,8 +1592,9 @@
       'android', 'cast_android', 'cast_receiver', 'clang', 'debug_static_bot_reclient',
     ],
 
+    # TODO(1486663): Change back to debug_bot_reclient when unit_tests binary size issue is resolved.
     'android_clang_asan_debug_bot_reclient': [
-      'android', 'clang', 'asan', 'debug_bot_reclient', 'strip_debug_info',
+      'android', 'clang', 'asan', 'debug_bot_reclient_nosymbols', 'strip_debug_info',
     ],
 
     'android_clang_asan_release_bot_reclient': [
@@ -3645,10 +3646,6 @@
       'release_bot_reclient', 'fuchsia', 'blink_symbol', 'minimal_symbols',
     ],
 
-    'release_bot_mac_strip_minimal_symbols': [
-      'release_bot', 'mac_strip', 'minimal_symbols',
-    ],
-
     'release_bot_mac_strip_minimal_symbols_arm64_reclient': [
       'release_bot_reclient', 'mac_strip', 'minimal_symbols', 'arm64',
     ],
@@ -3657,6 +3654,10 @@
       'release_bot_reclient', 'mac_strip', 'minimal_symbols',
     ],
 
+    'release_bot_minimal_symbols': [
+      'release_bot', 'minimal_symbols',
+    ],
+
     'release_bot_minimal_symbols_no_clang': [
       'release_bot', 'minimal_symbols', 'no_clang', 'no_goma',
     ],
@@ -4254,6 +4255,11 @@
       'mixins': ['debug', 'shared', 'reclient', 'minimal_symbols'],
     },
 
+    # TODO(1486663): Remove this when unit_tests binary size problem is resolved.
+    'debug_bot_reclient_nosymbols': {
+      'mixins': ['debug', 'shared', 'reclient', 'no_symbols'],
+    },
+
     'debug_static_bot': {
       'mixins': ['debug', 'static', 'minimal_symbols', 'goma'],
     },
diff --git a/tools/mb/mb_config_expectations/chromium.android.json b/tools/mb/mb_config_expectations/chromium.android.json
index 9a1d2caf..ba289cb 100644
--- a/tools/mb/mb_config_expectations/chromium.android.json
+++ b/tools/mb/mb_config_expectations/chromium.android.json
@@ -9,7 +9,7 @@
       "is_debug": true,
       "proprietary_codecs": true,
       "strip_debug_info": true,
-      "symbol_level": 1,
+      "symbol_level": 0,
       "target_os": "android",
       "use_remoteexec": true
     }
diff --git a/tools/mb/mb_config_expectations/chromium.goma.fyi.json b/tools/mb/mb_config_expectations/chromium.goma.fyi.json
index d6065e01..ce9f924 100644
--- a/tools/mb/mb_config_expectations/chromium.goma.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.goma.fyi.json
@@ -141,7 +141,6 @@
   "mac-archive-rel-goma-rbe-canary": {
     "gn_args": {
       "dcheck_always_on": false,
-      "enable_stripping": true,
       "is_component_build": false,
       "is_debug": false,
       "symbol_level": 1,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.android.json b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
index 4188a92..c2cd1ce 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.android.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
@@ -225,7 +225,7 @@
       "is_debug": true,
       "proprietary_codecs": true,
       "strip_debug_info": true,
-      "symbol_level": 1,
+      "symbol_level": 0,
       "target_os": "android",
       "use_remoteexec": true
     }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 48079cc..8aa9254 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -33866,7 +33866,6 @@
   <int value="1157" label="SafeBrowsingDeepScanningEnabled"/>
   <int value="1158" label="DriveFileSyncAvailable"/>
   <int value="1159" label="DeviceSwitchFunctionKeysBehaviorEnabled"/>
-  <int value="1160" label="DeviceDlcPredownloadList"/>
 </enum>
 
 <enum name="EnterprisePoliciesSources">
@@ -56565,11 +56564,13 @@
   <int value="0" label="Success"/>
   <int value="1" label="Failed - No Account"/>
   <int value="2" label="Failed - Not Eligible"/>
-  <int value="3" label="Failed - OAuth Token"/>
+  <int value="3" label="Deprecated"/>
   <int value="4" label="Failed - BSA Error 400"/>
   <int value="5" label="Failed - BSA Error 401"/>
   <int value="6" label="Failed - BSA Error 403"/>
   <int value="7" label="Failed - BSA Error Other"/>
+  <int value="8" label="Transient OAuth Token Failure"/>
+  <int value="9" label="Persistent OAuth Token Failure"/>
 </enum>
 
 <enum name="IppVersion">
@@ -61239,6 +61240,7 @@
   <int value="-1807092388" label="ReduceUserAgentPlatformOsCpu:enabled"/>
   <int value="-1806739839"
       label="UseLookalikesForNavigationSuggestions:disabled"/>
+  <int value="-1806173068" label="UseSharedImagesForPepperVideo:enabled"/>
   <int value="-1804485171" label="disable-fullscreen-tab-detaching"/>
   <int value="-1804411756" label="ClipboardSuggestionContentHidden:enabled"/>
   <int value="-1802905985" label="OmniboxExpandedStateSuggestIcons:enabled"/>
@@ -66780,6 +66782,7 @@
   <int value="948682684" label="BorealisDGPU:disabled"/>
   <int value="951048852" label="IOSPromoPasswordBubble:enabled"/>
   <int value="951111587" label="MediaAppPhotosIntegrationVideo:disabled"/>
+  <int value="951133343" label="UseSharedImagesForPepperVideo:disabled"/>
   <int value="951338017" label="SidePanelJourneysQueryless:enabled"/>
   <int value="952558794" label="enable-remote-assistance"/>
   <int value="952625847"
diff --git a/tools/metrics/histograms/metadata/arc/histograms.xml b/tools/metrics/histograms/metadata/arc/histograms.xml
index eb44789..b916065 100644
--- a/tools/metrics/histograms/metadata/arc/histograms.xml
+++ b/tools/metrics/histograms/metadata/arc/histograms.xml
@@ -143,6 +143,15 @@
   <variant name="ResumeMigration" summary="resume migration"/>
 </variants>
 
+<variants name="ChromeOSAppType">
+  <variant name="ArcApp"/>
+  <variant name="Browser"/>
+  <variant name="ChromeApp"/>
+  <variant name="CrostiniApp"/>
+  <variant name="Others"/>
+  <variant name="SystemApp"/>
+</variants>
+
 <variants name="FileTypeByDirectoryOrNot">
   <variant name="Directories" summary="directories"/>
   <variant name="Files"
@@ -1361,7 +1370,7 @@
 </histogram>
 
 <histogram name="Arc.GuestZram.TotalReclaimTime" units="ms"
-    expires_after="2023-10-01">
+    expires_after="2024-10-01">
   <owner>hungmn@google.com</owner>
   <owner>raging@google.com</owner>
   <owner>yuholong@google.com</owner>
@@ -1373,7 +1382,7 @@
 </histogram>
 
 <histogram name="Arc.GuestZram.UnreclaimedProcess" units="count"
-    expires_after="2023-10-01">
+    expires_after="2024-10-01">
   <owner>hungmn@google.com</owner>
   <owner>raging@google.com</owner>
   <owner>yuholong@google.com</owner>
@@ -2796,6 +2805,17 @@
   </summary>
 </histogram>
 
+<histogram name="Arc.WM.WindowMaximizedDelayTime.{ChromeOSAppType}" units="ms"
+    expires_after="2024-09-30">
+  <owner>lingyufeng@google.com</owner>
+  <owner>arc-framework@google.com</owner>
+  <summary>
+    Records the time elapsed from a window maximizing operation until the window
+    state is changed to be maximized. The data is collected once when a
+    maximizing operation happens.
+  </summary>
+</histogram>
+
 </histograms>
 
 </histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index 75a5d6a..edf9e2d 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -2448,7 +2448,7 @@
 </histogram>
 
 <histogram name="Ash.Desks.NumberOfWindowsClosed2" units="units"
-    expires_after="2024-03-10">
+    expires_after="2024-05-07">
   <owner>aprilzhou@google.com</owner>
   <owner>janetmac@chromium.org</owner>
   <summary>
@@ -2459,7 +2459,7 @@
 </histogram>
 
 <histogram name="Ash.Desks.NumberOfWindowsClosed2.{RemovalSource}"
-    units="windows" expires_after="2023-10-03">
+    units="windows" expires_after="2024-05-07">
   <owner>aprilzhou@google.com</owner>
   <owner>janetmac@chromium.org</owner>
   <summary>
@@ -6230,6 +6230,16 @@
   </summary>
 </histogram>
 
+<histogram name="Ash.Shelf.ShowStackedHotseat" enum="Boolean"
+    expires_after="2024-09-24">
+  <owner>jiamingc@google.com</owner>
+  <owner>cros-status-area-eng@google.com</owner>
+  <summary>
+    Show stacked hotseat app bar above the shelf button panels/system tray when
+    there is no enough space for the app bar.
+  </summary>
+</histogram>
+
 <histogram name="Ash.Shelf.ShutdownConfirmationBubble.Action"
     enum="ShutdownConfirmationBubbleAction" expires_after="2024-01-21">
   <owner>sherrilin@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index 6329173f..cec5a2a 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -9268,7 +9268,7 @@
 </histogram>
 
 <histogram name="PageImageService.Backend.Suggest.Result{ClientId}"
-    enum="PageImageServiceResult" expires_after="2023-11-08">
+    enum="PageImageServiceResult" expires_after="2024-02-20">
   <owner>tommycli@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>UI&gt;Browser&gt;Journeys</component>
diff --git a/tools/metrics/histograms/metadata/power/histograms.xml b/tools/metrics/histograms/metadata/power/histograms.xml
index 13b4f23..3c43fc0 100644
--- a/tools/metrics/histograms/metadata/power/histograms.xml
+++ b/tools/metrics/histograms/metadata/power/histograms.xml
@@ -2339,7 +2339,7 @@
 
 <histogram name="PowerML.SmartDimComponent.LoadComponentEvent"
     enum="PowerMLSmartDimComponentLoadComponentEvent"
-    expires_after="2023-11-01">
+    expires_after="2024-04-01">
   <owner>alanlxl@chromium.org</owner>
   <owner>amoylan@chromium.org</owner>
   <owner>napper@chromium.org</owner>
@@ -2350,7 +2350,7 @@
 </histogram>
 
 <histogram name="PowerML.SmartDimComponent.VersionType"
-    enum="PowerMLSmartDimComponentVersionType" expires_after="2023-11-01">
+    enum="PowerMLSmartDimComponentVersionType" expires_after="2024-04-01">
   <owner>alanlxl@chromium.org</owner>
   <owner>amoylan@chromium.org</owner>
   <owner>napper@chromium.org</owner>
@@ -2361,7 +2361,7 @@
 </histogram>
 
 <histogram name="PowerML.SmartDimComponent.WorkerType"
-    enum="PowerMLSmartDimComponentWorkerType" expires_after="2023-10-08">
+    enum="PowerMLSmartDimComponentWorkerType" expires_after="2024-04-01">
   <owner>alanlxl@chromium.org</owner>
   <owner>amoylan@chromium.org</owner>
   <owner>napper@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/search/histograms.xml b/tools/metrics/histograms/metadata/search/histograms.xml
index de863504..3196a6d 100644
--- a/tools/metrics/histograms/metadata/search/histograms.xml
+++ b/tools/metrics/histograms/metadata/search/histograms.xml
@@ -1491,6 +1491,19 @@
   </summary>
 </histogram>
 
+<histogram name="Search.Lens.ViewportDimensionsSent.Success" units="Boolean"
+    expires_after="2024-03-31">
+  <owner>mercerd@google.com</owner>
+  <owner>lens-chrome-eng@google.com</owner>
+  <summary>
+    When the user performs a Lens search on Desktop, records if the viewport
+    dimensions of the side panel were included in the request. A false value
+    indicates either the viewport width or height were not included in the
+    request. A true value is recorded if and only if both the `vpw` and `vph`
+    url params were added to the request with non-zero values.
+  </summary>
+</histogram>
+
 <histogram name="Search.PartnershipSearchPerformed" enum="SearchEntryPoint"
     expires_after="M85">
   <owner>yusufo@chromium.org</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 2148aa8..9833be1 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,8 +5,8 @@
             "full_remote_path": "perfetto-luci-artifacts/v37.0/linux-arm64/trace_processor_shell"
         },
         "win": {
-            "hash": "7ed930009091d9a0f408abe9967911e7ffbfdd1a",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/43ee4b90e33bcc0c9191d569b74e6f76585d314a/trace_processor_shell.exe"
+            "hash": "19d2164f44c41cb4d9b0fc94828760f78ea68040",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/c478eb8ffb74aa961c2320efb2c901a5d1d69cba/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "4ad0dc8eeae3ad92d6a1da2f1653a81fb9e3c4c1",
diff --git a/ui/file_manager/file_manager/background/js/BUILD.gn b/ui/file_manager/file_manager/background/js/BUILD.gn
index e3205a0d..7b04243 100644
--- a/ui/file_manager/file_manager/background/js/BUILD.gn
+++ b/ui/file_manager/file_manager/background/js/BUILD.gn
@@ -35,7 +35,6 @@
 
 js_type_check("closure_compile_jsmodules") {
   deps = [
-    ":app_window_wrapper",
     ":file_manager_base",
     ":file_operation_handler",
     ":file_operation_manager",
@@ -48,15 +47,18 @@
     ":volume_manager_factory",
     ":volume_manager_impl",
     ":volume_manager_util",
+    "//ui/file_manager:js_from_ts",
   ]
 
   closure_flags = strict_error_checking_closure_args + [
                     "language_in=ECMASCRIPT_2020",
+                    "js_module_root=./gen/ui/file_manager/tsc",
                     "js_module_root=./gen/ui/file_manager",
                     "js_module_root=" +
                         rebase_path("//ui/file_manager", root_build_dir),
                     "browser_resolver_prefix_replacements=\"chrome://webui-test/=./\"",
                     "hide_warnings_for=third_party/",
+                    "hide_warnings_for=gen/ui/file_manager/tsc/",
                     "browser_resolver_prefix_replacements=\"chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp/=./image_loader/\"",
                     "browser_resolver_prefix_replacements=\"chrome://file-manager/=./file_manager/\"",
                   ]
@@ -70,26 +72,20 @@
     ":mock_progress_center",
     ":mock_volume_manager",
     ":runtime_loaded_test_util",
+    "//ui/file_manager:js_from_ts",
   ]
   closure_flags =
       strict_error_checking_closure_args + [
         "language_in=ECMASCRIPT_2020",
+        "js_module_root=./gen/ui/file_manager/tsc",
         "js_module_root=./gen/ui",
         "js_module_root=" + rebase_path("//ui", root_build_dir),
         "browser_resolver_prefix_replacements=\"chrome://webui-test/=./\"",
         "hide_warnings_for=third_party/",
+        "hide_warnings_for=gen/ui/file_manager/tsc/",
       ]
 }
 
-js_library("app_window_wrapper") {
-  visibility += related_apps
-  deps = [
-    "//ui/file_manager/file_manager/common/js:api",
-    "//ui/file_manager/file_manager/common/js:async_util",
-    "//ui/file_manager/file_manager/common/js:files_app_state",
-  ]
-}
-
 js_library("file_manager_base") {
   visibility += [ "//ui/file_manager/file_manager/foreground/js:file_manager" ]
   deps = [
@@ -312,14 +308,17 @@
 
   closure_flags = strict_error_checking_closure_args + [
                     "language_in=ECMASCRIPT_2020",
-                    "js_module_root=./gen/ui/file_manager",
+                    "js_module_root=gen/ui/file_manager/tsc/",
+                    "js_module_root=gen/ui/file_manager/",
                     "js_module_root=" +
-                        rebase_path("//ui/file_manager", root_build_dir),
+                        rebase_path("//ui/file_manager/", root_build_dir),
                     "browser_resolver_prefix_replacements=\"chrome://webui-test/=./\"",
                     "hide_warnings_for=third_party/",
+                    "hide_warnings_for=gen/ui/file_manager/tsc/",
                     "browser_resolver_prefix_replacements=\"chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp/=./image_loader/\"",
                     "browser_resolver_prefix_replacements=\"chrome://file-manager/=./file_manager/\"",
                   ]
+  extra_deps = [ "//ui/file_manager:js_from_ts" ]
 }
 
 tsc_folder =
diff --git a/ui/file_manager/file_manager/background/js/app_window_wrapper.js b/ui/file_manager/file_manager/background/js/app_window_wrapper.js
deleted file mode 100644
index c296c5c..0000000
--- a/ui/file_manager/file_manager/background/js/app_window_wrapper.js
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {openWindow} from '../../common/js/api.js';
-import {AsyncQueue} from '../../common/js/async_util.js';
-import {FilesAppState} from '../../common/js/files_app_state.js';
-
-/** Coordinates the creation of new windows for Files app.  */
-export class AppWindowWrapper {
-  /**
-   * @param {string} url App window content url.
-   */
-  constructor(url) {
-    this.url_ = url;
-    /** @private {?FilesAppState} */
-    this.appState_ = null;
-    this.openingOrOpened_ = false;
-
-    /** @protected {!AsyncQueue} */
-    this.queue_ = new AsyncQueue();
-  }
-
-  /**
-   * Gets the launch lock, used to synchronize the asynchronous initialization
-   * steps.
-   *
-   * @return {Promise<function()>} A function to be called to release the lock.
-   */
-  async getLaunchLock() {
-    return this.queue_.lock();
-  }
-
-  /**
-   * Opens the window.
-   *
-   * @param {!FilesAppState} appState App state.
-   * @return {Promise} Resolved when the window is launched.
-   */
-  async launch(appState) {
-    // Check if the window is opened or not.
-    if (this.openingOrOpened_) {
-      console.warn('The window is already opened.');
-      return Promise.resolve();
-    }
-    this.openingOrOpened_ = true;
-
-    // Save application state.
-    this.appState_ = appState;
-
-    return this.launch_();
-  }
-
-  /**
-   * Opens a new window for the SWA.
-   *
-   * @return {Promise} Resolved when the window is launched.
-   * @private
-   */
-  async launch_() {
-    const unlock = await this.getLaunchLock();
-    try {
-      await this.createWindow_();
-    } catch (error) {
-      console.error(error);
-    } finally {
-      unlock();
-    }
-  }
-
-  /**
-   * @return {Promise} Resolved when the new window is opened.
-   * @private
-   */
-  async createWindow_() {
-    const url = this.appState_.currentDirectoryURL || '';
-    const result = await openWindow({
-      currentDirectoryURL: url,
-      selectionURL: this.appState_.selectionURL,
-    });
-
-    if (!result) {
-      throw new Error(`Failed to create window for ${url}`);
-    }
-  }
-}
diff --git a/ui/file_manager/file_manager/background/js/app_window_wrapper.ts b/ui/file_manager/file_manager/background/js/app_window_wrapper.ts
new file mode 100644
index 0000000..419ad8f9
--- /dev/null
+++ b/ui/file_manager/file_manager/background/js/app_window_wrapper.ts
@@ -0,0 +1,70 @@
+// Copyright 2014 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {openWindow} from '../../common/js/api.js';
+import {AsyncQueue} from '../../common/js/async_util.js';
+import {FilesAppState} from '../../common/js/files_app_state.js';
+
+/** Coordinates the creation of new windows for Files app.  */
+export class AppWindowWrapper {
+  private appState_: FilesAppState|null = null;
+  private openingOrOpened_: boolean = false;
+  protected queue_ = new AsyncQueue();
+
+  /**
+   * Gets the launch lock, used to synchronize the asynchronous initialization
+   * steps.
+   */
+  async getLaunchLock(): Promise<() => void> {
+    return this.queue_.lock();
+  }
+
+  /**
+   * Opens the window.
+   * @return Resolves when the window is launched.
+   */
+  async launch(appState: FilesAppState): Promise<void> {
+    // Check if the window is opened or not.
+    if (this.openingOrOpened_) {
+      console.warn('The window is already opened.');
+      return Promise.resolve();
+    }
+    this.openingOrOpened_ = true;
+
+    // Save application state.
+    this.appState_ = appState;
+
+    return this.launch_();
+  }
+
+  /**
+   * Opens a new window for the SWA. Returns a Promise which resolves when the
+   * window is launched.
+   */
+  private async launch_(): Promise<void> {
+    const unlock = await this.getLaunchLock();
+    try {
+      await this.createWindow_();
+    } catch (error) {
+      console.error(error);
+    } finally {
+      unlock();
+    }
+  }
+
+  /**
+   * Return a Promise which resolves when the new window is opened.
+   */
+  private async createWindow_(): Promise<void> {
+    const url = this.appState_!.currentDirectoryURL?.toString() || '';
+    const result = await openWindow({
+      currentDirectoryURL: url,
+      selectionURL: this.appState_!.selectionURL,
+    });
+
+    if (!result) {
+      throw new Error(`Failed to create window for ${url}`);
+    }
+  }
+}
diff --git a/ui/file_manager/file_manager/background/js/launcher.ts b/ui/file_manager/file_manager/background/js/launcher.ts
index f5bfb671..7be5d31 100644
--- a/ui/file_manager/file_manager/background/js/launcher.ts
+++ b/ui/file_manager/file_manager/background/js/launcher.ts
@@ -43,7 +43,8 @@
 
   await initializationPromise;
 
-  const appWindow = new AppWindowWrapper('main.html');
+  const appWindow = new AppWindowWrapper();
 
-  await appWindow.launch(appState || {});
+  // TODO: Remove `as FileAppsState` this type is an TS interface.
+  await appWindow.launch(appState || {} as FilesAppState);
 }
diff --git a/ui/file_manager/file_manager/common/js/files_app_state.js b/ui/file_manager/file_manager/common/js/files_app_state.js
index 5d9eb450..727664a3 100644
--- a/ui/file_manager/file_manager/common/js/files_app_state.js
+++ b/ui/file_manager/file_manager/common/js/files_app_state.js
@@ -26,14 +26,14 @@
      * The desired target directory when opening a new window.
      * @public {string|null|undefined}
      */
-    this.currentDirectoryURL;
+    this.currentDirectoryURL = undefined;
 
     /**
      * The URL for a file or directory to be selected once a new window is
      * spawned.
      * @public {string|undefined}
      */
-    this.selectionURL;
+    this.selectionURL = undefined;
 
     /**
      * For SaveAs dialog it prefills the <input> for the file name with this
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn
index 46b7d5b..657cfcd9 100644
--- a/ui/file_manager/file_manager/foreground/js/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -1118,10 +1118,9 @@
                     "language_in=ECMASCRIPT_2020",
                     "generate_exports=false",
                     "js_module_root=gen/ui/file_manager/tsc/",
-                    "js_module_root=./gen/ui",
+                    "js_module_root=./gen/ui/file_manager",
                     "js_module_root=" +
                         rebase_path("//ui/file_manager/", root_build_dir),
-                    "js_module_root=./gen/ui/file_manager/",
                     "jscomp_off=duplicate",
                     "browser_resolver_prefix_replacements=\"chrome://webui-test/=./\"",
                     "browser_resolver_prefix_replacements=\"chrome://file-manager/=./file_manager/\"",
diff --git a/ui/file_manager/file_names.gni b/ui/file_manager/file_names.gni
index 175dc19c..253a986 100644
--- a/ui/file_manager/file_names.gni
+++ b/ui/file_manager/file_names.gni
@@ -14,7 +14,6 @@
 
 static_js_files = [
   # Background:
-  "file_manager/background/js/app_window_wrapper.js",
   "file_manager/background/js/file_manager_base.js",
   "file_manager/background/js/file_operation_handler.js",
   "file_manager/background/js/file_operation_manager.js",
@@ -303,6 +302,7 @@
   "file_manager/foreground/js/ui/banners/types.ts",
 
   # Background.
+  "file_manager/background/js/app_window_wrapper.ts",
   "file_manager/background/js/crostini.ts",
   "file_manager/background/js/drive_sync_handler.ts",
   "file_manager/background/js/entry_location_impl.ts",