diff --git a/DEPS b/DEPS
index e1ab0a8..5c3819f2 100644
--- a/DEPS
+++ b/DEPS
@@ -297,7 +297,7 @@
   # 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': '61860c1148f35fe66498be4b431372bea28872b2',
+  'skia_revision': 'e8674a8843e228a0a8b8cbc7d0c453f226a734d7',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -305,7 +305,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': '9e3e203278ee3cfe52c64ac9dc9b4ecb2a2ef9ca',
+  'angle_revision': '0d5ba4dc4c0b33934c14734696c8f0fa34a6a1fd',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -313,7 +313,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '5d5c0eb382f3dd409ab49121a6ad8db59f72f9f0',
+  'pdfium_revision': 'cabc70aeee98f8747cf459d8a56b7e36840ae235',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -324,7 +324,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Fuchsia sdk
   # and whatever else without interference from each other.
-  'fuchsia_version': 'version:9.20220805.2.1',
+  'fuchsia_version': 'version:9.20220805.3.1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -368,7 +368,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'd4a09458ea5c4374e8280348b7eff6871dc8888a',
+  'catapult_revision': '1c7fc8f4bdb81fa561152ab0ecb2a5647cb08f8b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -376,7 +376,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '6d97228951a6c8884b3ac4b712e966e79f2bdc3c',
+  'devtools_frontend_revision': 'c82fdff2b06a6d6e6eff7d6d00504885bea29fd6',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -412,7 +412,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'a0df1384f207c4b3b36351bf75dd6dd6ec857901',
+  'dawn_revision': '8c60a92d5cf2ee858c524ae8cd41213a6121240b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -440,7 +440,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling nearby
   # and whatever else without interference from each other.
-  'nearby_revision': '4bf31d18da0faddcf0a39262c743c4ea95de95ac',
+  'nearby_revision': '4c70daf66fa93c57418a5b7f0cbb1d6d32333c98',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling securemessage
   # and whatever else without interference from each other.
@@ -952,7 +952,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'gAsD4l8EoP_W0IH5vzedZ1tyN3-wAP8-fqkaS_mX6rcC',
+          'version': 'oQVmxoZfDdo9Mj05wSSn9d3L7V49brnXoS-_uhaTmO4C',
       },
     ],
     'condition': 'checkout_android',
@@ -1613,7 +1613,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/r8',
-              'version': 'MQolCMavu5-KSAcEH_GUHAmKTQ1g5ydGaNBmKfh7czkC',
+              'version': '2hvl2k3joC-JDLAwGjZsfj41stBLPQ0yTXoLLdc0JycC',
           },
       ],
       'condition': 'checkout_android',
@@ -1693,7 +1693,7 @@
       'dep_type': 'cipd',
   },
 
-  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@7e4e5d736e846a65703dd908cdd95677b1492d97',
+  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@9e1fdf25c826ef360488fc53802cd62360892616',
 
   'src/third_party/vulkan_memory_allocator':
     Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907',
@@ -1805,7 +1805,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@58a9745cd53376e9943a6bfed836a1cc27e0561d',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@498fbb5835e00fa7a62dd3a71e12f9ff88e8231a',
     'condition': 'checkout_src_internal',
   },
 
@@ -1857,7 +1857,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': '2RhTW2BBRrFPnmJ_QJKH74XQxJz8GjrUWae3yd8C1AEC',
+        'version': '54LxIAPBZjnLUVKgH_W62Hds3qPMZE0mPnTKg8KG4toC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/ash/components/arc/mojom/auth.mojom b/ash/components/arc/mojom/auth.mojom
index 0cff50e..052b719 100644
--- a/ash/components/arc/mojom/auth.mojom
+++ b/ash/components/arc/mojom/auth.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Next MinVersion: 30
+// Next MinVersion: 31
 
 module arc.mojom;
 
@@ -250,6 +250,12 @@
     // Main account set in system properties is not found in Android
     // Account Manager.
     [MinVersion=27] MAIN_ACCOUNT_UNKNOWN = 1,
+
+    // Device Policy Controller account info is out of sync.
+    [MinVersion=30] DPC_OUT_OF_SYNC = 2,
+
+    // Used as a baseline to capture when reauth is not needed.
+    [MinVersion=30] NOT_NEEDED = 3,
 };
 
 [Extensible]
diff --git a/ash/components/arc/session/arc_vm_client_adapter.cc b/ash/components/arc/session/arc_vm_client_adapter.cc
index a0e98fc..5dea6d3d 100644
--- a/ash/components/arc/session/arc_vm_client_adapter.cc
+++ b/ash/components/arc/session/arc_vm_client_adapter.cc
@@ -504,9 +504,8 @@
     VLOG(1) << "Use BalanceAvailableBalloonPolicy";
   }
 
-  if (base::FeatureList::IsEnabled(kGuestZram)) {
+  if (base::FeatureList::IsEnabled(kGuestZram))
     request.set_guest_swappiness(kGuestZramSwappiness.Get());
-  }
 
   request.set_enable_consumer_auto_update_toggle(base::FeatureList::IsEnabled(
       ash::features::kConsumerAutoUpdateToggleAllowed));
diff --git a/ash/components/drivefs/drivefs_host_observer.h b/ash/components/drivefs/drivefs_host_observer.h
index cf63e46..88eec14 100644
--- a/ash/components/drivefs/drivefs_host_observer.h
+++ b/ash/components/drivefs/drivefs_host_observer.h
@@ -24,7 +24,7 @@
   virtual void OnError(const mojom::DriveError& error) {}
 
  protected:
-  ~DriveFsHostObserver() = default;
+  virtual ~DriveFsHostObserver() = default;
 };
 
 }  // namespace drivefs
diff --git a/ash/components/hid_detection/hid_detection_manager_impl.cc b/ash/components/hid_detection/hid_detection_manager_impl.cc
index 7ece9c5..edb1dac 100644
--- a/ash/components/hid_detection/hid_detection_manager_impl.cc
+++ b/ash/components/hid_detection/hid_detection_manager_impl.cc
@@ -87,6 +87,7 @@
                  << ", name: " << info->name;
   const std::string& device_id = info->id;
   device_id_to_device_map_[device_id] = std::move(info);
+  hid_detection::RecordHidConnected(*device_id_to_device_map_[device_id]);
 
   if (AttemptSetDeviceAsConnectedHid(*device_id_to_device_map_[device_id])) {
     NotifyHidDetectionStatusChanged();
diff --git a/ash/components/hid_detection/hid_detection_manager_impl_unittest.cc b/ash/components/hid_detection/hid_detection_manager_impl_unittest.cc
index 68d8ea4..f54e12f 100644
--- a/ash/components/hid_detection/hid_detection_manager_impl_unittest.cc
+++ b/ash/components/hid_detection/hid_detection_manager_impl_unittest.cc
@@ -139,7 +139,7 @@
     AddDevice(std::vector{hid_type}, device_type, id_out, name);
   }
 
-  void AddDevice(std::vector<TestHidType> hid_types,
+  void AddDevice(const std::vector<TestHidType>& hid_types,
                  InputDeviceType device_type,
                  std::string* id_out = nullptr,
                  const char* name = NULL) {
@@ -241,6 +241,13 @@
         "OOBE.HidDetectionScreen.InitialHidsMissing", count);
   }
 
+  void AssertHidConnectedCount(HidType hid_type, int count) {
+    histogram_tester_.ExpectBucketCount("OOBE.HidDetectionScreen.HidConnected",
+                                        hid_type, count);
+    histogram_tester_.ExpectTotalCount("OOBE.HidDetectionScreen.HidConnected",
+                                       count);
+  }
+
   size_t GetNumSetInputDevicesStatusCalls() {
     return fake_bluetooth_hid_detector_->num_set_input_devices_status_calls();
   }
@@ -308,6 +315,7 @@
 TEST_F(HidDetectionManagerImplTest, StartDetection_TouchscreenPreConnected) {
   AddDevice(TestHidType::kTouchscreen, InputDeviceType::TYPE_SERIO);
   EXPECT_EQ(0u, GetNumHidDetectionStatusChangedCalls());
+  AssertHidConnectedCount(HidType::kTouchscreen, /*count=*/0);
 
   StartHidDetection();
   EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
@@ -368,6 +376,41 @@
   StopHidDetection(/*should_be_using_bluetooth=*/false);
 }
 
+TEST_F(HidDetectionManagerImplTest, StartDetection_NonHidConnected) {
+  StartHidDetection();
+  EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
+  ASSERT_TRUE(GetLastHidDetectionStatus().has_value());
+  AssertHidDetectionStatus(
+      /*pointer_metadata=*/{InputState::kSearching,
+                            /*detected_hid_name=*/""},
+      /*keyboard_metadata=*/
+      {InputState::kSearching, /*detected_hid_name=*/""},
+      /*touchscreen_detected=*/false,
+      /*pairing_state=*/absl::nullopt);
+  EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
+  AssertInputDevicesStatus(
+      {.pointer_is_missing = true, .keyboard_is_missing = true});
+  AssertHidConnectedCount(HidType::kTouchscreen, /*count=*/0);
+
+  // Add a device without a HID type. This should not inform the delegate
+  // and no state changed.
+  std::vector<TestHidType> hid_types{};
+  AddDevice(hid_types, InputDeviceType::TYPE_USB);
+  EXPECT_EQ(1u, GetNumHidDetectionStatusChangedCalls());
+  AssertHidDetectionStatus(
+      /*pointer_metadata=*/{InputState::kSearching,
+                            /*detected_hid_name=*/""},
+      /*keyboard_metadata=*/
+      {InputState::kSearching, /*detected_hid_name=*/""},
+      /*touchscreen_detected=*/false,
+      /*pairing_state=*/absl::nullopt);
+  EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
+  AssertInputDevicesStatus(
+      {.pointer_is_missing = true, .keyboard_is_missing = true});
+  AssertHidConnectedCount(HidType::kBluetoothPointer, /*count=*/0);
+  StopHidDetection(/*should_be_using_bluetooth=*/false);
+}
+
 TEST_F(HidDetectionManagerImplTest,
        StartDetection_TouchscreenConnectedDisconnected) {
   StartHidDetection();
@@ -383,6 +426,7 @@
   EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
   AssertInputDevicesStatus(
       {.pointer_is_missing = true, .keyboard_is_missing = true});
+  AssertHidConnectedCount(HidType::kTouchscreen, /*count=*/0);
 
   std::string touchscreen_id1;
   AddDevice(TestHidType::kTouchscreen, InputDeviceType::TYPE_SERIO,
@@ -398,6 +442,7 @@
   EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
   AssertInputDevicesStatus(
       {.pointer_is_missing = true, .keyboard_is_missing = true});
+  AssertHidConnectedCount(HidType::kTouchscreen, /*count=*/1);
 
   RemoveDevice(touchscreen_id1);
   EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
@@ -440,6 +485,7 @@
   EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
   AssertInputDevicesStatus(
       {.pointer_is_missing = true, .keyboard_is_missing = true});
+  AssertHidConnectedCount(HidType::kTouchscreen, /*count=*/1);
 
   // Remove the touchscreen device. This should not inform the delegate.
   RemoveDevice(touchscreen_id2);
@@ -471,6 +517,7 @@
   EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
   AssertInputDevicesStatus(
       {.pointer_is_missing = true, .keyboard_is_missing = true});
+  AssertHidConnectedCount(HidType::kBluetoothPointer, /*count=*/0);
 
   std::string pointer_id1;
   AddDevice(TestHidType::kMouse, InputDeviceType::TYPE_BLUETOOTH, &pointer_id1);
@@ -484,6 +531,7 @@
   EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
   AssertInputDevicesStatus(
       {.pointer_is_missing = false, .keyboard_is_missing = true});
+  AssertHidConnectedCount(HidType::kBluetoothPointer, /*count=*/1);
 
   RemoveDevice(pointer_id1);
   EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
@@ -525,6 +573,7 @@
   EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
   AssertInputDevicesStatus(
       {.pointer_is_missing = true, .keyboard_is_missing = true});
+  AssertHidConnectedCount(HidType::kBluetoothPointer, /*count=*/1);
 
   // Remove the pointer device. This should not inform the delegate.
   RemoveDevice(pointer_id2);
@@ -556,6 +605,7 @@
   EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
   AssertInputDevicesStatus(
       {.pointer_is_missing = true, .keyboard_is_missing = true});
+  AssertHidConnectedCount(HidType::kUsbKeyboard, /*count=*/0);
 
   std::string keyboard_id1;
   AddDevice(TestHidType::kKeyboard, InputDeviceType::TYPE_USB, &keyboard_id1);
@@ -570,6 +620,7 @@
   EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
   AssertInputDevicesStatus(
       {.pointer_is_missing = true, .keyboard_is_missing = false});
+  AssertHidConnectedCount(HidType::kUsbKeyboard, /*count=*/1);
 
   RemoveDevice(keyboard_id1);
   EXPECT_EQ(3u, GetNumHidDetectionStatusChangedCalls());
@@ -611,6 +662,7 @@
   EXPECT_EQ(2u, GetNumSetInputDevicesStatusCalls());
   AssertInputDevicesStatus(
       {.pointer_is_missing = true, .keyboard_is_missing = true});
+  AssertHidConnectedCount(HidType::kUsbKeyboard, /*count=*/1);
 
   // Remove the keyboard device. This should not inform the delegate.
   RemoveDevice(keyboard_id2);
@@ -812,6 +864,7 @@
   EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
   AssertInputDevicesStatus(
       {.pointer_is_missing = true, .keyboard_is_missing = true});
+  AssertHidConnectedCount(HidType::kBluetoothPointer, /*count=*/0);
 
   SimulatePairingStarted(
       BluetoothHidMetadata{kTestHidName, BluetoothHidType::kPointer});
@@ -839,6 +892,7 @@
   EXPECT_EQ(1u, GetNumSetInputDevicesStatusCalls());
   AssertInputDevicesStatus(
       {.pointer_is_missing = false, .keyboard_is_missing = true});
+  AssertHidConnectedCount(HidType::kBluetoothPointer, /*count=*/1);
 
   SimulatePairingSessionEnded();
   EXPECT_EQ(4u, GetNumHidDetectionStatusChangedCalls());
@@ -914,6 +968,7 @@
   EXPECT_EQ(0u, GetNumSetInputDevicesStatusCalls());
   AssertInputDevicesStatus(
       {.pointer_is_missing = true, .keyboard_is_missing = true});
+  AssertHidConnectedCount(HidType::kBluetoothKeyboard, /*count=*/0);
 
   SimulatePairingStarted(
       BluetoothHidMetadata{kTestHidName, BluetoothHidType::kKeyboard});
@@ -942,6 +997,8 @@
   // Simulate the pairing succeeding.
   AddDevice(TestHidType::kKeyboard, InputDeviceType::TYPE_BLUETOOTH,
             /*id_out=*/nullptr, kTestHidName);
+  AssertHidConnectedCount(HidType::kBluetoothKeyboard, /*count=*/1);
+
   EXPECT_EQ(4u, GetNumHidDetectionStatusChangedCalls());
   AssertHidDetectionStatus(
       /*pointer_metadata=*/{InputState::kSearching, /*detected_hid_name=*/""},
diff --git a/ash/in_session_auth/DIR_METADATA b/ash/in_session_auth/DIR_METADATA
new file mode 100644
index 0000000..d3d821d
--- /dev/null
+++ b/ash/in_session_auth/DIR_METADATA
@@ -0,0 +1,5 @@
+team_email: "cros-lurs@google.com"
+os: CHROME_OS
+monorail {
+  component: "UI>Shell>LockScreen"
+}
diff --git a/ash/in_session_auth/OWNERS b/ash/in_session_auth/OWNERS
new file mode 100644
index 0000000..20e41d6
--- /dev/null
+++ b/ash/in_session_auth/OWNERS
@@ -0,0 +1 @@
+file://ash/login/LOGIN_LOCK_OWNERS
diff --git a/ash/projector/projector_controller_impl.cc b/ash/projector/projector_controller_impl.cc
index ff05f32..aa1eef9 100644
--- a/ash/projector/projector_controller_impl.cc
+++ b/ash/projector/projector_controller_impl.cc
@@ -148,7 +148,7 @@
 void ProjectorControllerImpl::CreateScreencastContainerFolder(
     CreateScreencastContainerFolderCallback callback) {
   base::FilePath mounted_path;
-  if (!client_->GetDriveFsMountPointPath(&mounted_path)) {
+  if (!client_->GetBaseStoragePath(&mounted_path)) {
     LOG(ERROR) << "Failed to get DriveFs mounted point path.";
     ProjectorUiController::ShowSaveFailureNotification();
     std::move(callback).Run(base::FilePath());
diff --git a/ash/projector/projector_controller_unittest.cc b/ash/projector/projector_controller_unittest.cc
index c43d9df..2bd6762 100644
--- a/ash/projector/projector_controller_unittest.cc
+++ b/ash/projector/projector_controller_unittest.cc
@@ -257,8 +257,7 @@
 
 TEST_F(ProjectorControllerTest, RecordingEnded) {
   base::FilePath screencast_container_path;
-  ASSERT_TRUE(
-      mock_client_.GetDriveFsMountPointPath(&screencast_container_path));
+  ASSERT_TRUE(mock_client_.GetBaseStoragePath(&screencast_container_path));
   ON_CALL(mock_client_, IsDriveFsMounted())
       .WillByDefault(testing::Return(true));
 
@@ -325,8 +324,7 @@
   bool user_deleted_video_file = std::get<1>(GetParam());
 
   base::FilePath screencast_container_path;
-  ASSERT_TRUE(
-      mock_client_.GetDriveFsMountPointPath(&screencast_container_path));
+  ASSERT_TRUE(mock_client_.GetBaseStoragePath(&screencast_container_path));
   ON_CALL(mock_client_, IsDriveFsMounted())
       .WillByDefault(testing::Return(true));
 
diff --git a/ash/public/cpp/projector/projector_client.h b/ash/public/cpp/projector/projector_client.h
index 33df33f..b18b1d2 100644
--- a/ash/public/cpp/projector/projector_client.h
+++ b/ash/public/cpp/projector/projector_client.h
@@ -28,8 +28,10 @@
 
   virtual void StartSpeechRecognition() = 0;
   virtual void StopSpeechRecognition() = 0;
-  // Returns false if Drive is not enabled.
-  virtual bool GetDriveFsMountPointPath(base::FilePath* result) const = 0;
+  // Returns false if base storage path is not available. Normally the base path
+  // is the DriveFS mounted folder. It is download folder when extended feature
+  // command line flag is disabled.
+  virtual bool GetBaseStoragePath(base::FilePath* result) const = 0;
   virtual bool IsDriveFsMounted() const = 0;
   // Return true if Drive mount failed. Drive will not automatically retry to
   // mount.
diff --git a/ash/public/cpp/test/mock_projector_client.cc b/ash/public/cpp/test/mock_projector_client.cc
index 5525f28e..bfd7e77 100644
--- a/ash/public/cpp/test/mock_projector_client.cc
+++ b/ash/public/cpp/test/mock_projector_client.cc
@@ -13,8 +13,7 @@
 
 MockProjectorClient::~MockProjectorClient() = default;
 
-bool MockProjectorClient::GetDriveFsMountPointPath(
-    base::FilePath* result) const {
+bool MockProjectorClient::GetBaseStoragePath(base::FilePath* result) const {
   *result = screencast_container_path_.GetPath();
   return true;
 }
diff --git a/ash/public/cpp/test/mock_projector_client.h b/ash/public/cpp/test/mock_projector_client.h
index 43d07f1..80e2f2c 100644
--- a/ash/public/cpp/test/mock_projector_client.h
+++ b/ash/public/cpp/test/mock_projector_client.h
@@ -30,7 +30,7 @@
   // ProjectorClient:
   MOCK_METHOD0(StartSpeechRecognition, void());
   MOCK_METHOD0(StopSpeechRecognition, void());
-  bool GetDriveFsMountPointPath(base::FilePath* result) const override;
+  bool GetBaseStoragePath(base::FilePath* result) const override;
   MOCK_CONST_METHOD0(IsDriveFsMounted, bool());
   MOCK_CONST_METHOD0(IsDriveFsMountFailed, bool());
   MOCK_CONST_METHOD0(OpenProjectorApp, void());
diff --git a/ash/webui/common/resources/cr_picture/cr_camera.js b/ash/webui/common/resources/cr_picture/cr_camera.js
index f48daae..bbb0fe8 100644
--- a/ash/webui/common/resources/cr_picture/cr_camera.js
+++ b/ash/webui/common/resources/cr_picture/cr_camera.js
@@ -8,7 +8,7 @@
  * user webcam to use as a Chrome OS profile picture.
  */
 import '//resources/cr_elements/shared_style_css.m.js';
-import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '//resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import '//resources/polymer/v3_0/iron-a11y-keys/iron-a11y-keys.js';
 import '//resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js';
 import './icons.html.js';
diff --git a/ash/webui/common/resources/cr_picture/cr_picture_pane.js b/ash/webui/common/resources/cr_picture/cr_picture_pane.js
index 32bf9d0..de35f86b 100644
--- a/ash/webui/common/resources/cr_picture/cr_picture_pane.js
+++ b/ash/webui/common/resources/cr_picture/cr_picture_pane.js
@@ -9,7 +9,7 @@
  */
 
 import '//resources/cr_elements/shared_style_css.m.js';
-import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '//resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import './cr_camera.js';
 
 import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/ash/webui/common/resources/page_toolbar.js b/ash/webui/common/resources/page_toolbar.js
index 0e015e9..dfbc1d35 100644
--- a/ash/webui/common/resources/page_toolbar.js
+++ b/ash/webui/common/resources/page_toolbar.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
diff --git a/ash/webui/personalization_app/resources/js/ambient/topic_source_item_element.ts b/ash/webui/personalization_app/resources/js/ambient/topic_source_item_element.ts
index 43795f2..9d1a671 100644
--- a/ash/webui/personalization_app/resources/js/ambient/topic_source_item_element.ts
+++ b/ash/webui/personalization_app/resources/js/ambient/topic_source_item_element.ts
@@ -7,7 +7,7 @@
  */
 
 import 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button_style_css.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
diff --git a/ash/webui/personalization_app/resources/js/personalization_breadcrumb_element.ts b/ash/webui/personalization_app/resources/js/personalization_breadcrumb_element.ts
index f93f7b5..424ada4 100644
--- a/ash/webui/personalization_app/resources/js/personalization_breadcrumb_element.ts
+++ b/ash/webui/personalization_app/resources/js/personalization_breadcrumb_element.ts
@@ -10,7 +10,7 @@
 
 import '/strings.m.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import 'chrome://resources/polymer/v3_0/iron-a11y-keys/iron-a11y-keys.js';
diff --git a/ash/webui/print_management/resources/print_job_entry.js b/ash/webui/print_management/resources/print_job_entry.js
index c88b1a1..b0d9bdc 100644
--- a/ash/webui/print_management/resources/print_job_entry.js
+++ b/ash/webui/print_management/resources/print_job_entry.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/mojo/mojo/public/mojom/base/big_buffer.mojom-lite.js';
diff --git a/ash/webui/scanning/resources/action_toolbar.js b/ash/webui/scanning/resources/action_toolbar.js
index 5edc76a9..bf32453 100644
--- a/ash/webui/scanning/resources/action_toolbar.js
+++ b/ash/webui/scanning/resources/action_toolbar.js
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import './scanning_shared_css.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
diff --git a/ash/webui/scanning/resources/scan_done_section.js b/ash/webui/scanning/resources/scan_done_section.js
index 09753e9..f01774f 100644
--- a/ash/webui/scanning/resources/scan_done_section.js
+++ b/ash/webui/scanning/resources/scan_done_section.js
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import './file_path.mojom-lite.js';
 
diff --git a/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.html b/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.html
index d7add02..521166f2 100644
--- a/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.html
+++ b/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.html
@@ -38,7 +38,8 @@
       border: 1px solid;
       border-color: var(--google-grey-200);
       border-radius: 8px;
-      width: 268px;
+      padding: 10px;
+      width: 180px;
     }
 
   #qrCodeWrapper {
diff --git a/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js b/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js
index 4baf731..c8b574c 100644
--- a/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js
+++ b/ash/webui/shimless_rma/resources/onboarding_enter_rsu_wp_disable_code_page.js
@@ -17,8 +17,6 @@
 
 // The size of each tile in pixels.
 const QR_CODE_TILE_SIZE = 5;
-// Amount of padding around the QR code in pixels.
-const QR_CODE_PADDING = 4 * QR_CODE_TILE_SIZE;
 // Styling for filled tiles in the QR code.
 const QR_CODE_FILL_STYLE = '#000000';
 
@@ -167,8 +165,7 @@
     if (!response || !response.qrCode) {
       return;
     }
-    this.canvasSize_ =
-        response.qrCode.size * QR_CODE_TILE_SIZE + 2 * QR_CODE_PADDING;
+    this.canvasSize_ = response.qrCode.size * QR_CODE_TILE_SIZE;
     const context = this.getCanvasContext_();
     context.clearRect(0, 0, this.canvasSize_, this.canvasSize_);
     context.fillStyle = QR_CODE_FILL_STYLE;
@@ -177,8 +174,7 @@
       for (let y = 0; y < response.qrCode.size; y++) {
         if (response.qrCode.data[index]) {
           context.fillRect(
-              x * QR_CODE_TILE_SIZE + QR_CODE_PADDING,
-              y * QR_CODE_TILE_SIZE + QR_CODE_PADDING, QR_CODE_TILE_SIZE,
+              x * QR_CODE_TILE_SIZE, y * QR_CODE_TILE_SIZE, QR_CODE_TILE_SIZE,
               QR_CODE_TILE_SIZE);
         }
         index++;
diff --git a/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.js b/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.js
index 72a646a..ca5e17a 100644
--- a/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.js
+++ b/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.js
@@ -4,7 +4,7 @@
 
 import './icons.js';
 import './shortcut_customization_shared_css.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index a1980cea..4b7c9bb 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-9.20220805.2.1
+9.20220805.3.1
diff --git a/chrome/VERSION b/chrome/VERSION
index 8eba71a..8412313 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=106
 MINOR=0
-BUILD=5222
+BUILD=5223
 PATCH=0
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayIntegrationTest.java
index 17ec41f..a9b4db236 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayIntegrationTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayIntegrationTest.java
@@ -43,6 +43,7 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisableIf;
 import org.chromium.base.test.util.DisabledTest;
+import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.autofill_assistant.proto.ActionProto;
 import org.chromium.chrome.browser.autofill_assistant.proto.BitmapDrawableProto;
 import org.chromium.chrome.browser.autofill_assistant.proto.ChipProto;
@@ -64,6 +65,7 @@
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill_assistant.R;
+import org.chromium.ui.test.util.UiRestriction;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -86,6 +88,7 @@
      */
     @Test
     @MediumTest
+    @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE})
     public void testShowCastOnDocumentElement() throws Exception {
         SelectorProto element = toCssSelector("#touch_area_one");
 
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 9ac2f18..882faba 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-106.0.5211.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-amd64-106.0.5221.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/app_management_strings.grdp b/chrome/app/app_management_strings.grdp
index 3876ef8..4884e79 100644
--- a/chrome/app/app_management_strings.grdp
+++ b/chrome/app/app_management_strings.grdp
@@ -163,7 +163,7 @@
       You can open and edit supported files with this app from the File Explorer or other apps. To control which files open in this app by default, go to <ph name="BEGIN_LINK">&lt;a href="#"&gt;</ph>Windows settings<ph name="END_LINK">&lt;/a&gt;</ph>.
     </message>
   </if>
-  <if expr="chromeos_ash or chromeos_lacros">
+  <if expr="is_chromeos">
     <message name="IDS_APP_MANAGEMENT_FILE_HANDLING_SET_DEFAULTS_LINK" desc="Further explanation of the File Handling API, including text describing the purpose of the toggle (referencing the ChromeOS Files app) and a link to a learn more link for default filetype associations.">
       You can open and edit supported files with this app from the Files app or other apps. To control which files open this app by default, <ph name="BEGIN_LINK">&lt;a href="#"&gt;</ph>learn how to set default apps on your device<ph name="END_LINK">&lt;/a&gt;</ph>.
     </message>
diff --git a/chrome/app/chromeos_shared_strings.grdp b/chrome/app/chromeos_shared_strings.grdp
index e229f7e..ad21960 100644
--- a/chrome/app/chromeos_shared_strings.grdp
+++ b/chrome/app/chromeos_shared_strings.grdp
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- ChromeOS-specific strings (included from generated_resources.grd).
      Shared between both Ash and Lacros.
-     Everything in this file is wrapped in <if expr="chromeos_ash or chromeos_lacros">. -->
+     Everything in this file is wrapped in <if expr="is_chromeos">. -->
 <grit-part>
 
   <!-- Settings -->
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index c52b1ab..fc71302 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -3333,6 +3333,15 @@
   <message name="IDS_NETWORK_UI_SET_TETHERING_CONFIG_BUTTON_TEXT" desc="Text for button which, when pressed, set the tethering configuration.">
     Set Tethering Configuration
   </message>
+  <message name="IDS_NETWORK_UI_TETHERING_READINESS_LABEL" desc="Title for the section for displaying and checking tethering readiness.">
+    Tethering Readiness:
+  </message>
+  <message name="IDS_NETWORK_UI_CHECK_TETHERING_READINESS_BUTTON_TEXT" desc="Text for button which, when pressed, check the tethering readiness.">
+    Check Tethering Readiness
+  </message>
+  <message name="IDS_NETWORK_UI_SET_TETHERING_ENABLED_LABEL" desc="Title for the section for enabling or disabling tethering.">
+    Enable/Disable Tethering
+  </message>
 
   <message name="IDS_DEVICE_LOG_LINK_TEXT" desc="Message preceeding link to chrome://device-log">
     To view network UI logs, see: <ph name="DEVICE_LOG_LINK">&lt;a href="chrome://device-log"&gt;chrome://device-log&lt;/a&gt;</ph>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_NETWORK_UI_CHECK_TETHERING_READINESS_BUTTON_TEXT.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_NETWORK_UI_CHECK_TETHERING_READINESS_BUTTON_TEXT.png.sha1
new file mode 100644
index 0000000..d3d4764
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_NETWORK_UI_CHECK_TETHERING_READINESS_BUTTON_TEXT.png.sha1
@@ -0,0 +1 @@
+377b96b74b3c27bb80058a5300c26df840d6c5d8
\ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_NETWORK_UI_SET_TETHERING_ENABLED_LABEL.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_NETWORK_UI_SET_TETHERING_ENABLED_LABEL.png.sha1
new file mode 100644
index 0000000..65907cf
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_NETWORK_UI_SET_TETHERING_ENABLED_LABEL.png.sha1
@@ -0,0 +1 @@
+be88a56b481ec0deb1f81f689c29e089933975a6
\ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_NETWORK_UI_TETHERING_READINESS_LABEL.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_NETWORK_UI_TETHERING_READINESS_LABEL.png.sha1
new file mode 100644
index 0000000..a1889be
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_NETWORK_UI_TETHERING_READINESS_LABEL.png.sha1
@@ -0,0 +1 @@
+3bdf5a0fc1893607e5f3552cb53c7f371bbcf098
\ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 2d50540..6b12742 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -295,7 +295,7 @@
       <part file="profiles_strings.grdp" />
 
       <!-- Chrome-OS-specific strings -->
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <part file="chromeos_shared_strings.grdp" />
       </if>
       <if expr="chromeos_ash">
@@ -379,7 +379,7 @@
         </message>
       </if>
 
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <message name="IDS_PERMISSIONS_REQUESTED_SCREENREADER_ANNOUNCEMENT" desc="Announcement to screen readers on ChromeOS when permission is requested to inform users of how to focus the permission UI.">
           Permission requested, press Ctrl + Forward to respond
         </message>
@@ -389,7 +389,7 @@
           Permission requested, press ⌘ + Option + Down arrow to respond
         </message>
       </if>
-      <if expr="not chromeos_ash and not chromeos_lacros and not is_macosx and toolkit_views">
+      <if expr="not is_chromeos and not is_macosx and toolkit_views">
         <message name="IDS_PERMISSIONS_REQUESTED_SCREENREADER_ANNOUNCEMENT" desc="Announcement to screen readers on Windows, Linux or Fuchsia when permission is requested to inform users of how to focus the permission UI.">
           Permission requested, press F6 to respond
         </message>
@@ -1409,7 +1409,7 @@
       </if>
 
       <!-- App menu -->
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <message name="IDS_TOGGLE_REQUEST_TABLET_SITE" desc="The toggle to request mobile version site on a touch dev.">
           Request mobile site
         </message>
@@ -1800,7 +1800,7 @@
                desc="When starting a download, let the user know we're starting the download.">
         Starting...
       </message>
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <message name="IDS_DOWNLOAD_STATUS_IN_PROGRESS_TITLE"
                  desc="The title of a download notification: the current download status is in progress.">
                  Downloading <ph name="FILE_NAME">$1<ex>somedocument.pdf</ex></ph>
@@ -2012,21 +2012,21 @@
         This file is encrypted. Ask its owner to decrypt.
       </message>
 
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <message name="IDS_PROMPT_BLOCKED_MIXED_DOWNLOAD_TITLE"
                  desc="In the download notification, a title of the message shown on a download blocked for being insecure.">
           Insecure download blocked
         </message>
       </if>
 
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <message name="IDS_PROMPT_BLOCKED_MALICIOUS_DOWNLOAD_TITLE"
                  desc="In the download notification, a title of message shown for blocked download">
           Dangerous download blocked
         </message>
       </if>
 
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <message name="IDS_PROMPT_SEND_TO_SAFEBROWSING_DOWNLOAD_TITLE"
                  desc="In the download notification, a title of message shown indicating that the file may be malicious and Safe Browsing recommends sending the file to Google">
           Scan file before opening?
@@ -4897,7 +4897,7 @@
         Could not load '<ph name="IMAGE_PATH">$1<ex>/path/to/file</ex></ph>' for theme.
       </message>
 
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <message name="IDS_EXTENSION_NOTIFICATION_INSTALLED" desc="Toast message shown when an application is successfully installed.">
           <ph name="APP">$1<ex>Google Keep</ex></ph> installed
         </message>
@@ -5651,7 +5651,7 @@
         App Settings
       </message>
 
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <then>
           <message name="IDS_WEB_APP_SETTINGS_LINK" desc="Text of the link pointing to the app settings page. This appears at the bottom of the Permissions pane of the Page Information Window for app windows (in place of 'Site settings').">
             App settings
@@ -7222,7 +7222,7 @@
           Open in app
         </message>
 
-        <if expr="chromeos_ash or chromeos_lacros">
+        <if expr="is_chromeos">
           <then>
             <message name="IDR_INTENT_PICKER_SUPPORTED_LINKS_INFOBAR_MESSAGE" desc="The text of an infobar asking if the user wants to open web links supported by a particular app (e.g. https://www.youtube.com) in that app.">
               Always use the <ph name="APP">$1<ex>YouTube</ex></ph> app to open supported web links?
@@ -8328,7 +8328,7 @@
  for unfollowing a site.">
           Unfollow site
         </message>
-        <if expr="chromeos_ash or chromeos_lacros">
+        <if expr="is_chromeos">
           <message name="IDS_TAB_CXMENU_GROUPED_BY_DESK_MENU_ITEM_A11Y" desc="The a11y message for menu items in 'Move tabs to another window' when grouped by desk.">
             <ph name="TAB_TITLE">$1<ex>Google News</ex></ph> belongs to desk <ph name="DESK_TITLE">$2<ex>School</ex></ph>
           </message>
@@ -8723,7 +8723,7 @@
         Send feedback
       </message>
       <!-- Killed Tab Strings -->
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <message name="IDS_KILLED_TAB_BY_OOM_MESSAGE" desc="The message displayed on the killed tab page when the page was killed by an out of memory error.">
           Either Chrome ran out of memory or the process for the webpage was terminated for some other reason.  To continue, reload or go to another page.
         </message>
@@ -11672,7 +11672,7 @@
       <message name="IDS_TAB_AX_LABEL_PINNED_FORMAT" is_accessibility_with_no_ui="true" desc="Accessibility label text, when a tab is pinned. Example: 'Google Search - Pinned'">
         <ph name="WINDOW_TITLE">$1<ex>Google Search</ex></ph> - Pinned
       </message>
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <message name="IDS_TAB_AX_LABEL_PERMISSION_REQUESTED_FORMAT" desc="Accessibility label text for ChromeOS, when a tab has a pending request. Example: 'Google Search - Permission requested, press F6 to respond'.">
           <ph name="WINDOW_TITLE">$1<ex>Google Search</ex></ph> - Permission requested, press Ctrl + Forward to respond
         </message>
@@ -11682,7 +11682,7 @@
           <ph name="WINDOW_TITLE">$1<ex>Google Search</ex></ph> - Permission requested, press ⌘ + Option + Up arrow to respond
         </message>
       </if>
-      <if expr="not chromeos_ash and not chromeos_lacros and not is_macosx and toolkit_views">
+      <if expr="not is_chromeos and not is_macosx and toolkit_views">
         <message name="IDS_TAB_AX_LABEL_PERMISSION_REQUESTED_FORMAT" desc="Accessibility label text for Windows, Linux or Fuchsia, when a tab has a pending request. Example: 'Google Search - Permission requested, press F6 to respond'.">
           <ph name="WINDOW_TITLE">$1<ex>Google Search</ex></ph> - Permission requested, press F6 to respond
         </message>
diff --git a/chrome/app/printing_strings.grdp b/chrome/app/printing_strings.grdp
index ae15f300..a3b65e6 100644
--- a/chrome/app/printing_strings.grdp
+++ b/chrome/app/printing_strings.grdp
@@ -262,7 +262,7 @@
     <message name="IDS_PRINT_PREVIEW_MANAGED_SETTINGS_TEXT" desc="Text shown when hovering over the enterprise managed icon in the header">
       These settings are enforced by your administrator
     </message>
-    <if expr="chromeos_ash or chromeos_lacros">
+    <if expr="is_chromeos">
       <message name="IDS_PRINT_PREVIEW_PRINT_TO_GOOGLE_DRIVE"
                desc="Option shown on printer drop-down list for saving previewed document to Google Drive.">
         Save to Google Drive
@@ -336,7 +336,7 @@
         other {Exceeds limit of {COUNT} sheets of paper}}
       </message>
     </if>
-    <if expr="not chromeos_ash and not chromeos_lacros">
+    <if expr="not is_chromeos">
       <message name="IDS_PRINT_PREVIEW_SYSTEM_DIALOG_OPTION" desc="Option allowing the user to access advanced printer settings using the native print system dialog instead of printing through the print preview mechanism. Shortcut key is not translated">
         Print using system dialog... <ph name="SHORTCUT_KEY">$1<ex>(Ctrl+Alt+P)</ex></ph>
       </message>
diff --git a/chrome/app/settings_chromium_strings.grdp b/chrome/app/settings_chromium_strings.grdp
index 632a81f..5c1d5a3 100644
--- a/chrome/app/settings_chromium_strings.grdp
+++ b/chrome/app/settings_chromium_strings.grdp
@@ -101,7 +101,7 @@
     To apply your changes, relaunch Chromium
   </message>
 
-  <if expr="not chromeos_ash and not chromeos_lacros">
+  <if expr="not is_chromeos">
     <message name="IDS_SETTINGS_SIGNIN_ALLOWED" desc="The title of the preference to allow to sign-in to Chrome">
     Allow Chromium sign-in
     </message>
@@ -114,7 +114,7 @@
   <message name="IDS_SETTINGS_SITE_SETTINGS_PDFS_BLOCKED" desc="Label for the disabled option of the pdfs content setting.">
     Open PDFs in Chromium
   </message>
-  <if expr="not chromeos_ash and not chromeos_lacros">
+  <if expr="not is_chromeos">
     <message name="IDS_SETTINGS_COOKIES_CLEAR_ON_EXIT_DESC" desc="Secondary text for the toggle that allows the user to automatically delete their cookies and site data when they close all browser windows. This sublabel clarifies that when the toggle is enabled the user will be signed out of Chrome each time they close all Chrome windows.">
       When on, you'll also be signed out of Chromium
     </message>
diff --git a/chrome/app/settings_google_chrome_strings.grdp b/chrome/app/settings_google_chrome_strings.grdp
index 0e6ac897..733d32e 100644
--- a/chrome/app/settings_google_chrome_strings.grdp
+++ b/chrome/app/settings_google_chrome_strings.grdp
@@ -115,7 +115,7 @@
     To apply your changes, relaunch Chrome
   </message>
 
-  <if expr="not chromeos_ash and not chromeos_lacros">
+  <if expr="not is_chromeos">
     <message name="IDS_SETTINGS_SIGNIN_ALLOWED" desc="The title of the preference to allow to sign-in to Chrome">
     Allow Chrome sign-in
     </message>
@@ -128,7 +128,7 @@
   <message name="IDS_SETTINGS_SITE_SETTINGS_PDFS_BLOCKED" desc="Label for the disabled option of the pdfs content setting.">
     Open PDFs in Chrome
   </message>
-  <if expr="not chromeos_ash and not chromeos_lacros">
+  <if expr="not is_chromeos">
     <message name="IDS_SETTINGS_COOKIES_CLEAR_ON_EXIT_DESC" desc="Secondary text for the toggle that allows the user to automatically delete their cookies and site data when they close all browser windows. This sublabel clarifies that when the toggle is enabled the user will be signed out of Chrome each time they close all Chrome windows.">
       When on, you'll also be signed out of Chrome
     </message>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index e111a09..04cb51e 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -124,12 +124,12 @@
   <message name="IDS_SETTINGS_HOME_BUTTON_DISABLED" desc="Sub label for the Show home button setting when disabled.">
     Disabled
   </message>
-  <if expr="chromeos_ash or chromeos_lacros">
+  <if expr="is_chromeos">
     <message name="IDS_SETTINGS_THEMES" desc="Name of the control which allows the user to get a theme for the browser.">
       Browser themes
     </message>
   </if>
-  <if expr="not chromeos_ash and not chromeos_lacros">
+  <if expr="not is_chromeos">
     <message name="IDS_SETTINGS_THEMES" desc="Name of the control which allows the user to get a theme for the browser.">
       Theme
     </message>
@@ -148,7 +148,7 @@
       Use Classic
     </message>
   </if>
-  <if expr="not is_linux or chromeos_ash or chromeos_lacros or is_fuchsia">
+  <if expr="not is_linux or is_chromeos or is_fuchsia">
     <message name="IDS_SETTINGS_RESET_TO_DEFAULT_THEME" desc="Name of the control which resets the browser theme back to the default theme.">
       Reset to default
     </message>
@@ -863,7 +863,7 @@
   </message>
 
   <!-- Default Browser Page -->
-  <if expr="not chromeos_ash and not chromeos_lacros">
+  <if expr="not is_chromeos">
     <message name="IDS_SETTINGS_DEFAULT_BROWSER" desc="Name of the Default Browser page, which allows users to set which browser will open .html files within the OS.">
       Default browser
     </message>
@@ -1053,7 +1053,7 @@
     <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_WRITE_ERROR_FORMAT" desc="The text in the error dialog for PKCS #12 file write errors.">
       There was an error while trying to write the file: <ph name="ERROR_TEXT">$1<ex>Permission denied.</ex></ph>.
     </message>
-    <if expr="chromeos_ash or chromeos_lacros">
+    <if expr="is_chromeos">
       <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_PROVISIONING_LIST_HEADER" desc="Header that lists the certificate provisioning processes.">
         Certificates are being provisioned for these certificate profiles
       </message>
@@ -1431,7 +1431,7 @@
   <message name="IDS_SETTINGS_PRIVACY_MORE" desc="Label on the expansion button to show more privacy settings.">
     More
   </message>
-  <if expr="chromeos_ash or chromeos_lacros">
+  <if expr="is_chromeos">
     <if expr="reven">
       <message name="IDS_SETTINGS_SECURE_DNS_OPEN_CHROME_OS_SETTINGS_LABEL" desc="Label for the section that allow users to open Secure DNS settings in ChromeOS Flex.">
         Manage secure DNS in ChromeOS Flex settings
@@ -3584,7 +3584,7 @@
     Control how your browsing history is used to personalize Search and more
   </message>
 
-  <if expr="not chromeos_ash and not chromeos_lacros">
+  <if expr="not is_chromeos">
     <!-- Import Settings Dialog -->
     <message name="IDS_SETTINGS_IMPORT_SETTINGS_TITLE" desc="Dialog title for import dialog.">
       Import bookmarks and settings
@@ -3691,7 +3691,7 @@
       System
     </message>
   </if>
-  <if expr="not chromeos_ash and not chromeos_lacros">
+  <if expr="not is_chromeos">
     <message name="IDS_SETTINGS_SYSTEM_HARDWARE_ACCELERATION_LABEL" desc="Label for the checkbox that forces Chrome to render via hardware acceleration (GPU) when available.">
       Use hardware acceleration when available
     </message>
diff --git a/chrome/app/shared_settings_strings.grdp b/chrome/app/shared_settings_strings.grdp
index ffb0732..b778eaa 100644
--- a/chrome/app/shared_settings_strings.grdp
+++ b/chrome/app/shared_settings_strings.grdp
@@ -374,7 +374,7 @@
     </message>
   </if>
 
-  <if expr="chromeos_ash or chromeos_lacros">
+  <if expr="is_chromeos">
     <message name="IDS_BROWSER_SETTINGS_SYNC_FEATURE_LABEL" desc="Label describing the browser sync feature.">
       Your data will be synced across all Chrome browsers where you have turned on sync for this account. For ChromeOS sync options, go to <ph name="LINK_BEGIN">&lt;a&gt;</ph>ChromeOS settings<ph name="LINK_END">&lt;/a&gt;</ph>.
     </message>
@@ -395,7 +395,7 @@
   </message>
 
   <!-- Password Prompt Dialog -->
-  <if expr="chromeos_ash or chromeos_lacros">
+  <if expr="is_chromeos">
     <message name="IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_TITLE" desc="Title of the password prompt dialog popup.">
       Confirm your password
     </message>
diff --git a/chrome/browser/apps/app_service/metrics/website_metrics.cc b/chrome/browser/apps/app_service/metrics/website_metrics.cc
index 23a3181..b9bb4f58 100644
--- a/chrome/browser/apps/app_service/metrics/website_metrics.cc
+++ b/chrome/browser/apps/app_service/metrics/website_metrics.cc
@@ -101,10 +101,37 @@
   owner_->OnInstallableWebAppStatusUpdated(web_contents());
 }
 
+WebsiteMetrics::UrlInfo::UrlInfo(const base::Value& value) {
+  const base::Value::Dict* data_dict = value.GetIfDict();
+  if (!data_dict) {
+    return;
+  }
+
+  absl::optional<base::TimeDelta> running_time_value =
+      base::ValueToTimeDelta(data_dict->Find(kRunningTimeKey));
+  if (!running_time_value.has_value()) {
+    return;
+  }
+
+  auto url_content_value = data_dict->FindInt(kUrlContentKey);
+  if (!url_content_value.has_value()) {
+    return;
+  }
+
+  auto promotable_value = data_dict->FindBool(kPromotableKey);
+  if (!promotable_value.has_value()) {
+    return;
+  }
+
+  running_time_in_two_hours = running_time_value.value();
+  url_content = static_cast<UrlContent>(url_content_value.value());
+  promotable = promotable_value.value();
+}
+
 base::Value WebsiteMetrics::UrlInfo::ConvertToValue() const {
   base::Value usage_time_dict(base::Value::Type::DICTIONARY);
   usage_time_dict.SetPath(kRunningTimeKey,
-                          base::TimeDeltaToValue(running_time));
+                          base::TimeDeltaToValue(running_time_in_two_hours));
   usage_time_dict.SetIntKey(kUrlContentKey, static_cast<int>(url_content));
   usage_time_dict.SetBoolKey(kPromotableKey, promotable);
   return usage_time_dict;
@@ -196,12 +223,20 @@
 }
 
 void WebsiteMetrics::OnFiveMinutes() {
+  // When the user logs in, there might be usage time for some websites saved in
+  // the user pref for the last login, and they haven't been recorded yet. So
+  // for the first five minutes, read the usage time saved in the user pref, and
+  // record the UKM, then save the new usage time to the user pref.
+  if (should_record_ukm_from_pref_) {
+    RecordUsageTimeFromPref();
+    should_record_ukm_from_pref_ = false;
+  }
+
   SaveUsageTime();
 }
 
 void WebsiteMetrics::OnTwoHours() {
-  // TODO(crbug.com/1334173): Records the usage time UKM, and reset the local
-  // variables after recording the UKM.
+  RecordUsageTime();
 
   std::map<GURL, UrlInfo> url_infos;
   for (const auto& it : webcontents_to_ukm_key_) {
@@ -425,8 +460,10 @@
     return;
   }
 
-  DCHECK_GE(base::TimeTicks::Now(), it->second.start_time);
-  it->second.running_time += base::TimeTicks::Now() - it->second.start_time;
+  auto current_time = base::TimeTicks::Now();
+  DCHECK_GE(current_time, it->second.start_time);
+  it->second.running_time_in_five_minutes +=
+      current_time - it->second.start_time;
   it->second.is_activated = false;
 }
 
@@ -435,13 +472,48 @@
                                          kWebsiteUsageTime);
   auto& dict = usage_time_update->GetDict();
   dict.clear();
-  for (auto it : url_infos_) {
+  for (auto& it : url_infos_) {
     if (it.second.is_activated) {
-      it.second.running_time += base::TimeTicks::Now() - it.second.start_time;
-      it.second.start_time = base::TimeTicks::Now();
+      auto current_time = base::TimeTicks::Now();
+      it.second.running_time_in_five_minutes +=
+          current_time - it.second.start_time;
+      it.second.start_time = current_time;
     }
-    if (!it.second.running_time.is_zero()) {
+    if (!it.second.running_time_in_five_minutes.is_zero()) {
+      it.second.running_time_in_two_hours +=
+          it.second.running_time_in_five_minutes;
       dict.Set(it.first.spec(), it.second.ConvertToValue());
+      it.second.running_time_in_five_minutes = base::TimeDelta();
+    }
+  }
+}
+
+void WebsiteMetrics::RecordUsageTime() {
+  for (auto& it : url_infos_) {
+    if (!it.second.running_time_in_two_hours.is_zero()) {
+      // TODO(crbug.com/1334173): Records the usage time UKM.
+      it.second.running_time_in_two_hours = base::TimeDelta();
+    }
+  }
+
+  // The app usage time AppKMs have been recorded, so clear the saved usage time
+  // in the user pref.
+  DictionaryPrefUpdate usage_time_update(profile_->GetPrefs(),
+                                         kWebsiteUsageTime);
+  usage_time_update->GetDict().clear();
+}
+
+void WebsiteMetrics::RecordUsageTimeFromPref() {
+  DictionaryPrefUpdate usage_time_update(profile_->GetPrefs(),
+                                         kWebsiteUsageTime);
+  if (!usage_time_update->is_dict()) {
+    return;
+  }
+
+  for (const auto [url, url_info_value] : usage_time_update->GetDict()) {
+    auto url_info = std::make_unique<UrlInfo>(url_info_value);
+    if (!url_info->running_time_in_two_hours.is_zero()) {
+      // TODO(crbug.com/1334173): Records the usage time UKM.
     }
   }
 }
diff --git a/chrome/browser/apps/app_service/metrics/website_metrics.h b/chrome/browser/apps/app_service/metrics/website_metrics.h
index 3af9b217e..c6a8ef8 100644
--- a/chrome/browser/apps/app_service/metrics/website_metrics.h
+++ b/chrome/browser/apps/app_service/metrics/website_metrics.h
@@ -124,8 +124,15 @@
   };
 
   struct UrlInfo {
+    UrlInfo() = default;
+    explicit UrlInfo(const base::Value& value);
     base::TimeTicks start_time;
-    base::TimeDelta running_time;
+    // Running time in the past 5 minutes without noise.
+    base::TimeDelta running_time_in_five_minutes;
+    // Sum `running_time_in_five_minutes` with noise in the past 2 hours:
+    // time1 * noise1 + time2 * noise2 + time3 * noise3....
+    base::TimeDelta running_time_in_two_hours;
+
     UrlContent url_content = UrlContent::kUnknown;
     bool is_activated = false;
     bool promotable = false;
@@ -185,6 +192,13 @@
   // minutes.
   void SaveUsageTime();
 
+  // Records the website usage time metrics each 2 hours.
+  void RecordUsageTime();
+
+  // Records the usage time UKM saved in the user pref at the first 5 minutes
+  // after the user logs in.
+  void RecordUsageTimeFromPref();
+
   const raw_ptr<Profile> profile_;
 
   BrowserTabStripTracker browser_tab_strip_tracker_;
@@ -210,6 +224,8 @@
   // UKM records. `url_infos_` is cleared after recording the UKM each 2 hours.
   std::map<GURL, UrlInfo> url_infos_;
 
+  bool should_record_ukm_from_pref_ = true;
+
   // A set of observed activation clients for all browser's windows.
   base::ScopedMultiSourceObservation<wm::ActivationClient,
                                      wm::ActivationChangeObserver>
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.cc b/chrome/browser/apps/app_service/publishers/arc_apps.cc
index 8762a6a..ec7927e 100644
--- a/chrome/browser/apps/app_service/publishers/arc_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/arc_apps.cc
@@ -161,31 +161,30 @@
   }
 }
 
-bool GetArcPermissionType(
-    apps::mojom::PermissionType app_service_permission_type,
-    arc::mojom::AppPermission& arc_permission) {
+bool GetArcPermissionType(apps::PermissionType app_service_permission_type,
+                          arc::mojom::AppPermission& arc_permission) {
   switch (app_service_permission_type) {
-    case apps::mojom::PermissionType::kCamera:
+    case apps::PermissionType::kCamera:
       arc_permission = arc::mojom::AppPermission::CAMERA;
       return true;
-    case apps::mojom::PermissionType::kLocation:
+    case apps::PermissionType::kLocation:
       arc_permission = arc::mojom::AppPermission::LOCATION;
       return true;
-    case apps::mojom::PermissionType::kMicrophone:
+    case apps::PermissionType::kMicrophone:
       arc_permission = arc::mojom::AppPermission::MICROPHONE;
       return true;
-    case apps::mojom::PermissionType::kNotifications:
+    case apps::PermissionType::kNotifications:
       arc_permission = arc::mojom::AppPermission::NOTIFICATIONS;
       return true;
-    case apps::mojom::PermissionType::kContacts:
+    case apps::PermissionType::kContacts:
       arc_permission = arc::mojom::AppPermission::CONTACTS;
       return true;
-    case apps::mojom::PermissionType::kStorage:
+    case apps::PermissionType::kStorage:
       arc_permission = arc::mojom::AppPermission::STORAGE;
       return true;
-    case apps::mojom::PermissionType::kUnknown:
-    case apps::mojom::PermissionType::kPrinting:
-    case apps::mojom::PermissionType::kFileHandling:
+    case apps::PermissionType::kUnknown:
+    case apps::PermissionType::kPrinting:
+    case apps::PermissionType::kFileHandling:
       return false;
   }
 }
@@ -971,6 +970,52 @@
   arc::ExecuteArcShortcutCommand(profile_, app_id, shortcut_id, display_id);
 }
 
+void ArcApps::SetPermission(const std::string& app_id,
+                            PermissionPtr permission) {
+  ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_);
+  if (!prefs) {
+    return;
+  }
+  const std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
+      prefs->GetApp(app_id);
+  if (!app_info) {
+    LOG(ERROR) << "SetPermission failed, could not find app with id " << app_id;
+    return;
+  }
+
+  auto* arc_service_manager = arc::ArcServiceManager::Get();
+  if (!arc_service_manager) {
+    LOG(WARNING) << "SetPermission failed, ArcServiceManager not available.";
+    return;
+  }
+
+  // TODO(crbug.com/1198390): Add unknown type for arc permissions enum.
+  arc::mojom::AppPermission permission_type = arc::mojom::AppPermission::CAMERA;
+
+  if (!GetArcPermissionType(permission->permission_type, permission_type)) {
+    LOG(ERROR) << "SetPermission failed, permission type not supported by ARC.";
+    return;
+  }
+
+  if (permission->IsPermissionEnabled()) {
+    auto* permissions_instance = ARC_GET_INSTANCE_FOR_METHOD(
+        arc_service_manager->arc_bridge_service()->app_permissions(),
+        GrantPermission);
+    if (permissions_instance) {
+      permissions_instance->GrantPermission(app_info->package_name,
+                                            permission_type);
+    }
+  } else {
+    auto* permissions_instance = ARC_GET_INSTANCE_FOR_METHOD(
+        arc_service_manager->arc_bridge_service()->app_permissions(),
+        RevokePermission);
+    if (permissions_instance) {
+      permissions_instance->RevokePermission(app_info->package_name,
+                                             permission_type);
+    }
+  }
+}
+
 void ArcApps::OnPreferredAppSet(
     const std::string& app_id,
     IntentFilterPtr intent_filter,
@@ -1213,48 +1258,7 @@
 
 void ArcApps::SetPermission(const std::string& app_id,
                             apps::mojom::PermissionPtr permission) {
-  ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_);
-  if (!prefs) {
-    return;
-  }
-  const std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
-      prefs->GetApp(app_id);
-  if (!app_info) {
-    LOG(ERROR) << "SetPermission failed, could not find app with id " << app_id;
-    return;
-  }
-
-  auto* arc_service_manager = arc::ArcServiceManager::Get();
-  if (!arc_service_manager) {
-    LOG(WARNING) << "SetPermission failed, ArcServiceManager not available.";
-    return;
-  }
-
-  // TODO(crbug.com/1198390): Add unknown type for arc permissions enum.
-  arc::mojom::AppPermission permission_type = arc::mojom::AppPermission::CAMERA;
-
-  if (!GetArcPermissionType(permission->permission_type, permission_type)) {
-    LOG(ERROR) << "SetPermission failed, permission type not supported by ARC.";
-    return;
-  }
-
-  if (apps_util::IsPermissionEnabled(permission->value)) {
-    auto* permissions_instance = ARC_GET_INSTANCE_FOR_METHOD(
-        arc_service_manager->arc_bridge_service()->app_permissions(),
-        GrantPermission);
-    if (permissions_instance) {
-      permissions_instance->GrantPermission(app_info->package_name,
-                                            permission_type);
-    }
-  } else {
-    auto* permissions_instance = ARC_GET_INSTANCE_FOR_METHOD(
-        arc_service_manager->arc_bridge_service()->app_permissions(),
-        RevokePermission);
-    if (permissions_instance) {
-      permissions_instance->RevokePermission(app_info->package_name,
-                                             permission_type);
-    }
-  }
+  SetPermission(app_id, ConvertMojomPermissionToPermission(permission));
 }
 
 void ArcApps::SetResizeLocked(const std::string& app_id,
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.h b/chrome/browser/apps/app_service/publishers/arc_apps.h
index 45b2b8d..cbb09a3 100644
--- a/chrome/browser/apps/app_service/publishers/arc_apps.h
+++ b/chrome/browser/apps/app_service/publishers/arc_apps.h
@@ -39,6 +39,7 @@
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/instance_registry.h"
 #include "components/services/app_service/public/cpp/intent.h"
+#include "components/services/app_service/public/cpp/permission.h"
 #include "components/services/app_service/public/cpp/publisher_base.h"
 #include "components/services/app_service/public/mojom/app_service.mojom.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -121,6 +122,7 @@
   void LaunchShortcut(const std::string& app_id,
                       const std::string& shortcut_id,
                       int64_t display_id) override;
+  void SetPermission(const std::string& app_id, PermissionPtr permission);
   void OnPreferredAppSet(
       const std::string& app_id,
       IntentFilterPtr intent_filter,
diff --git a/chrome/browser/ash/arc/intent_helper/arc_settings_service.cc b/chrome/browser/ash/arc/intent_helper/arc_settings_service.cc
index ed43845..e3a7287 100644
--- a/chrome/browser/ash/arc/intent_helper/arc_settings_service.cc
+++ b/chrome/browser/ash/arc/intent_helper/arc_settings_service.cc
@@ -101,8 +101,8 @@
   return !host->empty() && *port;
 }
 
-bool IsProxyAutoDetectionConfigured(const base::Value* proxy_config_dict) {
-  ProxyConfigDictionary dict(proxy_config_dict->Clone());
+bool IsProxyAutoDetectionConfigured(const base::Value& proxy_config_dict) {
+  ProxyConfigDictionary dict(proxy_config_dict.Clone());
   ProxyPrefs::ProxyMode mode;
   dict.GetMode(&mode);
   return mode == ProxyPrefs::MODE_AUTO_DETECT;
@@ -357,8 +357,9 @@
     //  configured to use the Web Proxy Auto-Discovery (WPAD) Protocol via the
     //  DHCP discovery method, the PAC URL will be propagated to Chrome via the
     //  default network properties.
-    if (dhcp_wpad_url_changed && IsProxyAutoDetectionConfigured(GetPrefs()->Get(
-                                     proxy_config::prefs::kProxy))) {
+    if (dhcp_wpad_url_changed &&
+        IsProxyAutoDetectionConfigured(
+            GetPrefs()->GetValue(proxy_config::prefs::kProxy))) {
       SyncProxySettings();
     }
     return;
@@ -382,7 +383,7 @@
   // Check if proxy auto detection is enabled. If yes, and the PAC URL set via
   // DHCP has changed, propagate the change to ARC.
   if (!default_proxy_config_.is_none() && dhcp_wpad_url_changed &&
-      IsProxyAutoDetectionConfigured(&default_proxy_config_)) {
+      IsProxyAutoDetectionConfigured(default_proxy_config_)) {
     sync_proxy = true;
   }
 
diff --git a/chrome/browser/ash/browser_context_keyed_service_factories.cc b/chrome/browser/ash/browser_context_keyed_service_factories.cc
index 0c4f4384..02e962c 100644
--- a/chrome/browser/ash/browser_context_keyed_service_factories.cc
+++ b/chrome/browser/ash/browser_context_keyed_service_factories.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/ash/kerberos/kerberos_credentials_manager_factory.h"
 #include "chrome/browser/ash/lock_screen_apps/lock_screen_apps.h"
 #include "chrome/browser/ash/login/easy_unlock/easy_unlock_service_factory.h"
+#include "chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager_factory.h"
 #include "chrome/browser/ash/login/signin_partition_manager.h"
 #include "chrome/browser/ash/nearby/nearby_dependencies_provider_factory.h"
 #include "chrome/browser/ash/nearby/nearby_process_manager_factory.h"
@@ -82,6 +83,7 @@
   guest_os::GuestOsRegistryServiceFactory::GetInstance();
   KerberosCredentialsManagerFactory::GetInstance();
   LockScreenAppsFactory::GetInstance();
+  LoginScreenExtensionsLifetimeManagerFactory::GetInstance();
   login::SigninPartitionManager::Factory::GetInstance();
   nearby::NearbyDependenciesProviderFactory::GetInstance();
   nearby::NearbyProcessManagerFactory::GetInstance();
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.cc b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
index 07594d0..ab5fd5d 100644
--- a/chrome/browser/ash/chrome_browser_main_parts_ash.cc
+++ b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
@@ -112,7 +112,6 @@
 #include "chrome/browser/ash/login/demo_mode/demo_session.h"
 #include "chrome/browser/ash/login/helper.h"
 #include "chrome/browser/ash/login/lock/screen_locker.h"
-#include "chrome/browser/ash/login/login_screen_extensions_lifetime_manager.h"
 #include "chrome/browser/ash/login/login_screen_extensions_storage_cleaner.h"
 #include "chrome/browser/ash/login/login_wizard.h"
 #include "chrome/browser/ash/login/session/chrome_session_manager.h"
@@ -1236,8 +1235,6 @@
     demo_mode_resources_remover_ = DemoModeResourcesRemover::CreateIfNeeded(
         g_browser_process->local_state());
 
-    login_screen_extensions_lifetime_manager_ =
-        std::make_unique<LoginScreenExtensionsLifetimeManager>();
     login_screen_extensions_storage_cleaner_ =
         std::make_unique<LoginScreenExtensionsStorageCleaner>();
   }
@@ -1478,7 +1475,6 @@
   lock_to_single_user_manager_.reset();
   wilco_dtc_supportd_manager_.reset();
   gnubby_notification_.reset();
-  login_screen_extensions_lifetime_manager_.reset();
   login_screen_extensions_storage_cleaner_.reset();
   debugd_notification_handler_.reset();
   shortcut_mapping_pref_service_.reset();
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.h b/chrome/browser/ash/chrome_browser_main_parts_ash.h
index 77853355..76416ca 100644
--- a/chrome/browser/ash/chrome_browser_main_parts_ash.h
+++ b/chrome/browser/ash/chrome_browser_main_parts_ash.h
@@ -80,7 +80,6 @@
 class FwupdDownloadClientImpl;
 class GnubbyNotification;
 class IdleActionWarningObserver;
-class LoginScreenExtensionsLifetimeManager;
 class LoginScreenExtensionsStorageCleaner;
 class LowDiskNotification;
 class NetworkPrefStateObserver;
@@ -264,8 +263,6 @@
 
   std::unique_ptr<policy::LockToSingleUserManager> lock_to_single_user_manager_;
   std::unique_ptr<WilcoDtcSupportdManager> wilco_dtc_supportd_manager_;
-  std::unique_ptr<LoginScreenExtensionsLifetimeManager>
-      login_screen_extensions_lifetime_manager_;
   std::unique_ptr<LoginScreenExtensionsStorageCleaner>
       login_screen_extensions_storage_cleaner_;
 
diff --git a/chrome/browser/ash/guest_os/guest_os_mime_types_service.cc b/chrome/browser/ash/guest_os/guest_os_mime_types_service.cc
index 2ad1348..52e24f3 100644
--- a/chrome/browser/ash/guest_os/guest_os_mime_types_service.cc
+++ b/chrome/browser/ash/guest_os/guest_os_mime_types_service.cc
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "base/logging.h"
-#include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "chrome/browser/ash/guest_os/guest_os_pref_names.h"
 #include "chrome/browser/profiles/profile.h"
@@ -18,78 +17,13 @@
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
 
-using vm_tools::apps::App;
-
 namespace guest_os {
 
-namespace {
-
-constexpr char kMimeTypeKey[] = "mime_type";
-
-}  // namespace
-
 GuestOsMimeTypesService::GuestOsMimeTypesService(Profile* profile)
     : prefs_(profile->GetPrefs()) {}
 
 GuestOsMimeTypesService::~GuestOsMimeTypesService() = default;
 
-// static
-// TODO(crbug.com/1015353): Can be removed after M99.
-void GuestOsMimeTypesService::MigrateVerboseMimeTypePrefs(
-    PrefService* pref_service) {
-  DictionaryPrefUpdate update(pref_service, prefs::kGuestOsMimeTypes);
-  base::Value* mime_types = update.Get();
-  std::map<std::string,
-           std::map<std::string, std::map<std::string, std::string>>>
-      migrated;
-  std::vector<std::string> to_remove;
-
-  for (const auto item : mime_types->DictItems()) {
-    std::vector<std::string> parts = base::SplitString(
-        item.first, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
-    if (parts.size() == 1) {
-      // Already migrated.
-      continue;
-    }
-
-    // Migrate: "termina/penguin/txt": { "mime_type": "text/plain" } to:
-    // "termina": { "penguin": { "txt": "text/plain" } }
-    to_remove.push_back(item.first);
-    std::string* mime_type;
-    if (parts.size() == 3 && item.second.is_dict() &&
-        (mime_type = item.second.FindStringKey(kMimeTypeKey))) {
-      migrated[parts[0]][parts[1]][parts[2]] = *mime_type;
-    } else {
-      LOG(ERROR) << "Deleting unexpected crostini.mime_types key " << item.first
-                 << "=" << item.second;
-    }
-  }
-
-  // Delete old values.
-  for (const std::string& s : to_remove) {
-    mime_types->RemoveKey(s);
-  }
-
-  auto get_or_create = [](base::Value* v, const std::string& k) {
-    base::Value* result = v->FindDictKey(k);
-    if (!result) {
-      result = v->SetKey(k, base::Value(base::Value::Type::DICTIONARY));
-    }
-    return result;
-  };
-
-  // Add migrated values.
-  for (const auto& vm_item : migrated) {
-    base::Value* vm = get_or_create(mime_types, vm_item.first);
-    for (const auto& container_item : vm_item.second) {
-      base::Value* container = get_or_create(vm, container_item.first);
-      for (const auto& ext : container_item.second) {
-        container->SetStringKey(ext.first, ext.second);
-      }
-    }
-  }
-}
-
 std::string GuestOsMimeTypesService::GetMimeType(
     const base::FilePath& file_path,
     const std::string& vm_name,
diff --git a/chrome/browser/ash/guest_os/guest_os_mime_types_service.h b/chrome/browser/ash/guest_os/guest_os_mime_types_service.h
index a2424943..b878c8e 100644
--- a/chrome/browser/ash/guest_os/guest_os_mime_types_service.h
+++ b/chrome/browser/ash/guest_os/guest_os_mime_types_service.h
@@ -31,10 +31,6 @@
   GuestOsMimeTypesService& operator=(const GuestOsMimeTypesService&) = delete;
   ~GuestOsMimeTypesService() override;
 
-  // Migrates from <vm_name>/<container_name>/<ext>: { "mime_type": ... } to
-  // <vm_name>: { <container_name>: { <ext>: <mime_type> } }.
-  static void MigrateVerboseMimeTypePrefs(PrefService* pref_service);
-
   // Returns a MIME type that corresponds to the file extension for the passed
   // in |file_path| for the specified |vm_name| and |container_name|. Returns
   // the empty string if there is no mapping.
diff --git a/chrome/browser/ash/guest_os/guest_os_mime_types_service_unittest.cc b/chrome/browser/ash/guest_os/guest_os_mime_types_service_unittest.cc
index b3839c3..65dd5b0 100644
--- a/chrome/browser/ash/guest_os/guest_os_mime_types_service_unittest.cc
+++ b/chrome/browser/ash/guest_os/guest_os_mime_types_service_unittest.cc
@@ -7,7 +7,6 @@
 #include <stddef.h>
 
 #include "base/files/file_path.h"
-#include "base/json/json_reader.h"
 #include "chrome/browser/ash/crostini/crostini_test_helper.h"
 #include "chrome/browser/ash/crostini/crostini_util.h"
 #include "chrome/test/base/testing_profile.h"
@@ -160,41 +159,4 @@
                                        "container 1"));
 }
 
-TEST_F(GuestOsMimeTypesServiceTest, Migrate) {
-  base::Value old = *base::JSONReader::Read(R"({
-    "termina/penguin/txt": { "mime_type": "text/plain" },
-    "termina/penguin/jpg": { "mime_type": "image/jpg" },
-    "termina/penguin/tar.gz": { "mime_type": "application/tar+gzip" },
-    "borealis/penguin/txt": { "mime_type": "text/plain" },
-    "termina": {
-      "penguin": {
-        "already": "x/already-migrated"
-      }
-    },
-    "delete/me": { "mime_type": "text/plain" },
-    "delete/me/as/well": { "mime_type": "text/plain" }
-  })");
-
-  base::Value expected = *base::JSONReader::Read(R"({
-    "termina": {
-      "penguin": {
-        "already": "x/already-migrated",
-        "txt": "text/plain",
-        "jpg": "image/jpg",
-        "tar.gz": "application/tar+gzip"
-      }
-    },
-    "borealis": {
-      "penguin": {
-        "txt": "text/plain"
-      }
-    }
-  })");
-
-  PrefService* prefs = profile()->GetPrefs();
-  prefs->Set("crostini.mime_types", std::move(old));
-  GuestOsMimeTypesService::MigrateVerboseMimeTypePrefs(prefs);
-  EXPECT_EQ(expected, prefs->GetValueDict("crostini.mime_types"));
-}
-
 }  // namespace guest_os
diff --git a/chrome/browser/ash/login/extensions/OWNERS b/chrome/browser/ash/login/extensions/OWNERS
new file mode 100644
index 0000000..4a32a834
--- /dev/null
+++ b/chrome/browser/ash/login/extensions/OWNERS
@@ -0,0 +1,3 @@
+file://chrome/browser/chromeos/extensions/login_screen/OWNERS
+
+emaxx@chromium.org
diff --git a/chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager.cc b/chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager.cc
new file mode 100644
index 0000000..6eb5ce8
--- /dev/null
+++ b/chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager.cc
@@ -0,0 +1,204 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager.h"
+
+#include "base/bind.h"
+#include "base/callback_helpers.h"
+#include "base/check.h"
+#include "base/check_is_test.h"
+#include "base/check_op.h"
+#include "base/location.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/values.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "components/prefs/pref_service.h"
+#include "components/session_manager/core/session_manager.h"
+#include "components/session_manager/session_manager_types.h"
+#include "extensions/browser/disable_reason.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/browser/pref_names.h"
+#include "extensions/browser/process_manager.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/extension_id.h"
+#include "extensions/common/manifest.h"
+
+namespace ash {
+
+LoginScreenExtensionsLifetimeManager::LoginScreenExtensionsLifetimeManager(
+    Profile* signin_original_profile)
+    : signin_original_profile_(signin_original_profile),
+      extension_system_(
+          extensions::ExtensionSystem::Get(signin_original_profile_)),
+      extensions_process_manager_(
+          extensions::ProcessManager::Get(signin_original_profile_)),
+      session_manager_(session_manager::SessionManager::Get()) {
+  DCHECK(signin_original_profile_);
+  DCHECK(extension_system_);
+  DCHECK(extensions_process_manager_);
+  DCHECK(session_manager_);
+
+  auto* const extension_registry =
+      extensions::ExtensionRegistry::Get(signin_original_profile_);
+  DCHECK(extension_registry);
+  extension_registry_observation_.Observe(extension_registry);
+
+  session_manager_observation_.Observe(session_manager_);
+
+  ProfileManager* const profile_manager = g_browser_process->profile_manager();
+  DCHECK(profile_manager);
+  profile_manager_observation_.Observe(profile_manager);
+
+  UpdateStateIfProfileReady();
+}
+
+LoginScreenExtensionsLifetimeManager::~LoginScreenExtensionsLifetimeManager() {
+  // `ShutDown()` and, optionally, `OnProfileManagerDestroying()` must have
+  // already been called until this point.
+  DCHECK(!profile_manager_observation_.IsObserving());
+}
+
+void LoginScreenExtensionsLifetimeManager::Shutdown() {
+  // We need to do it here in addition to `OnProfileManagerDestroying()`, in
+  // case the profile destruction happens before the profile manager's one.
+  profile_manager_observation_.Reset();
+
+  session_manager_observation_.Reset();
+  extension_registry_observation_.Reset();
+}
+
+void LoginScreenExtensionsLifetimeManager::OnProfileAdded(Profile* profile) {
+  if (profile == signin_original_profile_)
+    UpdateState();
+}
+
+void LoginScreenExtensionsLifetimeManager::OnProfileManagerDestroying() {
+  DCHECK(profile_manager_observation_.IsObserving());
+  // We need to do this here in addition to `Shutdown()`, because the profile
+  // manager destruction can start before the profile's one.
+  profile_manager_observation_.Reset();
+}
+
+void LoginScreenExtensionsLifetimeManager::OnSessionStateChanged() {
+  UpdateStateIfProfileReady();
+}
+
+void LoginScreenExtensionsLifetimeManager::OnExtensionLoaded(
+    content::BrowserContext* /*browser_context*/,
+    const extensions::Extension* extension) {
+  if (extension->location() ==
+          extensions::mojom::ManifestLocation::kExternalPolicyDownload &&
+      !ShouldEnableLoginScreenPolicyExtensions()) {
+    // The policy extensions should be disabled, however the extension got
+    // loaded - due to the policy change or due to some internal reason in the
+    // extensions subsystem. Therefore forcibly disable this extension.
+    // Doing this in an asynchronous job, in order to avoid confusing other
+    // observers of OnExtensionLoaded().
+    base::SequencedTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE,
+        base::BindOnce(&LoginScreenExtensionsLifetimeManager::DisableExtension,
+                       weak_factory_.GetWeakPtr(), extension->id()));
+  }
+}
+
+bool LoginScreenExtensionsLifetimeManager::
+    ShouldEnableLoginScreenPolicyExtensions() const {
+  // Note that extensions are intentionally allowed during the intermediate
+  // transition states between the login screen and the user session, since the
+  // user may still see some pieces of the login screen that rely on these
+  // extensions.
+  return session_manager_->session_state() !=
+         session_manager::SessionState::ACTIVE;
+}
+
+extensions::ExtensionService*
+LoginScreenExtensionsLifetimeManager::GetExtensionService() {
+  // Note that we cannot cache the service pointer in our constructor, because
+  // the service doesn't exist at that point.
+  extensions::ExtensionService* service =
+      extension_system_->extension_service();
+  if (!service) {
+    // Many unit tests skip initialization of profile services, including the
+    // extension service. In production, the service should always be present at
+    // this point (after the profile initialization completion).
+    CHECK_IS_TEST();
+  }
+  return service;
+}
+
+void LoginScreenExtensionsLifetimeManager::UpdateStateIfProfileReady() {
+  ProfileManager* const profile_manager = g_browser_process->profile_manager();
+  DCHECK(profile_manager);
+  if (!profile_manager->IsValidProfile(signin_original_profile_)) {
+    // Wait until the profile is initialized - see `OnProfileAdded()`.
+    return;
+  }
+  UpdateState();
+}
+
+void LoginScreenExtensionsLifetimeManager::UpdateState() {
+  if (ShouldEnableLoginScreenPolicyExtensions())
+    EnablePolicyExtensions();
+  else
+    DisablePolicyExtensions();
+}
+
+extensions::ExtensionIdList
+LoginScreenExtensionsLifetimeManager::GetPolicyExtensionIds() const {
+  const PrefService* const prefs = signin_original_profile_->GetPrefs();
+  DCHECK_NE(prefs->GetAllPrefStoresInitializationStatus(),
+            PrefService::INITIALIZATION_STATUS_WAITING);
+
+  const PrefService::Preference* const pref =
+      prefs->FindPreference(extensions::pref_names::kInstallForceList);
+  if (!pref || !pref->IsManaged() ||
+      pref->GetType() != base::Value::Type::DICTIONARY) {
+    return {};
+  }
+  extensions::ExtensionIdList extension_ids;
+  for (const auto item : pref->GetValue()->DictItems())
+    extension_ids.push_back(item.first);
+  return extension_ids;
+}
+
+void LoginScreenExtensionsLifetimeManager::DisablePolicyExtensions() {
+  extensions::ExtensionService* const extension_service = GetExtensionService();
+  if (!extension_service)
+    return;
+  for (const extensions::ExtensionId& extension_id : GetPolicyExtensionIds()) {
+    extension_service->DisableExtension(
+        extension_id, extensions::disable_reason::DISABLE_BLOCKED_BY_POLICY);
+  }
+}
+
+void LoginScreenExtensionsLifetimeManager::EnablePolicyExtensions() {
+  extensions::ExtensionService* const extension_service = GetExtensionService();
+  if (!extension_service)
+    return;
+  // This reapplies the policy. For the extensions that were previously
+  // disabled due to `DISABLE_BLOCKED_BY_POLICY`, this unsets this disable
+  // reason and reenables the extension.
+  extension_service->CheckManagementPolicy();
+
+  // Make sure the event pages for the login-screen extensions are loaded
+  // back, since they may need to do some operations on the Login/Lock Screen
+  // but are likely to have missed the session state change notification.
+  for (const extensions::ExtensionId& extension_id : GetPolicyExtensionIds())
+    extensions_process_manager_->WakeEventPage(extension_id, base::DoNothing());
+}
+
+void LoginScreenExtensionsLifetimeManager::DisableExtension(
+    const extensions::ExtensionId& extension_id) {
+  extensions::ExtensionService* const extension_service = GetExtensionService();
+  if (!extension_service)
+    return;
+  extension_service->DisableExtension(
+      extension_id, extensions::disable_reason::DISABLE_BLOCKED_BY_POLICY);
+}
+
+}  // namespace ash
diff --git a/chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager.h b/chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager.h
new file mode 100644
index 0000000..3b96c38
--- /dev/null
+++ b/chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager.h
@@ -0,0 +1,92 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ASH_LOGIN_EXTENSIONS_LOGIN_SCREEN_EXTENSIONS_LIFETIME_MANAGER_H_
+#define CHROME_BROWSER_ASH_LOGIN_EXTENSIONS_LOGIN_SCREEN_EXTENSIONS_LIFETIME_MANAGER_H_
+
+#include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/scoped_observation.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/profiles/profile_manager_observer.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "components/session_manager/core/session_manager.h"
+#include "components/session_manager/core/session_manager_observer.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_registry_observer.h"
+#include "extensions/common/extension_id.h"
+
+class Profile;
+
+namespace extensions {
+class ExtensionService;
+class ExtensionSystem;
+class ProcessManager;
+}  // namespace extensions
+
+namespace ash {
+
+// Manages the lifetime of the login-screen policy-installed extensions and
+// apps, making sure that they are stopped during an active user session.
+class LoginScreenExtensionsLifetimeManager final
+    : public KeyedService,
+      public ProfileManagerObserver,
+      public session_manager::SessionManagerObserver,
+      public extensions::ExtensionRegistryObserver {
+ public:
+  explicit LoginScreenExtensionsLifetimeManager(
+      Profile* signin_original_profile);
+  LoginScreenExtensionsLifetimeManager(
+      const LoginScreenExtensionsLifetimeManager&) = delete;
+  LoginScreenExtensionsLifetimeManager& operator=(
+      const LoginScreenExtensionsLifetimeManager&) = delete;
+  ~LoginScreenExtensionsLifetimeManager() override;
+
+  // KeyedService:
+  void Shutdown() override;
+
+  // ProfileManagerObserver:
+  void OnProfileAdded(Profile* profile) override;
+  void OnProfileManagerDestroying() override;
+
+  // session_manager::SessionManagerObserver:
+  void OnSessionStateChanged() override;
+
+  // extensions::ExtensionRegistryObserver:
+  void OnExtensionLoaded(content::BrowserContext* browser_context,
+                         const extensions::Extension* extension) override;
+
+ private:
+  bool ShouldEnableLoginScreenPolicyExtensions() const;
+  extensions::ExtensionService* GetExtensionService();
+  void UpdateStateIfProfileReady();
+  void UpdateState();
+  extensions::ExtensionIdList GetPolicyExtensionIds() const;
+  void DisablePolicyExtensions();
+  void EnablePolicyExtensions();
+  void DisableExtension(const extensions::ExtensionId& extension_id);
+
+  // Unowned pointers:
+  raw_ptr<Profile> const signin_original_profile_;
+  raw_ptr<extensions::ExtensionSystem> const extension_system_;
+  raw_ptr<extensions::ProcessManager> const extensions_process_manager_;
+  raw_ptr<session_manager::SessionManager> const session_manager_;
+
+  base::ScopedObservation<extensions::ExtensionRegistry,
+                          extensions::ExtensionRegistryObserver>
+      extension_registry_observation_{this};
+  base::ScopedObservation<session_manager::SessionManager,
+                          session_manager::SessionManagerObserver>
+      session_manager_observation_{this};
+  base::ScopedObservation<ProfileManager, ProfileManagerObserver>
+      profile_manager_observation_{this};
+
+  // Must be the last member.
+  base::WeakPtrFactory<LoginScreenExtensionsLifetimeManager> weak_factory_{
+      this};
+};
+
+}  // namespace ash
+
+#endif  // CHROME_BROWSER_ASH_LOGIN_EXTENSIONS_LOGIN_SCREEN_EXTENSIONS_LIFETIME_MANAGER_H_
diff --git a/chrome/browser/ash/login/login_screen_extensions_lifetime_manager_browsertest.cc b/chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager_browsertest.cc
similarity index 98%
rename from chrome/browser/ash/login/login_screen_extensions_lifetime_manager_browsertest.cc
rename to chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager_browsertest.cc
index e80c8b2..a37814a 100644
--- a/chrome/browser/ash/login/login_screen_extensions_lifetime_manager_browsertest.cc
+++ b/chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager_browsertest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ash/login/login_screen_extensions_lifetime_manager.h"
+#include "chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager.h"
 
 #include <string>
 
diff --git a/chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager_factory.cc b/chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager_factory.cc
new file mode 100644
index 0000000..92731bd
--- /dev/null
+++ b/chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager_factory.cc
@@ -0,0 +1,74 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager_factory.h"
+
+#include "base/check_is_test.h"
+#include "base/no_destructor.h"
+#include "chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager.h"
+#include "chrome/browser/ash/profiles/profile_helper.h"
+#include "chrome/browser/extensions/extension_system_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+#include "components/session_manager/core/session_manager.h"
+#include "extensions/browser/extension_registry_factory.h"
+#include "extensions/browser/process_manager_factory.h"
+
+namespace ash {
+
+LoginScreenExtensionsLifetimeManager*
+LoginScreenExtensionsLifetimeManagerFactory::GetForProfile(Profile* profile) {
+  return static_cast<LoginScreenExtensionsLifetimeManager*>(
+      GetInstance()->GetServiceForBrowserContext(profile, /*create=*/true));
+}
+
+LoginScreenExtensionsLifetimeManagerFactory*
+LoginScreenExtensionsLifetimeManagerFactory::GetInstance() {
+  static base::NoDestructor<LoginScreenExtensionsLifetimeManagerFactory>
+      instance;
+  return instance.get();
+}
+
+LoginScreenExtensionsLifetimeManagerFactory::
+    LoginScreenExtensionsLifetimeManagerFactory()
+    : BrowserContextKeyedServiceFactory(
+          "LoginScreenExtensionsLifetimeManager",
+          BrowserContextDependencyManager::GetInstance()) {
+  DependsOn(extensions::ExtensionRegistryFactory::GetInstance());
+  DependsOn(extensions::ExtensionSystemFactory::GetInstance());
+  DependsOn(extensions::ProcessManagerFactory::GetInstance());
+}
+
+LoginScreenExtensionsLifetimeManagerFactory::
+    ~LoginScreenExtensionsLifetimeManagerFactory() = default;
+
+KeyedService*
+LoginScreenExtensionsLifetimeManagerFactory::BuildServiceInstanceFor(
+    content::BrowserContext* context) const {
+  // Exit early in unit tests that don't initialize prerequisites for the
+  // manager.
+  if (!session_manager::SessionManager::Get()) {
+    CHECK_IS_TEST();
+    return nullptr;
+  }
+
+  Profile* profile = Profile::FromBrowserContext(context);
+  if (!profile)
+    return nullptr;
+  if (!ProfileHelper::IsSigninProfile(profile)) {
+    // The manager should only be created for the sign-in profile.
+    return nullptr;
+  }
+  return new LoginScreenExtensionsLifetimeManager(profile);
+}
+
+bool LoginScreenExtensionsLifetimeManagerFactory::
+    ServiceIsCreatedWithBrowserContext() const {
+  // The manager works in the background, regardless of whether something tried
+  // to access it via the factory.
+  return true;
+}
+
+}  // namespace ash
diff --git a/chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager_factory.h b/chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager_factory.h
new file mode 100644
index 0000000..22fc5aa
--- /dev/null
+++ b/chrome/browser/ash/login/extensions/login_screen_extensions_lifetime_manager_factory.h
@@ -0,0 +1,42 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ASH_LOGIN_EXTENSIONS_LOGIN_SCREEN_EXTENSIONS_LIFETIME_MANAGER_FACTORY_H_
+#define CHROME_BROWSER_ASH_LOGIN_EXTENSIONS_LOGIN_SCREEN_EXTENSIONS_LIFETIME_MANAGER_FACTORY_H_
+
+#include "base/no_destructor.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+class KeyedService;
+class Profile;
+
+namespace content {
+class BrowserContext;
+}
+
+namespace ash {
+
+class LoginScreenExtensionsLifetimeManager;
+
+class LoginScreenExtensionsLifetimeManagerFactory
+    : public BrowserContextKeyedServiceFactory {
+ public:
+  static LoginScreenExtensionsLifetimeManager* GetForProfile(Profile* profile);
+  static LoginScreenExtensionsLifetimeManagerFactory* GetInstance();
+
+ private:
+  friend class base::NoDestructor<LoginScreenExtensionsLifetimeManagerFactory>;
+
+  LoginScreenExtensionsLifetimeManagerFactory();
+  ~LoginScreenExtensionsLifetimeManagerFactory() override;
+
+  // BrowserContextKeyedServiceFactory:
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* context) const override;
+  bool ServiceIsCreatedWithBrowserContext() const override;
+};
+
+}  // namespace ash
+
+#endif  // CHROME_BROWSER_ASH_LOGIN_EXTENSIONS_LOGIN_SCREEN_EXTENSIONS_LIFETIME_MANAGER_FACTORY_H_
diff --git a/chrome/browser/ash/login/login_screen_extensions_lifetime_manager.cc b/chrome/browser/ash/login/login_screen_extensions_lifetime_manager.cc
deleted file mode 100644
index a9821b9..0000000
--- a/chrome/browser/ash/login/login_screen_extensions_lifetime_manager.cc
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ash/login/login_screen_extensions_lifetime_manager.h"
-
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/check_op.h"
-#include "base/location.h"
-#include "base/threading/sequenced_task_runner_handle.h"
-#include "base/values.h"
-#include "chrome/browser/ash/profiles/profile_helper.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/profiles/profile.h"
-#include "components/prefs/pref_service.h"
-#include "components/session_manager/core/session_manager.h"
-#include "components/session_manager/session_manager_types.h"
-#include "extensions/browser/disable_reason.h"
-#include "extensions/browser/extension_registry.h"
-#include "extensions/browser/extension_system.h"
-#include "extensions/browser/pref_names.h"
-#include "extensions/browser/process_manager.h"
-#include "extensions/common/extension.h"
-#include "extensions/common/extension_id.h"
-#include "extensions/common/manifest.h"
-
-namespace ash {
-namespace {
-
-void DisableLoginScreenExtension(const extensions::ExtensionId& extension_id) {
-  extensions::ExtensionSystem::Get(ProfileHelper::GetSigninProfile())
-      ->extension_service()
-      ->DisableExtension(extension_id,
-                         extensions::disable_reason::DISABLE_BLOCKED_BY_POLICY);
-}
-
-std::vector<std::string> GetLoginScreenPolicyExtensionIds() {
-  DCHECK(ProfileHelper::IsSigninProfileInitialized());
-
-  const PrefService* const prefs =
-      ProfileHelper::GetSigninProfile()->GetPrefs();
-  DCHECK_EQ(prefs->GetAllPrefStoresInitializationStatus(),
-            PrefService::INITIALIZATION_STATUS_SUCCESS);
-
-  const PrefService::Preference* const pref =
-      prefs->FindPreference(extensions::pref_names::kInstallForceList);
-  if (!pref || !pref->IsManaged() ||
-      pref->GetType() != base::Value::Type::DICTIONARY) {
-    return {};
-  }
-  std::vector<std::string> extension_ids;
-  for (const auto item : pref->GetValue()->DictItems())
-    extension_ids.push_back(item.first);
-  return extension_ids;
-}
-
-void DisableLoginScreenPolicyExtensions() {
-  DCHECK(ProfileHelper::IsSigninProfileInitialized());
-
-  extensions::ExtensionService* const extension_service =
-      extensions::ExtensionSystem::Get(ProfileHelper::GetSigninProfile())
-          ->extension_service();
-  for (const std::string& extension_id : GetLoginScreenPolicyExtensionIds()) {
-    extension_service->DisableExtension(
-        extension_id, extensions::disable_reason::DISABLE_BLOCKED_BY_POLICY);
-  }
-}
-
-void EnableLoginScreenPolicyExtensions() {
-  DCHECK(ProfileHelper::IsSigninProfileInitialized());
-
-  Profile* const signin_profile = ProfileHelper::GetSigninProfile();
-  extensions::ExtensionService* const extension_service =
-      extensions::ExtensionSystem::Get(signin_profile)->extension_service();
-  // This reapplies the policy. For the extensions that were previously disabled
-  // due to `DISABLE_BLOCKED_BY_POLICY`, this unsets this disable reason and
-  // reenables the extension.
-  extension_service->CheckManagementPolicy();
-
-  // Make sure the event pages for the login-screen extensions are loaded back,
-  // since they may need to do some operations on the Login/Lock Screen but are
-  // likely to have missed the session state change notification.
-  extensions::ProcessManager* extensions_process_manager =
-      extensions::ProcessManager::Get(signin_profile->GetOriginalProfile());
-  for (const std::string& extension_id : GetLoginScreenPolicyExtensionIds())
-    extensions_process_manager->WakeEventPage(extension_id, base::DoNothing());
-}
-
-bool ShouldEnableLoginScreenPolicyExtensions() {
-  // Note that extensions are intentionally allowed during the intermediate
-  // transition states between the login screen and the user session, since the
-  // user may still see some pieces of the login screen that rely on these
-  // extensions.
-  return session_manager::SessionManager::Get()->session_state() !=
-         session_manager::SessionState::ACTIVE;
-}
-
-void UpdateLoginScreenPolicyExtensionsState() {
-  if (ShouldEnableLoginScreenPolicyExtensions())
-    EnableLoginScreenPolicyExtensions();
-  else
-    DisableLoginScreenPolicyExtensions();
-}
-
-}  // namespace
-
-LoginScreenExtensionsLifetimeManager::LoginScreenExtensionsLifetimeManager() {
-  UpdateLoginScreenPolicyExtensionsState();
-  session_manager::SessionManager::Get()->AddObserver(this);
-  extensions::ExtensionRegistry::Get(ProfileHelper::GetSigninProfile())
-      ->AddObserver(this);
-}
-
-LoginScreenExtensionsLifetimeManager::~LoginScreenExtensionsLifetimeManager() {
-  extensions::ExtensionRegistry::Get(ProfileHelper::GetSigninProfile())
-      ->RemoveObserver(this);
-  session_manager::SessionManager::Get()->RemoveObserver(this);
-}
-
-void LoginScreenExtensionsLifetimeManager::OnSessionStateChanged() {
-  UpdateLoginScreenPolicyExtensionsState();
-}
-
-void LoginScreenExtensionsLifetimeManager::OnExtensionLoaded(
-    content::BrowserContext* /*browser_context*/,
-    const extensions::Extension* extension) {
-  if (extension->location() ==
-          extensions::mojom::ManifestLocation::kExternalPolicyDownload &&
-      !ShouldEnableLoginScreenPolicyExtensions()) {
-    // The policy extensions should be disabled, however the extension got
-    // loaded - due to the policy change or due to some internal reason in the
-    // extensions subsystem. Therefore forcibly disable this extension.
-    // Doing this in an asynchronous job, in order to avoid confusing other
-    // observers of OnExtensionLoaded().
-    base::SequencedTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::BindOnce(&DisableLoginScreenExtension, extension->id()));
-  }
-}
-
-}  // namespace ash
diff --git a/chrome/browser/ash/login/login_screen_extensions_lifetime_manager.h b/chrome/browser/ash/login/login_screen_extensions_lifetime_manager.h
deleted file mode 100644
index 2fabf6c..0000000
--- a/chrome/browser/ash/login/login_screen_extensions_lifetime_manager.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ASH_LOGIN_LOGIN_SCREEN_EXTENSIONS_LIFETIME_MANAGER_H_
-#define CHROME_BROWSER_ASH_LOGIN_LOGIN_SCREEN_EXTENSIONS_LIFETIME_MANAGER_H_
-
-#include "components/session_manager/core/session_manager_observer.h"
-#include "extensions/browser/extension_registry_observer.h"
-
-namespace ash {
-
-// Manages the lifetime of the login-screen policy-installed extensions and
-// apps, making sure that they are stopped during an active user session.
-class LoginScreenExtensionsLifetimeManager final
-    : public session_manager::SessionManagerObserver,
-      public extensions::ExtensionRegistryObserver {
- public:
-  LoginScreenExtensionsLifetimeManager();
-  LoginScreenExtensionsLifetimeManager(
-      const LoginScreenExtensionsLifetimeManager&) = delete;
-  LoginScreenExtensionsLifetimeManager& operator=(
-      const LoginScreenExtensionsLifetimeManager&) = delete;
-  ~LoginScreenExtensionsLifetimeManager() override;
-
-  // session_manager::SessionManagerObserver:
-  void OnSessionStateChanged() override;
-
-  // extensions::ExtensionRegistryObserver:
-  void OnExtensionLoaded(content::BrowserContext* browser_context,
-                         const extensions::Extension* extension) override;
-};
-
-}  // namespace ash
-
-#endif  // CHROME_BROWSER_ASH_LOGIN_LOGIN_SCREEN_EXTENSIONS_LIFETIME_MANAGER_H_
diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc
index 114f1b60..0fb6d46c 100644
--- a/chrome/browser/autocomplete/search_provider_unittest.cc
+++ b/chrome/browser/autocomplete/search_provider_unittest.cc
@@ -3416,68 +3416,68 @@
   TemplateURL google_template_url(template_url_data);
 
   // All conditions should be met.
-  EXPECT_TRUE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_TRUE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("http://www.google.com/search"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::OTHER, SearchTermsData(), client_.get(),
       true));
 
   // Invalid page URL.
-  EXPECT_FALSE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_FALSE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("badpageurl"), GURL("https://www.google.com/complete/search"),
       &google_template_url, metrics::OmniboxEventProto::OTHER,
       SearchTermsData(), client_.get(), true));
 
   // Invalid page classification.
-  EXPECT_FALSE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_FALSE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("http://www.google.com/search"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS,
       SearchTermsData(), client_.get(), true));
 
   // Invalid page classification.
-  EXPECT_FALSE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_FALSE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("http://www.google.com/search"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS,
       SearchTermsData(), client_.get(), true));
 
   // Invalid page classification.
-  EXPECT_FALSE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_FALSE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("http://www.google.com/search"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::NTP, SearchTermsData(), client_.get(), true));
 
   // Invalid page classification.
-  EXPECT_FALSE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_FALSE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("http://www.google.com/search"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::OBSOLETE_INSTANT_NTP, SearchTermsData(),
       client_.get(), true));
 
   // HTTPS page URL on same domain as provider.
-  EXPECT_TRUE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_TRUE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("https://www.google.com/search"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::OTHER, SearchTermsData(), client_.get(),
       true));
 
   // Non-HTTP[S] page URL on same domain as provider.
-  EXPECT_FALSE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_FALSE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("ftp://www.google.com/search"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::OTHER, SearchTermsData(), client_.get(),
       true));
 
   // Non-HTTP page URL on different domain.
-  EXPECT_TRUE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_TRUE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("https://www.notgoogle.com/search"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::OTHER, SearchTermsData(), client_.get(),
       true));
 
   // Non-HTTPS provider.
-  EXPECT_FALSE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_FALSE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("http://www.google.com/search"),
       GURL("http://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::OTHER, SearchTermsData(), client_.get(),
@@ -3485,7 +3485,7 @@
 
   // Suggest disabled.
   profile_->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, false);
-  EXPECT_FALSE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_FALSE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("http://www.google.com/search"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::OTHER, SearchTermsData(), client_.get(),
@@ -3495,7 +3495,7 @@
   // Incognito.
   ChromeAutocompleteProviderClient client_incognito(
       profile_->GetPrimaryOTRProfile(/*create_if_needed=*/true));
-  EXPECT_FALSE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_FALSE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("http://www.google.com/search"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::OTHER, SearchTermsData(), &client_incognito,
@@ -3506,25 +3506,25 @@
   // empty.
   client_->set_is_personalized_url_data_collection_active(false);
   // Different origin, with search terms.
-  EXPECT_FALSE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_FALSE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("https://www.different-origin.com"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::OTHER, SearchTermsData(), client_.get(),
       true));
   // Same origin, with search terms.
-  EXPECT_FALSE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_FALSE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("https://www.google.com/search"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::OTHER, SearchTermsData(), client_.get(),
       true));
   // Different origin, empty search terms.
-  EXPECT_FALSE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_FALSE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("https://www.different-origin.com"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::OTHER, SearchTermsData(), client_.get(),
       false));
   // Same origin, empty search terms.
-  EXPECT_TRUE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_TRUE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("https://www.google.com/search"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::OTHER, SearchTermsData(), client_.get(),
@@ -3532,7 +3532,7 @@
   client_->set_is_personalized_url_data_collection_active(true);
 
   // Check that there were no side effects from previous tests.
-  EXPECT_TRUE(SearchProvider::CanSendRequestWithURL(
+  EXPECT_TRUE(SearchProvider::CanSendCurrentPageURLInRequest(
       GURL("http://www.google.com/search"),
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::OTHER, SearchTermsData(), client_.get(),
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 7d91b66..873e773 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -72,7 +72,7 @@
       </if>
 
       <!-- Contact Center Insights extension, enabled on managed ChromeOS devices -->
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <include name="IDR_CONTACT_CENTER_INSIGHTS_MANIFEST" file="resources\chromeos\contact_center_insights\manifest.json" type="BINDATA" />
       </if>
 
@@ -86,7 +86,7 @@
         <include name="IDR_GAIA_AUTH_WEBVIEW_SAML_INJECTED_JS" file="resources\gaia_auth_host\webview_saml_injected.js" flattenhtml="true" type="BINDATA" />
       </if>
 
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <include name="IDR_CHROME_URLS_DISABLED_PAGE_HTML" file="resources\chromeos\chrome_urls_disabled_page\app.html" type="BINDATA" />
       </if>
 
@@ -130,7 +130,7 @@
       <include name="IDR_USB_DEVICE_MANAGER_CLIENT_MOJOM_WEBUI_JS" file="${root_gen_dir}\mojom-webui\services\device\public\mojom\usb_manager_client.mojom-webui.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_WEBSTORE_MANIFEST" file="resources\webstore_app\manifest.json" type="BINDATA" />
       <include name="IDR_CRYPTOTOKEN_MANIFEST" file="resources\cryptotoken\manifest.json" type="BINDATA" />
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <include name="IDR_ECHO_MANIFEST" file="resources\chromeos\echo\manifest.json" type="BINDATA" />
       </if>
       <if expr="chromeos_ash">
@@ -225,7 +225,7 @@
         <include name="IDR_PRODUCT_CHROMEOS_SYNC_CONSENT_SCREEN_ICONS" file="internal\resources\chromeos-sync-consent-icons.html" type="BINDATA" />
         <include name="IDR_PRODUCT_CHROMEOS_SYNC_CONSENT_SCREEN_ICONS_M_JS" file="internal\resources\chromeos-sync-consent-icons.m.js" type="BINDATA" />
       </if>
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <if expr="_google_chrome">
           <include name="IDR_QUICKOFFICE_MANIFEST" file="resources\chromeos\quickoffice\manifest.json" type="BINDATA" />
         </if>
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 769908a..04ee7ae 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -690,6 +690,10 @@
     "../ash/login/error_screens_histogram_helper.h",
     "../ash/login/existing_user_controller.cc",
     "../ash/login/existing_user_controller.h",
+    "../ash/login/extensions/login_screen_extensions_lifetime_manager.cc",
+    "../ash/login/extensions/login_screen_extensions_lifetime_manager.h",
+    "../ash/login/extensions/login_screen_extensions_lifetime_manager_factory.cc",
+    "../ash/login/extensions/login_screen_extensions_lifetime_manager_factory.h",
     "../ash/login/gaia_reauth_token_fetcher.cc",
     "../ash/login/gaia_reauth_token_fetcher.h",
     "../ash/login/hats_unlock_survey_trigger.cc",
@@ -712,8 +716,6 @@
     "../ash/login/login_client_cert_usage_observer.h",
     "../ash/login/login_pref_names.cc",
     "../ash/login/login_pref_names.h",
-    "../ash/login/login_screen_extensions_lifetime_manager.cc",
-    "../ash/login/login_screen_extensions_lifetime_manager.h",
     "../ash/login/login_screen_extensions_storage_cleaner.cc",
     "../ash/login/login_screen_extensions_storage_cleaner.h",
     "../ash/login/login_wizard.h",
diff --git a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h
index b1acb09..94601af 100644
--- a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h
+++ b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h
@@ -37,7 +37,7 @@
  public:
   explicit DriveFsEventRouter(SystemNotificationManager* notification_manager);
   DriveFsEventRouter(const DriveFsEventRouter&) = delete;
-  virtual ~DriveFsEventRouter();
+  ~DriveFsEventRouter() override;
 
   DriveFsEventRouter& operator=(const DriveFsEventRouter&) = delete;
 
diff --git a/chrome/browser/dev_ui_browser_resources.grd b/chrome/browser/dev_ui_browser_resources.grd
index 95ab701..a9f2ea6 100644
--- a/chrome/browser/dev_ui_browser_resources.grd
+++ b/chrome/browser/dev_ui_browser_resources.grd
@@ -36,7 +36,7 @@
       <include name="IDR_PREDICTORS_JS" file="${root_gen_dir}\chrome\browser\resources\predictors\predictors.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_PREDICTORS_RESOURCE_PREFETCH_PREDICTOR_JS" file="${root_gen_dir}\chrome\browser\resources\predictors\resource_prefetch_predictor.js" use_base_dir="false" type="BINDATA" />
 
-      <if expr="is_android or is_linux or chromeos_ash or chromeos_lacros">
+      <if expr="is_android or is_linux or is_chromeos">
         <include name="IDR_SANDBOX_INTERNALS_HTML" file="resources\sandbox_internals\sandbox_internals.html" preprocess="true" type="BINDATA" />
         <include name="IDR_SANDBOX_INTERNALS_JS" file="${root_gen_dir}\chrome\browser\resources\sandbox_internals\tsc\sandbox_internals.js" use_base_dir="false" type="BINDATA" />
       </if>
diff --git a/chrome/browser/devtools/protocol/devtools_printtopdf_browsertest.cc b/chrome/browser/devtools/protocol/devtools_printtopdf_browsertest.cc
index e8d884b..f537bc1 100644
--- a/chrome/browser/devtools/protocol/devtools_printtopdf_browsertest.cc
+++ b/chrome/browser/devtools/protocol/devtools_printtopdf_browsertest.cc
@@ -25,6 +25,7 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 using DevToolsProtocolTest = DevToolsProtocolTestBase;
 
@@ -119,6 +120,16 @@
   }
 
   void RendePdfPage(int page_index) {
+    absl::optional<gfx::SizeF> page_size_in_points =
+        chrome_pdf::GetPDFPageSizeByIndex(pdf_span_, page_index);
+    ASSERT_TRUE(page_size_in_points.has_value());
+
+    gfx::SizeF page_size_in_pixels =
+        gfx::ScaleSize(page_size_in_points.value(),
+                       static_cast<float>(kDpi) / printing::kPointsPerInch);
+
+    gfx::Rect page_rect(gfx::ToCeiledSize(page_size_in_pixels));
+
     constexpr chrome_pdf::RenderOptions options = {
         .stretch_to_bounds = false,
         .keep_aspect_ratio = true,
@@ -127,26 +138,16 @@
         .render_device_type = chrome_pdf::RenderDeviceType::kPrinter,
     };
 
-    absl::optional<gfx::SizeF> page_size =
-        chrome_pdf::GetPDFPageSizeByIndex(pdf_span_, page_index);
-    ASSERT_TRUE(page_size.has_value());
+    bitmap_size_ = page_rect.size();
+    bitmap_data_.resize(kColorChannels * bitmap_size_.GetArea());
 
-    gfx::Rect rect(kPaperWidth * kDpi, kPaperHeight * kDpi);
-    printing::PdfRenderSettings settings(
-        rect, gfx::Point(), gfx::Size(kDpi, kDpi), options.autorotate,
-        options.use_color, printing::PdfRenderSettings::Mode::NORMAL);
-    std::vector<uint8_t> bitmap_data(kColorChannels *
-                                     settings.area.size().GetArea());
     ASSERT_TRUE(chrome_pdf::RenderPDFPageToBitmap(
-        pdf_span_, page_index, bitmap_data.data(), settings.area.size(),
-        settings.dpi, options));
-
-    bitmap_data_.swap(bitmap_data);
-    bitmap_size_ = settings.area.size();
+        pdf_span_, page_index, bitmap_data_.data(), bitmap_size_,
+        gfx::Size(kDpi, kDpi), options));
   }
 
   uint32_t GetPixelRGB(int x, int y) {
-    int pixel_index =
+    size_t pixel_index =
         bitmap_size_.width() * y * kColorChannels + x * kColorChannels;
     return bitmap_data_[pixel_index + 0]           // B
            | bitmap_data_[pixel_index + 1] << 8    // G
@@ -466,4 +467,25 @@
   EXPECT_EQ(GetPixelRGB(bitmap_width() / 2, bitmap_height() / 2), 0xff0000u);
 }
 
+IN_PROC_BROWSER_TEST_P(PrintToPdfProtocolTest, PrintToPdfOOPIF) {
+  NavigateToURLBlockUntilNavigationsComplete("/print_to_pdf/oopif.html");
+
+  Attach();
+
+  base::Value::Dict params;
+  params.Set("printBackground", true);
+  params.Set("paperWidth", kPaperWidth);
+  params.Set("paperHeight", kPaperHeight);
+  params.Set("marginTop", 0);
+  params.Set("marginLeft", 0);
+  params.Set("marginBottom", 0);
+  params.Set("marginRight", 0);
+  PrintToPdfAndRenderPage(base::Value(std::move(params)), 0);
+
+  ASSERT_TRUE(printing::IsOopifEnabled());
+
+  // Expect red iframe pixel at 1 inch into the page.
+  EXPECT_EQ(GetPixelRGB(1 * kDpi, 1 * kDpi), 0xff0000u);
+}
+
 }  // namespace
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
index c0e6577..7c2ee020 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
@@ -40,7 +40,6 @@
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/ui/app_list/app_list_util.h"
-#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/extensions/extensions_dialogs.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
@@ -244,9 +243,9 @@
     return;
   }
 
-  chrome::ShowExtensionInstallBlockedByParentDialog(
-      chrome::ExtensionInstalledBlockedByParentDialogAction::kAdd, extension,
-      contents, std::move(done_callback));
+  extensions::ShowExtensionInstallBlockedByParentDialog(
+      extensions::ExtensionInstalledBlockedByParentDialogAction::kAdd,
+      extension, contents, std::move(done_callback));
 }
 
 #endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS)
@@ -934,9 +933,9 @@
     return;
   }
 
-  chrome::ShowExtensionInstallBlockedDialog(
-      extension->id(), extension->name(), blocked_by_policy_error_message_,
-      image, contents, std::move(done_callback));
+  ShowExtensionInstallBlockedDialog(extension->id(), extension->name(),
+                                    blocked_by_policy_error_message_, image,
+                                    contents, std::move(done_callback));
 }
 
 WebstorePrivateCompleteInstallFunction::
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc
index d14ae9f..f69f680 100644
--- a/chrome/browser/extensions/service_worker_apitest.cc
+++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -442,6 +442,39 @@
                      u"See https://github.com/w3c/ServiceWorker/issues/1356."));
 }
 
+// Tests a service worker registration that fails due to the worker script
+// synchronously throwing a runtime error.
+IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest,
+                       ServiceWorkerWithRegistrationFailure) {
+  // The error console only captures errors if the user is in dev mode.
+  profile()->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode, true);
+
+  constexpr size_t kErrorsExpected = 2u;
+  ErrorConsole* error_console = ErrorConsole::Get(profile());
+  ErrorObserver observer(kErrorsExpected, error_console);
+
+  const Extension* extension = LoadExtension(
+      test_data_dir_.AppendASCII("service_worker/worker_based_background/"
+                                 "service_worker_registration_failure"),
+                                 {.wait_for_renderers = false});
+
+  ASSERT_TRUE(extension);
+  observer.WaitForErrors();
+  const ErrorList& error_list =
+      error_console->GetErrorsForExtension(extension->id());
+  ASSERT_EQ(kErrorsExpected, error_list.size());
+
+  std::vector<std::u16string> error_message_list;
+  for (std::string::size_type i = 0; i < error_list.size(); i++) {
+    error_message_list.push_back(error_list[i]->message());
+  }
+  // status code 15: kErrorScriptEvaluateFailed
+  EXPECT_THAT(error_message_list,
+              testing::UnorderedElementsAre(
+                  u"Uncaught Error: lol",
+                  u"Service worker registration failed. Status code: 15"));
+}
+
 // Tests that an error is generated if there is a syntax error in the service
 // worker script.
 IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, SyntaxError) {
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index b17a45b..1200872f 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -178,6 +178,7 @@
     &kBackgroundThreadPool,
     &kBulkTabRestore,
     &kCastDeviceFilter,
+    &kClearOmniboxFocusAfterNavigation,
     &kCloseTabSuggestions,
     &kCriticalPersistedTabData,
     &kCommerceCoupons,
@@ -493,6 +494,9 @@
 const base::Feature kCastDeviceFilter{"CastDeviceFilter",
                                       base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kClearOmniboxFocusAfterNavigation{
+    "ClearOmniboxFocusAfterNavigation", base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kCloseTabSuggestions{"CloseTabSuggestions",
                                          base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
index e2fedbb..bc43c08 100644
--- a/chrome/browser/flags/android/chrome_feature_list.h
+++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -31,6 +31,7 @@
 extern const base::Feature kAppToWebAttribution;
 extern const base::Feature kBackgroundThreadPool;
 extern const base::Feature kBulkTabRestore;
+extern const base::Feature kClearOmniboxFocusAfterNavigation;
 extern const base::Feature kCloseTabSuggestions;
 extern const base::Feature kCriticalPersistedTabData;
 extern const base::Feature kCommerceCoupons;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index aaa89fa..d80854c 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -276,6 +276,8 @@
             "ChromeSharingHubLaunchAdjacent";
     public static final String CHROME_SURVEY_NEXT_ANDROID = "ChromeSurveyNextAndroid";
     public static final String ENABLE_CBD_SIGN_OUT = "EnableCbdSignOut";
+    public static final String CLEAR_OMNIBOX_FOCUS_AFTER_NAVIGATION =
+            "ClearOmniboxFocusAfterNavigation";
     public static final String COMMAND_LINE_ON_NON_ROOTED = "CommandLineOnNonRooted";
     public static final String COMMERCE_COUPONS = "CommerceCoupons";
     public static final String COMMERCE_MERCHANT_VIEWER = "CommerceMerchantViewer";
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 267c1cf2..8e0ee4c 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -331,7 +331,6 @@
 #include "chrome/browser/ash/first_run/first_run.h"
 #include "chrome/browser/ash/floating_workspace/floating_workspace_util.h"
 #include "chrome/browser/ash/guest_os/guest_id.h"
-#include "chrome/browser/ash/guest_os/guest_os_mime_types_service.h"
 #include "chrome/browser/ash/guest_os/guest_os_pref_names.h"
 #include "chrome/browser/ash/guest_os/guest_os_terminal.h"
 #include "chrome/browser/ash/lock_screen_apps/state_controller.h"
@@ -1824,11 +1823,6 @@
   profile_prefs->ClearPref(kExtensionCheckupOnStartup);
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  // Added 2021/07.
-  guest_os::GuestOsMimeTypesService::MigrateVerboseMimeTypePrefs(profile_prefs);
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
 #if !BUILDFLAG(IS_ANDROID)
   // Added 2021/07
   profile_prefs->ClearPref(kCloudPrintDeprecationWarningsSuppressed);
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index 8a17d3b..6b867df 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -37,7 +37,6 @@
 #include "components/prefs/pref_service.h"
 #include "components/printing/browser/print_composite_client.h"
 #include "components/printing/browser/print_manager_utils.h"
-#include "components/printing/browser/print_to_pdf/pdf_print_utils.h"
 #include "components/printing/common/print.mojom.h"
 #include "components/services/print_compositor/public/cpp/print_service_mojo_types.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -80,8 +79,6 @@
 #include "chrome/browser/printing/print_job_utils_lacros.h"
 #endif
 
-using print_to_pdf::PdfPrintResult;
-
 namespace printing {
 
 namespace {
@@ -288,44 +285,10 @@
     content::RenderFrameHost* rfh,
     const std::string& page_ranges,
     mojom::PrintPagesParamsPtr print_pages_params,
-    PrintToPdfCallback callback) {
-  DCHECK(callback);
-
-  if (print_to_pdf_callback_) {
-    std::move(callback).Run(PdfPrintResult::kSimultaneousPrintActive,
-                            base::MakeRefCounted<base::RefCountedString>());
-    return;
-  }
-
-  if (!rfh->IsRenderFrameLive()) {
-    std::move(callback).Run(PdfPrintResult::kPrintFailure,
-                            base::MakeRefCounted<base::RefCountedString>());
-    return;
-  }
-
-  absl::variant<printing::PageRanges, PdfPrintResult> parsed_ranges =
-      print_to_pdf::TextPageRangesToPageRanges(page_ranges);
-  if (absl::holds_alternative<PdfPrintResult>(parsed_ranges)) {
-    DCHECK_NE(absl::get<PdfPrintResult>(parsed_ranges),
-              PdfPrintResult::kPrintSuccess);
-    std::move(callback).Run(absl::get<PdfPrintResult>(parsed_ranges),
-                            base::MakeRefCounted<base::RefCountedString>());
-    return;
-  }
-
-  // TODO(crbug.com/1348323): OOPIF printing is not yet supported by
-  // PrintToPdf(), so very limited state is set up here, just enough to handle
-  // RenderFrameDeleted() and printed document type is forced to be PDF instead
-  // of Skia MultiPictureDocument.
-  SetPrintingRFH(rfh);
-  print_pages_params->pages = absl::get<printing::PageRanges>(parsed_ranges);
-  print_pages_params->params->printed_doc_type = mojom::SkiaDocumentType::kPDF;
-  print_to_pdf_callback_ = std::move(callback);
-
-  GetPrintRenderFrame(rfh)->PrintWithParams(
-      std::move(print_pages_params),
-      base::BindOnce(&PrintViewManagerBase::OnDidPrintWithParams,
-                     weak_ptr_factory_.GetWeakPtr()));
+    print_to_pdf::PdfPrintJob::PrintToPdfCallback callback) {
+  print_to_pdf::PdfPrintJob::StartJob(
+      web_contents(), rfh, GetPrintRenderFrame(rfh), page_ranges,
+      std::move(print_pages_params), std::move(callback));
 }
 
 void PrintViewManagerBase::PrintDocument(
@@ -775,11 +738,6 @@
   if (render_frame_host != printing_rfh_)
     return;
 
-  if (print_to_pdf_callback_) {
-    FailPrintToPdfJob(PdfPrintResult::kPrintFailure);
-    return;
-  }
-
   printing_rfh_ = nullptr;
 
   PrintManager::PrintingRenderFrameDeleted();
@@ -1235,58 +1193,4 @@
 }
 #endif  // BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS)
 
-void PrintViewManagerBase::OnDidPrintWithParams(
-    printing::mojom::PrintWithParamsResultPtr result) {
-  DCHECK(print_to_pdf_callback_);
-
-  if (result->is_failure_reason()) {
-    switch (result->get_failure_reason()) {
-      case mojom::PrintFailureReason::kGeneralFailure:
-        FailPrintToPdfJob(PdfPrintResult::kPrintFailure);
-        return;
-      case mojom::PrintFailureReason::kInvalidPageRange:
-        FailPrintToPdfJob(PdfPrintResult::kPageCountExceeded);
-        return;
-    }
-  }
-
-  auto& content = *result->get_params()->content;
-  if (!content.metafile_data_region.IsValid()) {
-    FailPrintToPdfJob(PdfPrintResult::kInvalidMemoryHandle);
-    return;
-  }
-
-  base::ReadOnlySharedMemoryMapping map = content.metafile_data_region.Map();
-  if (!map.IsValid()) {
-    FailPrintToPdfJob(PdfPrintResult::kMetafileMapError);
-    return;
-  }
-
-  std::string data =
-      std::string(static_cast<const char*>(map.memory()), map.size());
-  std::move(print_to_pdf_callback_)
-      .Run(PdfPrintResult::kPrintSuccess,
-           base::RefCountedString::TakeString(&data));
-
-  ResetPrintToPdfJob();
-}
-
-void PrintViewManagerBase::FailPrintToPdfJob(PdfPrintResult result) {
-  DCHECK_NE(result, PdfPrintResult::kPrintSuccess);
-  DCHECK(print_to_pdf_callback_);
-
-  std::move(print_to_pdf_callback_)
-      .Run(result, base::MakeRefCounted<base::RefCountedString>());
-
-  ResetPrintToPdfJob();
-}
-
-void PrintViewManagerBase::ResetPrintToPdfJob() {
-  printing_rfh_ = nullptr;
-
-  // The callback is supposed to be consumed at this point meaning we
-  // reported results to the PrintToPdf() caller.
-  DCHECK(!print_to_pdf_callback_);
-}
-
 }  // namespace printing
diff --git a/chrome/browser/printing/print_view_manager_base.h b/chrome/browser/printing/print_view_manager_base.h
index f146d74..871e00c4 100644
--- a/chrome/browser/printing/print_view_manager_base.h
+++ b/chrome/browser/printing/print_view_manager_base.h
@@ -11,7 +11,6 @@
 #include "base/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/read_only_shared_memory_region.h"
-#include "base/memory/ref_counted_memory.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
@@ -21,7 +20,7 @@
 #include "chrome/browser/ui/webui/print_preview/printer_handler.h"
 #include "components/prefs/pref_member.h"
 #include "components/printing/browser/print_manager.h"
-#include "components/printing/browser/print_to_pdf/pdf_print_result.h"
+#include "components/printing/browser/print_to_pdf/pdf_print_job.h"
 #include "components/printing/common/print.mojom-forward.h"
 #include "components/services/print_compositor/public/mojom/print_compositor.mojom.h"
 #include "printing/buildflags/buildflags.h"
@@ -58,10 +57,6 @@
     virtual void OnPrintPreview(const content::RenderFrameHost* rfh) {}
   };
 
-  using PrintToPdfCallback =
-      base::OnceCallback<void(print_to_pdf::PdfPrintResult result,
-                              scoped_refptr<base::RefCountedMemory>)>;
-
   PrintViewManagerBase(const PrintViewManagerBase&) = delete;
   PrintViewManagerBase& operator=(const PrintViewManagerBase&) = delete;
 
@@ -90,7 +85,7 @@
   void PrintToPdf(content::RenderFrameHost* rfh,
                   const std::string& page_ranges,
                   mojom::PrintPagesParamsPtr print_pages_params,
-                  PrintToPdfCallback callback);
+                  print_to_pdf::PdfPrintJob::PrintToPdfCallback callback);
 
   // Whether printing is enabled or not.
   void UpdatePrintingEnabled();
@@ -326,13 +321,6 @@
       bool allowed);
 #endif  // BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS)
 
-  // This is called to report PrintToPdf() call results.
-  void OnDidPrintWithParams(printing::mojom::PrintWithParamsResultPtr result);
-
-  // Helpers to report PrintToPdf() failure and cleanup related state.
-  void FailPrintToPdfJob(print_to_pdf::PdfPrintResult result);
-  void ResetPrintToPdfJob();
-
   // The current RFH that is printing with a system printing dialog.
   raw_ptr<content::RenderFrameHost> printing_rfh_ = nullptr;
 
@@ -352,8 +340,6 @@
   absl::optional<uint32_t> service_manager_client_id_;
 #endif
 
-  PrintToPdfCallback print_to_pdf_callback_;
-
   const scoped_refptr<PrintQueriesQueue> queue_;
 
   base::ObserverList<Observer> observers_;
diff --git a/chrome/browser/printing/printing_init.cc b/chrome/browser/printing/printing_init.cc
index 8255983..57e5bbf 100644
--- a/chrome/browser/printing/printing_init.cc
+++ b/chrome/browser/printing/printing_init.cc
@@ -21,16 +21,18 @@
 namespace printing {
 
 void InitializePrinting(content::WebContents* web_contents) {
+  // Native Headless mode uses a minimalistic Print Manager implementation that
+  // shortcuts most of the callbacks providing only print to PDF functionality.
   if (headless::IsChromeNativeHeadless()) {
     headless::HeadlessPrintManager::CreateForWebContents(web_contents);
-    return;
-  }
+  } else {
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
-  printing::PrintViewManager::CreateForWebContents(web_contents);
-  printing::PdfNupConverterClient::CreateForWebContents(web_contents);
+    PrintViewManager::CreateForWebContents(web_contents);
+    PdfNupConverterClient::CreateForWebContents(web_contents);
 #else
-  printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
+    PrintViewManagerBasic::CreateForWebContents(web_contents);
 #endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW)
+  }
   CreateCompositeClientIfNeeded(web_contents, embedder_support::GetUserAgent());
 }
 
diff --git a/chrome/browser/resources/bookmarks/folder_node.ts b/chrome/browser/resources/bookmarks/folder_node.ts
index 3f67e60..5df8667 100644
--- a/chrome/browser/resources/bookmarks/folder_node.ts
+++ b/chrome/browser/resources/bookmarks/folder_node.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_nav_menu_item_style.css.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
diff --git a/chrome/browser/resources/bookmarks/item.ts b/chrome/browser/resources/bookmarks/item.ts
index 65ab78c..9f8a905 100644
--- a/chrome/browser/resources/bookmarks/item.ts
+++ b/chrome/browser/resources/bookmarks/item.ts
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import './shared_style.css.js';
 import './strings.m.js';
 
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {assert} from 'chrome://resources/js/assert_ts.js';
 import {isMac} from 'chrome://resources/js/cr.m.js';
 import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js';
diff --git a/chrome/browser/resources/bookmarks/toolbar.ts b/chrome/browser/resources/bookmarks/toolbar.ts
index b2f6133..6aa2d02 100644
--- a/chrome/browser/resources/bookmarks/toolbar.ts
+++ b/chrome/browser/resources/bookmarks/toolbar.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import './shared_style.css.js';
diff --git a/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn b/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn
index a22fac6..f33946c 100644
--- a/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn
+++ b/chrome/browser/resources/chromeos/emoji_picker/BUILD.gn
@@ -191,7 +191,7 @@
 
 copy("symbol_test_data") {
   sources = [ "./symbol_test_ordering.json" ]
-  outputs =  [ "$target_gen_dir/symbol_test_ordering.json" ]
+  outputs = [ "$target_gen_dir/symbol_test_ordering.json" ]
 }
 
 js_library("emoji_picker") {
@@ -224,7 +224,7 @@
   deps = [
     ":icons",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
   ]
 }
 
@@ -233,7 +233,7 @@
     ":events",
     ":icons",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
   ]
 }
 
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_category_button.js b/chrome/browser/resources/chromeos/emoji_picker/emoji_category_button.js
index 518e056..04f78d1 100644
--- a/chrome/browser/resources/chromeos/emoji_picker/emoji_category_button.js
+++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_category_button.js
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import './icons.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_group_button.js b/chrome/browser/resources/chromeos/emoji_picker/emoji_group_button.js
index 250fa7b..0c86a14 100644
--- a/chrome/browser/resources/chromeos/emoji_picker/emoji_group_button.js
+++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_group_button.js
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import './icons.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
diff --git a/chrome/browser/resources/chromeos/emulator/audio_settings.js b/chrome/browser/resources/chromeos/emulator/audio_settings.js
index d7afbe0..c904e4c 100644
--- a/chrome/browser/resources/chromeos/emulator/audio_settings.js
+++ b/chrome/browser/resources/chromeos/emulator/audio_settings.js
@@ -5,7 +5,7 @@
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button.m.js';
 import 'chrome://resources/cr_elements/cr_radio_group/cr_radio_group.m.js';
diff --git a/chrome/browser/resources/chromeos/emulator/battery_settings.js b/chrome/browser/resources/chromeos/emulator/battery_settings.js
index 8f0a42c..399df8c 100644
--- a/chrome/browser/resources/chromeos/emulator/battery_settings.js
+++ b/chrome/browser/resources/chromeos/emulator/battery_settings.js
@@ -4,7 +4,7 @@
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button.m.js';
 import 'chrome://resources/cr_elements/cr_radio_group/cr_radio_group.m.js';
diff --git a/chrome/browser/resources/chromeos/emulator/bluetooth_settings.js b/chrome/browser/resources/chromeos/emulator/bluetooth_settings.js
index 190242e..1af478a8 100644
--- a/chrome/browser/resources/chromeos/emulator/bluetooth_settings.js
+++ b/chrome/browser/resources/chromeos/emulator/bluetooth_settings.js
@@ -5,7 +5,7 @@
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button.m.js';
 import 'chrome://resources/cr_elements/cr_radio_group/cr_radio_group.m.js';
diff --git a/chrome/browser/resources/chromeos/emulator/input_device_settings.js b/chrome/browser/resources/chromeos/emulator/input_device_settings.js
index 38d3662..01ee498 100644
--- a/chrome/browser/resources/chromeos/emulator/input_device_settings.js
+++ b/chrome/browser/resources/chromeos/emulator/input_device_settings.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js';
 import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
diff --git a/chrome/browser/resources/chromeos/login/components/BUILD.gn b/chrome/browser/resources/chromeos/login/components/BUILD.gn
index 4eb9e731..11330db 100644
--- a/chrome/browser/resources/chromeos/login/components/BUILD.gn
+++ b/chrome/browser/resources/chromeos/login/components/BUILD.gn
@@ -288,6 +288,7 @@
   html_file = "gaia_dialog.html"
   html_type = "dom-module"
   auto_imports = oobe_auto_imports
+  migrated_imports = oobe_migrated_imports
   namespace_rewrites = oobe_namespace_rewrites
 }
 
@@ -373,6 +374,7 @@
   html_file = "oobe_carousel.html"
   html_type = "dom-module"
   auto_imports = oobe_auto_imports
+  migrated_imports = oobe_migrated_imports
   namespace_rewrites = oobe_namespace_rewrites
 }
 
@@ -381,6 +383,7 @@
   html_file = "oobe_cr_lottie.html"
   html_type = "dom-module"
   auto_imports = oobe_auto_imports
+  migrated_imports = oobe_migrated_imports
   namespace_rewrites = oobe_namespace_rewrites
 }
 
diff --git a/chrome/browser/resources/chromeos/login/oobe_auto_imports.gni b/chrome/browser/resources/chromeos/login/oobe_auto_imports.gni
index 057984ce1..243e576 100644
--- a/chrome/browser/resources/chromeos/login/oobe_auto_imports.gni
+++ b/chrome/browser/resources/chromeos/login/oobe_auto_imports.gni
@@ -96,4 +96,5 @@
   "ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html",
   "ui/webui/resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.html",
   "ui/webui/resources/cr_elements/cr_fingerprint/cr_fingerprint_icon.html",
+  "ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.html",
 ]
diff --git a/chrome/browser/resources/chromeos/network_ui/network_ui.html b/chrome/browser/resources/chromeos/network_ui/network_ui.html
index 4e50692..8ee2c19c 100644
--- a/chrome/browser/resources/chromeos/network_ui/network_ui.html
+++ b/chrome/browser/resources/chromeos/network_ui/network_ui.html
@@ -178,6 +178,20 @@
         $i18n{setTetheringConfigButtonText}
       </cr-button>
       <div id="set-tethering-config-result"></div>
+
+      <h2>$i18n{tetheringReadinessLabel}</h2>
+      <div id="check-tethering-readiness-result">Unknown</div>
+      <cr-button class="action-button" on-click="checkTetheringReadiness_">
+        $i18n{checkTetheringReadinessButtonText}
+      </cr-button>
+
+      <h2>$i18n{setTetheringEnabledLabel}</h2>
+      <cr-toggle id="enable-tethering-toggle"
+            checked="{{isTetheringEnabled_}}"
+            disabled="[[tetheringChangeInProgress_]]"
+            on-change="onTetheringToggleChanged_">
+      </cr-toggle>
+      <div id="set-tethering-enabled-result"></div>
     </div>
   <template>
 </iron-pages>
diff --git a/chrome/browser/resources/chromeos/network_ui/network_ui.js b/chrome/browser/resources/chromeos/network_ui/network_ui.js
index 4eff0283..a90324c 100644
--- a/chrome/browser/resources/chromeos/network_ui/network_ui.js
+++ b/chrome/browser/resources/chromeos/network_ui/network_ui.js
@@ -9,6 +9,7 @@
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/cr_tabs/cr_tabs.js';
+import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js';
 import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
 import 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-lite.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
@@ -88,6 +89,22 @@
       },
     },
 
+    /**@private */
+    isTetheringEnabled_: {
+      type: Boolean,
+      value: false,
+    },
+
+    /**
+     * Set to true while an tethering state change is requested and the
+     * callback hasn't been fired yet.
+     * @private
+     */
+    tetheringChangeInProgress_: {
+      type: Boolean,
+      value: false,
+    },
+
     /** @private */
     isHotspotEnabled_: {
       type: Boolean,
@@ -252,6 +269,14 @@
     this.browserProxy_.getTetheringStatus().then(result => {
       this.$$('#tethering-status-div').textContent =
           this.stringifyJSON_(result);
+      const state = result['state'];
+      const startingState = loadTimeData.getString('tetheringStateStarting');
+      const activeState = loadTimeData.getString('tetheringStateActive');
+      if (!!state && (state === startingState || state === activeState)) {
+        this.isTetheringEnabled_ = true;
+        return;
+      }
+      this.isTetheringEnabled_ = false;
     });
   },
 
@@ -277,6 +302,15 @@
         });
   },
 
+  /** @private */
+  checkTetheringReadiness_() {
+    this.browserProxy_.checkTetheringReadiness().then(result => {
+      const resultDiv = this.$$('#check-tethering-readiness-result');
+      resultDiv.innerText = result;
+      resultDiv.classList.toggle('error', result !== 'ready');
+    });
+  },
+
   /**
    * Check if the input tethering config string is a valid JSON object.
    * @private
@@ -300,6 +334,19 @@
     }
   },
 
+  /** @private */
+  onTetheringToggleChanged_() {
+    this.tetheringChangeInProgress_ = true;
+    this.browserProxy_.setTetheringEnabled(this.isTetheringEnabled_)
+        .then(result => {
+          const resultDiv = this.$$('#set-tethering-enabled-result');
+          resultDiv.innerText = result;
+          resultDiv.classList.toggle('error', result !== 'success');
+          this.getTetheringStatus_();
+          this.tetheringChangeInProgress_ = false;
+        });
+  },
+
   /**
    * @param {!Event} event
    * @private
diff --git a/chrome/browser/resources/chromeos/network_ui/network_ui_browser_proxy.js b/chrome/browser/resources/chromeos/network_ui/network_ui_browser_proxy.js
index 01a74b7..f751f68 100644
--- a/chrome/browser/resources/chromeos/network_ui/network_ui_browser_proxy.js
+++ b/chrome/browser/resources/chromeos/network_ui/network_ui_browser_proxy.js
@@ -98,6 +98,17 @@
    * @return {Promise<string>}
    */
   setTetheringConfig(config) {}
+
+  /**
+   * @return {Promise<string>}
+   */
+  checkTetheringReadiness() {}
+
+  /**
+   * @param {boolean} enabled
+   * @return {Promise<string>}
+   */
+  setTetheringEnabled(enabled) {}
 }
 
 /**
@@ -221,6 +232,21 @@
   setTetheringConfig(config) {
     return sendWithPromise('setTetheringConfig', config);
   }
+
+  /**
+   * @return {Promise<string>}
+   */
+  checkTetheringReadiness() {
+    return sendWithPromise('checkTetheringReadiness');
+  }
+
+  /**
+   * @param {boolean} enabled
+   * @return {Promise<string>}
+   */
+  setTetheringEnabled(enabled) {
+    return sendWithPromise('setTetheringEnabled', enabled);
+  }
 }
 
 addSingletonGetter(NetworkUIBrowserProxyImpl);
diff --git a/chrome/browser/resources/downloads/item.ts b/chrome/browser/resources/downloads/item.ts
index a0a6217f..4f7c176 100644
--- a/chrome/browser/resources/downloads/item.ts
+++ b/chrome/browser/resources/downloads/item.ts
@@ -4,7 +4,7 @@
 
 import './icons.html.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
 import 'chrome://resources/cr_elements/icons.m.js';
diff --git a/chrome/browser/resources/downloads/toolbar.ts b/chrome/browser/resources/downloads/toolbar.ts
index 64ebe0dd..f87344a 100644
--- a/chrome/browser/resources/downloads/toolbar.ts
+++ b/chrome/browser/resources/downloads/toolbar.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
 import 'chrome://resources/cr_elements/icons.m.js';
@@ -13,7 +13,7 @@
 import './strings.m.js';
 
 import {CrActionMenuElement} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {getToastManager} from 'chrome://resources/cr_elements/cr_toast/cr_toast_manager.js';
 import {CrToolbarElement} from 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar.js';
 import {assert} from 'chrome://resources/js/assert_ts.js';
diff --git a/chrome/browser/resources/extensions/activity_log/activity_log.ts b/chrome/browser/resources/extensions/activity_log/activity_log.ts
index f17dc02..12f4954d 100644
--- a/chrome/browser/resources/extensions/activity_log/activity_log.ts
+++ b/chrome/browser/resources/extensions/activity_log/activity_log.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/cr_tabs/cr_tabs.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
diff --git a/chrome/browser/resources/extensions/activity_log/activity_log_history.ts b/chrome/browser/resources/extensions/activity_log/activity_log_history.ts
index 8267111..12e3b5a 100644
--- a/chrome/browser/resources/extensions/activity_log/activity_log_history.ts
+++ b/chrome/browser/resources/extensions/activity_log/activity_log_history.ts
@@ -4,7 +4,7 @@
 
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_search_field/cr_search_field.js';
 import '../shared_style.css.js';
 import './activity_log_history_item.js';
diff --git a/chrome/browser/resources/extensions/activity_log/activity_log_history_item.ts b/chrome/browser/resources/extensions/activity_log/activity_log_history_item.ts
index b9bad36..8282e275 100644
--- a/chrome/browser/resources/extensions/activity_log/activity_log_history_item.ts
+++ b/chrome/browser/resources/extensions/activity_log/activity_log_history_item.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import '../shared_style.css.js';
diff --git a/chrome/browser/resources/extensions/detail_view.ts b/chrome/browser/resources/extensions/detail_view.ts
index 6b2070e..ace5e94 100644
--- a/chrome/browser/resources/extensions/detail_view.ts
+++ b/chrome/browser/resources/extensions/detail_view.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js';
diff --git a/chrome/browser/resources/extensions/error_page.ts b/chrome/browser/resources/extensions/error_page.ts
index 80be32d..66fc542 100644
--- a/chrome/browser/resources/extensions/error_page.ts
+++ b/chrome/browser/resources/extensions/error_page.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
diff --git a/chrome/browser/resources/extensions/item.ts b/chrome/browser/resources/extensions/item.ts
index f71e6a3..28f3bf8 100644
--- a/chrome/browser/resources/extensions/item.ts
+++ b/chrome/browser/resources/extensions/item.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
diff --git a/chrome/browser/resources/extensions/kiosk_dialog.ts b/chrome/browser/resources/extensions/kiosk_dialog.ts
index 4af291b..cfa27051 100644
--- a/chrome/browser/resources/extensions/kiosk_dialog.ts
+++ b/chrome/browser/resources/extensions/kiosk_dialog.ts
@@ -5,7 +5,7 @@
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
diff --git a/chrome/browser/resources/extensions/runtime_host_permissions.ts b/chrome/browser/resources/extensions/runtime_host_permissions.ts
index 9101841..1b7813f 100644
--- a/chrome/browser/resources/extensions/runtime_host_permissions.ts
+++ b/chrome/browser/resources/extensions/runtime_host_permissions.ts
@@ -5,7 +5,7 @@
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_radio_group/cr_radio_group.m.js';
 import 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button.m.js';
 import 'chrome://resources/cr_elements/icons.m.js';
diff --git a/chrome/browser/resources/extensions/shortcut_input.ts b/chrome/browser/resources/extensions/shortcut_input.ts
index 315015e..e9ed24a 100644
--- a/chrome/browser/resources/extensions/shortcut_input.ts
+++ b/chrome/browser/resources/extensions/shortcut_input.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
diff --git a/chrome/browser/resources/extensions/site_permissions_by_site.ts b/chrome/browser/resources/extensions/site_permissions_by_site.ts
index 6a4c25f7..4cf1523 100644
--- a/chrome/browser/resources/extensions/site_permissions_by_site.ts
+++ b/chrome/browser/resources/extensions/site_permissions_by_site.ts
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import './shared_style.css.js';
 import './shared_vars.css.js';
 import './site_permissions_site_group.js';
 
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {ItemDelegate} from './item.js';
diff --git a/chrome/browser/resources/extensions/site_permissions_list.ts b/chrome/browser/resources/extensions/site_permissions_list.ts
index 6f3f8d7..35ac4f8 100644
--- a/chrome/browser/resources/extensions/site_permissions_list.ts
+++ b/chrome/browser/resources/extensions/site_permissions_list.ts
@@ -4,7 +4,7 @@
 
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import './strings.m.js';
diff --git a/chrome/browser/resources/extensions/site_permissions_site_group.ts b/chrome/browser/resources/extensions/site_permissions_site_group.ts
index 6364e07..55a49815 100644
--- a/chrome/browser/resources/extensions/site_permissions_site_group.ts
+++ b/chrome/browser/resources/extensions/site_permissions_site_group.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import './strings.m.js';
diff --git a/chrome/browser/resources/history/history_item.ts b/chrome/browser/resources/history/history_item.ts
index 9d1a655..8688389 100644
--- a/chrome/browser/resources/history/history_item.ts
+++ b/chrome/browser/resources/history/history_item.ts
@@ -11,7 +11,7 @@
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 
 import {CrCheckboxElement} from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {FocusRowBehavior} from 'chrome://resources/js/cr/ui/focus_row_behavior.m.js';
 import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js';
 import {EventTracker} from 'chrome://resources/js/event_tracker.m.js';
diff --git a/chrome/browser/resources/history/lazy_load.ts b/chrome/browser/resources/history/lazy_load.ts
index 7e1b7ad..a6adfbee 100644
--- a/chrome/browser/resources/history/lazy_load.ts
+++ b/chrome/browser/resources/history/lazy_load.ts
@@ -8,5 +8,5 @@
 import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
 import 'chrome://resources/cr_elements/cr_drawer/cr_drawer.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.js';
diff --git a/chrome/browser/resources/history/synced_device_card.ts b/chrome/browser/resources/history/synced_device_card.ts
index 30a3041..c6e24c0 100644
--- a/chrome/browser/resources/history/synced_device_card.ts
+++ b/chrome/browser/resources/history/synced_device_card.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js';
diff --git a/chrome/browser/resources/management/icons.html b/chrome/browser/resources/management/icons.html
index 733139a6..441726e 100644
--- a/chrome/browser/resources/management/icons.html
+++ b/chrome/browser/resources/management/icons.html
@@ -2,7 +2,7 @@
 <iron-iconset-svg name="management" size="24">
   <svg>
     <defs>
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
       <g id="bar-chart"><path d="M5 9.2h3V19H5zM10.6 5h2.8v14h-2.8zm5.6 8H19v6h-2.8z"></path></g>
       <g id="report"><path d="M15.73 3H8.27L3 8.27v7.46L8.27 21h7.46L21 15.73V8.27L15.73 3zM12 17.3c-.72 0-1.3-.58-1.3-1.3 0-.72.58-1.3 1.3-1.3.72 0 1.3.58 1.3 1.3 0 .72-.58 1.3-1.3 1.3zm1-4.3h-2V7h2v6z"></path></g>
       <g id="supervised-user"><path d="M11.99 2c-5.52 0-10 4.48-10 10s4.48 10 10 10 10-4.48 10-10-4.48-10-10-10zm3.61 6.34c1.07 0 1.93.86 1.93 1.93 0 1.07-.86 1.93-1.93 1.93-1.07 0-1.93-.86-1.93-1.93-.01-1.07.86-1.93 1.93-1.93zm-6-1.58c1.3 0 2.36 1.06 2.36 2.36 0 1.3-1.06 2.36-2.36 2.36s-2.36-1.06-2.36-2.36c0-1.31 1.05-2.36 2.36-2.36zm0 9.13v3.75c-2.4-.75-4.3-2.6-5.14-4.96 1.05-1.12 3.67-1.69 5.14-1.69.53 0 1.2.08 1.9.22-1.64.87-1.9 2.02-1.9 2.68zM11.99 20c-.27 0-.53-.01-.79-.04v-4.07c0-1.42 2.94-2.13 4.4-2.13 1.07 0 2.92.39 3.84 1.15-1.17 2.97-4.06 5.09-7.45 5.09z"></path></g>
diff --git a/chrome/browser/resources/management/management_browser_proxy.ts b/chrome/browser/resources/management/management_browser_proxy.ts
index 87311a7b..b286e08f 100644
--- a/chrome/browser/resources/management/management_browser_proxy.ts
+++ b/chrome/browser/resources/management/management_browser_proxy.ts
@@ -47,7 +47,7 @@
   description: string;
 }
 
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 /**
  * @enum {string} Look at ToJSDeviceReportingType usage in
  *    management_ui_handler.cc for more details.
@@ -85,7 +85,7 @@
 
   getManagedWebsites(): Promise<string[]>;
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   /**
    * @return Whether trust root configured or not.
    */
@@ -121,7 +121,7 @@
     return sendWithPromise('getManagedWebsites');
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   getLocalTrustRootsInfo() {
     return sendWithPromise('getLocalTrustRootsInfo');
   }
diff --git a/chrome/browser/resources/management/management_ui.html b/chrome/browser/resources/management/management_ui.html
index 8d81b3c..c868241e 100644
--- a/chrome/browser/resources/management/management_ui.html
+++ b/chrome/browser/resources/management/management_ui.html
@@ -271,7 +271,7 @@
             </section>
           </template>
 
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
           <div hidden="[[!localTrustRoots_]]">
             <section>
               <h2 class="cr-title-text">$i18n{localTrustRoots}</h2>
@@ -306,7 +306,7 @@
             </section>
           </template>
 </if>
-<if expr="not chromeos_ash and not chromeos_lacros">
+<if expr="not is_chromeos">
           <template is="dom-if"
               if="[[showBrowserReportingInfo_(browserReportingInfo_)]]">
             <section>
diff --git a/chrome/browser/resources/management/management_ui.ts b/chrome/browser/resources/management/management_ui.ts
index d016c1b..e2a0b7b2 100644
--- a/chrome/browser/resources/management/management_ui.ts
+++ b/chrome/browser/resources/management/management_ui.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/cr_page_host_style.css.js';
 import 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar.js';
@@ -20,7 +20,7 @@
 import {getTemplate} from './management_ui.html.js';
 
 import {BrowserReportingResponse, Extension, ManagementBrowserProxy, ManagementBrowserProxyImpl, ReportingType, ThreatProtectionInfo} from './management_browser_proxy.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {DeviceReportingResponse, DeviceReportingType} from './management_browser_proxy.js';
 // </if>
 
@@ -59,7 +59,7 @@
 
       managedWebsitesSubtitle_: String,
 
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       /**
        * List of messages related to device reporting.
        */
@@ -95,7 +95,7 @@
   private managedWebsites_: string[]|null;
   private managedWebsitesSubtitle_: string;
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   private deviceReportingInfo_: DeviceReportingResponse[]|null;
   private localTrustRoots_: string;
   private customerLogo_: string;
@@ -132,7 +132,7 @@
         (reportingInfo: BrowserReportingResponse[]) =>
             this.onBrowserReportingInfoReceived_(reportingInfo));
 
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     this.addWebUIListener(
         'plugin-vm-data-collection-updated',
         (enabled: boolean) => this.pluginVmDataCollectionEnabled_ = enabled);
@@ -148,7 +148,7 @@
 
     this.getExtensions_();
     this.getManagedWebsites_();
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     this.getDeviceReportingInfo_();
     this.getPluginVmDataCollectionStatus_();
     this.getLocalTrustRootsInfo_();
@@ -211,7 +211,7 @@
         this.threatProtectionInfo_.info.length > 0;
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   private getLocalTrustRootsInfo_() {
     this.browserProxy_!.getLocalTrustRootsInfo().then(trustRootsConfigured => {
       this.localTrustRoots_ = trustRootsConfigured ?
diff --git a/chrome/browser/resources/new_tab_page/doodle_share_dialog.ts b/chrome/browser/resources/new_tab_page/doodle_share_dialog.ts
index 89a5c27..2709b18 100644
--- a/chrome/browser/resources/new_tab_page/doodle_share_dialog.ts
+++ b/chrome/browser/resources/new_tab_page/doodle_share_dialog.ts
@@ -5,14 +5,14 @@
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 
 import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
 import {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {getTemplate} from './doodle_share_dialog.html.js';
 
+import {getTemplate} from './doodle_share_dialog.html.js';
 import {DoodleShareChannel} from './new_tab_page.mojom-webui.js';
 import {WindowProxy} from './window_proxy.js';
 
diff --git a/chrome/browser/resources/new_tab_page/modules/cart/module.ts b/chrome/browser/resources/new_tab_page/modules/cart/module.ts
index 2b7bfc4..5fac0de 100644
--- a/chrome/browser/resources/new_tab_page/modules/cart/module.ts
+++ b/chrome/browser/resources/new_tab_page/modules/cart/module.ts
@@ -5,7 +5,7 @@
 import '../module_header.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/cr_auto_img/cr_auto_img.js';
 import 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
diff --git a/chrome/browser/resources/new_tab_page/modules/cart_v2/module.ts b/chrome/browser/resources/new_tab_page/modules/cart_v2/module.ts
index 60130be..e924cbc 100644
--- a/chrome/browser/resources/new_tab_page/modules/cart_v2/module.ts
+++ b/chrome/browser/resources/new_tab_page/modules/cart_v2/module.ts
@@ -5,13 +5,13 @@
 import '../module_header.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/cr_auto_img/cr_auto_img.js';
 import 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
 
 import {CrActionMenuElement} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {CrLazyRenderElement} from 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js';
 import {CrToastElement} from 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
 import {DomIf, DomRepeat, DomRepeatEvent, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/new_tab_page/realbox/realbox_dropdown.ts b/chrome/browser/resources/new_tab_page/realbox/realbox_dropdown.ts
index 4cce30f..e29c570 100644
--- a/chrome/browser/resources/new_tab_page/realbox/realbox_dropdown.ts
+++ b/chrome/browser/resources/new_tab_page/realbox/realbox_dropdown.ts
@@ -4,7 +4,7 @@
 
 import './realbox_match.js';
 import 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 
 import {assert} from 'chrome://resources/js/assert.m.js';
diff --git a/chrome/browser/resources/new_tab_page/realbox/realbox_match.ts b/chrome/browser/resources/new_tab_page/realbox/realbox_match.ts
index f6bb182..ce8464d0 100644
--- a/chrome/browser/resources/new_tab_page/realbox/realbox_match.ts
+++ b/chrome/browser/resources/new_tab_page/realbox/realbox_match.ts
@@ -4,7 +4,7 @@
 
 import './realbox_icon.js';
 import './realbox_action.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
 
diff --git a/chrome/browser/resources/new_tab_page/voice_search_overlay.ts b/chrome/browser/resources/new_tab_page/voice_search_overlay.ts
index 02efd35..99d9cbd 100644
--- a/chrome/browser/resources/new_tab_page/voice_search_overlay.ts
+++ b/chrome/browser/resources/new_tab_page/voice_search_overlay.ts
@@ -5,7 +5,7 @@
 import 'chrome://resources/polymer/v3_0/iron-pages/iron-pages.js';
 import 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
diff --git a/chrome/browser/resources/pdf/elements/viewer-annotations-bar.ts b/chrome/browser/resources/pdf/elements/viewer-annotations-bar.ts
index d3c6eeb..5158593 100644
--- a/chrome/browser/resources/pdf/elements/viewer-annotations-bar.ts
+++ b/chrome/browser/resources/pdf/elements/viewer-annotations-bar.ts
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import './icons.html.js';
 import './pdf-shared.css.js';
 import './viewer-pen-options.js';
 import './viewer-toolbar-dropdown.js';
 
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {assert} from 'chrome://resources/js/assert_ts.js';
 import {EventTracker} from 'chrome://resources/js/event_tracker.m.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/pdf/elements/viewer-bookmark.ts b/chrome/browser/resources/pdf/elements/viewer-bookmark.ts
index 3271913b..17726d8 100644
--- a/chrome/browser/resources/pdf/elements/viewer-bookmark.ts
+++ b/chrome/browser/resources/pdf/elements/viewer-bookmark.ts
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/polymer/v3_0/paper-styles/color.js';
 import './pdf-shared.css.js';
 
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {Bookmark} from '../bookmark_type.js';
diff --git a/chrome/browser/resources/pdf/elements/viewer-download-controls.ts b/chrome/browser/resources/pdf/elements/viewer-download-controls.ts
index 857dafa..e9fe243 100644
--- a/chrome/browser/resources/pdf/elements/viewer-download-controls.ts
+++ b/chrome/browser/resources/pdf/elements/viewer-download-controls.ts
@@ -3,13 +3,13 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import './icons.html.js';
 import './pdf-shared.css.js';
 
 import {AnchorAlignment, CrActionMenuElement} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
diff --git a/chrome/browser/resources/pdf/elements/viewer-pdf-sidenav.ts b/chrome/browser/resources/pdf/elements/viewer-pdf-sidenav.ts
index 3d5fbf1..da54796 100644
--- a/chrome/browser/resources/pdf/elements/viewer-pdf-sidenav.ts
+++ b/chrome/browser/resources/pdf/elements/viewer-pdf-sidenav.ts
@@ -7,7 +7,7 @@
 import './icons.html.js';
 import './viewer-document-outline.js';
 import './viewer-thumbnail-bar.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 
diff --git a/chrome/browser/resources/pdf/elements/viewer-pen-options.ts b/chrome/browser/resources/pdf/elements/viewer-pen-options.ts
index 3ff97e29..ac1c858 100644
--- a/chrome/browser/resources/pdf/elements/viewer-pen-options.ts
+++ b/chrome/browser/resources/pdf/elements/viewer-pen-options.ts
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {assert} from 'chrome://resources/js/assert_ts.js';
 import {beforeNextRender, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
diff --git a/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.ts b/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.ts
index 9a91be0..a5db4e9 100644
--- a/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.ts
+++ b/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown.ts
@@ -2,13 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/polymer/v3_0/paper-styles/shadow.js';
 
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
 import {getTemplate} from './viewer-toolbar-dropdown.html.js';
 
 /**
diff --git a/chrome/browser/resources/pdf/elements/viewer-toolbar.ts b/chrome/browser/resources/pdf/elements/viewer-toolbar.ts
index cc25d70b..4567609 100644
--- a/chrome/browser/resources/pdf/elements/viewer-toolbar.ts
+++ b/chrome/browser/resources/pdf/elements/viewer-toolbar.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
diff --git a/chrome/browser/resources/pdf/elements/viewer-zoom-button.ts b/chrome/browser/resources/pdf/elements/viewer-zoom-button.ts
index 9176dd8f..66f4779 100644
--- a/chrome/browser/resources/pdf/elements/viewer-zoom-button.ts
+++ b/chrome/browser/resources/pdf/elements/viewer-zoom-button.ts
@@ -3,10 +3,11 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/polymer/v3_0/paper-styles/shadow.js';
 
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
 import {getTemplate} from './viewer-zoom-button.html.js';
 
 export class ViewerZoomButtonElement extends PolymerElement {
diff --git a/chrome/browser/resources/pdf/pdf_viewer_wrapper.ts b/chrome/browser/resources/pdf/pdf_viewer_wrapper.ts
index 00b7ac3..417d829 100644
--- a/chrome/browser/resources/pdf/pdf_viewer_wrapper.ts
+++ b/chrome/browser/resources/pdf/pdf_viewer_wrapper.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 export {CrActionMenuElement} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
-export {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+export {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 // <if expr="enable_ink">
 export {AnnotationTool} from './annotation_tool.js';
 // </if>
diff --git a/chrome/browser/resources/preinstalled_web_apps/resources.grd b/chrome/browser/resources/preinstalled_web_apps/resources.grd
index c1942e9..b2712b2 100644
--- a/chrome/browser/resources/preinstalled_web_apps/resources.grd
+++ b/chrome/browser/resources/preinstalled_web_apps/resources.grd
@@ -18,7 +18,7 @@
       <include name="IDR_PREINSTALLED_WEB_APPS_GOOGLE_SLIDES_ICON_192_PNG" file="internal/google_slides_192.png" type="BINDATA" />
       <include name="IDR_PREINSTALLED_WEB_APPS_GMAIL_ICON_192_PNG" file="internal/gmail_192.png" type="BINDATA" />
       <include name="IDR_PREINSTALLED_WEB_APPS_YOUTUBE_ICON_192_PNG" file="internal/youtube_192.png" type="BINDATA" />
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <include name="IDR_PREINSTALLED_WEB_APPS_GOOGLE_CALENDAR_ICON_192_PNG" file="internal/google_calendar_192.png" type="BINDATA" />
       </if>
     </includes>
diff --git a/chrome/browser/resources/print_preview/data/cdd.ts b/chrome/browser/resources/print_preview/data/cdd.ts
index 8c72a9e..b266784 100644
--- a/chrome/browser/resources/print_preview/data/cdd.ts
+++ b/chrome/browser/resources/print_preview/data/cdd.ts
@@ -134,7 +134,7 @@
   page_orientation?: PageOrientationCapability;
   media_size?: MediaSizeCapability;
   dpi?: DpiCapability;
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   pin?: PinCapability;
   // </if>
 }
diff --git a/chrome/browser/resources/print_preview/data/destination.ts b/chrome/browser/resources/print_preview/data/destination.ts
index 22beb37..79b9dfd 100644
--- a/chrome/browser/resources/print_preview/data/destination.ts
+++ b/chrome/browser/resources/print_preview/data/destination.ts
@@ -6,13 +6,13 @@
 
 import {assert} from 'chrome://resources/js/assert_ts.js';
 
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {NativeLayerCrosImpl} from '../native_layer_cros.js';
 // </if>
 
 import {Cdd, ColorCapability, ColorOption, CopiesCapability} from './cdd.js';
 
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {getStatusReasonFromPrinterStatus, PrinterStatus, PrinterStatusReason} from './printer_status_cros.js';
 // </if>
 
@@ -25,7 +25,7 @@
   // legacy entries in the recent destinations, since we can't guarantee all
   // such recent printers have been overridden.
   COOKIES = 'cookies',
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   DEVICE = 'device',
   // </if>
   PRIVET = 'privet',
@@ -45,7 +45,7 @@
   CLOUD_PRINTER_DEPRECATED = 4
 }
 
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 /**
  * Enumeration specifying whether a destination is provisional and the reason
  * the destination is provisional.
@@ -78,7 +78,7 @@
 }
 
 export function isPdfPrinter(id: string): boolean {
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   if (id === GooglePromotedDestinationId.SAVE_TO_DRIVE_CROS) {
     return true;
   }
@@ -123,7 +123,7 @@
 
 export interface DestinationOptionalParams {
   isEnterprisePrinter?: boolean;
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   provisionalType?: DestinationProvisionalType;
   // </if>
   extensionId?: string;
@@ -192,7 +192,7 @@
    */
   private extensionName_: string;
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   /**
    * Different from  DestinationProvisionalType.NONE if
    * the destination is provisional. Provisional destinations cannot be
@@ -244,7 +244,7 @@
     this.extensionName_ = (params && params.extensionName) || '';
     this.location_ = (params && params.location) || '';
     this.type_ = this.computeType_(id, origin);
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     this.provisionalType_ =
         (params && params.provisionalType) || DestinationProvisionalType.NONE;
 
@@ -324,7 +324,7 @@
     }
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   get eulaUrl(): string {
     return this.eulaUrl_;
   }
@@ -436,7 +436,7 @@
 
   /** @return Path to the SVG for the destination's icon. */
   get icon(): string {
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     if (this.id_ === GooglePromotedDestinationId.SAVE_TO_DRIVE_CROS) {
       return 'print-preview:save-to-drive';
     }
@@ -582,7 +582,7 @@
  */
 export enum GooglePromotedDestinationId {
   SAVE_AS_PDF = 'Save as PDF',
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   SAVE_TO_DRIVE_CROS = 'Save to Drive CrOS',
   // </if>
 }
@@ -591,7 +591,7 @@
 export const PDF_DESTINATION_KEY: string =
     `${GooglePromotedDestinationId.SAVE_AS_PDF}/${DestinationOrigin.LOCAL}/`;
 
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 /* Unique identifier for the Save to Drive CrOS destination */
 export const SAVE_TO_DRIVE_CROS_DESTINATION_KEY: string =
     `${GooglePromotedDestinationId.SAVE_TO_DRIVE_CROS}/${
diff --git a/chrome/browser/resources/print_preview/data/destination_store.ts b/chrome/browser/resources/print_preview/data/destination_store.ts
index 676b87f..6ba5dcc 100644
--- a/chrome/browser/resources/print_preview/data/destination_store.ts
+++ b/chrome/browser/resources/print_preview/data/destination_store.ts
@@ -7,18 +7,18 @@
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 
 import {CapabilitiesResponse, NativeLayer, NativeLayerImpl} from '../native_layer.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {NativeLayerCros, NativeLayerCrosImpl, PrinterSetupResponse} from '../native_layer_cros.js';
 
 // </if>
 import {Cdd, MediaSizeOption} from './cdd.js';
 import {createDestinationKey, createRecentDestinationKey, Destination, DestinationOrigin, GooglePromotedDestinationId, isPdfPrinter, PDF_DESTINATION_KEY, PrinterType, RecentDestination} from './destination.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {DestinationProvisionalType} from './destination.js';
 // </if>
 import {DestinationMatch} from './destination_match.js';
 import {ExtensionDestinationInfo, LocalDestinationInfo, parseDestination} from './local_parsers.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {parseExtensionDestination} from './local_parsers.js';
 // </if>
 
@@ -152,7 +152,7 @@
   ERROR = 'DestinationStore.ERROR',
   SELECTED_DESTINATION_CAPABILITIES_READY = 'DestinationStore' +
       '.SELECTED_DESTINATION_CAPABILITIES_READY',
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   DESTINATION_EULA_READY = 'DestinationStore.DESTINATION_EULA_READY',
   // </if>
 }
@@ -188,7 +188,7 @@
    */
   private nativeLayer_: NativeLayer = NativeLayerImpl.getInstance();
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   /**
    * Used to fetch information about Chrome OS local print destinations.
    */
@@ -317,10 +317,10 @@
    */
   init(
       pdfPrinterDisabled: boolean,
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       isDriveMounted: boolean,
       // </if>
-      // <if expr="not chromeos_ash and not chromeos_lacros">
+      // <if expr="not is_chromeos">
       _isDriveMounted: boolean,
       // </if>
       systemDefaultDestinationId: string,
@@ -331,10 +331,10 @@
       const systemDefaultType = systemDefaultVirtual ?
           PrinterType.PDF_PRINTER :
           PrinterType.LOCAL_PRINTER;
-      // <if expr="not chromeos_ash and not chromeos_lacros">
+      // <if expr="not is_chromeos">
       const systemDefaultOrigin = DestinationOrigin.LOCAL;
       // </if>
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       const systemDefaultOrigin = systemDefaultVirtual ?
           DestinationOrigin.LOCAL :
           DestinationOrigin.CROS;
@@ -359,7 +359,7 @@
 
     this.pdfPrinterEnabled_ = !pdfPrinterDisabled;
     this.createLocalPdfPrintDestination_();
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     if (isDriveMounted) {
       this.createLocalDrivePrintDestination_();
     }
@@ -497,7 +497,7 @@
     this.tracker_.removeAll();
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   /**
    * Attempts to find the EULA URL of the the destination ID.
    */
@@ -586,7 +586,7 @@
       return;
     }
 
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     assert(
         !destination.isProvisional, 'Unable to select provisonal destinations');
     // </if>
@@ -610,7 +610,7 @@
     }
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   /**
    * Attempt to resolve the capabilities for a Chrome OS printer.
    */
@@ -716,7 +716,7 @@
     return this.destinationMap_.get(key);
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   /**
    * Removes the provisional destination with ID |provisionalId| from
    * |destinationMap_| and |destinations_|.
@@ -833,7 +833,7 @@
     }
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   /**
    * Creates a local Drive print destination.
    */
@@ -900,7 +900,7 @@
       }
       dest.capabilities = settingsInfo.capabilities;
       this.updateDestination_(dest);
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       // Start the fetch for the PPD EULA URL.
       this.fetchEulaUrl(dest.id);
       // </if>
diff --git a/chrome/browser/resources/print_preview/data/local_parsers.ts b/chrome/browser/resources/print_preview/data/local_parsers.ts
index 7e21f33..b99138e6 100644
--- a/chrome/browser/resources/print_preview/data/local_parsers.ts
+++ b/chrome/browser/resources/print_preview/data/local_parsers.ts
@@ -6,7 +6,7 @@
 import {isChromeOS, isLacros} from 'chrome://resources/js/cr.m.js';
 
 import {Destination, DestinationOptionalParams, DestinationOrigin, PrinterType} from './destination.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {DestinationProvisionalType} from './destination.js';
 // </if>
 
@@ -84,7 +84,7 @@
  */
 export function parseExtensionDestination(
     destinationInfo: ExtensionDestinationInfo): Destination {
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   const provisionalType = destinationInfo.provisional ?
       DestinationProvisionalType.NEEDS_USB_PERMISSION :
       DestinationProvisionalType.NONE;
@@ -95,7 +95,7 @@
         description: destinationInfo.description || '',
         extensionId: destinationInfo.extensionId,
         extensionName: destinationInfo.extensionName || '',
-        // <if expr="chromeos_ash or chromeos_lacros">
+        // <if expr="is_chromeos">
         provisionalType: provisionalType,
         // </if>
       });
diff --git a/chrome/browser/resources/print_preview/data/model.ts b/chrome/browser/resources/print_preview/data/model.ts
index 50a4cac..0cac7a33 100644
--- a/chrome/browser/resources/print_preview/data/model.ts
+++ b/chrome/browser/resources/print_preview/data/model.ts
@@ -3,14 +3,14 @@
 // found in the LICENSE file.
 
 import {assert} from 'chrome://resources/js/assert_ts.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 // </if>
 import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {BackgroundGraphicsModeRestriction, Policies} from '../native_layer.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {ColorModeRestriction, DuplexModeRestriction, PinModeRestriction} from '../native_layer.js';
 // </if>
 import {CapabilityWithReset, Cdd, CddCapabilities, ColorOption, DpiOption, DuplexOption, MediaSizeOption} from './cdd.js';
@@ -59,7 +59,7 @@
   otherOptions: Setting;
   ranges: Setting;
   pagesPerSheet: Setting;
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   pin: Setting;
   pinValue: Setting;
   // </if>
@@ -83,7 +83,7 @@
   scalingType?: ScalingType;
   scalingTypePdf?: ScalingType;
   vendorOptions?: object;
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   isPinEnabled?: boolean;
   pinValue?: string;
   // </if>
@@ -167,7 +167,7 @@
   pageCount: number,
   pageHeight: number,
   pageWidth: number,
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   printToGoogleDrive: boolean,
   // </if>
   showSystemDialog: boolean,
@@ -226,7 +226,7 @@
   'scalingTypePdf',
   'vendorItems',
 ];
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 STICKY_SETTING_NAMES.push('pin', 'pinValue');
 // </if>
 
@@ -497,7 +497,7 @@
               key: 'recentDestinations',
               updatesPreview: false,
             },
-            // <if expr="chromeos_ash or chromeos_lacros">
+            // <if expr="is_chromeos">
             pin: {
               value: false,
               unavailableValue: false,
@@ -743,7 +743,7 @@
     this.setSettingPath_(
         'vendorItems.available', !!caps && !!caps.vendor_capability);
 
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     const pinSupported = !!caps && !!caps.pin && !!caps.pin.supported &&
         loadTimeData.getBoolean('isEnterpriseManaged');
     this.set('settings.pin.available', pinSupported);
@@ -1064,7 +1064,7 @@
     // to free up these spots for supported printers.
     const unsupportedOrigins: DestinationOrigin[] = [
       DestinationOrigin.COOKIES,
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       DestinationOrigin.DEVICE,
       // </if>
       DestinationOrigin.PRIVET,
@@ -1202,7 +1202,7 @@
       const allowedMode = policiesObject[settingName].allowedMode;
       this.configurePolicySetting_(settingName, allowedMode, defaultMode);
     });
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     if (policiesObject['sheets']) {
       if (!this.policySettings_) {
         this.policySettings_ = {};
@@ -1297,7 +1297,7 @@
       for (const [settingName, policy] of Object.entries(
                this.policySettings_)) {
         const policyEntry = policy as PolicyEntry;
-        // <if expr="chromeos_ash or chromeos_lacros">
+        // <if expr="is_chromeos">
         if (settingName === 'sheets') {
           this.maxSheets = policyEntry.value;
           continue;
@@ -1469,7 +1469,7 @@
 
   private updateManaged_() {
     let managedSettings = ['cssBackground', 'headerFooter'];
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     managedSettings =
         managedSettings.concat(['color', 'duplex', 'duplexShortEdge', 'pin']);
     // </if>
@@ -1560,7 +1560,7 @@
       pageWidth: this.pageSize.width,
       pageHeight: this.pageSize.height,
       showSystemDialog: showSystemDialog,
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       printToGoogleDrive:
           destination.id === GooglePromotedDestinationId.SAVE_TO_DRIVE_CROS,
       // </if>
@@ -1581,7 +1581,7 @@
       ticket['capabilities'] = JSON.stringify(destination.capabilities);
     }
 
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     if (this.getSettingValue('pin')) {
       ticket['pinValue'] = this.getSettingValue('pinValue');
     }
diff --git a/chrome/browser/resources/print_preview/native_layer.ts b/chrome/browser/resources/print_preview/native_layer.ts
index 362bf752..5469b40 100644
--- a/chrome/browser/resources/print_preview/native_layer.ts
+++ b/chrome/browser/resources/print_preview/native_layer.ts
@@ -45,7 +45,7 @@
   DUPLEX = 0x6,
 }
 
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 /**
  * Enumeration of PIN printing mode restrictions used by Chromium.
  * This has to coincide with |printing::PinModeRestriction| as defined in
@@ -77,7 +77,7 @@
     allowedMode?: DuplexModeRestriction,
     defaultMode?: DuplexModeRestriction,
   };
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   pin?: {allowedMode?: PinModeRestriction, defaultMode?: PinModeRestriction};
   // </if>
   printPdfAsImage?: {defaultMode?: boolean};
@@ -173,7 +173,7 @@
    */
   saveAppState(appStateStr: string): void;
 
-  // <if expr="not chromeos_ash and not chromeos_lacros and not is_win">
+  // <if expr="not is_chromeos and not is_win">
   /** Shows the system's native printing dialog. */
   showSystemDialog(): void;
   // </if>
diff --git a/chrome/browser/resources/print_preview/print_preview.ts b/chrome/browser/resources/print_preview/print_preview.ts
index bcca586..ba0e02ba 100644
--- a/chrome/browser/resources/print_preview/print_preview.ts
+++ b/chrome/browser/resources/print_preview/print_preview.ts
@@ -4,12 +4,12 @@
 
 export {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 export {CrCheckboxElement} from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
-export {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+export {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 export {PluralStringProxyImpl as PrintPreviewPluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js';
 export {IronMeta} from 'chrome://resources/polymer/v3_0/iron-meta/iron-meta.js';
 export {Cdd, MediaSizeCapability, MediaSizeOption, VendorCapabilityValueType} from './data/cdd.js';
 export {ColorMode, createDestinationKey, Destination, DestinationOrigin, GooglePromotedDestinationId, makeRecentDestination, PDF_DESTINATION_KEY, PrinterType, RecentDestination} from './data/destination.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 export {SAVE_TO_DRIVE_CROS_DESTINATION_KEY} from './data/destination.js';
 // </if>
 export {DestinationErrorType, DestinationStore, DestinationStoreEventType} from './data/destination_store.js';
@@ -18,17 +18,17 @@
 export {CustomMarginsOrientation, Margins, MarginsSetting, MarginsType} from './data/margins.js';
 export {MeasurementSystem, MeasurementSystemUnitType} from './data/measurement_system.js';
 export {DuplexMode, DuplexType, getInstance, PolicyObjectEntry, PrintPreviewModelElement, PrintTicket, SerializedSettings, Setting, Settings, whenReady} from './data/model.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 export {PrintServerStore, PrintServerStoreEventType} from './data/print_server_store.js';
 // </if>
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 export {PrinterState, PrinterStatus, PrinterStatusReason, PrinterStatusSeverity} from './data/printer_status_cros.js';
 // </if>
 export {ScalingType} from './data/scaling.js';
 export {Size} from './data/size.js';
 export {Error, State} from './data/state.js';
 export {BackgroundGraphicsModeRestriction, CapabilitiesResponse, ColorModeRestriction, DuplexModeRestriction, NativeInitialSettings, NativeLayer, NativeLayerImpl} from './native_layer.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 export {PinModeRestriction} from './native_layer.js';
 export {NativeLayerCros, NativeLayerCrosImpl, PrinterSetupResponse, PrintServersConfig} from './native_layer_cros.js';
 // </if>
@@ -39,24 +39,24 @@
 export {PrintPreviewButtonStripElement} from './ui/button_strip.js';
 export {PrintPreviewColorSettingsElement} from './ui/color_settings.js';
 export {DEFAULT_MAX_COPIES, PrintPreviewCopiesSettingsElement} from './ui/copies_settings.js';
-// <if expr="not chromeos_ash and not chromeos_lacros">
+// <if expr="not is_chromeos">
 export {PrintPreviewDestinationDialogElement} from './ui/destination_dialog.js';
 // </if>
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 export {PrintPreviewDestinationDialogCrosElement} from './ui/destination_dialog_cros.js';
 export {PrintPreviewDestinationDropdownCrosElement} from './ui/destination_dropdown_cros.js';
 // </if>
 export {PrintPreviewDestinationListElement} from './ui/destination_list.js';
-// <if expr="not chromeos_ash and not chromeos_lacros">
+// <if expr="not is_chromeos">
 export {PrintPreviewDestinationListItemElement} from './ui/destination_list_item.js';
 // </if>
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 export {PrintPreviewDestinationListItemElement} from './ui/destination_list_item_cros.js';
 // </if>
-// <if expr="not chromeos_ash and not chromeos_lacros">
+// <if expr="not is_chromeos">
 export {PrintPreviewDestinationSelectElement} from './ui/destination_select.js';
 // </if>
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 export {PrintPreviewDestinationSelectCrosElement} from './ui/destination_select_cros.js';
 // </if>
 export {DestinationState, NUM_PERSISTED_DESTINATIONS, PrintPreviewDestinationSettingsElement} from './ui/destination_settings.js';
@@ -64,7 +64,7 @@
 export {PrintPreviewDuplexSettingsElement} from './ui/duplex_settings.js';
 export {PrintPreviewHeaderElement} from './ui/header.js';
 export {PrintPreviewLayoutSettingsElement} from './ui/layout_settings.js';
-// <if expr="not chromeos_ash and not chromeos_lacros">
+// <if expr="not is_chromeos">
 export {PrintPreviewLinkContainerElement} from './ui/link_container.js';
 // </if>
 export {PrintPreviewMarginControlElement} from './ui/margin_control.js';
@@ -75,7 +75,7 @@
 export {PrintPreviewOtherOptionsSettingsElement} from './ui/other_options_settings.js';
 export {PrintPreviewPagesPerSheetSettingsElement} from './ui/pages_per_sheet_settings.js';
 export {PagesValue, PrintPreviewPagesSettingsElement} from './ui/pages_settings.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 export {PrintPreviewPinSettingsElement} from './ui/pin_settings.js';
 // </if>
 export {PluginProxy, PluginProxyImpl, ViewportChangedCallback} from './ui/plugin_proxy.js';
diff --git a/chrome/browser/resources/print_preview/ui/app.html b/chrome/browser/resources/print_preview/ui/app.html
index 9ce0d9a..18b779b 100644
--- a/chrome/browser/resources/print_preview/ui/app.html
+++ b/chrome/browser/resources/print_preview/ui/app.html
@@ -56,7 +56,7 @@
 <if expr="is_macosx">
     on-open-pdf-in-preview="onOpenPdfInPreview_"
 </if>
-<if expr="not chromeos_ash and not chromeos_lacros">
+<if expr="not is_chromeos">
     on-print-with-system-dialog="onPrintWithSystemDialog_"
 </if>
     on-print-requested="onPrintRequested_"
diff --git a/chrome/browser/resources/print_preview/ui/app.ts b/chrome/browser/resources/print_preview/ui/app.ts
index 28353e1..a719848 100644
--- a/chrome/browser/resources/print_preview/ui/app.ts
+++ b/chrome/browser/resources/print_preview/ui/app.ts
@@ -220,7 +220,7 @@
     // On Linux/Windows, shift + p means that e.key will be 'P' with caps lock
     // off or 'p' with caps lock on.
     // On Mac, alt + p means that e.key will be unicode 03c0 (pi).
-    // <if expr="not chromeos_ash and not chromeos_lacros">
+    // <if expr="not is_chromeos">
     if (e.key === 'P' || e.key === 'p' || e.key === '\u03c0') {
       if ((isMac && e.metaKey && e.altKey && !e.shiftKey && !e.ctrlKey) ||
           (!isMac && e.shiftKey && e.ctrlKey && !e.altKey && !e.metaKey)) {
@@ -336,7 +336,7 @@
         break;
       case DestinationState.ERROR:
         let newState = State.ERROR;
-        // <if expr="chromeos_ash or chromeos_lacros">
+        // <if expr="is_chromeos">
         if (this.error_ === Error.NO_DESTINATIONS) {
           newState = State.FATAL_ERROR;
         }
@@ -426,7 +426,7 @@
     this.$.state.transitTo(State.READY);
   }
 
-  // <if expr="not chromeos_ash and not chromeos_lacros">
+  // <if expr="not is_chromeos">
   private onPrintWithSystemDialog_() {
     // <if expr="is_win">
     this.showSystemDialogBeforePrint_ = true;
diff --git a/chrome/browser/resources/print_preview/ui/button_strip.html b/chrome/browser/resources/print_preview/ui/button_strip.html
index 88448ff..3c0280e 100644
--- a/chrome/browser/resources/print_preview/ui/button_strip.html
+++ b/chrome/browser/resources/print_preview/ui/button_strip.html
@@ -23,7 +23,7 @@
     margin-inline-end: 0;
   }
 
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
   .error-message {
     color: red;
     margin: 16px 16px 0;
@@ -31,7 +31,7 @@
   }
 </if>
 </style>
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
 <div class="error-message"
     hidden="[[!showSheetsError_(destination.id, maxSheets, sheetCount)]]">
   [[errorMessage_]]
diff --git a/chrome/browser/resources/print_preview/ui/button_strip.ts b/chrome/browser/resources/print_preview/ui/button_strip.ts
index e00d70c..66986cc 100644
--- a/chrome/browser/resources/print_preview/ui/button_strip.ts
+++ b/chrome/browser/resources/print_preview/ui/button_strip.ts
@@ -9,7 +9,7 @@
 
 import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {PluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js';
 import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js';
 // </if>
@@ -54,7 +54,7 @@
         },
       },
 
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       errorMessage_: {
         type: String,
         observer: 'errorMessageChanged_',
@@ -67,7 +67,7 @@
     return [
       'updatePrintButtonLabel_(destination.id)',
       'updatePrintButtonEnabled_(state, destination.id, maxSheets, sheetCount)',
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       'updateErrorMessage_(state, destination.id, maxSheets, sheetCount)',
       // </if>
 
@@ -81,7 +81,7 @@
   state: State;
   private printButtonEnabled_: boolean;
   private printButtonLabel_: string;
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   private errorMessage_: string;
   // </if>
 
@@ -116,10 +116,10 @@
         this.printButtonEnabled_ = false;
         break;
       case (State.READY):
-        // <if expr="chromeos_ash or chromeos_lacros">
+        // <if expr="is_chromeos">
         this.printButtonEnabled_ = !this.printButtonDisabled_();
         // </if>
-        // <if expr="not chromeos_ash and not chromeos_lacros">
+        // <if expr="not is_chromeos">
         this.printButtonEnabled_ = true;
         // </if>
         if (this.firstLoad || this.lastState_ === State.PRINTING) {
@@ -136,7 +136,7 @@
     this.lastState_ = this.state;
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   /**
    * @return Whether to disable "Print" button because of sheets limit policy.
    */
diff --git a/chrome/browser/resources/print_preview/ui/destination_list.ts b/chrome/browser/resources/print_preview/ui/destination_list.ts
index 5124dd9..1863b2f 100644
--- a/chrome/browser/resources/print_preview/ui/destination_list.ts
+++ b/chrome/browser/resources/print_preview/ui/destination_list.ts
@@ -5,10 +5,10 @@
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
-// <if expr="not chromeos_ash and not chromeos_lacros">
+// <if expr="not is_chromeos">
 import './destination_list_item.js';
 // </if>
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import './destination_list_item_cros.js';
 // </if>
 import './print_preview_vars.css.js';
diff --git a/chrome/browser/resources/print_preview/ui/destination_settings.html b/chrome/browser/resources/print_preview/ui/destination_settings.html
index 8e65a3e..80ae0a9 100644
--- a/chrome/browser/resources/print_preview/ui/destination_settings.html
+++ b/chrome/browser/resources/print_preview/ui/destination_settings.html
@@ -1,11 +1,11 @@
 <style include="print-preview-shared">
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
   :host([has-pin-setting_]) {
     margin-bottom: 0 !important;
   }
 </if>
 </style>
-<if expr="not chromeos_ash and not chromeos_lacros">
+<if expr="not is_chromeos">
   <print-preview-destination-select id="destinationSelect"
       active-user="[[activeUser_]]" dark="[[dark]]"
       destination="[[destination]]"
@@ -27,7 +27,7 @@
     </template>
   </cr-lazy-render>
 </if>
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
   <print-preview-destination-select-cros id="destinationSelect"
       active-user="[[activeUser_]]" dark="[[dark]]"
       destination="[[destination]]"
diff --git a/chrome/browser/resources/print_preview/ui/destination_settings.ts b/chrome/browser/resources/print_preview/ui/destination_settings.ts
index 8bd9d54..9c53c6a 100644
--- a/chrome/browser/resources/print_preview/ui/destination_settings.ts
+++ b/chrome/browser/resources/print_preview/ui/destination_settings.ts
@@ -5,16 +5,16 @@
 import 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
-// <if expr="not chromeos_ash and not chromeos_lacros">
+// <if expr="not is_chromeos">
 import './destination_dialog.js';
 // </if>
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import './destination_dialog_cros.js';
 // </if>
-// <if expr="not chromeos_ash and not chromeos_lacros">
+// <if expr="not is_chromeos">
 import './destination_select.js';
 // </if>
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import './destination_select_cros.js';
 // </if>
 import './print_preview_shared.css.js';
@@ -31,22 +31,22 @@
 import {beforeNextRender, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {createRecentDestinationKey, Destination, isPdfPrinter, makeRecentDestination, PrinterType, RecentDestination} from '../data/destination.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {SAVE_TO_DRIVE_CROS_DESTINATION_KEY} from '../data/destination.js';
 // </if>
 import {DestinationErrorType, DestinationStore, DestinationStoreEventType} from '../data/destination_store.js';
 import {Error, State} from '../data/state.js';
 
-// <if expr="not chromeos_ash and not chromeos_lacros">
+// <if expr="not is_chromeos">
 import {PrintPreviewDestinationDialogElement} from './destination_dialog.js';
 // </if>
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {PrintPreviewDestinationDialogCrosElement} from './destination_dialog_cros.js';
 // </if>
-// <if expr="not chromeos_ash and not chromeos_lacros">
+// <if expr="not is_chromeos">
 import {PrintPreviewDestinationSelectElement} from './destination_select.js';
 // </if>
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {PrintPreviewDestinationSelectCrosElement} from './destination_select_cros.js';
 // </if>
 import {getTemplate} from './destination_settings.html.js';
@@ -60,10 +60,10 @@
 }
 
 /** Number of recent destinations to save. */
-// <if expr="not chromeos_ash and not chromeos_lacros">
+// <if expr="not is_chromeos">
 export const NUM_PERSISTED_DESTINATIONS: number = 5;
 // </if>
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 export const NUM_PERSISTED_DESTINATIONS: number = 10;
 // </if>
 
@@ -75,12 +75,12 @@
 
 export interface PrintPreviewDestinationSettingsElement {
   $: {
-    // <if expr="not chromeos_ash and not chromeos_lacros">
+    // <if expr="not is_chromeos">
     destinationDialog:
         CrLazyRenderElement<PrintPreviewDestinationDialogElement>,
     destinationSelect: PrintPreviewDestinationSelectElement,
     // </if>
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     destinationDialog:
         CrLazyRenderElement<PrintPreviewDestinationDialogCrosElement>,
     destinationSelect: PrintPreviewDestinationSelectCrosElement,
@@ -137,7 +137,7 @@
 
       displayedDestinations_: Array,
 
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       driveDestinationKey_: {
         type: String,
         value: '',
@@ -179,7 +179,7 @@
   private destinationStore_: DestinationStore|null;
   private displayedDestinations_: Destination[];
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   private driveDestinationKey_: string;
   private hasPinSetting_: boolean;
   // </if>
@@ -216,7 +216,7 @@
         this.destinationStore_, DestinationStoreEventType.DESTINATIONS_INSERTED,
         this.updateDropdownDestinations_.bind(this));
 
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     this.tracker_.add(
         this.destinationStore_,
         DestinationStoreEventType.DESTINATION_EULA_READY,
@@ -246,7 +246,7 @@
     this.pdfPrinterDisabled_ = pdfPrinterDisabled;
     let recentDestinations =
         this.getSettingValue('recentDestinations') as RecentDestination[];
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     this.driveDestinationKey_ =
         isDriveMounted ? SAVE_TO_DRIVE_CROS_DESTINATION_KEY : '';
     // </if>
@@ -428,7 +428,7 @@
           this.destination.type === PrinterType.PDF_PRINTER));
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   private computeHasPinSetting_(): boolean {
     return this.getSetting('pin').available;
   }
@@ -480,7 +480,7 @@
     return this.destinationStore_;
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   /**
    * @param e Event containing the current destination's EULA URL.
    */
diff --git a/chrome/browser/resources/print_preview/ui/icons.html b/chrome/browser/resources/print_preview/ui/icons.html
index a0c19c5..4fe2cce 100644
--- a/chrome/browser/resources/print_preview/ui/icons.html
+++ b/chrome/browser/resources/print_preview/ui/icons.html
@@ -11,7 +11,7 @@
         <path d="M-5-5h32v32H-5z">
       </g>
 
-    <if expr="chromeos_ash or chromeos_lacros">
+    <if expr="is_chromeos">
       <!-- Icon from http://icons/ -->
       <g id="save-to-drive">
         <path fill="none" d="M0 0h24v24H0z"></path>
diff --git a/chrome/browser/resources/print_preview/ui/link_container.ts b/chrome/browser/resources/print_preview/ui/link_container.ts
index 318990c..2dc40ed7 100644
--- a/chrome/browser/resources/print_preview/ui/link_container.ts
+++ b/chrome/browser/resources/print_preview/ui/link_container.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import './print_preview_vars.css.js';
diff --git a/chrome/browser/resources/print_preview/ui/preview_area.ts b/chrome/browser/resources/print_preview/ui/preview_area.ts
index 01af4b5..882c9ce 100644
--- a/chrome/browser/resources/print_preview/ui/preview_area.ts
+++ b/chrome/browser/resources/print_preview/ui/preview_area.ts
@@ -745,7 +745,7 @@
           substitutions: [],
           tags: ['BR'],
         });
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       case Error.NO_DESTINATIONS:
         return this.i18n('noDestinationsMessage');
       // </if>
diff --git a/chrome/browser/resources/print_preview/ui/print_preview_search_box.ts b/chrome/browser/resources/print_preview/ui/print_preview_search_box.ts
index 8e225fd3..f93fbb8b 100644
--- a/chrome/browser/resources/print_preview/ui/print_preview_search_box.ts
+++ b/chrome/browser/resources/print_preview/ui/print_preview_search_box.ts
@@ -4,7 +4,7 @@
 
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import './print_preview_shared.css.js';
 
diff --git a/chrome/browser/resources/print_preview/ui/sidebar.html b/chrome/browser/resources/print_preview/ui/sidebar.html
index 89634bae..24c24911 100644
--- a/chrome/browser/resources/print_preview/ui/sidebar.html
+++ b/chrome/browser/resources/print_preview/ui/sidebar.html
@@ -48,7 +48,7 @@
       disabled="[[controlsDisabled_]]"
       available class="settings-section">
   </print-preview-destination-settings>
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
   <print-preview-pin-settings state="[[state]]" settings="[[settings]]"
       disabled="[[controlsDisabled_]]"
       hidden$="[[!settings.pin.available]]" class="settings-section">
@@ -121,7 +121,7 @@
         hidden$="[[!settings.vendorItems.available]]"
         class="settings-section">
     </print-preview-advanced-options-settings>
-<if expr="not chromeos_ash and not chromeos_lacros">
+<if expr="not is_chromeos">
     <print-preview-link-container destination="[[destination]]"
         app-kiosk-mode="[[isInAppKioskMode_]]"
         disabled="[[controlsDisabled_]]">
diff --git a/chrome/browser/resources/print_preview/ui/sidebar.ts b/chrome/browser/resources/print_preview/ui/sidebar.ts
index 17ceb06..547f665 100644
--- a/chrome/browser/resources/print_preview/ui/sidebar.ts
+++ b/chrome/browser/resources/print_preview/ui/sidebar.ts
@@ -20,13 +20,13 @@
 import './other_options_settings.js';
 import './pages_per_sheet_settings.js';
 import './pages_settings.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import './pin_settings.js';
 // </if>
 import './print_preview_vars.css.js';
 import './scaling_settings.js';
 import '../strings.m.js';
-// <if expr="not chromeos_ash and not chromeos_lacros">
+// <if expr="not is_chromeos">
 import './link_container.js';
 
 // </if>
@@ -246,7 +246,7 @@
     }
   }
 
-  // <if expr="not chromeos_ash and not chromeos_lacros">
+  // <if expr="not is_chromeos">
   /** @return Whether the system dialog link is available. */
   systemDialogLinkAvailable(): boolean {
     const linkContainer =
diff --git a/chrome/browser/resources/sandbox_internals/sandbox_internals.ts b/chrome/browser/resources/sandbox_internals/sandbox_internals.ts
index f146849..0c36dc3 100644
--- a/chrome/browser/resources/sandbox_internals/sandbox_internals.ts
+++ b/chrome/browser/resources/sandbox_internals/sandbox_internals.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// <if expr="is_linux or chromeos_ash or chromeos_lacros">
+// <if expr="is_linux or is_chromeos">
 import './strings.m.js';
 
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
@@ -121,7 +121,7 @@
 }
 // </if>
 
-// <if expr="is_linux or chromeos_ash or chromeos_lacros">
+// <if expr="is_linux or is_chromeos">
 
 /**
  * Adds a status row that reports either Yes or No.
@@ -182,7 +182,7 @@
   // <if expr="is_android">
   androidHandler();
   // </if>
-  // <if expr="is_linux or chromeos_ash or chromeos_lacros">
+  // <if expr="is_linux or is_chromeos">
   linuxHandler();
   // </if>
 });
diff --git a/chrome/browser/resources/settings/about_page/about_page.ts b/chrome/browser/resources/settings/about_page/about_page.ts
index 407b1be..fe82f559 100644
--- a/chrome/browser/resources/settings/about_page/about_page.ts
+++ b/chrome/browser/resources/settings/about_page/about_page.ts
@@ -16,7 +16,7 @@
 import '../settings_page_styles.css.js';
 import '../settings_shared.css.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
diff --git a/chrome/browser/resources/settings/autofill_page/autofill_section.ts b/chrome/browser/resources/settings/autofill_page/autofill_section.ts
index 399e3f8..19a24e1e 100644
--- a/chrome/browser/resources/settings/autofill_page/autofill_section.ts
+++ b/chrome/browser/resources/settings/autofill_page/autofill_section.ts
@@ -9,7 +9,7 @@
 
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
 import '../settings_shared.css.js';
diff --git a/chrome/browser/resources/settings/autofill_page/credit_card_list_entry.ts b/chrome/browser/resources/settings/autofill_page/credit_card_list_entry.ts
index 9fe61bd..0b1d9395 100644
--- a/chrome/browser/resources/settings/autofill_page/credit_card_list_entry.ts
+++ b/chrome/browser/resources/settings/autofill_page/credit_card_list_entry.ts
@@ -7,7 +7,7 @@
  * the settings page.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import '../i18n_setup.js';
 import '../settings_shared.css.js';
diff --git a/chrome/browser/resources/settings/autofill_page/password_check.html b/chrome/browser/resources/settings/autofill_page/password_check.html
index 7cd5db9d..c601d9f1 100644
--- a/chrome/browser/resources/settings/autofill_page/password_check.html
+++ b/chrome/browser/resources/settings/autofill_page/password_check.html
@@ -135,7 +135,7 @@
               clicked-change-password=
               "[[clickedChangePassword_(item, clickedChangePasswordIds_.size)]]"
               on-change-password-clicked="onChangePasswordClick_"
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
               token-request-manager="[[tokenRequestManager]]"
 </if>
               on-already-changed-password-click="onAlreadyChangedClick_">
@@ -165,7 +165,7 @@
                   clicked-change-password="[[clickedChangePassword_(item,
                                              clickedChangePasswordIds_.size)]]"
                   on-change-password-clicked="onChangePasswordClick_"
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
                   token-request-manager="[[tokenRequestManager]]"
 </if>
                   on-already-changed-password-click="onAlreadyChangedClick_">
@@ -194,7 +194,7 @@
               clicked-change-password=
               "[[clickedChangePassword_(item, clickedChangePasswordIds_.size)]]"
               on-change-password-clicked="onChangePasswordClick_"
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
               token-request-manager="[[tokenRequestManager]]"
 </if>
               on-already-changed-password-click="onAlreadyChangedClick_">
@@ -260,7 +260,7 @@
           on-close="onEditDisclaimerClosed_">
       </settings-password-edit-disclaimer-dialog>
     </template>
-    <if expr="chromeos_ash or chromeos_lacros">
+    <if expr="is_chromeos">
       <template is="dom-if" if="[[showPasswordPromptDialog_]]" restamp>
         <settings-password-prompt-dialog on-token-obtained="onTokenObtained_"
             on-close="onPasswordPromptClosed_">
diff --git a/chrome/browser/resources/settings/autofill_page/password_check.ts b/chrome/browser/resources/settings/autofill_page/password_check.ts
index b0bb261..5016640a 100644
--- a/chrome/browser/resources/settings/autofill_page/password_check.ts
+++ b/chrome/browser/resources/settings/autofill_page/password_check.ts
@@ -17,7 +17,7 @@
 import './password_check_edit_disclaimer_dialog.js';
 import './password_check_list_item.js';
 import './password_remove_confirmation_dialog.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import '../controls/password_prompt_dialog.js';
 
 // </if>
@@ -27,13 +27,13 @@
 import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js';
 import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js';
 import {I18nMixin, I18nMixinInterface} from 'chrome://resources/js/i18n_mixin.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {getDeepActiveElement} from 'chrome://resources/js/util.m.js';
 // </if>
 import {WebUIListenerMixin, WebUIListenerMixinInterface} from 'chrome://resources/js/web_ui_listener_mixin.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {loadTimeData} from '../i18n_setup.js';
 // </if>
 
@@ -41,7 +41,7 @@
 import {routes} from '../route.js';
 import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js';
 
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {BlockingRequestManager} from './blocking_request_manager.js';
 // </if>
 import {MergePasswordsStoreCopiesMixin, MergePasswordsStoreCopiesMixinInterface} from './merge_passwords_store_copies_mixin.js';
@@ -175,7 +175,7 @@
         value: new Set(),
       },
 
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       showPasswordPromptDialog_: Boolean,
       // </if>
     };
@@ -198,7 +198,7 @@
   private iconHaloClass_: string;
   private clickedChangePasswordIds_: Set<number>;
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   private showPasswordPromptDialog_: boolean;
   // </if>
 
@@ -235,7 +235,7 @@
   override connectedCallback() {
     super.connectedCallback();
 
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     // If the user's account supports the password check, an auth token will be
     // required in order for them to view or export passwords. Otherwise there
     // is no additional security so |tokenRequestManager_| will immediately
@@ -797,7 +797,7 @@
     return this.clickedChangePasswordIds_.has(item.id);
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   /**
    * Copied from passwords_section.js.
    * TODO(crbug.com/1074228): Extract to a separate behavior
diff --git a/chrome/browser/resources/settings/autofill_page/password_check_list_item.ts b/chrome/browser/resources/settings/autofill_page/password_check_list_item.ts
index 1951ffbc..c1df863d 100644
--- a/chrome/browser/resources/settings/autofill_page/password_check_list_item.ts
+++ b/chrome/browser/resources/settings/autofill_page/password_check_list_item.ts
@@ -7,14 +7,14 @@
  * list of insecure passwords.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/js/action_link.js';
 import '../settings_shared.css.js';
 import '../site_favicon.js';
 import './passwords_shared.css.js';
 
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
diff --git a/chrome/browser/resources/settings/autofill_page/password_edit_dialog.ts b/chrome/browser/resources/settings/autofill_page/password_edit_dialog.ts
index 362d01e..eaa303dc 100644
--- a/chrome/browser/resources/settings/autofill_page/password_edit_dialog.ts
+++ b/chrome/browser/resources/settings/autofill_page/password_edit_dialog.ts
@@ -9,7 +9,7 @@
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
diff --git a/chrome/browser/resources/settings/autofill_page/password_list_item.ts b/chrome/browser/resources/settings/autofill_page/password_list_item.ts
index 369f7abd3..7f1ee55 100644
--- a/chrome/browser/resources/settings/autofill_page/password_list_item.ts
+++ b/chrome/browser/resources/settings/autofill_page/password_list_item.ts
@@ -9,7 +9,7 @@
  * Clicking the button fires a password-more-actions-clicked event.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import '../settings_shared.css.js';
 import '../site_favicon.js';
diff --git a/chrome/browser/resources/settings/autofill_page/password_requestor_mixin.ts b/chrome/browser/resources/settings/autofill_page/password_requestor_mixin.ts
index 5dd0b28f..0d47a152 100644
--- a/chrome/browser/resources/settings/autofill_page/password_requestor_mixin.ts
+++ b/chrome/browser/resources/settings/autofill_page/password_requestor_mixin.ts
@@ -4,7 +4,7 @@
 
 import {dedupingMixin, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {BlockingRequestManager} from './blocking_request_manager.js';
 // </if>
 import {PasswordManagerImpl} from './password_manager_proxy.js';
@@ -15,7 +15,7 @@
     <T extends Constructor<PolymerElement>>(superClass: T): T&
     Constructor<PasswordRequestorMixinInterface> => {
       class PasswordRequestorMixin extends superClass {
-        // <if expr="chromeos_ash or chromeos_lacros">
+        // <if expr="is_chromeos">
         static get properties() {
           return {tokenRequestManager: Object};
         }
@@ -26,7 +26,7 @@
         requestPlaintextPassword(
             id: number,
             reason: chrome.passwordsPrivate.PlaintextReason): Promise<string> {
-          // <if expr="chromeos_ash or chromeos_lacros">
+          // <if expr="is_chromeos">
           // If no password was found, refresh auth token and retry.
           return new Promise(resolve => {
             PasswordManagerImpl.getInstance()
@@ -52,7 +52,7 @@
   requestPlaintextPassword(
       id: number,
       reason: chrome.passwordsPrivate.PlaintextReason): Promise<string>;
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   tokenRequestManager: BlockingRequestManager;
   // </if>
 }
diff --git a/chrome/browser/resources/settings/autofill_page/password_view.html b/chrome/browser/resources/settings/autofill_page/password_view.html
index e425e6c..fca20f62 100644
--- a/chrome/browser/resources/settings/autofill_page/password_view.html
+++ b/chrome/browser/resources/settings/autofill_page/password_view.html
@@ -99,7 +99,7 @@
     </cr-button>
   </div>
 </template>
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
   <template is="dom-if" if="[[showPasswordPromptDialog_]]" restamp>
     <settings-password-prompt-dialog on-token-obtained="onTokenObtained_"
         on-close="onPasswordPromptClose_">
diff --git a/chrome/browser/resources/settings/autofill_page/password_view.ts b/chrome/browser/resources/settings/autofill_page/password_view.ts
index f753fda..6c3bb70 100644
--- a/chrome/browser/resources/settings/autofill_page/password_view.ts
+++ b/chrome/browser/resources/settings/autofill_page/password_view.ts
@@ -8,11 +8,11 @@
  */
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
 import '../controls/settings_textarea.js';
 import '../i18n_setup.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import '../controls/password_prompt_dialog.js';
 // </if>
 import '../settings_shared.css.js';
@@ -31,7 +31,7 @@
 import {routes} from '../route.js';
 import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js';
 
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {BlockingRequestManager} from './blocking_request_manager.js';
 // </if>
 import {MergePasswordsStoreCopiesMixin, MergePasswordsStoreCopiesMixinInterface} from './merge_passwords_store_copies_mixin.js';
@@ -142,7 +142,7 @@
         value: false,
       },
 
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       showPasswordPromptDialog_: Boolean,
       // </if>
 
@@ -171,12 +171,12 @@
   private isPasswordVisible_: boolean;
   private password_: string;
   private recentlyEdited_: boolean;
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   private showPasswordPromptDialog_: boolean;
   // </if>
   private showEditDialog_: boolean;
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   override connectedCallback() {
     super.connectedCallback();
 
@@ -328,7 +328,7 @@
     Router.getInstance().updateRouteParams(newParams);
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   /**
    * When this event fired, it means that the password-prompt-dialog succeeded
    * in creating a fresh token in the quickUnlockPrivate API. Because new tokens
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_export_dialog.ts b/chrome/browser/resources/settings/autofill_page/passwords_export_dialog.ts
index 6512b2d..e4b64cc 100644
--- a/chrome/browser/resources/settings/autofill_page/passwords_export_dialog.ts
+++ b/chrome/browser/resources/settings/autofill_page/passwords_export_dialog.ts
@@ -17,7 +17,7 @@
 import {I18nMixin} from 'chrome://resources/js/i18n_mixin.js';
 import {microTask, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {BlockingRequestManager} from './blocking_request_manager.js';
 // </if>
 import {PasswordManagerImpl, PasswordManagerProxy, PasswordsFileExportProgressListener} from './password_manager_proxy.js';
@@ -68,7 +68,7 @@
       showProgressDialog_: Boolean,
       showErrorDialog_: Boolean,
 
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       tokenRequestManager: Object,
       // </if>
     };
@@ -86,7 +86,7 @@
   private delayedCompletionToken_: number|null;
   private delayedProgress_: chrome.passwordsPrivate.PasswordExportProgress|null;
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   tokenRequestManager: BlockingRequestManager;
   // </if>
 
@@ -206,10 +206,10 @@
   }
 
   private onExportTap_() {
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     this.tokenRequestManager.request(() => this.exportPasswords_());
     // </if>
-    // <if expr="not (chromeos_ash or chromeos_lacros)">
+    // <if expr="not is_chromeos">
     this.exportPasswords_();
     // </if>
   }
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.html b/chrome/browser/resources/settings/autofill_page/passwords_section.html
index 7214159..973fe13 100644
--- a/chrome/browser/resources/settings/autofill_page/passwords_section.html
+++ b/chrome/browser/resources/settings/autofill_page/passwords_section.html
@@ -201,7 +201,7 @@
     </div>
 
     <passwords-list-handler id="passwordsListHandler"
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
         token-request-manager="[[tokenRequestManager]]"
 </if>
         is-account-store-user="[[isAccountStoreUser]]"
@@ -265,7 +265,7 @@
                 items="[[savedPasswords]]" filter="[[passwordFilter_(filter)]]"
                 rendered-item-count="{{shownPasswordsCount_::dom-change}}">
               <password-list-item entry="[[item]]"
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
                   token-request-manager="[[tokenRequestManager]]"
 </if>
               >
@@ -295,7 +295,7 @@
       <password-edit-dialog on-close="onAddPasswordDialogClosed_"
           id="addPasswordDialog" account-email="[[profileEmail]]"
           saved-passwords="[[savedPasswords]]"
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
           token-request-manager="[[tokenRequestManager]]"
 </if>
           is-account-store-user="[[isAccountStoreUser]]">
@@ -303,7 +303,7 @@
     </template>
     <template is="dom-if" if="[[showPasswordsExportDialog_]]" restamp>
       <passwords-export-dialog
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
         token-request-manager="[[tokenRequestManager]]"
 </if>
         on-passwords-export-dialog-close="onPasswordsExportDialogClosed_">
@@ -314,7 +314,7 @@
           on-close="onPasswordsImportDialogClosed_">
       </passwords-import-dialog>
     </template>
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
     <template is="dom-if" if="[[showPasswordPromptDialog_]]" restamp>
       <settings-password-prompt-dialog on-token-obtained="onTokenObtained_"
           on-close="onPasswordPromptClosed_">
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.ts b/chrome/browser/resources/settings/autofill_page/passwords_section.ts
index db1dc5ba..c715479 100644
--- a/chrome/browser/resources/settings/autofill_page/passwords_section.ts
+++ b/chrome/browser/resources/settings/autofill_page/passwords_section.ts
@@ -10,14 +10,14 @@
 
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
 import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
 import '../controls/extension_controlled_indicator.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import '../controls/password_prompt_dialog.js';
 // </if>
 import '../controls/settings_toggle_button.js';
@@ -51,7 +51,7 @@
 import {routes} from '../route.js';
 import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js';
 
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {BlockingRequestManager} from './blocking_request_manager.js';
 // </if>
 import {MergePasswordsStoreCopiesMixin, MergePasswordsStoreCopiesMixinInterface} from './merge_passwords_store_copies_mixin.js';
@@ -269,7 +269,7 @@
         value: () => [],
       },
 
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       showPasswordPromptDialog_: Boolean,
       // </if>
 
@@ -309,7 +309,7 @@
   private hidePasswordsLink_: boolean;
   private showImportPasswords_: boolean;
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   private showPasswordPromptDialog_: boolean;
   // </if>
 
@@ -371,7 +371,7 @@
       this.passwordExceptions = exceptionList;
     };
 
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     // If the user's account supports the password check, an auth token will be
     // required in order for them to view or export passwords. Otherwise there
     // is no additional security so |tokenRequestManager| will immediately
@@ -523,7 +523,7 @@
     return this.passwordManager_;
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   /**
    * When this event fired, it means that the password-prompt-dialog succeeded
    * in creating a fresh token in the quickUnlockPrivate API. Because new tokens
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_shared.css b/chrome/browser/resources/settings/autofill_page/passwords_shared.css
index 2348af9..132f15f7 100644
--- a/chrome/browser/resources/settings/autofill_page/passwords_shared.css
+++ b/chrome/browser/resources/settings/autofill_page/passwords_shared.css
@@ -90,7 +90,7 @@
    * necessary to prevent Chrome from using the operating system's font
    * instead of the Material Design font.
    * TODO(dbeam): why not font: inherit? */
-<if expr="is_linux or chromeos_ash or chromeos_lacros">
+<if expr="is_linux or is_chromeos">
   font-family: 'DejaVu Sans Mono', monospace;
 </if>
 <if expr="is_win">
diff --git a/chrome/browser/resources/settings/autofill_page/upi_id_list_entry.ts b/chrome/browser/resources/settings/autofill_page/upi_id_list_entry.ts
index 016f037..46612651 100644
--- a/chrome/browser/resources/settings/autofill_page/upi_id_list_entry.ts
+++ b/chrome/browser/resources/settings/autofill_page/upi_id_list_entry.ts
@@ -7,7 +7,7 @@
  * the settings page. https://en.wikipedia.org/wiki/Unified_Payments_Interface
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import '../i18n_setup.js';
 import '../settings_shared.css.js';
diff --git a/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_item.js b/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_item.js
index 5c6ca9d..fb996ec8 100644
--- a/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_item.js
+++ b/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_item.js
@@ -9,7 +9,7 @@
 
 import 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button_style_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import '../../settings_shared.css.js';
diff --git a/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_device_list_item.js b/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_device_list_item.js
index a77d83d9..420a536 100644
--- a/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_device_list_item.js
+++ b/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_device_list_item.js
@@ -7,7 +7,7 @@
  */
 
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import '../os_icons.js';
diff --git a/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_page.js b/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_page.js
index d60e44f..f93f3cb7 100644
--- a/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_page.js
+++ b/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_page.js
@@ -8,7 +8,7 @@
  * just provodes a summary and link to the subpage.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/policy/cr_policy_pref_indicator.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn
index 92a80363..3b9c18d 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/BUILD.gn
@@ -139,7 +139,7 @@
     "../guest_os:guest_os_shared_paths",
     "../guest_os:guest_os_shared_usb_devices",
     "//ui/webui/resources/cr_elements/cr_button:cr_button.m",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
     "//ui/webui/resources/cr_elements/policy:cr_policy_indicator.m",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
@@ -155,7 +155,7 @@
     "../guest_os:guest_os_browser_proxy",
     "../guest_os:guest_os_container_select",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
@@ -190,7 +190,7 @@
     "..:prefs_behavior",
     "../guest_os:guest_os_browser_proxy",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_extra_containers.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_extra_containers.js
index 796b77e..e0d1eb3 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_extra_containers.js
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_extra_containers.js
@@ -9,7 +9,7 @@
  */
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import './crostini_extra_containers_create_dialog.js';
 import '../../settings_shared.css.js';
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.js
index 08112a3..af3c72e 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.js
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_page.js
@@ -10,7 +10,7 @@
  */
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/policy/cr_policy_indicator.m.js';
 import '../../settings_page/settings_animated_pages.js';
 import '../../settings_page/settings_subpage.js';
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.js b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.js
index e19a4b0e..6bf4bb05 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.js
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.js
@@ -9,7 +9,7 @@
  */
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import './crostini_port_forwarding_add_port_dialog.js';
diff --git a/chrome/browser/resources/settings/chromeos/device_page/storage.js b/chrome/browser/resources/settings/chromeos/device_page/storage.js
index d9e8fd7..fbbc4960 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/storage.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/storage.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/guest_os/BUILD.gn b/chrome/browser/resources/settings/chromeos/guest_os/BUILD.gn
index e4973b9..eadbde6 100644
--- a/chrome/browser/resources/settings/chromeos/guest_os/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/guest_os/BUILD.gn
@@ -48,7 +48,7 @@
     ":guest_os_browser_proxy",
     "..:metrics_recorder",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
 }
diff --git a/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_paths.js b/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_paths.js
index a166c369..fd933f7 100644
--- a/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_paths.js
+++ b/chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_paths.js
@@ -7,7 +7,7 @@
  * 'guest-os-shared-paths' is the settings shared paths subpage for guest OSes.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
 import '../../settings_shared.css.js';
 
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
index 16adbac7..5d1d939 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
@@ -71,7 +71,7 @@
     "//ui/webui/resources/cr_components/chromeos/cellular_setup:esim_manager_listener_behavior.m",
     "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider.m",
     "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
@@ -115,7 +115,6 @@
     "//ui/webui/resources/cr_components/chromeos/network_health:network_health_container",
     "//ui/webui/resources/cr_components/chromeos/traffic_counters:traffic_counters",
     "//ui/webui/resources/cr_elements/cr_button:cr_button.m",
-    "//ui/webui/resources/cr_elements/cr_expand_button:cr_expand_button",
     "//ui/webui/resources/cr_elements/cr_toggle:cr_toggle.m",
     "//ui/webui/resources/cr_elements/policy:cr_policy_indicator.m",
     "//ui/webui/resources/js:assert.m",
@@ -138,7 +137,7 @@
     "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider.m",
     "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior.m",
     "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
@@ -173,8 +172,7 @@
     "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior.m",
     "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
     "//ui/webui/resources/cr_components/chromeos/network:sim_lock_dialogs.m",
-    "//ui/webui/resources/cr_elements/cr_expand_button:cr_expand_button",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
     "//ui/webui/resources/cr_elements/policy:cr_policy_indicator.m",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
@@ -215,7 +213,7 @@
     "//ui/webui/resources/cr_components/chromeos/network:network_list.m",
     "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior.m",
     "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
     "//ui/webui/resources/cr_elements/cr_toggle:cr_toggle.m",
     "//ui/webui/resources/cr_elements/policy:cr_policy_indicator.m",
     "//ui/webui/resources/js:i18n_behavior.m",
@@ -271,7 +269,7 @@
     "//ui/webui/resources/cr_components/chromeos/network:network_siminfo.m",
     "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
     "//ui/webui/resources/cr_components/chromeos/traffic_counters:traffic_counters",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
     "//ui/webui/resources/cr_elements/cr_toggle:cr_toggle.m",
     "//ui/webui/resources/cr_elements/policy:cr_policy_indicator_behavior.m",
     "//ui/webui/resources/js:assert.m",
@@ -305,7 +303,7 @@
     "//ui/webui/resources/cr_components/chromeos/cellular_setup:esim_manager_utils.m",
     "//ui/webui/resources/cr_components/chromeos/network:cellular_utils.m",
     "//ui/webui/resources/cr_components/chromeos/network:network_list_types.m",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.js b/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.js
index de3b4de..a43b907 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.js
@@ -8,7 +8,7 @@
  */
 
 import 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_eid_dialog.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
 import 'chrome://resources/cr_elements/policy/cr_policy_indicator.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_menu.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_menu.js
index d9db214..0df2b61 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_menu.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_menu.js
@@ -7,7 +7,7 @@
  * additional actions for a network in the network detail page.
  */
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import '../../settings_shared.css.js';
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.js
index 2646363..9f72d47 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.js
@@ -8,7 +8,7 @@
  * known networks for a type (currently always WiFi).
  */
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import '../../settings_shared.css.js';
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_page.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_page.js
index ac97915..a5d0dc2 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_page.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_page.js
@@ -11,7 +11,7 @@
 import 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_setup_icons.m.js';
 import 'chrome://resources/cr_components/chromeos/network/sim_lock_dialogs.m.js';
 import 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/policy/cr_policy_indicator.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.js
index 1da7166..7c2bff03 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.js
@@ -8,7 +8,7 @@
  */
 
 import 'chrome://resources/cr_components/chromeos/network/network_list.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js';
 import 'chrome://resources/cr_elements/policy/cr_policy_indicator.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.js b/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.js
index 8ebc555..9531a1f 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.js
@@ -11,7 +11,7 @@
 
 import 'chrome://resources/cr_components/chromeos/network/network_icon.m.js';
 import 'chrome://resources/cr_components/chromeos/network/network_siminfo.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
diff --git a/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_accounts.js b/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_accounts.js
index b4284a0..9320102 100644
--- a/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_accounts.js
+++ b/chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_accounts.js
@@ -10,7 +10,7 @@
 
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
 import 'chrome://resources/cr_elements/policy/cr_policy_indicator.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.js
index e702320..6de0fc9 100644
--- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.js
+++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.js
@@ -11,7 +11,7 @@
  * feature's autonomous page if there is one.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import '../../settings_shared.css.js';
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js
index 50109fe..dd578d79 100644
--- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js
+++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import '../../controls/password_prompt_dialog.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn
index fd9e97fa..7ed5d4e 100644
--- a/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn
@@ -269,7 +269,6 @@
     "//chrome/browser/resources/settings/chromeos/os_languages_page:languages_browser_proxy",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_elements/cr_button:cr_button.m",
-    "//ui/webui/resources/cr_elements/cr_expand_button:cr_expand_button",
     "//ui/webui/resources/cr_elements/cr_input:cr_input.m",
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/audio_and_captions_page.js b/chrome/browser/resources/settings/chromeos/os_a11y_page/audio_and_captions_page.js
index f6d5d76f..e93d0e1 100644
--- a/chrome/browser/resources/settings/chromeos/os_a11y_page/audio_and_captions_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/audio_and_captions_page.js
@@ -8,7 +8,7 @@
  * audio and captions accessibility settings.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/cursor_and_touchpad_page.js b/chrome/browser/resources/settings/chromeos/os_a11y_page/cursor_and_touchpad_page.js
index a5b892f7..8a523cd 100644
--- a/chrome/browser/resources/settings/chromeos/os_a11y_page/cursor_and_touchpad_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/cursor_and_touchpad_page.js
@@ -8,7 +8,7 @@
  * for cursor and touchpad accessibility settings.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.js b/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.js
index 34020f34..a251c740 100644
--- a/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/display_and_magnification_page.js
@@ -8,7 +8,7 @@
  * subpage for display and magnification accessibility settings.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/keyboard_and_text_input_page.js b/chrome/browser/resources/settings/chromeos/os_a11y_page/keyboard_and_text_input_page.js
index 9a994349..9724a618 100644
--- a/chrome/browser/resources/settings/chromeos/os_a11y_page/keyboard_and_text_input_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/keyboard_and_text_input_page.js
@@ -8,7 +8,7 @@
  * for keyboard and text input accessibility settings.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.js b/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.js
index a39bead..3297c8a 100644
--- a/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/manage_a11y_page.js
@@ -8,7 +8,7 @@
  * settings.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.js b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.js
index 90583615..6fb524d2 100644
--- a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.js
@@ -20,7 +20,7 @@
 import './detailed_build_info.js';
 import './update_warning_dialog.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/main_view.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/main_view.js
index 938c64c..196f87bf 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/main_view.js
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/main_view.js
@@ -4,7 +4,7 @@
 
 import './app_item.js';
 import './shared_style.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 
 import {alphabeticalSort} from 'chrome://resources/cr_components/app_management/util.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js
index 0c2a466..e74cad779 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js
@@ -6,7 +6,7 @@
 import 'chrome://resources/cr_components/app_management/icons.html.js';
 import 'chrome://resources/cr_components/app_management/permission_item.js';
 import '../shared_style.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 
 import {getSelectedApp} from 'chrome://resources/cr_components/app_management/util.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.js b/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.js
index e5e4abb..1926680 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/os_apps_page.js
@@ -8,7 +8,7 @@
  *
  */
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/policy/cr_policy_pref_indicator.m.js';
 import '../../settings_page/settings_animated_pages.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_device_detail_subpage.js b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_device_detail_subpage.js
index 7c68aa6..ba1f759 100644
--- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_device_detail_subpage.js
+++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_device_detail_subpage.js
@@ -9,7 +9,7 @@
  */
 
 import '../../settings_shared.css.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/policy/cr_tooltip_icon.m.js';
 import './os_bluetooth_change_device_name_dialog.js';
 import './os_bluetooth_true_wireless_images.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_page.js b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_page.js
index e24bb7b..9bed25b 100644
--- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_page.js
@@ -9,7 +9,7 @@
  */
 
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import '../../settings_shared.css.js';
 import '../../settings_page/settings_animated_pages.js';
 import './os_bluetooth_devices_subpage.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_summary.js b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_summary.js
index 33577c4..ad5c8cb 100644
--- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_summary.js
+++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_summary.js
@@ -9,7 +9,7 @@
  */
 
 import '../../settings_shared.css.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 
 import {getDeviceName} from 'chrome://resources/cr_components/chromeos/bluetooth/bluetooth_utils.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_paired_bluetooth_list_item.js b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_paired_bluetooth_list_item.js
index fe0fe970..632c8297 100644
--- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_paired_bluetooth_list_item.js
+++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_paired_bluetooth_list_item.js
@@ -9,7 +9,7 @@
  */
 
 import '../../settings_shared.css.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import 'chrome://resources/cr_components/chromeos/bluetooth/bluetooth_icon.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_saved_devices_list_item.js b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_saved_devices_list_item.js
index e7d3b3f..63554c42 100644
--- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_saved_devices_list_item.js
+++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_saved_devices_list_item.js
@@ -10,7 +10,7 @@
 
 import '../../settings_shared.css.js';
 import '../os_icons.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 
 import {FastPairSavedDevicesUiEvent, recordSavedDevicesUiEventMetrics} from 'chrome://resources/cr_components/chromeos/bluetooth/bluetooth_metrics_utils.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
index 0d1319b..eda15f44 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
@@ -202,7 +202,6 @@
     "..:route_observer_behavior",
     "../..:router",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_expand_button:cr_expand_button",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:cr.m",
     "//ui/webui/resources/js/cr/ui:focus_without_ink.m",
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js
index 0d97292..54b958b 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js
@@ -9,7 +9,7 @@
 
 import 'chrome://resources/cr_components/localized_link/localized_link.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import './add_input_methods_dialog.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/os_edit_dictionary_page.js b/chrome/browser/resources/settings/chromeos/os_languages_page/os_edit_dictionary_page.js
index 5f51de8a..6cbfea3 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/os_edit_dictionary_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/os_edit_dictionary_page.js
@@ -8,7 +8,7 @@
  */
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/polymer/v3_0/iron-a11y-keys/iron-a11y-keys.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.js b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.js
index ec9befa2..2f4942b 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.js
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.js
@@ -8,7 +8,7 @@
  */
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/js/action_link.js';
 import 'chrome://resources/cr_elements/action_link_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.js b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.js
index 4217fe2..d2d79279 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.js
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.js
@@ -8,7 +8,7 @@
  * languages.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import './input_page.js';
 import './os_languages_page_v2.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.js b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.js
index 2c0b9a08..8bc78340 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.js
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/account_manager.js
@@ -11,7 +11,7 @@
 import 'chrome://resources/cr_components/localized_link/localized_link.js';
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/policy/cr_policy_indicator.m.js';
 import 'chrome://resources/cr_elements/policy/cr_tooltip_icon.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_list.js b/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_list.js
index 3f0f82f..5eee436 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_list.js
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/fingerprint_list.js
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/policy/cr_tooltip_icon.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.js b/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.js
index c68600c..b362cb1 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.js
@@ -6,7 +6,7 @@
  * @fileoverview
  * 'settings-people-page' is the settings page containing sign-in settings.
  */
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/policy/cr_policy_indicator.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/user_list.js b/chrome/browser/resources/settings/chromeos/os_people_page/user_list.js
index 3251ce1a..c3bd87f 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/user_list.js
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/user_list.js
@@ -13,7 +13,7 @@
  *    </settings-user-list>
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.js b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.js
index 1c999fb..a8fc703 100644
--- a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.js
+++ b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.js
@@ -11,7 +11,7 @@
 
 // TODO(xdai): Rename it to 'settings-cups-printers-page'.
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
 import 'chrome://resources/cr_elements/policy/cr_policy_pref_indicator.m.js';
 import 'chrome://resources/js/action_link.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_toolbar/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_toolbar/BUILD.gn
index c6dd67c46..9b8ca80 100644
--- a/chrome/browser/resources/settings/chromeos/os_toolbar/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_toolbar/BUILD.gn
@@ -16,7 +16,7 @@
   deps = [
     "../os_settings_search_box:os_settings_search_box",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
     "//ui/webui/resources/js:load_time_data.m",
   ]
   externs_list = [ "//ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field_externs.js" ]
diff --git a/chrome/browser/resources/settings/chromeos/os_toolbar/os_toolbar.js b/chrome/browser/resources/settings/chromeos/os_toolbar/os_toolbar.js
index 0afc2d1..3997681 100644
--- a/chrome/browser/resources/settings/chromeos/os_toolbar/os_toolbar.js
+++ b/chrome/browser/resources/settings/chromeos/os_toolbar/os_toolbar.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
 import 'chrome://resources/cr_elements/icons.m.js';
diff --git a/chrome/browser/resources/settings/languages_page/edit_dictionary_page.ts b/chrome/browser/resources/settings/languages_page/edit_dictionary_page.ts
index 77cb79ed..a48427e4 100644
--- a/chrome/browser/resources/settings/languages_page/edit_dictionary_page.ts
+++ b/chrome/browser/resources/settings/languages_page/edit_dictionary_page.ts
@@ -8,7 +8,7 @@
  */
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/polymer/v3_0/iron-a11y-keys/iron-a11y-keys.js';
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.ts b/chrome/browser/resources/settings/languages_page/languages_page.ts
index 03f38bf..1a669b4 100644
--- a/chrome/browser/resources/settings/languages_page/languages_page.ts
+++ b/chrome/browser/resources/settings/languages_page/languages_page.ts
@@ -12,7 +12,7 @@
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
diff --git a/chrome/browser/resources/settings/languages_page/translate_page.ts b/chrome/browser/resources/settings/languages_page/translate_page.ts
index 424fba0f..cf5a890 100644
--- a/chrome/browser/resources/settings/languages_page/translate_page.ts
+++ b/chrome/browser/resources/settings/languages_page/translate_page.ts
@@ -8,7 +8,7 @@
  */
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
diff --git a/chrome/browser/resources/settings/lazy_load.ts b/chrome/browser/resources/settings/lazy_load.ts
index c4887ec..dbf95b8 100644
--- a/chrome/browser/resources/settings/lazy_load.ts
+++ b/chrome/browser/resources/settings/lazy_load.ts
@@ -71,7 +71,7 @@
 
 export {CrCheckboxElement} from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
 export {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
-export {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+export {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 export {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 export {CrSliderElement} from 'chrome://resources/cr_elements/cr_slider/cr_slider.js';
 export {getToastManager} from 'chrome://resources/cr_elements/cr_toast/cr_toast_manager.js';
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_url_entry.ts b/chrome/browser/resources/settings/on_startup_page/startup_url_entry.ts
index 45baa48..e6ed7e7 100644
--- a/chrome/browser/resources/settings/on_startup_page/startup_url_entry.ts
+++ b/chrome/browser/resources/settings/on_startup_page/startup_url_entry.ts
@@ -9,7 +9,7 @@
  */
 
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import '../settings_shared.css.js';
diff --git a/chrome/browser/resources/settings/people_page/people_page.ts b/chrome/browser/resources/settings/people_page/people_page.ts
index 90049a90..83a4294 100644
--- a/chrome/browser/resources/settings/people_page/people_page.ts
+++ b/chrome/browser/resources/settings/people_page/people_page.ts
@@ -7,7 +7,7 @@
  * 'settings-people-page' is the settings page containing sign-in settings.
  */
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
 import 'chrome://resources/cr_elements/icons.m.js';
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.ts b/chrome/browser/resources/settings/people_page/sync_account_control.ts
index 16368e0..fc77700 100644
--- a/chrome/browser/resources/settings/people_page/sync_account_control.ts
+++ b/chrome/browser/resources/settings/people_page/sync_account_control.ts
@@ -8,7 +8,7 @@
  */
 import '//resources/cr_elements/cr_action_menu/cr_action_menu.js';
 import '//resources/cr_elements/cr_button/cr_button.m.js';
-import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '//resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import '//resources/cr_elements/icons.m.js';
 import '//resources/cr_elements/shared_style_css.m.js';
 import '//resources/cr_elements/shared_vars_css.m.js';
diff --git a/chrome/browser/resources/settings/privacy_page/cookies_page.ts b/chrome/browser/resources/settings/privacy_page/cookies_page.ts
index 04f6ffe..2376d68 100644
--- a/chrome/browser/resources/settings/privacy_page/cookies_page.ts
+++ b/chrome/browser/resources/settings/privacy_page/cookies_page.ts
@@ -8,7 +8,7 @@
  * settings.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
 import '../controls/settings_toggle_button.js';
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.html b/chrome/browser/resources/settings/privacy_page/personalization_options.html
index 647cc0f..56fda9d9 100644
--- a/chrome/browser/resources/settings/privacy_page/personalization_options.html
+++ b/chrome/browser/resources/settings/privacy_page/personalization_options.html
@@ -13,7 +13,7 @@
         padding-inline-start: 0;
       }
     </style>
-<if expr="not chromeos_ash and not chromeos_lacros">
+<if expr="not is_chromeos">
     <!-- Signout is not supported yet on lacros, https://crbug.com/1217645 -->
     <settings-toggle-button id="signinAllowedToggle"
         class="hr"
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.ts b/chrome/browser/resources/settings/privacy_page/personalization_options.ts
index 4138f5c..d75928b 100644
--- a/chrome/browser/resources/settings/privacy_page/personalization_options.ts
+++ b/chrome/browser/resources/settings/privacy_page/personalization_options.ts
@@ -99,7 +99,7 @@
         computed: 'computeSyncFirstSetupInProgress_(syncStatus)',
       },
 
-      // <if expr="not chromeos_ash and not chromeos_lacros">
+      // <if expr="not is_chromeos">
       signinAvailable_: {
         type: Boolean,
         value: () => loadTimeData.getBoolean('signinAvailable'),
@@ -126,7 +126,7 @@
   private showSignoutDialog_: boolean;
   private syncFirstSetupInProgress_: boolean;
 
-  // <if expr="not chromeos_ash and not chromeos_lacros">
+  // <if expr="not is_chromeos">
   private signinAvailable_: boolean;
   // </if>
 
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_dialog.ts b/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_dialog.ts
index 2943970..ac0e7c1 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_dialog.ts
+++ b/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_dialog.ts
@@ -7,7 +7,7 @@
  * 'settings-rivacy-guide-dialog' is a settings dialog that helps users guide
  * various privacy settings.
  */
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import '../../prefs/prefs.js';
 import '../../settings_shared.css.js';
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html
index 93c6034..bc7b142 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_page.html
+++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -754,7 +754,7 @@
 <if expr="not chromeos_ash and not chromeos_lacros and not is_win">
         <settings-subpage page-title="$i18n{siteSettingsProtectedContent}">
 </if>
-<if expr="chromeos_ash or chromeos_lacros or is_win">
+<if expr="is_chromeos or is_win">
         <settings-subpage page-title="$i18n{siteSettingsProtectedContent}"
             search-label="$i18n{siteSettingsAllSitesSearch}"
             search-term="{{searchFilter_}}">
@@ -788,7 +788,7 @@
               </settings-collapse-radio-button>
             </settings-radio-group>
           </div>
-<if expr="chromeos_ash or chromeos_lacros or is_win">
+<if expr="is_chromeos or is_win">
           <settings-category-default-radio-group
             header="$i18n{siteSettingsProtectedContentIdentifiers}"
             description=
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.ts b/chrome/browser/resources/settings/privacy_page/privacy_page.ts
index fb54cf7c..e8c738f 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_page.ts
+++ b/chrome/browser/resources/settings/privacy_page/privacy_page.ts
@@ -8,7 +8,7 @@
  * security settings.
  */
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.ts b/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.ts
index 17cb6d1..2687b7a 100644
--- a/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.ts
+++ b/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.ts
@@ -12,7 +12,7 @@
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
 import 'chrome://resources/polymer/v3_0/iron-pages/iron-pages.js';
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.ts b/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.ts
index 53bdd224..c223a2e 100644
--- a/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.ts
+++ b/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.ts
@@ -7,7 +7,7 @@
  * dialog for viewing and erasing credentials stored on a security key.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
 import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
@@ -20,7 +20,7 @@
 
 import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js';
 import {I18nMixin} from 'chrome://resources/js/i18n_mixin.js';
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_phones_list.ts b/chrome/browser/resources/settings/privacy_page/security_keys_phones_list.ts
index fb9d43e..0109377 100644
--- a/chrome/browser/resources/settings/privacy_page/security_keys_phones_list.ts
+++ b/chrome/browser/resources/settings/privacy_page/security_keys_phones_list.ts
@@ -7,7 +7,7 @@
     optionally with a drop-down menu for editing or deleting them.
  */
 import '../settings_shared.css.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 
 import {AnchorAlignment} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.ts b/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.ts
index b9bf3f2..e981a07 100644
--- a/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.ts
+++ b/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.ts
@@ -8,7 +8,7 @@
  */
 
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import '../settings_shared.css.js';
 import '../i18n_setup.js';
 
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.ts b/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.ts
index 3b76ba0..b24d6401 100644
--- a/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.ts
+++ b/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.ts
@@ -9,7 +9,7 @@
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/polymer/v3_0/iron-pages/iron-pages.js';
diff --git a/chrome/browser/resources/settings/privacy_page/security_page.html b/chrome/browser/resources/settings/privacy_page/security_page.html
index 31c656e9..a4f7a6f 100644
--- a/chrome/browser/resources/settings/privacy_page/security_page.html
+++ b/chrome/browser/resources/settings/privacy_page/security_page.html
@@ -166,7 +166,7 @@
     <template is="dom-if" if="[[showSecureDnsSetting_]]">
       <settings-secure-dns prefs="{{prefs}}"></settings-secure-dns>
     </template>
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
     <template is="dom-if" if="[[showSecureDnsSettingLink_]]">
         <cr-link-row id="openChromeOSSecureDnsSettings"
             on-click="onOpenChromeOSSecureDnsSettingsClicked_"
diff --git a/chrome/browser/resources/settings/privacy_page/security_page.ts b/chrome/browser/resources/settings/privacy_page/security_page.ts
index b46fca26..e7c2bef 100644
--- a/chrome/browser/resources/settings/privacy_page/security_page.ts
+++ b/chrome/browser/resources/settings/privacy_page/security_page.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import './collapse_radio_button.js';
@@ -24,7 +24,7 @@
 import {FocusConfig} from '../focus_config.js';
 import {loadTimeData} from '../i18n_setup.js';
 import {MetricsBrowserProxy, MetricsBrowserProxyImpl, PrivacyElementInteractions, SafeBrowsingInteractions} from '../metrics_browser_proxy.js';
-// <if expr="chromeos_ash or chromeos_lacros or chrome_root_store_supported">
+// <if expr="is_chromeos or chrome_root_store_supported">
 import {OpenWindowProxyImpl} from '../open_window_proxy.js';
 // </if>
 
@@ -121,7 +121,7 @@
         },
       },
 
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       /**
        * Whether a link to secure DNS OS setting should be displayed.
        */
@@ -177,7 +177,7 @@
   private showHttpsOnlyModeSetting_: boolean;
   private showSecureDnsSetting_: boolean;
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   private showSecureDnsSettingLink_: boolean;
   // </if>
 
@@ -368,7 +368,7 @@
     this.recordActionOnExpandButtonClicked_(SafeBrowsingSetting.STANDARD);
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   private onOpenChromeOSSecureDnsSettingsClicked_() {
     const path =
         loadTimeData.getString('chromeOSPrivacyAndSecuritySectionPath');
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_page.ts b/chrome/browser/resources/settings/safety_check_page/safety_check_page.ts
index 8931bd83..13a749d 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_page.ts
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_page.ts
@@ -9,7 +9,7 @@
  */
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js';
diff --git a/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.ts b/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.ts
index 8b04d3f..06bca31 100644
--- a/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.ts
+++ b/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.ts
@@ -6,7 +6,7 @@
  * @fileoverview 'settings-omnibox-extension-entry' is a component for showing
  * an omnibox extension with its name and keyword.
  */
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import './search_engine_entry.css.js';
 import '../settings_shared.css.js';
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engine_entry.ts b/chrome/browser/resources/settings/search_engines_page/search_engine_entry.ts
index 28cc1c2..b2421620 100644
--- a/chrome/browser/resources/settings/search_engines_page/search_engine_entry.ts
+++ b/chrome/browser/resources/settings/search_engines_page/search_engine_entry.ts
@@ -6,7 +6,7 @@
  * @fileoverview 'settings-search-engine-entry' is a component for showing a
  * search engine with its name, domain and query URL.
  */
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import '../controls/extension_controlled_indicator.js';
 import './search_engine_entry.css.js';
diff --git a/chrome/browser/resources/settings/settings_page/settings_subpage.ts b/chrome/browser/resources/settings/settings_page/settings_subpage.ts
index 965525f9..0de6b68 100644
--- a/chrome/browser/resources/settings/settings_page/settings_subpage.ts
+++ b/chrome/browser/resources/settings/settings_page/settings_subpage.ts
@@ -8,7 +8,7 @@
  * the subpage title, a search field and a back icon.
  */
 
-import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '//resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import '//resources/cr_elements/cr_search_field/cr_search_field.js';
 import '//resources/cr_elements/icons.m.js';
 import '//resources/cr_elements/shared_style_css.m.js';
diff --git a/chrome/browser/resources/settings/site_settings/protocol_handlers.ts b/chrome/browser/resources/settings/site_settings/protocol_handlers.ts
index f6ccbc2..e093fc4 100644
--- a/chrome/browser/resources/settings/site_settings/protocol_handlers.ts
+++ b/chrome/browser/resources/settings/site_settings/protocol_handlers.ts
@@ -9,7 +9,7 @@
  */
 
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_radio_group/cr_radio_group.m.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js';
diff --git a/chrome/browser/resources/settings/site_settings/site_data_details_subpage.ts b/chrome/browser/resources/settings/site_settings/site_data_details_subpage.ts
index a1e36832f..1b26f01 100644
--- a/chrome/browser/resources/settings/site_settings/site_data_details_subpage.ts
+++ b/chrome/browser/resources/settings/site_settings/site_data_details_subpage.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
diff --git a/chrome/browser/resources/settings/site_settings/site_data_entry.ts b/chrome/browser/resources/settings/site_settings/site_data_entry.ts
index b037bde..93f318b 100644
--- a/chrome/browser/resources/settings/site_settings/site_data_entry.ts
+++ b/chrome/browser/resources/settings/site_settings/site_data_entry.ts
@@ -7,7 +7,7 @@
  * 'site-data-entry' handles showing the local storage summary for a site.
  */
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
diff --git a/chrome/browser/resources/settings/site_settings/site_details.html b/chrome/browser/resources/settings/site_settings/site_details.html
index f4688ce..ef14089 100644
--- a/chrome/browser/resources/settings/site_settings/site_details.html
+++ b/chrome/browser/resources/settings/site_settings/site_details.html
@@ -171,7 +171,7 @@
       <site-details-permission category="[[contentSettingsTypesEnum_.HID_DEVICES]]"
           icon="settings:hid-device" label="$i18n{siteSettingsHidDevices}">
       </site-details-permission>
-<if expr="chromeos_ash or chromeos_lacros or is_win">
+<if expr="is_chromeos or is_win">
       <site-details-permission
           category="[[contentSettingsTypesEnum_.PROTECTED_CONTENT]]"
           icon="settings:protected-content"
diff --git a/chrome/browser/resources/settings/site_settings/site_details.ts b/chrome/browser/resources/settings/site_settings/site_details.ts
index 22890df..950f2aa5 100644
--- a/chrome/browser/resources/settings/site_settings/site_details.ts
+++ b/chrome/browser/resources/settings/site_settings/site_details.ts
@@ -11,7 +11,7 @@
 import 'chrome://resources/cr_elements/action_link_css.m.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
diff --git a/chrome/browser/resources/settings/site_settings/site_entry.ts b/chrome/browser/resources/settings/site_settings/site_entry.ts
index 59110a7..bd6378d 100644
--- a/chrome/browser/resources/settings/site_settings/site_entry.ts
+++ b/chrome/browser/resources/settings/site_settings/site_entry.ts
@@ -7,14 +7,14 @@
  * 'site-entry' is an element representing a single eTLD+1 site entity.
  */
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js';
 import '../settings_shared.css.js';
 import '../site_favicon.js';
 
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {CrLazyRenderElement} from 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js';
 import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js';
 import {FocusRowBehavior} from 'chrome://resources/js/cr/ui/focus_row_behavior.m.js';
diff --git a/chrome/browser/resources/settings/site_settings/site_list_entry.ts b/chrome/browser/resources/settings/site_settings/site_list_entry.ts
index 0c8403e..9a2c280 100644
--- a/chrome/browser/resources/settings/site_settings/site_list_entry.ts
+++ b/chrome/browser/resources/settings/site_settings/site_list_entry.ts
@@ -6,7 +6,7 @@
  * @fileoverview
  * 'site-list-entry' shows an Allowed and Blocked site for a given category.
  */
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/policy/cr_policy_pref_indicator.m.js';
 import 'chrome://resources/cr_elements/policy/cr_tooltip_icon.m.js';
diff --git a/chrome/browser/resources/settings/site_settings/zoom_levels.ts b/chrome/browser/resources/settings/site_settings/zoom_levels.ts
index 47466b5..9f497f4 100644
--- a/chrome/browser/resources/settings/site_settings/zoom_levels.ts
+++ b/chrome/browser/resources/settings/site_settings/zoom_levels.ts
@@ -9,7 +9,7 @@
  */
 
 import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import '../settings_shared.css.js';
diff --git a/chrome/browser/resources/settings/system_page/system_page.ts b/chrome/browser/resources/settings/system_page/system_page.ts
index 21138b2..c783733 100644
--- a/chrome/browser/resources/settings/system_page/system_page.ts
+++ b/chrome/browser/resources/settings/system_page/system_page.ts
@@ -8,7 +8,7 @@
  */
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/policy/cr_policy_pref_indicator.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
 import '../controls/extension_controlled_indicator.js';
diff --git a/chrome/browser/resources/side_panel/bookmarks/bookmark_folder.ts b/chrome/browser/resources/side_panel/bookmarks/bookmark_folder.ts
index 2d929a5..7c61f5f 100644
--- a/chrome/browser/resources/side_panel/bookmarks/bookmark_folder.ts
+++ b/chrome/browser/resources/side_panel/bookmarks/bookmark_folder.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/cr_elements/mwb_element_shared_style.css.js';
 
diff --git a/chrome/browser/resources/side_panel/reading_list/app.ts b/chrome/browser/resources/side_panel/reading_list/app.ts
index ef2dacd4..fe49e9b 100644
--- a/chrome/browser/resources/side_panel/reading_list/app.ts
+++ b/chrome/browser/resources/side_panel/reading_list/app.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/cr_elements/mwb_element_shared_style.css.js';
diff --git a/chrome/browser/resources/side_panel/reading_list/reading_list_item.ts b/chrome/browser/resources/side_panel/reading_list/reading_list_item.ts
index f7ce4e5c..cce2dc11 100644
--- a/chrome/browser/resources/side_panel/reading_list/reading_list_item.ts
+++ b/chrome/browser/resources/side_panel/reading_list/reading_list_item.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/mwb_element_shared_style.css.js';
diff --git a/chrome/browser/resources/signin/profile_picker/profile_card_menu.ts b/chrome/browser/resources/signin/profile_picker/profile_card_menu.ts
index f0809df..3d515ce 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_card_menu.ts
+++ b/chrome/browser/resources/signin/profile_picker/profile_card_menu.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/action_link_css.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/account_selection_lacros.ts b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/account_selection_lacros.ts
index 4624aa3..38ac7b3 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/account_selection_lacros.ts
+++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/account_selection_lacros.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import './profile_creation_shared.css.js';
 
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.ts b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.ts
index 622e70c..e5c11618 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.ts
+++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.ts
@@ -5,7 +5,7 @@
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.ts b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.ts
index 5c053d8..fb5e0be 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.ts
+++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import './profile_creation_shared.css.js';
 
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.ts b/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.ts
index 1682461..5af0677 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.ts
+++ b/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
diff --git a/chrome/browser/resources/tab_search/tab_search_group_item.ts b/chrome/browser/resources/tab_search/tab_search_group_item.ts
index 6556572..1f584b0 100644
--- a/chrome/browser/resources/tab_search/tab_search_group_item.ts
+++ b/chrome/browser/resources/tab_search/tab_search_group_item.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/mwb_shared_icons.html.js';
 import 'chrome://resources/cr_elements/mwb_shared_vars.css.js';
diff --git a/chrome/browser/resources/tab_search/tab_search_item.ts b/chrome/browser/resources/tab_search/tab_search_item.ts
index 74ef7df..354ad9e1 100644
--- a/chrome/browser/resources/tab_search/tab_search_item.ts
+++ b/chrome/browser/resources/tab_search/tab_search_item.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/mwb_shared_icons.html.js';
 import 'chrome://resources/cr_elements/mwb_shared_vars.css.js';
diff --git a/chrome/browser/resources/tab_strip/tab_list.html b/chrome/browser/resources/tab_strip/tab_list.html
index 1904363..a1680af 100644
--- a/chrome/browser/resources/tab_strip/tab_list.html
+++ b/chrome/browser/resources/tab_strip/tab_list.html
@@ -8,10 +8,10 @@
         0 2px 3px 0 rgba(var(--google-grey-800-rgb), .3),
         0 6px 10px 4px rgba(var(--google-grey-800-rgb), .15);
 
-<if expr="not chromeos_ash and not chromeos_lacros">
+<if expr="not is_chromeos">
     --tabstrip-tab-drag-image-scale: 1.1;
 </if>
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
     /* ChromeOS scales drag images by 1.2, so this variable multiplied by
      * 1.2 should be around 1.1. */
     --tabstrip-tab-drag-image-scale: calc(1.1 / 1.2);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_action_menu_demo_component.ts b/chrome/browser/resources/webui_gallery/demos/cr_action_menu_demo_component.ts
index ec7643c..83dd173 100644
--- a/chrome/browser/resources/webui_gallery/demos/cr_action_menu_demo_component.ts
+++ b/chrome/browser/resources/webui_gallery/demos/cr_action_menu_demo_component.ts
@@ -6,7 +6,7 @@
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo_component.ts b/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo_component.ts
index 7299b74..41c993ee 100644
--- a/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo_component.ts
+++ b/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo_component.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
diff --git a/chrome/browser/supervised_user/supervised_user_extensions_delegate_impl.cc b/chrome/browser/supervised_user/supervised_user_extensions_delegate_impl.cc
index 7feec72..10d24f1b1 100644
--- a/chrome/browser/supervised_user/supervised_user_extensions_delegate_impl.cc
+++ b/chrome/browser/supervised_user/supervised_user_extensions_delegate_impl.cc
@@ -12,7 +12,7 @@
 #include "chrome/browser/supervised_user/supervised_user_extensions_metrics_recorder.h"
 #include "chrome/browser/supervised_user/supervised_user_service.h"
 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
-#include "chrome/browser/ui/browser_dialogs.h"
+#include "chrome/browser/ui/extensions/extensions_dialogs.h"
 #include "chrome/browser/ui/supervised_user/parent_permission_dialog.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/browser/extension_dialog_auto_confirm.h"
@@ -128,9 +128,9 @@
                                                   std::move(done_callback));
     return;
   }
-  chrome::ShowExtensionInstallBlockedByParentDialog(
-      chrome::ExtensionInstalledBlockedByParentDialogAction::kEnable,
-      &extension, contents, std::move(done_callback));
+  ShowExtensionInstallBlockedByParentDialog(
+      ExtensionInstalledBlockedByParentDialogAction::kEnable, &extension,
+      contents, std::move(done_callback));
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index f6baf06..fe977b4 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -2330,6 +2330,8 @@
       "ash/projector/projector_app_client_impl.h",
       "ash/projector/projector_client_impl.cc",
       "ash/projector/projector_client_impl.h",
+      "ash/projector/projector_drivefs_provider.cc",
+      "ash/projector/projector_drivefs_provider.h",
       "ash/projector/projector_soda_installation_controller.cc",
       "ash/projector/projector_soda_installation_controller.h",
       "ash/projector/projector_utils.cc",
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
index bf06843c..7f466033 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -21,10 +21,13 @@
 import org.chromium.base.ActivityState;
 import org.chromium.base.Callback;
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.TraceEvent;
 import org.chromium.base.jank_tracker.JankScenario;
 import org.chromium.base.jank_tracker.JankTracker;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.base.supplier.Supplier;
+import org.chromium.base.task.PostTask;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.omnibox.LocationBarDataProvider;
 import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType;
 import org.chromium.chrome.browser.omnibox.R;
@@ -44,6 +47,7 @@
 import org.chromium.components.metrics.OmniboxEventProtos.OmniboxEventProto.PageClassification;
 import org.chromium.components.omnibox.AutocompleteMatch;
 import org.chromium.components.omnibox.AutocompleteResult;
+import org.chromium.content_public.browser.UiThreadTaskTraits;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.ui.base.PageTransition;
 import org.chromium.ui.modaldialog.DialogDismissalCause;
@@ -94,6 +98,8 @@
     private AutocompleteController mAutocomplete;
     private long mUrlFocusTime;
     private boolean mShouldCacheSuggestions;
+    private boolean mClearFocusAfterNavigation;
+    private boolean mClearFocusAfterNavigationAsynchronously;
 
     @IntDef({SuggestionVisibilityState.DISALLOWED, SuggestionVisibilityState.PENDING_ALLOW,
             SuggestionVisibilityState.ALLOWED})
@@ -280,6 +286,12 @@
      */
     void onNativeInitialized() {
         mNativeInitialized = true;
+        mClearFocusAfterNavigation =
+                ChromeFeatureList.isEnabled(ChromeFeatureList.CLEAR_OMNIBOX_FOCUS_AFTER_NAVIGATION);
+        mClearFocusAfterNavigationAsynchronously =
+                ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
+                        ChromeFeatureList.CLEAR_OMNIBOX_FOCUS_AFTER_NAVIGATION,
+                        "clear_focus_asynchronously", false);
         mDropdownViewInfoListBuilder.onNativeInitialized();
         runPendingAutocompleteRequests();
     }
@@ -782,55 +794,78 @@
      */
     private void loadUrlForOmniboxMatch(int matchIndex, @NonNull AutocompleteMatch suggestion,
             @NonNull GURL url, long inputStart, boolean inVisibleSuggestionList) {
-        SuggestionsMetrics.recordFocusToOpenTime(System.currentTimeMillis() - mUrlFocusTime);
+        try (TraceEvent e = TraceEvent.scoped("AutocompleteMediator.loadUrlFromOmniboxMatch")) {
+            SuggestionsMetrics.recordFocusToOpenTime(System.currentTimeMillis() - mUrlFocusTime);
 
-        // Clear the deferred site load action in case it executes. Reclaims a bit of memory.
-        mDeferredLoadAction = null;
+            // Clear the deferred site load action in case it executes. Reclaims a bit of memory.
+            mDeferredLoadAction = null;
 
-        mOmniboxFocusResultedInNavigation = true;
-        url = updateSuggestionUrlIfNeeded(suggestion, matchIndex, url, !inVisibleSuggestionList);
+            mOmniboxFocusResultedInNavigation = true;
+            url = updateSuggestionUrlIfNeeded(
+                    suggestion, matchIndex, url, !inVisibleSuggestionList);
 
-        // loadUrl modifies AutocompleteController's state clearing the native
-        // AutocompleteResults needed by onSuggestionsSelected. Therefore,
-        // loadUrl should should be invoked last.
-        int transition = suggestion.getTransition();
-        int type = suggestion.getType();
+            // loadUrl modifies AutocompleteController's state clearing the native
+            // AutocompleteResults needed by onSuggestionsSelected. Therefore,
+            // loadUrl should should be invoked last.
+            int transition = suggestion.getTransition();
+            int type = suggestion.getType();
 
-        recordMetrics(matchIndex, WindowOpenDisposition.CURRENT_TAB, suggestion);
-        if (((transition & PageTransition.CORE_MASK) == PageTransition.TYPED)
-                && TextUtils.equals(url.getSpec(), mDataProvider.getCurrentUrl())) {
-            // When the user hit enter on the existing permanent URL, treat it like a
-            // reload for scoring purposes.  We could detect this by just checking
-            // user_input_in_progress_, but it seems better to treat "edits" that end
-            // up leaving the URL unchanged (e.g. deleting the last character and then
-            // retyping it) as reloads too.  We exclude non-TYPED transitions because if
-            // the transition is GENERATED, the user input something that looked
-            // different from the current URL, even if it wound up at the same place
-            // (e.g. manually retyping the same search query), and it seems wrong to
-            // treat this as a reload.
-            transition = PageTransition.RELOAD;
-        } else if (type == OmniboxSuggestionType.URL_WHAT_YOU_TYPED
-                && mUrlBarEditingTextProvider.wasLastEditPaste()) {
-            // It's important to use the page transition from the suggestion or we might end
-            // up saving generated URLs as typed URLs, which would then pollute the subsequent
-            // omnibox results. There is one special case where the suggestion text was pasted,
-            // where we want the transition type to be LINK.
+            recordMetrics(matchIndex, WindowOpenDisposition.CURRENT_TAB, suggestion);
+            if (((transition & PageTransition.CORE_MASK) == PageTransition.TYPED)
+                    && TextUtils.equals(url.getSpec(), mDataProvider.getCurrentUrl())) {
+                // When the user hit enter on the existing permanent URL, treat it like a
+                // reload for scoring purposes.  We could detect this by just checking
+                // user_input_in_progress_, but it seems better to treat "edits" that end
+                // up leaving the URL unchanged (e.g. deleting the last character and then
+                // retyping it) as reloads too.  We exclude non-TYPED transitions because if
+                // the transition is GENERATED, the user input something that looked
+                // different from the current URL, even if it wound up at the same place
+                // (e.g. manually retyping the same search query), and it seems wrong to
+                // treat this as a reload.
+                transition = PageTransition.RELOAD;
+            } else if (type == OmniboxSuggestionType.URL_WHAT_YOU_TYPED
+                    && mUrlBarEditingTextProvider.wasLastEditPaste()) {
+                // It's important to use the page transition from the suggestion or we might end
+                // up saving generated URLs as typed URLs, which would then pollute the subsequent
+                // omnibox results. There is one special case where the suggestion text was pasted,
+                // where we want the transition type to be LINK.
 
-            transition = PageTransition.LINK;
+                transition = PageTransition.LINK;
+            }
+
+            // Kick off an action to clear focus and dismiss the suggestions list.
+            // This normally happens when the target site loads and focus is moved to the
+            // webcontents. On Android T we occasionally observe focus events to be lost, resulting
+            // with Suggestions list obscuring the view.
+            // TODO(crbug.com/1348324): clearing the Omnibox focus is slow, so we want to experiment
+            // with two alternatives:
+            // 1) Clear the Omnibox focus in a follow-up task. From a latency perspective, this is
+            //    the best option: the navigation gets kicked off right away, and important
+            //    navigation tasks can get scheduled between the current task and the task clearing
+            //    the Omnibox focus. The ClearOmniboxFocusAfterNavigation feature with the
+            //    clear_focus_asynchronously = false parameter (default) implements this option.
+            // 2) Clear the Omnibox focus synchronously *after* the navigation has been kicked off.
+            //    This allows some navigation work outside the browser process (e.g. running
+            //    beforeunload handlers) to start ASAP. This is implemented by the setting the
+            //    clear_focus_asynchronously = true parameter.
+            if (!mClearFocusAfterNavigation) {
+                mDelegate.clearOmniboxFocus();
+            }
+
+            if (suggestion.getType() == OmniboxSuggestionType.CLIPBOARD_IMAGE) {
+                mDelegate.loadUrlWithPostData(url.getSpec(), transition, inputStart,
+                        suggestion.getPostContentType(), suggestion.getPostData());
+            } else {
+                mDelegate.loadUrl(url.getSpec(), transition, inputStart);
+            }
+
+            if (mClearFocusAfterNavigationAsynchronously) {
+                PostTask.postTask(
+                        UiThreadTaskTraits.USER_VISIBLE, () -> mDelegate.clearOmniboxFocus());
+            } else if (mClearFocusAfterNavigation) {
+                mDelegate.clearOmniboxFocus();
+            }
         }
-
-        // Kick off an action to clear focus and dismiss the suggestions list.
-        // This normally happens when the target site loads and focus is moved to the webcontents.
-        // On Android T we occasionally observe focus events to be lost, resulting with Suggestions
-        // list obscuring the view.
-        mDelegate.clearOmniboxFocus();
-
-        if (suggestion.getType() == OmniboxSuggestionType.CLIPBOARD_IMAGE) {
-            mDelegate.loadUrlWithPostData(url.getSpec(), transition, inputStart,
-                    suggestion.getPostContentType(), suggestion.getPostData());
-            return;
-        }
-        mDelegate.loadUrl(url.getSpec(), transition, inputStart);
     }
 
     /**
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediatorUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediatorUnitTest.java
index e96aa51..c7937806 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediatorUnitTest.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediatorUnitTest.java
@@ -42,6 +42,7 @@
 import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.JniMocker;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.omnibox.LocationBarDataProvider;
 import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType;
 import org.chromium.chrome.browser.omnibox.UrlBarEditingTextStateProvider;
@@ -74,6 +75,7 @@
  */
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE, shadows = {ShadowLog.class, ShadowLooper.class, ShadowGURL.class})
+@Features.DisableFeatures({ChromeFeatureList.CLEAR_OMNIBOX_FOCUS_AFTER_NAVIGATION})
 public class AutocompleteMediatorUnitTest {
     private static final int MINIMUM_NUMBER_OF_SUGGESTIONS_TO_SHOW = 5;
     private static final int SUGGESTION_MIN_HEIGHT = 20;
diff --git a/chrome/browser/ui/ash/projector/pending_screencast_manager.cc b/chrome/browser/ui/ash/projector/pending_screencast_manager.cc
index 5a7405f..b2a0f033 100644
--- a/chrome/browser/ui/ash/projector/pending_screencast_manager.cc
+++ b/chrome/browser/ui/ash/projector/pending_screencast_manager.cc
@@ -24,10 +24,6 @@
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
 #include "chrome/browser/ash/drive/drive_integration_service.h"
-#include "chrome/browser/ash/profiles/profile_helper.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/ui/ash/projector/projector_utils.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/base/url_util.h"
@@ -49,11 +45,6 @@
          path.MatchesExtension(ash::kProjectorMetadataFileExtension);
 }
 
-drivefs::DriveFsHost* GetDriveFsHostForActiveProfile() {
-  auto* drivefs_integration = GetDriveIntegrationServiceForActiveProfile();
-  return drivefs_integration ? drivefs_integration->GetDriveFsHost() : nullptr;
-}
-
 // "Absolute path" is the DriveFS absolute path of `drive_relative_path` on
 // local file system, for example: absolute_path =
 // "/{$drivefs_mounted_point}/root/{$drive_relative_path}";
@@ -115,7 +106,7 @@
     PendingScreencastManager::OnGetFileIdCallback callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
   auto* drive_integration_service =
-      GetDriveIntegrationServiceForActiveProfile();
+      ProjectorDriveFsProvider::GetActiveDriveIntegrationService();
   if (!drive_integration_service)
     return;
   const base::FilePath local_path = GetLocalAbsolutePath(
@@ -337,20 +328,17 @@
 
 }  // namespace
 
+// Using base::Unretained for callback is safe since the
+// PendingScreencastManager owns the `drive_helper_`.
 PendingScreencastManager::PendingScreencastManager(
     PendingScreencastChangeCallback pending_screencast_change_callback)
     : pending_screencast_change_callback_(pending_screencast_change_callback),
       blocking_task_runner_(base::ThreadPool::CreateSequencedTaskRunner(
           {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
-           base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {
-  session_manager::SessionManager* session_manager =
-      session_manager::SessionManager::Get();
-  if (session_manager)
-    session_observation_.Observe(session_manager);
-  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
-  if (user_manager)
-    session_state_observation_.Observe(user_manager);
-}
+           base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})),
+      drive_helper_(base::BindRepeating(
+          &PendingScreencastManager::MaybeSwitchDriveFsObservation,
+          base::Unretained(this))) {}
 
 PendingScreencastManager::~PendingScreencastManager() = default;
 
@@ -375,9 +363,7 @@
 // download event. Find a way to filter out the upload event.
 void PendingScreencastManager::OnSyncingStatusUpdate(
     const drivefs::mojom::SyncingStatus& status) {
-  drive::DriveIntegrationService* drivefs_integration =
-      GetDriveIntegrationServiceForActiveProfile();
-  if (!drivefs_integration->IsMounted())
+  if (!ProjectorDriveFsProvider::IsDriveFsMounted())
     return;
   std::vector<drivefs::mojom::ItemEvent> pending_webm_or_projector_events;
   for (const auto& event : status.item_events) {
@@ -422,7 +408,7 @@
       base::BindOnce(ProcessAndGenerateNewScreencasts,
                      std::move(pending_webm_or_projector_events),
                      error_syncing_files_,
-                     drivefs_integration->GetMountPointPath()),
+                     ProjectorDriveFsProvider::GetDriveFsMountPointPath()),
       base::BindOnce(
           &PendingScreencastManager::OnProcessAndGenerateNewScreencastsFinished,
           weak_ptr_factory_.GetWeakPtr(),
@@ -471,6 +457,25 @@
   xhr_sender_ = std::move(xhr_sender);
 }
 
+void PendingScreencastManager::MaybeSwitchDriveFsObservation() {
+  auto* drivefs_integration =
+      ProjectorDriveFsProvider::GetActiveDriveIntegrationService();
+  if (!drivefs_integration)
+    return;
+
+  auto* drivefs_host = drivefs_integration->GetDriveFsHost();
+  if (!drivefs_host || drivefs_observation_.IsObservingSource(drivefs_host))
+    return;
+
+  pending_screencast_cache_.clear();
+  error_syncing_files_.clear();
+
+  // Reset if observing DriveFsHost of other profile.
+  if (drivefs_observation_.IsObserving())
+    drivefs_observation_.Reset();
+  drivefs_observation_.Observe(drivefs_host);
+}
+
 void PendingScreencastManager::OnProcessAndGenerateNewScreencastsFinished(
     const base::TimeTicks task_start_tick,
     const ash::PendingScreencastSet& screencasts) {
@@ -494,41 +499,6 @@
       pending_screencast_cache_.empty() ? base::TimeTicks() : now;
 }
 
-void PendingScreencastManager::OnUserProfileLoaded(
-    const AccountId& account_id) {
-  MaybeSwitchDriveFsObservation();
-}
-
-void PendingScreencastManager::ActiveUserChanged(
-    user_manager::User* active_user) {
-  // After user login, the first ActiveUserChanged() might be called before
-  // profile is loaded.
-  if (!active_user->is_profile_created())
-    return;
-
-  MaybeSwitchDriveFsObservation();
-}
-
-void PendingScreencastManager::MaybeSwitchDriveFsObservation() {
-  auto* profile = ProfileManager::GetActiveUserProfile();
-
-  if (!IsProjectorAllowedForProfile(profile))
-    return;
-
-  auto* drivefs_host = GetDriveFsHostForActiveProfile();
-  if (!drivefs_host || drivefs_observation_.IsObservingSource(drivefs_host))
-    return;
-
-  pending_screencast_cache_.clear();
-  error_syncing_files_.clear();
-
-  // Reset if observing DriveFsHost of other profile.
-  if (drivefs_observation_.IsObserving())
-    drivefs_observation_.Reset();
-
-  drivefs_observation_.Observe(drivefs_host);
-}
-
 void PendingScreencastManager::OnFileSyncedCompletely(
     const base::FilePath& event_file) {
   // If observes a error uploaded file is now successfully uploaded, removes
diff --git a/chrome/browser/ui/ash/projector/pending_screencast_manager.h b/chrome/browser/ui/ash/projector/pending_screencast_manager.h
index db90fd3..dd67fba 100644
--- a/chrome/browser/ui/ash/projector/pending_screencast_manager.h
+++ b/chrome/browser/ui/ash/projector/pending_screencast_manager.h
@@ -14,12 +14,9 @@
 #include "base/callback.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
-#include "base/observer_list.h"
 #include "base/scoped_observation.h"
 #include "base/time/time.h"
-#include "components/session_manager/core/session_manager.h"
-#include "components/session_manager/core/session_manager_observer.h"
-#include "components/user_manager/user_manager.h"
+#include "chrome/browser/ui/ash/projector/projector_drivefs_provider.h"
 
 namespace drivefs {
 namespace mojom {
@@ -39,10 +36,7 @@
     base::RepeatingCallback<void(const ash::PendingScreencastSet&)>;
 
 // A class that handles pending screencast events.
-class PendingScreencastManager
-    : public drivefs::DriveFsHostObserver,
-      public user_manager::UserManager::UserSessionStateObserver,
-      public session_manager::SessionManagerObserver {
+class PendingScreencastManager : public drivefs::DriveFsHostObserver {
  public:
   explicit PendingScreencastManager(
       PendingScreencastChangeCallback pending_screencast_change_callback);
@@ -59,6 +53,9 @@
   // Returns a list of pending screencast from `pending_screencast_cache_`.
   const ash::PendingScreencastSet& GetPendingScreencasts() const;
 
+  // Maybe reset `drivefs_observation_` and observe the current active profile.
+  void MaybeSwitchDriveFsObservation();
+
   // Test only:
   base::TimeTicks last_pending_screencast_change_tick() const {
     return last_pending_screencast_change_tick_;
@@ -81,15 +78,6 @@
       const base::TimeTicks task_start_tick,
       const ash::PendingScreencastSet& screencasts);
 
-  // session_manager::SessionManagerObserver:
-  void OnUserProfileLoaded(const AccountId& account_id) override;
-
-  // user_manager::UserManager::UserSessionStateObserver:
-  void ActiveUserChanged(user_manager::User* active_user) override;
-
-  // Maybe reset `drivefs_observation_` and observe the current active profile.
-  void MaybeSwitchDriveFsObservation();
-
   // Called when the `event_file` is synced to Drive. Removed completedly synced
   // files from `error_syncing_files_` and `syncing_metadata_files_` cached. If
   // it is a screencast metadata file, post task to update indexable text.
@@ -126,16 +114,6 @@
 
   base::ScopedObservation<drivefs::DriveFsHost, drivefs::DriveFsHostObserver>
       drivefs_observation_{this};
-  base::ScopedObservation<session_manager::SessionManager,
-                          session_manager::SessionManagerObserver>
-      session_observation_{this};
-
-  base::ScopedObservation<
-      user_manager::UserManager,
-      user_manager::UserManager::UserSessionStateObserver,
-      &user_manager::UserManager::AddSessionStateObserver,
-      &user_manager::UserManager::RemoveSessionStateObserver>
-      session_state_observation_{this};
 
   // The time tick when last `pending_screencast_change_callback_` was called.
   // Could be null if last `pending_screencast_change_callback_` was called with
@@ -152,6 +130,8 @@
   OnGetRequestBodyCallback on_get_request_body_;
   OnGetFileIdCallback on_get_file_id_callback_;
 
+  ProjectorDriveFsProvider drive_helper_;
+
   base::WeakPtrFactory<PendingScreencastManager> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/ui/ash/projector/projector_client_impl.cc b/chrome/browser/ui/ash/projector/projector_client_impl.cc
index b74c8df4..18d230a7 100644
--- a/chrome/browser/ui/ash/projector/projector_client_impl.cc
+++ b/chrome/browser/ui/ash/projector/projector_client_impl.cc
@@ -51,17 +51,18 @@
   web_view->LoadInitialURL(GURL(ash::kChromeUITrustedAnnotatorAppUrl));
 }
 
+// Using base::Unretained for callback is safe since the ProjectorClientImpl
+// owns `drive_helper_`.
 ProjectorClientImpl::ProjectorClientImpl(ash::ProjectorController* controller)
-    : controller_(controller) {
+    : controller_(controller),
+      drive_helper_(base::BindRepeating(
+          &ProjectorClientImpl::MaybeSwitchDriveIntegrationServiceObservation,
+          base::Unretained(this))) {
   controller_->SetClient(this);
   session_manager::SessionManager* session_manager =
       session_manager::SessionManager::Get();
   if (session_manager)
     session_observation_.Observe(session_manager);
-
-  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
-  if (user_manager)
-    session_state_observation_.Observe(user_manager);
 }
 
 ProjectorClientImpl::ProjectorClientImpl()
@@ -90,8 +91,7 @@
   speech_recognizer_->Stop();
 }
 
-bool ProjectorClientImpl::GetDriveFsMountPointPath(
-    base::FilePath* result) const {
+bool ProjectorClientImpl::GetBaseStoragePath(base::FilePath* result) const {
   if (!IsDriveFsMounted())
     return false;
 
@@ -105,9 +105,7 @@
     return true;
   }
 
-  drive::DriveIntegrationService* integration_service =
-      GetDriveIntegrationServiceForActiveProfile();
-  *result = integration_service->GetMountPointPath();
+  *result = ProjectorDriveFsProvider::GetDriveFsMountPointPath();
   return true;
 }
 
@@ -120,16 +118,11 @@
     // folder for Projector storage.
     return true;
   }
-
-  drive::DriveIntegrationService* integration_service =
-      GetDriveIntegrationServiceForActiveProfile();
-  return integration_service && integration_service->IsMounted();
+  return ProjectorDriveFsProvider::IsDriveFsMounted();
 }
 
 bool ProjectorClientImpl::IsDriveFsMountFailed() const {
-  drive::DriveIntegrationService* integration_service =
-      GetDriveIntegrationServiceForActiveProfile();
-  return integration_service && integration_service->mount_failed();
+  return ProjectorDriveFsProvider::IsDriveFsMountFailed();
 }
 
 void ProjectorClientImpl::OpenProjectorApp() const {
@@ -220,10 +213,6 @@
       controller_->GetNewScreencastPrecondition());
 }
 
-void ProjectorClientImpl::OnUserProfileLoaded(const AccountId& account_id) {
-  MaybeSwitchDriveIntegrationServiceObservation();
-}
-
 void ProjectorClientImpl::OnUserSessionStarted(bool is_primary_user) {
   if (!is_primary_user || !pref_change_registrar_.IsEmpty())
     return;
@@ -241,20 +230,9 @@
                           base::Unretained(this)));
 }
 
-void ProjectorClientImpl::ActiveUserChanged(user_manager::User* active_user) {
-  // After user login, the first ActiveUserChanged() might be called before
-  // profile is loaded.
-  if (active_user->is_profile_created())
-    MaybeSwitchDriveIntegrationServiceObservation();
-}
-
 void ProjectorClientImpl::MaybeSwitchDriveIntegrationServiceObservation() {
-  auto* profile = ProfileManager::GetActiveUserProfile();
-  if (!IsProjectorAllowedForProfile(profile))
-    return;
-
   drive::DriveIntegrationService* drive_service =
-      GetDriveIntegrationServiceForActiveProfile();
+      ProjectorDriveFsProvider::GetActiveDriveIntegrationService();
   if (!drive_service || drive_observation_.IsObservingSource(drive_service))
     return;
 
diff --git a/chrome/browser/ui/ash/projector/projector_client_impl.h b/chrome/browser/ui/ash/projector/projector_client_impl.h
index 90da7a4..19c8b7c 100644
--- a/chrome/browser/ui/ash/projector/projector_client_impl.h
+++ b/chrome/browser/ui/ash/projector/projector_client_impl.h
@@ -14,12 +14,12 @@
 #include "base/scoped_observation.h"
 #include "chrome/browser/ash/drive/drive_integration_service.h"
 #include "chrome/browser/speech/speech_recognizer_delegate.h"
+#include "chrome/browser/ui/ash/projector/projector_drivefs_provider.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/session_manager/core/session_manager.h"
 #include "components/session_manager/core/session_manager_observer.h"
 #include "components/soda/constants.h"
 #include "components/soda/soda_installer.h"
-#include "components/user_manager/user_manager.h"
 
 namespace views {
 class WebView;
@@ -29,13 +29,11 @@
 
 // The client implementation for the ProjectorController in ash/. This client is
 // responsible for handling requests that have browser dependencies.
-class ProjectorClientImpl
-    : public ash::ProjectorClient,
-      public SpeechRecognizerDelegate,
-      public ash::ProjectorAnnotatorController,
-      public drive::DriveIntegrationServiceObserver,
-      public session_manager::SessionManagerObserver,
-      public user_manager::UserManager::UserSessionStateObserver {
+class ProjectorClientImpl : public ash::ProjectorClient,
+                            public SpeechRecognizerDelegate,
+                            public ash::ProjectorAnnotatorController,
+                            public drive::DriveIntegrationServiceObserver,
+                            public session_manager::SessionManagerObserver {
  public:
   // RecordingOverlayViewImpl calls this function to initialize the annotator
   // tool.
@@ -51,7 +49,7 @@
   // ash::ProjectorClient:
   void StartSpeechRecognition() override;
   void StopSpeechRecognition() override;
-  bool GetDriveFsMountPointPath(base::FilePath* result) const override;
+  bool GetBaseStoragePath(base::FilePath* result) const override;
   bool IsDriveFsMounted() const override;
   bool IsDriveFsMountFailed() const override;
   void OpenProjectorApp() const override;
@@ -83,17 +81,13 @@
   void OnFileSystemMountFailed() override;
 
   // session_manager::SessionManagerObserver:
-  void OnUserProfileLoaded(const AccountId& account_id) override;
   void OnUserSessionStarted(bool is_primary_user) override;
 
-  // user_manager::UserManager::UserSessionStateObserver:
-  void ActiveUserChanged(user_manager::User* active_user) override;
-
- private:
   // Maybe reset |drive_observation_| and observe the Drive integration service
   // of active profile when ActiveUserChanged and OnUserProfileLoaded.
   void MaybeSwitchDriveIntegrationServiceObservation();
 
+ private:
   // Called when any of the policies change that control whether the Projector
   // app is enabled.
   void OnEnablementPolicyChanged();
@@ -106,8 +100,6 @@
       SpeechRecognizerStatus::SPEECH_RECOGNIZER_OFF;
   std::unique_ptr<OnDeviceSpeechRecognizer> speech_recognizer_;
 
-  // TODO(b/221492092): Clean this duplicate code with PendingScreencastManager.
-  // Create a new class to handle Drive related service.
   base::ScopedObservation<session_manager::SessionManager,
                           session_manager::SessionManagerObserver>
       session_observation_{this};
@@ -118,13 +110,7 @@
                           drive::DriveIntegrationServiceObserver>
       drive_observation_{this};
 
-  base::ScopedObservation<
-      user_manager::UserManager,
-      user_manager::UserManager::UserSessionStateObserver,
-      &user_manager::UserManager::AddSessionStateObserver,
-      &user_manager::UserManager::RemoveSessionStateObserver>
-      session_state_observation_{this};
-
+  ProjectorDriveFsProvider drive_helper_;
   base::WeakPtrFactory<ProjectorClientImpl> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc b/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc
index 27b6500..b1c97d2 100644
--- a/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc
+++ b/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc
@@ -248,7 +248,7 @@
   ASSERT_FALSE(client()->IsDriveFsMountFailed());
 
   base::FilePath mounted_path;
-  ASSERT_TRUE(client()->GetDriveFsMountPointPath(&mounted_path));
+  ASSERT_TRUE(client()->GetBaseStoragePath(&mounted_path));
   ASSERT_EQ(browser()->profile()->GetPath().Append("drivefs"), mounted_path);
 }
 
diff --git a/chrome/browser/ui/ash/projector/projector_drivefs_provider.cc b/chrome/browser/ui/ash/projector/projector_drivefs_provider.cc
new file mode 100644
index 0000000..bccec480
--- /dev/null
+++ b/chrome/browser/ui/ash/projector/projector_drivefs_provider.cc
@@ -0,0 +1,76 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/ash/projector/projector_drivefs_provider.h"
+
+#include "base/files/file_path.h"
+#include "chrome/browser/ash/drive/drive_integration_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/ash/projector/projector_utils.h"
+
+// static
+drive::DriveIntegrationService*
+ProjectorDriveFsProvider::GetActiveDriveIntegrationService() {
+  return drive::DriveIntegrationServiceFactory::FindForProfile(
+      ProfileManager::GetActiveUserProfile());
+}
+
+// static
+bool ProjectorDriveFsProvider::IsDriveFsMounted() {
+  drive::DriveIntegrationService* integration_service =
+      ProjectorDriveFsProvider::GetActiveDriveIntegrationService();
+  return integration_service && integration_service->IsMounted();
+}
+
+// static
+bool ProjectorDriveFsProvider::IsDriveFsMountFailed() {
+  drive::DriveIntegrationService* integration_service =
+      ProjectorDriveFsProvider::GetActiveDriveIntegrationService();
+  return integration_service && integration_service->mount_failed();
+}
+
+// static
+base::FilePath ProjectorDriveFsProvider::GetDriveFsMountPointPath() {
+  drive::DriveIntegrationService* integration_service =
+      ProjectorDriveFsProvider::GetActiveDriveIntegrationService();
+  return integration_service ? integration_service->GetMountPointPath()
+                             : base::FilePath();
+}
+
+ProjectorDriveFsProvider::ProjectorDriveFsProvider(
+    OnDriveFsObservationChangeCallback on_drivefs_observation_change)
+    : on_drivefs_observation_change_(on_drivefs_observation_change) {
+  session_manager::SessionManager* session_manager =
+      session_manager::SessionManager::Get();
+  if (session_manager)
+    session_observation_.Observe(session_manager);
+
+  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
+  if (user_manager)
+    session_state_observation_.Observe(user_manager);
+}
+
+ProjectorDriveFsProvider::~ProjectorDriveFsProvider() = default;
+
+void ProjectorDriveFsProvider::OnUserProfileLoaded(
+    const AccountId& account_id) {
+  OnProfileSwitch();
+}
+
+void ProjectorDriveFsProvider::ActiveUserChanged(
+    user_manager::User* active_user) {
+  // After user login, the first ActiveUserChanged() might be called before
+  // profile is loaded.
+  if (active_user->is_profile_created())
+    OnProfileSwitch();
+}
+
+void ProjectorDriveFsProvider::OnProfileSwitch() {
+  auto* profile = ProfileManager::GetActiveUserProfile();
+  if (!IsProjectorAllowedForProfile(profile))
+    return;
+
+  on_drivefs_observation_change_.Run();
+}
diff --git a/chrome/browser/ui/ash/projector/projector_drivefs_provider.h b/chrome/browser/ui/ash/projector/projector_drivefs_provider.h
new file mode 100644
index 0000000..f56087df
--- /dev/null
+++ b/chrome/browser/ui/ash/projector/projector_drivefs_provider.h
@@ -0,0 +1,61 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_ASH_PROJECTOR_PROJECTOR_DRIVEFS_PROVIDER_H_
+#define CHROME_BROWSER_UI_ASH_PROJECTOR_PROJECTOR_DRIVEFS_PROVIDER_H_
+
+#include "base/callback.h"
+#include "base/files/file_path.h"
+#include "base/scoped_observation.h"
+#include "components/session_manager/core/session_manager.h"
+#include "components/session_manager/core/session_manager_observer.h"
+#include "components/user_manager/user_manager.h"
+
+namespace drive {
+class DriveIntegrationService;
+}
+
+// A class provides DriveFs service for active profile. Encapsulates the logic
+// to observe UserSession and Profile change and trigger the callback when
+// profile change.
+class ProjectorDriveFsProvider
+    : public session_manager::SessionManagerObserver,
+      public user_manager::UserManager::UserSessionStateObserver {
+ public:
+  static drive::DriveIntegrationService* GetActiveDriveIntegrationService();
+  static bool IsDriveFsMounted();
+  static bool IsDriveFsMountFailed();
+  static base::FilePath GetDriveFsMountPointPath();
+
+  using OnDriveFsObservationChangeCallback = base::RepeatingCallback<void()>;
+  explicit ProjectorDriveFsProvider(
+      OnDriveFsObservationChangeCallback on_drivefs_observation_change);
+  ProjectorDriveFsProvider(const ProjectorDriveFsProvider&) = delete;
+  ProjectorDriveFsProvider& operator=(const ProjectorDriveFsProvider&) = delete;
+  ~ProjectorDriveFsProvider() override;
+
+ private:
+  // session_manager::SessionManagerObserver:
+  void OnUserProfileLoaded(const AccountId& account_id) override;
+
+  // user_manager::UserManager::UserSessionStateObserver:
+  void ActiveUserChanged(user_manager::User* active_user) override;
+
+  void OnProfileSwitch();
+
+  base::ScopedObservation<session_manager::SessionManager,
+                          session_manager::SessionManagerObserver>
+      session_observation_{this};
+
+  base::ScopedObservation<
+      user_manager::UserManager,
+      user_manager::UserManager::UserSessionStateObserver,
+      &user_manager::UserManager::AddSessionStateObserver,
+      &user_manager::UserManager::RemoveSessionStateObserver>
+      session_state_observation_{this};
+
+  OnDriveFsObservationChangeCallback on_drivefs_observation_change_;
+};
+
+#endif  // CHROME_BROWSER_UI_ASH_PROJECTOR_PROJECTOR_DRIVEFS_PROVIDER_H_
diff --git a/chrome/browser/ui/ash/projector/projector_utils.cc b/chrome/browser/ui/ash/projector/projector_utils.cc
index c1df0469d..4310463 100644
--- a/chrome/browser/ui/ash/projector/projector_utils.cc
+++ b/chrome/browser/ui/ash/projector/projector_utils.cc
@@ -6,7 +6,6 @@
 
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
-#include "chrome/browser/ash/drive/drive_integration_service.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/policy/profile_policy_connector.h"
 #include "chrome/browser/profiles/profile.h"
@@ -57,8 +56,3 @@
          (ash::features::IsProjectorManagedUserIgnorePolicyEnabled() ||
           profile->GetPrefs()->GetBoolean(ash::prefs::kProjectorAllowByPolicy));
 }
-
-drive::DriveIntegrationService* GetDriveIntegrationServiceForActiveProfile() {
-  return drive::DriveIntegrationServiceFactory::FindForProfile(
-      ProfileManager::GetActiveUserProfile());
-}
diff --git a/chrome/browser/ui/ash/projector/projector_utils.h b/chrome/browser/ui/ash/projector/projector_utils.h
index b27b9cbc..dc20ffb 100644
--- a/chrome/browser/ui/ash/projector/projector_utils.h
+++ b/chrome/browser/ui/ash/projector/projector_utils.h
@@ -7,16 +7,10 @@
 
 class Profile;
 
-namespace drive {
-class DriveIntegrationService;
-}
-
 // Returns whether Projector is allowed for given `profile`.
 bool IsProjectorAllowedForProfile(const Profile* profile);
 
 // Returns whether the Projector app is enabled.
 bool IsProjectorAppEnabled(const Profile* profile);
 
-drive::DriveIntegrationService* GetDriveIntegrationServiceForActiveProfile();
-
 #endif  // CHROME_BROWSER_UI_ASH_PROJECTOR_PROJECTOR_UTILS_H_
diff --git a/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.cc b/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.cc
index fb272b8..9eeabe4 100644
--- a/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.cc
+++ b/chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "base/metrics/histogram_functions.h"
 #include "chrome/browser/commerce/coupons/coupon_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/autofill/autofill_bubble_base.h"
@@ -179,6 +180,9 @@
   // going to show another bubble anyway.
   HideBubbleAndClearTimestamp(/*should_show_icon=*/true);
 
+  DCHECK(IsIconVisible());
+  autofill_metrics::LogPageLoadsWithOfferIconShown(offer->GetOfferType());
+
   if (card)
     card_ = *card;
 
@@ -189,8 +193,6 @@
     if (!last_display_time.is_null() &&
         (base::Time::Now() - last_display_time) <
             commerce::kCouponDisplayInterval.Get()) {
-      bubble_state_ = BubbleState::kShowingIcon;
-      UpdatePageActionIcon();
       autofill_metrics::LogOfferNotificationBubbleSuppressed(
           AutofillOfferData::OfferType::FREE_LISTING_COUPON_OFFER);
       return;
diff --git a/chrome/browser/ui/browser_dialogs.h b/chrome/browser/ui/browser_dialogs.h
index fa18eed1..0e21a9e9 100644
--- a/chrome/browser/ui/browser_dialogs.h
+++ b/chrome/browser/ui/browser_dialogs.h
@@ -16,11 +16,9 @@
 #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/common/buildflags.h"
 #include "content/public/browser/bluetooth_delegate.h"
 #include "content/public/browser/login_delegate.h"
 #include "extensions/buildflags/buildflags.h"
-#include "extensions/common/extension_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/interaction/element_identifier.h"
@@ -292,37 +290,6 @@
 
 #endif  // BUILDFLAG(IS_WIN)
 
-// TODO(crbug.com/1324288): Move extensions dialogs to
-// c/b/ui/extensions/extensions_dialogs.h
-
-// Displays a dialog to notify the user that the extension installation is
-// blocked due to policy. It also show additional information from administrator
-// if it exists.
-void ShowExtensionInstallBlockedDialog(
-    const extensions::ExtensionId& extension_id,
-    const std::string& extension_name,
-    const std::u16string& custom_error_message,
-    const gfx::ImageSkia& icon,
-    content::WebContents* web_contents,
-    base::OnceClosure done_callback);
-
-#if BUILDFLAG(ENABLE_SUPERVISED_USERS) && BUILDFLAG(ENABLE_EXTENSIONS)
-// The type of action that the ExtensionInstalledBlockedByParentDialog
-// is being shown in reaction to.
-enum class ExtensionInstalledBlockedByParentDialogAction {
-  kAdd,     // The user attempted to add the extension.
-  kEnable,  // The user attempted to enable the extension.
-};
-
-// Displays a dialog to notify the user that the extension installation is
-// blocked by a parent
-void ShowExtensionInstallBlockedByParentDialog(
-    ExtensionInstalledBlockedByParentDialogAction action,
-    const extensions::Extension* extension,
-    content::WebContents* web_contents,
-    base::OnceClosure done_callback);
-#endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS) && BUILDFLAG(ENABLE_EXTENSIONS)
-
 // Returns a OnceClosure that client code can call to close the device chooser.
 // This OnceClosure references the actual dialog as a WeakPtr, so it's safe to
 // call at any point.
diff --git a/chrome/browser/ui/extensions/extensions_dialogs.h b/chrome/browser/ui/extensions/extensions_dialogs.h
index d265b41..d000e88 100644
--- a/chrome/browser/ui/extensions/extensions_dialogs.h
+++ b/chrome/browser/ui/extensions/extensions_dialogs.h
@@ -5,9 +5,12 @@
 #ifndef CHROME_BROWSER_UI_EXTENSIONS_EXTENSIONS_DIALOGS_H_
 #define CHROME_BROWSER_UI_EXTENSIONS_EXTENSIONS_DIALOGS_H_
 
+#include <string>
+
 #include "base/callback_forward.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "chrome/common/buildflags.h"
 #include "extensions/buildflags/buildflags.h"
 #include "extensions/common/extension_id.h"
 #include "ui/gfx/native_widget_types.h"
@@ -30,6 +33,19 @@
 
 namespace extensions {
 
+class Extension;
+
+// Shows a dialog to notify the user that the extension installation is
+// blocked due to policy. It also shows additional information from
+// administrator if it exists.
+void ShowExtensionInstallBlockedDialog(
+    const ExtensionId& extension_id,
+    const std::string& extension_name,
+    const std::u16string& custom_error_message,
+    const gfx::ImageSkia& icon,
+    content::WebContents* web_contents,
+    base::OnceClosure done_callback);
+
 // Shows a modal dialog to Enhanced Safe Browsing users before the extension
 // install dialog if the extension is not included in the Safe Browsing CRX
 // allowlist. `callback` will be invoked with `true` if the user accepts or
@@ -53,6 +69,25 @@
     bool is_updating_permissions,
     base::OnceClosure callback);
 
+#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
+
+// The type of action that the ExtensionInstalledBlockedByParentDialog
+// is being shown in reaction to.
+enum class ExtensionInstalledBlockedByParentDialogAction {
+  kAdd,     // The user attempted to add the extension.
+  kEnable,  // The user attempted to enable the extension.
+};
+
+// Displays a dialog to notify the user that the extension installation is
+// blocked by a parent
+void ShowExtensionInstallBlockedByParentDialog(
+    ExtensionInstalledBlockedByParentDialogAction action,
+    const Extension* extension,
+    content::WebContents* web_contents,
+    base::OnceClosure done_callback);
+
+#endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS)
+
 #if BUILDFLAG(IS_CHROMEOS)
 
 // Shows the print job confirmation dialog bubble anchored to the toolbar icon
diff --git a/chrome/browser/ui/views/autofill/payments/offer_notification_bubble_views_interactive_uitest.cc b/chrome/browser/ui/views/autofill/payments/offer_notification_bubble_views_interactive_uitest.cc
index c6650c7e..43624639 100644
--- a/chrome/browser/ui/views/autofill/payments/offer_notification_bubble_views_interactive_uitest.cc
+++ b/chrome/browser/ui/views/autofill/payments/offer_notification_bubble_views_interactive_uitest.cc
@@ -20,6 +20,7 @@
 #include "components/autofill/core/browser/metrics/autofill_metrics.h"
 #include "components/autofill/core/browser/metrics/payments/offers_metrics.h"
 #include "components/autofill/core/browser/payments/offer_notification_handler.h"
+#include "components/autofill/core/browser/test_autofill_clock.h"
 #include "components/autofill/core/browser/ui/payments/payments_bubble_closed_reasons.h"
 #include "components/autofill/core/common/autofill_payments_features.h"
 #include "components/strings/grit/components_strings.h"
@@ -148,6 +149,7 @@
         ->notification_handler_.ClearShownNotificationIdForTesting();
   }
 
+  TestAutofillClock test_clock_;
   const AutofillOfferData::OfferType test_offer_type_;
 };
 
@@ -547,4 +549,39 @@
       GURL(GetDefaultTestDetailsUrlString()));
 }
 
+IN_PROC_BROWSER_TEST_P(
+    OfferNotificationBubbleViewsInteractiveUiTest,
+    RecordPageLoadsWithPromoOfferIconShowingMetricForFreeListingOffer) {
+  // Applies to free listing coupons offers only, as we don't log this metric
+  // for other offers.
+  if (test_offer_type_ !=
+      AutofillOfferData::OfferType::FREE_LISTING_COUPON_OFFER) {
+    return;
+  }
+
+  base::HistogramTester histogram_tester;
+
+  ShowBubbleForOfferAndVerify();
+  ASSERT_TRUE(GetOfferNotificationBubbleViews());
+  ASSERT_TRUE(IsIconVisible());
+  histogram_tester.ExpectBucketCount(
+      "Autofill.PageLoadsWithOfferIconShowing.FreeListingCouponOffer", true, 1);
+
+  test_clock_.Advance(kAutofillBubbleSurviveNavigationTime);
+
+  // Navigates to another valid domain will not reshow the bubble.
+  NavigateTo("https://www.merchantsite1.com/second");
+  EXPECT_FALSE(GetOfferNotificationBubbleViews());
+  EXPECT_TRUE(IsIconVisible());
+  histogram_tester.ExpectBucketCount(
+      "Autofill.PageLoadsWithOfferIconShowing.FreeListingCouponOffer", true, 2);
+
+  // Navigates to an invalid domain will dismiss the icon.
+  NavigateTo("https://www.about.com/");
+  EXPECT_FALSE(GetOfferNotificationBubbleViews());
+  EXPECT_FALSE(IsIconVisible());
+  histogram_tester.ExpectBucketCount(
+      "Autofill.PageLoadsWithOfferIconShowing.FreeListingCouponOffer", true, 2);
+}
+
 }  // namespace autofill
diff --git a/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view.cc
index 43e2e56..fac24a4 100644
--- a/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view.cc
+++ b/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view.cc
@@ -10,7 +10,6 @@
 #include "base/bind.h"
 #include "base/i18n/message_formatter.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/chrome_typography.h"
 #include "chrome/common/extensions/extension_constants.h"
@@ -34,7 +33,7 @@
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/widget/widget.h"
 
-namespace chrome {
+namespace extensions {
 
 void ShowExtensionInstallBlockedDialog(
     const std::string& extension_id,
@@ -51,7 +50,7 @@
       ->Show();
 }
 
-}  // namespace chrome
+}  // namespace extensions
 
 ExtensionInstallBlockedDialogView::ExtensionInstallBlockedDialogView(
     const std::string& extension_id,
diff --git a/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view_browsertest.cc b/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view_browsertest.cc
index c9aeab8..853702d0 100644
--- a/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/extensions/extension_install_blocked_dialog_view_browsertest.cc
@@ -7,7 +7,7 @@
 #include "base/callback_helpers.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_dialogs.h"
+#include "chrome/browser/ui/extensions/extensions_dialogs.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/test/test_browser_dialog.h"
 #include "content/public/browser/web_contents.h"
@@ -19,7 +19,7 @@
   ~ExtensionInstallBlockedDialogViewTest() override = default;
 
   void ShowUi(const std::string& name) override {
-    chrome::ShowExtensionInstallBlockedDialog(
+    extensions::ShowExtensionInstallBlockedDialog(
         "extension_id", "extension_name", message_, CreateExtensionIcon(),
         browser()->tab_strip_model()->GetWebContentsAt(0), base::DoNothing());
   }
diff --git a/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.cc b/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.cc
index 57dea62..8640d47 100644
--- a/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.cc
+++ b/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.cc
@@ -31,7 +31,7 @@
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/fill_layout.h"
 
-namespace chrome {
+namespace extensions {
 
 void ShowExtensionInstallBlockedByParentDialog(
     ExtensionInstalledBlockedByParentDialogAction action,
@@ -51,11 +51,11 @@
   widget->Show();
 }
 
-}  // namespace chrome
+}  // namespace extensions
 
 ExtensionInstallBlockedByParentDialogView::
     ExtensionInstallBlockedByParentDialogView(
-        chrome::ExtensionInstalledBlockedByParentDialogAction action,
+        extensions::ExtensionInstalledBlockedByParentDialogAction action,
         const extensions::Extension* extension,
         base::OnceClosure done_callback)
     : extension_(extension),
@@ -90,13 +90,13 @@
 void ExtensionInstallBlockedByParentDialogView::ConfigureTitle() {
   std::u16string title_string;
   switch (action_) {
-    case chrome::ExtensionInstalledBlockedByParentDialogAction::kAdd:
+    case extensions::ExtensionInstalledBlockedByParentDialogAction::kAdd:
       // The user is trying to add/install the extension/app
       title_string = l10n_util::GetStringFUTF16(
           IDS_EXTENSION_INSTALL_BLOCKED_BY_PARENT_PROMPT_TITLE,
           GetExtensionTypeString());
       break;
-    case chrome::ExtensionInstalledBlockedByParentDialogAction::kEnable:
+    case extensions::ExtensionInstalledBlockedByParentDialogAction::kEnable:
       // The user is trying to enable the extension/app
       title_string = l10n_util::GetStringFUTF16(
           IDS_EXTENSION_ENABLE_BLOCKED_BY_PARENT_PROMPT_TITLE,
@@ -111,13 +111,13 @@
 
   std::u16string body_string;
   switch (action_) {
-    case chrome::ExtensionInstalledBlockedByParentDialogAction::kAdd:
+    case extensions::ExtensionInstalledBlockedByParentDialogAction::kAdd:
       // The user is trying to add/install the extension/app
       body_string = l10n_util::GetStringFUTF16(
           IDS_EXTENSION_INSTALL_BLOCKED_BY_PARENT_PROMPT_MESSAGE,
           GetExtensionTypeString());
       break;
-    case chrome::ExtensionInstalledBlockedByParentDialogAction::kEnable:
+    case extensions::ExtensionInstalledBlockedByParentDialogAction::kEnable:
       // The user is trying to enable the extension/app
       body_string = l10n_util::GetStringFUTF16(
           IDS_EXTENSION_ENABLE_BLOCKED_BY_PARENT_PROMPT_MESSAGE,
diff --git a/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.h b/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.h
index d08db41..72544c20 100644
--- a/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.h
+++ b/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.h
@@ -9,7 +9,7 @@
 
 #include "base/callback_forward.h"
 #include "base/memory/raw_ptr.h"
-#include "chrome/browser/ui/browser_dialogs.h"
+#include "chrome/browser/ui/extensions/extensions_dialogs.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/views/controls/button/button.h"
@@ -35,7 +35,7 @@
   // |window| is the window the dialog will modally attach to.
   // |done_callback| will be called when the dialog is dismissed by the user.
   ExtensionInstallBlockedByParentDialogView(
-      chrome::ExtensionInstalledBlockedByParentDialogAction action,
+      extensions::ExtensionInstalledBlockedByParentDialogAction action,
       const extensions::Extension* extension,
       base::OnceClosure done_callback);
   ExtensionInstallBlockedByParentDialogView(
@@ -52,7 +52,7 @@
   std::u16string GetExtensionTypeString() const;
 
   raw_ptr<const extensions::Extension> extension_ = nullptr;
-  chrome::ExtensionInstalledBlockedByParentDialogAction action_;
+  extensions::ExtensionInstalledBlockedByParentDialogAction action_;
   base::OnceClosure done_callback_;
 };
 
diff --git a/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view_browsertest.cc b/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view_browsertest.cc
index 6647f6c..54e7062 100644
--- a/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view_browsertest.cc
@@ -7,7 +7,7 @@
 #include "base/callback_helpers.h"
 #include "base/memory/scoped_refptr.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_dialogs.h"
+#include "chrome/browser/ui/extensions/extensions_dialogs.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/test/test_browser_dialog.h"
 #include "content/public/browser/web_contents.h"
@@ -32,8 +32,8 @@
     }
     extension_ = extensions::ExtensionBuilder("test extension", type).Build();
 
-    chrome::ShowExtensionInstallBlockedByParentDialog(
-        chrome::ExtensionInstalledBlockedByParentDialogAction::kAdd,
+    extensions::ShowExtensionInstallBlockedByParentDialog(
+        extensions::ExtensionInstalledBlockedByParentDialogAction::kAdd,
         extension_.get(), browser()->tab_strip_model()->GetWebContentsAt(0),
         base::DoNothing());
   }
diff --git a/chrome/browser/ui/webui/chromeos/network_ui.cc b/chrome/browser/ui/webui/chromeos/network_ui.cc
index a12b838..3de5c202 100644
--- a/chrome/browser/ui/webui/chromeos/network_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/network_ui.cc
@@ -85,6 +85,8 @@
 constexpr char kGetTetheringStatus[] = "getTetheringStatus";
 constexpr char kGetTetheringConfig[] = "getTetheringConfig";
 constexpr char kSetTetheringConfig[] = "setTetheringConfig";
+constexpr char kCheckTetheringReadiness[] = "checkTetheringReadiness";
+constexpr char kSetTetheringEnabled[] = "setTetheringEnabled";
 
 bool GetServicePathFromGuid(const std::string& guid,
                             std::string* service_path) {
@@ -543,6 +545,15 @@
         kSetTetheringConfig,
         base::BindRepeating(&HotspotConfigMessageHandler::SetTetheringConfig,
                             base::Unretained(this)));
+    web_ui()->RegisterMessageCallback(
+        kCheckTetheringReadiness,
+        base::BindRepeating(
+            &HotspotConfigMessageHandler::CheckTetheringReadiness,
+            base::Unretained(this)));
+    web_ui()->RegisterMessageCallback(
+        kSetTetheringEnabled,
+        base::BindRepeating(&HotspotConfigMessageHandler::SetTetheringEnabled,
+                            base::Unretained(this)));
   }
 
  private:
@@ -581,6 +592,46 @@
         shill::kTetheringConfigProperty));
   }
 
+  void CheckTetheringReadiness(const base::Value::List& arg_list) {
+    CHECK_EQ(1u, arg_list.size());
+    std::string callback_id = arg_list[0].GetString();
+
+    ShillManagerClient::Get()->CheckTetheringReadiness(
+        base::BindOnce(&HotspotConfigMessageHandler::RespondStringResult,
+                       weak_ptr_factory_.GetWeakPtr(), callback_id),
+        base::BindOnce(&HotspotConfigMessageHandler::RespondError,
+                       weak_ptr_factory_.GetWeakPtr(), callback_id,
+                       kCheckTetheringReadiness));
+  }
+
+  void SetTetheringEnabled(const base::Value::List& arg_list) {
+    CHECK_EQ(2u, arg_list.size());
+    std::string callback_id = arg_list[0].GetString();
+    bool enabled = arg_list[1].GetBool();
+
+    // Enable TetheringAllowed flag in Shill manager before turning on/off
+    // tethering.
+    ShillManagerClient::Get()->SetProperty(
+        shill::kTetheringAllowedProperty, base::Value(true),
+        base::BindOnce(&HotspotConfigMessageHandler::PerformSetTetheringEnabled,
+                       weak_ptr_factory_.GetWeakPtr(), callback_id, enabled),
+        base::BindOnce(
+            &HotspotConfigMessageHandler::SetManagerPropertiesErrorCallback,
+            weak_ptr_factory_.GetWeakPtr(), callback_id,
+            shill::kTetheringConfigProperty));
+  }
+
+  void PerformSetTetheringEnabled(const std::string& callback_id,
+                                  bool enabled) {
+    ShillManagerClient::Get()->SetTetheringEnabled(
+        enabled,
+        base::BindOnce(&HotspotConfigMessageHandler::RespondStringResult,
+                       weak_ptr_factory_.GetWeakPtr(), callback_id, "success"),
+        base::BindOnce(&HotspotConfigMessageHandler::RespondError,
+                       weak_ptr_factory_.GetWeakPtr(), callback_id,
+                       kSetTetheringEnabled));
+  }
+
   void SetTetheringConfig(const base::Value::List& arg_list) {
     CHECK_EQ(2u, arg_list.size());
     std::string callback_id = arg_list[0].GetString();
@@ -597,9 +648,8 @@
                   << ": " << *value;
     ShillManagerClient::Get()->SetProperty(
         shill::kTetheringConfigProperty, *value,
-        base::BindOnce(
-            &HotspotConfigMessageHandler::SetManagerPropertiesSuccessCallback,
-            weak_ptr_factory_.GetWeakPtr(), callback_id),
+        base::BindOnce(&HotspotConfigMessageHandler::RespondStringResult,
+                       weak_ptr_factory_.GetWeakPtr(), callback_id, "success"),
         base::BindOnce(
             &HotspotConfigMessageHandler::SetManagerPropertiesErrorCallback,
             weak_ptr_factory_.GetWeakPtr(), callback_id,
@@ -633,8 +683,18 @@
     Respond(callback_id, base::Value(dbus_error_name));
   }
 
-  void SetManagerPropertiesSuccessCallback(const std::string& callback_id) {
-    Respond(callback_id, base::Value("success"));
+  void RespondError(const std::string& callback_id,
+                    const std::string& operation,
+                    const std::string& error_name,
+                    const std::string& error_message) {
+    NET_LOG(ERROR) << "Error occured when " << operation << ": " << error_name
+                   << ", error message: " << error_message;
+    Respond(callback_id, base::Value(error_name));
+  }
+
+  void RespondStringResult(const std::string& callback_id,
+                           const std::string& result) {
+    Respond(callback_id, base::Value(result));
   }
 
   base::WeakPtrFactory<HotspotConfigMessageHandler> weak_ptr_factory_{this};
@@ -827,6 +887,16 @@
   localized_strings.Set("setTetheringConfigButtonText",
                         l10n_util::GetStringUTF16(
                             IDS_NETWORK_UI_SET_TETHERING_CONFIG_BUTTON_TEXT));
+  localized_strings.Set(
+      "tetheringReadinessLabel",
+      l10n_util::GetStringUTF16(IDS_NETWORK_UI_TETHERING_READINESS_LABEL));
+  localized_strings.Set(
+      "checkTetheringReadinessButtonText",
+      l10n_util::GetStringUTF16(
+          IDS_NETWORK_UI_CHECK_TETHERING_READINESS_BUTTON_TEXT));
+  localized_strings.Set(
+      "setTetheringEnabledLabel",
+      l10n_util::GetStringUTF16(IDS_NETWORK_UI_SET_TETHERING_ENABLED_LABEL));
   return localized_strings;
 }
 
@@ -854,6 +924,8 @@
   html->AddLocalizedStrings(localized_strings);
   html->AddBoolean("isGuestModeActive", IsGuestModeActive());
   html->AddBoolean("isHotspotEnabled", ash::features::IsHotspotEnabled());
+  html->AddString("tetheringStateStarting", shill::kTetheringStateStarting);
+  html->AddString("tetheringStateActive", shill::kTetheringStateActive);
   network_health::AddResources(html);
   network_diagnostics::AddResources(html);
   cellular_setup::AddLocalizedStrings(html);
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index cdeebcaf..bcf0461 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1659722381-13479a5c89934f6ea661341ced0db071475a6676.profdata
+chrome-linux-main-1659764845-b87c313cba6b11709f20d75fe0782762fa5534b1.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 1b7c814..c8e4f64 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1659722381-be619584abc441f883e868bc99cc1563cda483b3.profdata
+chrome-mac-arm-main-1659764845-a762f7f39e65e96e475171a86b88a279fb85a62c.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index c9f4681..b1c8f85 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1659722381-9fce1a67fb233581251f973f329ff7a33d90dbac.profdata
+chrome-mac-main-1659786925-183adb4e72ce041c474b31fc81a22ff6a7c0d166.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index d087f01..141fa65 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1659711517-b8f6f7be5dcbb97489eeaa43a00b9d73439a60d4.profdata
+chrome-win32-main-1659772175-7b423c0f403ed5e8c0f933904a5224c500a99f6f.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index f113d944..363e0e71 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1659722381-5d2c9919108699318e2b1350bbee597ecb821a69.profdata
+chrome-win64-main-1659772175-72a90428b44ac6af8a69b39eddd8559280e24854.profdata
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 2487080..c31577c 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -3648,6 +3648,7 @@
         "../browser/ash/login/error_screen_browsertest.cc",
         "../browser/ash/login/eula_browsertest.cc",
         "../browser/ash/login/existing_user_controller_browsertest.cc",
+        "../browser/ash/login/extensions/login_screen_extensions_lifetime_manager_browsertest.cc",
         "../browser/ash/login/guest_login_browsertest.cc",
         "../browser/ash/login/lock/fingerprint_unlock_browsertest.cc",
         "../browser/ash/login/lock/lock_screen_browsertest.cc",
@@ -3659,7 +3660,6 @@
         "../browser/ash/login/login_browsertest.cc",
         "../browser/ash/login/login_manager_test.cc",
         "../browser/ash/login/login_manager_test.h",
-        "../browser/ash/login/login_screen_extensions_lifetime_manager_browsertest.cc",
         "../browser/ash/login/login_screen_policy_browsertest.cc",
         "../browser/ash/login/login_ui_browsertest.cc",
         "../browser/ash/login/login_ui_keyboard_browsertest.cc",
diff --git a/chrome/test/data/extensions/api_test/service_worker/worker_based_background/service_worker_registration_failure/manifest.json b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/service_worker_registration_failure/manifest.json
new file mode 100644
index 0000000..c15ad89
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/service_worker_registration_failure/manifest.json
@@ -0,0 +1,9 @@
+{
+  "name": "Service Worker-based background script",
+  "version": "0.1",
+  "manifest_version": 3,
+  "description": "Test a service script that throws error.",
+  "background": {
+    "service_worker": "service_worker_background.js"
+  }
+}
diff --git a/chrome/test/data/extensions/api_test/service_worker/worker_based_background/service_worker_registration_failure/service_worker_background.js b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/service_worker_registration_failure/service_worker_background.js
new file mode 100644
index 0000000..cd5e14a
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/service_worker_registration_failure/service_worker_background.js
@@ -0,0 +1,5 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+throw new Error('lol');
diff --git a/chrome/test/data/print_to_pdf/oopif.html b/chrome/test/data/print_to_pdf/oopif.html
new file mode 100644
index 0000000..a9abb37
--- /dev/null
+++ b/chrome/test/data/print_to_pdf/oopif.html
@@ -0,0 +1,9 @@
+<body>
+  <iframe width=100% height=100% style="border:none; background: blue;"></iframe>
+  <script>
+    var url = window.location.href;
+    url = url.replace(/a\.com/, "b.com");
+    url = url.replace(/oopif\.html/, "oopif_frame.html");
+    document.querySelector('iframe').setAttribute('src', url);
+  </script>
+</body>
diff --git a/chrome/test/data/print_to_pdf/oopif_frame.html b/chrome/test/data/print_to_pdf/oopif_frame.html
new file mode 100644
index 0000000..eacc2d25
--- /dev/null
+++ b/chrome/test/data/print_to_pdf/oopif_frame.html
@@ -0,0 +1 @@
+<div style="width: 100%; height: 100%; background: red; display: block;"></div>
diff --git a/chrome/test/data/webui/cr_elements/cr_expand_button_tests.ts b/chrome/test/data/webui/cr_elements/cr_expand_button_tests.ts
index efc5c2d..800bbfb 100644
--- a/chrome/test/data/webui/cr_elements/cr_expand_button_tests.ts
+++ b/chrome/test/data/webui/cr_elements/cr_expand_button_tests.ts
@@ -6,7 +6,7 @@
 import 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.js';
 
 import {CrExpandButtonElement} from 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.js';
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 // clang-format on
 
diff --git a/chrome/test/data/webui/cr_elements/cr_icon_button_tests.ts b/chrome/test/data/webui/cr_elements/cr_icon_button_tests.ts
index 79a05df..aba14ba 100644
--- a/chrome/test/data/webui/cr_elements/cr_icon_button_tests.ts
+++ b/chrome/test/data/webui/cr_elements/cr_icon_button_tests.ts
@@ -3,13 +3,12 @@
 // found in the LICENSE file.
 
 // clang-format off
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {downAndUp, pressAndReleaseKeyOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
-
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {eventToPromise, flushTasks} from 'chrome://webui-test/test_util.js';
 
diff --git a/chrome/test/data/webui/cr_elements/cr_link_row_tests.ts b/chrome/test/data/webui/cr_elements/cr_link_row_tests.ts
index bb04597..85d9727 100644
--- a/chrome/test/data/webui/cr_elements/cr_link_row_tests.ts
+++ b/chrome/test/data/webui/cr_elements/cr_link_row_tests.ts
@@ -5,7 +5,7 @@
 // clang-format off
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 
-import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {CrLinkRowElement} from 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
diff --git a/chrome/test/data/webui/tab_strip/tab_list_test.ts b/chrome/test/data/webui/tab_strip/tab_list_test.ts
index 1a4fd32..e8c7a6f 100644
--- a/chrome/test/data/webui/tab_strip/tab_list_test.ts
+++ b/chrome/test/data/webui/tab_strip/tab_list_test.ts
@@ -696,6 +696,7 @@
     const tabToGroup = tabs[1]!;
     callbackRouter.tabGroupStateChanged(
         tabToGroup.id, tabToGroup.index, 'group0');
+    callbackRouter.tabMoved(tabToGroup.id, 0, false);
     callbackRouter.tabGroupMoved('group0', 0);
     await flushTasks();
 
@@ -704,6 +705,54 @@
     assertEquals(tabAtIndex0.tab.id, tabToGroup.id);
   });
 
+  test('MoveTabGroupMultipleTabs', async () => {
+    const tabToGroup1 = tabs[1]!;
+    const tabToGroup2 = tabs[2]!;
+
+    // Group tabs {1, 2} and assert the tab elements are correctly added under
+    // their tab group element.
+    callbackRouter.tabGroupStateChanged(
+        tabToGroup1.id, tabToGroup1.index, 'group0');
+    callbackRouter.tabGroupStateChanged(
+        tabToGroup2.id, tabToGroup2.index, 'group0');
+    await flushTasks();
+    assertEquals(
+        getUnpinnedTabs()[1]!.parentElement!.tagName, 'TABSTRIP-TAB-GROUP');
+    assertEquals(
+        getUnpinnedTabs()[2]!.parentElement!.tagName, 'TABSTRIP-TAB-GROUP');
+
+    // During a drag and drop session that triggers a tab group move within the
+    // WebUI tab strip the following sequence of events occur:
+    //   1. The drag manager places the existing tab group element at the
+    //      proposed drop index.
+    //   2. The drag completes and the tab strip model is updated. This results
+    //      in a series of tabMoved() events followed by a final tabGroupMoved()
+    //      event.
+    // The code below simulates this sequence of events and ensures the tab
+    // strip responds correctly.
+
+    // 1.
+    const tabGroupElement = tabList.shadowRoot!.querySelector(
+        'tabstrip-tab-group[data-group-id="group0"]')!;
+    tabList.placeTabGroupElement(tabGroupElement as TabGroupElement, 0);
+
+    // 2.
+    callbackRouter.tabMoved(tabToGroup2.id, 0, false);
+    callbackRouter.tabMoved(tabToGroup1.id, 0, false);
+    callbackRouter.tabGroupMoved('group0', 0);
+    await flushTasks();
+
+    // Assert the tabs have moved as expected and are still members of their
+    // oroginal tab group colloring the move.
+    const tabAtIndex0 = getUnpinnedTabs()[0]!;
+    assertEquals(tabAtIndex0.parentElement!.tagName, 'TABSTRIP-TAB-GROUP');
+    assertEquals(tabAtIndex0.tab.id, tabToGroup1.id);
+
+    const tabAtIndex1 = getUnpinnedTabs()[1]!;
+    assertEquals(tabAtIndex1.parentElement!.tagName, 'TABSTRIP-TAB-GROUP');
+    assertEquals(tabAtIndex1.tab.id, tabToGroup2.id);
+  });
+
   test('tracks and untracks thumbnails based on viewport', async () => {
     // Wait for slideIn animations to complete updating widths and reset
     // resolvers to track new calls.
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt
index a99b492..bb8b0c56 100644
--- a/chromeos/profiles/atom.afdo.newest.txt
+++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-atom-106-5187.0-1658747184-benchmark-106.0.5211.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-atom-106-5195.5-1659346912-benchmark-106.0.5221.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt
index 17e357a..11a5623 100644
--- a/chromeos/profiles/bigcore.afdo.newest.txt
+++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-bigcore-106-5187.0-1658744016-benchmark-106.0.5211.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-bigcore-106-5195.5-1659348806-benchmark-106.0.5221.0-r1-redacted.afdo.xz
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
index 229d1ff..dc84f884 100644
--- a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
+++ b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
@@ -2528,8 +2528,22 @@
   EXPECT_FALSE(
       histogram_tester.GetAllSamples("Autofill.Timing.DetermineHeuristicTypes")
           .empty());
-  EXPECT_FALSE(
-      histogram_tester.GetAllSamples("Autofill.Timing.ParseForm").empty());
+  if (!base::FeatureList::IsEnabled(features::kAutofillParseAsync)) {
+    EXPECT_FALSE(
+        histogram_tester.GetAllSamples("Autofill.Timing.ParseForm").empty());
+  } else {
+    EXPECT_FALSE(
+        histogram_tester.GetAllSamples("Autofill.Timing.ParseFormsAsync")
+            .empty());
+    EXPECT_FALSE(
+        histogram_tester
+            .GetAllSamples("Autofill.Timing.ParseFormsAsync.RunHeuristics")
+            .empty());
+    EXPECT_FALSE(
+        histogram_tester
+            .GetAllSamples("Autofill.Timing.ParseFormsAsync.UpdateCache")
+            .empty());
+  }
 }
 
 // Test that we log quality metrics appropriately when an upload is triggered
@@ -2590,6 +2604,8 @@
 
   // Simulate text input on one of the fields.
   ChangeTextField(form, form.fields[0]);
+  autofill_manager().SetSeenFormPredictions(form.global_id(), heuristic_types,
+                                            server_types);
 
   // Trigger a form upload and metrics by Resetting the manager.
   base::HistogramTester histogram_tester;
diff --git a/components/autofill/core/browser/metrics/payments/offers_metrics.cc b/components/autofill/core/browser/metrics/payments/offers_metrics.cc
index 3c9a79d..f82c7cb 100644
--- a/components/autofill/core/browser/metrics/payments/offers_metrics.cc
+++ b/components/autofill/core/browser/metrics/payments/offers_metrics.cc
@@ -210,4 +210,24 @@
   base::UmaHistogramBoolean("Autofill.Offer.SyncedOfferDataBeingValid", valid);
 }
 
+void LogPageLoadsWithOfferIconShown(AutofillOfferData::OfferType offer_type) {
+  std::string histogram_name = "Autofill.PageLoadsWithOfferIconShowing";
+  // Switch to different sub-histogram depending on offer type being displayed.
+  switch (offer_type) {
+    case AutofillOfferData::OfferType::FREE_LISTING_COUPON_OFFER:
+      histogram_name += ".FreeListingCouponOffer";
+      break;
+    case AutofillOfferData::OfferType::GPAY_CARD_LINKED_OFFER:
+      histogram_name += "CardLinkedOffer";
+      break;
+    case AutofillOfferData::OfferType::GPAY_PROMO_CODE_OFFER:
+      histogram_name += ".GPayPromoCodeOffer";
+      break;
+    case AutofillOfferData::OfferType::UNKNOWN:
+      NOTREACHED();
+      return;
+  }
+  base::UmaHistogramBoolean(histogram_name, true);
+}
+
 }  // namespace autofill::autofill_metrics
diff --git a/components/autofill/core/browser/metrics/payments/offers_metrics.h b/components/autofill/core/browser/metrics/payments/offers_metrics.h
index 3dc3859..c57c4bd 100644
--- a/components/autofill/core/browser/metrics/payments/offers_metrics.h
+++ b/components/autofill/core/browser/metrics/payments/offers_metrics.h
@@ -126,6 +126,10 @@
 // Logs whether the synced autofill offer data is valid.
 void LogSyncedOfferDataBeingValid(bool invalid);
 
+// Log the presence of the offer notification icon shows on navigation event
+// for |offer_type|.
+void LogPageLoadsWithOfferIconShown(AutofillOfferData::OfferType offer_type);
+
 }  // namespace autofill::autofill_metrics
 
 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_PAYMENTS_OFFERS_METRICS_H_
diff --git a/components/omnibox/browser/base_search_provider.cc b/components/omnibox/browser/base_search_provider.cc
index 89f1d9c..b76d01ca 100644
--- a/components/omnibox/browser/base_search_provider.cc
+++ b/components/omnibox/browser/base_search_provider.cc
@@ -290,7 +290,6 @@
     const GURL& current_page_url,
     const GURL& suggest_url,
     const TemplateURL* template_url,
-    metrics::OmniboxEventProto::PageClassification page_classification,
     const SearchTermsData& search_terms_data,
     const AutocompleteProviderClient* client,
     bool sending_search_terms) {
@@ -298,18 +297,6 @@
     return false;
   }
 
-  // Don't bother sending the URL of an NTP page; it's not useful.  The server
-  // already gets equivalent information in the form of the current page
-  // classification.
-  if (IsNTPPage(page_classification)) {
-    return false;
-  }
-
-  // Only allow valid HTTP or HTTPS URLs.
-  if (!CanSendPageURLInRequest(current_page_url)) {
-    return false;
-  }
-
   // If URL data collection is off, forbid sending the current page URL to the
   // suggest endpoint - unless both of these hold:
   //  * The suggest endpoint and current page must be same-origin. In that
diff --git a/components/omnibox/browser/base_search_provider.h b/components/omnibox/browser/base_search_provider.h
index da98b6f0..6156e71 100644
--- a/components/omnibox/browser/base_search_provider.h
+++ b/components/omnibox/browser/base_search_provider.h
@@ -131,8 +131,6 @@
   // Returns whether we can send the URL of the current page in any suggest
   // requests.  Doing this requires that all the following hold:
   // * CanSendRequest() returns true.
-  // * IsNTPPage() returns false.
-  // * CanSendPageURLInRequest() returns true.
   // * Either one of:
   //   * The user consented to sending URLs of current page to Google and have
   //     them associated with their Google account.
@@ -142,14 +140,12 @@
   //     Chrome still shouldn't leak the association between typed search terms
   //     and which tab the user is looking at. On-focus suggest requests never
   //     send search terms.
-  static bool CanSendRequestWithURL(
-      const GURL& current_page_url,
-      const GURL& suggest_url,
-      const TemplateURL* template_url,
-      metrics::OmniboxEventProto::PageClassification page_classification,
-      const SearchTermsData& search_terms_data,
-      const AutocompleteProviderClient* client,
-      bool sending_search_terms);
+  static bool CanSendRequestWithURL(const GURL& current_page_url,
+                                    const GURL& suggest_url,
+                                    const TemplateURL* template_url,
+                                    const SearchTermsData& search_terms_data,
+                                    const AutocompleteProviderClient* client,
+                                    bool sending_search_terms);
 
   // AutocompleteProvider:
   void DeleteMatch(const AutocompleteMatch& match) override;
diff --git a/components/omnibox/browser/search_provider.cc b/components/omnibox/browser/search_provider.cc
index fdf0181..b38c1f8 100644
--- a/components/omnibox/browser/search_provider.cc
+++ b/components/omnibox/browser/search_provider.cc
@@ -213,9 +213,29 @@
   set_field_trial_triggered_in_session(false);
 }
 
-SearchProvider::~SearchProvider() {
+// static
+bool SearchProvider::CanSendCurrentPageURLInRequest(
+    const GURL& current_page_url,
+    const GURL& suggest_url,
+    const TemplateURL* template_url,
+    metrics::OmniboxEventProto::PageClassification page_classification,
+    const SearchTermsData& search_terms_data,
+    const AutocompleteProviderClient* client,
+    bool sending_search_terms) {
+  // Send the current page URL if the request eligiblility and the user settings
+  // requirements are met and the URL is valid with an HTTP(S) scheme.
+  // Don't bother sending the URL of an NTP page; it's not useful. The server
+  // already gets equivalent information in the form of the current page
+  // classification.
+  return !IsNTPPage(page_classification) &&
+         CanSendPageURLInRequest(current_page_url) &&
+         BaseSearchProvider::CanSendRequestWithURL(
+             current_page_url, suggest_url, template_url, search_terms_data,
+             client, sending_search_terms);
 }
 
+SearchProvider::~SearchProvider() = default;
+
 // static
 void SearchProvider::UpdateOldResults(
     bool minimal_changes,
@@ -975,10 +995,10 @@
   if (!suggest_url.is_valid())
     return nullptr;
 
-  // Send the current page URL if user setting and URL requirements are met.
-  if (CanSendRequestWithURL(input.current_url(), suggest_url, template_url,
-                            input.current_page_classification(),
-                            search_terms_data, client(), true)) {
+  if (CanSendCurrentPageURLInRequest(input.current_url(), suggest_url,
+                                     template_url,
+                                     input.current_page_classification(),
+                                     search_terms_data, client(), true)) {
     search_term_args.current_page_url = input.current_url().spec();
     // Create the suggest URL again with the current page URL.
     suggest_url = GURL(template_url->suggestions_url_ref().ReplaceSearchTerms(
diff --git a/components/omnibox/browser/search_provider.h b/components/omnibox/browser/search_provider.h
index 3199da2..ee18f04 100644
--- a/components/omnibox/browser/search_provider.h
+++ b/components/omnibox/browser/search_provider.h
@@ -82,13 +82,23 @@
   // The verbatim score for an input which is not a URL.
   static const int kNonURLVerbatimRelevance = 1300;
 
+  // Returns whether the current page URL can be sent in the suggest requests.
+  // This method is static to avoid depending on the provider state.
+  static bool CanSendCurrentPageURLInRequest(
+      const GURL& current_page_url,
+      const GURL& suggest_url,
+      const TemplateURL* template_url,
+      metrics::OmniboxEventProto::PageClassification page_classification,
+      const SearchTermsData& search_terms_data,
+      const AutocompleteProviderClient* client,
+      bool sending_search_terms);
+
  protected:
   ~SearchProvider() override;
 
  private:
   friend class AutocompleteProviderTest;
   friend class BaseSearchProviderTest;
-  FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, CanSendRequestWithURL);
   FRIEND_TEST_ALL_PREFIXES(SearchProviderTest,
                            DontInlineAutocompleteAsynchronously);
   FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, NavigationInline);
diff --git a/components/omnibox/browser/zero_suggest_provider.cc b/components/omnibox/browser/zero_suggest_provider.cc
index 6351ca7..c8cace0 100644
--- a/components/omnibox/browser/zero_suggest_provider.cc
+++ b/components/omnibox/browser/zero_suggest_provider.cc
@@ -41,21 +41,28 @@
 #include "third_party/metrics_proto/omnibox_input_type.pb.h"
 #include "url/gurl.h"
 
-using metrics::OmniboxEventProto;
-using metrics::OmniboxInputType;
+using OEP = metrics::OmniboxEventProto;
+using OFT = OmniboxFocusType;
+using OIT = metrics::OmniboxInputType;
 
 namespace {
 
-// Represents whether ZeroSuggestProvider is allowed to display contextual
-// suggestions on focus, and if not, why not.
+// Represents whether ZeroSuggestProvider is allowed to display zero-prefix
+// suggestions, and if not, why not.
 // These values are written to logs.  New enum values can be added, but existing
 // enums must never be renumbered or deleted and reused.
 enum class Eligibility {
   kEligible = 0,
-  // kURLIneligible would be kEligible except some property of the current URL
-  // itself prevents ZeroSuggest from triggering.
-  kURLIneligible = 1,
-  kGenerallyIneligible = 2,
+  // Suggest request without sending the current page URL cannot be made. E.g.,
+  // the user is in incognito mode or Google is not set as the DSE.
+  kRequestNoURLIneligible = 1,
+  // Suggest request with sending the current page URL cannot be made. E.g.,
+  // the user has not consented and the suggest endpoint and page URL are not
+  // same-origin.
+  kRemoteSendURLIneligible = 2,
+  // Zero-prefix suggestions are not eligible in the given context. E.g., due to
+  // the page classification, focus type, input type, or an invalid page URL.
+  kGenerallyIneligible = 3,
 
   kMaxValue = kGenerallyIneligible,
 };
@@ -86,9 +93,9 @@
 void LogEvent(Event event,
               ZeroSuggestProvider::ResultType result_type,
               bool is_prefetch) {
-  DCHECK_NE(ZeroSuggestProvider::ResultType::NONE, result_type);
+  DCHECK_NE(ZeroSuggestProvider::ResultType::kNone, result_type);
   const std::string result_type_string =
-      result_type == ZeroSuggestProvider::ResultType::REMOTE_NO_URL
+      result_type == ZeroSuggestProvider::ResultType::kRemoteNoURL
           ? ".NoURL"
           : ".URLBased";
   const std::string request_type_string =
@@ -101,13 +108,8 @@
 // Relevance value to use if it was not set explicitly by the server.
 const int kDefaultZeroSuggestRelevance = 100;
 
-// Metric name tracking the omnibox suggestion eligibility.
-constexpr char kOmniboxZeroSuggestEligibleHistogramName[] =
-    "Omnibox.ZeroSuggest.Eligible.OnFocusV2";
-
-// Returns whether the current URL can be sent in the suggest request and
-// records metrics on eligibility.
-// This function only applies to REMOTE_SEND_URL variant.
+// Returns whether the current URL can be sent in the suggest request.
+// This function only applies to kRemoteSendURL variant.
 bool AllowRemoteSendURL(const AutocompleteProviderClient* client,
                         const AutocompleteInput& input) {
   const TemplateURLService* template_url_service =
@@ -115,48 +117,34 @@
   if (!template_url_service) {
     return false;
   }
+  const TemplateURL* default_provider =
+      template_url_service->GetDefaultSearchProvider();
+  if (!default_provider) {
+    return false;
+  }
+  TemplateURLRef::SearchTermsArgs search_terms_args;
+  GURL suggest_url = RemoteSuggestionsService::EndpointUrl(
+      search_terms_args, template_url_service);
 
-  // Returns whether sending the given url in the suggest request is possible.
-  auto can_send_request_with_url = [&](GURL url) {
-    const TemplateURL* default_provider =
-        template_url_service->GetDefaultSearchProvider();
-    TemplateURLRef::SearchTermsArgs search_terms_args;
-    GURL suggest_url = RemoteSuggestionsService::EndpointUrl(
-        search_terms_args, template_url_service);
-    OmniboxEventProto::PageClassification current_page_classification =
-        input.current_page_classification();
-
-    return BaseSearchProvider::CanSendRequestWithURL(
-        url, suggest_url, default_provider, current_page_classification,
-        template_url_service->search_terms_data(), client,
-        /*sending_search_terms=*/false);
-  };
-
-  // Find out whether sending a request with the current page url or otherwise
-  // any eligible url is possible and log eligibility metrics.
-  const GURL kArbitraryInsecureUrl{"http://www.google.com/"};
-  Eligibility eligibility = can_send_request_with_url(input.current_url())
-                                ? Eligibility::kEligible
-                            : can_send_request_with_url(kArbitraryInsecureUrl)
-                                ? Eligibility::kURLIneligible
-                                : Eligibility::kGenerallyIneligible;
-  base::UmaHistogramEnumeration(kOmniboxZeroSuggestEligibleHistogramName,
-                                eligibility);
-
-  return eligibility == Eligibility::kEligible;
+  return BaseSearchProvider::CanSendRequestWithURL(
+      input.current_url(), suggest_url, default_provider,
+      template_url_service->search_terms_data(), client,
+      /*sending_search_terms=*/false);
 }
 
 // Return whether a suggest request can be made without sending the current URL.
-// This function only applies to REMOTE_NO_URL variant.
+// This function only applies to kRemoteNoURL variant.
 bool AllowRemoteNoURL(const AutocompleteProviderClient* client) {
   const TemplateURLService* template_url_service =
       client->GetTemplateURLService();
   if (!template_url_service) {
     return false;
   }
-
   const TemplateURL* default_provider =
       template_url_service->GetDefaultSearchProvider();
+  if (!default_provider) {
+    return false;
+  }
   TemplateURLRef::SearchTermsArgs search_terms_args;
   GURL suggest_url = RemoteSuggestionsService::EndpointUrl(
       search_terms_args, template_url_service);
@@ -225,8 +213,8 @@
     return false;
   }
 
-  // Store the valid response only if running the REMOTE_NO_URL variant.
-  if (result_type == ZeroSuggestProvider::ResultType::REMOTE_NO_URL) {
+  // Store the valid response only if running the kRemoteNoURL variant.
+  if (result_type == ZeroSuggestProvider::ResultType::kRemoteNoURL) {
     client->GetPrefs()->SetString(omnibox::kZeroSuggestCachedResults,
                                   response_json);
     LogEvent(Event::kRemoteResponseCached, result_type, is_prefetch);
@@ -246,8 +234,8 @@
                         SearchSuggestionParser::Results* results) {
   DCHECK(results);
 
-  // Use the stored response only if running the REMOTE_NO_URL variant.
-  if (result_type != ZeroSuggestProvider::ResultType::REMOTE_NO_URL) {
+  // Use the stored response only if running the kRemoteNoURL variant.
+  if (result_type != ZeroSuggestProvider::ResultType::kRemoteNoURL) {
     return false;
   }
 
@@ -276,91 +264,93 @@
 }  // namespace
 
 // static
-ZeroSuggestProvider::ResultType ZeroSuggestProvider::TypeOfResultToRun(
+ZeroSuggestProvider::ResultType ZeroSuggestProvider::ResultTypeToRun(
     const AutocompleteProviderClient* client,
-    const AutocompleteInput& input,
-    bool bypass_request_eligibility_checks) {
+    const AutocompleteInput& input) {
   const auto page_class = input.current_page_classification();
-  const auto focus_type = input.focus_type();
+  const auto focus_type_input_type =
+      std::make_pair(input.focus_type(), input.type());
 
-  const bool allow_remote_no_url =
-      bypass_request_eligibility_checks || AllowRemoteNoURL(client);
-
-  // New Tab Page family.
-  if ((BaseSearchProvider::IsNTPPage(page_class) ||
-       page_class == OmniboxEventProto::CHROMEOS_APP_LIST) &&
-      allow_remote_no_url) {
-    if (focus_type == OmniboxFocusType::ON_FOCUS &&
-        input.type() == OmniboxInputType::EMPTY) {
-      return ZeroSuggestProvider::REMOTE_NO_URL;
-    } else if (page_class == OmniboxEventProto::ANDROID_SHORTCUTS_WIDGET &&
-               focus_type == OmniboxFocusType::ON_FOCUS &&
-               input.type() == OmniboxInputType::URL) {
-      return ZeroSuggestProvider::REMOTE_NO_URL;
+  // Android Search Widget.
+  if (page_class == OEP::ANDROID_SHORTCUTS_WIDGET) {
+    if (focus_type_input_type == std::make_pair(OFT::ON_FOCUS, OIT::URL)) {
+      return ResultType::kRemoteNoURL;
     }
   }
 
-  const bool allow_remote_send_url =
-      bypass_request_eligibility_checks || AllowRemoteSendURL(client, input);
+  // New Tab Page.
+  if (BaseSearchProvider::IsNTPPage(page_class)) {
+    if (focus_type_input_type == std::make_pair(OFT::ON_FOCUS, OIT::EMPTY)) {
+      return ResultType::kRemoteNoURL;
+    }
+  }
+
+  // The following cases require sending the current page URL in the request.
+  // Ensure the URL is valid with an HTTP(S) scheme and is not the NTP page URL.
+  if (BaseSearchProvider::IsNTPPage(page_class) ||
+      !BaseSearchProvider::CanSendPageURLInRequest(input.current_url())) {
+    return ResultType::kNone;
+  }
 
   // Open Web - does NOT include Search Results Page.
-  if (page_class == OmniboxEventProto::OTHER && allow_remote_send_url) {
-    if (focus_type == OmniboxFocusType::ON_FOCUS &&
-        (base::FeatureList::IsEnabled(
-            omnibox::kFocusTriggersContextualWebZeroSuggest))) {
-      return ZeroSuggestProvider::REMOTE_SEND_URL;
+  if (page_class == OEP::OTHER) {
+    if (focus_type_input_type == std::make_pair(OFT::ON_FOCUS, OIT::URL) &&
+        base::FeatureList::IsEnabled(
+            omnibox::kFocusTriggersContextualWebZeroSuggest)) {
+      return ResultType::kRemoteSendURL;
     }
-    if (focus_type == OmniboxFocusType::DELETED_PERMANENT_TEXT &&
-        input.type() == OmniboxInputType::EMPTY &&
+    if (focus_type_input_type ==
+            std::make_pair(OFT::DELETED_PERMANENT_TEXT, OIT::EMPTY) &&
         base::FeatureList::IsEnabled(
             omnibox::kClobberTriggersContextualWebZeroSuggest)) {
-      return ZeroSuggestProvider::REMOTE_SEND_URL;
+      return ResultType::kRemoteSendURL;
     }
   }
 
   // Search Results Page.
-  if (BaseSearchProvider::IsSearchResultsPage(page_class) &&
-      allow_remote_send_url) {
-    if (focus_type == OmniboxFocusType::ON_FOCUS &&
+  if (BaseSearchProvider::IsSearchResultsPage(page_class)) {
+    if (focus_type_input_type == std::make_pair(OFT::ON_FOCUS, OIT::URL) &&
         base::FeatureList::IsEnabled(omnibox::kFocusTriggersSRPZeroSuggest)) {
-      return ZeroSuggestProvider::REMOTE_SEND_URL;
+      return ResultType::kRemoteSendURL;
     }
-    if (focus_type == OmniboxFocusType::DELETED_PERMANENT_TEXT &&
-        input.type() == OmniboxInputType::EMPTY &&
+    if (focus_type_input_type ==
+            std::make_pair(OFT::DELETED_PERMANENT_TEXT, OIT::EMPTY) &&
         base::FeatureList::IsEnabled(omnibox::kClobberTriggersSRPZeroSuggest)) {
-      return ZeroSuggestProvider::REMOTE_SEND_URL;
+      return ResultType::kRemoteSendURL;
     }
   }
 
-  return ZeroSuggestProvider::NONE;
+  return ResultType::kNone;
 }
 
 // static
 bool ZeroSuggestProvider::AllowZeroPrefixSuggestions(
     const AutocompleteProviderClient* client,
-    const AutocompleteInput& input,
-    ResultType* result_type_to_run) {
-  DCHECK(result_type_to_run);
-  *result_type_to_run = ZeroSuggestProvider::NONE;
+    const AutocompleteInput& input) {
+  auto eligibility = Eligibility::kEligible;
 
-  if (input.focus_type() == OmniboxFocusType::DEFAULT) {
-    return false;
+  switch (ResultTypeToRun(client, input)) {
+    case ResultType::kRemoteNoURL: {
+      if (!AllowRemoteNoURL(client)) {
+        eligibility = Eligibility::kRequestNoURLIneligible;
+      }
+      break;
+    }
+    case ResultType::kRemoteSendURL: {
+      if (!AllowRemoteSendURL(client, input)) {
+        eligibility = Eligibility::kRemoteSendURLIneligible;
+      }
+      break;
+    }
+    default: {
+      eligibility = Eligibility::kGenerallyIneligible;
+      break;
+    }
   }
 
-  // Before checking whether the external conditions for sending a request are
-  // met, find out whether zero-prefix suggestions are generally allowed in
-  // the given context. This is being done for metrics purposes only.
-  *result_type_to_run = TypeOfResultToRun(
-      client, input, /*bypass_request_eligibility_checks=*/true);
-  if (*result_type_to_run == ZeroSuggestProvider::NONE) {
-    base::UmaHistogramEnumeration(kOmniboxZeroSuggestEligibleHistogramName,
-                                  Eligibility::kGenerallyIneligible);
-    return false;
-  }
-
-  *result_type_to_run = TypeOfResultToRun(
-      client, input, /*bypass_request_eligibility_checks=*/false);
-  return *result_type_to_run != ZeroSuggestProvider::NONE;
+  base::UmaHistogramEnumeration("Omnibox.ZeroSuggestProvider.Eligibility",
+                                eligibility);
+  return eligibility == Eligibility::kEligible;
 }
 
 // static
@@ -379,8 +369,7 @@
 void ZeroSuggestProvider::StartPrefetch(const AutocompleteInput& input) {
   TRACE_EVENT0("omnibox", "ZeroSuggestProvider::StartPrefetch");
 
-  ResultType result_type;
-  if (!AllowZeroPrefixSuggestions(client(), input, &result_type)) {
+  if (!AllowZeroPrefixSuggestions(client(), input)) {
     return;
   }
 
@@ -389,6 +378,8 @@
     return;
   }
 
+  ResultType result_type = ResultTypeToRun(client(), input);
+
   if (prefetch_loader_) {
     LogEvent(Event::kRequestInvalidated, result_type, /*is_prefetch=*/true);
   }
@@ -397,7 +388,7 @@
   TemplateURLRef::SearchTermsArgs search_terms_args;
   search_terms_args.page_classification = input.current_page_classification();
   search_terms_args.focus_type = input.focus_type();
-  search_terms_args.current_page_url = result_type == REMOTE_SEND_URL
+  search_terms_args.current_page_url = result_type == ResultType::kRemoteSendURL
                                            ? input.current_url().spec()
                                            : std::string();
   prefetch_loader_ =
@@ -418,11 +409,12 @@
   TRACE_EVENT0("omnibox", "ZeroSuggestProvider::Start");
   Stop(true, false);
 
-  result_type_running_ = NONE;
-  if (!AllowZeroPrefixSuggestions(client(), input, &result_type_running_)) {
+  result_type_running_ = ResultType::kNone;
+  if (!AllowZeroPrefixSuggestions(client(), input)) {
     return;
   }
 
+  result_type_running_ = ResultTypeToRun(client(), input);
   set_field_trial_triggered(false);
   set_field_trial_triggered_in_session(false);
 
@@ -446,9 +438,10 @@
   TemplateURLRef::SearchTermsArgs search_terms_args;
   search_terms_args.page_classification = input.current_page_classification();
   search_terms_args.focus_type = input.focus_type();
-  search_terms_args.current_page_url = result_type_running_ == REMOTE_SEND_URL
-                                           ? input.current_url().spec()
-                                           : std::string();
+  search_terms_args.current_page_url =
+      result_type_running_ == ResultType::kRemoteSendURL
+          ? input.current_url().spec()
+          : std::string();
   loader_ = client()
                 ->GetRemoteSuggestionsService(/*create_if_necessary=*/true)
                 ->StartSuggestionsRequest(
@@ -479,7 +472,7 @@
 void ZeroSuggestProvider::DeleteMatch(const AutocompleteMatch& match) {
   // Remove the deleted match from the cache, so it is not shown to the user
   // again. Since we cannot remove just one result, blow away the cache.
-  // Although the cache is currently only used for REMOTE_NO_URL, we have no
+  // Although the cache is currently only used for kRemoteNoURL, we have no
   // easy way of checking the request type after-the-fact. It's safe though, to
   // always clear the cache even if we are on a different request type.
   client()->GetPrefs()->SetString(omnibox::kZeroSuggestCachedResults,
diff --git a/components/omnibox/browser/zero_suggest_provider.h b/components/omnibox/browser/zero_suggest_provider.h
index 51cf6cf6..2615d941 100644
--- a/components/omnibox/browser/zero_suggest_provider.h
+++ b/components/omnibox/browser/zero_suggest_provider.h
@@ -36,44 +36,37 @@
 // omnibox text and suggestions.
 class ZeroSuggestProvider : public BaseSearchProvider {
  public:
-  // ZeroSuggestProvider is processing one of the following type of results
-  // at any time. Exposed as public for testing purposes.
-  enum ResultType {
-    NONE,
+  // The result type that can be processed by ZeroSuggestProvider.
+  // Public for testing purposes and for use in LocalHistoryZeroSuggestProvider.
+  enum class ResultType {
+    kNone = 0,
 
-    // A remote endpoint (usually the default search provider) is queried for
-    // suggestions. The endpoint is sent the user's authentication state, but
-    // not sent the current URL.
-    REMOTE_NO_URL,
+    // The remote endpoint is queried for zero-prefix suggestions. The endpoint
+    // is sent the user's authentication state, but not the current papge URL.
+    kRemoteNoURL = 1,
 
-    // A remote endpoint (usually the default search provider) is queried for
-    // suggestions. The endpoint is sent the user's authentication state and
-    // the current URL.
-    REMOTE_SEND_URL,
+    // The emote endpoint is queried for zero-prefix suggestions. The endpoint
+    // is sent both the user's authentication state and the current page URL.
+    kRemoteSendURL = 2,
   };
 
-  // Returns the type of results that should be generated for the given context.
-  // If `bypass_request_eligibility_checks` is false, checks whether the
-  // external conditions for REMOTE_NO_URL and REMOTE_SEND_URL variants are met;
-  // Logs eligibility UMA metrics, if applicable. Must be called exactly once
-  // with `bypass_request_eligibility_checks` set to false,
-  // otherwise the meaning of the metrics being logged would change.
+  // Returns the type of results that should be generated for the given context;
+  // however, it does not check whether or not a suggest request can be made.
+  // Those checks must be done using BaseSearchProvider::CanSendRequest() and
+  // BaseSearchProvider::CanSendPageURLInRequest() for the kRemoteNoURL and
+  // kRemoteSendURL variants respectively.
   // This method is static to avoid depending on the provider state.
-  static ResultType TypeOfResultToRun(const AutocompleteProviderClient* client,
-                                      const AutocompleteInput& input,
-                                      bool bypass_request_eligibility_checks);
+  static ResultType ResultTypeToRun(const AutocompleteProviderClient* client,
+                                    const AutocompleteInput& input);
 
-  // Called in Start(), confirms whether zero-prefix suggestions are allowed in
-  // the given context and logs eligibility UMA metrics. `result_type_to_run`
-  // must not be nullptr. It will be set to the result type that should be
-  // generated for the given context.
-  // Must be called exactly once, in Start(), otherwise the meaning of the
-  // the metrics being logged would change.
+  // Called in Start() or StartPrefetch(), confirms whether zero-prefix
+  // suggestions are allowed in the given context and logs eligibility UMA
+  // metrics. Must be called exactly once. Otherwise the meaning of the the
+  // metrics it logs would change.
   // This method is static to avoid depending on the provider state.
   static bool AllowZeroPrefixSuggestions(
       const AutocompleteProviderClient* client,
-      const AutocompleteInput& input,
-      ResultType* result_type_to_run);
+      const AutocompleteInput& input);
 
   // Creates and returns an instance of this provider.
   static ZeroSuggestProvider* Create(AutocompleteProviderClient* client,
@@ -153,7 +146,7 @@
   // The result type that is currently being retrieved and processed for
   // non-prefetch requests.
   // Set in Start() and used in Stop() for logging purposes.
-  ResultType result_type_running_{NONE};
+  ResultType result_type_running_{ResultType::kNone};
 
   // Loader used to retrieve results for non-prefetch requests.
   std::unique_ptr<network::SimpleURLLoader> loader_;
diff --git a/components/omnibox/browser/zero_suggest_provider_unittest.cc b/components/omnibox/browser/zero_suggest_provider_unittest.cc
index 584a9c5..8f7e39ca 100644
--- a/components/omnibox/browser/zero_suggest_provider_unittest.cc
+++ b/components/omnibox/browser/zero_suggest_provider_unittest.cc
@@ -245,10 +245,11 @@
     base::test::ScopedFeatureList features;
     features.InitAndEnableFeature(omnibox::kZeroSuggestOnNTPForSignedOutUsers);
 
-    ZeroSuggestProvider::ResultType result_type = ZeroSuggestProvider::NONE;
-    ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), onfocus_ntp_input, &result_type);
-    EXPECT_EQ(ZeroSuggestProvider::REMOTE_NO_URL, result_type);
+    EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
+        client_.get(), onfocus_ntp_input));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kRemoteNoURL,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), onfocus_ntp_input));
   }
   // Disable on-focus zero-suggest for signed-out users.
   {
@@ -258,10 +259,11 @@
     EXPECT_CALL(*client_, IsAuthenticated())
         .WillRepeatedly(testing::Return(false));
 
-    ZeroSuggestProvider::ResultType result_type = ZeroSuggestProvider::NONE;
-    ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), onfocus_ntp_input, &result_type);
-    EXPECT_EQ(ZeroSuggestProvider::NONE, result_type);
+    EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
+        client_.get(), onfocus_ntp_input));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kRemoteNoURL,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), onfocus_ntp_input));
   }
 }
 
@@ -273,7 +275,6 @@
   AutocompleteInput on_focus_srp_input = OnFocusInputForSRP();
   AutocompleteInput on_clobber_web_input = OnClobberInputForWeb();
   AutocompleteInput on_clobber_srp_input = OnClobberInputForSRP();
-  ZeroSuggestProvider::ResultType result_type;
 
   // Disable on-clobber for OTHER and SRP.
   // Enable on-focus for OTHER and SRP.
@@ -289,19 +290,19 @@
         });
 
     EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), prefix_web_input, &result_type));
+        client_.get(), prefix_web_input));
     EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), prefix_srp_input, &result_type));
+        client_.get(), prefix_srp_input));
 
     EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), on_focus_web_input, &result_type));
+        client_.get(), on_focus_web_input));
     EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), on_focus_srp_input, &result_type));
+        client_.get(), on_focus_srp_input));
 
     EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), on_clobber_web_input, &result_type));
+        client_.get(), on_clobber_web_input));
     EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), on_clobber_srp_input, &result_type));
+        client_.get(), on_clobber_srp_input));
   }
   // Enable on-clobber and on-focus for OTHER.
   // Disable on-clobber and on-focus for SRP.
@@ -314,19 +315,19 @@
                                omnibox::kFocusTriggersSRPZeroSuggest});
 
     EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), prefix_web_input, &result_type));
+        client_.get(), prefix_web_input));
     EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), prefix_srp_input, &result_type));
+        client_.get(), prefix_srp_input));
 
     EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), on_focus_web_input, &result_type));
+        client_.get(), on_focus_web_input));
     EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), on_focus_srp_input, &result_type));
+        client_.get(), on_focus_srp_input));
 
     EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), on_clobber_web_input, &result_type));
+        client_.get(), on_clobber_web_input));
     EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), on_clobber_srp_input, &result_type));
+        client_.get(), on_clobber_srp_input));
   }
   // Enable on-clobber and on-focus for SRP.
   // Disable on-clobber and on-focus for OTHER.
@@ -340,19 +341,19 @@
             omnibox::kFocusTriggersContextualWebZeroSuggest});
 
     EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), prefix_web_input, &result_type));
+        client_.get(), prefix_web_input));
     EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), prefix_srp_input, &result_type));
+        client_.get(), prefix_srp_input));
 
     EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), on_focus_web_input, &result_type));
+        client_.get(), on_focus_web_input));
     EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), on_focus_srp_input, &result_type));
+        client_.get(), on_focus_srp_input));
 
     EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), on_clobber_web_input, &result_type));
+        client_.get(), on_clobber_web_input));
     EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-        client_.get(), on_clobber_srp_input, &result_type));
+        client_.get(), on_clobber_srp_input));
   }
 }
 
@@ -363,23 +364,20 @@
   base::test::ScopedFeatureList features;
   features.InitAndEnableFeature(omnibox::kFocusTriggersSRPZeroSuggest);
 
-  AutocompleteInput on_focus_srp_input = OnFocusInputForSRP();
-  ZeroSuggestProvider::ResultType result_type = ZeroSuggestProvider::NONE;
   EXPECT_TRUE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-      client_.get(), on_focus_srp_input, &result_type));
+      client_.get(), OnFocusInputForSRP()));
+  histogram_tester.ExpectBucketCount("Omnibox.ZeroSuggestProvider.Eligibility",
+                                     0 /*kEligible*/, 1);
 
-  histogram_tester.ExpectBucketCount("Omnibox.ZeroSuggest.Eligible.OnFocusV2",
-                                     0 /*ELIGIBLE*/, 1);
-
+  // Invalid URLs cannot be sent in the zero-suggest request.
   AutocompleteInput on_focus_srp_input_ineligible_url = OnFocusInputForSRP();
   on_focus_srp_input_ineligible_url.set_current_url(GURL("chrome://history"));
   EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-      client_.get(), on_focus_srp_input_ineligible_url, &result_type));
+      client_.get(), on_focus_srp_input_ineligible_url));
+  histogram_tester.ExpectBucketCount("Omnibox.ZeroSuggestProvider.Eligibility",
+                                     3 /*kGenerallyIneligible*/, 1);
 
-  histogram_tester.ExpectBucketCount("Omnibox.ZeroSuggest.Eligible.OnFocusV2",
-                                     1 /*URL_INELIGIBLE*/, 1);
-
-  // zero-suggest is not allowed for non-Google default search providers.
+  // Change the default search provider.
   TemplateURLService* template_url_service = client_->GetTemplateURLService();
   TemplateURLData data;
   data.SetURL("https://www.example.com/?q={searchTerms}");
@@ -388,31 +386,37 @@
       template_url_service->Add(std::make_unique<TemplateURL>(data));
   template_url_service->SetUserSelectedDefaultSearchProvider(
       other_search_provider);
+
+  // Zero-suggest is not allowed for non-Google default search providers.
   EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-      client_.get(), on_focus_srp_input, &result_type));
+      client_.get(), OnFocusInputForSRP()));
+  histogram_tester.ExpectBucketCount("Omnibox.ZeroSuggestProvider.Eligibility",
+                                     2 /*kRemoteSendURLIneligible*/, 1);
 
-  histogram_tester.ExpectBucketCount("Omnibox.ZeroSuggest.Eligible.OnFocusV2",
-                                     2 /*GENERALLY_INELIGIBLE*/, 1);
-
-  // zero-suggest is not allowed for non-empty inputs.
-  AutocompleteInput prefix_srp_input = PrefixInputForSRP();
+  // Zero-suggest is not allowed for non-Google default search providers.
   EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
-      client_.get(), prefix_srp_input, &result_type));
+      client_.get(), OnFocusInputForNTP()));
+  histogram_tester.ExpectBucketCount("Omnibox.ZeroSuggestProvider.Eligibility",
+                                     1 /*kRequestNoUrlIneligible*/, 1);
 
-  // The last case is not taken into account for eligibility metrics.
-  histogram_tester.ExpectTotalCount("Omnibox.ZeroSuggest.Eligible.OnFocusV2",
-                                    3);
+  // Zero-suggest is not allowed for non-empty inputs.
+  EXPECT_FALSE(ZeroSuggestProvider::AllowZeroPrefixSuggestions(
+      client_.get(), PrefixInputForSRP()));
+  histogram_tester.ExpectBucketCount("Omnibox.ZeroSuggestProvider.Eligibility",
+                                     3 /*kGenerallyIneligible*/, 2);
+
+  histogram_tester.ExpectTotalCount("Omnibox.ZeroSuggestProvider.Eligibility",
+                                    5);
 }
 
-TEST_F(ZeroSuggestProviderTest, TypeOfResultToRun_NTP) {
+TEST_F(ZeroSuggestProviderTest, ResultTypeToRun_NTP) {
   AutocompleteInput onfocus_ntp_input = OnFocusInputForNTP();
-  EXPECT_EQ(ZeroSuggestProvider::REMOTE_NO_URL,
-            ZeroSuggestProvider::TypeOfResultToRun(
-                client_.get(), onfocus_ntp_input,
-                /*bypass_request_eligibility_checks=*/true));
+  EXPECT_EQ(
+      ZeroSuggestProvider::ResultType::kRemoteNoURL,
+      ZeroSuggestProvider::ResultTypeToRun(client_.get(), onfocus_ntp_input));
 }
 
-TEST_F(ZeroSuggestProviderTest, TypeOfResultToRun_ContextualWeb) {
+TEST_F(ZeroSuggestProviderTest, ResultTypeToRun_ContextualWeb) {
   AutocompleteInput on_focus_input = OnFocusInputForWeb();
   AutocompleteInput on_clobber_input = OnClobberInputForWeb();
 
@@ -425,15 +429,13 @@
             omnibox::kFocusTriggersContextualWebZeroSuggest,
             omnibox::kClobberTriggersContextualWebZeroSuggest});
 
-    EXPECT_EQ(ZeroSuggestProvider::NONE,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_focus_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kNone,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_focus_input));
 
-    EXPECT_EQ(ZeroSuggestProvider::NONE,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_clobber_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kNone,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_clobber_input));
   }
   // Enable on-focus only.
   {
@@ -443,15 +445,13 @@
         /*disabled_features=*/{
             omnibox::kClobberTriggersContextualWebZeroSuggest});
 
-    EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_focus_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kRemoteSendURL,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_focus_input));
 
-    EXPECT_EQ(ZeroSuggestProvider::NONE,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_clobber_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kNone,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_clobber_input));
   }
   // Enable on-clobber only.
   {
@@ -462,15 +462,13 @@
         /*disabled_features=*/
         {omnibox::kFocusTriggersContextualWebZeroSuggest});
 
-    EXPECT_EQ(ZeroSuggestProvider::NONE,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_focus_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kNone,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_focus_input));
 
-    EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_clobber_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kRemoteSendURL,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_clobber_input));
   }
   // Enable on-focus and on-clobber.
   {
@@ -481,19 +479,17 @@
          omnibox::kClobberTriggersContextualWebZeroSuggest},
         /*disabled_features=*/{});
 
-    EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_focus_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kRemoteSendURL,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_focus_input));
 
-    EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_clobber_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kRemoteSendURL,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_clobber_input));
   }
 }
 
-TEST_F(ZeroSuggestProviderTest, TypeOfResultToRun_SRP) {
+TEST_F(ZeroSuggestProviderTest, ResultTypeToRun_SRP) {
   AutocompleteInput on_focus_input = OnFocusInputForSRP();
   AutocompleteInput on_clobber_input = OnClobberInputForSRP();
 
@@ -505,15 +501,13 @@
         /*disabled_features=*/{omnibox::kFocusTriggersSRPZeroSuggest,
                                omnibox::kClobberTriggersSRPZeroSuggest});
 
-    EXPECT_EQ(ZeroSuggestProvider::NONE,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_focus_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kNone,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_focus_input));
 
-    EXPECT_EQ(ZeroSuggestProvider::NONE,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_clobber_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kNone,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_clobber_input));
   }
   // Enable on-focus only.
   {
@@ -522,15 +516,13 @@
         /*enabled_features=*/{omnibox::kFocusTriggersSRPZeroSuggest},
         /*disabled_features=*/{omnibox::kClobberTriggersSRPZeroSuggest});
 
-    EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_focus_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kRemoteSendURL,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_focus_input));
 
-    EXPECT_EQ(ZeroSuggestProvider::NONE,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_clobber_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kNone,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_clobber_input));
   }
   // Enable on-clobber only.
   {
@@ -540,15 +532,13 @@
         /*disabled_features=*/
         {omnibox::kFocusTriggersSRPZeroSuggest});
 
-    EXPECT_EQ(ZeroSuggestProvider::NONE,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_focus_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kNone,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_focus_input));
 
-    EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_clobber_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kRemoteSendURL,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_clobber_input));
   }
   // Enable on-focus and on-clobber.
   {
@@ -559,15 +549,13 @@
          omnibox::kClobberTriggersSRPZeroSuggest},
         /*disabled_features=*/{});
 
-    EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_focus_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kRemoteSendURL,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_focus_input));
 
-    EXPECT_EQ(ZeroSuggestProvider::REMOTE_SEND_URL,
-              ZeroSuggestProvider::TypeOfResultToRun(
-                  client_.get(), on_clobber_input,
-                  /*bypass_request_eligibility_checks=*/true));
+    EXPECT_EQ(
+        ZeroSuggestProvider::ResultType::kRemoteSendURL,
+        ZeroSuggestProvider::ResultTypeToRun(client_.get(), on_clobber_input));
   }
 }
 
@@ -637,7 +625,7 @@
 
   AutocompleteInput input = OnFocusInputForNTP();
   provider_->Start(input, false);
-  ASSERT_EQ(ZeroSuggestProvider::REMOTE_NO_URL,
+  ASSERT_EQ(ZeroSuggestProvider::ResultType::kRemoteNoURL,
             provider_->GetResultTypeRunningForTesting());
 
   EXPECT_TRUE(provider_->matches().empty());
@@ -694,7 +682,7 @@
   GURL suggest_url = GetSuggestURL(metrics::OmniboxEventProto::NTP_REALBOX);
 
   provider_->Start(input, false);
-  ASSERT_EQ(ZeroSuggestProvider::REMOTE_NO_URL,
+  ASSERT_EQ(ZeroSuggestProvider::ResultType::kRemoteNoURL,
             provider_->GetResultTypeRunningForTesting());
   EXPECT_TRUE(provider_->done());
   EXPECT_TRUE(provider_->matches().empty());
@@ -723,7 +711,7 @@
 
   AutocompleteInput input = OnFocusInputForNTP();
   provider_->Start(input, false);
-  ASSERT_EQ(ZeroSuggestProvider::REMOTE_NO_URL,
+  ASSERT_EQ(ZeroSuggestProvider::ResultType::kRemoteNoURL,
             provider_->GetResultTypeRunningForTesting());
 
   // Expect that matches get populated synchronously out of the cache.
@@ -794,7 +782,7 @@
 
   AutocompleteInput input = OnFocusInputForNTP();
   provider_->Start(input, false);
-  ASSERT_EQ(ZeroSuggestProvider::REMOTE_NO_URL,
+  ASSERT_EQ(ZeroSuggestProvider::ResultType::kRemoteNoURL,
             provider_->GetResultTypeRunningForTesting());
 
   // Expect that matches get populated synchronously out of the cache.
@@ -917,7 +905,7 @@
     AutocompleteInput input = OnFocusInputForNTP();
     provider_->Start(input, false);
     EXPECT_FALSE(provider_->done());
-    ASSERT_EQ(ZeroSuggestProvider::REMOTE_NO_URL,
+    ASSERT_EQ(ZeroSuggestProvider::ResultType::kRemoteNoURL,
               provider_->GetResultTypeRunningForTesting());
 
     // Expect the results from the cached response.
diff --git a/components/omnibox/resources/omnibox_pedal_synonyms.grd_unused b/components/omnibox/resources/omnibox_pedal_synonyms.grd_unused
index 72c433c..1d7ebc2 100644
--- a/components/omnibox/resources/omnibox_pedal_synonyms.grd_unused
+++ b/components/omnibox/resources/omnibox_pedal_synonyms.grd_unused
@@ -41,7 +41,7 @@
       <output filename="omnibox_pedal_synonyms_zh-HK.pak" type="data_package" lang="zh-HK" />
       <output filename="omnibox_pedal_synonyms_zu.pak" type="data_package" lang="zu" />
     </if>
-    <if expr="chromeos_ash or chromeos_lacros">
+    <if expr="is_chromeos">
       <output filename="omnibox_pedal_synonyms_is.pak" type="data_package" lang="is" />
     </if>
     <output filename="omnibox_pedal_synonyms_am.pak" type="data_package" lang="am" />
diff --git a/components/printing/browser/headless/headless_print_manager.cc b/components/printing/browser/headless/headless_print_manager.cc
index 65d0697..f146b4c 100644
--- a/components/printing/browser/headless/headless_print_manager.cc
+++ b/components/printing/browser/headless/headless_print_manager.cc
@@ -4,27 +4,21 @@
 
 #include "components/printing/browser/headless/headless_print_manager.h"
 
-#include <utility>
-
-#include "base/bind.h"
-#include "build/build_config.h"
-#include "components/printing/browser/print_to_pdf/pdf_print_utils.h"
+#include "components/printing/browser/print_to_pdf/pdf_print_result.h"
 #include "printing/mojom/print.mojom.h"
-#include "printing/page_range.h"
-#include "third_party/abseil-cpp/absl/types/variant.h"
+#include "printing/printing_utils.h"
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
 #include "mojo/public/cpp/bindings/message.h"
 #endif
 
-using print_to_pdf::PdfPrintResult;
-
 namespace headless {
 
 namespace {
 
-#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
-constexpr char kUnexpectedPrintManagerCall[] = "Unexpected Print Manager call";
+#if BUILDFLAG(ENABLE_PRINT_PREVIEW) || BUILDFLAG(ENABLE_TAGGED_PDF)
+constexpr char kUnexpectedPrintManagerCall[] =
+    "Headless Print Manager: Unexpected Print Manager call";
 #endif
 
 }  // namespace
@@ -54,51 +48,10 @@
     content::RenderFrameHost* rfh,
     const std::string& page_ranges,
     printing::mojom::PrintPagesParamsPtr print_pages_params,
-    PrintToPdfCallback callback) {
-  DCHECK(callback);
-
-  if (print_to_pdf_callback_) {
-    std::move(callback).Run(PdfPrintResult::kSimultaneousPrintActive,
-                            base::MakeRefCounted<base::RefCountedString>());
-    return;
-  }
-
-  if (!rfh->IsRenderFrameLive()) {
-    std::move(callback).Run(PdfPrintResult::kPrintFailure,
-                            base::MakeRefCounted<base::RefCountedString>());
-    return;
-  }
-
-  absl::variant<printing::PageRanges, PdfPrintResult> parsed_ranges =
-      print_to_pdf::TextPageRangesToPageRanges(page_ranges);
-  if (absl::holds_alternative<PdfPrintResult>(parsed_ranges)) {
-    DCHECK_NE(absl::get<PdfPrintResult>(parsed_ranges),
-              PdfPrintResult::kPrintSuccess);
-    std::move(callback).Run(absl::get<PdfPrintResult>(parsed_ranges),
-                            base::MakeRefCounted<base::RefCountedString>());
-    return;
-  }
-
-  printing_rfh_ = rfh;
-  print_pages_params->pages = absl::get<printing::PageRanges>(parsed_ranges);
-  print_to_pdf_callback_ = std::move(callback);
-
-  // There is no need for a weak pointer here since the mojo proxy is held
-  // in the base class. If we're gone, mojo will discard the callback.
-  GetPrintRenderFrame(rfh)->PrintWithParams(
-      std::move(print_pages_params),
-      base::BindOnce(&HeadlessPrintManager::OnDidPrintWithParams,
-                     base::Unretained(this)));
-}
-
-void HeadlessPrintManager::RenderFrameDeleted(
-    content::RenderFrameHost* render_frame_host) {
-  PrintManager::RenderFrameDeleted(render_frame_host);
-
-  if (printing_rfh_ != render_frame_host)
-    return;
-
-  FailJob(PdfPrintResult::kPrintFailure);
+    print_to_pdf::PdfPrintJob::PrintToPdfCallback callback) {
+  print_to_pdf::PdfPrintJob::StartJob(
+      web_contents(), rfh, GetPrintRenderFrame(rfh), page_ranges,
+      std::move(print_pages_params), std::move(callback));
 }
 
 void HeadlessPrintManager::GetDefaultPrintSettings(
@@ -116,10 +69,6 @@
   std::move(callback).Run(std::move(default_param));
 }
 
-void HeadlessPrintManager::ShowInvalidPrinterSettingsError() {
-  FailJob(PdfPrintResult::kInvalidPrinterSettings);
-}
-
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
 void HeadlessPrintManager::UpdatePrintSettings(
     int32_t cookie,
@@ -161,59 +110,6 @@
 void HeadlessPrintManager::PdfWritingDone(int page_count) {}
 #endif
 
-void HeadlessPrintManager::OnDidPrintWithParams(
-    printing::mojom::PrintWithParamsResultPtr result) {
-  if (result->is_failure_reason()) {
-    switch (result->get_failure_reason()) {
-      case printing::mojom::PrintFailureReason::kGeneralFailure:
-        FailJob(PdfPrintResult::kPrintFailure);
-        return;
-      case printing::mojom::PrintFailureReason::kInvalidPageRange:
-        FailJob(PdfPrintResult::kPageCountExceeded);
-        return;
-    }
-  }
-
-  auto& content = *result->get_params()->content;
-  if (!content.metafile_data_region.IsValid()) {
-    FailJob(PdfPrintResult::kInvalidMemoryHandle);
-    return;
-  }
-
-  base::ReadOnlySharedMemoryMapping map = content.metafile_data_region.Map();
-  if (!map.IsValid()) {
-    FailJob(PdfPrintResult::kMetafileMapError);
-    return;
-  }
-
-  std::string data =
-      std::string(static_cast<const char*>(map.memory()), map.size());
-  std::move(print_to_pdf_callback_)
-      .Run(PdfPrintResult::kPrintSuccess,
-           base::RefCountedString::TakeString(&data));
-
-  Reset();
-}
-
-void HeadlessPrintManager::FailJob(PdfPrintResult result) {
-  DCHECK_NE(result, PdfPrintResult::kPrintSuccess);
-
-  if (print_to_pdf_callback_) {
-    std::move(print_to_pdf_callback_)
-        .Run(result, base::MakeRefCounted<base::RefCountedString>());
-  }
-
-  Reset();
-}
-
-void HeadlessPrintManager::Reset() {
-  printing_rfh_ = nullptr;
-
-  // The callback is supposed to be consumed at this point meaning we
-  // reported results to the PrintToPdf() caller.
-  CHECK(!print_to_pdf_callback_);
-}
-
 WEB_CONTENTS_USER_DATA_KEY_IMPL(HeadlessPrintManager);
 
 }  // namespace headless
diff --git a/components/printing/browser/headless/headless_print_manager.h b/components/printing/browser/headless/headless_print_manager.h
index a919903..4575697 100644
--- a/components/printing/browser/headless/headless_print_manager.h
+++ b/components/printing/browser/headless/headless_print_manager.h
@@ -7,13 +7,10 @@
 
 #include <memory>
 #include <string>
-#include <vector>
 
-#include "base/memory/raw_ptr.h"
-#include "base/memory/ref_counted_memory.h"
 #include "build/build_config.h"
 #include "components/printing/browser/print_manager.h"
-#include "components/printing/browser/print_to_pdf/pdf_print_result.h"
+#include "components/printing/browser/print_to_pdf/pdf_print_job.h"
 #include "components/printing/common/print.mojom.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents_observer.h"
@@ -29,10 +26,6 @@
     : public printing::PrintManager,
       public content::WebContentsUserData<HeadlessPrintManager> {
  public:
-  using PrintToPdfCallback =
-      base::OnceCallback<void(print_to_pdf::PdfPrintResult,
-                              scoped_refptr<base::RefCountedMemory>)>;
-
   ~HeadlessPrintManager() override;
 
   HeadlessPrintManager(const HeadlessPrintManager&) = delete;
@@ -46,22 +39,18 @@
   void PrintToPdf(content::RenderFrameHost* rfh,
                   const std::string& page_ranges,
                   printing::mojom::PrintPagesParamsPtr print_page_params,
-                  PrintToPdfCallback callback);
+                  print_to_pdf::PdfPrintJob::PrintToPdfCallback callback);
 
  private:
   friend class content::WebContentsUserData<HeadlessPrintManager>;
 
   explicit HeadlessPrintManager(content::WebContents* web_contents);
 
-  // WebContentsObserver overrides (via PrintManager):
-  void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
-
   // printing::mojom::PrintManagerHost:
   void GetDefaultPrintSettings(
       GetDefaultPrintSettingsCallback callback) override;
   void ScriptedPrint(printing::mojom::ScriptedPrintParamsPtr params,
                      ScriptedPrintCallback callback) override;
-  void ShowInvalidPrinterSettingsError() override;
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
   void UpdatePrintSettings(int32_t cookie,
                            base::Value::Dict job_settings,
@@ -84,14 +73,6 @@
   void PdfWritingDone(int page_count) override;
 #endif
 
-  void OnDidPrintWithParams(printing::mojom::PrintWithParamsResultPtr result);
-
-  void FailJob(print_to_pdf::PdfPrintResult result);
-  void Reset();
-
-  raw_ptr<content::RenderFrameHost> printing_rfh_ = nullptr;
-  PrintToPdfCallback print_to_pdf_callback_;
-
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 };
 
diff --git a/components/printing/browser/print_to_pdf/BUILD.gn b/components/printing/browser/print_to_pdf/BUILD.gn
index 394f173..85e01a8 100644
--- a/components/printing/browser/print_to_pdf/BUILD.gn
+++ b/components/printing/browser/print_to_pdf/BUILD.gn
@@ -9,6 +9,8 @@
 
 static_library("print_to_pdf") {
   sources = [
+    "pdf_print_job.cc",
+    "pdf_print_job.h",
     "pdf_print_result.cc",
     "pdf_print_result.h",
     "pdf_print_utils.cc",
@@ -18,6 +20,8 @@
   deps = [
     "//base",
     "//components/printing/browser",
+    "//components/services/print_compositor",
+    "//components/services/print_compositor/public/mojom",
     "//printing",
     "//printing/buildflags",
     "//printing/mojom",
diff --git a/components/printing/browser/print_to_pdf/pdf_print_job.cc b/components/printing/browser/print_to_pdf/pdf_print_job.cc
new file mode 100644
index 0000000..88bad6a
--- /dev/null
+++ b/components/printing/browser/print_to_pdf/pdf_print_job.cc
@@ -0,0 +1,156 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/printing/browser/print_to_pdf/pdf_print_job.h"
+
+#include "base/bind.h"
+#include "base/memory/read_only_shared_memory_region.h"
+#include "components/printing/browser/print_composite_client.h"
+#include "components/printing/browser/print_to_pdf/pdf_print_utils.h"
+#include "components/printing/common/print.mojom.h"
+#include "printing/mojom/print.mojom.h"
+#include "printing/page_range.h"
+#include "printing/printing_utils.h"
+#include "third_party/abseil-cpp/absl/types/variant.h"
+
+namespace print_to_pdf {
+
+PdfPrintJob::PdfPrintJob(content::WebContents* contents,
+                         content::RenderFrameHost* rfh,
+                         PrintToPdfCallback callback)
+    : content::WebContentsObserver(contents),
+      printing_rfh_(rfh),
+      print_to_pdf_callback_(std::move(callback)) {}
+
+PdfPrintJob::~PdfPrintJob() {
+  // The callback is supposed to be consumed at this point confirming
+  // that job result was reported to the job starter.
+  DCHECK(!print_to_pdf_callback_);
+}
+
+void PdfPrintJob::StartJob(
+    content::WebContents* contents,
+    content::RenderFrameHost* rfh,
+    const mojo::AssociatedRemote<printing::mojom::PrintRenderFrame>& remote,
+    const std::string& page_ranges,
+    printing::mojom::PrintPagesParamsPtr print_pages_params,
+    PrintToPdfCallback callback) {
+  DCHECK(callback);
+
+  if (!rfh->IsRenderFrameLive()) {
+    std::move(callback).Run(PdfPrintResult::kPrintFailure, nullptr);
+    return;
+  }
+
+  absl::variant<printing::PageRanges, PdfPrintResult> pages =
+      print_to_pdf::TextPageRangesToPageRanges(page_ranges);
+  if (absl::holds_alternative<PdfPrintResult>(pages)) {
+    std::move(callback).Run(absl::get<PdfPrintResult>(pages), nullptr);
+    return;
+  }
+
+  print_pages_params->pages = absl::get<printing::PageRanges>(pages);
+
+  // Job is self-owned and will delete itself when complete.
+  auto* job = new PdfPrintJob(contents, rfh, std::move(callback));
+  remote->PrintWithParams(std::move(print_pages_params),
+                          base::BindOnce(&PdfPrintJob::OnDidPrintWithParams,
+                                         job->weak_ptr_factory_.GetWeakPtr()));
+}
+
+void PdfPrintJob::OnDidPrintWithParams(
+    printing::mojom::PrintWithParamsResultPtr result) {
+  if (result->is_failure_reason()) {
+    switch (result->get_failure_reason()) {
+      case printing::mojom::PrintFailureReason::kGeneralFailure:
+        FailJob(PdfPrintResult::kPrintFailure);
+        return;
+      case printing::mojom::PrintFailureReason::kInvalidPageRange:
+        FailJob(PdfPrintResult::kPageCountExceeded);
+        return;
+    }
+  }
+
+  printing::mojom::DidPrintDocumentParamsPtr& params = result->get_params();
+
+  auto& content = *params->content;
+  auto& region = content.metafile_data_region;
+  if (!region.IsValid()) {
+    FailJob(PdfPrintResult::kInvalidSharedMemoryRegion);
+    return;
+  }
+
+  // If the printed data already looks like a PDF, report it now.
+  if (printing::LooksLikePdf(region.Map().GetMemoryAsSpan<char>())) {
+    ReportMemoryRegion(region);
+    return;
+  }
+
+  // Otherwise assume this is a composite document and invoke compositor.
+  printing::PrintCompositeClient::FromWebContents(web_contents())
+      ->DoCompositeDocumentToPdf(
+          params->document_cookie, printing_rfh_, content,
+          base::BindOnce(&PdfPrintJob::OnCompositeDocumentToPdfDone,
+                         weak_ptr_factory_.GetWeakPtr(), params->page_size,
+                         params->content_area, params->physical_offsets));
+}
+
+void PdfPrintJob::OnCompositeDocumentToPdfDone(
+    const gfx::Size& page_size,
+    const gfx::Rect& content_area,
+    const gfx::Point& physical_offsets,
+    printing::mojom::PrintCompositor::Status status,
+    base::ReadOnlySharedMemoryRegion region) {
+  if (status != printing::mojom::PrintCompositor::Status::kSuccess) {
+    DLOG(ERROR) << "Compositing pdf failed with error " << status;
+    FailJob(PdfPrintResult::kPrintFailure);
+    return;
+  }
+
+  if (!region.IsValid()) {
+    FailJob(PdfPrintResult::kInvalidSharedMemoryRegion);
+    return;
+  }
+
+  ReportMemoryRegion(region);
+}
+
+void PdfPrintJob::ReportMemoryRegion(
+    const base::ReadOnlySharedMemoryRegion& region) {
+  DCHECK(region.IsValid());
+  DCHECK(printing::LooksLikePdf(region.Map().GetMemoryAsSpan<char>()));
+
+  base::ReadOnlySharedMemoryMapping mapping = region.Map();
+  if (!mapping.IsValid()) {
+    FailJob(PdfPrintResult::kInvalidSharedMemoryMapping);
+    return;
+  }
+
+  std::string data =
+      std::string(static_cast<const char*>(mapping.memory()), mapping.size());
+  std::move(print_to_pdf_callback_)
+      .Run(PdfPrintResult::kPrintSuccess,
+           base::RefCountedString::TakeString(&data));
+
+  delete this;
+}
+
+void PdfPrintJob::FailJob(PdfPrintResult result) {
+  DCHECK_NE(result, PdfPrintResult::kPrintSuccess);
+  DCHECK(print_to_pdf_callback_);
+
+  std::move(print_to_pdf_callback_).Run(result, nullptr);
+
+  delete this;
+}
+
+void PdfPrintJob::RenderFrameDeleted(
+    content::RenderFrameHost* render_frame_host) {
+  if (render_frame_host != printing_rfh_)
+    return;
+
+  FailJob(PdfPrintResult::kPrintFailure);
+}
+
+}  // namespace print_to_pdf
diff --git a/components/printing/browser/print_to_pdf/pdf_print_job.h b/components/printing/browser/print_to_pdf/pdf_print_job.h
new file mode 100644
index 0000000..ee85e7c
--- /dev/null
+++ b/components/printing/browser/print_to_pdf/pdf_print_job.h
@@ -0,0 +1,81 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PRINTING_BROWSER_PRINT_TO_PDF_PDF_PRINT_JOB_H_
+#define COMPONENTS_PRINTING_BROWSER_PRINT_TO_PDF_PDF_PRINT_JOB_H_
+
+#include <string>
+
+#include "base/memory/raw_ptr.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/memory/weak_ptr.h"
+#include "components/printing/browser/print_to_pdf/pdf_print_result.h"
+#include "components/printing/common/print.mojom-forward.h"
+#include "components/services/print_compositor/public/mojom/print_compositor.mojom.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace base {
+class ReadOnlySharedMemoryRegion;
+}
+
+namespace print_to_pdf {
+
+class PdfPrintJob : public content::WebContentsObserver {
+ public:
+  using PrintToPdfCallback =
+      base::OnceCallback<void(PdfPrintResult,
+                              scoped_refptr<base::RefCountedMemory>)>;
+
+  PdfPrintJob(const PdfPrintJob&) = delete;
+  PdfPrintJob& operator=(const PdfPrintJob&) = delete;
+
+  // Starts a PDF print job for the specified web contents that
+  // prints the current document pages specified by `page_ranges` with
+  // parameters, specified by `print_pages_params` into a PDF document,
+  // returned with `callback`. If `page_ranges` is empty, the entire
+  // document is printed.
+  //
+  // The job will delete itself when complete.
+  static void StartJob(
+      content::WebContents* contents,
+      content::RenderFrameHost* rfh,
+      const mojo::AssociatedRemote<printing::mojom::PrintRenderFrame>& remote,
+      const std::string& page_ranges,
+      printing::mojom::PrintPagesParamsPtr print_pages_params,
+      PrintToPdfCallback callback);
+
+ private:
+  PdfPrintJob(content::WebContents* contents,
+              content::RenderFrameHost* rfh,
+              PrintToPdfCallback callback);
+  ~PdfPrintJob() override;
+
+  // WebContentsObserver overrides:
+  void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
+
+  void OnDidPrintWithParams(printing::mojom::PrintWithParamsResultPtr result);
+  void OnCompositeDocumentToPdfDone(
+      const gfx::Size& page_size,
+      const gfx::Rect& content_area,
+      const gfx::Point& physical_offsets,
+      printing::mojom::PrintCompositor::Status status,
+      base::ReadOnlySharedMemoryRegion region);
+
+  void ReportMemoryRegion(const base::ReadOnlySharedMemoryRegion& region);
+  void FailJob(print_to_pdf::PdfPrintResult result);
+
+  raw_ptr<content::RenderFrameHost> printing_rfh_;
+  PrintToPdfCallback print_to_pdf_callback_;
+
+  base::WeakPtrFactory<PdfPrintJob> weak_ptr_factory_{this};
+};
+
+}  // namespace print_to_pdf
+
+#endif  // COMPONENTS_PRINTING_BROWSER_PRINT_TO_PDF_PDF_PRINT_JOB_H_
diff --git a/components/printing/browser/print_to_pdf/pdf_print_result.cc b/components/printing/browser/print_to_pdf/pdf_print_result.cc
index 8f6fc9e..d51c6df 100644
--- a/components/printing/browser/print_to_pdf/pdf_print_result.cc
+++ b/components/printing/browser/print_to_pdf/pdf_print_result.cc
@@ -14,12 +14,10 @@
       return "Printing failed";
     case PdfPrintResult::kInvalidPrinterSettings:
       return "Show invalid printer settings error";
-    case PdfPrintResult::kInvalidMemoryHandle:
-      return "Invalid memory handle";
-    case PdfPrintResult::kMetafileMapError:
-      return "Map to shared memory error";
-    case PdfPrintResult::kSimultaneousPrintActive:
-      return "The previous printing job hasn't finished";
+    case PdfPrintResult::kInvalidSharedMemoryRegion:
+      return "Invalid shared memory region";
+    case PdfPrintResult::kInvalidSharedMemoryMapping:
+      return "Invalid shared memory mapping";
     case PdfPrintResult::kPageRangeSyntaxError:
       return "Page range syntax error";
     case PdfPrintResult::kPageRangeInvalidRange:
diff --git a/components/printing/browser/print_to_pdf/pdf_print_result.h b/components/printing/browser/print_to_pdf/pdf_print_result.h
index 85395b2..e650918 100644
--- a/components/printing/browser/print_to_pdf/pdf_print_result.h
+++ b/components/printing/browser/print_to_pdf/pdf_print_result.h
@@ -13,9 +13,8 @@
   kPrintSuccess,
   kPrintFailure,
   kInvalidPrinterSettings,
-  kInvalidMemoryHandle,
-  kMetafileMapError,
-  kSimultaneousPrintActive,
+  kInvalidSharedMemoryRegion,
+  kInvalidSharedMemoryMapping,
   kPageRangeSyntaxError,
   kPageRangeInvalidRange,
   kPageCountExceeded,
diff --git a/components/send_tab_to_self/send_tab_to_self_bridge.cc b/components/send_tab_to_self/send_tab_to_self_bridge.cc
index 8d9ec885..9575b66 100644
--- a/components/send_tab_to_self/send_tab_to_self_bridge.cc
+++ b/components/send_tab_to_self/send_tab_to_self_bridge.cc
@@ -14,6 +14,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/observer_list.h"
 #include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/time/clock.h"
 #include "base/time/time.h"
 #include "components/history/core/browser/history_service.h"
@@ -303,7 +304,8 @@
   std::string trimmed_title = "";
 
   if (base::IsStringUTF8(title)) {
-    trimmed_title = base::CollapseWhitespaceASCII(title, false);
+    trimmed_title = base::UTF16ToUTF8(
+        base::CollapseWhitespace(base::UTF8ToUTF16(title), false));
   }
 
   auto entry = std::make_unique<SendTabToSelfEntry>(
diff --git a/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc b/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc
index 9074c81c..f511e5b6 100644
--- a/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc
+++ b/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc
@@ -919,6 +919,18 @@
   EXPECT_FALSE(bridge()->HasValidTargetDevice());
 }
 
+TEST_F(SendTabToSelfBridgeTest, CollapseWhitespacesOfEntryTitle) {
+  InitializeBridge();
+
+  const SendTabToSelfEntry* result =
+      bridge()->AddEntry(GURL("http://a.com"), " a  b ", kLocalDeviceCacheGuid);
+  EXPECT_EQ("a b", result->GetTitle());
+
+  result =
+      bridge()->AddEntry(GURL("http://b.com"), "ìž…", kLocalDeviceCacheGuid);
+  EXPECT_EQ("ìž…", result->GetTitle());
+}
+
 }  // namespace
 
 }  // namespace send_tab_to_self
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index f4b35e6..4deaffe 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -2712,18 +2712,24 @@
     ]
   }
 
-  # TODO(crbug.com/1306610): Split out files that only need `enable_plugins`.
-  if (enable_ppapi) {
+  if (enable_plugins) {
     sources += [
       "../public/browser/plugin_service.h",
-      "media/session/pepper_playback_observer.cc",
-      "media/session/pepper_playback_observer.h",
-      "media/session/pepper_player_delegate.cc",
-      "media/session/pepper_player_delegate.h",
       "plugin_list.cc",
       "plugin_list.h",
       "plugin_service_impl.cc",
       "plugin_service_impl.h",
+      "renderer_host/plugin_registry_impl.cc",
+      "renderer_host/plugin_registry_impl.h",
+    ]
+  }
+
+  if (enable_ppapi) {
+    sources += [
+      "media/session/pepper_playback_observer.cc",
+      "media/session/pepper_playback_observer.h",
+      "media/session/pepper_player_delegate.cc",
+      "media/session/pepper_player_delegate.h",
       "ppapi_plugin_process_host.cc",
       "ppapi_plugin_process_host.h",
       "ppapi_plugin_process_host_receiver_bindings.cc",
@@ -2773,8 +2779,6 @@
       "renderer_host/pepper/pepper_udp_socket_message_filter.h",
       "renderer_host/pepper/quota_reservation.cc",
       "renderer_host/pepper/quota_reservation.h",
-      "renderer_host/plugin_registry_impl.cc",
-      "renderer_host/plugin_registry_impl.h",
     ]
     deps += [
       "//ppapi/host",
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc
index dc37e11..43ed99b 100644
--- a/content/browser/devtools/devtools_instrumentation.cc
+++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -318,10 +318,12 @@
 
 void DidCancelPrerender(const GURL& prerendering_url,
                         FrameTreeNode* ftn,
-                        PrerenderHost::FinalStatus status) {
+                        PrerenderHost::FinalStatus status,
+                        const std::string& reason_details) {
   std::string initiating_frame_id = ftn->devtools_frame_token().ToString();
   DispatchToAgents(ftn, &protocol::PageHandler::DidCancelPrerender,
-                   prerendering_url, initiating_frame_id, status);
+                   prerendering_url, initiating_frame_id, status,
+                   reason_details);
 }
 
 namespace {
diff --git a/content/browser/devtools/devtools_instrumentation.h b/content/browser/devtools/devtools_instrumentation.h
index 89885a6..f45ab26 100644
--- a/content/browser/devtools/devtools_instrumentation.h
+++ b/content/browser/devtools/devtools_instrumentation.h
@@ -174,9 +174,15 @@
     const BackForwardCacheCanStoreTreeResult* tree_result);
 
 void DidActivatePrerender(const NavigationRequest& nav_request);
+
+// This function reports cancellation status to DevTools with the
+// `reason_details`, which is used to give users more information about the
+// cancellation details, and reason_details will be formatted for display in
+// the DevTools. See the DevTools implementation for the format.
 void DidCancelPrerender(const GURL& prerendering_url,
                         FrameTreeNode* ftn,
-                        PrerenderHost::FinalStatus status);
+                        PrerenderHost::FinalStatus status,
+                        const std::string& reason_details);
 
 void OnSignedExchangeReceived(
     FrameTreeNode* frame_tree_node,
diff --git a/content/browser/devtools/devtools_issue_storage_browsertest.cc b/content/browser/devtools/devtools_issue_storage_browsertest.cc
index 333d3c6..f79d858 100644
--- a/content/browser/devtools/devtools_issue_storage_browsertest.cc
+++ b/content/browser/devtools/devtools_issue_storage_browsertest.cc
@@ -76,7 +76,7 @@
   // Report an empty SameSite cookie issue.
   ReportDummyIssue(main_frame_host());
   Attach();
-  SendCommand("Audits.enable", std::make_unique<base::DictionaryValue>());
+  SendCommandSync("Audits.enable");
   // Verify we have received the SameSite issue.
   WaitForDummyIssueNotification();
 }
@@ -85,7 +85,7 @@
                        DevToolsReceivesBrowserIssuesWhileAttached) {
   EXPECT_TRUE(NavigateToURL(shell(), GURL("about:blank")));
   Attach();
-  SendCommand("Audits.enable", std::make_unique<base::DictionaryValue>());
+  SendCommandSync("Audits.enable");
   // Report an empty SameSite cookie issue.
   ReportDummyIssue(main_frame_host());
   // Verify we have received the SameSite issue.
@@ -115,7 +115,7 @@
 
   // 4) Open DevTools and enable Audits domain.
   Attach();
-  SendCommand("Audits.enable", std::make_unique<base::DictionaryValue>());
+  SendCommandSync("Audits.enable");
 
   // 5) Verify we have received the SameSite issue on the main target.
   WaitForDummyIssueNotification();
@@ -136,7 +136,7 @@
 
   // 4) Open DevTools and enable Audits domain.
   Attach();
-  SendCommand("Audits.enable", std::make_unique<base::DictionaryValue>());
+  SendCommandSync("Audits.enable");
 
   // 5) Verify that we haven't received any notifications.
   ASSERT_FALSE(HasExistingNotification());
@@ -184,7 +184,7 @@
 
   // 5) Open DevTools and enable Audits domain.
   Attach();
-  SendCommand("Audits.enable", std::make_unique<base::DictionaryValue>());
+  SendCommandSync("Audits.enable");
 
   // 6) Verify we have received the SameSite issue on the main target.
   WaitForDummyIssueNotification();
@@ -234,7 +234,7 @@
 
   // 5) Open DevTools and enable Audits domain.
   Attach();
-  SendCommand("Audits.enable", std::make_unique<base::DictionaryValue>());
+  SendCommandSync("Audits.enable");
 
   // 6) Verify we have received the SameSite issue on the main target.
   WaitForDummyIssueNotification();
@@ -277,7 +277,7 @@
 
   // 5) Open DevTools and enable Audits domain.
   Attach();
-  SendCommand("Audits.enable", std::make_unique<base::DictionaryValue>());
+  SendCommandSync("Audits.enable");
 
   // 6) Verify we have received the SameSite issue on the main target.
   WaitForDummyIssueNotification();
diff --git a/content/browser/devtools/devtools_trust_token_browsertest.cc b/content/browser/devtools/devtools_trust_token_browsertest.cc
index caebdfb..02d62ac 100644
--- a/content/browser/devtools/devtools_trust_token_browsertest.cc
+++ b/content/browser/devtools/devtools_trust_token_browsertest.cc
@@ -33,7 +33,7 @@
 
   // The returned view is only valid until the next |SendCommand| call.
   base::Value::ConstListView GetTrustTokensViaProtocol() {
-    SendCommand("Storage.getTrustTokens", nullptr);
+    SendCommandSync("Storage.getTrustTokens");
     const base::Value* tokens = result()->Find("tokens");
     CHECK(tokens);
     return tokens->GetListDeprecated();
@@ -80,7 +80,7 @@
 
   // 2) Open DevTools and enable Network domain.
   Attach();
-  SendCommand("Network.enable", std::make_unique<base::DictionaryValue>());
+  SendCommandSync("Network.enable");
 
   // Make sure there are no existing DevTools events in the queue.
   EXPECT_FALSE(HasExistingNotification());
@@ -142,7 +142,7 @@
 
   // Open DevTools and enable Network domain.
   Attach();
-  SendCommand("Network.enable", std::make_unique<base::DictionaryValue>());
+  SendCommandSync("Network.enable");
 
   // Make sure there are no existing DevTools events in the queue.
   EXPECT_FALSE(HasExistingNotification());
@@ -201,7 +201,7 @@
 
   // 2) Open DevTools and enable Network domain.
   Attach();
-  SendCommand("Network.enable", std::make_unique<base::DictionaryValue>());
+  SendCommandSync("Network.enable");
 
   // 3) Request and redeem a token, then use the redeemed token in a Signing
   // request.
@@ -238,7 +238,7 @@
 
   // 2) Open DevTools and enable Network domain.
   Attach();
-  SendCommand("Network.enable", std::make_unique<base::DictionaryValue>());
+  SendCommandSync("Network.enable");
 
   // 3) Request and redeem a token, then use the redeemed token in a Signing
   // request.
@@ -288,7 +288,7 @@
 
   // 2) Open DevTools and enable Network domain.
   Attach();
-  SendCommand("Network.enable", std::make_unique<base::DictionaryValue>());
+  SendCommandSync("Network.enable");
 
   // 3) Request some Trust Tokens.
   EXPECT_EQ("OperationError", EvalJs(shell(), R"(fetch('/issue',
@@ -354,9 +354,9 @@
   AssertTrustTokensViaProtocol(IssuanceOriginFromHost("a.test"), 10);
 
   // 5) Call Storage.clearTrustTokens
-  auto params = std::make_unique<base::DictionaryValue>();
-  params->SetStringPath("issuerOrigin", IssuanceOriginFromHost("a.test"));
-  auto* result = SendCommand("Storage.clearTrustTokens", std::move(params));
+  base::Value::Dict params;
+  params.Set("issuerOrigin", IssuanceOriginFromHost("a.test"));
+  auto* result = SendCommandSync("Storage.clearTrustTokens", std::move(params));
 
   EXPECT_THAT(result->FindBool("didDeleteTokens"), ::testing::Optional(true));
 
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
index 06a7ac2..b5c7288c 100644
--- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
+++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -187,16 +187,48 @@
                     int nativeKeyCode,
                     const std::string& key,
                     bool wait) {
-    std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-    params->SetStringKey("type", type);
-    params->SetIntKey("modifiers", modifier);
-    params->SetIntKey("windowsVirtualKeyCode", windowsKeyCode);
-    params->SetIntKey("nativeVirtualKeyCode", nativeKeyCode);
-    params->SetStringKey("key", key);
+    base::Value::Dict params;
+    params.Set("type", type);
+    params.Set("modifiers", modifier);
+    params.Set("windowsVirtualKeyCode", windowsKeyCode);
+    params.Set("nativeVirtualKeyCode", nativeKeyCode);
+    params.Set("key", key);
     SendCommand("Input.dispatchKeyEvent", std::move(params), wait);
   }
 };
 
+class PrerenderDevToolsProtocolTest : public DevToolsProtocolTest {
+ public:
+  PrerenderDevToolsProtocolTest() {
+    prerender_helper_ = std::make_unique<test::PrerenderTestHelper>(
+        base::BindRepeating(&PrerenderDevToolsProtocolTest::web_contents,
+                            base::Unretained(this)));
+  }
+
+  GURL GetUrl(const std::string& path) {
+    return embedded_test_server()->GetURL("a.test", path);
+  }
+
+  bool HasHostForUrl(const GURL& url) {
+    int host_id = prerender_helper_->GetHostForUrl(url);
+    return host_id != RenderFrameHost::kNoFrameTreeNodeId;
+  }
+
+  int AddPrerender(const GURL& prerendering_url) {
+    return prerender_helper_->AddPrerender(prerendering_url);
+  }
+
+  RenderFrameHostImpl* GetPrerenderedMainFrameHost(int host_id) {
+    return static_cast<RenderFrameHostImpl*>(
+        prerender_helper_->GetPrerenderedMainFrameHost(host_id));
+  }
+
+ private:
+  WebContents* web_contents() const { return shell()->web_contents(); }
+
+  std::unique_ptr<test::PrerenderTestHelper> prerender_helper_;
+};
+
 class SyntheticMouseEventTest : public DevToolsProtocolTest {
  public:
   SyntheticMouseEventTest() {
@@ -215,13 +247,13 @@
                       int y,
                       const std::string& button,
                       bool wait) {
-    std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-    params->SetStringKey("type", type);
-    params->SetIntKey("x", x);
-    params->SetIntKey("y", y);
+    base::Value::Dict params;
+    params.Set("type", type);
+    params.Set("x", x);
+    params.Set("y", y);
     if (!button.empty()) {
-      params->SetStringKey("button", button);
-      params->SetIntKey("clickCount", 1);
+      params.Set("button", button);
+      params.Set("clickCount", 1);
     }
     SendCommand("Input.dispatchMouseEvent", std::move(params), wait);
   }
@@ -291,7 +323,7 @@
                                      ->GetWidget()),
       blink::WebInputEvent::Type::kRawKeyDown);
 
-  SendCommand("Debugger.enable", nullptr);
+  SendCommandSync("Debugger.enable");
   SendKeyEvent("rawKeyDown", 0, 13, 13, "Enter", false);
 
   // We expect that the debugger message event arrives *before* the input
@@ -300,7 +332,7 @@
   EXPECT_FALSE(filter->HasReceivedAck());
   EXPECT_EQ(1, received_responses_count());
 
-  SendCommand("Debugger.resume", nullptr);
+  SendCommandSync("Debugger.resume");
   filter->WaitForAck();
   EXPECT_EQ(3, received_responses_count());
 }
@@ -321,7 +353,7 @@
                                      ->GetWidget()),
       blink::WebInputEvent::Type::kMouseDown);
 
-  SendCommand("Debugger.enable", nullptr);
+  SendCommandSync("Debugger.enable");
   SendMouseEvent("mousePressed", 15, 15, "left", false);
 
   // We expect that the debugger message event arrives *before* the input
@@ -331,7 +363,7 @@
   EXPECT_FALSE(filter->HasReceivedAck());
   EXPECT_EQ(1, received_responses_count());
 
-  SendCommand("Debugger.resume", nullptr);
+  SendCommandSync("Debugger.resume");
   filter->WaitForAck();
   EXPECT_EQ(3, received_responses_count());
 }
@@ -356,7 +388,7 @@
   GURL test_url = embedded_test_server()->GetURL("/devtools/zoom.html");
   NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
   Attach();
-  SendCommand("Page.enable", nullptr, true);
+  SendCommandSync("Page.enable");
   InitMouseDownLog();
 
   HostZoomMap* host_zoom_map =
@@ -488,23 +520,23 @@
       float clip_scale = 0,
       bool capture_beyond_viewport = false,
       bool expect_error = false) {
-    std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-    params->SetStringKey("format", EncodingEnumToString(encoding));
-    params->SetIntKey("quality", 100);
-    params->SetBoolKey("fromSurface", from_surface);
+    base::Value::Dict params;
+    params.Set("format", EncodingEnumToString(encoding));
+    params.Set("quality", 100);
+    params.Set("fromSurface", from_surface);
     if (capture_beyond_viewport) {
-      params->SetBoolKey("captureBeyondViewport", true);
+      params.Set("captureBeyondViewport", true);
     }
     if (clip_scale) {
-      base::Value clip_value(base::Value::Type::DICTIONARY);
-      clip_value.SetDoubleKey("x", clip.x());
-      clip_value.SetDoubleKey("y", clip.y());
-      clip_value.SetDoubleKey("width", clip.width());
-      clip_value.SetDoubleKey("height", clip.height());
-      clip_value.SetDoubleKey("scale", clip_scale);
-      params->SetKey("clip", std::move(clip_value));
+      base::Value::Dict clip_value;
+      clip_value.Set("x", clip.x());
+      clip_value.Set("y", clip.y());
+      clip_value.Set("width", clip.width());
+      clip_value.Set("height", clip.height());
+      clip_value.Set("scale", clip_scale);
+      params.Set("clip", std::move(clip_value));
     }
-    SendCommand("Page.captureScreenshot", std::move(params));
+    SendCommandSync("Page.captureScreenshot", std::move(params));
 
     std::unique_ptr<SkBitmap> result_bitmap;
     if (expect_error && error()) {
@@ -562,7 +594,7 @@
     static const int kBoxOffsetHeight = 100;
     const gfx::Size scaled_box_size =
         ScaleToFlooredSize(box_size, screenshot_scale);
-    std::unique_ptr<base::DictionaryValue> params;
+    base::Value::Dict params;
 
     VLOG(1) << "Testing screenshot of box with size " << box_size.width() << "x"
             << box_size.height() << "px at scale " << screenshot_scale
@@ -586,12 +618,12 @@
     // change during screenshotting. This verifies that the page doesn't observe
     // a change in frame size as a side effect of screenshotting.
 
-    params = std::make_unique<base::DictionaryValue>();
-    params->SetIntKey("width", frame_size.width());
-    params->SetIntKey("height", frame_size.height());
-    params->SetDoubleKey("deviceScaleFactor", device_scale_factor);
-    params->SetBoolKey("mobile", false);
-    SendCommand("Emulation.setDeviceMetricsOverride", std::move(params));
+    params = base::Value::Dict();
+    params.Set("width", frame_size.width());
+    params.Set("height", frame_size.height());
+    params.Set("deviceScaleFactor", device_scale_factor);
+    params.Set("mobile", false);
+    SendCommandSync("Emulation.setDeviceMetricsOverride", std::move(params));
 
     // Resize frame to scaled blue box size.
     gfx::RectF clip;
@@ -619,7 +651,7 @@
                                   screenshot_scale);
 
     // Reset for next screenshot.
-    SendCommand("Emulation.clearDeviceMetricsOverride", nullptr);
+    SendCommandSync("Emulation.clearDeviceMetricsOverride");
   }
 
   bool IsTrusted() override { return is_trusted_; }
@@ -766,15 +798,15 @@
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
   Attach();
 
-  auto params = std::make_unique<base::DictionaryValue>();
-  params->SetIntKey("width", 1280);
-  params->SetIntKey("height", 8440);
-  params->SetDoubleKey("deviceScaleFactor", 1);
-  params->SetBoolKey("mobile", false);
-  SendCommand("Emulation.setDeviceMetricsOverride", std::move(params));
+  auto params = base::Value::Dict();
+  params.Set("width", 1280);
+  params.Set("height", 8440);
+  params.Set("deviceScaleFactor", 1);
+  params.Set("mobile", false);
+  SendCommandSync("Emulation.setDeviceMetricsOverride", std::move(params));
   auto bitmap = CaptureScreenshot(ScreenshotEncoding::PNG, true,
                                   gfx::RectF(0, 0, 1280, 8440), 1);
-  SendCommand("Emulation.clearDeviceMetricsOverride", nullptr);
+  SendCommandSync("Emulation.clearDeviceMetricsOverride");
 
   EXPECT_EQ(1280, bitmap->width());
   EXPECT_EQ(8440, bitmap->height());
@@ -823,14 +855,15 @@
   Attach();
 
   // Override background to blue.
-  base::DictionaryValue color;
-  color.SetIntKey("r", 0x00);
-  color.SetIntKey("g", 0x00);
-  color.SetIntKey("b", 0xff);
-  color.SetDoubleKey("a", 1.0);
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-  params->SetKey("color", std::move(color));
-  SendCommand("Emulation.setDefaultBackgroundColorOverride", std::move(params));
+  base::Value::Dict color;
+  color.Set("r", 0x00);
+  color.Set("g", 0x00);
+  color.Set("b", 0xff);
+  color.Set("a", 1.0);
+  base::Value::Dict params;
+  params.Set("color", std::move(color));
+  SendCommandSync("Emulation.setDefaultBackgroundColorOverride",
+                  std::move(params));
 
   SkBitmap expected_bitmap;
   // We compare against the actual physical backing size rather than the
@@ -845,8 +878,7 @@
 
   // Tests that resetting Emulation.setDefaultBackgroundColorOverride
   // clears the background color override.
-  SendCommand("Emulation.setDefaultBackgroundColorOverride",
-              std::make_unique<base::DictionaryValue>());
+  SendCommandSync("Emulation.setDefaultBackgroundColorOverride");
   expected_bitmap.eraseColor(SK_ColorWHITE);
   CaptureScreenshotAndCompareTo(expected_bitmap, ScreenshotEncoding::PNG, true);
 }
@@ -863,17 +895,18 @@
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
   Attach();
 
-  auto params = std::make_unique<base::DictionaryValue>();
+  auto params = base::Value::Dict();
   {
     // Override background to fully transparent.
-    base::Value color(base::Value::Type::DICTIONARY);
-    color.SetIntKey("r", 0);
-    color.SetIntKey("g", 0);
-    color.SetIntKey("b", 0);
-    color.SetDoubleKey("a", 0);
-    params->SetKey("color", std::move(color));
+    base::Value::Dict color;
+    color.Set("r", 0);
+    color.Set("g", 0);
+    color.Set("b", 0);
+    color.Set("a", 0);
+    params.Set("color", std::move(color));
   }
-  SendCommand("Emulation.setDefaultBackgroundColorOverride", std::move(params));
+  SendCommandSync("Emulation.setDefaultBackgroundColorOverride",
+                  std::move(params));
 
   SkBitmap expected_bitmap;
   // We compare against the actual physical backing size rather than the
@@ -891,45 +924,46 @@
       display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
 
   // Check that device emulation does not affect the transparency.
-  params = std::make_unique<base::DictionaryValue>();
-  params->SetIntKey("width", view_size.width());
-  params->SetIntKey("height", view_size.height());
-  params->SetDoubleKey("deviceScaleFactor", 0);
-  params->SetBoolKey("mobile", false);
-  params->SetBoolKey("fitWindow", false);
-  SendCommand("Emulation.setDeviceMetricsOverride", std::move(params));
+  params = base::Value::Dict();
+  params.Set("width", view_size.width());
+  params.Set("height", view_size.height());
+  params.Set("deviceScaleFactor", 0);
+  params.Set("mobile", false);
+  params.Set("fitWindow", false);
+  SendCommandSync("Emulation.setDeviceMetricsOverride", std::move(params));
   CaptureScreenshotAndCompareTo(expected_bitmap, ScreenshotEncoding::PNG, true,
                                 device_scale_factor);
-  SendCommand("Emulation.clearDeviceMetricsOverride", nullptr);
+  SendCommandSync("Emulation.clearDeviceMetricsOverride");
 #endif  // !BUILDFLAG(IS_ANDROID)
 
   {
     // Override background to a semi-transparent color.
-    base::Value color(base::Value::Type::DICTIONARY);
-    color.SetIntKey("r", 255);
-    color.SetIntKey("g", 0);
-    color.SetIntKey("b", 0);
-    color.SetDoubleKey("a", 1.0 / 255 * 16);
-    params = std::make_unique<base::DictionaryValue>();
-    params->SetKey("color", std::move(color));
+    base::Value::Dict color;
+    color.Set("r", 255);
+    color.Set("g", 0);
+    color.Set("b", 0);
+    color.Set("a", 1.0 / 255 * 16);
+    params = base::Value::Dict();
+    params.Set("color", std::move(color));
   }
-  SendCommand("Emulation.setDefaultBackgroundColorOverride", std::move(params));
+  SendCommandSync("Emulation.setDefaultBackgroundColorOverride",
+                  std::move(params));
 
   expected_bitmap.eraseColor(SkColorSetARGB(16, 255, 0, 0));
   CaptureScreenshotAndCompareTo(expected_bitmap, ScreenshotEncoding::PNG, true);
 
 #if !BUILDFLAG(IS_ANDROID)
   // Check that device emulation does not affect the transparency.
-  params = std::make_unique<base::DictionaryValue>();
-  params->SetIntKey("width", view_size.width());
-  params->SetIntKey("height", view_size.height());
-  params->SetDoubleKey("deviceScaleFactor", 0);
-  params->SetBoolKey("mobile", false);
-  params->SetBoolKey("fitWindow", false);
-  SendCommand("Emulation.setDeviceMetricsOverride", std::move(params));
+  params = base::Value::Dict();
+  params.Set("width", view_size.width());
+  params.Set("height", view_size.height());
+  params.Set("deviceScaleFactor", 0);
+  params.Set("mobile", false);
+  params.Set("fitWindow", false);
+  SendCommandSync("Emulation.setDeviceMetricsOverride", std::move(params));
   CaptureScreenshotAndCompareTo(expected_bitmap, ScreenshotEncoding::PNG, true,
                                 device_scale_factor);
-  SendCommand("Emulation.clearDeviceMetricsOverride", nullptr);
+  SendCommandSync("Emulation.clearDeviceMetricsOverride");
 #endif  // !BUILDFLAG(IS_ANDROID)
 }
 
@@ -955,11 +989,11 @@
 
   int old_height = EvalJs(shell(), "window.innerHeight").ExtractInt();
 
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-  params->SetIntKey("x", old_width / 2);
-  params->SetIntKey("y", old_height / 2);
-  params->SetDoubleKey("scaleFactor", 2.0);
-  SendCommand("Input.synthesizePinchGesture", std::move(params));
+  base::Value::Dict params;
+  params.Set("x", old_width / 2);
+  params.Set("y", old_height / 2);
+  params.Set("scaleFactor", 2.0);
+  SendCommandSync("Input.synthesizePinchGesture", std::move(params));
 
   int new_width = EvalJs(shell(), "window.innerWidth").ExtractInt();
   ASSERT_DOUBLE_EQ(2.0, static_cast<double>(old_width) / new_width);
@@ -975,12 +1009,12 @@
 
   ASSERT_EQ(0, EvalJs(shell(), "document.body.scrollTop"));
 
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-  params->SetIntKey("x", 0);
-  params->SetIntKey("y", 0);
-  params->SetIntKey("xDistance", 0);
-  params->SetIntKey("yDistance", -100);
-  SendCommand("Input.synthesizeScrollGesture", std::move(params));
+  base::Value::Dict params;
+  params.Set("x", 0);
+  params.Set("y", 0);
+  params.Set("xDistance", 0);
+  params.Set("yDistance", -100);
+  SendCommandSync("Input.synthesizeScrollGesture", std::move(params));
 
   ASSERT_EQ(100, EvalJs(shell(), "document.body.scrollTop"));
 }
@@ -992,11 +1026,11 @@
 
   ASSERT_EQ(0, EvalJs(shell(), "document.body.scrollTop"));
 
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-  params->SetIntKey("x", 16);
-  params->SetIntKey("y", 16);
-  params->SetStringKey("gestureSourceType", "touch");
-  SendCommand("Input.synthesizeTapGesture", std::move(params));
+  base::Value::Dict params;
+  params.Set("x", 16);
+  params.Set("y", 16);
+  params.Set("gestureSourceType", "touch");
+  SendCommandSync("Input.synthesizeTapGesture", std::move(params));
 
   // The link that we just tapped should take us to the bottom of the page. The
   // new value of |document.body.scrollTop| will depend on the screen dimensions
@@ -1013,10 +1047,9 @@
   NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
   Attach();
 
-  std::unique_ptr<base::DictionaryValue> command_params;
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetBoolKey("discover", true);
-  SendCommand("Target.setDiscoverTargets", std::move(command_params));
+  base::Value::Dict command_params;
+  command_params.Set("discover", true);
+  SendCommandSync("Target.setDiscoverTargets", std::move(command_params));
 
   base::Value::Dict params = WaitForNotification("Target.targetCreated", true);
   EXPECT_THAT(*params.FindStringByDottedPath("targetInfo.type"), Eq("page"));
@@ -1025,7 +1058,7 @@
   ClearNotifications();
   {
     content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
-    SendCommand("Page.crash", nullptr, false);
+    SendCommandAsync("Page.crash");
     params = WaitForNotification("Target.targetCrashed", true);
   }
   EXPECT_EQ(*params.FindString("targetId"), target_id);
@@ -1048,10 +1081,9 @@
   NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
   Attach();
 
-  std::unique_ptr<base::DictionaryValue> command_params;
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetBoolKey("discover", true);
-  SendCommand("Target.setDiscoverTargets", std::move(command_params));
+  base::Value::Dict command_params;
+  command_params.Set("discover", true);
+  SendCommandSync("Target.setDiscoverTargets", std::move(command_params));
 
   base::Value::Dict params;
   std::string frame_target_id;
@@ -1064,11 +1096,11 @@
     ASSERT_LT(targetCount, 2);
   }
 
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetStringKey("targetId", frame_target_id);
-  command_params->SetBoolKey("flatten", true);
+  command_params = base::Value::Dict();
+  command_params.Set("targetId", frame_target_id);
+  command_params.Set("flatten", true);
   const base::Value::Dict* result =
-      SendCommand("Target.attachToTarget", std::move(command_params));
+      SendCommandSync("Target.attachToTarget", std::move(command_params));
   ASSERT_TRUE(result);
   const std::string* session_id = result->FindString("sessionId");
   ASSERT_TRUE(session_id);
@@ -1088,22 +1120,20 @@
   NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
   Attach();
 
-  std::unique_ptr<base::DictionaryValue> command_params;
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetBoolKey("discover", true);
+  base::Value::Dict command_params;
+  command_params.Set("discover", true);
 
-  SendCommand("Target.setDiscoverTargets", std::move(command_params));
+  SendCommandSync("Target.setDiscoverTargets", std::move(command_params));
 
   base::Value::Dict params = WaitForNotification("Target.targetCreated", true);
   EXPECT_THAT(*params.FindStringByDottedPath("targetInfo.type"), Eq("page"));
   std::string target_id = *params.FindStringByDottedPath("targetInfo.targetId");
 
-  SendCommand("Debugger.enable", nullptr, true);
+  SendCommandSync("Debugger.enable");
 
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetStringKey("expression",
-                               "console.log('first page'); debugger");
-  SendCommand("Runtime.evaluate", std::move(command_params), false);
+  command_params = base::Value::Dict();
+  command_params.Set("expression", "console.log('first page'); debugger");
+  SendCommandAsync("Runtime.evaluate", std::move(command_params));
   WaitForNotification("Debugger.paused");
 
   {
@@ -1112,11 +1142,11 @@
     params = WaitForNotification("Target.targetCrashed", true);
   }
   ClearNotifications();
-  SendCommand("Page.reload", nullptr, false);
+  SendCommandAsync("Page.reload");
   WaitForNotification("Inspector.targetReloadedAfterCrash", true);
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetStringKey("expression", "console.log('second page')");
-  SendCommand("Runtime.evaluate", std::move(command_params), true);
+  command_params = base::Value::Dict();
+  command_params.Set("expression", "console.log('second page')");
+  SendCommandSync("Runtime.evaluate", std::move(command_params));
   EXPECT_THAT(console_messages_, ElementsAre("first page", "second page"));
 }
 
@@ -1128,13 +1158,13 @@
   GURL test_url = embedded_test_server()->GetURL("/devtools/navigation.html");
   NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
   Attach();
-  SendCommand("Page.enable", nullptr, false);
+  SendCommandAsync("Page.enable");
 
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
+  base::Value::Dict params;
   test_url = GetTestUrl("devtools", "navigation.html");
-  params->SetStringKey("url", test_url.spec());
+  params.Set("url", test_url.spec());
   TestNavigationObserver navigation_observer(shell()->web_contents());
-  SendCommand("Page.navigate", std::move(params), true);
+  SendCommandSync("Page.navigate", std::move(params));
   navigation_observer.Wait();
 
   EXPECT_GE(received_responses_count(), 2);
@@ -1145,17 +1175,17 @@
                        NavigationToFileUrlRequiresFileAccess) {
   Attach();
 
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
+  base::Value::Dict params;
   GURL test_url = GetTestUrl("devtools", "navigation.html");
-  params->SetStringKey("url", test_url.spec());
-  ASSERT_TRUE(SendCommand("Page.navigate", params->GetDict().Clone(), true));
+  params.Set("url", test_url.spec());
+  ASSERT_TRUE(SendCommandSync("Page.navigate", params.Clone()));
 
   Detach();
   SetMayReadLocalFiles(false);
 
   Attach();
 
-  ASSERT_FALSE(SendCommand("Page.navigate", params->GetDict().Clone(), true));
+  ASSERT_FALSE(SendCommandSync("Page.navigate", params.Clone()));
   EXPECT_THAT(
       error()->FindInt("code"),
       testing::Optional(static_cast<int>(crdtp::DispatchCode::SERVER_ERROR)));
@@ -1186,14 +1216,14 @@
       embedded_test_server()->GetURL("A.com", "/devtools/navigation.html");
   NavigateToURLBlockUntilNavigationsComplete(shell(), test_url1, 1);
   Attach();
-  SendCommand("Page.enable", nullptr, false);
+  SendCommandAsync("Page.enable");
 
   GURL test_url2 =
       embedded_test_server()->GetURL("B.com", "/devtools/navigation.html");
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-  params->SetStringKey("url", test_url2.spec());
+  base::Value::Dict params;
+  params.Set("url", test_url2.spec());
   const base::Value::Dict* result =
-      SendCommand("Page.navigate", std::move(params));
+      SendCommandSync("Page.navigate", std::move(params));
   const std::string* frame_id = result->FindString("frameId");
 
   base::Value::Dict frame_stopped =
@@ -1226,7 +1256,7 @@
 
   NavigateToURLBlockUntilNavigationsComplete(shell(), url_a, 1);
   Attach();
-  SendCommand("Inspector.enable", nullptr);
+  SendCommandSync("Inspector.enable");
 
   {
     ScopedAllowRendererCrashes scoped_allow_renderer_crashes(shell());
@@ -1251,7 +1281,7 @@
 
   NavigateToURLBlockUntilNavigationsComplete(shell(), url_a, 1);
   Attach();
-  SendCommand("Inspector.enable", nullptr);
+  SendCommandSync("Inspector.enable");
 
   {
     ScopedAllowRendererCrashes scoped_allow_renderer_crashes(shell());
@@ -1275,7 +1305,7 @@
   GURL url = GURL("data:text/html,<body></body>");
   NavigateToURLBlockUntilNavigationsComplete(shell(), url, 1);
   Attach();
-  SendCommand("Inspector.enable", nullptr);
+  SendCommandSync("Inspector.enable");
 
   {
     ScopedAllowRendererCrashes scoped_allow_renderer_crashes(shell());
@@ -1284,7 +1314,7 @@
   }
 
   ClearNotifications();
-  SendCommand("Page.reload", nullptr, false);
+  SendCommandAsync("Page.reload");
   WaitForNotification("Inspector.targetReloadedAfterCrash", true);
 }
 
@@ -1297,7 +1327,7 @@
   NavigateToURLBlockUntilNavigationsComplete(second, test_url, 1);
 
   Attach();
-  SendCommand("Runtime.enable", nullptr);
+  SendCommandSync("Runtime.enable");
 
   agent_host_->DisconnectWebContents();
   agent_host_->ConnectWebContents(second->web_contents());
@@ -1311,7 +1341,7 @@
   NavigateToURLBlockUntilNavigationsComplete(shell(),
       embedded_test_server()->GetURL("A.com", "/devtools/navigation.html"), 1);
   Attach();
-  SendCommand("Debugger.enable", nullptr);
+  SendCommandSync("Debugger.enable");
 
   ASSERT_TRUE(content::ExecJs(
       shell(),
@@ -1321,7 +1351,7 @@
       embedded_test_server()->GetURL("B.com", "/devtools/navigation.html"));
   WaitForNotification("Debugger.paused");
   TestNavigationObserver observer(shell()->web_contents(), 1);
-  SendCommand("Debugger.resume", nullptr);
+  SendCommandSync("Debugger.resume");
   observer.Wait();
 }
 
@@ -1375,7 +1405,7 @@
   GURL test_url = embedded_test_server()->GetURL("/devtools/navigation.html");
   NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
   Attach();
-  SendCommand("ServiceWorker.enable", nullptr);
+  SendCommandSync("ServiceWorker.enable");
   NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
   CrashTab(shell()->web_contents());
   NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
@@ -1392,16 +1422,16 @@
       gfx::Size());
   WaitForLoadStop(window->web_contents());
   Attach();
-  SendCommand("Page.reload", nullptr, false);
+  SendCommandAsync("Page.reload");
   // Should not crash at this point.
 }
 
 IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, EvaluateInBlankPage) {
   NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
   Attach();
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-  params->SetStringKey("expression", "window");
-  SendCommand("Runtime.evaluate", std::move(params), true);
+  base::Value::Dict params;
+  params.Set("expression", "window");
+  SendCommandSync("Runtime.evaluate", std::move(params));
   EXPECT_FALSE(result()->Find("exceptionDetails"));
 }
 
@@ -1412,9 +1442,9 @@
   NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
   Attach();
   NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-  params->SetStringKey("expression", "window");
-  SendCommand("Runtime.evaluate", std::move(params), true);
+  base::Value::Dict params;
+  params.Set("expression", "window");
+  SendCommandSync("Runtime.evaluate", std::move(params));
   EXPECT_FALSE(result()->Find("exceptionDetails"));
 }
 
@@ -1424,11 +1454,11 @@
   TestJavaScriptDialogManager dialog_manager;
   WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
   wc->SetDelegate(&dialog_manager);
-  SendCommand("Page.enable", nullptr, true);
+  SendCommandSync("Page.enable");
 
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-  params->SetStringKey("expression", "prompt('hello?', 'default')");
-  SendCommand("Runtime.evaluate", std::move(params), false);
+  base::Value::Dict params;
+  params.Set("expression", "prompt('hello?', 'default')");
+  SendCommandAsync("Runtime.evaluate", std::move(params));
 
   base::Value::Dict notification =
       WaitForNotification("Page.javascriptDialogOpening");
@@ -1437,10 +1467,10 @@
   EXPECT_EQ(*notification.FindString("type"), "prompt");
   EXPECT_EQ(*notification.FindString("defaultPrompt"), "default");
 
-  params = std::make_unique<base::DictionaryValue>();
-  params->SetBoolKey("accept", true);
-  params->SetStringKey("promptText", "hi!");
-  SendCommand("Page.handleJavaScriptDialog", std::move(params), false);
+  params = base::Value::Dict();
+  params.Set("accept", true);
+  params.Set("promptText", "hi!");
+  SendCommandAsync("Page.handleJavaScriptDialog", std::move(params));
 
   notification = WaitForNotification("Page.javascriptDialogClosed", true);
   EXPECT_THAT(notification.FindBool("result"), testing::Optional(true));
@@ -1458,12 +1488,12 @@
   TestJavaScriptDialogManager dialog_manager;
   WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
   wc->SetDelegate(&dialog_manager);
-  SendCommand("Page.enable", nullptr, true);
-  SendCommand("Runtime.enable", nullptr, true);
+  SendCommandSync("Page.enable");
+  SendCommandSync("Runtime.enable");
 
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-  params->SetStringKey("expression", "alert('42')");
-  SendCommand("Runtime.evaluate", std::move(params), false);
+  base::Value::Dict params;
+  params.Set("expression", "alert('42')");
+  SendCommandAsync("Runtime.evaluate", std::move(params));
   WaitForNotification("Page.javascriptDialogOpening");
 
   dialog_manager.Handle();
@@ -1479,25 +1509,25 @@
   WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
   wc->SetDelegate(&dialog_manager);
 
-  SendCommand("Page.enable", nullptr, true);
-  SendCommand("Runtime.enable", nullptr, true);
+  SendCommandSync("Page.enable");
+  SendCommandSync("Runtime.enable");
 
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-  params->SetStringKey("expression", "alert('42')");
-  SendCommand("Runtime.evaluate", std::move(params), false);
+  base::Value::Dict params;
+  params.Set("expression", "alert('42')");
+  SendCommandAsync("Runtime.evaluate", std::move(params));
   WaitForNotification("Page.javascriptDialogOpening");
   EXPECT_TRUE(wc->IsJavaScriptDialogShowing());
 
   EXPECT_FALSE(dialog_manager.is_handled());
-  SendCommand("Page.disable", nullptr, false);
+  SendCommandAsync("Page.disable");
   EXPECT_TRUE(wc->IsJavaScriptDialogShowing());
   EXPECT_FALSE(dialog_manager.is_handled());
   dialog_manager.Handle();
   EXPECT_FALSE(wc->IsJavaScriptDialogShowing());
 
-  params = std::make_unique<base::DictionaryValue>();
-  params->SetStringKey("expression", "42");
-  SendCommand("Runtime.evaluate", std::move(params), true);
+  params = base::Value::Dict();
+  params.Set("expression", "42");
+  SendCommandSync("Runtime.evaluate", std::move(params));
 
   wc->SetDelegate(nullptr);
   wc->SetJavaScriptDialogManagerForTesting(nullptr);
@@ -1509,16 +1539,16 @@
   WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
   wc->SetDelegate(nullptr);
 
-  SendCommand("Page.enable", nullptr, true);
-  SendCommand("Runtime.enable", nullptr, true);
+  SendCommandSync("Page.enable");
+  SendCommandSync("Runtime.enable");
 
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-  params->SetStringKey("expression", "alert('42');");
-  SendCommand("Runtime.evaluate", std::move(params), false);
+  base::Value::Dict params;
+  params.Set("expression", "alert('42');");
+  SendCommandAsync("Runtime.evaluate", std::move(params));
   WaitForNotification("Page.javascriptDialogOpening");
   EXPECT_TRUE(wc->IsJavaScriptDialogShowing());
 
-  SendCommand("Page.disable", nullptr, true);
+  SendCommandSync("Page.disable");
   EXPECT_FALSE(wc->IsJavaScriptDialogShowing());
 }
 
@@ -1529,18 +1559,17 @@
 
   WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
   wc->SetDelegate(&dialog_manager);
-  SendCommand("Runtime.enable", nullptr, true);
+  SendCommandSync("Runtime.enable");
 
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
+  base::Value::Dict params;
 
-  params = std::make_unique<base::DictionaryValue>();
-  params->SetStringKey("expression",
-                       "window.onbeforeunload=()=>{return 'prompt';}");
-  params->SetBoolKey("userGesture", true);
-  SendCommand("Runtime.evaluate", std::move(params), true);
+  params = base::Value::Dict();
+  params.Set("expression", "window.onbeforeunload=()=>{return 'prompt';}");
+  params.Set("userGesture", true);
+  SendCommandSync("Runtime.evaluate", std::move(params));
 
-  SendCommand("Page.enable", nullptr, true);
-  SendCommand("Page.reload", nullptr, false);
+  SendCommandSync("Page.enable");
+  SendCommandAsync("Page.reload");
 
   base::Value::Dict notification =
       WaitForNotification("Page.javascriptDialogOpening", true);
@@ -1548,9 +1577,9 @@
   EXPECT_THAT(*notification.FindString("url"), Eq("about:blank"));
   EXPECT_THAT(*notification.FindString("type"), Eq("beforeunload"));
 
-  params = std::make_unique<base::DictionaryValue>();
-  params->SetBoolKey("accept", true);
-  SendCommand("Page.handleJavaScriptDialog", std::move(params), false);
+  params = base::Value::Dict();
+  params.Set("accept", true);
+  SendCommandAsync("Page.handleJavaScriptDialog", std::move(params));
   WaitForNotification("Page.javascriptDialogClosed", true);
   wc->SetDelegate(nullptr);
   wc->SetJavaScriptDialogManagerForTesting(nullptr);
@@ -1560,18 +1589,18 @@
   NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
   Attach();
   EXPECT_EQ(1u, shell()->windows().size());
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-  params->SetStringKey("url", "about:blank");
-  SendCommand("Target.createTarget", std::move(params), true);
+  base::Value::Dict params;
+  params.Set("url", "about:blank");
+  SendCommandSync("Target.createTarget", std::move(params));
   const std::string* target_id = result()->FindString("targetId");
   ASSERT_TRUE(target_id);
   EXPECT_EQ(2u, shell()->windows().size());
 
   // TODO(eseckler): Since the RenderView is closed asynchronously, we currently
   // don't verify that the command actually closes the shell.
-  params = std::make_unique<base::DictionaryValue>();
-  params->SetStringKey("targetId", *target_id);
-  SendCommand("Target.closeTarget", std::move(params), true);
+  params = base::Value::Dict();
+  params.Set("targetId", *target_id);
+  SendCommandSync("Target.closeTarget", std::move(params));
 
   EXPECT_THAT(result()->FindBool("success"), testing::Optional(true));
 }
@@ -1579,7 +1608,7 @@
 IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, BrowserGetTargets) {
   NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
   Attach();
-  SendCommand("Target.getTargets", nullptr, true);
+  SendCommandSync("Target.getTargets");
   const base::Value::List* target_infos = result()->FindList("targetInfos");
   ASSERT_TRUE(target_infos);
   EXPECT_EQ(1u, target_infos->size());
@@ -1601,38 +1630,38 @@
   NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
   Attach();
 
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-  params->SetStringKey("policy", "pause");
-  SendCommand("Emulation.setVirtualTimePolicy", std::move(params), true);
+  base::Value::Dict params;
+  params.Set("policy", "pause");
+  SendCommandSync("Emulation.setVirtualTimePolicy", std::move(params));
 
-  params = std::make_unique<base::DictionaryValue>();
-  params->SetStringKey("expression",
-                       "setTimeout(function(){console.log('before')}, 999);"
-                       "setTimeout(function(){console.log('at')}, 1000);"
-                       "setTimeout(function(){console.log('after')}, 1001);");
-  SendCommand("Runtime.evaluate", std::move(params), true);
+  params = base::Value::Dict();
+  params.Set("expression",
+             "setTimeout(function(){console.log('before')}, 999);"
+             "setTimeout(function(){console.log('at')}, 1000);"
+             "setTimeout(function(){console.log('after')}, 1001);");
+  SendCommandSync("Runtime.evaluate", std::move(params));
 
   // Let virtual time advance for one second.
-  params = std::make_unique<base::DictionaryValue>();
-  params->SetStringKey("policy", "advance");
-  params->SetIntKey("budget", 1000);
-  SendCommand("Emulation.setVirtualTimePolicy", std::move(params), true);
+  params = base::Value::Dict();
+  params.Set("policy", "advance");
+  params.Set("budget", 1000);
+  SendCommandSync("Emulation.setVirtualTimePolicy", std::move(params));
 
   WaitForNotification("Emulation.virtualTimeBudgetExpired");
 
-  params = std::make_unique<base::DictionaryValue>();
-  params->SetStringKey("expression", "console.log('done')");
-  SendCommand("Runtime.evaluate", std::move(params), true);
+  params = base::Value::Dict();
+  params.Set("expression", "console.log('done')");
+  SendCommandSync("Runtime.evaluate", std::move(params));
 
   // The third timer should not fire.
   EXPECT_THAT(console_messages_, ElementsAre("before", "at", "done"));
 
   // Let virtual time advance for another second, which should make the third
   // timer fire.
-  params = std::make_unique<base::DictionaryValue>();
-  params->SetStringKey("policy", "advance");
-  params->SetIntKey("budget", 1000);
-  SendCommand("Emulation.setVirtualTimePolicy", std::move(params), true);
+  params = base::Value::Dict();
+  params.Set("policy", "advance");
+  params.Set("budget", 1000);
+  SendCommandSync("Emulation.setVirtualTimePolicy", std::move(params));
 
   WaitForNotification("Emulation.virtualTimeBudgetExpired");
 
@@ -1645,22 +1674,22 @@
   https_server.ServeFilesFromSourceDirectory(GetTestDataFilePath());
   ASSERT_TRUE(https_server.Start());
   GURL test_url = https_server.GetURL("/devtools/navigation.html");
-  std::unique_ptr<base::DictionaryValue> command_params;
+  base::Value::Dict command_params;
 
   shell()->LoadURL(GURL("about:blank"));
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
 
   Attach();
-  SendCommand("Network.enable", nullptr, true);
-  SendCommand("Security.enable", nullptr, false);
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetBoolKey("override", true);
-  SendCommand("Security.setOverrideCertificateErrors",
-              std::move(command_params), true);
+  SendCommandSync("Network.enable");
+  SendCommandAsync("Security.enable");
+  command_params = base::Value::Dict();
+  command_params.Set("override", true);
+  SendCommandSync("Security.setOverrideCertificateErrors",
+                  std::move(command_params));
 
   // Test cancel.
-  SendCommand("Network.clearBrowserCache", nullptr, true);
-  SendCommand("Network.clearBrowserCookies", nullptr, true);
+  SendCommandSync("Network.clearBrowserCache");
+  SendCommandSync("Network.clearBrowserCookies");
   TestNavigationObserver cancel_observer(shell()->web_contents(), 1);
   shell()->LoadURL(test_url);
   base::Value::Dict params =
@@ -1669,11 +1698,11 @@
   EXPECT_EQ(
       test_url,
       shell()->web_contents()->GetController().GetPendingEntry()->GetURL());
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetIntKey("eventId", *params.FindInt("eventId"));
-  command_params->SetStringKey("action", "cancel");
-  SendCommand("Security.handleCertificateError", std::move(command_params),
-              false);
+  command_params = base::Value::Dict();
+  command_params.Set("eventId", *params.FindInt("eventId"));
+  command_params.Set("action", "cancel");
+  SendCommandAsync("Security.handleCertificateError",
+                   std::move(command_params));
   cancel_observer.Wait();
   EXPECT_FALSE(shell()->web_contents()->GetController().GetPendingEntry());
   EXPECT_EQ(GURL("about:blank"), shell()
@@ -1683,16 +1712,16 @@
                                      ->GetURL());
 
   // Test continue.
-  SendCommand("Network.clearBrowserCache", nullptr, true);
-  SendCommand("Network.clearBrowserCookies", nullptr, true);
+  SendCommandSync("Network.clearBrowserCache");
+  SendCommandSync("Network.clearBrowserCookies");
   TestNavigationObserver continue_observer(shell()->web_contents(), 1);
   shell()->LoadURL(test_url);
   params = WaitForNotification("Security.certificateError", false);
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetIntKey("eventId", *params.FindInt("eventId"));
-  command_params->SetStringKey("action", "continue");
-  SendCommand("Security.handleCertificateError", std::move(command_params),
-              false);
+  command_params = base::Value::Dict();
+  command_params.Set("eventId", *params.FindInt("eventId"));
+  command_params.Set("action", "continue");
+  SendCommandAsync("Security.handleCertificateError",
+                   std::move(command_params));
   WaitForNotification("Network.loadingFinished", true);
   continue_observer.Wait();
   EXPECT_EQ(test_url, shell()
@@ -1702,16 +1731,16 @@
                           ->GetURL());
 
   // Reset override.
-  SendCommand("Security.disable", nullptr, true);
+  SendCommandSync("Security.disable");
 
   // Test ignoring all certificate errors.
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetBoolKey("ignore", true);
-  SendCommand("Security.setIgnoreCertificateErrors", std::move(command_params),
-              true);
+  command_params = base::Value::Dict();
+  command_params.Set("ignore", true);
+  SendCommandSync("Security.setIgnoreCertificateErrors",
+                  std::move(command_params));
 
-  SendCommand("Network.clearBrowserCache", nullptr, true);
-  SendCommand("Network.clearBrowserCookies", nullptr, true);
+  SendCommandSync("Network.clearBrowserCache");
+  SendCommandSync("Network.clearBrowserCookies");
   TestNavigationObserver continue_observer2(shell()->web_contents(), 1);
   shell()->LoadURL(test_url);
   WaitForNotification("Network.loadingFinished", true);
@@ -1735,29 +1764,28 @@
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
 
   Attach();
-  SendCommand("Network.enable", nullptr);
-  SendCommand("Security.enable", base::Value::Dict(), false);
-  SendCommand("Network.setRequestInterception",
-              std::move(base::JSONReader::Read(
-                            "{\"patterns\": [{\"urlPattern\": \"*\"}]}")
-                            ->GetDict()));
+  SendCommandSync("Network.enable");
+  SendCommandAsync("Security.enable");
+  SendCommandSync("Network.setRequestInterception",
+                  std::move(base::JSONReader::Read(
+                                "{\"patterns\": [{\"urlPattern\": \"*\"}]}")
+                                ->GetDict()));
 
-  SendCommand(
+  SendCommandSync(
       "Security.setIgnoreCertificateErrors",
       std::move(base::JSONReader::Read("{\"ignore\": true}")->GetDict()));
 
-  SendCommand("Network.clearBrowserCache", nullptr);
-  SendCommand("Network.clearBrowserCookies", nullptr);
+  SendCommandSync("Network.clearBrowserCache");
+  SendCommandSync("Network.clearBrowserCookies");
   TestNavigationObserver continue_observer(shell()->web_contents(), 1);
   shell()->LoadURL(test_url);
   base::Value::Dict params =
       WaitForNotification("Network.requestIntercepted", false);
   std::string interceptionId = *params.FindString("interceptionId");
-  SendCommand("Network.continueInterceptedRequest",
-              std::move(base::JSONReader::Read("{\"interceptionId\": \"" +
-                                               interceptionId + "\"}")
-                            ->GetDict()),
-              false);
+  SendCommandAsync("Network.continueInterceptedRequest",
+                   std::move(base::JSONReader::Read("{\"interceptionId\": \"" +
+                                                    interceptionId + "\"}")
+                                 ->GetDict()));
   continue_observer.Wait();
   EXPECT_EQ(test_url, shell()
                           ->web_contents()
@@ -1772,25 +1800,25 @@
   https_server.ServeFilesFromSourceDirectory(GetTestDataFilePath());
   ASSERT_TRUE(https_server.Start());
   GURL test_url = https_server.GetURL("/devtools/navigation.html");
-  std::unique_ptr<base::DictionaryValue> params;
-  std::unique_ptr<base::DictionaryValue> command_params;
+  base::Value::Dict params;
+  base::Value::Dict command_params;
 
   shell()->LoadURL(GURL("about:blank"));
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
 
   // Clear cookies and cache to avoid interference with cert error events.
   Attach();
-  SendCommand("Network.enable", nullptr, true);
-  SendCommand("Network.clearBrowserCache", nullptr, true);
-  SendCommand("Network.clearBrowserCookies", nullptr, true);
+  SendCommandSync("Network.enable");
+  SendCommandSync("Network.clearBrowserCache");
+  SendCommandSync("Network.clearBrowserCookies");
   Detach();
 
   // Test that browser target can ignore cert errors.
   AttachToBrowserTarget();
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetBoolKey("ignore", true);
-  SendCommand("Security.setIgnoreCertificateErrors", std::move(command_params),
-              true);
+  command_params = base::Value::Dict();
+  command_params.Set("ignore", true);
+  SendCommandSync("Security.setIgnoreCertificateErrors",
+                  std::move(command_params));
 
   TestNavigationObserver continue_observer(shell()->web_contents(), 1);
   shell()->LoadURL(test_url);
@@ -1808,17 +1836,17 @@
   https_server.ServeFilesFromSourceDirectory("content/test/data/devtools");
   ASSERT_TRUE(https_server.Start());
   GURL test_url = https_server.GetURL("/image.html");
-  std::unique_ptr<base::DictionaryValue> command_params;
+  base::Value::Dict command_params;
 
   shell()->LoadURL(GURL("about:blank"));
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
 
   Attach();
-  SendCommand("Security.enable", nullptr, false);
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetBoolKey("override", true);
-  SendCommand("Security.setOverrideCertificateErrors",
-              std::move(command_params), true);
+  SendCommandAsync("Security.enable");
+  command_params = base::Value::Dict();
+  command_params.Set("override", true);
+  SendCommandSync("Security.setOverrideCertificateErrors",
+                  std::move(command_params));
 
   TestNavigationObserver observer(shell()->web_contents(), 1);
   shell()->LoadURL(test_url);
@@ -1826,19 +1854,19 @@
   // Expect certificateError event for main frame.
   base::Value::Dict params =
       WaitForNotification("Security.certificateError", false);
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetIntKey("eventId", *params.FindInt("eventId"));
-  command_params->SetStringKey("action", "continue");
-  SendCommand("Security.handleCertificateError", std::move(command_params),
-              false);
+  command_params = base::Value::Dict();
+  command_params.Set("eventId", *params.FindInt("eventId"));
+  command_params.Set("action", "continue");
+  SendCommandAsync("Security.handleCertificateError",
+                   std::move(command_params));
 
   // Expect certificateError event for image.
   params = WaitForNotification("Security.certificateError", false);
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetIntKey("eventId", *params.FindInt("eventId"));
-  command_params->SetStringKey("action", "continue");
-  SendCommand("Security.handleCertificateError", std::move(command_params),
-              false);
+  command_params = base::Value::Dict();
+  command_params.Set("eventId", *params.FindInt("eventId"));
+  command_params.Set("action", "continue");
+  SendCommandAsync("Security.handleCertificateError",
+                   std::move(command_params));
 
   observer.Wait();
   EXPECT_EQ(test_url, shell()
@@ -1850,7 +1878,7 @@
 
 IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, TargetDiscovery) {
   std::set<std::string> ids;
-  std::unique_ptr<base::DictionaryValue> command_params;
+  base::Value::Dict command_params;
 
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL first_url = embedded_test_server()->GetURL("/devtools/navigation.html");
@@ -1862,9 +1890,9 @@
 
   Attach();
   int attached_count = 0;
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetBoolKey("discover", true);
-  SendCommand("Target.setDiscoverTargets", std::move(command_params), true);
+  command_params = base::Value::Dict();
+  command_params.Set("discover", true);
+  SendCommandSync("Target.setDiscoverTargets", std::move(command_params));
   base::Value::Dict params = WaitForNotification("Target.targetCreated", true);
   EXPECT_THAT(*params.FindStringByDottedPath("targetInfo.type"), Eq("page"));
   attached_count += *params.FindBoolByDottedPath("targetInfo.attached") ? 1 : 0;
@@ -1909,9 +1937,9 @@
   EXPECT_THAT(ids.erase(target_id), Eq(1u));
   EXPECT_FALSE(HasExistingNotification());
 
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetStringKey("targetId", attached_id);
-  SendCommand("Target.attachToTarget", std::move(command_params), true);
+  command_params = base::Value::Dict();
+  command_params.Set("targetId", attached_id);
+  SendCommandSync("Target.attachToTarget", std::move(command_params));
   params = WaitForNotification("Target.targetInfoChanged", true);
   EXPECT_THAT(*params.FindStringByDottedPath("targetInfo.targetId"),
               Eq(attached_id));
@@ -1939,14 +1967,14 @@
   EXPECT_THAT(*params.FindStringByDottedPath("targetInfo.type"), Eq("page"));
   EXPECT_FALSE(HasExistingNotification());
 
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetBoolKey("discover", false);
-  SendCommand("Target.setDiscoverTargets", std::move(command_params), true);
+  command_params = base::Value::Dict();
+  command_params.Set("discover", false);
+  SendCommandSync("Target.setDiscoverTargets", std::move(command_params));
   EXPECT_FALSE(HasExistingNotification());
 
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetStringKey("sessionId", session_id);
-  SendCommand("Target.detachFromTarget", std::move(command_params), true);
+  command_params = base::Value::Dict();
+  command_params.Set("sessionId", session_id);
+  SendCommandSync("Target.detachFromTarget", std::move(command_params));
   params = WaitForNotification("Target.detachedFromTarget", true);
   EXPECT_THAT(*params.FindString("sessionId"), Eq(session_id));
   EXPECT_THAT(*params.FindString("targetId"), Eq(attached_id));
@@ -1961,21 +1989,21 @@
 
   // Set two cookies, one of which matches the loaded URL and another that
   // doesn't.
-  std::unique_ptr<base::DictionaryValue> command_params;
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetStringKey("url", test_url.spec());
-  command_params->SetStringKey("name", "cookie_for_this_url");
-  command_params->SetStringKey("value", "mendacious");
-  SendCommand("Network.setCookie", std::move(command_params), false);
+  base::Value::Dict command_params;
+  command_params = base::Value::Dict();
+  command_params.Set("url", test_url.spec());
+  command_params.Set("name", "cookie_for_this_url");
+  command_params.Set("value", "mendacious");
+  SendCommandAsync("Network.setCookie", std::move(command_params));
 
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetStringKey("url", "https://www.chromium.org");
-  command_params->SetStringKey("name", "cookie_for_another_url");
-  command_params->SetStringKey("value", "polyglottal");
-  SendCommand("Network.setCookie", std::move(command_params), false);
+  command_params = base::Value::Dict();
+  command_params.Set("url", "https://www.chromium.org");
+  command_params.Set("name", "cookie_for_another_url");
+  command_params.Set("value", "polyglottal");
+  SendCommandAsync("Network.setCookie", std::move(command_params));
 
   // First get the cookies for just the loaded URL.
-  SendCommand("Network.getCookies", nullptr, true);
+  SendCommandSync("Network.getCookies");
 
   const base::Value::List* cookies = result()->FindList("cookies");
   ASSERT_TRUE(cookies);
@@ -1993,7 +2021,7 @@
   EXPECT_EQ("mendacious", value);
 
   // Then get all the cookies in the cookie jar.
-  SendCommand("Network.getAllCookies", nullptr, true);
+  SendCommandSync("Network.getAllCookies");
 
   cookies = result()->FindList("cookies");
   ASSERT_TRUE(cookies);
@@ -2051,12 +2079,12 @@
   EXPECT_NE(main_frame_agent, nullptr);
 
   // Start auto-attach.
-  std::unique_ptr<base::DictionaryValue> command_params;
-  command_params = std::make_unique<base::DictionaryValue>();
-  command_params->SetBoolKey("autoAttach", true);
-  command_params->SetBoolKey("waitForDebuggerOnStart", false);
-  command_params->SetBoolKey("flatten", true);
-  SendCommand("Target.setAutoAttach", std::move(command_params));
+  base::Value::Dict command_params;
+  command_params = base::Value::Dict();
+  command_params.Set("autoAttach", true);
+  command_params.Set("waitForDebuggerOnStart", false);
+  command_params.Set("flatten", true);
+  SendCommandSync("Target.setAutoAttach", std::move(command_params));
 
   // Child frame should be created at this point, but isn't an OOPIF yet, so
   // shouldn't have its own DevToolsAgentHost yet.
@@ -2079,12 +2107,12 @@
   ~DevToolsProtocolDeviceEmulationTest() override {}
 
   void EmulateDeviceSize(gfx::Size size) {
-    auto params = std::make_unique<base::DictionaryValue>();
-    params->SetIntKey("width", size.width());
-    params->SetIntKey("height", size.height());
-    params->SetDoubleKey("deviceScaleFactor", 0);
-    params->SetBoolKey("mobile", false);
-    SendCommand("Emulation.setDeviceMetricsOverride", std::move(params));
+    base::Value::Dict params;
+    params.Set("width", size.width());
+    params.Set("height", size.height());
+    params.Set("deviceScaleFactor", 0);
+    params.Set("mobile", false);
+    SendCommandSync("Emulation.setDeviceMetricsOverride", std::move(params));
   }
 
   gfx::Size GetViewSize() {
@@ -2129,7 +2157,7 @@
   NavigateToURLBlockUntilNavigationsComplete(shell(), test_url2, 1);
   EXPECT_EQ(emulated_size_2, GetViewSize());
 
-  SendCommand("Emulation.clearDeviceMetricsOverride", nullptr);
+  SendCommandSync("Emulation.clearDeviceMetricsOverride");
   EXPECT_EQ(original_size, GetViewSize());
 }
 
@@ -2152,7 +2180,7 @@
         shell(), GURL(blink::kChromeUICrashURL), 1);
   }
 
-  SendCommand("Emulation.clearDeviceMetricsOverride", nullptr);
+  SendCommandSync("Emulation.clearDeviceMetricsOverride");
   // Should not crash at this point.
 }
 
@@ -2213,7 +2241,7 @@
   prerender_helper_.NavigatePrimaryPage(prerender_url);
   EXPECT_EQ(emulated_size, GetViewSize());
 
-  SendCommand("Emulation.clearDeviceMetricsOverride", nullptr);
+  SendCommandSync("Emulation.clearDeviceMetricsOverride");
   EXPECT_EQ(original_size, GetViewSize());
 }
 
@@ -2229,7 +2257,7 @@
 };
 
 IN_PROC_BROWSER_TEST_F(DevToolsProtocolTouchTest, EnableTouch) {
-  std::unique_ptr<base::DictionaryValue> params;
+  base::Value::Dict params;
 
   content::SetupCrossSiteRedirector(embedded_test_server());
   ASSERT_TRUE(embedded_test_server()->Start());
@@ -2240,29 +2268,29 @@
   NavigateToURLBlockUntilNavigationsComplete(shell(), test_url1, 1);
   Attach();
 
-  params = std::make_unique<base::DictionaryValue>();
-  SendCommand("Page.enable", std::move(params), true);
+  params = base::Value::Dict();
+  SendCommandSync("Page.enable", std::move(params));
 
   EXPECT_EQ(true, EvalJs(shell()->web_contents(), "checkProtos(false)"));
 
-  params = std::make_unique<base::DictionaryValue>();
-  params->SetBoolKey("enabled", true);
-  SendCommand("Emulation.setTouchEmulationEnabled", std::move(params), true);
+  params = base::Value::Dict();
+  params.Set("enabled", true);
+  SendCommandSync("Emulation.setTouchEmulationEnabled", std::move(params));
   EXPECT_EQ(true, EvalJs(shell()->web_contents(), "checkProtos(false)"));
 
-  params = std::make_unique<base::DictionaryValue>();
-  params->SetStringKey("url", test_url2.spec());
-  SendCommand("Page.navigate", std::move(params), false);
+  params = base::Value::Dict();
+  params.Set("url", test_url2.spec());
+  SendCommandAsync("Page.navigate", std::move(params));
   WaitForNotification("Page.frameStoppedLoading");
   EXPECT_EQ(true, EvalJs(shell()->web_contents(), "checkProtos(true)"));
 
-  params = std::make_unique<base::DictionaryValue>();
-  params->SetBoolKey("enabled", false);
-  SendCommand("Emulation.setTouchEmulationEnabled", std::move(params), true);
+  params = base::Value::Dict();
+  params.Set("enabled", false);
+  SendCommandSync("Emulation.setTouchEmulationEnabled", std::move(params));
   EXPECT_EQ(true, EvalJs(shell()->web_contents(), "checkProtos(true)"));
 
-  params = std::make_unique<base::DictionaryValue>();
-  SendCommand("Page.reload", std::move(params), false);
+  params = base::Value::Dict();
+  SendCommandAsync("Page.reload", std::move(params));
   WaitForNotification("Page.frameStoppedLoading");
   EXPECT_EQ(true, EvalJs(shell()->web_contents(), "checkProtos(false)"));
 }
@@ -2283,9 +2311,9 @@
 
   std::string Evaluate(const std::string& script,
                        const base::Location& location) {
-    std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-    params->SetStringKey("expression", script);
-    SendCommand("Runtime.evaluate", std::move(params), true);
+    base::Value::Dict params;
+    params.Set("expression", script);
+    SendCommandSync("Runtime.evaluate", std::move(params));
     const std::string* result_value =
         result()->FindStringByDottedPath("result.value");
     DCHECK(result_value) << "Valued to evaluate " << script << " from "
@@ -2512,19 +2540,19 @@
   }
 
   void SetDownloadBehavior(const std::string& behavior) {
-    std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-    params->SetStringKey("behavior", behavior);
-    SendCommand("Page.setDownloadBehavior", std::move(params));
+    base::Value::Dict params;
+    params.Set("behavior", behavior);
+    SendCommandSync("Page.setDownloadBehavior", std::move(params));
 
     EXPECT_GE(received_responses_count(), 1);
   }
 
   void SetDownloadBehavior(const std::string& behavior,
                            const std::string& download_path) {
-    std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-    params->SetStringKey("behavior", behavior);
-    params->SetStringKey("downloadPath", download_path);
-    SendCommand("Page.setDownloadBehavior", std::move(params));
+    base::Value::Dict params;
+    params.Set("behavior", behavior);
+    params.Set("downloadPath", download_path);
+    SendCommandSync("Page.setDownloadBehavior", std::move(params));
 
     EXPECT_GE(received_responses_count(), 1);
   }
@@ -2780,23 +2808,22 @@
   NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
   Attach();
 
-  base::Value params(base::Value::Type::DICTIONARY);
-  params.SetStringKey("url", "http://www.example.com/hello.js");
-  params.SetStringKey("data", "Tm90aGluZyB0byBzZWUgaGVyZSE=");
+  base::Value::Dict params;
+  params.Set("url", "http://www.example.com/hello.js");
+  params.Set("data", "Tm90aGluZyB0byBzZWUgaGVyZSE=");
 
-  SendCommand("Page.addCompilationCache", params.GetDict().Clone());
+  SendCommandSync("Page.addCompilationCache", params.Clone());
   EXPECT_TRUE(result());
   Detach();
   SetAllowUnsafeOperations(false);
   Attach();
-  SendCommand("Page.addCompilationCache", params.GetDict().Clone());
+  SendCommandSync("Page.addCompilationCache", params.Clone());
   EXPECT_THAT(
       error()->FindInt("code"),
       testing::Optional(static_cast<int>(crdtp::DispatchCode::SERVER_ERROR)));
 }
 
 IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, TracingWithPerfettoConfig) {
-  std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
   base::trace_event::TraceConfig chrome_config;
   perfetto::TraceConfig perfetto_config;
   std::string perfetto_config_encoded;
@@ -2809,14 +2836,16 @@
       perfetto::protos::gen::ChromeConfig::USER_INITIATED);
   base::Base64Encode(perfetto_config.SerializeAsString(),
                      &perfetto_config_encoded);
-  params->SetKey("perfettoConfig", base::Value(perfetto_config_encoded));
-  params->SetStringKey("transferMode", "ReturnAsStream");
+
+  base::Value::Dict params;
+  params.Set("perfettoConfig", perfetto_config_encoded);
+  params.Set("transferMode", "ReturnAsStream");
 
   NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
   Attach();
 
-  EXPECT_TRUE(SendCommand("Tracing.start", std::move(params), true));
-  EXPECT_TRUE(SendCommand("Tracing.end", nullptr, true));
+  EXPECT_TRUE(SendCommandSync("Tracing.start", std::move(params)));
+  EXPECT_TRUE(SendCommandSync("Tracing.end"));
 
   WaitForNotification("Tracing.tracingComplete", true);
 }
@@ -2828,7 +2857,7 @@
   base::Value::Dict params;
   params.Set("url", "about:blank");
   const base::Value::Dict* result =
-      SendCommand("Page.navigate", std::move(params));
+      SendCommandSync("Page.navigate", std::move(params));
   EXPECT_THAT(result->FindString("loaderId"),
               testing::Pointee(testing::Not("")));
 }
@@ -2846,15 +2875,15 @@
     base::Base64Encode(perfetto_config.SerializeAsString(),
                        &perfetto_config_encoded);
 
-    auto params = std::make_unique<base::DictionaryValue>();
-    params->SetKey("perfettoConfig", base::Value(perfetto_config_encoded));
-    params->SetStringKey("transferMode", "ReturnAsStream");
-    params->SetStringKey("tracingBackend", "system");
+    base::Value::Dict params;
+    params.Set("perfettoConfig", perfetto_config_encoded);
+    params.Set("transferMode", "ReturnAsStream");
+    params.Set("tracingBackend", "system");
 
     NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
     Attach();
 
-    return SendCommand("Tracing.start", std::move(params), true);
+    return SendCommandSync("Tracing.start", std::move(params));
   }
 };
 
@@ -2968,7 +2997,7 @@
 IN_PROC_BROWSER_TEST_F(FakeSystemTracingDevToolsProtocolTest,
                        MAYBE_TracingWithFakeSystemBackend) {
   EXPECT_TRUE(StartSystemTrace());
-  EXPECT_TRUE(SendCommand("Tracing.end", nullptr, true));
+  EXPECT_TRUE(SendCommandSync("Tracing.end"));
   WaitForNotification("Tracing.tracingComplete", true);
 }
 
@@ -3045,7 +3074,7 @@
                                              server.GetURL("/title1.html"), 1);
 
   Attach();
-  SendCommand("Network.enable", base::Value::Dict(), false);
+  SendCommandAsync("Network.enable");
 
   base::Value::Dict response =
       FetchAndWaitForResponse(server.GetURL("/empty.html"));
@@ -3126,7 +3155,7 @@
                                              server.GetURL("/title1.html"), 1);
 
   Attach();
-  SendCommand("Network.enable", base::Value::Dict(), false);
+  SendCommandAsync("Network.enable");
 
   base::Value::Dict response =
       FetchAndWaitForResponse(server.GetURL("/empty.html"));
@@ -3185,7 +3214,7 @@
                                              server.GetURL("/title1.html"), 1);
 
   Attach();
-  SendCommand("Network.enable", base::Value::Dict(), false);
+  SendCommandAsync("Network.enable");
 
   base::Value::Dict response =
       FetchAndWaitForResponse(server.GetURL("/empty.html"));
@@ -3226,7 +3255,7 @@
                                              server.GetURL("/title1.html"), 1);
 
   Attach();
-  SendCommand("Network.enable", base::Value::Dict(), false);
+  SendCommandAsync("Network.enable");
 
   base::Value::Dict response =
       FetchAndWaitForResponse(server.GetURL("/empty.html"));
@@ -3312,7 +3341,7 @@
                                              1);
 
   Attach();
-  SendCommand("Network.enable", base::Value::Dict(), false);
+  SendCommandAsync("Network.enable");
 
   base::Value::Dict response = FetchAndWaitForResponse(GetURL("/empty.html"));
   absl::optional<bool> ech = response.FindBoolByDottedPath(
@@ -3320,4 +3349,40 @@
   EXPECT_EQ(true, ech);
 }
 
+IN_PROC_BROWSER_TEST_F(PrerenderDevToolsProtocolTest,
+                       ReportPrerenderDisallowedAPICancellationDetails) {
+  base::HistogramTester histogram_tester;
+  ASSERT_TRUE(embedded_test_server()->Start());
+  const GURL kInitialUrl = GetUrl("/empty.html");
+  const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");
+
+  // Navigate to an initial page.
+  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
+
+  // Make a prerendered page.
+  int host_id = AddPrerender(kPrerenderingUrl);
+  auto* prerender_render_frame_host = GetPrerenderedMainFrameHost(host_id);
+  Attach();
+  SendCommand("Page.enable", nullptr, true);
+  SendCommand("Runtime.enable", nullptr, true);
+
+  // Executing `navigator.getGamepads()` to start binding the GamepadMonitor
+  // interface, and this is expected to cause prerender cancellation because
+  // the API is disallowed.
+  ExecuteScriptAsyncWithoutUserGesture(prerender_render_frame_host,
+                                       "navigator.getGamepads()");
+
+  base::Value::Dict result =
+      WaitForNotification("Page.prerenderAttemptCompleted", true);
+
+  // Verify Mojo capability control cancels prerendering.
+  EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
+  EXPECT_THAT(*result.FindString("reasonDetails"),
+              Eq("device.mojom.GamepadMonitor"));
+
+  histogram_tester.ExpectUniqueSample(
+      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
+      PrerenderHost::FinalStatus::kMojoBinderPolicy, 1);
+}
+
 }  // namespace content
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc
index 1d18955..5927c47 100644
--- a/content/browser/devtools/protocol/page_handler.cc
+++ b/content/browser/devtools/protocol/page_handler.cc
@@ -1940,13 +1940,17 @@
 
 void PageHandler::DidCancelPrerender(const GURL& prerendering_url,
                                      const std::string& initiating_frame_id,
-                                     PrerenderHost::FinalStatus status) {
+                                     PrerenderHost::FinalStatus status,
+                                     const std::string& reason_details) {
   if (!enabled_)
     return;
   DCHECK_NE(status, PrerenderHost::FinalStatus::kActivated);
-  frontend_->PrerenderAttemptCompleted(initiating_frame_id,
-                                       prerendering_url.spec(),
-                                       PrerenderFinalStatusToProtocol(status));
+  Maybe<std::string> opt_reason = reason_details.empty()
+                                      ? Maybe<std::string>()
+                                      : Maybe<std::string>(reason_details);
+  frontend_->PrerenderAttemptCompleted(
+      initiating_frame_id, prerendering_url.spec(),
+      PrerenderFinalStatusToProtocol(status), std::move(opt_reason));
 }
 
 bool PageHandler::ShouldBypassCSP() {
diff --git a/content/browser/devtools/protocol/page_handler.h b/content/browser/devtools/protocol/page_handler.h
index 2065335..1f38edf 100644
--- a/content/browser/devtools/protocol/page_handler.h
+++ b/content/browser/devtools/protocol/page_handler.h
@@ -111,7 +111,8 @@
   void DidActivatePrerender(const NavigationRequest& nav_request);
   void DidCancelPrerender(const GURL& prerendering_url,
                           const std::string& initiating_frame_id,
-                          PrerenderHost::FinalStatus status);
+                          PrerenderHost::FinalStatus status,
+                          const std::string& reason_details);
 
   Response Enable() override;
   Response Disable() override;
diff --git a/content/browser/devtools/protocol/visual_debugger_handler_browsertest.cc b/content/browser/devtools/protocol/visual_debugger_handler_browsertest.cc
index 59800bb..c4122d9 100644
--- a/content/browser/devtools/protocol/visual_debugger_handler_browsertest.cc
+++ b/content/browser/devtools/protocol/visual_debugger_handler_browsertest.cc
@@ -27,16 +27,15 @@
   GURL url = GURL("data:text/html,<body></body>");
   NavigateToURLBlockUntilNavigationsComplete(shell(), url, 1);
   Attach();
-  SendCommand("VisualDebugger.startStream", nullptr);
+  SendCommandSync("VisualDebugger.startStream");
   WaitForNotification("VisualDebugger.frameResponse", true);
 
-  std::unique_ptr<base::DictionaryValue> command_params =
-      std::make_unique<base::DictionaryValue>();
   auto filter_param =
       std::string(R"({"filters":[{"selector":{"anno":""},"active":true}]})");
-  command_params->SetString("json", filter_param);
-  SendCommand("VisualDebugger.filterStream", std::move(command_params));
-  SendCommand("VisualDebugger.stopStream", nullptr);
+  base::Value::Dict command_params;
+  command_params.Set("json", filter_param);
+  SendCommandSync("VisualDebugger.filterStream", std::move(command_params));
+  SendCommandSync("VisualDebugger.stopStream");
 }
 
 }  // namespace content
diff --git a/content/browser/plugin_service_impl.cc b/content/browser/plugin_service_impl.cc
index 1ad0267..d7c7984 100644
--- a/content/browser/plugin_service_impl.cc
+++ b/content/browser/plugin_service_impl.cc
@@ -117,6 +117,7 @@
     const base::FilePath& plugin_path,
     const base::FilePath& profile_data_directory,
     const absl::optional<url::Origin>& origin_lock) {
+#if BUILDFLAG(ENABLE_PPAPI)
   for (PpapiPluginProcessHostIterator iter; !iter.Done(); ++iter) {
     if (iter->plugin_path() == plugin_path &&
         iter->profile_data_directory() == profile_data_directory &&
@@ -124,6 +125,7 @@
       return *iter;
     }
   }
+#endif  // BUILDFLAG(ENABLE_PPAPI)
   return nullptr;
 }
 
@@ -132,6 +134,7 @@
     const base::FilePath& plugin_path,
     const base::FilePath& profile_data_directory,
     const absl::optional<url::Origin>& origin_lock) {
+#if BUILDFLAG(ENABLE_PPAPI)
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) {
@@ -168,6 +171,9 @@
   }
 
   return plugin_host;
+#else
+  return nullptr;
+#endif  // BUILDFLAG(ENABLE_PPAPI)
 }
 
 void PluginServiceImpl::OpenChannelToPpapiPlugin(
@@ -176,6 +182,7 @@
     const base::FilePath& profile_data_directory,
     const absl::optional<url::Origin>& origin_lock,
     PpapiPluginProcessHost::PluginClient* client) {
+#if BUILDFLAG(ENABLE_PPAPI)
   PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess(
       render_process_id, plugin_path, profile_data_directory, origin_lock);
   if (plugin_host) {
@@ -184,6 +191,7 @@
     // Send error.
     client->OnPpapiChannelOpened(IPC::ChannelHandle(), base::kNullProcessId, 0);
   }
+#endif  // BUILDFLAG(ENABLE_PPAPI)
 }
 
 bool PluginServiceImpl::GetPluginInfoArray(
@@ -266,14 +274,17 @@
 }
 
 void PluginServiceImpl::RegisterPepperPlugins() {
+#if BUILDFLAG(ENABLE_PPAPI)
   ComputePepperPluginList(&ppapi_plugins_);
   for (const auto& plugin : ppapi_plugins_)
     RegisterInternalPlugin(plugin.ToWebPluginInfo(), /*add_at_beginning=*/true);
+#endif  // BUILDFLAG(ENABLE_PPAPI)
 }
 
 // There should generally be very few plugins so a brute-force search is fine.
 const PepperPluginInfo* PluginServiceImpl::GetRegisteredPpapiPluginInfo(
     const base::FilePath& plugin_path) {
+#if BUILDFLAG(ENABLE_PPAPI)
   for (auto& plugin : ppapi_plugins_) {
     if (plugin.path == plugin_path)
       return &plugin;
@@ -292,6 +303,9 @@
     return nullptr;
   ppapi_plugins_.push_back(new_pepper_info);
   return &ppapi_plugins_.back();
+#else
+  return nullptr;
+#endif  // BUILDFLAG(ENABLE_PPAPI)
 }
 
 void PluginServiceImpl::SetFilter(PluginServiceFilter* filter) {
diff --git a/content/browser/preloading/prerender/prerender_host.h b/content/browser/preloading/prerender/prerender_host.h
index 516639d..fa06adc 100644
--- a/content/browser/preloading/prerender/prerender_host.h
+++ b/content/browser/preloading/prerender/prerender_host.h
@@ -175,6 +175,8 @@
   }
   const GURL& initiator_url() const { return attributes_.initiator_url; }
 
+  const GURL& prerendering_url() const { return attributes_.prerendering_url; }
+
   bool IsBrowserInitiated() { return attributes_.IsBrowserInitiated(); }
 
   int frame_tree_node_id() const { return frame_tree_node_id_; }
diff --git a/content/browser/preloading/prerender/prerender_metrics.cc b/content/browser/preloading/prerender/prerender_metrics.cc
index 6f582cd..2b22f880 100644
--- a/content/browser/preloading/prerender/prerender_metrics.cc
+++ b/content/browser/preloading/prerender/prerender_metrics.cc
@@ -113,16 +113,20 @@
         .Record(ukm::UkmRecorder::Get());
   }
 
-  // The kActivated case is recorded in `PrerenderHost::Activate`. Browser
-  // initiated prerendering doesn't report cancellation reasons to the DevTools
-  // as it doesn't have the initiator frame associated with DevTools agents.
+  // The kActivated case is recorded in `PrerenderHost::Activate`, and the
+  // kMojoBinderPolicy case is recorded in
+  // RenderFrameHostImpl::CancelPrerenderingByMojoBinderPolicy for storing the
+  // interface detail. Browser initiated prerendering doesn't report
+  // cancellation reasons to the DevTools as it doesn't have the initiator frame
+  // associated with DevTools agents.
   if (!attributes.IsBrowserInitiated() &&
-      status != PrerenderHost::FinalStatus::kActivated) {
+      status != PrerenderHost::FinalStatus::kActivated &&
+      status != PrerenderHost::FinalStatus::kMojoBinderPolicy) {
     auto* ftn = FrameTreeNode::GloballyFindByID(
         attributes.initiator_frame_tree_node_id);
     DCHECK(ftn);
     devtools_instrumentation::DidCancelPrerender(attributes.prerendering_url,
-                                                 ftn, status);
+                                                 ftn, status, "");
   }
 }
 
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 6ea342e..a8616adc 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -10504,6 +10504,19 @@
   // prerendering, as it could mean an interface request is never resolved for
   // an active page.
   DCHECK(canceled);
+
+  FrameTreeNode* prerender_initiator_frame = FrameTreeNode::GloballyFindByID(
+      prerender_host->initiator_frame_tree_node_id());
+  // The prerender initiator frame is used to report the cancellation to
+  // DevTools. When a prerender is canceled, we use the prerender initiator
+  // frame's DevTools agent instead of the cancelled prerendered frame's. This
+  // is because DevTools agent gets attached to a frame when it becomes active,
+  // so a canceled prerendered frame won't have a Devtools agent attached.
+  if (prerender_initiator_frame) {
+    devtools_instrumentation::DidCancelPrerender(
+        prerender_host->prerendering_url(), prerender_initiator_frame,
+        PrerenderHost::FinalStatus::kMojoBinderPolicy, interface_name);
+  }
 }
 
 void RenderFrameHostImpl::RendererWillActivateForPrerendering() {
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index 99558277..e49a388e 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -120,12 +120,6 @@
     "origin_util.cc",
     "partition_alloc_support.cc",
     "partition_alloc_support.h",
-    "pepper_file_util.cc",
-    "pepper_file_util.h",
-    "pepper_plugin_list.cc",
-    "pepper_plugin_list.h",
-    "pepper_renderer_instance_data.cc",
-    "pepper_renderer_instance_data.h",
     "process_type.cc",
     "process_visibility_tracker.cc",
     "process_visibility_tracker.h",
@@ -357,12 +351,7 @@
   }
 
   if (enable_ppapi) {
-    deps += [
-      "//ppapi/proxy:ipc",
-      "//ppapi/shared_impl",
-    ]
-  } else {
-    sources -= [
+    sources += [
       "pepper_file_util.cc",
       "pepper_file_util.h",
       "pepper_plugin_list.cc",
@@ -370,6 +359,10 @@
       "pepper_renderer_instance_data.cc",
       "pepper_renderer_instance_data.h",
     ]
+    deps += [
+      "//ppapi/proxy:ipc",
+      "//ppapi/shared_impl",
+    ]
   }
 
   if (is_mac) {
diff --git a/content/gpu/gpu_sandbox_hook_linux.cc b/content/gpu/gpu_sandbox_hook_linux.cc
index 9a689e3..ffe939f 100644
--- a/content/gpu/gpu_sandbox_hook_linux.cc
+++ b/content/gpu/gpu_sandbox_hook_linux.cc
@@ -45,7 +45,10 @@
 namespace {
 
 inline bool IsChromeOS() {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // TODO(b/206464999): for now, we're making the LaCrOS and Ash GPU sandboxes
+  // behave similarly. However, the LaCrOS GPU sandbox could probably be made
+  // tighter.
+#if BUILDFLAG(IS_CHROMEOS)
   return true;
 #else
   return false;
@@ -77,6 +80,7 @@
 }
 
 inline bool UseLibV4L2() {
+  // TODO(b/240881905): for LaCrOS, this will need to be determined at runtime.
 #if BUILDFLAG(USE_LIBV4L2)
   return true;
 #else
@@ -84,7 +88,7 @@
 #endif
 }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) && defined(__aarch64__)
+#if BUILDFLAG(IS_CHROMEOS) && defined(__aarch64__)
 static const char kLibGlesPath[] = "/usr/lib64/libGLESv2.so.2";
 static const char kLibEglPath[] = "/usr/lib64/libEGL.so.1";
 static const char kLibMaliPath[] = "/usr/lib64/libmali.so";
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index 83d16fbf..ea154d8f 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -524,13 +524,17 @@
     "//content/browser",
   ]
 
-  # TODO(crbug.com/1306610): Split out files that only need `enable_plugins`.
+  if (enable_plugins) {
+    sources += [
+      "plugin_service.h",
+      "plugin_service_filter.h",
+    ]
+  }
+
   if (enable_ppapi) {
     sources += [
       "browser_ppapi_host.h",
       "pepper_vpn_provider_resource_host_proxy.h",
-      "plugin_service.h",
-      "plugin_service_filter.h",
     ]
     deps += [ "//ppapi/c" ]
   }
diff --git a/content/public/renderer/BUILD.gn b/content/public/renderer/BUILD.gn
index 2f5967c..8efe76e 100644
--- a/content/public/renderer/BUILD.gn
+++ b/content/public/renderer/BUILD.gn
@@ -82,11 +82,13 @@
     "//content/renderer",
   ]
 
-  # TODO(crbug.com/1306610): Split out files that only need `enable_plugins`.
+  if (enable_plugins) {
+    sources += [ "plugin_ax_tree_source.h" ]
+  }
+
   if (enable_ppapi) {
     sources += [
       "pepper_plugin_instance.h",
-      "plugin_ax_tree_source.h",
       "ppapi_gfx_conversion.h",
       "renderer_ppapi_host.h",
     ]
diff --git a/content/public/test/test_devtools_protocol_client.h b/content/public/test/test_devtools_protocol_client.h
index fdb958de4..5465bc8 100644
--- a/content/public/test/test_devtools_protocol_client.h
+++ b/content/public/test/test_devtools_protocol_client.h
@@ -31,6 +31,21 @@
     return SendSessionCommand(method, std::move(params), std::string(), wait);
   }
 
+  const base::Value::Dict* SendCommandSync(std::string method) {
+    return SendCommand(std::move(method), base::Value::Dict(), true);
+  }
+  const base::Value::Dict* SendCommandSync(std::string method,
+                                           base::Value::Dict params) {
+    return SendCommand(std::move(method), std::move(params), true);
+  }
+  const base::Value::Dict* SendCommandAsync(std::string method) {
+    return SendCommand(std::move(method), base::Value::Dict(), false);
+  }
+  const base::Value::Dict* SendCommandAsync(std::string method,
+                                            base::Value::Dict params) {
+    return SendCommand(std::move(method), std::move(params), false);
+  }
+
   // DEPRECATED! Use the overload above.
   const base::Value::Dict* SendCommand(
       std::string method,
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index fe77cb5..bde274f 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -288,14 +288,13 @@
     ]
   }
 
-  # TODO(crbug.com/1306610): Split out files that only need `enable_plugins`.
-  if (enable_ppapi) {
+  if (enable_plugins) {
     sources += [
       "browser/shell_plugin_service_filter.cc",
       "browser/shell_plugin_service_filter.h",
     ]
-    deps += [ "//ppapi/shared_impl" ]
   }
+
   if (enable_cast_renderer) {
     deps += [ "//media/mojo/services" ]
   }
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index e00d9af..a6a2254 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1659,10 +1659,12 @@
     "//third_party/mesa_headers",
   ]
 
-  # TODO(crbug.com/1306610): Split out files that only need `enable_plugins`.
+  if (enable_plugins) {
+    sources += [ "../browser/plugin_service_impl_browsertest.cc" ]
+  }
+
   if (enable_ppapi) {
     sources += [
-      "../browser/plugin_service_impl_browsertest.cc",
       "../renderer/pepper/fake_pepper_plugin_instance.cc",
       "../renderer/pepper/fake_pepper_plugin_instance.h",
       "../renderer/pepper/mock_renderer_ppapi_host.cc",
diff --git a/extensions/browser/service_worker_task_queue.cc b/extensions/browser/service_worker_task_queue.cc
index 0493106..16fffce 100644
--- a/extensions/browser/service_worker_task_queue.cc
+++ b/extensions/browser/service_worker_task_queue.cc
@@ -12,6 +12,7 @@
 #include "base/bind.h"
 #include "base/containers/contains.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/syslog_logging.h"
 #include "content/public/browser/browser_context.h"
@@ -533,8 +534,11 @@
   }
 
   if (!success) {
+    std::string msg = base::StringPrintf(
+        "Service worker registration failed. Status code: %d",
+        static_cast<int>(status_code));
     auto error = std::make_unique<ManifestError>(
-        extension_id, u"Service worker registration failed",
+        extension_id, base::UTF8ToUTF16(msg),
         base::UTF8ToUTF16(manifest_keys::kBackground),
         base::UTF8ToUTF16(
             BackgroundInfo::GetBackgroundServiceWorkerScript(extension)));
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc
index 2678141..40c3b4e 100644
--- a/gpu/command_buffer/service/raster_decoder.cc
+++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -810,51 +810,43 @@
       GLsizei n,
       const volatile GLuint* paint_cache_ids);
   void DoClearPaintCacheINTERNAL();
-  void FlushAndSubmitIfNecessary(
-      SkSurface* surface,
-      std::unique_ptr<GrBackendSurfaceMutableState> TakeEndState,
-      std::vector<GrBackendSemaphore> signal_semaphores) {
-    bool sync_cpu = gpu::ShouldVulkanSyncCpuForSkiaSubmit(
-        shared_context_state_->vk_context_provider());
-    if (signal_semaphores.empty()) {
-      if (surface) {
-        surface->flush({}, TakeEndState.get());
-      } else {
-        gr_context()->flush();
-      }
 
-      // If DrDc is enabled, submit the gr_context() to ensure correct ordering
-      // of vulkan commands between raster and display compositor.
-      // TODO(vikassoni): This submit could be happening more often than
-      // intended resulting in perf penalty. Explore ways to reduce it by
-      // trying to issue submit only once per draw call for both gpu main and
-      // drdc thread gr_context. Also add metric to see how often submits are
-      // happening per frame.
-      if (sync_cpu || is_drdc_enabled_) {
-        gr_context()->submit(sync_cpu);
-      }
-      return;
+  void FlushSurface(SkiaImageRepresentation::ScopedWriteAccess* access) {
+    auto* surface = access->surface();
+    auto end_state = access->TakeEndState();
+
+    DCHECK(surface);
+    surface->flush({}, end_state.get());
+  }
+
+  void SubmitIfNecessary(std::vector<GrBackendSemaphore> signal_semaphores) {
+    if (!signal_semaphores.empty()) {
+      GrFlushInfo flush_info = {
+          .fNumSemaphores = signal_semaphores.size(),
+          .fSignalSemaphores = signal_semaphores.data(),
+      };
+      gpu::AddVulkanCleanupTaskForSkiaFlush(
+          shared_context_state_->vk_context_provider(), &flush_info);
+
+      auto result = gr_context()->flush(flush_info);
+      DCHECK_EQ(result, GrSemaphoresSubmitted::kYes);
     }
 
-    // Always flush the surface even if source_scoped_access.success() is
-    // false, so the begin_semaphores can be released, and end_semaphores can
-    // be signalled.
-    GrFlushInfo flush_info = {
-        .fNumSemaphores = signal_semaphores.size(),
-        .fSignalSemaphores = signal_semaphores.data(),
-    };
-    gpu::AddVulkanCleanupTaskForSkiaFlush(
-        shared_context_state_->vk_context_provider(), &flush_info);
+    bool sync_cpu = gpu::ShouldVulkanSyncCpuForSkiaSubmit(
+        shared_context_state_->vk_context_provider());
 
-    GrSemaphoresSubmitted result;
-    if (surface)
-      result = surface->flush(flush_info, TakeEndState.get());
-    else
-      result = gr_context()->flush(flush_info);
-    // If the |signal_semaphores| is empty, we can deferred the queue
-    // submission.
-    DCHECK_EQ(result, GrSemaphoresSubmitted::kYes);
-    gr_context()->submit(sync_cpu);
+    // If DrDc is enabled, submit the gr_context() to ensure correct ordering
+    // of vulkan commands between raster and display compositor.
+    // TODO(vikassoni): This submit could be happening more often than
+    // intended resulting in perf penalty. Explore ways to reduce it by
+    // trying to issue submit only once per draw call for both gpu main and
+    // drdc thread gr_context. Also add metric to see how often submits are
+    // happening per frame.
+    const bool need_submit =
+        sync_cpu || !signal_semaphores.empty() || is_drdc_enabled_;
+
+    if (need_submit)
+      gr_context()->submit(sync_cpu);
   }
 
 #if defined(NDEBUG)
@@ -2229,9 +2221,8 @@
     if (!dest_shared_image->IsCleared()) {
       dest_shared_image->SetClearedRect(new_cleared_rect);
     }
-    FlushAndSubmitIfNecessary(dest_scoped_access->surface(),
-                              dest_scoped_access->TakeEndState(),
-                              std::move(end_semaphores));
+    FlushSurface(dest_scoped_access.get());
+    SubmitIfNecessary(std::move(end_semaphores));
 
     // Note, we're intentionally don't mark this CopySubTexture as succeeded.
     return;
@@ -2265,6 +2256,8 @@
   if (!source_scoped_access) {
     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTexture",
                        "Source shared image is not accessable");
+    // We still need to flush surface for begin semaphores above.
+    FlushSurface(dest_scoped_access.get());
   } else {
     auto source_image = source_scoped_access->CreateSkImage(
         shared_context_state_->gr_context());
@@ -2284,6 +2277,8 @@
                           gfx::RectToSkRect(dest_rect), SkSamplingOptions(),
                           &paint, SkCanvas::kStrict_SrcRectConstraint);
 
+    FlushSurface(dest_scoped_access.get());
+
     if (auto end_state = source_scoped_access->TakeEndState()) {
       gr_context()->setBackendTextureState(
           source_scoped_access->promise_image_texture()->backendTexture(),
@@ -2295,9 +2290,7 @@
     }
   }
 
-  FlushAndSubmitIfNecessary(dest_scoped_access->surface(),
-                            dest_scoped_access->TakeEndState(),
-                            std::move(end_semaphores));
+  SubmitIfNecessary(std::move(end_semaphores));
 
   std::ignore = runner.Release();
   bug_1307307_tracker_.CopySubTextureFinished(source_mailbox, dest_mailbox,
@@ -2350,9 +2343,9 @@
 
   dest_scoped_access->surface()->writePixels(subset, xoffset, yoffset);
 
-  FlushAndSubmitIfNecessary(dest_scoped_access->surface(),
-                            dest_scoped_access->TakeEndState(),
-                            std::move(end_semaphores));
+  FlushSurface(dest_scoped_access);
+  SubmitIfNecessary(std::move(end_semaphores));
+
   if (!dest_shared_image->IsCleared()) {
     dest_shared_image->SetClearedRect(dest_cleared_rect);
   }
@@ -2498,9 +2491,9 @@
                        "Failed to write pixels to SkCanvas");
   }
 
-  FlushAndSubmitIfNecessary(dest_scoped_access->surface(),
-                            dest_scoped_access->TakeEndState(),
-                            std::move(end_semaphores));
+  FlushSurface(dest_scoped_access.get());
+  SubmitIfNecessary(std::move(end_semaphores));
+
   if (!dest_shared_image->IsCleared()) {
     dest_shared_image->SetClearedRect(
         gfx::Rect(x_offset, y_offset, src_width, src_height));
@@ -2541,7 +2534,7 @@
         dest_scoped_access->promise_image_texture()->backendTexture(),
         *end_state);
 
-  FlushAndSubmitIfNecessary(nullptr, nullptr, std::move(end_semaphores));
+  SubmitIfNecessary(std::move(end_semaphores));
   if (written && !dest_shared_image->IsCleared()) {
     dest_shared_image->SetClearedRect(
         gfx::Rect(src_info.width(), src_info.height()));
@@ -2692,7 +2685,7 @@
         *end_state);
   }
 
-  FlushAndSubmitIfNecessary(nullptr, nullptr, std::move(end_semaphores));
+  SubmitIfNecessary(std::move(end_semaphores));
 }
 
 namespace {
@@ -3099,9 +3092,9 @@
     }
   }
 
-  FlushAndSubmitIfNecessary(dest_scoped_access->surface(),
-                            dest_scoped_access->TakeEndState(),
-                            std::move(end_semaphores));
+  FlushSurface(dest_scoped_access.get());
+  SubmitIfNecessary(std::move(end_semaphores));
+
   if (!rgba_image->IsCleared() && drew_image) {
     rgba_image->SetCleared();
   }
@@ -3178,12 +3171,11 @@
   skia::BlitRGBAToYUVA(rgba_sk_image.get(), yuva_sk_surfaces, yuva_info);
 
   for (int i = 0; i < num_yuva_planes; ++i) {
-    FlushAndSubmitIfNecessary(yuva_scoped_access[i]->surface(),
-                              yuva_scoped_access[i]->TakeEndState(),
-                              end_semaphores);
+    FlushSurface(yuva_scoped_access[i].get());
     if (!yuva_images[i]->IsCleared())
       yuva_images[i]->SetCleared();
   }
+  SubmitIfNecessary(std::move(end_semaphores));
 }
 
 void RasterDecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
@@ -3559,10 +3551,12 @@
     // scoped_shared_image_write_ can be nullptr if sk_surface_ was set by
     // SetUpForRasterCHROMIUMForTest.
     if (scoped_shared_image_write_) {
+      FlushSurface(scoped_shared_image_write_.get());
+      // Flushing surface will cause vulkan command buffer to be recorded with
+      // image layout transitions as necessary. Transitioning layout back to
+      // desired need to be happening after.
       paint_op_shared_image_provider_->ApplyEndAccessState();
-      FlushAndSubmitIfNecessary(sk_surface_,
-                                scoped_shared_image_write_->TakeEndState(),
-                                std::move(end_semaphores_));
+      SubmitIfNecessary(std::move(end_semaphores_));
       end_semaphores_.clear();
     } else {
       DCHECK(end_semaphores_.empty());
diff --git a/headless/test/headless_printtopdf_browsertest.cc b/headless/test/headless_printtopdf_browsertest.cc
index 1f03bad..e93b75b8 100644
--- a/headless/test/headless_printtopdf_browsertest.cc
+++ b/headless/test/headless_printtopdf_browsertest.cc
@@ -26,6 +26,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size_conversions.h"
 #include "ui/gfx/geometry/size_f.h"
 
 namespace headless {
diff --git a/infra/orchestrator/BUILD.gn b/infra/orchestrator/BUILD.gn
index b007180f..137639b 100644
--- a/infra/orchestrator/BUILD.gn
+++ b/infra/orchestrator/BUILD.gn
@@ -25,6 +25,7 @@
   data = [
     # Various merge/collect scripts will likely need a venv specified in
     # the root vpython spec files.
+    "//.vpython",
     "//.vpython3",
 
     # Test specs the Orchestrator needs to trigger swarming tests
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm b/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm
index e8ba37b..252db7d 100644
--- a/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm
+++ b/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm
@@ -216,6 +216,11 @@
 // Verifies the UMA metric for page loads before a tab eviction by loading
 // some tabs, forcing a tab eviction, then checking the histogram.
 - (void)testPageLoadCountBeforeEvictedTab {
+  // TODO(crbug.com/1350733): Re-enable when flake fixed.
+  if (@available(iOS 16, *)) {
+    EARL_GREY_TEST_DISABLED(@"Test consistently failing on iOS16 iPhone 8.");
+  }
+
   [ChromeEarlGrey resetTabUsageRecorder];
   const GURL url1 = web::test::HttpServer::MakeUrl(kTestUrl1);
   // This test opens three tabs.
@@ -465,6 +470,10 @@
     // is displayed at the bottom of the tab grid and not evicted.
     EARL_GREY_TEST_SKIPPED(@"Thumbstrip keeps active tab alive.");
   }
+  // TODO(crbug.com/1350733): Re-enable when flake fixed.
+  if (@available(iOS 16, *)) {
+    EARL_GREY_TEST_DISABLED(@"Test consistently failing on iOS16 iPhone 8.");
+  }
 
   std::map<GURL, std::string> responses;
   const GURL slowURL = web::test::HttpServer::MakeUrl("http://slow");
@@ -522,6 +531,11 @@
 // Test that the USER_DID_NOT_WAIT metric is logged when the user opens an NTP
 // while the evicted tab is still reloading.
 - (void)testEvictedTabReloadSwitchToNTP {
+  // TODO(crbug.com/1350733): Re-enable when flake fixed.
+  if (@available(iOS 16, *)) {
+    EARL_GREY_TEST_DISABLED(@"Test consistently failing on iOS16 iPhone 8.");
+  }
+
   if ([ChromeEarlGrey isThumbstripEnabledForWindowWithNumber:0]) {
     // Skip this test if thumbstrip is enabled. When enabled, the current tab
     // is displayed at the bottom of the tab grid and not evicted.
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm b/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm
index a3ba8d7f..50344ec 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm
@@ -781,6 +781,11 @@
 // appearing, and that the Reading List entry is present in the Reading List.
 // Loads offline version by tapping on entry with delayed web server.
 - (void)testSavingToReadingListAndLoadBadNetwork {
+  // TODO(crbug.com/1350732): Re-enable when flake fixed.
+  if (@available(iOS 16, *)) {
+    EARL_GREY_TEST_DISABLED(@"Test consistently failing on iOS16 iPhone 8.");
+  }
+
   [ReadingListAppInterface forceConnectionToWifi];
   GURL distillableURL = self.testServer->GetURL(kDistillableURL);
   // Open http://potato
@@ -1202,6 +1207,11 @@
 
 // Tests the Mark as Read/Unread context menu action for a reading list entry.
 - (void)testContextMenuMarkAsReadAndBack {
+  // TODO(crbug.com/1350732): Re-enable when flake fixed.
+  if (@available(iOS 16, *)) {
+    EARL_GREY_TEST_DISABLED(@"Test consistently failing on iOS16 iPhone 8.");
+  }
+
   AddEntriesAndOpenReadingList();
 
   AssertAllEntriesVisible();
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
index f7887cc..65c5bebf 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
@@ -389,6 +389,11 @@
 // the empty state. Then tests tapping Undo shows Close All button again.
 // Validates this case when Tab Grid Bulk Actions feature is enabled.
 - (void)testCloseAllAndUndoCloseAll {
+  // TODO(crbug.com/1350734): Re-enable when flake fixed.
+  if (@available(iOS 16, *)) {
+    EARL_GREY_TEST_DISABLED(@"Test consistently failing on iOS16 iPhone 8.")
+  }
+
   [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
       performAction:grey_tap()];
 
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
index 2d9947d..798c051 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-0d4278da614e8918142233db1d33bf9deeacae9f
\ No newline at end of file
+9fe0f2162be4ced697e6f07db707bc135ac23071
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
index 92d07b3..1ba22d4 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-7ab49ee0ec9b270e97a342c36abc301129e63a96
\ No newline at end of file
+8f4a5c5a5f62d75b3ca4705bc2727d1b02593331
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
index d02e429..2e7d3be 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-b7be878e6e1d7b4500e1ac90416ef572b35abcdc
\ No newline at end of file
+cd072cde0cb2f455331eee5d6728c41af7372114
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
index ea8daae..cb12406 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-e7dfef64798e8a5948b912a91739d25370a0fa70
\ No newline at end of file
+7ed2815e6c16cdecf92eba324e9a905c61c73196
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
index bcfc2848..b08e671 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-e2a79c8604cb750762ce76422d977b4fc6f68afc
\ No newline at end of file
+5dfbdc3823521b70f99e0fafd9bf15da3efb7017
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
index 7164aa7..19756d3 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-ee2abbde8fb8c0d45795a8192402ad70a8a23e31
\ No newline at end of file
+4467deca235f48371f50d144ae348a5df20f557a
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
index 9ba9927e..7c478bc7 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-09e3b88555acb92ece71ea71a116399f83f174e0
\ No newline at end of file
+a5c1c298972615bea305e8581d110b9ec691f24d
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
index 5a3d39a1..cef1680 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-a0577e201776b9e43962509fd81c5738154442f1
\ No newline at end of file
+72514a32d02a101f13b74ce6099d2f09852098b4
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
index 0e70cc6..e015da10 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-88701d0afc39730fe19b5cddf720221353808028
\ No newline at end of file
+82fc58d0aeffd0886d5ef0d73508b8301aab61c5
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
index 9e9c2df..f1d936e 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-9284b8e54dcd621317e9eb708d4bd6437692e1e3
\ No newline at end of file
+f0c11690af3fac2e274462c808f4f385cb7cc60b
\ No newline at end of file
diff --git a/mojo/public/js/mojo_bindings_resources.grd b/mojo/public/js/mojo_bindings_resources.grd
index 4200c00..8af1efb 100644
--- a/mojo/public/js/mojo_bindings_resources.grd
+++ b/mojo/public/js/mojo_bindings_resources.grd
@@ -26,7 +26,7 @@
           use_base_dir="false"
           resource_path="mojo/mojo/public/js/bindings.js"
           type="BINDATA" />
-      <if expr="chromeos_ash or chromeos_lacros">
+      <if expr="is_chromeos">
         <include name="IDR_MOJO_MOJO_BINDINGS_LITE_JS"
             file="${root_gen_dir}/mojo/public/js/mojo_bindings_lite.js"
             use_base_dir="false"
diff --git a/sandbox/policy/linux/bpf_gpu_policy_linux.cc b/sandbox/policy/linux/bpf_gpu_policy_linux.cc
index f8df9dc..e27980c4 100644
--- a/sandbox/policy/linux/bpf_gpu_policy_linux.cc
+++ b/sandbox/policy/linux/bpf_gpu_policy_linux.cc
@@ -50,10 +50,10 @@
   switch (sysno) {
     case __NR_kcmp:
       return Error(ENOSYS);
-#if !BUILDFLAG(IS_CHROMEOS_ASH)
+#if !BUILDFLAG(IS_CHROMEOS)
     case __NR_fallocate:
       return Allow();
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+#endif  // BUILDFLAG(IS_CHROMEOS)
     case __NR_fcntl: {
       // The Nvidia driver uses flags not in the baseline policy
       // fcntl(fd, F_ADD_SEALS, F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW)
diff --git a/sandbox/policy/linux/sandbox_seccomp_bpf_linux.cc b/sandbox/policy/linux/sandbox_seccomp_bpf_linux.cc
index 36b2147..1cd8d5b6 100644
--- a/sandbox/policy/linux/sandbox_seccomp_bpf_linux.cc
+++ b/sandbox/policy/linux/sandbox_seccomp_bpf_linux.cc
@@ -90,7 +90,7 @@
 // in its dependencies. Make sure to not link things that are not needed.
 #if !defined(IN_NACL_HELPER)
 inline bool IsChromeOS() {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
   return true;
 #else
   return false;
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 9401342..7bd86c2 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -2083,6 +2083,25 @@
             ]
         }
     ],
+    "BreakupLongOmniboxTasks": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "params": {
+                        "clear_focus_asynchronously": "true"
+                    },
+                    "enable_features": [
+                        "ClearOmniboxFocusAfterNavigation",
+                        "PostTaskFocusTab"
+                    ]
+                }
+            ]
+        }
+    ],
     "BrowserSwitcherNoneIsGreylist": [
         {
             "platforms": [
@@ -6424,21 +6443,6 @@
             ]
         }
     ],
-    "OmniboxPostTaskFocusTabAndroid": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "PostTaskFocusTab"
-                    ]
-                }
-            ]
-        }
-    ],
     "OmniboxPrerender": [
         {
             "platforms": [
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index 38f9c63..82663ce 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -8460,12 +8460,15 @@
       FailToGetMemoryUsage
 
   # Fired when a prerender attempt is completed.
-  event prerenderAttemptCompleted
+  experimental event prerenderAttemptCompleted
     parameters
       # The frame id of the frame initiating prerendering.
       FrameId initiatingFrameId
       string prerenderingUrl
       PrerenderFinalStatus finalStatus
+      # This is used to give users more information about the cancellation details,
+      # and this will be formatted for display.
+      optional string reasonDetails
 
   event loadEventFired
     parameters
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
index 7b9d2573..1c23b05 100644
--- a/third_party/blink/renderer/core/html/parser/html_document_parser.cc
+++ b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
@@ -454,32 +454,6 @@
   return HTMLTokenizer::kDataState;
 }
 
-class ScopedYieldTimer {
- public:
-  // This object is created at the start of a block of parsing, and will
-  // report the time since the last block yielded if known.
-  ScopedYieldTimer(std::unique_ptr<base::ElapsedTimer>* timer,
-                   HTMLParserMetrics* metrics_reporter)
-      : timer_(timer), reporting_metrics_(metrics_reporter) {
-    if (!reporting_metrics_ || !(*timer_))
-      return;
-
-    metrics_reporter->AddYieldInterval((*timer_)->Elapsed());
-    timer_->reset();
-  }
-
-  // The destructor creates a new timer, which will keep track of time until
-  // the next block starts.
-  ~ScopedYieldTimer() {
-    if (reporting_metrics_)
-      *timer_ = std::make_unique<base::ElapsedTimer>();
-  }
-
- private:
-  std::unique_ptr<base::ElapsedTimer>* timer_;
-  bool reporting_metrics_;
-};
-
 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document,
                                        ParserSynchronizationPolicy sync_policy,
                                        ParserPrefetchPolicy prefetch_policy)
diff --git a/third_party/blink/renderer/platform/image-decoders/jxl/jxl_image_decoder_test.cc b/third_party/blink/renderer/platform/image-decoders/jxl/jxl_image_decoder_test.cc
index a687044..aac0473 100644
--- a/third_party/blink/renderer/platform/image-decoders/jxl/jxl_image_decoder_test.cc
+++ b/third_party/blink/renderer/platform/image-decoders/jxl/jxl_image_decoder_test.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/platform/image-decoders/image_decoder_test_helpers.h"
+#include "third_party/skia/include/core/SkColorSpace.h"
 #include "ui/gfx/geometry/point.h"
 
 namespace blink {
@@ -146,6 +147,9 @@
                ColorBehavior color_behavior,
                int accuracy,
                size_t num_frames = 1) {
+  SCOPED_TRACE(testing::Message()
+               << "TestPixel jxl_file: " << jxl_file
+               << ", alpha_option:" << static_cast<int>(alpha_option));
   EXPECT_EQ(coordinates.size(), expected_colors.size());
   auto decoder = CreateJXLDecoderWithArguments(
       jxl_file, alpha_option, ImageDecoder::kDefaultBitDepth, color_behavior);
@@ -159,8 +163,11 @@
   }
   EXPECT_FALSE(decoder->Failed());
   for (size_t i = 0; i < coordinates.size(); ++i) {
+    SCOPED_TRACE(testing::Message() << "Coordinate: " << i);
     const SkBitmap& bitmap =
         decoder->DecodeFrameBufferAtIndex(coordinates[i].frame)->Bitmap();
+    EXPECT_TRUE(SkColorSpace::Equals(bitmap.colorSpace(),
+                                     decoder->ColorSpaceForSkImages().get()));
     int x = coordinates[i].point.x();
     int y = coordinates[i].point.y();
     SkColor frame_color = bitmap.getColor(x, y);
@@ -414,31 +421,31 @@
                 SkColorSetARGB(255, 255, 0, 0),
                 SkColorSetARGB(255, 0, 255, 0),
                 SkColorSetARGB(255, 0, 0, 255),
-                SkColorSetARGB(255, 225, 0, 36),
-                SkColorSetARGB(255, 0, 191, 0),
-                SkColorSetARGB(255, 0, 41, 190),
+                SkColorSetARGB(255, 128, 64, 64),
+                SkColorSetARGB(255, 64, 128, 64),
+                SkColorSetARGB(255, 64, 64, 128),
                 SkColorSetARGB(255, 255, 255, 255),
-                SkColorSetARGB(255, 181, 181, 181),
+                SkColorSetARGB(255, 128, 128, 128),
                 SkColorSetARGB(255, 0, 0, 0),
             },
             ImageDecoder::AlphaOption::kAlphaPremultiplied,
-            ColorBehavior::TransformToSRGB(), 2);
+            ColorBehavior::Tag(), 2);
 
   TestPixel("/images/resources/jxl/3x3_pq_lossy.jxl", gfx::Size(3, 3),
             coordinates_3x3,
             {
                 SkColorSetARGB(255, 255, 0, 0),
-                SkColorSetARGB(255, 0, 255, 0),
-                SkColorSetARGB(255, 0, 0, 255),
-                SkColorSetARGB(255, 226, 0, 37),
-                SkColorSetARGB(255, 0, 191, 0),
-                SkColorSetARGB(255, 0, 37, 195),
+                SkColorSetARGB(255, 64, 255, 64),
+                SkColorSetARGB(255, 39, 76, 255),
+                SkColorSetARGB(255, 128, 64, 64),
+                SkColorSetARGB(255, 64, 128, 64),
+                SkColorSetARGB(255, 64, 64, 128),
                 SkColorSetARGB(255, 255, 255, 255),
-                SkColorSetARGB(255, 182, 180, 189),
+                SkColorSetARGB(255, 128, 128, 128),
                 SkColorSetARGB(255, 0, 0, 0),
             },
             ImageDecoder::AlphaOption::kAlphaPremultiplied,
-            ColorBehavior::TransformToSRGB(), 15);
+            ColorBehavior::Tag(), 15);
 
   TestPixel("/images/resources/jxl/3x3a_pq_lossless.jxl", gfx::Size(3, 3),
             coordinates_3x3,
@@ -446,31 +453,31 @@
                 SkColorSetARGB(128, 255, 0, 0),
                 SkColorSetARGB(128, 0, 255, 0),
                 SkColorSetARGB(128, 0, 0, 255),
-                SkColorSetARGB(128, 225, 0, 36),
-                SkColorSetARGB(128, 0, 191, 0),
-                SkColorSetARGB(128, 0, 42, 189),
+                SkColorSetARGB(128, 128, 64, 64),
+                SkColorSetARGB(128, 64, 128, 64),
+                SkColorSetARGB(128, 64, 64, 128),
                 SkColorSetARGB(128, 255, 255, 255),
-                SkColorSetARGB(128, 181, 181, 181),
+                SkColorSetARGB(128, 128, 128, 128),
                 SkColorSetARGB(128, 0, 0, 0),
             },
             ImageDecoder::AlphaOption::kAlphaPremultiplied,
-            ColorBehavior::TransformToSRGB(), 2);
+            ColorBehavior::Tag(), 2);
 
   TestPixel("/images/resources/jxl/3x3a_pq_lossy.jxl", gfx::Size(3, 3),
             coordinates_3x3,
             {
                 SkColorSetARGB(128, 255, 0, 0),
-                SkColorSetARGB(128, 0, 255, 0),
-                SkColorSetARGB(128, 0, 0, 255),
-                SkColorSetARGB(128, 225, 0, 38),
-                SkColorSetARGB(128, 0, 191, 0),
-                SkColorSetARGB(128, 0, 38, 195),
+                SkColorSetARGB(128, 64, 255, 64),
+                SkColorSetARGB(128, 40, 82, 255),
+                SkColorSetARGB(128, 128, 64, 64),
+                SkColorSetARGB(128, 64, 128, 64),
+                SkColorSetARGB(128, 64, 64, 128),
                 SkColorSetARGB(128, 255, 255, 255),
-                SkColorSetARGB(128, 181, 179, 189),
+                SkColorSetARGB(128, 128, 128, 128),
                 SkColorSetARGB(128, 0, 0, 0),
             },
             ImageDecoder::AlphaOption::kAlphaPremultiplied,
-            ColorBehavior::TransformToSRGB(), 2);
+            ColorBehavior::Tag(), 15);
 
   TestPixel("/images/resources/jxl/3x3_hlg_lossless.jxl", gfx::Size(3, 3),
             coordinates_3x3,
@@ -478,31 +485,31 @@
                 SkColorSetARGB(255, 255, 0, 0),
                 SkColorSetARGB(255, 0, 255, 0),
                 SkColorSetARGB(255, 0, 0, 255),
-                SkColorSetARGB(255, 99, 30, 39),
-                SkColorSetARGB(255, 0, 86, 32),
-                SkColorSetARGB(255, 35, 39, 85),
+                SkColorSetARGB(255, 86, 46, 46),
+                SkColorSetARGB(255, 46, 86, 46),
+                SkColorSetARGB(255, 46, 46, 86),
                 SkColorSetARGB(255, 255, 255, 255),
-                SkColorSetARGB(255, 82, 82, 82),
+                SkColorSetARGB(255, 85, 85, 85),
                 SkColorSetARGB(255, 0, 0, 0),
             },
             ImageDecoder::AlphaOption::kAlphaPremultiplied,
-            ColorBehavior::TransformToSRGB(), 15);
+            ColorBehavior::Tag(), 2);
 
   TestPixel("/images/resources/jxl/3x3_hlg_lossy.jxl", gfx::Size(3, 3),
             coordinates_3x3,
             {
-                SkColorSetARGB(255, 255, 0, 0),
-                SkColorSetARGB(255, 0, 255, 0),
-                SkColorSetARGB(255, 0, 0, 255),
-                SkColorSetARGB(255, 185, 61, 75),
-                SkColorSetARGB(255, 0, 161, 66),
-                SkColorSetARGB(255, 74, 77, 160),
+                SkColorSetARGB(255, 255, 13, 13),
+                SkColorSetARGB(255, 13, 255, 13),
+                SkColorSetARGB(255, 13, 13, 255),
+                SkColorSetARGB(255, 128, 64, 64),
+                SkColorSetARGB(255, 64, 128, 64),
+                SkColorSetARGB(255, 64, 64, 128),
                 SkColorSetARGB(255, 255, 255, 255),
-                SkColorSetARGB(255, 159, 151, 154),
+                SkColorSetARGB(255, 128, 128, 128),
                 SkColorSetARGB(255, 0, 0, 0),
             },
             ImageDecoder::AlphaOption::kAlphaPremultiplied,
-            ColorBehavior::TransformToSRGB(), 15);
+            ColorBehavior::Tag(), 15);
 
   TestPixel("/images/resources/jxl/3x3a_hlg_lossless.jxl", gfx::Size(3, 3),
             coordinates_3x3,
@@ -510,31 +517,31 @@
                 SkColorSetARGB(128, 255, 0, 0),
                 SkColorSetARGB(128, 0, 255, 0),
                 SkColorSetARGB(128, 0, 0, 255),
-                SkColorSetARGB(128, 99, 30, 39),
-                SkColorSetARGB(128, 0, 86, 32),
-                SkColorSetARGB(128, 35, 39, 85),
+                SkColorSetARGB(128, 86, 46, 46),
+                SkColorSetARGB(128, 46, 86, 46),
+                SkColorSetARGB(128, 46, 46, 86),
                 SkColorSetARGB(128, 255, 255, 255),
-                SkColorSetARGB(128, 82, 82, 82),
+                SkColorSetARGB(128, 85, 85, 85),
                 SkColorSetARGB(128, 0, 0, 0),
             },
             ImageDecoder::AlphaOption::kAlphaPremultiplied,
-            ColorBehavior::TransformToSRGB(), 6);
+            ColorBehavior::Tag(), 6);
 
   TestPixel("/images/resources/jxl/3x3a_hlg_lossy.jxl", gfx::Size(3, 3),
             coordinates_3x3,
             {
-                SkColorSetARGB(128, 255, 0, 0),
-                SkColorSetARGB(128, 0, 255, 0),
-                SkColorSetARGB(128, 0, 0, 255),
-                SkColorSetARGB(128, 185, 62, 76),
-                SkColorSetARGB(128, 0, 161, 66),
-                SkColorSetARGB(128, 74, 78, 159),
+                SkColorSetARGB(128, 255, 13, 13),
+                SkColorSetARGB(128, 13, 255, 13),
+                SkColorSetARGB(128, 13, 13, 255),
+                SkColorSetARGB(128, 128, 64, 64),
+                SkColorSetARGB(128, 64, 128, 64),
+                SkColorSetARGB(128, 74, 64, 128),
                 SkColorSetARGB(128, 255, 255, 255),
-                SkColorSetARGB(128, 159, 151, 153),
+                SkColorSetARGB(128, 128, 128, 128),
                 SkColorSetARGB(128, 0, 0, 0),
             },
             ImageDecoder::AlphaOption::kAlphaPremultiplied,
-            ColorBehavior::TransformToSRGB(), 15);
+            ColorBehavior::Tag(), 15);
 }
 
 TEST(JXLTests, ColorProfileTest) {
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py
index 2d030ca..a5e8cd6 100644
--- a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py
+++ b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py
@@ -253,7 +253,9 @@
             test_passed = current_node['actual'] == 'PASS'
             self._maybe_write_text_results(artifacts, current_path,
                                            test_passed)
-            self._maybe_write_screenshots(artifacts, current_path)
+            diff_stats = self._maybe_write_screenshots(artifacts, current_path)
+            if diff_stats:
+                current_node["image_diff_stats"] = diff_stats
             self._maybe_write_logs(artifacts, current_path)
             # Required by blinkpy/web_tests/results.html to show stderr.
             if 'stderr' in artifacts:
@@ -372,6 +374,7 @@
 
     def _maybe_write_screenshots(self, artifacts, test_name):
         """Write actual, expected, and diff screenshots to disk, if possible.
+        Returns the diff stats if the screenshots are different.
 
         The raw "screenshots" artifact is a list of strings, each of which has
         the format "<url>:<base64-encoded PNG>". Each URL-PNG pair is a
@@ -415,8 +418,8 @@
             )
             artifacts[screenshot_key] = [screenshot_subpath]
 
-        diff_bytes, _, error = self.port.diff_image(expected_image_bytes,
-                                                    actual_image_bytes)
+        diff_bytes, stats, error = self.port.diff_image(
+            expected_image_bytes, actual_image_bytes)
         if error:
             _log.error(
                 'Error creating diff image for %s '
@@ -430,6 +433,8 @@
             )
             artifacts['image_diff'] = [diff_subpath]
 
+        return stats
+
     def _maybe_write_logs(self, artifacts, test_name):
         """Write WPT logs to disk, if possible."""
         log = artifacts.pop('wpt_log', None)
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor_unittest.py
index c42a1528..ba1a994 100644
--- a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor_unittest.py
+++ b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor_unittest.py
@@ -619,6 +619,10 @@
         self.assertEqual(
             [self.fs.join(path_from_out_dir_base, 'reftest-diff.png')],
             test_node['artifacts']['image_diff'])
+        self.assertEqual({
+            'maxDifference': 100,
+            'maxPixels': 3
+        }, test_node['image_diff_stats'])
 
     def test_copy_expected_output(self):
         # Check that an -expected.txt file is created from a checked-in metadata
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/base.py b/third_party/blink/tools/blinkpy/web_tests/port/base.py
index 65cd3e4e..276674e 100644
--- a/third_party/blink/tools/blinkpy/web_tests/port/base.py
+++ b/third_party/blink/tools/blinkpy/web_tests/port/base.py
@@ -494,8 +494,11 @@
     def baseline_flag_specific_dir(self):
         """If --additional-driver-flag is specified, returns the absolute path to the flag-specific
            platform-independent results. Otherwise returns None."""
-        flag_specific_path = self._flag_specific_baseline_search_path()
-        return flag_specific_path[-1] if flag_specific_path else None
+        config_name = self.flag_specific_config_name()
+        if not config_name:
+            return None
+        return self._filesystem.join(self.web_tests_dir(), 'flag-specific',
+                                     config_name)
 
     def baseline_search_path(self):
         return (self.get_option('additional_platform_directory', []) +
@@ -1814,18 +1817,8 @@
             return self.path_to_flag_specific_expectations_file(config_name)
 
     def _flag_specific_baseline_search_path(self):
-        config_name = self.flag_specific_config_name()
-        if not config_name:
-            return []
-        flag_dir = self._filesystem.join(self.web_tests_dir(), 'flag-specific',
-                                         config_name)
-        # FIXME: should we delete the line below? We only run flag specific
-        # tests on linux now
-        baseline_dirs = [
-            self._filesystem.join(flag_dir, 'platform', baseline_dir)
-            for baseline_dir in self.FALLBACK_PATHS[self.version()]
-        ]
-        return baseline_dirs + [flag_dir]
+        dir = self.baseline_flag_specific_dir()
+        return [dir] if dir else []
 
     def expectations_dict(self):
         """Returns an OrderedDict of name -> expectations strings.
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/base_unittest.py b/third_party/blink/tools/blinkpy/web_tests/port/base_unittest.py
index e60f110..58a091bf 100644
--- a/third_party/blink/tools/blinkpy/web_tests/port/base_unittest.py
+++ b/third_party/blink/tools/blinkpy/web_tests/port/base_unittest.py
@@ -237,13 +237,11 @@
         port._options.additional_platform_directory = []
         port._options.additional_driver_flag = ['--special-flag']
         self.assertEqual(port.baseline_search_path(), [
-            MOCK_WEB_TESTS + 'flag-specific/special-flag/platform/foo',
             MOCK_WEB_TESTS + 'flag-specific/special-flag',
             MOCK_WEB_TESTS + 'platform/foo'
         ])
-        self.assertEqual(
-            port.baseline_version_dir(),
-            MOCK_WEB_TESTS + 'flag-specific/special-flag/platform/foo')
+        self.assertEqual(port.baseline_version_dir(),
+                         MOCK_WEB_TESTS + 'flag-specific/special-flag')
 
         # Flag-specific baseline
         port.host.filesystem.write_text_file(
@@ -295,20 +293,19 @@
             MOCK_WEB_TESTS +
             'flag-specific/special-flag/platform/foo/fast/test-expected.txt',
             'foo')
-        self.assertEqual(
-            port.expected_baselines(test_file, '.txt'),
-            [(MOCK_WEB_TESTS + 'flag-specific/special-flag/platform/foo',
-              'fast/test-expected.txt')])
+        self.assertEqual(port.expected_baselines(test_file, '.txt'),
+                         [(MOCK_WEB_TESTS + 'flag-specific/special-flag',
+                           'fast/test-expected.txt')])
         self.assertEqual(
             port.expected_filename(test_file, '.txt'), MOCK_WEB_TESTS +
-            'flag-specific/special-flag/platform/foo/fast/test-expected.txt')
+            'flag-specific/special-flag/fast/test-expected.txt')
         self.assertEqual(
             port.expected_filename(test_file, '.txt',
                                    return_default=False), MOCK_WEB_TESTS +
-            'flag-specific/special-flag/platform/foo/fast/test-expected.txt')
+            'flag-specific/special-flag/fast/test-expected.txt')
         self.assertEqual(
-            port.fallback_expected_filename(test_file, '.txt'), MOCK_WEB_TESTS
-            + 'flag-specific/special-flag/fast/test-expected.txt')
+            port.fallback_expected_filename(test_file, '.txt'),
+            MOCK_WEB_TESTS + 'platform/foo/fast/test-expected.txt')
 
     def test_expected_baselines_virtual(self):
         port = self.make_port(port_name='foo')
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
index af6f942..92ceb17 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
+++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -1232,6 +1232,7 @@
 crbug.com/591099 virtual/compositor_threaded_scrollbar_scrolling/paint/invalidation/scroll/sticky/invalidate-after-composited-scroll-with-sticky.html [ Failure ]
 
 crbug.com/591099 external/wpt/css/css-flexbox/flexbox-min-width-auto-005.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-flexbox/flexbox-min-width-auto-006.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-flexbox/flexbox_align-items-stretch-3.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-flexbox/percentage-heights-006.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-flexbox/percentage-heights-014.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 02c4849..ca97ee1 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -318,6 +318,8 @@
 crbug.com/1311705 virtual/document-transition-wide-gamut/wpt_internal/document-transition/old-content-captures-different-size.html [ Failure ]
 crbug.com/1311705 virtual/document-transition-wide-gamut/wpt_internal/document-transition/old-content-captures-opacity.html [ Failure ]
 
+crbug.com/1350640 [ Mac11 ] virtual/document-transition-wide-gamut/wpt_internal/document-transition/commit-timeout-crash.html [ Timeout ]
+
 ########## Ref tests can't be rebaselined ##########
 crbug.com/619103 paint/invalidation/background/background-resize-width.html [ Failure Pass ]
 
@@ -1504,10 +1506,6 @@
 crbug.com/886585 external/wpt/css/css-flexbox/flexbox-align-self-baseline-horiz-007.xhtml [ Failure ]
 crbug.com/886585 external/wpt/css/css-flexbox/flexbox-align-self-baseline-horiz-008.xhtml [ Failure ]
 
-# Bad test expectations, but we aren't sure if web compatible yet.
-crbug.com/1114280 external/wpt/css/css-flexbox/flexbox-min-width-auto-005.html [ Failure ]
-crbug.com/1114280 external/wpt/css/css-flexbox/flexbox-min-width-auto-006.html [ Failure ]
-
 # [css-lists]
 crbug.com/1123457 external/wpt/css/css-lists/counter-list-item.html [ Failure ]
 crbug.com/1123457 external/wpt/css/css-lists/counter-list-item-2.html [ Failure ]
@@ -3368,6 +3366,8 @@
 crbug.com/626703 [ Win ] virtual/partitioned-cookies/http/tests/inspector-protocol/network/disabled-cache-navigation.js [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 [ Mac11-arm64 ] external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-022.html [ Failure ]
+crbug.com/626703 [ Mac12 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-018.https.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-pseudo/lang-pseudo-class-across-shadow-boundaries.html [ Failure ]
 crbug.com/626703 external/wpt/custom-elements/throw-on-dynamic-markup-insertion-counter-construct-xml-parser.xhtml [ Crash ]
 crbug.com/626703 [ Linux ] external/wpt/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions-xml-parser.xhtml [ Crash ]
diff --git a/third_party/blink/web_tests/android/ChromeWPTOverrideExpectations b/third_party/blink/web_tests/android/ChromeWPTOverrideExpectations
index a2bc9456..8f589d2 100644
--- a/third_party/blink/web_tests/android/ChromeWPTOverrideExpectations
+++ b/third_party/blink/web_tests/android/ChromeWPTOverrideExpectations
@@ -1727,7 +1727,6 @@
 crbug.com/1050754 external/wpt/webrtc/RTCDTMFSender-ontonechange.https.html [ Timeout ]
 crbug.com/1050754 external/wpt/webrtc/RTCIceConnectionState-candidate-pair.https.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-operations.https.html [ Failure ]
-crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-offer.html [ Failure ]
 crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-rollback.html [ Crash Pass ]
 crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-videoDetectorTest.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/webrtc/protocol/rtp-clockrate.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations b/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations
index 79b20e9..f0c44ac9 100644
--- a/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations
+++ b/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations
@@ -1778,7 +1778,6 @@
 crbug.com/1050754 external/wpt/webrtc/RTCDTMFSender-ontonechange.https.html [ Failure Timeout ]
 crbug.com/1050754 external/wpt/webrtc/RTCIceConnectionState-candidate-pair.https.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-operations.https.html [ Failure ]
-crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-offer.html [ Failure ]
 crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-rollback.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-videoDetectorTest.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/webrtc/protocol/rtp-clockrate.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/android/WebviewWPTExpectations b/third_party/blink/web_tests/android/WebviewWPTExpectations
index ad25162..84e6862 100644
--- a/third_party/blink/web_tests/android/WebviewWPTExpectations
+++ b/third_party/blink/web_tests/android/WebviewWPTExpectations
@@ -4986,7 +4986,6 @@
 crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-setLocalDescription-parameterless.https.html [ Pass Timeout ]
 crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-setLocalDescription-pranswer.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-setLocalDescription-rollback.html [ Failure Pass ]
-crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-offer.html [ Failure ]
 crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-simulcast.https.html [ Failure Pass ]
 crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html [ Timeout ]
 crbug.com/1050754 external/wpt/webrtc/RTCPeerConnection-setRemoteDescription.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version
index 959063e..41ba409 100644
--- a/third_party/blink/web_tests/external/Version
+++ b/third_party/blink/web_tests/external/Version
@@ -1 +1 @@
-Version: 853d9c3a31016504d1a51aa811c9890495a1d442
+Version: a7353198a551342aa02f843c2c50ea1fca502ab7
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 3736da5..71c78a6 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -328363,6 +328363,10 @@
       "97d77fcc58a3bbd347a98e2cbd9fa6243a83838a",
       []
      ],
+     "iframe-load-from-mem-cache-transfer-size.html": [
+      "6f37a33e8c2e83f3347b3c18ce0fb2d1ed5efe10",
+      []
+     ],
      "iframe-navigate-back.html": [
       "f944b633e2f207774789c8cd602dac6abc5b8a47",
       []
@@ -328495,6 +328499,10 @@
       "cf1c1df39200029cd4ff89933841b8cc96f6768c",
       []
      ],
+     "resource_timing_test0.js.headers": [
+      "308bee94d0e47a70ac88b59d71de0ff661fca27f",
+      []
+     ],
      "resource_timing_test0.png": [
       "be211bc377180386eec7e891485e083a2c45841e",
       []
@@ -331695,7 +331703,7 @@
        []
       ],
       "update-max-aged-worker.py": [
-       "221ef771d9bc8adb6bc3a42b11d95e8acae55f1c",
+       "4f879069ef98ad7ff738cf144fe1fd75fdd1089e",
        []
       ],
       "update-missing-import-scripts-imported-worker.py": [
@@ -379728,7 +379736,14 @@
      ],
      "intrinsic-size": {
       "row-005.html": [
-       "986a657fdc83a68e9bd3675533dddb97eae498b8",
+       "0f34c6fbdb400c35af723c8be56c22bbe1612e96",
+       [
+        null,
+        {}
+       ]
+      ],
+      "row-008.html": [
+       "b34306b483fa2cde8f0c862a698e85f0fe1b8839",
        [
         null,
         {}
@@ -398994,7 +399009,7 @@
       ]
      ],
      "clamp-length-serialize.html": [
-      "4719e4c0254902bb1c2234c4cfc1c4003a8df0d4",
+      "2aa8564f6c15128202e3f014aede26ed93b53e2d",
       [
        null,
        {}
@@ -449740,41 +449755,6 @@
           {}
          ]
         ],
-        "canvas-colorManaged-convertToBlob-roundtrip.html": [
-         "75bd34da3d13c1d1433f5ac21af38173949239fd",
-         [
-          null,
-          {}
-         ]
-        ],
-        "canvas-colorManaged-toBlob-toDataURL.html": [
-         "87f8d6d7f150bef803b700f2d8ff9f518b52aec0",
-         [
-          null,
-          {}
-         ]
-        ],
-        "canvas-colorspace-arguments.html": [
-         "f44b3240bcf7f1fca8f0d6058e62f63874f05773",
-         [
-          null,
-          {}
-         ]
-        ],
-        "canvas-createImageBitmap-e_srgb.html": [
-         "9fa42000dfc48fb22c33880ff30e45b0cf652d4b",
-         [
-          null,
-          {}
-         ]
-        ],
-        "canvas-createPutGetImageData-colorManaged.html": [
-         "2018acbbe775dbd1ab069a0e704ce356e867e023",
-         [
-          null,
-          {}
-         ]
-        ],
         "canvas-display-p3-drawImage-ImageBitmap-Blob.html": [
          "9b96b1a6d21ce7bdc4d45db8e07db4e4c828b2f6",
          [
@@ -449858,48 +449838,6 @@
           null,
           {}
          ]
-        ],
-        "canvas-draw-high-bit-depth-images.html": [
-         "d830d6ea335a4aa414f6b3923dcf17a8ce4da70f",
-         [
-          null,
-          {}
-         ]
-        ],
-        "canvas-drawImage-e_srgb.html": [
-         "793cd920338bb4992ea77cf9e748c6a34ccc2056",
-         [
-          null,
-          {}
-         ]
-        ],
-        "canvas-drawImage-offscreenCanvas.html": [
-         "aebcea3c1d14b1d78595df79a4d11a3171676b79",
-         [
-          null,
-          {}
-         ]
-        ],
-        "canvas-getImageData-e_srgb.html": [
-         "03e0d29720d67f628650eb62b04bf0ab1614fc39",
-         [
-          null,
-          {}
-         ]
-        ],
-        "imageData-colorManagedBehavior.html": [
-         "49078bab6723061e43007762e5a9de8169b95598",
-         [
-          null,
-          {}
-         ]
-        ],
-        "transferFromImageBitmap.html": [
-         "1b90396154969711550ba9090374f6307ff1f77a",
-         [
-          null,
-          {}
-         ]
         ]
        }
       },
@@ -480484,7 +480422,7 @@
        ]
       ],
       "popup-css-properties.tentative.html": [
-       "c0e58f06b95907d7b35e66558593f939ccf80814",
+       "ac5e9f7f2f4117d0667ce07b867be1e745aa4ef1",
        [
         null,
         {}
@@ -480519,7 +480457,7 @@
        ]
       ],
       "popup-focus.tentative.html": [
-       "76cc33261eaf8798814bbc672f9651221604c45b",
+       "979cb0a8feab692e9aa4a3eaaa5d09b41d62c4ea",
        [
         null,
         {
@@ -480529,17 +480467,7 @@
        ]
       ],
       "popup-hover-hide.tentative.html": [
-       "64a81a449fe5eccb846461420f3cfed574f83972",
-       [
-        null,
-        {
-         "testdriver": true,
-         "timeout": "long"
-        }
-       ]
-      ],
-      "popup-hoverpopup-attribute.tentative.html": [
-       "56646d4a22032f4ef3725cc6312ac889688ceccf",
+       "16acd687aae657a7b24a5fda8150b926c337fb93",
        [
         null,
         {
@@ -480584,6 +480512,16 @@
         }
        ]
       ],
+      "popup-popuphovertarget-attribute.tentative.html": [
+       "e845b0d49df5f4cd06b1a7c602d5a219f403605a",
+       [
+        null,
+        {
+         "testdriver": true,
+         "timeout": "long"
+        }
+       ]
+      ],
       "popup-removal-2.tentative.html": [
        "7cf0951e5b14bcca0a6af7d8846cb4f85e8b8995",
        [
@@ -522680,6 +522618,13 @@
       }
      ]
     ],
+    "load-from-mem-cache-transfer-size.html": [
+     "3d2d32d6e63bf4b2f4b715b2680047e3ca020166",
+     [
+      null,
+      {}
+     ]
+    ],
     "nested-context-navigations-embed.html": [
      "f804adbb8a99e44bd0f7d0c543ceea3f09e6ea62",
      [
@@ -557270,7 +557215,7 @@
      ]
     ],
     "RTCPeerConnection-addTrack.https.html": [
-     "d75022afb213e4c3fae0c8a21b69b17093a7572a",
+     "91665822c4901dfab7ba8813ce60a8c79073a371",
      [
       null,
       {
@@ -557606,7 +557551,7 @@
      ]
     ],
     "RTCPeerConnection-setRemoteDescription-offer.html": [
-     "247d6e0d49ec6447cde9d4e79127da7f9136ce39",
+     "d5acb7e1c933aa13a774b69f54ba4282905d2f4d",
      [
       null,
       {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox-min-width-auto-005.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox-min-width-auto-005.html
index 018d8e6..7cf43c4 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox-min-width-auto-005.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox-min-width-auto-005.html
@@ -2,8 +2,8 @@
 <title>CSS Flexible Box Test: Aspect ratio handling of images</title>
 <link rel="author" title="Sergio Villar Senin" href="mailto:svillar@igalia.com" />
 <link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#min-size-auto" />
+<link rel="help" href="https://github.com/web-platform-tests/wpt/issues/31609" />
 <link rel="match" href="reference/flexbox-min-width-auto-005-ref.html" />
-<meta name="assert" content="Test that min-width:auto does not incorrectly stretch items with aspect ratio" />
 
 <style>
 .reference-overlapped-red {
@@ -29,7 +29,7 @@
 
 <br>
 
-<div class="reference-overlapped-red" style="width: 40px;"></div>
+<div class="reference-overlapped-red"></div>
 <div style="display: flex">
     <div class="constrained-flex">
         <img src="support/40x20-green.png" />
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox-min-width-auto-006.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox-min-width-auto-006.html
index 7ff72d6..30e077e43 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox-min-width-auto-006.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox-min-width-auto-006.html
@@ -2,18 +2,10 @@
 <title>CSS Flexible Box Test: Aspect ratio handling of images</title>
 <link rel="author" title="Sergio Villar Senin" href="mailto:svillar@igalia.com" />
 <link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#min-size-auto" />
+<link rel="help" href="https://github.com/web-platform-tests/wpt/issues/31609" />
 <link rel="match" href="reference/flexbox-min-width-auto-006-ref.html" />
-<meta name="assert" content="Test that min-width:auto does not incorrectly stretch items with aspect ratio" />
 
 <style>
-#reference-overlapped-red {
-    position: relative;
-    background-color: red;
-    width: 10px;
-    height: 10px;
-    top: 40px;
-    z-index: -1;
-}
 .constrained-width-flex {
     width: 100px;
     display: flex;
@@ -25,7 +17,7 @@
 }
 </style>
 
-<p>Test passes if there are a (vertically centered) 20x20 and a 60x100 green boxes enclosed on each 100x100 square.</p>
+<p>Test passes if there are two 100x100 green squares.</p>
 
 <div class="constrained-width-flex">
     <div class="constrained-height-flex">
@@ -42,4 +34,4 @@
     <div class="constrained-height-flex">
         <img  src="support/60x60-green.png"/>
     </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/reference/flexbox-min-width-auto-005-ref.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/reference/flexbox-min-width-auto-005-ref.html
index d1e9d96..6bc8a27 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-flexbox/reference/flexbox-min-width-auto-005-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/reference/flexbox-min-width-auto-005-ref.html
@@ -7,18 +7,10 @@
   height: 50px;
   width: 100px;
 }
-span {
-  display: inline-block;
-  background-color: green;
-  height: 50px;
-  width: 40px;
-}
 br { margin: 50px; }
 </style>
 
 <p>Test passes if there is <strong>no red</strong> visible on the page.</p>
 <div></div>
-
 <br>
-
-<span></span>
\ No newline at end of file
+<div></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/reference/flexbox-min-width-auto-006-ref.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/reference/flexbox-min-width-auto-006-ref.html
index 1d6cb7a..1f1b7df 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-flexbox/reference/flexbox-min-width-auto-006-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/reference/flexbox-min-width-auto-006-ref.html
@@ -5,28 +5,14 @@
 .box {
   width: 100px;
   height: 100px;
+  background: green;
   border: 1px solid black;
 }
-#green-square {
-    background: green;
-    margin-top: 40px;
-    width: 20px;
-    height: 20px;
-}
-#green-rectange {
-    background: green;
-    width: 60px;
-    height: 100px;
-}
 </style>
 
-<p>Test passes if there are a (vertically centered) 20x20 and a 60x100 green boxes enclosed on each 100x100 square.</p>
-<div class="box">
-    <div id="green-square"></div>
-</div>
+<p>Test passes if there are two 100x100 green squares.</p>
+<div class="box"></div>
 
 <br>
 
-<div class="box">
-    <div id="green-rectange"></div>
-</div>
+<div class="box"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/clamp-length-serialize.html b/third_party/blink/web_tests/external/wpt/css/css-values/clamp-length-serialize.html
index 4719e4c..2aa8564f 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-values/clamp-length-serialize.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/clamp-length-serialize.html
@@ -10,6 +10,6 @@
 }
 
 test_valid_length('clamp(1px, 2px, 3px)', 'clamp(1px, 2px, 3px)');
-test_valid_length('clamp(1px, 2px, clamp(2px, 3px, 4px))', 'clamp(1px, 2px, clamp(2px, 3px, 4px))');
+test_valid_length('clamp(1px, 2px, clamp(2px, 3px, 4px))', 'clamp(1px, 2px, 3px)');
 
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/update-max-aged-worker.py b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/update-max-aged-worker.py
index 221ef77..4f87906 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/update-max-aged-worker.py
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/update-max-aged-worker.py
@@ -13,7 +13,7 @@
     body = u'''
         const mainTime = {time:8f};
         const testName = {test};
-        importScripts('update-max-aged-worker-imported-script.py?test={test}');
+        importScripts('update-max-aged-worker-imported-script.py');
 
         addEventListener('message', event => {{
             event.source.postMessage({{
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addTrack.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addTrack.https.html
index d75022a..9166582 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addTrack.https.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addTrack.https.html
@@ -341,4 +341,54 @@
     assert_equals(first_transceiver.transport, second_transceiver.transport);
 
   }, 'Adding more tracks does not generate more candidates if bundled');
+
+  promise_test(async t => {
+    const pc1 = new RTCPeerConnection();
+    t.add_cleanup(() => pc1.close());
+    const pc2 = new RTCPeerConnection();
+    t.add_cleanup(() => pc2.close());
+
+    const stream = await getNoiseStream({ audio: true });
+    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
+    const [track] = stream.getTracks();
+
+    pc1.addTrack(track);
+    const offer = await pc1.createOffer();
+    // We do not await here; we want to ensure that the transceiver this creates
+    // is untouched by addTrack, and that addTrack creates _another_ transceiver
+    const srdPromise = pc2.setRemoteDescription(offer);
+
+    const sender = pc2.addTrack(track);
+
+    await srdPromise;
+
+    assert_equals(pc2.getTransceivers().length, 1, "Should have 1 transceiver");
+    assert_equals(pc2.getTransceivers()[0].sender, sender, "The transceiver should be the one added by addTrack");
+  }, 'Calling addTrack while sRD(offer) is pending should allow the new remote transceiver to be the same one that addTrack creates');
+
+  promise_test(async t => {
+    const pc1 = new RTCPeerConnection();
+    t.add_cleanup(() => pc1.close());
+    const pc2 = new RTCPeerConnection();
+    t.add_cleanup(() => pc2.close());
+    pc1.addTransceiver('video');
+
+    const stream = await getNoiseStream({ audio: true });
+    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
+    const [track] = stream.getTracks();
+
+    const offer = await pc1.createOffer();
+    const srdPromise = pc2.setRemoteDescription(offer);
+    assert_equals(pc2.getTransceivers().length, 0);
+    pc2.addTrack(track);
+    assert_equals(pc2.getTransceivers().length, 1);
+    const transceiver0 = pc2.getTransceivers()[0];
+    assert_equals(transceiver0.mid, null);
+    await srdPromise;
+    assert_equals(pc2.getTransceivers().length, 2);
+    const transceiver1 = pc2.getTransceivers()[1];
+    assert_equals(transceiver0.mid, null);
+    assert_not_equals(transceiver1.mid, null);
+  }, 'When addTrack is called while sRD is in progress, and both addTrack and sRD add a transceiver of different media types, the addTrack transceiver should come first, and then the sRD transceiver.');
+
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-offer.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-offer.html
index 247d6e0..d5acb7e1 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-offer.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-offer.html
@@ -340,4 +340,17 @@
     await waitForIceStateChange(pc2, ['connected', 'completed']);
   }, 'sRD(reoffer) with candidates and without trickle works');
 
+  promise_test(async t => {
+    const pc1 = new RTCPeerConnection();
+    t.add_cleanup(() => pc1.close());
+    const pc2 = new RTCPeerConnection();
+    t.add_cleanup(() => pc2.close());
+    pc1.addTransceiver('video');
+    const offer = await pc1.createOffer();
+    const srdPromise = pc2.setRemoteDescription(offer);
+    assert_equals(pc2.getTransceivers().length, 0);
+    await srdPromise;
+    assert_equals(pc2.getTransceivers().length, 1);
+  }, 'Transceivers added by sRD(offer) should not show up until sRD resolves');
+
 </script>
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/reflections/transparent-reflected-sublayers-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/reflections/transparent-reflected-sublayers-expected.png
deleted file mode 100644
index c71122a..0000000
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/reflections/transparent-reflected-sublayers-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/table/frame-and-rules-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/table/frame-and-rules-expected.png
deleted file mode 100644
index 99922d5..0000000
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/table/frame-and-rules-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/fast/forms/color-scheme/datetimelocal-picker/datetimelocal-picker-appearance-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/fast/forms/color-scheme/datetimelocal-picker/datetimelocal-picker-appearance-expected.png
deleted file mode 100644
index f1e2d58..0000000
--- a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/fast/forms/color-scheme/datetimelocal-picker/datetimelocal-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/fast/forms/color-scheme/suggestion-picker/time-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/fast/forms/color-scheme/suggestion-picker/time-suggestion-picker-appearance-expected.png
deleted file mode 100644
index 5d25ee6..0000000
--- a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/fast/forms/color-scheme/suggestion-picker/time-suggestion-picker-appearance-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/fast/forms/suggestion-picker/week-suggestion-picker-appearance-rtl-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/fast/forms/suggestion-picker/week-suggestion-picker-appearance-rtl-expected.png
deleted file mode 100644
index 31906e0b..0000000
--- a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/fast/forms/suggestion-picker/week-suggestion-picker-appearance-rtl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/fast/reflections/transparent-reflected-sublayers-expected.png b/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/fast/reflections/transparent-reflected-sublayers-expected.png
deleted file mode 100644
index c71122a..0000000
--- a/third_party/blink/web_tests/flag-specific/disable-site-isolation-trials/fast/reflections/transparent-reflected-sublayers-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/paint/invalidation/repaint-overlay/layers-overlay.html b/third_party/blink/web_tests/paint/invalidation/repaint-overlay/layers-overlay.html
index e8557f2..f3e45c0 100644
--- a/third_party/blink/web_tests/paint/invalidation/repaint-overlay/layers-overlay.html
+++ b/third_party/blink/web_tests/paint/invalidation/repaint-overlay/layers-overlay.html
@@ -56,7 +56,7 @@
 var expected = {
   "layers": [
     {
-      "name": "Scrolling Contents Layer",
+      "name": "Scrolling background of LayoutView #document",
       "bounds": [800, 2016],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF",
@@ -65,6 +65,7 @@
     {
       "name": "LayoutNGBlockFlow (positioned) DIV id='container'",
       "bounds": [100, 100],
+      "contentsOpaqueForText": true,
       "backgroundColor": "#0000FF80",
       "invalidations": [
         [20, 20, 10, 10]
@@ -74,18 +75,14 @@
     {
       "name": "LayoutNGBlockFlow (relative positioned) DIV id='scrollable'",
       "bounds": [302, 302],
+      "contentsOpaqueForText": true,
       "transform": 3
     },
     {
-      "name": "Horizontal Scrollbar Layer",
-      "position": [1, 301],
-      "bounds": [300, 0],
-      "transform": 3
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [301, 1],
-      "bounds": [0, 300],
+      "name": "LayoutNGBlockFlow (relative positioned) DIV id='scrollable'",
+      "position": [1, 1],
+      "bounds": [300, 300],
+      "drawsContent": false,
       "transform": 3
     },
     {
@@ -97,11 +94,6 @@
         [20, 20, 10, 10]
       ],
       "transform": 6
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [800, 0],
-      "bounds": [0, 600]
     }
   ],
   "transforms": [
@@ -171,7 +163,7 @@
 var actual = {
   "layers": [
     {
-      "name": "Scrolling Contents Layer",
+      "name": "Scrolling background of LayoutView #document",
       "bounds": [800, 2016],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF",
@@ -180,6 +172,7 @@
     {
       "name": "LayoutNGBlockFlow (positioned) DIV id='container'",
       "bounds": [100, 100],
+      "contentsOpaqueForText": true,
       "backgroundColor": "#0000FF80",
       "invalidations": [
         [20, 20, 10, 10]
@@ -189,18 +182,14 @@
     {
       "name": "LayoutNGBlockFlow (relative positioned) DIV id='scrollable'",
       "bounds": [302, 302],
+      "contentsOpaqueForText": true,
       "transform": 3
     },
     {
-      "name": "Horizontal Scrollbar Layer",
-      "position": [1, 301],
-      "bounds": [300, 0],
-      "transform": 3
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [301, 1],
-      "bounds": [0, 300],
+      "name": "LayoutNGBlockFlow (relative positioned) DIV id='scrollable'",
+      "position": [1, 1],
+      "bounds": [300, 300],
+      "drawsContent": false,
       "transform": 3
     },
     {
@@ -212,11 +201,6 @@
         [20, 20, 10, 10]
       ],
       "transform": 6
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [800, 0],
-      "bounds": [0, 600]
     }
   ],
   "transforms": [
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/css-values/clamp-length-serialize-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/css-values/clamp-length-serialize-expected.txt
new file mode 100644
index 0000000..e70c161
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/css/css-values/clamp-length-serialize-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+PASS e.style['letter-spacing'] = "clamp(1px, 2px, 3px)" should set the property value
+FAIL e.style['letter-spacing'] = "clamp(1px, 2px, clamp(2px, 3px, 4px))" should set the property value assert_equals: serialization should be canonical expected "clamp(1px, 2px, 3px)" but got "clamp(1px, 2px, clamp(2px, 3px, 4px))"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/generic/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-addTrack.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-addTrack.https-expected.txt
index 5640dcb..76f83e6 100644
--- a/third_party/blink/web_tests/platform/generic/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-addTrack.https-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-addTrack.https-expected.txt
@@ -9,5 +9,7 @@
 FAIL addTrack with existing sender that has been used to send should create new sender promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
 FAIL addTrack with existing sender with null track, different kind, and recvonly direction should create new sender promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
 FAIL Adding more tracks does not generate more candidates if bundled promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
+FAIL Calling addTrack while sRD(offer) is pending should allow the new remote transceiver to be the same one that addTrack creates assert_equals: Should have 1 transceiver expected 1 but got 0
+FAIL When addTrack is called while sRD is in progress, and both addTrack and sRD add a transceiver of different media types, the addTrack transceiver should come first, and then the sRD transceiver. promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/linux/virtual/fenced-frame-mparch/wpt_internal/fenced_frame/key-scrolling.https-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/fenced-frame-mparch/wpt_internal/fenced_frame/key-scrolling.https-expected.txt
new file mode 100644
index 0000000..0c42154
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/fenced-frame-mparch/wpt_internal/fenced_frame/key-scrolling.https-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL Keyboard scrolling bubbles out of fenced frame step_wait_func: Wait for horizontal scroll. Timed out waiting on condition
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac11/virtual/fenced-frame-mparch/wpt_internal/fenced_frame/key-scrolling.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac11/virtual/fenced-frame-mparch/wpt_internal/fenced_frame/key-scrolling.https-expected.txt
new file mode 100644
index 0000000..0c42154
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11/virtual/fenced-frame-mparch/wpt_internal/fenced_frame/key-scrolling.https-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL Keyboard scrolling bubbles out of fenced frame step_wait_func: Wait for horizontal scroll. Timed out waiting on condition
+Harness: the test ran to completion.
+
diff --git a/third_party/nearby/README.chromium b/third_party/nearby/README.chromium
index bb18a6d3..45d737768 100644
--- a/third_party/nearby/README.chromium
+++ b/third_party/nearby/README.chromium
@@ -1,7 +1,7 @@
 Name: Nearby Connections Library
 Short Name: Nearby
 URL: https://github.com/google/nearby
-Version: 4bf31d18da0faddcf0a39262c743c4ea95de95ac
+Version: 4c70daf66fa93c57418a5b7f0cbb1d6d32333c98
 License: Apache 2.0
 License File: LICENSE
 Security Critical: yes
diff --git a/tools/cast3p/cast_core.version b/tools/cast3p/cast_core.version
index 1a9cdc3..baf82bb 100644
--- a/tools/cast3p/cast_core.version
+++ b/tools/cast3p/cast_core.version
@@ -1 +1 @@
-cast_20220805_0600_RC00
+cast_20220805_0600_RC01
diff --git a/tools/grit/grit/node/base.py b/tools/grit/grit/node/base.py
index bbfbe2f..91454d5 100644
--- a/tools/grit/grit/node/base.py
+++ b/tools/grit/grit/node/base.py
@@ -480,15 +480,14 @@
   def EvaluateExpression(cls, expr, defs, target_platform, extra_variables={}):
     '''Worker for EvaluateCondition (below) and conditions in XTB files.'''
 
-    def IsChromeOS(defs):
-      '''Returns whether the target is Chrome OS based on specified definitions.
-
-      Unlike other platforms, the target platform for Chrome OS is Linux and not
-      the target OS, which is instead specified by one of two defines.
-
-      TODO(crbug.com/1316150): Remove once GRIT natively supports `is_chromeos`.
-      '''
-      return defs.get('chromeos_ash') or defs.get('chromeos_lacros')
+    if target_platform == 'chromeos':
+      assert defs.get('chromeos_ash', False) != defs.get(
+          'chromeos_lacros',
+          False), 'The chromeos target must be either ash or lacros'
+    else:
+      assert not defs.get('chromeos_ash', False) and not defs.get(
+          'chromeos_lacros',
+          False), 'Non-chromeos targets cannot be ash or lacros'
 
     if expr in cls.eval_expr_cache:
       code, variables_in_expr = cls.eval_expr_cache[expr]
@@ -509,9 +508,9 @@
         value = defs
 
       elif name == 'is_linux':
-        # Although the `target_platform` for Chrome OS is 'linux', do not
-        # consider `is_linux` to be true, consistent with the GN arg.
-        value = target_platform == 'linux' and not IsChromeOS(defs)
+        value = target_platform == 'linux'
+      elif name == 'is_chromeos':
+        value = target_platform == 'chromeos'
       elif name == 'is_macosx':
         value = target_platform == 'darwin'
       elif name == 'is_win':
@@ -526,7 +525,8 @@
         value = 'bsd' in target_platform
       elif name == 'is_posix':
         value = (target_platform in ('linux', 'darwin', 'sunos5', 'android',
-                                     'ios') or 'bsd' in target_platform)
+                                     'ios', 'chromeos')
+                 or 'bsd' in target_platform)
 
       elif name == 'pp_ifdef':
         def pp_ifdef(symbol):
@@ -667,7 +667,7 @@
                                self._COMPRESS_BY_DEFAULT_EXTENSIONS))
 
     if compress == 'gzip' or compress_by_default:
-      # We only use rsyncable compression on Linux.
+      # We only use rsyncable compression for platforms built on Linux.
       if sys.platform == 'linux':
         return grit.format.gzip_string.GzipStringRsyncable(data)
       return grit.format.gzip_string.GzipString(data)
diff --git a/tools/grit/grit/node/base_unittest.py b/tools/grit/grit/node/base_unittest.py
index c4290bf1..b2fe165a 100755
--- a/tools/grit/grit/node/base_unittest.py
+++ b/tools/grit/grit/node/base_unittest.py
@@ -215,16 +215,13 @@
     AssertExpr(False, "is_linux", {}, 'linux2', {})  # Python 2 used 'linux2'.
     AssertExpr(False, "is_linux", {}, 'linux-foo', {})  # Must match exactly.
     AssertExpr(False, "is_linux", {}, 'foollinux', {})
-    AssertExpr(True, "is_linux", {'chromeos_ash': False}, 'linux', {})
-    AssertExpr(False, "is_linux", {'chromeos_ash': True}, 'linux', {})
-    AssertExpr(True, "is_linux", {'chromeos_lacros': False}, 'linux', {})
-    AssertExpr(False, "is_linux", {'chromeos_lacros': True}, 'linux', {})
+    AssertExpr(False, "is_linux", {'chromeos_ash': True}, 'chromeos', {})
+    AssertExpr(False, "is_linux", {'chromeos_lacros': True}, 'chromeos', {})
     # `is_chromeos` is not used with GRIT and is thus ignored.
     AssertExpr(True, "is_linux", {'is_chromeos': True}, 'linux', {})
-    # `is_chromeos` is not currently supported.
-    # TODO(crbug.com/1316150): Uncomment and update these tests when fixed.
-    # AssertExpr(False, "is_chromeos", {}, 'linux', {})
-    # AssertExpr(True, "is_chromeos", {<some condition>}, 'linux', {})
+    AssertExpr(True, "is_chromeos", {'chromeos_ash': True}, 'chromeos', {})
+    AssertExpr(True, "is_chromeos", {'chromeos_lacros': True}, 'chromeos', {})
+    AssertExpr(False, "is_chromeos", {}, 'linux', {})
     AssertExpr(False, "is_fuchsia", {}, 'linux', {})
     AssertExpr(False, "is_linux", {}, 'win32', {})
     AssertExpr(True, "is_macosx", {}, 'darwin', {})
@@ -236,8 +233,8 @@
     AssertExpr(True, "is_ios", {}, 'ios', {})
     AssertExpr(False, "is_ios", {}, 'darwin', {})
     AssertExpr(True, "is_posix", {}, 'linux', {})
-    AssertExpr(True, "is_posix", {'chromeos_ash': True}, 'linux', {})
-    AssertExpr(True, "is_posix", {'chromeos_lacros': True}, 'linux', {})
+    AssertExpr(True, "is_posix", {'chromeos_ash': True}, 'chromeos', {})
+    AssertExpr(True, "is_posix", {'chromeos_lacros': True}, 'chromeos', {})
     AssertExpr(True, "is_posix", {}, 'darwin', {})
     AssertExpr(True, "is_posix", {}, 'android', {})
     AssertExpr(True, "is_posix", {}, 'ios', {})
@@ -286,17 +283,35 @@
     AssertExpr(False, "foo == 'bar' or not baz",
                {'foo': 'ruz', 'baz': True}, 'ios', {'lang': 'en'})
 
-  def testEvaluateExpressionWithUndefinedVariables(self):
-    def AssertThrows(expr, defs):
+  def testEvaluateExpressionThrows(self):
+    def AssertThrows(expr, defs, target_platform, message):
       with self.assertRaises(AssertionError) as cm:
-        base.Node.EvaluateExpression(expr, defs, 'linux', {})
-      self.assertTrue(
-          str(cm.exception).startswith('undefined Grit variable found:'))
+        base.Node.EvaluateExpression(expr, defs, target_platform, {})
+      self.assertTrue(str(cm.exception) == message)
 
-    AssertThrows("is_chromeos", {})
-    AssertThrows("foo == 'baz'", {})
-    AssertThrows("is_chromeos", {'is_macosx': True})
-    AssertThrows("foo == 'bar' or not baz", {'foo': 'bar', 'fun': True})
+    # Test undefined variables.
+    AssertThrows("foo == 'baz'", {}, 'linux',
+                 'undefined Grit variable found: foo')
+    AssertThrows("foo == 'bar' or not baz", {
+        'foo': 'bar',
+        'fun': True
+    }, 'linux', 'undefined Grit variable found: baz')
+
+    # Test invalid chromeos configurations.
+    AssertThrows("is_chromeos", {}, 'chromeos',
+                 'The chromeos target must be either ash or lacros')
+    AssertThrows("is_chromeos", {
+        'chromeos_ash': True,
+        'chromeos_lacros': True
+    }, 'chromeos', 'The chromeos target must be either ash or lacros')
+    AssertThrows("is_linux", {'chromeos_ash': True}, 'linux',
+                 'Non-chromeos targets cannot be ash or lacros')
+    AssertThrows("is_linux", {'chromeos_lacros': True}, 'linux',
+                 'Non-chromeos targets cannot be ash or lacros')
+    AssertThrows("is_linux", {
+        'chromeos_ash': True,
+        'chromeos_lacros': True
+    }, 'linux', 'Non-chromeos targets cannot be ash or lacros')
 
 
 if __name__ == '__main__':
diff --git a/tools/grit/grit_args.gni b/tools/grit/grit_args.gni
index 92be15a..18792c9 100644
--- a/tools/grit/grit_args.gni
+++ b/tools/grit/grit_args.gni
@@ -14,8 +14,8 @@
 
 # Prefer using this (and excluding specific platforms) when a resource applies
 # to (most) desktop platforms.
-assert(toolkit_views == (is_chromeos_ash || is_chromeos_lacros || is_fuchsia ||
-                         is_linux || is_mac || is_win))
+assert(toolkit_views ==
+       (is_chromeos || is_fuchsia || is_linux || is_mac || is_win))
 
 # Variables that are passed to grit with the -D flag.
 
@@ -75,7 +75,9 @@
 }
 
 # When cross-compiling, explicitly pass the target system to grit.
-if (current_toolchain != host_toolchain) {
+# There's an exception for Chrome OS, as the toolchain can be the same
+# as linux, but the target platform still must be set.
+if (current_toolchain != host_toolchain || is_chromeos) {
   _target_platform = ""
 
   if (is_android) {
@@ -87,9 +89,12 @@
   if (is_ios) {
     _target_platform = "ios"
   }
-  if (is_linux || is_chromeos) {
+  if (is_linux) {
     _target_platform = "linux"
   }
+  if (is_chromeos) {
+    _target_platform = "chromeos"
+  }
   if (is_mac) {
     _target_platform = "darwin"
   }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 024cbe4..eae5609 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -3969,6 +3969,8 @@
 <enum name="ArcAuthReauthReason">
   <int value="0" label="AndroidID is missing"/>
   <int value="1" label="Main account is missing"/>
+  <int value="2" label="ARC DPC is out of sync"/>
+  <int value="3" label="Reauth not needed"/>
 </enum>
 
 <enum name="ArcBootContinueCodeInstallationResult">
@@ -22804,6 +22806,7 @@
   <int value="17" label="TSS invalid handle"/>
   <int value="18" label="Keyset wrapped both by TPM and Scrypt"/>
   <int value="19" label="Failed to clean up ephemeral cryptohome"/>
+  <int value="20" label="TPM out of memory"/>
 </enum>
 
 <enum name="CryptohomeErrorHashed">
@@ -105016,7 +105019,29 @@
   <int value="4" label="DriveQuickAccess"/>
 </enum>
 
+<enum name="ZeroSuggestEligibility">
+  <int value="0" label="Eligible for current context and external conditions">
+    Zero-prefix suggestions are eligible.
+  </int>
+  <int value="1" label="Remote request without page URL ineligible">
+    Suggest request without sending the current page URL cannot be made. E.g.,
+    the user is in icognito mode or Google is not set as the DSE.
+  </int>
+  <int value="2" label="Remote request with sending page URL ineligible">
+    Suggest request with sending the current page URL cannot be made. E.g., the
+    user has not consented and the suggest endpoint and page URL are not
+    same-origin.
+  </int>
+  <int value="3" label="Generally ineligible in current context">
+    Zero-prefix suggestions are not eligible in the given context. E.g., due to
+    the page classification, focus type, input type, or an invalid page URL.
+  </int>
+</enum>
+
 <enum name="ZeroSuggestEligibleOnFocus">
+  <obsolete>
+    Obsolete as of M106.
+  </obsolete>
   <int value="0" label="Eligible">
     URL can be currently sent to the suggest server.
   </int>
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml
index e64b85b..1328d2b 100644
--- a/tools/metrics/histograms/metadata/autofill/histograms.xml
+++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -2485,6 +2485,18 @@
   <token key="OtpAuthType" variants="Autofill.OtpAuth.Type"/>
 </histogram>
 
+<histogram name="Autofill.PageLoadsWithOfferIconShowing.{OfferType}"
+    enum="BooleanShown" expires_after="2023-07-01">
+  <owner>meiliang@chromium.org</owner>
+  <owner>chrome-shopping@google.com</owner>
+  <summary>
+    Emits true if the offer notification icon is currently being shown in the
+    omnibox after a page navigation for {OfferType}. Doesn't emit any other
+    value.
+  </summary>
+  <token key="OfferType" variants="Autofill.OfferNotification.Type"/>
+</histogram>
+
 <histogram name="Autofill.PageTranslationStatus" enum="Boolean"
     expires_after="2022-12-12">
   <owner>koerber@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml
index fa0e950..14b13e3a 100644
--- a/tools/metrics/histograms/metadata/extensions/histograms.xml
+++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -646,7 +646,7 @@
 </histogram>
 
 <histogram name="Extensions.DeclarativeNetRequest.CreateVerifiedMatcherTime"
-    units="ms" expires_after="2022-08-28">
+    units="ms" expires_after="2023-08-28">
   <owner>kelvinjiang@chromium.org</owner>
   <owner>src/extensions/OWNERS</owner>
   <summary>
@@ -824,7 +824,7 @@
 </histogram>
 
 <histogram name="Extensions.DeclarativeNetRequest.UpdateDynamicRulesStatus"
-    enum="UpdateDynamicRulesStatus" expires_after="2022-06-26">
+    enum="UpdateDynamicRulesStatus" expires_after="2023-06-26">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>src/extensions/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/omnibox/histograms.xml b/tools/metrics/histograms/metadata/omnibox/histograms.xml
index 0b3d2dd9..48ea72d 100644
--- a/tools/metrics/histograms/metadata/omnibox/histograms.xml
+++ b/tools/metrics/histograms/metadata/omnibox/histograms.xml
@@ -2055,6 +2055,9 @@
 
 <histogram name="Omnibox.ZeroSuggest.Eligible.OnFocusV2"
     enum="ZeroSuggestEligibleOnFocus" expires_after="2022-12-25">
+  <obsolete>
+    Obsolete as of M106.
+  </obsolete>
   <owner>mpearson@chromium.org</owner>
   <owner>jdonnelly@chromium.org</owner>
   <summary>
@@ -2086,6 +2089,20 @@
   </summary>
 </histogram>
 
+<histogram name="Omnibox.ZeroSuggestProvider.Eligibility"
+    enum="ZeroSuggestEligibility" expires_after="2022-12-11">
+  <owner>mahmadi@chromium.org</owner>
+  <owner>chrome-omnibox-team@google.com</owner>
+  <summary>
+    Logs whether ZeroSuggestProvider is eligible to request and display zero-
+    prefix suggestions, and if not, why not. Emitted for both
+    omit_asynchronous_matches_ true (i.e, Autocomplete classifier) and false
+    inputs (i.e, when the user has typed in, focused the omnibox, or cleared it
+    but has not typed in yet) in ZeroSuggestProvider::Start(). Also emitted on
+    applicable page load/switch events in ZeroSuggestProvider::StartPrefetch().
+  </summary>
+</histogram>
+
 <histogram name="Omnibox.ZeroSuggestProvider.{ResultType}.{RequestType}"
     enum="ZeroSuggestProviderEvent" expires_after="2022-12-11">
   <owner>mahmadi@chromium.org</owner>
diff --git a/ui/file_manager/file_manager/foreground/elements/BUILD.gn b/ui/file_manager/file_manager/foreground/elements/BUILD.gn
index 00efd2a..5bdd5a5 100644
--- a/ui/file_manager/file_manager/foreground/elements/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/elements/BUILD.gn
@@ -215,10 +215,7 @@
 }
 
 js_library("xf_button") {
-  deps = [
-    "//ui/webui/resources/cr_elements/cr_button:cr_button.m",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
-  ]
+  deps = [ "//ui/webui/resources/cr_elements/cr_button:cr_button.m" ]
 }
 
 js_library("xf_circular_progress") {
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.cc b/ui/ozone/platform/wayland/host/wayland_event_source.cc
index 1379d5df..08171f88 100644
--- a/ui/ozone/platform/wayland/host/wayland_event_source.cc
+++ b/ui/ozone/platform/wayland/host/wayland_event_source.cc
@@ -253,7 +253,6 @@
     // Save new pointer location.
     pointer_location_ = location;
     window_manager_->SetPointerFocusedWindow(window);
-    pointer_scroll_data_.target = window;
   }
 
   auto* target = window_manager_->GetCurrentPointerFocusedWindow();
@@ -266,7 +265,6 @@
 
   if (!focused) {
     window_manager_->SetPointerFocusedWindow(nullptr);
-    pointer_scroll_data_.target = nullptr;
   }
 }
 
@@ -344,8 +342,8 @@
 #else
       false;
 #endif
-  auto* target = pointer_scroll_data_.target;
-  if (!window_manager_->IsWindowValid(target))
+  auto* target = window_manager_->GetCurrentPointerFocusedWindow();
+  if (!target)
     return;
 
   // Dispatch Fling event if pointer.axis_stop is notified and the recent
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.h b/ui/ozone/platform/wayland/host/wayland_event_source.h
index f9b66c1..7135851 100644
--- a/ui/ozone/platform/wayland/host/wayland_event_source.h
+++ b/ui/ozone/platform/wayland/host/wayland_event_source.h
@@ -165,7 +165,6 @@
     PointerScrollData& operator=(const PointerScrollData&);
     PointerScrollData& operator=(PointerScrollData&&);
 
-    WaylandWindow* target = nullptr;
     absl::optional<uint32_t> axis_source;
     float dx = 0.0f;
     float dy = 0.0f;
diff --git a/ui/webui/resources/BUILD.gn b/ui/webui/resources/BUILD.gn
index 70a04a3..f8a56b5 100644
--- a/ui/webui/resources/BUILD.gn
+++ b/ui/webui/resources/BUILD.gn
@@ -168,8 +168,7 @@
   "cr_elements/cr_checkbox/cr_checkbox.m.d.ts",
   "cr_elements/cr_container_shadow_behavior.m.d.ts",
   "cr_elements/cr_dialog/cr_dialog.m.d.ts",
-  "cr_elements/cr_expand_button/cr_expand_button.d.ts",
-  "cr_elements/cr_icon_button/cr_icon_button.m.d.ts",
+  "cr_elements/cr_icon_button/cr_icon_button.d.ts",
   "cr_elements/cr_input/cr_input.m.d.ts",
   "cr_elements/cr_lottie/cr_lottie.m.d.ts",
   "cr_elements/cr_radio_button/cr_card_radio_button.m.d.ts",
diff --git a/ui/webui/resources/cr_components/app_management/more_permissions_item.ts b/ui/webui/resources/cr_components/app_management/more_permissions_item.ts
index b427073..cc0437a 100644
--- a/ui/webui/resources/cr_components/app_management/more_permissions_item.ts
+++ b/ui/webui/resources/cr_components/app_management/more_permissions_item.ts
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import './app_management_shared_style.css.js';
-import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '//resources/cr_elements/cr_icon_button/cr_icon_button.js';
 
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_list.html b/ui/webui/resources/cr_components/certificate_manager/certificate_list.html
index fd6a180..418e0ed 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_list.html
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_list.html
@@ -18,7 +18,7 @@
       <cr-button id="import" on-click="onImportTap_"
           hidden="[[!canImport_(certificateType, importAllowed, isKiosk_)]]">
         [[i18n('certificateManagerImport')]]</cr-button>
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
       <cr-button id="importAndBind" on-click="onImportAndBindTap_"
           hidden="[[!canImportAndBind_(certificateType, importAllowed,
                  isGuest_)]]">
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_list.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_list.ts
index a454557..bea40a9 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_list.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_list.ts
@@ -24,7 +24,7 @@
 export interface CertificateListElement {
   $: {
     import: HTMLElement,
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     importAndBind: HTMLElement,
     // </if>
   };
@@ -53,7 +53,7 @@
       certificateType: String,
       importAllowed: Boolean,
 
-      // <if expr="chromeos_ash or chromeos_lacros">
+      // <if expr="is_chromeos">
       isGuest_: {
         type: Boolean,
         value() {
@@ -76,7 +76,7 @@
   certificates: CertificatesOrgGroup[];
   certificateType: CertificateType;
   importAllowed: boolean;
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   private isGuest_: boolean;
   // </if>
   private isKiosk_: boolean;
@@ -105,7 +105,7 @@
         this.importAllowed;
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   private canImportAndBind_(): boolean {
     return !this.isGuest_ &&
         this.certificateType === CertificateType.PERSONAL && this.importAllowed;
@@ -152,7 +152,7 @@
     this.handleImport_(false, e.target as HTMLElement);
   }
 
-  // <if expr="chromeos_ash or chromeos_lacros">
+  // <if expr="is_chromeos">
   private onImportAndBindTap_(e: Event) {
     this.handleImport_(true, e.target as HTMLElement);
   }
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.html b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.html
index 6d6a15b..a1bca9aa 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.html
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.html
@@ -37,7 +37,7 @@
             certificate-type="[[certificateTypeEnum_.PERSONAL]]"
             import-allowed="[[clientImportAllowed]]">
         </certificate-list>
-<if expr="chromeos_ash or chromeos_lacros">
+<if expr="is_chromeos">
         <certificate-provisioning-list></certificate-provisioning-list>
 </if>
       </div>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.ts
index 562e539..00141d6 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.ts
@@ -14,9 +14,8 @@
 import './certificate_password_decryption_dialog.js';
 import './certificate_password_encryption_dialog.js';
 import './certificates_error_dialog.js';
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import './certificate_provisioning_list.js';
-
 // </if>
 
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_manager_types.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_manager_types.ts
index 3526d30..9a2c590 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_manager_types.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_manager_types.ts
@@ -7,7 +7,7 @@
  */
 
 // clang-format off
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 import {CertificateProvisioningProcess} from './certificate_provisioning_browser_proxy.js';
 // </if>
 import {CertificatesError, CertificatesImportError,CertificateSubnode, CertificateType, NewCertificateSubNode} from './certificates_browser_proxy.js';
@@ -47,7 +47,7 @@
  */
 export const CertificateActionEvent = 'certificate-action';
 
-// <if expr="chromeos_ash or chromeos_lacros">
+// <if expr="is_chromeos">
 /**
  * The payload of the 'certificate-provisioning-view-details-action' event.
  */
@@ -69,7 +69,7 @@
   interface HTMLElementEventMap {
     'certificates-error': CustomEvent<CertificatesErrorEventDetail>;
     'certificate-action': CustomEvent<CertificateActionEventDetail>;
-    // <if expr="chromeos_ash or chromeos_lacros">
+    // <if expr="is_chromeos">
     'certificate-provisioning-view-details-action':
         CustomEvent<CertificateProvisioningActionEventDetail>;
     // </if>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.ts
index 303fa52..7f63d99 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.ts
@@ -7,7 +7,7 @@
  * one certificate provisioning processes.
  */
 import '../../cr_elements/cr_action_menu/cr_action_menu.js';
-import '../../cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '../../cr_elements/cr_icon_button/cr_icon_button.js';
 import '../../cr_elements/cr_lazy_render/cr_lazy_render.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
 import './certificate_shared.css.js';
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.ts
index 9acc398..fb6785a5e 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.ts
@@ -7,7 +7,7 @@
  */
 
 import '../../cr_elements/cr_action_menu/cr_action_menu.js';
-import '../../cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '../../cr_elements/cr_icon_button/cr_icon_button.js';
 import '../../cr_elements/cr_lazy_render/cr_lazy_render.js';
 import '../../cr_elements/policy/cr_policy_indicator.m.js';
 import '../../cr_elements/icons.m.js';
diff --git a/ui/webui/resources/cr_components/chromeos/network/BUILD.gn b/ui/webui/resources/cr_components/chromeos/network/BUILD.gn
index febe284..27a001dd 100644
--- a/ui/webui/resources/cr_components/chromeos/network/BUILD.gn
+++ b/ui/webui/resources/cr_components/chromeos/network/BUILD.gn
@@ -527,7 +527,7 @@
     ":network_config_element_behavior.m",
     ":network_shared_css.m",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
     "//ui/webui/resources/cr_elements/cr_input:cr_input.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
@@ -573,7 +573,7 @@
     ":network_shared_css.m",
     "//third_party/polymer/v3_0/components-chromium/iron-flex-layout:iron-flex-layout-classes",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
+    "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
   extra_deps = [ ":network_proxy_exclusions_module" ]
@@ -789,6 +789,7 @@
   html_file = "network_list_item.html"
   html_type = "dom-module"
   auto_imports = cr_components_chromeos_auto_imports
+  migrated_imports = cr_components_migrated_imports
   namespace_rewrites = cr_components_chromeos_namespace_rewrites
 }
 
@@ -804,6 +805,7 @@
   html_file = "network_password_input.html"
   html_type = "dom-module"
   auto_imports = cr_components_chromeos_auto_imports
+  migrated_imports = cr_components_migrated_imports
 }
 
 polymer_modulizer("network_property_list_mojo") {
@@ -818,6 +820,7 @@
   html_file = "network_proxy_exclusions.html"
   html_type = "dom-module"
   auto_imports = cr_components_chromeos_auto_imports
+  migrated_imports = cr_components_migrated_imports
   namespace_rewrites = cr_components_chromeos_namespace_rewrites
 }
 
diff --git a/ui/webui/resources/cr_components/chromeos/os_cr_components.gni b/ui/webui/resources/cr_components/chromeos/os_cr_components.gni
index 310e5d0..da0a181 100644
--- a/ui/webui/resources/cr_components/chromeos/os_cr_components.gni
+++ b/ui/webui/resources/cr_components/chromeos/os_cr_components.gni
@@ -71,5 +71,7 @@
   "ui/webui/resources/html/polymer.html|Polymer,flush,html,afterNextRender",
 ]
 
-cr_components_migrated_imports =
-    [ "ui/webui/resources/html/list_property_update_behavior.html" ]
+cr_components_migrated_imports = [
+  "ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.html",
+  "ui/webui/resources/html/list_property_update_behavior.html",
+]
diff --git a/ui/webui/resources/cr_components/chromeos/quick_unlock/BUILD.gn b/ui/webui/resources/cr_components/chromeos/quick_unlock/BUILD.gn
index 846598d..f90dac88 100644
--- a/ui/webui/resources/cr_components/chromeos/quick_unlock/BUILD.gn
+++ b/ui/webui/resources/cr_components/chromeos/quick_unlock/BUILD.gn
@@ -63,6 +63,7 @@
   html_file = "pin_keyboard.html"
   html_type = "dom-module"
   namespace_rewrites = cr_components_chromeos_namespace_rewrites
+  migrated_imports = cr_components_migrated_imports
   auto_imports = cr_components_chromeos_auto_imports
 }
 
diff --git a/ui/webui/resources/cr_components/customize_themes/customize_themes.ts b/ui/webui/resources/cr_components/customize_themes/customize_themes.ts
index 61264f7..b87cc97 100644
--- a/ui/webui/resources/cr_components/customize_themes/customize_themes.ts
+++ b/ui/webui/resources/cr_components/customize_themes/customize_themes.ts
@@ -4,7 +4,7 @@
 
 import '../managed_dialog/managed_dialog.js';
 import '../../cr_elements/cr_button/cr_button.m.js';
-import '../../cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '../../cr_elements/cr_icon_button/cr_icon_button.js';
 import '../../cr_elements/cr_icons_css.m.js';
 import '../../cr_elements/cr_grid/cr_grid.js';
 import '../../cr_elements/shared_vars_css.m.js';
diff --git a/ui/webui/resources/cr_components/help_bubble/help_bubble.ts b/ui/webui/resources/cr_components/help_bubble/help_bubble.ts
index b22443d..4f0f5d9 100644
--- a/ui/webui/resources/cr_components/help_bubble/help_bubble.ts
+++ b/ui/webui/resources/cr_components/help_bubble/help_bubble.ts
@@ -9,12 +9,12 @@
  * components directly).
  */
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/hidden_style_css.m.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 
 import {CrButtonElement} from '//resources/cr_elements/cr_button/cr_button.m.js';
-import {CrIconButtonElement} from '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from '//resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import {assert, assertNotReached} from '//resources/js/assert_ts.js';
 import {isWindows} from '//resources/js/cr.m.js';
 import {DomRepeatEvent, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/ui/webui/resources/cr_components/history_clusters/menu_container.ts b/ui/webui/resources/cr_components/history_clusters/menu_container.ts
index cd034c0..20d1e35 100644
--- a/ui/webui/resources/cr_components/history_clusters/menu_container.ts
+++ b/ui/webui/resources/cr_components/history_clusters/menu_container.ts
@@ -4,7 +4,7 @@
 
 import './history_clusters_shared_style.css.js';
 import '../../cr_elements/cr_action_menu/cr_action_menu.js';
-import '../../cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '../../cr_elements/cr_icon_button/cr_icon_button.js';
 import '../../cr_elements/cr_lazy_render/cr_lazy_render.js';
 
 import {I18nMixin} from 'chrome://resources/js/i18n_mixin.js';
diff --git a/ui/webui/resources/cr_components/history_clusters/url_visit.ts b/ui/webui/resources/cr_components/history_clusters/url_visit.ts
index 8cdc923..290a679 100644
--- a/ui/webui/resources/cr_components/history_clusters/url_visit.ts
+++ b/ui/webui/resources/cr_components/history_clusters/url_visit.ts
@@ -5,7 +5,7 @@
 import './page_favicon.js';
 import './history_clusters_shared_style.css.js';
 import '../../cr_elements/cr_action_menu/cr_action_menu.js';
-import '../../cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '../../cr_elements/cr_icon_button/cr_icon_button.js';
 import '../../cr_elements/cr_lazy_render/cr_lazy_render.js';
 
 import {I18nMixin} from 'chrome://resources/js/i18n_mixin.js';
diff --git a/ui/webui/resources/cr_components/most_visited/most_visited.ts b/ui/webui/resources/cr_components/most_visited/most_visited.ts
index 83c7b1e9..7f76ad7 100644
--- a/ui/webui/resources/cr_components/most_visited/most_visited.ts
+++ b/ui/webui/resources/cr_components/most_visited/most_visited.ts
@@ -5,7 +5,7 @@
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
-import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_icons_css.m.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
 import 'chrome://resources/cr_elements/cr_toast/cr_toast.js';
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn
index 0d832a0..425ff12 100644
--- a/ui/webui/resources/cr_elements/BUILD.gn
+++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -92,8 +92,6 @@
       "cr_container_shadow_behavior.js",
       "cr_dialog/cr_dialog.html",
       "cr_dialog/cr_dialog.js",
-      "cr_icon_button/cr_icon_button.html",
-      "cr_icon_button/cr_icon_button.js",
       "cr_icons_css.html",
       "cr_input/cr_input.html",
       "cr_input/cr_input.js",
@@ -144,8 +142,7 @@
       "cr_checkbox/cr_checkbox.m.js",
       "cr_container_shadow_behavior.m.js",
       "cr_dialog/cr_dialog.m.js",
-      "cr_expand_button/cr_expand_button.js",
-      "cr_icon_button/cr_icon_button.m.js",
+      "cr_icon_button/cr_icon_button.js",
       "cr_icons_css.m.js",
       "cr_input/cr_input.m.js",
       "cr_input/cr_input_style_css.m.js",
@@ -180,7 +177,6 @@
       ":cr_elements_resources",
       "cr_checkbox:closure_compile",
       "cr_dialog:closure_compile",
-      "cr_icon_button:closure_compile",
       "cr_input:closure_compile",
       "cr_lottie:closure_compile",
       "cr_radio_button:closure_compile",
@@ -192,7 +188,6 @@
       "cr_button:closure_compile_module",
       "cr_checkbox:closure_compile_module",
       "cr_dialog:closure_compile_module",
-      "cr_expand_button:closure_compile_module",
       "cr_icon_button:closure_compile_module",
       "cr_input:closure_compile_module",
       "cr_lottie:closure_compile_module",
@@ -300,8 +295,7 @@
       "cr_button:cr_button_module",
       "cr_checkbox:cr_checkbox_module",
       "cr_dialog:cr_dialog_module",
-      "cr_expand_button:web_components",
-      "cr_icon_button:cr_icon_button_module",
+      "cr_icon_button:web_components",
       "cr_input:polymer3_elements",
       "cr_lottie:cr_lottie_module",
       "cr_radio_button:polymer3_elements",
diff --git a/ui/webui/resources/cr_elements/cr_dialog/BUILD.gn b/ui/webui/resources/cr_elements/cr_dialog/BUILD.gn
index f80650e..e254ddde 100644
--- a/ui/webui/resources/cr_elements/cr_dialog/BUILD.gn
+++ b/ui/webui/resources/cr_elements/cr_dialog/BUILD.gn
@@ -21,6 +21,8 @@
   js_file = "cr_dialog.js"
   html_file = "cr_dialog.html"
   html_type = "dom-module"
+  migrated_imports =
+      [ "ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.html" ]
   auto_imports = [
     "ui/webui/resources/cr_elements/cr_container_shadow_behavior.html|CrContainerShadowBehavior",
     "ui/webui/resources/html/assert.html|assert",
diff --git a/ui/webui/resources/cr_elements/cr_elements.gni b/ui/webui/resources/cr_elements/cr_elements.gni
index eeab93d..85d8492d 100644
--- a/ui/webui/resources/cr_elements/cr_elements.gni
+++ b/ui/webui/resources/cr_elements/cr_elements.gni
@@ -31,6 +31,7 @@
     "cr_a11y_announcer/cr_a11y_announcer.ts",
     "cr_action_menu/cr_action_menu.ts",
     "cr_drawer/cr_drawer.ts",
+    "cr_expand_button/cr_expand_button.ts",
     "cr_fingerprint/cr_fingerprint_progress_arc.ts",
     "cr_grid/cr_grid.ts",
     "cr_link_row/cr_link_row.ts",
diff --git a/ui/webui/resources/cr_elements/cr_expand_button/BUILD.gn b/ui/webui/resources/cr_elements/cr_expand_button/BUILD.gn
deleted file mode 100644
index 8514adb..0000000
--- a/ui/webui/resources/cr_elements/cr_expand_button/BUILD.gn
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2018 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/chromeos/ui_mode.gni")
-import("//third_party/closure_compiler/compile_js.gni")
-import("//tools/polymer/html_to_js.gni")
-
-html_to_js("web_components") {
-  js_files = [ "cr_expand_button.js" ]
-}
-
-js_type_check("closure_compile_module") {
-  is_polymer3 = true
-  deps = [ ":cr_expand_button" ]
-}
-
-js_library("cr_expand_button") {
-  deps = [
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/js/cr/ui:focus_without_ink.m",
-  ]
-}
diff --git a/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.d.ts b/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.d.ts
deleted file mode 100644
index 4c16c58..0000000
--- a/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.d.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {LegacyElementMixin} from 'chrome://resources/polymer/v3_0/polymer/lib/legacy/legacy-element-mixin.js';
-
-interface CrExpandButtonElement extends LegacyElementMixin, HTMLElement {
-  expanded: boolean;
-  disabled: boolean;
-  tabIndex: number;
-  noink: boolean;
-  expandTitle?: string;
-  collapseTitle?: string;
-  focus(): void;
-}
-
-export {CrExpandButtonElement};
-
-declare global {
-  interface HTMLElementTagNameMap {
-    'cr-expand-button': CrExpandButtonElement;
-  }
-}
diff --git a/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.js b/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.ts
similarity index 74%
rename from ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.js
rename to ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.ts
index 6b5b7ebc..4de1f24 100644
--- a/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.js
+++ b/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.ts
@@ -8,22 +8,30 @@
  * between an opened (expanded) and closed state.
  */
 import '../cr_actionable_row_style.m.js';
-import '../cr_icon_button/cr_icon_button.m.js';
+import '../cr_icon_button/cr_icon_button.js';
 import '../icons.m.js';
 import '../shared_vars_css.m.js';
 
-import {html, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {focusWithoutInk} from '../../js/cr/ui/focus_without_ink.m.js';
+import {CrIconButtonElement} from '../cr_icon_button/cr_icon_button.js';
 
-/** @polymer */
+import {getTemplate} from './cr_expand_button.html.js';
+
+export interface CrExpandButtonElement {
+  $: {
+    icon: CrIconButtonElement,
+  };
+}
+
 export class CrExpandButtonElement extends PolymerElement {
   static get is() {
     return 'cr-expand-button';
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
@@ -83,45 +91,36 @@
     };
   }
 
+  expanded: boolean;
+  disabled: boolean;
+  expandIcon: string;
+  collapseIcon: string;
+  expandTitle: string;
+  collapseTitle: string;
+  private tooltipText_: string;
+
   static get observers() {
     return ['updateAriaExpanded_(disabled, expanded)'];
   }
 
-  /** @override */
-  ready() {
+  override ready() {
     super.ready();
     this.addEventListener('click', this.toggleExpand_);
   }
 
-  /**
-   * @return {string}
-   * @private
-   */
-  computeTooltipText_() {
+  private computeTooltipText_(): string {
     return this.expanded ? this.collapseTitle : this.expandTitle;
   }
 
-  /** @private */
-  onTooltipTextChange_() {
+  private onTooltipTextChange_() {
     this.title = this.tooltipText_;
   }
 
-  /** @type {boolean} */
-  get noink() {
-    return this.$.icon.noink;
-  }
-
-  /** @type {boolean} */
-  set noink(value) {
-    this.$.icon.noink = value;
-  }
-
-  focus() {
+  override focus() {
     this.$.icon.focus();
   }
 
-  /** @private */
-  onAriaLabelChange_() {
+  private onAriaLabelChange_() {
     if (this.ariaLabel) {
       this.$.icon.removeAttribute('aria-labelledby');
       this.$.icon.setAttribute('aria-label', this.ariaLabel);
@@ -131,26 +130,19 @@
     }
   }
 
-  /** @private */
-  onExpandedChange_() {
+  private onExpandedChange_() {
     this.updateIcon_();
   }
 
-  /** @private */
-  onIconChange_() {
+  private onIconChange_() {
     this.updateIcon_();
   }
 
-  /** @private */
-  updateIcon_() {
+  private updateIcon_() {
     this.$.icon.ironIcon = this.expanded ? this.collapseIcon : this.expandIcon;
   }
 
-  /**
-   * @param {!Event} event
-   * @private
-   */
-  toggleExpand_(event) {
+  private toggleExpand_(event: Event) {
     // Prevent |click| event from bubbling. It can cause parents of this
     // elements to erroneously re-toggle this control.
     event.stopPropagation();
@@ -161,14 +153,20 @@
     focusWithoutInk(this.$.icon);
   }
 
-  /** @private */
-  updateAriaExpanded_() {
+  private updateAriaExpanded_() {
     if (this.disabled) {
       this.$.icon.removeAttribute('aria-expanded');
     } else {
-      this.$.icon.setAttribute('aria-expanded', this.expanded);
+      this.$.icon.setAttribute(
+          'aria-expanded', this.expanded ? 'true' : 'false');
     }
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'cr-expand-button': CrExpandButtonElement;
+  }
+}
+
 customElements.define(CrExpandButtonElement.is, CrExpandButtonElement);
diff --git a/ui/webui/resources/cr_elements/cr_icon_button/BUILD.gn b/ui/webui/resources/cr_elements/cr_icon_button/BUILD.gn
index ad2d861..b6d3b4d9d 100644
--- a/ui/webui/resources/cr_elements/cr_icon_button/BUILD.gn
+++ b/ui/webui/resources/cr_elements/cr_icon_button/BUILD.gn
@@ -3,33 +3,20 @@
 # found in the LICENSE file.
 
 import("//third_party/closure_compiler/compile_js.gni")
-import("//tools/polymer/polymer.gni")
+import("//tools/polymer/html_to_js.gni")
 
-js_type_check("closure_compile") {
-  uses_legacy_modules = true
-  deps = [ ":cr_icon_button" ]
-}
-
-js_library("cr_icon_button") {
-  deps = [ "//third_party/polymer/v1_0/components-chromium/paper-behaviors:paper-ripple-behavior-extracted" ]
-}
-
-polymer_modulizer("cr_icon_button") {
-  js_file = "cr_icon_button.js"
-  html_file = "cr_icon_button.html"
-  html_type = "dom-module"
+html_to_js("web_components") {
+  js_files = [ "cr_icon_button.js" ]
 }
 
 js_type_check("closure_compile_module") {
   is_polymer3 = true
-  deps = [ ":cr_icon_button.m" ]
+  deps = [ ":cr_icon_button" ]
 }
 
-js_library("cr_icon_button.m") {
-  sources = [ "$root_gen_dir/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.m.js" ]
+js_library("cr_icon_button") {
   deps = [
     "//third_party/polymer/v3_0/components-chromium/paper-behaviors:paper-ripple-behavior",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
   ]
-  extra_deps = [ ":cr_icon_button_module" ]
 }
diff --git a/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.m.d.ts b/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.d.ts
similarity index 100%
rename from ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.m.d.ts
rename to ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.d.ts
diff --git a/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.html b/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.html
index 3cf2c2f..0058f2b3 100644
--- a/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.html
+++ b/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.html
@@ -1,10 +1,3 @@
-<link rel="import" href="../../html/polymer.html">
-
-<link rel="import" href="../shared_vars_css.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-
-<dom-module id="cr-icon-button">
-  <template>
     <style>
       :host {
         --cr-icon-button-fill-color: var(--google-grey-700);
@@ -124,6 +117,3 @@
     <div id="icon">
       <div id="maskedImage"></div>
     </div>
-  </template>
-  <script src="cr_icon_button.js"></script>
-</dom-module>
diff --git a/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.js b/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.js
index a5bb2d68..bf9ca1c 100644
--- a/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.js
+++ b/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.js
@@ -40,9 +40,16 @@
  * When using iron-icon's, more than one icon can be specified by setting
  * the |ironIcon| property to a comma-delimited list of keys.
  */
+import {Polymer, html} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import '../shared_vars_css.m.js';
+import '//resources/polymer/v3_0/iron-icon/iron-icon.js';
+
 Polymer({
   is: 'cr-icon-button',
 
+  _template: html`{__html_template__}`,
+
   properties: {
     disabled: {
       type: Boolean,
@@ -196,4 +203,3 @@
     }
   },
 });
-/* #ignore */ console.warn('crbug/1173575, non-JS module files deprecated.');
diff --git a/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.ts b/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.ts
index cd3d26a..93b4e457 100644
--- a/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.ts
+++ b/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.ts
@@ -10,7 +10,7 @@
  * page (somewhat like an HTML link).
  */
 import '../cr_actionable_row_style.m.js';
-import '../cr_icon_button/cr_icon_button.m.js';
+import '../cr_icon_button/cr_icon_button.js';
 import '../hidden_style_css.m.js';
 import '../icons.m.js';
 import '../shared_style_css.m.js';
@@ -19,7 +19,7 @@
 
 import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {CrIconButtonElement} from '../cr_icon_button/cr_icon_button.m.js';
+import {CrIconButtonElement} from '../cr_icon_button/cr_icon_button.js';
 
 import {getTemplate} from './cr_link_row.html.js';
 
diff --git a/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.ts b/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.ts
index c22429b..0d94146 100644
--- a/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.ts
+++ b/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.ts
@@ -8,7 +8,7 @@
  * uses CrSearchFieldMixin.
  */
 
-import '../cr_icon_button/cr_icon_button.m.js';
+import '../cr_icon_button/cr_icon_button.js';
 import '../cr_input/cr_input.m.js';
 import '../cr_input/cr_input_style_css.m.js';
 import '../icons.m.js';
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.ts b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.ts
index 5eece9c..90ea96a 100644
--- a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.ts
+++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import '../cr_icon_button/cr_icon_button.m.js';
+import '../cr_icon_button/cr_icon_button.js';
 import '../cr_icons_css.m.js';
 import '../hidden_style_css.m.js';
 import '../icons.m.js';
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.ts b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.ts
index 73f1344..1d63347 100644
--- a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.ts
+++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import '../cr_icon_button/cr_icon_button.m.js';
+import '../cr_icon_button/cr_icon_button.js';
 import '../cr_icons_css.m.js';
 import '../icons.m.js';
 import '../shared_style_css.m.js';
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.ts b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.ts
index 03e70fc..01d21171 100644
--- a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.ts
+++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.ts
@@ -14,7 +14,7 @@
  */
 
 import '../cr_button/cr_button.m.js';
-import '../cr_icon_button/cr_icon_button.m.js';
+import '../cr_icon_button/cr_icon_button.js';
 import '../icons.m.js';
 import '../shared_vars_css.m.js';